diff options
author | 2020-08-09 13:29:08 +0000 | |
---|---|---|
committer | 2020-08-09 13:29:08 +0000 | |
commit | 14832242cc36bec14cb1b6aee4fb4964b850367d (patch) | |
tree | 2fd114e0a6c8e00008f135ba2e39047fc50819f1 | |
parent | Remove now unused M_ACAST flag. (diff) | |
download | wireguard-openbsd-14832242cc36bec14cb1b6aee4fb4964b850367d.tar.xz wireguard-openbsd-14832242cc36bec14cb1b6aee4fb4964b850367d.zip |
Shuffle functions and declarations around to more logical grouping. Nuke some
leading whitespace. Rename some local functions.
-rw-r--r-- | sys/scsi/scsiconf.c | 763 |
1 files changed, 379 insertions, 384 deletions
diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index bf07b7416cb..d08ea785e78 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.c,v 1.230 2020/08/08 13:08:23 krw Exp $ */ +/* $OpenBSD: scsiconf.c,v 1.231 2020/08/09 13:29:08 krw Exp $ */ /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ /* @@ -67,13 +67,11 @@ #include <dev/biovar.h> #endif /* NBIO > 0 */ -/* - * Declarations - */ void scsi_get_target_luns(struct scsi_link *, struct scsi_lun_array *); -int scsi_probedev(struct scsibus_softc *, int, int, int); void scsi_add_link(struct scsi_link *); void scsi_remove_link(struct scsi_link *); +void scsi_print_link(struct scsi_link *); +int scsi_probe_link(struct scsibus_softc *, int, int, int); int scsi_activate_link(struct scsi_link *, int); int scsi_detach_link(struct scsi_link *, int); @@ -86,13 +84,19 @@ int scsibusmatch(struct device *, void *, void *); void scsibusattach(struct device *, struct device *, void *); int scsibusactivate(struct device *, int); int scsibusdetach(struct device *, int); - int scsibussubmatch(struct device *, void *, void *); +int scsibusprint(void *, const char *); + +int scsi_activate_bus(struct scsibus_softc *, int); +int scsi_activate_target(struct scsibus_softc *, int, int); +int scsi_activate_lun(struct scsibus_softc *, int, int, int); #if NBIO > 0 int scsibus_bioctl(struct device *, u_long, caddr_t); #endif /* NBIO > 0 */ +int scsi_autoconf = SCSI_AUTOCONF; + struct cfattach scsibus_ca = { sizeof(struct scsibus_softc), scsibusmatch, scsibusattach, scsibusdetach, scsibusactivate @@ -102,14 +106,84 @@ struct cfdriver scsibus_cd = { NULL, "scsibus", DV_DULL }; -int scsi_autoconf = SCSI_AUTOCONF; +struct scsi_quirk_inquiry_pattern { + struct scsi_inquiry_pattern pattern; + u_int16_t quirks; +}; -int scsibusprint(void *, const char *); -void scsibus_printlink(struct scsi_link *); +const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = { + {{T_CDROM, T_REMOV, + "PLEXTOR", "CD-ROM PX-40TS", "1.01"}, SDEV_NOSYNC}, -int scsi_activate_bus(struct scsibus_softc *, int); -int scsi_activate_target(struct scsibus_softc *, int, int); -int scsi_activate_lun(struct scsibus_softc *, int, int, int); + {{T_DIRECT, T_FIXED, + "MICROP ", "1588-15MBSUN0669", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "DEC ", "RZ55 (C) DEC", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "EMULEX ", "MD21/S2 ESDI", "A00"}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "IBMRAID ", "0662S", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "IBM ", "0663H", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "IBM", "0664", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "IBM ", "H3171-S2", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "IBM ", "KZ-C", ""}, SDEV_AUTOSAVE}, + /* Broken IBM disk */ + {{T_DIRECT, T_FIXED, + "" , "DFRSS2F", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_FIXED, + "QUANTUM ", "ELS85S ", ""}, SDEV_AUTOSAVE}, + {{T_DIRECT, T_REMOV, + "iomega", "jaz 1GB", ""}, SDEV_NOTAGS}, + {{T_DIRECT, T_FIXED, + "MICROP", "4421-07", ""}, SDEV_NOTAGS}, + {{T_DIRECT, T_FIXED, + "SEAGATE", "ST150176LW", "0002"}, SDEV_NOTAGS}, + {{T_DIRECT, T_FIXED, + "HP", "C3725S", ""}, SDEV_NOTAGS}, + {{T_DIRECT, T_FIXED, + "IBM", "DCAS", ""}, SDEV_NOTAGS}, + + {{T_SEQUENTIAL, T_REMOV, + "SONY ", "SDT-5000 ", "3."}, SDEV_NOSYNC|SDEV_NOWIDE}, + {{T_SEQUENTIAL, T_REMOV, + "WangDAT ", "Model 1300 ", "02.4"}, SDEV_NOSYNC|SDEV_NOWIDE}, + {{T_SEQUENTIAL, T_REMOV, + "WangDAT ", "Model 2600 ", "01.7"}, SDEV_NOSYNC|SDEV_NOWIDE}, + {{T_SEQUENTIAL, T_REMOV, + "WangDAT ", "Model 3200 ", "02.2"}, SDEV_NOSYNC|SDEV_NOWIDE}, + + /* ATAPI device quirks */ + {{T_CDROM, T_REMOV, + "CR-2801TE", "", "1.07"}, ADEV_NOSENSE}, + {{T_CDROM, T_REMOV, + "CREATIVECD3630E", "", "AC101"}, ADEV_NOSENSE}, + {{T_CDROM, T_REMOV, + "FX320S", "", "q01"}, ADEV_NOSENSE}, + {{T_CDROM, T_REMOV, + "GCD-R580B", "", "1.00"}, ADEV_LITTLETOC}, + {{T_CDROM, T_REMOV, + "MATSHITA CR-574", "", "1.02"}, ADEV_NOCAPACITY}, + {{T_CDROM, T_REMOV, + "MATSHITA CR-574", "", "1.06"}, ADEV_NOCAPACITY}, + {{T_CDROM, T_REMOV, + "Memorex CRW-2642", "", "1.0g"}, ADEV_NOSENSE}, + {{T_CDROM, T_REMOV, + "SANYO CRD-256P", "", "1.02"}, ADEV_NOCAPACITY}, + {{T_CDROM, T_REMOV, + "SANYO CRD-254P", "", "1.02"}, ADEV_NOCAPACITY}, + {{T_CDROM, T_REMOV, + "SANYO CRD-S54P", "", "1.08"}, ADEV_NOCAPACITY}, + {{T_CDROM, T_REMOV, + "CD-ROM CDR-S1", "", "1.70"}, ADEV_NOCAPACITY}, /* Sanyo */ + {{T_CDROM, T_REMOV, + "CD-ROM CDR-N16", "", "1.25"}, ADEV_NOCAPACITY}, /* Sanyo */ + {{T_CDROM, T_REMOV, + "UJDCD8730", "", "1.14"}, ADEV_NODOORLOCK}, /* Acer */ +}; int scsiprint(void *aux, const char *pnp) @@ -318,12 +392,6 @@ scsibus_bioctl(struct device *dev, u_long cmd, caddr_t addr) #endif /* NBIO > 0 */ void -scsi_probe_bus(struct scsibus_softc *sb) -{ - scsi_probe(sb, -1, -1); -} - -void scsi_get_target_luns(struct scsi_link *link0, struct scsi_lun_array *lunarray) { struct scsi_report_luns_data *report; @@ -379,16 +447,6 @@ dumbscan: } int -scsi_probe_target(struct scsibus_softc *sb, int target) -{ - /* Wild card target not allowed. */ - if (target == -1) - return EINVAL; - else - return scsi_probe(sb, target, -1); -} - -int scsi_probe(struct scsibus_softc *sb, int target, int lun) { struct scsi_lun_array lunarray; @@ -411,13 +469,13 @@ scsi_probe(struct scsibus_softc *sb, int target, int lun) if (lun == -1) { /* Probe all luns on the target. */ - scsi_probedev(sb, target, 0, 0); + scsi_probe_link(sb, target, 0, 0); link0 = scsi_get_link(sb, target, 0); if (link0 == NULL) return EINVAL; scsi_get_target_luns(link0, &lunarray); for (i = 0; i < lunarray.count; i++) { - r = scsi_probedev(sb, target, lunarray.luns[i], + r = scsi_probe_link(sb, target, lunarray.luns[i], lunarray.dumbscan); if (r == EINVAL && lunarray.dumbscan == 1) return 0; @@ -428,7 +486,23 @@ scsi_probe(struct scsibus_softc *sb, int target, int lun) } /* Probe lun on target. *NOT* a dumbscan! */ - return scsi_probedev(sb, target, lun, 0); + return scsi_probe_link(sb, target, lun, 0); +} + +void +scsi_probe_bus(struct scsibus_softc *sb) +{ + scsi_probe(sb, -1, -1); +} + +int +scsi_probe_target(struct scsibus_softc *sb, int target) +{ + /* Wild card target not allowed. */ + if (target == -1) + return EINVAL; + else + return scsi_probe(sb, target, -1); } int @@ -440,6 +514,280 @@ scsi_probe_lun(struct scsibus_softc *sb, int target, int lun) return scsi_probe(sb, target, lun); } +/* + * Given a target and lun, ask the device what it is, and find the correct + * driver table entry. + * + * Return 0 if further LUNs are possible, EINVAL if not. + */ +int +scsi_probe_link(struct scsibus_softc *sb, int target, int lun, int dumbscan) +{ + struct scsi_attach_args sa; + const struct scsi_quirk_inquiry_pattern *finger; + struct scsi_inquiry_data *inqbuf, *usbinqbuf; + struct scsi_link *link, *link0; + struct cfdata *cf; + int priority, rslt = 0; + u_int16_t devquirks; + + /* Skip this slot if it is already attached and try the next LUN. */ + if (scsi_get_link(sb, target, lun) != NULL) + return 0; + + link = malloc(sizeof(*link), M_DEVBUF, M_NOWAIT); + if (link == NULL) { + SC_DEBUG(link, SDEV_DB2, ("Bad LUN. can't allocate " + "scsi_link.\n")); + return EINVAL; + } + + link->state = 0; + link->target = target; + link->lun = lun; + link->openings = sb->sb_openings; + link->node_wwn = link->port_wwn = 0; + link->flags = sb->sb_flags; + link->quirks = sb->sb_quirks; + link->interpret_sense = scsi_interpret_sense; + link->device_softc = NULL; + link->bus = sb; + memset(&link->inqdata, 0, sizeof(link->inqdata)); + link->id = NULL; + TAILQ_INIT(&link->queue); + link->running = 0; + link->pending = 0; + link->pool = sb->sb_pool; + + SC_DEBUG(link, SDEV_DB2, ("scsi_link created.\n")); + + /* Ask the adapter if this will be a valid device. */ + if (sb->sb_adapter->dev_probe != NULL && + sb->sb_adapter->dev_probe(link) != 0) { + if (lun == 0) { + SC_DEBUG(link, SDEV_DB2, ("Bad LUN 0. dev_probe() " + "failed.\n")); + rslt = EINVAL; + } + goto free; + } + + /* + * If we havent been given an io pool by now then fall back to + * using link->openings. + */ + if (link->pool == NULL) { + link->pool = malloc(sizeof(*link->pool), + M_DEVBUF, M_NOWAIT); + if (link->pool == NULL) { + SC_DEBUG(link, SDEV_DB2, ("Bad LUN. can't allocate " + "link->pool.\n")); + rslt = ENOMEM; + goto bad; + } + scsi_iopool_init(link->pool, link, + scsi_default_get, scsi_default_put); + + SET(link->flags, SDEV_OWN_IOPL); + } + + /* + * Tell drivers that are paying attention to avoid sync/wide/tags until + * INQUIRY data has been processed and the quirks information is + * complete. Some drivers set bits in quirks before we get here, so + * just add NOTAGS, NOWIDE and NOSYNC. + */ + devquirks = link->quirks; + SET(link->quirks, SDEV_NOSYNC | SDEV_NOWIDE | SDEV_NOTAGS); + + /* + * Ask the device what it is. + */ +#ifdef SCSIDEBUG + if (((sb->sc_dev.dv_unit < 32) && + ((1U << sb->sc_dev.dv_unit) & scsidebug_buses)) && + ((target < 32) && ((1U << target) & scsidebug_targets)) && + ((lun < 32) && ((1U << lun) & scsidebug_luns))) + SET(link->flags, scsidebug_level); +#endif /* SCSIDEBUG */ + + if (lun == 0) { + /* Clear any outstanding errors. */ + scsi_test_unit_ready(link, TEST_READY_RETRIES, + scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST | + SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE); + } + + /* Now go ask the device all about itself. */ + inqbuf = dma_alloc(sizeof(*inqbuf), PR_NOWAIT | PR_ZERO); + if (inqbuf == NULL) { + SC_DEBUG(link, SDEV_DB2, ("Bad LUN. can't allocate inqbuf.\n")); + rslt = ENOMEM; + goto bad; + } + + rslt = scsi_inquire(link, inqbuf, scsi_autoconf | SCSI_SILENT); + memcpy(&link->inqdata, inqbuf, sizeof(link->inqdata)); + dma_free(inqbuf, sizeof(*inqbuf)); + + if (rslt != 0) { + if (lun == 0) { + SC_DEBUG(link, SDEV_DB2, ("Bad LUN 0. inquiry rslt = " + "%i\n", rslt)); + rslt = EINVAL; + } + goto bad; + } + inqbuf = &link->inqdata; + + switch (inqbuf->device & SID_QUAL) { + case SID_QUAL_RSVD: + case SID_QUAL_BAD_LU: + case SID_QUAL_LU_OFFLINE: + SC_DEBUG(link, SDEV_DB1, ("Bad LUN. SID_QUAL = 0x%02x\n", + inqbuf->device & SID_QUAL)); + goto bad; + + case SID_QUAL_LU_OK: + break; + + default: + SC_DEBUG(link, SDEV_DB1, ("Vendor-specific SID_QUAL = 0x%02x\n", + inqbuf->device & SID_QUAL)); + break; + } + + if ((inqbuf->device & SID_TYPE) == T_NODEVICE) { + SC_DEBUG(link, SDEV_DB1, + ("Bad LUN. SID_TYPE = T_NODEVICE\n")); + goto bad; + } + + scsi_devid(link); + + link0 = scsi_get_link(sb, target, 0); + if (lun == 0 || link0 == NULL) + ; + else if (ISSET(link->flags, SDEV_UMASS)) + ; + else if (link->id != NULL && !DEVID_CMP(link0->id, link->id)) + ; + else if (dumbscan == 1 && memcmp(inqbuf, &link0->inqdata, + sizeof(*inqbuf)) == 0) { + /* The device doesn't distinguish between LUNs. */ + SC_DEBUG(link, SDEV_DB1, ("Bad LUN. IDENTIFY not supported." + "\n")); + rslt = EINVAL; + goto free_devid; + } + + link->quirks = devquirks; /* Restore what the device wanted. */ + + finger = (const struct scsi_quirk_inquiry_pattern *)scsi_inqmatch( + inqbuf, scsi_quirk_patterns, + nitems(scsi_quirk_patterns), + sizeof(scsi_quirk_patterns[0]), &priority); + if (priority != 0) + SET(link->quirks, finger->quirks); + + switch (SID_ANSII_REV(inqbuf)) { + case SCSI_REV_0: + case SCSI_REV_1: + SET(link->quirks, SDEV_NOTAGS | SDEV_NOSYNC | SDEV_NOWIDE | + SDEV_NOSYNCCACHE); + break; + case SCSI_REV_2: + case SCSI_REV_SPC: + case SCSI_REV_SPC2: + if (!ISSET(inqbuf->flags, SID_CmdQue)) + SET(link->quirks, SDEV_NOTAGS); + if (!ISSET(inqbuf->flags, SID_Sync)) + SET(link->quirks, SDEV_NOSYNC); + if (!ISSET(inqbuf->flags, SID_WBus16)) + SET(link->quirks, SDEV_NOWIDE); + break; + case SCSI_REV_SPC3: + case SCSI_REV_SPC4: + case SCSI_REV_SPC5: + /* By this time SID_Sync and SID_WBus16 were obsolete. */ + if (!ISSET(inqbuf->flags, SID_CmdQue)) + SET(link->quirks, SDEV_NOTAGS); + break; + default: + break; + } + + /* + * If the device can't use tags, >1 opening may confuse it. + */ + if (ISSET(link->quirks, SDEV_NOTAGS)) + link->openings = 1; + + /* + * note what BASIC type of device it is + */ + if (ISSET(inqbuf->dev_qual2, SID_REMOVABLE)) + SET(link->flags, SDEV_REMOVABLE); + + sa.sa_sc_link = link; + + if ((cf = config_search(scsibussubmatch, (struct device *)sb, + &sa)) == 0) { + scsibusprint(&sa, sb->sc_dev.dv_xname); + printf(" not configured\n"); + goto free_devid; + } + + /* + * Braindead USB devices, especially some x-in-1 media readers, try to + * 'help' by pretending any LUN is actually LUN 0 until they see a + * different LUN used in a command. So do an INQUIRY on LUN 1 at this + * point to prevent such helpfulness before it causes confusion. + */ + if (lun == 0 && ISSET(link->flags, SDEV_UMASS) && + scsi_get_link(sb, target, 1) == NULL && sb->sb_luns > 1 && + (usbinqbuf = dma_alloc(sizeof(*usbinqbuf), M_NOWAIT)) != NULL) { + + link->lun = 1; + scsi_inquire(link, usbinqbuf, scsi_autoconf | SCSI_SILENT); + link->lun = 0; + + dma_free(usbinqbuf, sizeof(*usbinqbuf)); + } + + scsi_add_link(link); + + /* + * Generate a TEST_UNIT_READY command. This gives drivers waiting for + * valid quirks data a chance to set wide/sync/tag options + * appropriately. It also clears any outstanding ACA conditions that + * INQUIRY may leave behind. + * + * Do this now so that any messages generated by config_attach() do not + * have negotiation messages inserted into their midst. + */ + scsi_test_unit_ready(link, TEST_READY_RETRIES, + scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST | + SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE); + + config_attach((struct device *)sb, cf, &sa, scsibusprint); + + return 0; + +free_devid: + if (link->id) + devid_free(link->id); +bad: + if (ISSET(link->flags, SDEV_OWN_IOPL)) + free(link->pool, M_DEVBUF, sizeof(*link->pool)); + + if (sb->sb_adapter->dev_free != NULL) + sb->sb_adapter->dev_free(link); +free: + free(link, M_DEVBUF, sizeof(*link)); + return rslt; +} + int scsi_detach(struct scsibus_softc *sb, int target, int lun, int flags) { @@ -617,85 +965,6 @@ scsi_strvis(u_char *dst, u_char *src, int len) *dst++ = 0; } -struct scsi_quirk_inquiry_pattern { - struct scsi_inquiry_pattern pattern; - u_int16_t quirks; -}; - -const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = { - {{T_CDROM, T_REMOV, - "PLEXTOR", "CD-ROM PX-40TS", "1.01"}, SDEV_NOSYNC}, - - {{T_DIRECT, T_FIXED, - "MICROP ", "1588-15MBSUN0669", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "DEC ", "RZ55 (C) DEC", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "EMULEX ", "MD21/S2 ESDI", "A00"}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "IBMRAID ", "0662S", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "IBM ", "0663H", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "IBM", "0664", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "IBM ", "H3171-S2", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "IBM ", "KZ-C", ""}, SDEV_AUTOSAVE}, - /* Broken IBM disk */ - {{T_DIRECT, T_FIXED, - "" , "DFRSS2F", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_FIXED, - "QUANTUM ", "ELS85S ", ""}, SDEV_AUTOSAVE}, - {{T_DIRECT, T_REMOV, - "iomega", "jaz 1GB", ""}, SDEV_NOTAGS}, - {{T_DIRECT, T_FIXED, - "MICROP", "4421-07", ""}, SDEV_NOTAGS}, - {{T_DIRECT, T_FIXED, - "SEAGATE", "ST150176LW", "0002"}, SDEV_NOTAGS}, - {{T_DIRECT, T_FIXED, - "HP", "C3725S", ""}, SDEV_NOTAGS}, - {{T_DIRECT, T_FIXED, - "IBM", "DCAS", ""}, SDEV_NOTAGS}, - - {{T_SEQUENTIAL, T_REMOV, - "SONY ", "SDT-5000 ", "3."}, SDEV_NOSYNC|SDEV_NOWIDE}, - {{T_SEQUENTIAL, T_REMOV, - "WangDAT ", "Model 1300 ", "02.4"}, SDEV_NOSYNC|SDEV_NOWIDE}, - {{T_SEQUENTIAL, T_REMOV, - "WangDAT ", "Model 2600 ", "01.7"}, SDEV_NOSYNC|SDEV_NOWIDE}, - {{T_SEQUENTIAL, T_REMOV, - "WangDAT ", "Model 3200 ", "02.2"}, SDEV_NOSYNC|SDEV_NOWIDE}, - - /* ATAPI device quirks */ - {{T_CDROM, T_REMOV, - "CR-2801TE", "", "1.07"}, ADEV_NOSENSE}, - {{T_CDROM, T_REMOV, - "CREATIVECD3630E", "", "AC101"}, ADEV_NOSENSE}, - {{T_CDROM, T_REMOV, - "FX320S", "", "q01"}, ADEV_NOSENSE}, - {{T_CDROM, T_REMOV, - "GCD-R580B", "", "1.00"}, ADEV_LITTLETOC}, - {{T_CDROM, T_REMOV, - "MATSHITA CR-574", "", "1.02"}, ADEV_NOCAPACITY}, - {{T_CDROM, T_REMOV, - "MATSHITA CR-574", "", "1.06"}, ADEV_NOCAPACITY}, - {{T_CDROM, T_REMOV, - "Memorex CRW-2642", "", "1.0g"}, ADEV_NOSENSE}, - {{T_CDROM, T_REMOV, - "SANYO CRD-256P", "", "1.02"}, ADEV_NOCAPACITY}, - {{T_CDROM, T_REMOV, - "SANYO CRD-254P", "", "1.02"}, ADEV_NOCAPACITY}, - {{T_CDROM, T_REMOV, - "SANYO CRD-S54P", "", "1.08"}, ADEV_NOCAPACITY}, - {{T_CDROM, T_REMOV, - "CD-ROM CDR-S1", "", "1.70"}, ADEV_NOCAPACITY}, /* Sanyo */ - {{T_CDROM, T_REMOV, - "CD-ROM CDR-N16", "", "1.25"}, ADEV_NOCAPACITY}, /* Sanyo */ - {{T_CDROM, T_REMOV, - "UJDCD8730", "", "1.14"}, ADEV_NODOORLOCK}, /* Acer */ -}; - void scsibus_printlink(struct scsi_link *link) { @@ -810,280 +1079,6 @@ scsibusprint(void *aux, const char *pnp) } /* - * Given a target and lun, ask the device what it is, and find the correct - * driver table entry. - * - * Return 0 if further LUNs are possible, EINVAL if not. - */ -int -scsi_probedev(struct scsibus_softc *sb, int target, int lun, int dumbscan) -{ - struct scsi_attach_args sa; - const struct scsi_quirk_inquiry_pattern *finger; - struct scsi_inquiry_data *inqbuf, *usbinqbuf; - struct scsi_link *link, *link0; - struct cfdata *cf; - int priority, rslt = 0; - u_int16_t devquirks; - - /* Skip this slot if it is already attached and try the next LUN. */ - if (scsi_get_link(sb, target, lun) != NULL) - return 0; - - link = malloc(sizeof(*link), M_DEVBUF, M_NOWAIT); - if (link == NULL) { - SC_DEBUG(link, SDEV_DB2, ("Bad LUN. can't allocate " - "scsi_link.\n")); - return EINVAL; - } - - link->state = 0; - link->target = target; - link->lun = lun; - link->openings = sb->sb_openings; - link->node_wwn = link->port_wwn = 0; - link->flags = sb->sb_flags; - link->quirks = sb->sb_quirks; - link->interpret_sense = scsi_interpret_sense; - link->device_softc = NULL; - link->bus = sb; - memset(&link->inqdata, 0, sizeof(link->inqdata)); - link->id = NULL; - TAILQ_INIT(&link->queue); - link->running = 0; - link->pending = 0; - link->pool = sb->sb_pool; - - SC_DEBUG(link, SDEV_DB2, ("scsi_link created.\n")); - - /* Ask the adapter if this will be a valid device. */ - if (sb->sb_adapter->dev_probe != NULL && - sb->sb_adapter->dev_probe(link) != 0) { - if (lun == 0) { - SC_DEBUG(link, SDEV_DB2, ("Bad LUN 0. dev_probe() " - "failed.\n")); - rslt = EINVAL; - } - goto free; - } - - /* - * If we havent been given an io pool by now then fall back to - * using link->openings. - */ - if (link->pool == NULL) { - link->pool = malloc(sizeof(*link->pool), - M_DEVBUF, M_NOWAIT); - if (link->pool == NULL) { - SC_DEBUG(link, SDEV_DB2, ("Bad LUN. can't allocate " - "link->pool.\n")); - rslt = ENOMEM; - goto bad; - } - scsi_iopool_init(link->pool, link, - scsi_default_get, scsi_default_put); - - SET(link->flags, SDEV_OWN_IOPL); - } - - /* - * Tell drivers that are paying attention to avoid sync/wide/tags until - * INQUIRY data has been processed and the quirks information is - * complete. Some drivers set bits in quirks before we get here, so - * just add NOTAGS, NOWIDE and NOSYNC. - */ - devquirks = link->quirks; - SET(link->quirks, SDEV_NOSYNC | SDEV_NOWIDE | SDEV_NOTAGS); - - /* - * Ask the device what it is. - */ -#ifdef SCSIDEBUG - if (((sb->sc_dev.dv_unit < 32) && - ((1U << sb->sc_dev.dv_unit) & scsidebug_buses)) && - ((target < 32) && ((1U << target) & scsidebug_targets)) && - ((lun < 32) && ((1U << lun) & scsidebug_luns))) - SET(link->flags, scsidebug_level); -#endif /* SCSIDEBUG */ - - if (lun == 0) { - /* Clear any outstanding errors. */ - scsi_test_unit_ready(link, TEST_READY_RETRIES, - scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST | - SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE); - } - - /* Now go ask the device all about itself. */ - inqbuf = dma_alloc(sizeof(*inqbuf), PR_NOWAIT | PR_ZERO); - if (inqbuf == NULL) { - SC_DEBUG(link, SDEV_DB2, ("Bad LUN. can't allocate inqbuf.\n")); - rslt = ENOMEM; - goto bad; - } - - rslt = scsi_inquire(link, inqbuf, scsi_autoconf | SCSI_SILENT); - memcpy(&link->inqdata, inqbuf, sizeof(link->inqdata)); - dma_free(inqbuf, sizeof(*inqbuf)); - - if (rslt != 0) { - if (lun == 0) { - SC_DEBUG(link, SDEV_DB2, ("Bad LUN 0. inquiry rslt = " - "%i\n", rslt)); - rslt = EINVAL; - } - goto bad; - } - inqbuf = &link->inqdata; - - switch (inqbuf->device & SID_QUAL) { - case SID_QUAL_RSVD: - case SID_QUAL_BAD_LU: - case SID_QUAL_LU_OFFLINE: - SC_DEBUG(link, SDEV_DB1, ("Bad LUN. SID_QUAL = 0x%02x\n", - inqbuf->device & SID_QUAL)); - goto bad; - - case SID_QUAL_LU_OK: - break; - - default: - SC_DEBUG(link, SDEV_DB1, ("Vendor-specific SID_QUAL = 0x%02x\n", - inqbuf->device & SID_QUAL)); - break; - } - - if ((inqbuf->device & SID_TYPE) == T_NODEVICE) { - SC_DEBUG(link, SDEV_DB1, - ("Bad LUN. SID_TYPE = T_NODEVICE\n")); - goto bad; - } - - scsi_devid(link); - - link0 = scsi_get_link(sb, target, 0); - if (lun == 0 || link0 == NULL) - ; - else if (ISSET(link->flags, SDEV_UMASS)) - ; - else if (link->id != NULL && !DEVID_CMP(link0->id, link->id)) - ; - else if (dumbscan == 1 && memcmp(inqbuf, &link0->inqdata, - sizeof(*inqbuf)) == 0) { - /* The device doesn't distinguish between LUNs. */ - SC_DEBUG(link, SDEV_DB1, ("Bad LUN. IDENTIFY not supported." - "\n")); - rslt = EINVAL; - goto free_devid; - } - - link->quirks = devquirks; /* Restore what the device wanted. */ - - finger = (const struct scsi_quirk_inquiry_pattern *)scsi_inqmatch( - inqbuf, scsi_quirk_patterns, - nitems(scsi_quirk_patterns), - sizeof(scsi_quirk_patterns[0]), &priority); - if (priority != 0) - SET(link->quirks, finger->quirks); - - switch (SID_ANSII_REV(inqbuf)) { - case SCSI_REV_0: - case SCSI_REV_1: - SET(link->quirks, SDEV_NOTAGS | SDEV_NOSYNC | SDEV_NOWIDE | - SDEV_NOSYNCCACHE); - break; - case SCSI_REV_2: - case SCSI_REV_SPC: - case SCSI_REV_SPC2: - if (!ISSET(inqbuf->flags, SID_CmdQue)) - SET(link->quirks, SDEV_NOTAGS); - if (!ISSET(inqbuf->flags, SID_Sync)) - SET(link->quirks, SDEV_NOSYNC); - if (!ISSET(inqbuf->flags, SID_WBus16)) - SET(link->quirks, SDEV_NOWIDE); - break; - case SCSI_REV_SPC3: - case SCSI_REV_SPC4: - case SCSI_REV_SPC5: - /* By this time SID_Sync and SID_WBus16 were obsolete. */ - if (!ISSET(inqbuf->flags, SID_CmdQue)) - SET(link->quirks, SDEV_NOTAGS); - break; - default: - break; - } - - /* - * If the device can't use tags, >1 opening may confuse it. - */ - if (ISSET(link->quirks, SDEV_NOTAGS)) - link->openings = 1; - - /* - * note what BASIC type of device it is - */ - if (ISSET(inqbuf->dev_qual2, SID_REMOVABLE)) - SET(link->flags, SDEV_REMOVABLE); - - sa.sa_sc_link = link; - - if ((cf = config_search(scsibussubmatch, (struct device *)sb, - &sa)) == 0) { - scsibusprint(&sa, sb->sc_dev.dv_xname); - printf(" not configured\n"); - goto free_devid; - } - - /* - * Braindead USB devices, especially some x-in-1 media readers, try to - * 'help' by pretending any LUN is actually LUN 0 until they see a - * different LUN used in a command. So do an INQUIRY on LUN 1 at this - * point to prevent such helpfulness before it causes confusion. - */ - if (lun == 0 && ISSET(link->flags, SDEV_UMASS) && - scsi_get_link(sb, target, 1) == NULL && sb->sb_luns > 1 && - (usbinqbuf = dma_alloc(sizeof(*usbinqbuf), M_NOWAIT)) != NULL) { - - link->lun = 1; - scsi_inquire(link, usbinqbuf, scsi_autoconf | SCSI_SILENT); - link->lun = 0; - - dma_free(usbinqbuf, sizeof(*usbinqbuf)); - } - - scsi_add_link(link); - - /* - * Generate a TEST_UNIT_READY command. This gives drivers waiting for - * valid quirks data a chance to set wide/sync/tag options - * appropriately. It also clears any outstanding ACA conditions that - * INQUIRY may leave behind. - * - * Do this now so that any messages generated by config_attach() do not - * have negotiation messages inserted into their midst. - */ - scsi_test_unit_ready(link, TEST_READY_RETRIES, - scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST | - SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE); - - config_attach((struct device *)sb, cf, &sa, scsibusprint); - - return 0; - -free_devid: - if (link->id) - devid_free(link->id); -bad: - if (ISSET(link->flags, SDEV_OWN_IOPL)) - free(link->pool, M_DEVBUF, sizeof(*link->pool)); - - if (sb->sb_adapter->dev_free != NULL) - sb->sb_adapter->dev_free(link); -free: - free(link, M_DEVBUF, sizeof(*link)); - return rslt; -} - -/* * Return a priority based on how much of the inquiry data matches * the patterns for the particular driver. */ |