The patch below adds two functions, scsi_get_link() and
scsi_set_link(), for accessing and manipulating the scsibus sc_link
field.  Additionally, it updates all uses of sc_link to instead
utilize these functions.

A subsequent patch will replace the sc_link multi-dimensional array
with a more compact data structure to save memory on device-sparse
SCSI buses.

Index: dev/atapiscsi/atapiscsi.c
===================================================================
RCS file: /cvs/src/sys/dev/atapiscsi/atapiscsi.c,v
retrieving revision 1.89
diff -u -p dev/atapiscsi/atapiscsi.c
--- dev/atapiscsi/atapiscsi.c   20 May 2010 00:55:17 -0000      1.89
+++ dev/atapiscsi/atapiscsi.c   3 Jun 2010 20:28:31 -0000
@@ -294,7 +294,7 @@ atapiscsi_attach(parent, self, aux)
 
        if (child != NULL) {
                struct scsibus_softc *scsi = (struct scsibus_softc *)child;
-               struct scsi_link *link = scsi->sc_link[0][0];
+               struct scsi_link *link = scsi_get_link(scsi, 0, 0);
 
                if (link) {
                        strlcpy(drvp->drive_name,
Index: dev/ic/ami.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ami.c,v
retrieving revision 1.205
diff -u -p dev/ic/ami.c
--- dev/ic/ami.c        3 Jun 2010 12:04:39 -0000       1.205
+++ dev/ic/ami.c        3 Jun 2010 20:28:31 -0000
@@ -2492,6 +2492,7 @@ ami_create_sensors(struct ami_softc *sc)
 {
        struct device *dev;
        struct scsibus_softc *ssc = NULL;
+       struct scsi_link *link;
        int i;
 
        TAILQ_FOREACH(dev, &alldevs, dv_list) {
@@ -2516,10 +2517,11 @@ ami_create_sensors(struct ami_softc *sc)
            sizeof(sc->sc_sensordev.xname));
 
        for (i = 0; i < sc->sc_nunits; i++) {
-               if (ssc->sc_link[i][0] == NULL)
+               link = scsi_get_link(ssc, i, 0);
+               if (link == NULL)
                        goto bad;
 
-               dev = ssc->sc_link[i][0]->device_softc;
+               dev = link->device_softc;
 
                sc->sc_sensors[i].type = SENSOR_DRIVE;
                sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
Index: dev/ic/cac.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/cac.c,v
retrieving revision 1.38
diff -u -p dev/ic/cac.c
--- dev/ic/cac.c        20 May 2010 00:55:17 -0000      1.38
+++ dev/ic/cac.c        3 Jun 2010 20:28:31 -0000
@@ -891,6 +891,7 @@ cac_create_sensors(struct cac_softc *sc)
 {
        struct device *dev;
        struct scsibus_softc *ssc = NULL;
+       struct scsi_link *link;
        int i;
 
        TAILQ_FOREACH(dev, &alldevs, dv_list) {
@@ -916,10 +917,11 @@ cac_create_sensors(struct cac_softc *sc)
            sizeof(sc->sc_sensordev.xname));
 
        for (i = 0; i < sc->sc_nunits; i++) {
-               if (ssc->sc_link[i][0] == NULL)
+               link = scsi_get_link(ssc, i, 0);
+               if (link == NULL)
                        goto bad;
 
-               dev = ssc->sc_link[i][0]->device_softc;
+               dev = link->device_softc;
 
                sc->sc_sensors[i].type = SENSOR_DRIVE;
                sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
Index: dev/ic/ciss.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/ciss.c,v
retrieving revision 1.54
diff -u -p dev/ic/ciss.c
--- dev/ic/ciss.c       3 Jun 2010 01:03:55 -0000       1.54
+++ dev/ic/ciss.c       3 Jun 2010 20:28:31 -0000
@@ -146,6 +146,7 @@ ciss_attach(struct ciss_softc *sc)
        struct ciss_ccb *ccb;
        struct ciss_cmd *cmd;
        struct ciss_inquiry *inq;
+       struct device *dev;
        bus_dma_segment_t seg[1];
        int error, i, total, rseg, maxfer;
        ciss_lock_t lock;
@@ -407,11 +408,10 @@ ciss_attach(struct ciss_softc *sc)
                    sensor_attach(&sc->sensordev, &sc->sensors[i++])) {
                        sc->sensors[i].type = SENSOR_DRIVE;
                        sc->sensors[i].status = SENSOR_S_UNKNOWN;
-                       strlcpy(sc->sensors[i].desc, ((struct device *)
-                           scsibus->sc_link[i][0]->device_softc)->dv_xname,
+                       dev = scsi_get_link(scsibus, i, 0)->device_softc;
+                       strlcpy(sc->sensors[i].desc, dev->dv_xname,
                            sizeof(sc->sensors[i].desc));
-                       strlcpy(sc->sc_lds[i]->xname, ((struct device *)
-                           scsibus->sc_link[i][0]->device_softc)->dv_xname,
+                       strlcpy(sc->sc_lds[i]->xname, dev->dv_xname,
                            sizeof(sc->sc_lds[i]->xname));
                }
                if (sensor_task_register(sc, ciss_sensors, 10) == NULL)
Index: dev/ic/mfi.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/mfi.c,v
retrieving revision 1.105
diff -u -p dev/ic/mfi.c
--- dev/ic/mfi.c        20 May 2010 00:55:17 -0000      1.105
+++ dev/ic/mfi.c        3 Jun 2010 20:28:31 -0000
@@ -1900,6 +1900,7 @@ mfi_create_sensors(struct mfi_softc *sc)
 {
        struct device           *dev;
        struct scsibus_softc    *ssc = NULL;
+       struct scsi_link        *link;
        int                     i;
 
        TAILQ_FOREACH(dev, &alldevs, dv_list) {
@@ -1924,10 +1925,11 @@ mfi_create_sensors(struct mfi_softc *sc)
            sizeof(sc->sc_sensordev.xname));
 
        for (i = 0; i < sc->sc_ld_cnt; i++) {
-               if (ssc->sc_link[i][0] == NULL)
+               link = scsi_get_link(ssc, i, 0);
+               if (link == NULL)
                        goto bad;
 
-               dev = ssc->sc_link[i][0]->device_softc;
+               dev = link->device_softc;
 
                sc->sc_sensors[i].type = SENSOR_DRIVE;
                sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
Index: dev/ic/mpi.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/mpi.c,v
retrieving revision 1.149
diff -u -p dev/ic/mpi.c
--- dev/ic/mpi.c        19 May 2010 07:26:01 -0000      1.149
+++ dev/ic/mpi.c        3 Jun 2010 20:28:31 -0000
@@ -462,7 +462,7 @@ mpi_run_ppr(struct mpi_softc *sc)
        }
 
        for (i = 0; i < sc->sc_buswidth; i++) {
-               link = sc->sc_scsibus->sc_link[i][0];
+               link = scsi_get_link(sc->sc_scsibus, i, 0);
                if (link == NULL)
                        continue;
 
@@ -2465,7 +2465,7 @@ mpi_get_raid(struct mpi_softc *sc)
                if (vol->vol_ioc != sc->sc_ioc_number || vol->vol_bus != 0)
                        continue;
 
-               link = sc->sc_scsibus->sc_link[vol->vol_id][0];
+               link = scsi_get_link(sc->sc_scsibus, vol->vol_id, 0);
                if (link == NULL)
                        continue;
 
@@ -3008,7 +3008,7 @@ mpi_ioctl_vol(struct mpi_softc *sc, struct bioc_vol *b
        bv->bv_nodisk = rpg0->num_phys_disks;
 
        for (i = 0, vol = -1; i < sc->sc_buswidth; i++) {
-               link = sc->sc_scsibus->sc_link[i][0];
+               link = scsi_get_link(sc->sc_scsibus, i, 0);
                if (link == NULL)
                        continue;
 
@@ -3121,7 +3121,7 @@ mpi_create_sensors(struct mpi_softc *sc)
 
        /* count volumes */
        for (i = 0, vol = 0; i < sc->sc_buswidth; i++) {
-               link = sc->sc_scsibus->sc_link[i][0];
+               link = scsi_get_link(sc->sc_scsibus, i, 0);
                if (link == NULL)
                        continue;
                /* skip if not a virtual disk */
@@ -3142,7 +3142,7 @@ mpi_create_sensors(struct mpi_softc *sc)
            sizeof(sc->sc_sensordev.xname));
 
        for (i = 0, vol= 0; i < sc->sc_buswidth; i++) {
-               link = sc->sc_scsibus->sc_link[i][0];
+               link = scsi_get_link(sc->sc_scsibus, i, 0);
                if (link == NULL)
                        continue;
                /* skip if not a virtual disk */
@@ -3182,7 +3182,7 @@ mpi_refresh_sensors(void *arg)
        rw_enter_write(&sc->sc_lock);
 
        for (i = 0, vol = 0; i < sc->sc_buswidth; i++) {
-               link = sc->sc_scsibus->sc_link[i][0];
+               link = scsi_get_link(sc->sc_scsibus, i, 0);
                if (link == NULL)
                        continue;
                /* skip if not a virtual disk */
Index: dev/pci/arc.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/arc.c,v
retrieving revision 1.84
diff -u -p dev/pci/arc.c
--- dev/pci/arc.c       20 May 2010 00:55:17 -0000      1.84
+++ dev/pci/arc.c       3 Jun 2010 20:28:31 -0000
@@ -1346,8 +1346,8 @@ arc_bio_vol(struct arc_softc *sc, struct bioc_vol *bv)
        }
 
        bv->bv_nodisk = volinfo->member_disks;
-       sc_link = sc->sc_scsibus->sc_link[volinfo->scsi_attr.target]
-           [volinfo->scsi_attr.lun];
+       sc_link = scsi_get_link(sc->sc_scsibus, volinfo->scsi_attr.target,
+           volinfo->scsi_attr.lun);
        if (sc_link != NULL) {
                dev = sc_link->device_softc;
                strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev));
Index: dev/pci/ips.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/ips.c,v
retrieving revision 1.97
diff -u -p dev/pci/ips.c
--- dev/pci/ips.c       20 May 2010 00:55:17 -0000      1.97
+++ dev/pci/ips.c       3 Jun 2010 20:28:31 -0000
@@ -608,6 +608,7 @@ ips_attach(struct device *parent, struct device *self,
        struct ips_adapterinfo *ai;
        struct ips_driveinfo *di;
        struct ips_pg5 *pg5;
+       struct device *dev;
        pcireg_t maptype;
        bus_size_t iosize;
        pci_intr_handle_t ih;
@@ -817,8 +818,8 @@ ips_attach(struct device *parent, struct device *self,
        for (i = 0; i < sc->sc_nunits; i++) {
                sc->sc_sensors[i].type = SENSOR_DRIVE;
                sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
-               strlcpy(sc->sc_sensors[i].desc, ((struct device *)
-                   sc->sc_scsibus->sc_link[i][0]->device_softc)->dv_xname,
+               dev = scsi_get_link(sc->sc_scsibus, i, 0)->device_softc;
+               strlcpy(sc->sc_sensors[i].desc, dev->dv_xname,
                    sizeof(sc->sc_sensors[i].desc));
                sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
        }
@@ -1212,7 +1213,7 @@ ips_ioctl_vol(struct ips_softc *sc, struct bioc_vol *b
                        }
        }
 
-       dv = sc->sc_scsibus->sc_link[vid][0]->device_softc;
+       dv = scsi_get_link(sc->sc_scsibus, vid, 0)->device_softc;
        strlcpy(bv->bv_dev, dv->dv_xname, sizeof(bv->bv_dev));
        strlcpy(bv->bv_vendor, "IBM", sizeof(bv->bv_vendor));
 
Index: dev/pci/mpii.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/mpii.c,v
retrieving revision 1.19
diff -u -p dev/pci/mpii.c
--- dev/pci/mpii.c      26 May 2010 17:46:31 -0000      1.19
+++ dev/pci/mpii.c      3 Jun 2010 20:28:31 -0000
@@ -4720,7 +4720,7 @@ mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol 
 
        bv->bv_size = letoh64(vpg->max_lba) * letoh16(vpg->block_size);
 
-       lnk = sc->sc_scsibus->sc_link[bv->bv_volid][0];
+       lnk = scsi_get_link(sc->sc_scsibus, bv->bv_volid, 0);
        if (lnk != NULL) {
                scdev = lnk->device_softc;
                strlcpy(bv->bv_dev, scdev->dv_xname, sizeof(bv->bv_dev));
@@ -5026,6 +5026,7 @@ mpii_create_sensors(struct mpii_softc *sc)
 {
        struct scsibus_softc    *ssc = sc->sc_scsibus;
        struct device           *dev;
+       struct scsi_link        *link;
        int                     i;
 
        sc->sc_sensors = malloc(sizeof(struct ksensor) * sc->sc_vd_count,
@@ -5039,10 +5040,11 @@ mpii_create_sensors(struct mpii_softc *sc)
 
        for (i = sc->sc_vd_id_low; i < sc->sc_vd_id_low + sc->sc_vd_count;
             i++) {
-               if (ssc->sc_link[i][0] == NULL)
+               link = scsi_get_link(ssc, i, 0);
+               if (link == NULL)
                        goto bad;
 
-               dev = ssc->sc_link[i][0]->device_softc;
+               dev = link->device_softc;
 
                sc->sc_sensors[i].type = SENSOR_DRIVE;
                sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
Index: scsi/scsiconf.c
===================================================================
RCS file: /cvs/src/sys/scsi/scsiconf.c,v
retrieving revision 1.157
diff -u -p scsi/scsiconf.c
--- scsi/scsiconf.c     23 Apr 2010 21:34:40 -0000      1.157
+++ scsi/scsiconf.c     3 Jun 2010 20:28:31 -0000
@@ -247,9 +247,10 @@ scsi_activate_target(struct scsibus_softc *sc, int tar
 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;
 
@@ -390,7 +391,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);
 
@@ -423,9 +424,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_set_link(sc, target, 0, NULL);
                        scsi_probe_lun(sc, target, lun);
-                       sc->sc_link[target][0] = link;
+                       scsi_set_link(sc, target, 0, link);
                }
 
                free(report, M_TEMP);
@@ -479,11 +480,8 @@ scsi_detach_target(struct scsibus_softc *sc, int targe
            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);
@@ -506,10 +504,7 @@ scsi_detach_lun(struct scsibus_softc *sc, int target, 
            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 +536,25 @@ scsi_detach_lun(struct scsibus_softc *sc, int target, 
        if (link->id != NULL)
                devid_free(link->id);
        free(link, M_DEVBUF);
-       sc->sc_link[target][lun] = NULL;
+       scsi_set_link(sc, target, lun, NULL);
 
        return (0);
 }
 
+struct scsi_link *
+scsi_get_link(struct scsibus_softc *sc, int target, int lun)
+{
+       return (sc->sc_link[target][lun]);
+}
+
 void
+scsi_set_link(struct scsibus_softc *sc, int target, int lun, 
+    struct scsi_link *link)
+{
+       sc->sc_link[target][lun] = link;
+}
+
+void
 scsi_strvis(u_char *dst, u_char *src, int len)
 {
        u_char                          last;
@@ -845,12 +853,12 @@ scsi_probedev(struct scsibus_softc *scsi, int target, 
        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);
@@ -947,15 +955,14 @@ scsi_probedev(struct scsibus_softc *scsi, int target, 
 
        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;
@@ -969,7 +976,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, 
                scsibus_printlink(sc_link);
                printf("\n");
 
-               scsi->sc_link[target][lun] = sc_link;
+               scsi_set_link(scsi, target, lun, sc_link);
                return (0);
        }
 #endif /* NMPATH */
@@ -1023,7 +1030,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, 
         * 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;
@@ -1031,7 +1038,7 @@ scsi_probedev(struct scsibus_softc *scsi, int target, 
                sc_link->lun = 0;
        }
 
-       scsi->sc_link[target][lun] = sc_link;
+       scsi_set_link(scsi, target, lun, sc_link);
 
        /*
         * Generate a TEST_UNIT_READY command. This gives drivers waiting for
Index: scsi/scsiconf.h
===================================================================
RCS file: /cvs/src/sys/scsi/scsiconf.h,v
retrieving revision 1.125
diff -u -p scsi/scsiconf.h
--- scsi/scsiconf.h     24 May 2010 06:57:09 -0000      1.125
+++ scsi/scsiconf.h     3 Jun 2010 20:28:31 -0000
@@ -623,6 +623,10 @@ int        scsi_req_detach(struct scsibus_softc *, int, 
int, 
 
 void   scsi_activate(struct scsibus_softc *, int, int, int);
 
+struct scsi_link *     scsi_get_link(struct scsibus_softc *, int, int);
+void                   scsi_set_link(struct scsibus_softc *, int, int,
+                           struct scsi_link *);
+
 extern const u_int8_t version_to_spc[];
 #define SCSISPC(x)(version_to_spc[(x) & SID_ANSII])

Reply via email to