summaryrefslogtreecommitdiff
path: root/sys/scsi/scsiconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/scsi/scsiconf.c')
-rw-r--r--sys/scsi/scsiconf.c87
1 files changed, 45 insertions, 42 deletions
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c
index 740f4f1e61e..8c3c53d25a9 100644
--- a/sys/scsi/scsiconf.c
+++ b/sys/scsi/scsiconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scsiconf.c,v 1.159 2010/06/30 19:23:59 deraadt Exp $ */
+/* $OpenBSD: scsiconf.c,v 1.160 2010/07/01 03:20:39 matthew Exp $ */
/* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */
/*
@@ -155,7 +155,6 @@ scsibusattach(struct device *parent, struct device *self, void *aux)
struct scsibus_softc *sb = (struct scsibus_softc *)self;
struct scsibus_attach_args *saa = aux;
struct scsi_link *sc_link_proto = saa->saa_sc_link;
- int nbytes, i;
if (!cold)
scsi_autoconf = 0;
@@ -182,16 +181,7 @@ scsibusattach(struct device *parent, struct device *self, void *aux)
/* Initialize shared data. */
scsi_init();
- nbytes = sb->sc_buswidth * sizeof(struct scsi_link **);
- sb->sc_link = malloc(nbytes, M_DEVBUF, M_NOWAIT);
- if (sb->sc_link == NULL)
- panic("scsibusattach: can't allocate target links");
- nbytes = sb->adapter_link->luns * sizeof(struct scsi_link *);
- for (i = 0; i < sb->sc_buswidth; i++) {
- sb->sc_link[i] = malloc(nbytes, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (sb->sc_link[i] == NULL)
- panic("scsibusattach: can't allocate lun links");
- }
+ SLIST_INIT(&sb->sc_link);
#if NBIO > 0
if (bio_register(&sb->sc_dev, scsibus_bioctl) != 0)
@@ -247,9 +237,10 @@ scsi_activate_target(struct scsibus_softc *sc, int target, int act)
void
scsi_activate_lun(struct scsibus_softc *sc, int target, int lun, int act)
{
- struct scsi_link *link = sc->sc_link[target][lun];
+ struct scsi_link *link;
struct device *dev;
+ link = scsi_get_link(sc, target, lun);
if (link == NULL)
return;
@@ -287,7 +278,7 @@ int
scsibusdetach(struct device *dev, int type)
{
struct scsibus_softc *sb = (struct scsibus_softc *)dev;
- int i, error;
+ int error;
#if NBIO > 0
bio_unregister(&sb->sc_dev);
@@ -297,12 +288,7 @@ scsibusdetach(struct device *dev, int type)
if (error != 0)
return (error);
- for (i = 0; i < sb->sc_buswidth; i++) {
- if (sb->sc_link[i] != NULL)
- free(sb->sc_link[i], M_DEVBUF);
- }
-
- free(sb->sc_link, M_DEVBUF);
+ KASSERT(SLIST_EMPTY(&sb->sc_link));
/* Free shared data. */
scsi_deinit();
@@ -391,7 +377,7 @@ scsi_probe_target(struct scsibus_softc *sc, int target)
if (scsi_probe_lun(sc, target, 0) == EINVAL)
return (EINVAL);
- link = sc->sc_link[target][0];
+ link = scsi_get_link(sc, target, 0);
if (link == NULL)
return (ENXIO);
@@ -424,9 +410,9 @@ scsi_probe_target(struct scsibus_softc *sc, int target)
continue;
/* Probe the provided LUN. Don't check LUN 0. */
- sc->sc_link[target][0] = NULL;
+ scsi_remove_link(sc, link);
scsi_probe_lun(sc, target, lun);
- sc->sc_link[target][0] = link;
+ scsi_add_link(sc, link);
}
free(report, M_TEMP);
@@ -480,11 +466,8 @@ scsi_detach_target(struct scsibus_softc *sc, int target, int flags)
target == alink->adapter_target)
return (ENXIO);
- if (sc->sc_link[target] == NULL)
- return (ENXIO);
-
for (i = 0; i < alink->luns; i++) { /* nicer backwards? */
- if (sc->sc_link[target][i] == NULL)
+ if (scsi_get_link(sc, target, i) == NULL)
continue;
err = scsi_detach_lun(sc, target, i, flags);
@@ -507,10 +490,7 @@ scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags)
lun < 0 || lun >= alink->luns)
return (ENXIO);
- if (sc->sc_link[target] == NULL)
- return (ENXIO);
-
- link = sc->sc_link[target][lun];
+ link = scsi_get_link(sc, target, lun);
if (link == NULL)
return (ENXIO);
@@ -541,12 +521,36 @@ scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags)
/* 4. free up its state in the midlayer */
if (link->id != NULL)
devid_free(link->id);
+ scsi_remove_link(sc, link);
free(link, M_DEVBUF);
- sc->sc_link[target][lun] = NULL;
return (0);
}
+struct scsi_link *
+scsi_get_link(struct scsibus_softc *sc, int target, int lun)
+{
+ struct scsi_link *link;
+
+ SLIST_FOREACH(link, &sc->sc_link, bus_list)
+ if (link->target == target && link->lun == lun)
+ return (link);
+
+ return (NULL);
+}
+
+void
+scsi_add_link(struct scsibus_softc *sc, struct scsi_link *link)
+{
+ SLIST_INSERT_HEAD(&sc->sc_link, link, bus_list);
+}
+
+void
+scsi_remove_link(struct scsibus_softc *sc, struct scsi_link *link)
+{
+ SLIST_REMOVE(&sc->sc_link, link, scsi_link, bus_list);
+}
+
void
scsi_strvis(u_char *dst, u_char *src, int len)
{
@@ -846,12 +850,12 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
const struct scsi_quirk_inquiry_pattern *finger;
struct scsi_inquiry_data *inqbuf;
struct scsi_attach_args sa;
- struct scsi_link *sc_link;
+ struct scsi_link *sc_link, *link0;
struct cfdata *cf;
int priority, rslt = 0;
/* Skip this slot if it is already attached and try the next LUN. */
- if (scsi->sc_link[target][lun] != NULL)
+ if (scsi_get_link(scsi, target, lun) != NULL)
return (0);
sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
@@ -948,15 +952,14 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
scsi_devid(sc_link);
- if (lun == 0 || scsi->sc_link[target][0] == NULL)
+ link0 = scsi_get_link(scsi, target, 0);
+ if (lun == 0 || link0 == NULL)
;
else if (sc_link->flags & SDEV_UMASS)
;
- else if (sc_link->id != NULL &&
- !DEVID_CMP(scsi->sc_link[target][0]->id, sc_link->id))
+ else if (sc_link->id != NULL && !DEVID_CMP(link0->id, sc_link->id))
;
- else if (memcmp(inqbuf, &scsi->sc_link[target][0]->inqdata,
- sizeof(*inqbuf)) == 0) {
+ else if (memcmp(inqbuf, &link0->inqdata, sizeof(*inqbuf)) == 0) {
/* The device doesn't distinguish between LUNs. */
SC_DEBUG(sc_link, SDEV_DB1, ("IDENTIFY not supported.\n"));
rslt = EINVAL;
@@ -970,7 +973,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
scsibus_printlink(sc_link);
printf("\n");
- scsi->sc_link[target][lun] = sc_link;
+ scsi_add_link(scsi, sc_link);
return (0);
}
#endif /* NMPATH */
@@ -1024,7 +1027,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
* point to prevent such helpfulness before it causes confusion.
*/
if (lun == 0 && (sc_link->flags & SDEV_UMASS) &&
- scsi->sc_link[target][1] == NULL && sc_link->luns > 1) {
+ scsi_get_link(scsi, target, 1) == NULL && sc_link->luns > 1) {
struct scsi_inquiry_data tmpinq;
sc_link->lun = 1;
@@ -1032,7 +1035,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
sc_link->lun = 0;
}
- scsi->sc_link[target][lun] = sc_link;
+ scsi_add_link(scsi, sc_link);
/*
* Generate a TEST_UNIT_READY command. This gives drivers waiting for