summaryrefslogtreecommitdiff
path: root/sys/scsi
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2007-11-26 15:40:52 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2007-11-26 15:40:52 +0000
commit2780a6859a5af847650e39067a3525e9216c46a8 (patch)
tree09912dff9c56754127039e83724d81375f705ede /sys/scsi
parent61b591d4724fe059ead2ae8a9d2c63137083b0e6 (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.c21
-rw-r--r--sys/scsi/scsiconf.h4
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 *);
};
/*