summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrw <krw@openbsd.org>2020-08-09 13:29:08 +0000
committerkrw <krw@openbsd.org>2020-08-09 13:29:08 +0000
commit14832242cc36bec14cb1b6aee4fb4964b850367d (patch)
tree2fd114e0a6c8e00008f135ba2e39047fc50819f1
parentRemove now unused M_ACAST flag. (diff)
downloadwireguard-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.c763
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.
*/