diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2007-11-26 15:40:52 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2007-11-26 15:40:52 +0000 |
commit | 2780a6859a5af847650e39067a3525e9216c46a8 (patch) | |
tree | 09912dff9c56754127039e83724d81375f705ede /sys/scsi | |
parent | 61b591d4724fe059ead2ae8a9d2c63137083b0e6 (diff) |
let scsibus ask the adapter about a device before probing it. also allow
the adapter to be notified when a device goes away so it can free any state
it maintains about that device.
ok deraadt@ marco@
Diffstat (limited to 'sys/scsi')
-rw-r--r-- | sys/scsi/scsiconf.c | 21 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 4 |
2 files changed, 21 insertions, 4 deletions
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index 101228588d6..39d01bdfc97 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.c,v 1.128 2007/11/25 22:28:54 dlg Exp $ */ +/* $OpenBSD: scsiconf.c,v 1.129 2007/11/26 15:40:51 dlg Exp $ */ /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ /* @@ -421,14 +421,18 @@ scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags) if (((flags & DETACH_FORCE) == 0) && (link->flags & SDEV_OPEN)) return (EBUSY); - /* detaching a device from scsibus is a two step process... */ + /* detaching a device from scsibus is a three step process... */ /* 1. detach the device */ rv = config_detach(link->device_softc, flags); if (rv != 0) return (rv); - /* 2. free up its state in the midlayer */ + /* 2. free up its state in the adapter */ + if (alink->adapter->dev_free != NULL) + alink->adapter->dev_free(link); + + /* 3. free up its state in the midlayer */ free(link, M_DEVBUF); sc->sc_link[target][lun] = NULL; @@ -716,6 +720,14 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun) SC_DEBUG(sc_link, SDEV_DB2, ("scsi_link created.\n")); + /* ask the adapter if this will be a valid device */ + if (scsi->adapter_link->adapter->dev_probe != NULL && + scsi->adapter_link->adapter->dev_probe(sc_link) != 0) { + if (lun == 0) + rslt = EINVAL; + goto free; + } + /* * Tell drivers that are paying attention to avoid sync/wide/tags until * INQUIRY data has been processed and the quirks information is @@ -865,6 +877,9 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun) return (0); bad: + if (scsi->adapter_link->adapter->dev_free != NULL) + scsi->adapter_link->adapter->dev_free(sc_link); +free: free(sc_link, M_DEVBUF); return (rslt); } diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index 6dd5ff63549..301ba634de9 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.h,v 1.88 2007/11/25 22:28:54 dlg Exp $ */ +/* $OpenBSD: scsiconf.h,v 1.89 2007/11/26 15:40:51 dlg Exp $ */ /* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */ /* @@ -107,6 +107,8 @@ struct scsi_adapter { int (*close_target_lu)(void); int (*ioctl)(struct scsi_link *, u_long, caddr_t, int, struct proc *); + int (*dev_probe)(struct scsi_link *); + void (*dev_free)(struct scsi_link *); }; /* |