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])