summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2006-11-26 09:29:07 +0000
committerdlg <dlg@openbsd.org>2006-11-26 09:29:07 +0000
commit059071676bfa736ffc7a23f957b12afdce141755 (patch)
tree8ceba7803eb1ca34e29b1d22711b1eb9dcbde6b9
parentsync (diff)
downloadwireguard-openbsd-059071676bfa736ffc7a23f957b12afdce141755.tar.xz
wireguard-openbsd-059071676bfa736ffc7a23f957b12afdce141755.zip
provide scsi_detach_bus, _target, and _lun to wrap up config_detach for
scsi devices. the midlayer keeps some state for each device that is attached which needs to be cleaned up on detach, hence this wrapper.
-rw-r--r--sys/scsi/scsiconf.c78
-rw-r--r--sys/scsi/scsiconf.h6
2 files changed, 82 insertions, 2 deletions
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c
index 3028dbe54bf..0725b902ad0 100644
--- a/sys/scsi/scsiconf.c
+++ b/sys/scsi/scsiconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.c,v 1.117 2006/10/21 07:36:15 dlg Exp $ */
+/* $OpenBSD: scsiconf.c,v 1.118 2006/11/26 09:29:07 dlg Exp $ */
/* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */
/*
@@ -297,6 +297,82 @@ scsi_probe_lun(struct scsibus_softc *sc, int target, int lun)
return (scsi_probedev(sc, target, lun));
}
+int
+scsi_detach_bus(struct scsibus_softc *sc, int flags)
+{
+ struct scsi_link *alink = sc->adapter_link;
+ int i, err, rv;
+
+ for (i = 0; i < alink->adapter_buswidth; i++) {
+ if (sc->sc_link[i] == NULL)
+ continue;
+
+ err = scsi_detach_target(sc, i, flags);
+ if (err != 0)
+ rv = err;
+ }
+
+ return (rv);
+}
+
+int
+scsi_detach_target(struct scsibus_softc *sc, int target, int flags)
+{
+ struct scsi_link *alink = sc->adapter_link;
+ int i, err, rv;
+
+ if (target < 0 || target >= alink->adapter_buswidth ||
+ target == alink->adapter_target)
+ return (ENXIO);
+
+ for (i = 0; i < alink->luns; i++) { /* nicer backwards? */
+ if (sc->sc_link[target][i] == NULL)
+ continue;
+
+ err = scsi_detach_lun(sc, target, i, flags);
+ if (err != 0)
+ rv = err;
+ }
+
+ return (rv);
+}
+
+int
+scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags)
+{
+ struct scsi_link *alink = sc->adapter_link;
+ struct scsi_link *link;
+ int rv;
+
+ if (target < 0 || target >= alink->adapter_buswidth ||
+ target == alink->adapter_target ||
+ lun < 0 || lun >= alink->luns)
+ return (ENXIO);
+
+ if (sc->sc_link[target] == NULL)
+ return (ENXIO);
+
+ link = sc->sc_link[target][lun];
+ if (link == NULL)
+ return (ENXIO);
+
+ if (((flags & DETACH_FORCE) == 0) && link->flags & SDEV_OPEN)
+ return (EBUSY);
+
+ /* detaching a device from scsibus is a two 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 */
+ free(link, M_DEVBUF);
+ sc->sc_link[target][lun] = NULL;
+
+ return (0);
+}
+
void
scsi_strvis(u_char *dst, u_char *src, int len)
{
diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h
index ffdf1d49a9a..143226f6204 100644
--- a/sys/scsi/scsiconf.h
+++ b/sys/scsi/scsiconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.h,v 1.76 2006/10/21 07:36:15 dlg Exp $ */
+/* $OpenBSD: scsiconf.h,v 1.77 2006/11/26 09:29:07 dlg Exp $ */
/* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */
/*
@@ -350,6 +350,10 @@ int scsi_probe_bus(struct scsibus_softc *);
int scsi_probe_target(struct scsibus_softc *, int);
int scsi_probe_lun(struct scsibus_softc *, int, int);
+int scsi_detach_bus(struct scsibus_softc *, int);
+int scsi_detach_target(struct scsibus_softc *, int, int);
+int scsi_detach_lun(struct scsibus_softc *, int, int, int);
+
static __inline void _lto2b(u_int32_t val, u_int8_t *bytes);
static __inline void _lto3b(u_int32_t val, u_int8_t *bytes);
static __inline void _lto4b(u_int32_t val, u_int8_t *bytes);