1 /*	$OpenBSD: scsiconf.c,v 1.96 2005/06/03 15:24:05 krw Exp $	*/
2 /*	$NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $	*/
3 
4 /*
5  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Charles Hannum.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Originally written by Julian Elischer (julian@tfs.com)
35  * for TRW Financial Systems for use under the MACH(2.5) operating system.
36  *
37  * TRW Financial Systems, in accordance with their agreement with Carnegie
38  * Mellon University, makes this software available to CMU to distribute
39  * or use in any manner that they see fit as long as this message is kept with
40  * the software. For this reason TFS also grants any other persons or
41  * organisations permission to use or modify this software.
42  *
43  * TFS supplies this software to be publicly redistributed
44  * on the understanding that TFS is not responsible for the correct
45  * functioning of this software in any circumstances.
46  *
47  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
48  */
49 
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/malloc.h>
54 #include <sys/device.h>
55 
56 #include <scsi/scsi_all.h>
57 #include <scsi/scsiconf.h>
58 
59 #if 0
60 #if NCALS > 0
61 	{ T_PROCESSOR, T_FIXED, 1,
62 	  0, 0, 0 },
63 #endif	/* NCALS */
64 #if NBLL > 0
65 	{ T_PROCESSOR, T_FIXED, 1,
66 	  "AEG     ", "READER          ", "V1.0" },
67 #endif	/* NBLL */
68 #if NKIL > 0
69 	{ T_SCANNER, T_FIXED, 0,
70 	  "KODAK   ", "IL Scanner 900  ", 0 },
71 #endif	/* NKIL */
72 #endif
73 
74 /*
75  * Declarations
76  */
77 int scsi_probedev(struct scsibus_softc *, struct scsi_inquiry_data *, int,
78     int);
79 int scsi_probe_bus(int bus, int target, int lun);
80 
81 struct scsi_device probe_switch = {
82 	NULL,
83 	NULL,
84 	NULL,
85 	NULL,
86 };
87 
88 int scsibusmatch(struct device *, void *, void *);
89 void scsibusattach(struct device *, struct device *, void *);
90 int  scsibusactivate(struct device *, enum devact);
91 int  scsibusdetach(struct device *, int);
92 void scsibuszeroref(struct device *);
93 
94 int scsibussubmatch(struct device *, void *, void *);
95 
96 
97 
98 struct cfattach scsibus_ca = {
99 	sizeof(struct scsibus_softc), scsibusmatch, scsibusattach,
100 	scsibusdetach, scsibusactivate, scsibuszeroref
101 };
102 
103 struct cfdriver scsibus_cd = {
104 	NULL, "scsibus", DV_DULL
105 };
106 
107 int scsidebug_buses = SCSIDEBUG_BUSES;
108 int scsidebug_targets = SCSIDEBUG_TARGETS;
109 int scsidebug_luns = SCSIDEBUG_LUNS;
110 int scsidebug_level = SCSIDEBUG_LEVEL;
111 
112 int scsiforcelun_buses = SCSIFORCELUN_BUSES;
113 int scsiforcelun_targets = SCSIFORCELUN_TARGETS;
114 
115 int scsi_autoconf = SCSI_AUTOCONF;
116 
117 int scsibusprint(void *, const char *);
118 
119 int
scsiprint(aux,pnp)120 scsiprint(aux, pnp)
121 	void *aux;
122 	const char *pnp;
123 {
124 	/* only "scsibus"es can attach to "scsi"s; easy. */
125 	if (pnp)
126 		printf("scsibus at %s", pnp);
127 
128 	return (UNCONF);
129 }
130 
131 int
scsibusmatch(parent,match,aux)132 scsibusmatch(parent, match, aux)
133 	struct device *parent;
134 	void *match, *aux;
135 {
136 
137 	return 1;
138 }
139 
140 /*
141  * The routine called by the adapter boards to get all their
142  * devices configured in.
143  */
144 void
scsibusattach(parent,self,aux)145 scsibusattach(parent, self, aux)
146 	struct device *parent, *self;
147 	void *aux;
148 {
149 	struct scsibus_softc *sb = (struct scsibus_softc *)self;
150 	struct scsi_link *sc_link_proto = aux;
151 	int nbytes, i;
152 
153 	if (!cold)
154 		scsi_autoconf = 0;
155 
156 	sc_link_proto->scsibus = sb->sc_dev.dv_unit;
157 	sb->adapter_link = sc_link_proto;
158 	if (sb->adapter_link->adapter_buswidth == 0)
159 		sb->adapter_link->adapter_buswidth = 8;
160 	sb->sc_buswidth = sb->adapter_link->adapter_buswidth;
161 	if (sb->adapter_link->luns == 0)
162 		sb->adapter_link->luns = 8;
163 
164 	printf(": %d targets\n", sb->sc_buswidth);
165 
166 	/* Initialize shared data. */
167 	scsi_init();
168 
169 	nbytes = sb->sc_buswidth * sizeof(struct scsi_link **);
170 	sb->sc_link = (struct scsi_link ***)malloc(nbytes, M_DEVBUF, M_NOWAIT);
171 	if (sb->sc_link == NULL)
172 		panic("scsibusattach: can't allocate target links");
173 	nbytes = 8 * sizeof(struct scsi_link *);
174 	for (i = 0; i < sb->sc_buswidth; i++) {
175 		sb->sc_link[i] = (struct scsi_link **)malloc(nbytes,
176 		    M_DEVBUF, M_NOWAIT);
177 		if (sb->sc_link[i] == NULL)
178 			panic("scsibusattach: can't allocate lun links");
179 		bzero(sb->sc_link[i], nbytes);
180 	}
181 
182 #if defined(SCSI_DELAY) && SCSI_DELAY > 2
183 	printf("%s: waiting for scsi devices to settle\n",
184 		sb->sc_dev.dv_xname);
185 #else	/* SCSI_DELAY > 2 */
186 #undef	SCSI_DELAY
187 #define SCSI_DELAY 2
188 #endif	/* SCSI_DELAY */
189 	delay(1000000 * SCSI_DELAY);
190 
191 	scsi_probe_bus(sb->sc_dev.dv_unit, -1, -1);
192 }
193 
194 
195 int
scsibusactivate(dev,act)196 scsibusactivate(dev, act)
197 	struct device *dev;
198 	enum devact act;
199 {
200 	return (config_activate_children(dev, act));
201 }
202 
203 int
scsibusdetach(dev,type)204 scsibusdetach (dev, type)
205 	struct device *dev;
206 	int type;
207 {
208 	return (config_detach_children(dev, type));
209 }
210 
211 void
scsibuszeroref(dev)212 scsibuszeroref(dev)
213 	struct device *dev;
214 {
215 	struct scsibus_softc *sb = (struct scsibus_softc *)dev;
216 	int i;
217 
218 	for (i = 0; i < sb->sc_buswidth; i++) {
219 		if (sb->sc_link[i] != NULL)
220 			free(sb->sc_link[i], M_DEVBUF);
221 	}
222 
223 	free(sb->sc_link, M_DEVBUF);
224 }
225 
226 
227 
228 int
scsibussubmatch(parent,match,aux)229 scsibussubmatch(parent, match, aux)
230 	struct device *parent;
231 	void *match, *aux;
232 {
233 	struct cfdata *cf = match;
234 	struct scsibus_attach_args *sa = aux;
235 	struct scsi_link *sc_link = sa->sa_sc_link;
236 
237 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != sc_link->target)
238 		return 0;
239 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != sc_link->lun)
240 		return 0;
241 	return ((*cf->cf_attach->ca_match)(parent, match, aux));
242 }
243 
244 /*
245  * Probe the requested scsi bus. It must be already set up.
246  * -1 requests all set up scsi busses.
247  * target and lun optionally narrow the search if not -1
248  */
249 int
scsi_probe_busses(bus,target,lun)250 scsi_probe_busses(bus, target, lun)
251 	int bus, target, lun;
252 {
253 
254 	if (bus == -1) {
255 		for (bus = 0; bus < scsibus_cd.cd_ndevs; bus++)
256 			if (scsibus_cd.cd_devs[bus])
257 				scsi_probe_bus(bus, target, lun);
258 		return 0;
259 	} else {
260 		return scsi_probe_bus(bus, target, lun);
261 	}
262 }
263 
264 /*
265  * Probe the requested scsi bus. It must be already set up.
266  * target and lun optionally narrow the search if not -1
267  */
268 int
scsi_probe_bus(bus,target,lun)269 scsi_probe_bus(bus, target, lun)
270 	int bus, target, lun;
271 {
272 	struct scsi_inquiry_data inqbuflun0;
273 	struct scsibus_softc *scsi;
274 	u_int16_t scsi_addr;
275 	int maxtarget, mintarget, maxlun, minlun;
276 
277 	if (bus < 0 || bus >= scsibus_cd.cd_ndevs)
278 		return ENXIO;
279 	scsi = scsibus_cd.cd_devs[bus];
280 	if (!scsi)
281 		return ENXIO;
282 
283 	scsi_addr = scsi->adapter_link->adapter_target;
284 
285 	if (target == -1) {
286 		maxtarget = scsi->adapter_link->adapter_buswidth - 1;
287 		mintarget = 0;
288 	} else {
289 		if (target < 0 ||
290 		    target >= scsi->adapter_link->adapter_buswidth)
291 			return EINVAL;
292 		maxtarget = mintarget = target;
293 	}
294 
295 	if (lun == -1) {
296 		maxlun = scsi->adapter_link->luns - 1;
297 		minlun = 0;
298 	} else {
299 		if (lun < 0 || lun >= scsi->adapter_link->luns)
300 			return EINVAL;
301 		maxlun = lun;
302 		if (lun == 0 || scsi->sc_link[target][0] == NULL)
303 			minlun = 0;
304 		else
305 			minlun = lun;
306 	}
307 
308 	for (target = mintarget; target <= maxtarget; target++)
309 		if (target != scsi_addr) {
310 			bzero(&inqbuflun0, sizeof inqbuflun0);
311 			if (minlun != 0 &&
312 			    (scsi_inquire(scsi->sc_link[target][0], &inqbuflun0,
313 			    0) != 0))
314 				continue;
315 			for (lun = minlun; lun <= maxlun; lun++)
316 				if (scsi_probedev(scsi, &inqbuflun0, target,
317 				    lun) == EINVAL)
318 					break;
319 		}
320 
321 	return 0;
322 }
323 
324 void
scsi_strvis(dst,src,len)325 scsi_strvis(dst, src, len)
326 	u_char *dst, *src;
327 	int len;
328 {
329 	u_char last;
330 
331 	/* Trim leading and trailing whitespace and NULs. */
332 	while (len > 0 && (src[0] == ' ' || src[0] == '\t' || src[0] == '\n' ||
333 	    src[0] == '\0' || src[0] == 0xff))
334 		++src, --len;
335 	while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t' ||
336 	    src[len-1] == '\n' || src[len-1] == '\0' || src[len-1] == 0xff))
337 		--len;
338 
339 	last = 0xff;
340 	while (len > 0) {
341 		switch (*src) {
342 		case ' ':
343 		case '\t':
344 		case '\n':
345 		case '\0':
346 		case 0xff:
347 			/* collapse whitespace and NULs to a single space */
348 			if (last != ' ')
349 				*dst++ = ' ';
350 			last = ' ';
351 			break;
352 		case '\\':
353 			/* quote characters */
354 			*dst++ = '\\';
355 			*dst++ = '\\';
356 			last = '\\';
357 			break;
358 		default:
359 			if (*src < 0x20 || *src >= 0x80) {
360 				/* non-printable characters */
361 				*dst++ = '\\';
362 				*dst++ = ((*src & 0300) >> 6) + '0';
363 				*dst++ = ((*src & 0070) >> 3) + '0';
364 				*dst++ = ((*src & 0007) >> 0) + '0';
365 			} else {
366 				/* normal characters */
367 				*dst++ = *src;
368 			}
369 			last = *src;
370 			break;
371 		}
372 		++src, --len;
373 	}
374 
375 	*dst++ = 0;
376 }
377 
378 struct scsi_quirk_inquiry_pattern {
379 	struct scsi_inquiry_pattern pattern;
380 	u_int16_t quirks;
381 };
382 
383 const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
384 	{{T_CDROM, T_REMOV,
385 	 "PLEXTOR", "CD-ROM PX-40TS", "1.01"}, SDEV_NOSYNC},
386 
387 	{{T_DIRECT, T_FIXED,
388 	 "MICROP  ", "1588-15MBSUN0669", ""},     SDEV_AUTOSAVE},
389 	{{T_DIRECT, T_FIXED,
390 	 "DEC     ", "RZ55     (C) DEC", ""},     SDEV_AUTOSAVE},
391 	{{T_DIRECT, T_FIXED,
392 	 "EMULEX  ", "MD21/S2     ESDI", "A00"},  SDEV_AUTOSAVE},
393 	{{T_DIRECT, T_FIXED,
394 	 "IBMRAID ", "0662S",            ""},     SDEV_AUTOSAVE},
395 	{{T_DIRECT, T_FIXED,
396 	 "IBM     ", "0663H",            ""},     SDEV_AUTOSAVE},
397 	{{T_DIRECT, T_FIXED,
398 	 "IBM",	  "0664",		 ""},	  SDEV_AUTOSAVE},
399 	{{T_DIRECT, T_FIXED,
400 	 "IBM     ", "H3171-S2",         ""},	  SDEV_AUTOSAVE},
401 	{{T_DIRECT, T_FIXED,
402 	 "IBM     ", "KZ-C",		 ""},	  SDEV_AUTOSAVE},
403 	/* Broken IBM disk */
404 	{{T_DIRECT, T_FIXED,
405 	 ""	   , "DFRSS2F",		 ""},	  SDEV_AUTOSAVE},
406 	{{T_DIRECT, T_FIXED,
407 	 "QUANTUM ", "ELS85S          ", ""},	  SDEV_AUTOSAVE},
408 	{{T_DIRECT, T_REMOV,
409 	 "iomega", "jaz 1GB",		 ""},	  SDEV_NOTAGS},
410         {{T_DIRECT, T_FIXED,
411          "MICROP", "4421-07",		 ""},     SDEV_NOTAGS},
412         {{T_DIRECT, T_FIXED,
413          "SEAGATE", "ST150176LW",        "0002"}, SDEV_NOTAGS},
414         {{T_DIRECT, T_FIXED,
415          "HP", "C3725S",		 ""},     SDEV_NOTAGS},
416         {{T_DIRECT, T_FIXED,
417          "IBM", "DCAS",			 ""},     SDEV_NOTAGS},
418 
419 	{{T_SEQUENTIAL, T_REMOV,
420 	 "SONY    ", "SDT-5000        ", "3."},   SDEV_NOSYNC|SDEV_NOWIDE},
421 	{{T_SEQUENTIAL, T_REMOV,
422 	 "WangDAT ", "Model 1300      ", "02.4"}, SDEV_NOSYNC|SDEV_NOWIDE},
423 	{{T_SEQUENTIAL, T_REMOV,
424 	 "WangDAT ", "Model 2600      ", "01.7"}, SDEV_NOSYNC|SDEV_NOWIDE},
425 	{{T_SEQUENTIAL, T_REMOV,
426 	 "WangDAT ", "Model 3200      ", "02.2"}, SDEV_NOSYNC|SDEV_NOWIDE},
427 
428 	/* ATAPI device quirks */
429         {{T_CDROM, T_REMOV,
430          "ALPS ELECTRIC CO.,LTD. DC544C", "", "SW03D"}, ADEV_NOTUR},
431         {{T_CDROM, T_REMOV,
432          "CR-2801TE", "", "1.07"},              ADEV_NOSENSE},
433         {{T_CDROM, T_REMOV,
434          "CREATIVECD3630E", "", "AC101"},       ADEV_NOSENSE},
435         {{T_CDROM, T_REMOV,
436          "FX320S", "", "q01"},                  ADEV_NOSENSE},
437         {{T_CDROM, T_REMOV,
438          "GCD-R580B", "", "1.00"},              ADEV_LITTLETOC},
439         {{T_CDROM, T_REMOV,
440          "MATSHITA CR-574", "", "1.02"},        ADEV_NOCAPACITY},
441         {{T_CDROM, T_REMOV,
442          "MATSHITA CR-574", "", "1.06"},        ADEV_NOCAPACITY},
443         {{T_CDROM, T_REMOV,
444          "Memorex CRW-2642", "", "1.0g"},       ADEV_NOSENSE},
445         {{T_CDROM, T_REMOV,
446          "NEC                 CD-ROM DRIVE:273", "", "4.21"}, ADEV_NOTUR},
447         {{T_CDROM, T_REMOV,
448          "SANYO CRD-256P", "", "1.02"},         ADEV_NOCAPACITY},
449         {{T_CDROM, T_REMOV,
450          "SANYO CRD-254P", "", "1.02"},         ADEV_NOCAPACITY},
451         {{T_CDROM, T_REMOV,
452          "SANYO CRD-S54P", "", "1.08"},         ADEV_NOCAPACITY},
453         {{T_CDROM, T_REMOV,
454          "CD-ROM  CDR-S1", "", "1.70"},         ADEV_NOCAPACITY}, /* Sanyo */
455         {{T_CDROM, T_REMOV,
456          "CD-ROM  CDR-N16", "", "1.25"},        ADEV_NOCAPACITY}, /* Sanyo */
457         {{T_CDROM, T_REMOV,
458          "UJDCD8730", "", "1.14"},              ADEV_NODOORLOCK}, /* Acer */
459 };
460 
461 
462 /*
463  * Print out autoconfiguration information for a subdevice.
464  *
465  * This is a slight abuse of 'standard' autoconfiguration semantics,
466  * because 'print' functions don't normally print the colon and
467  * device information.  However, in this case that's better than
468  * either printing redundant information before the attach message,
469  * or having the device driver call a special function to print out
470  * the standard device information.
471  */
472 int
scsibusprint(aux,pnp)473 scsibusprint(aux, pnp)
474 	void	*aux;
475 	const char *pnp;
476 {
477 	struct scsibus_attach_args *sa = aux;
478 	struct scsi_inquiry_data *inqbuf;
479 	u_int8_t type;
480 	boolean removable;
481 	char *dtype, *qtype;
482 	char vendor[33], product[65], revision[17];
483 	int target, lun;
484 
485 	if (pnp != NULL)
486 		printf("%s", pnp);
487 
488 	inqbuf = sa->sa_inqbuf;
489 
490 	target = sa->sa_sc_link->target;
491 	lun = sa->sa_sc_link->lun;
492 
493 	type = inqbuf->device & SID_TYPE;
494 	removable = inqbuf->dev_qual2 & SID_REMOVABLE ? 1 : 0;
495 
496 	/*
497 	 * Figure out basic device type and qualifier.
498 	 */
499 	dtype = 0;
500 	switch (inqbuf->device & SID_QUAL) {
501 	case SID_QUAL_LU_OK:
502 		qtype = "";
503 		break;
504 
505 	case SID_QUAL_LU_OFFLINE:
506 		qtype = " offline";
507 		break;
508 
509 	case SID_QUAL_RSVD:
510 	case SID_QUAL_BAD_LU:
511 		panic("scsibusprint: impossible qualifier");
512 
513 	default:
514 		qtype = "";
515 		dtype = "vendor-unique";
516 		break;
517 	}
518 	if (dtype == 0) {
519 		switch (type) {
520 		case T_DIRECT:
521 			dtype = "direct";
522 			break;
523 		case T_SEQUENTIAL:
524 			dtype = "sequential";
525 			break;
526 		case T_PRINTER:
527 			dtype = "printer";
528 			break;
529 		case T_PROCESSOR:
530 			dtype = "processor";
531 			break;
532 		case T_CDROM:
533 			dtype = "cdrom";
534 			break;
535 		case T_WORM:
536 			dtype = "worm";
537 			break;
538 		case T_SCANNER:
539 			dtype = "scanner";
540 			break;
541 		case T_OPTICAL:
542 			dtype = "optical";
543 			break;
544 		case T_CHANGER:
545 			dtype = "changer";
546 			break;
547 		case T_COMM:
548 			dtype = "communication";
549 			break;
550 		case T_ENCLOSURE:
551 			dtype = "enclosure services";
552 			break;
553 		case T_RDIRECT:
554 			dtype = "simplified direct";
555 			break;
556 		case T_NODEVICE:
557 			panic("scsibusprint: impossible device type");
558 		default:
559 			dtype = "unknown";
560 			break;
561 		}
562 	}
563 
564 	scsi_strvis(vendor, inqbuf->vendor, 8);
565 	scsi_strvis(product, inqbuf->product, 16);
566 	scsi_strvis(revision, inqbuf->revision, 4);
567 
568 	printf(" targ %d lun %d: <%s, %s, %s> SCSI%d %d/%s %s%s",
569 	    target, lun, vendor, product, revision,
570 	    inqbuf->version & SID_ANSII, type, dtype,
571 	    removable ? "removable" : "fixed", qtype);
572 
573 	return (UNCONF);
574 }
575 
576 /*
577  * Given a target and lun, ask the device what it is, and find the correct
578  * driver table entry.
579  *
580  * Return 0 if further LUNs are possible, EINVAL if not.
581  */
582 int
scsi_probedev(scsi,inqbuflun0,target,lun)583 scsi_probedev(scsi, inqbuflun0, target, lun)
584 	struct scsibus_softc *scsi;
585 	struct scsi_inquiry_data *inqbuflun0;
586 	int target, lun;
587 {
588 	struct scsi_link *sc_link;
589 	static struct scsi_inquiry_data inqbuf;
590 	const struct scsi_quirk_inquiry_pattern *finger;
591 	int priority, rslt = 0;
592 	struct scsibus_attach_args sa;
593 	struct cfdata *cf;
594 
595 	/* Skip this slot if it is already attached and try the next LUN. */
596 	if (scsi->sc_link[target][lun])
597 		return (0);
598 
599 	sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
600 	if (sc_link == NULL)
601 		return (EINVAL);
602 
603 	*sc_link = *scsi->adapter_link;
604 	sc_link->target = target;
605 	sc_link->lun = lun;
606 	sc_link->device = &probe_switch;
607 	sc_link->inquiry_flags = 0;
608 
609 	SC_DEBUG(sc_link, SDEV_DB2, ("scsi_link created.\n"));
610 
611 	/*
612 	 * Tell drivers that are paying attention to avoid sync/wide/tags until
613 	 * INQUIRY data has been processed and the quirks information is
614 	 * complete. Some drivers set bits in quirks before we get here, so
615 	 * just add NOTAGS, NOWIDE and NOSYNC.
616 	 */
617 	sc_link->quirks |= SDEV_NOSYNC | SDEV_NOWIDE | SDEV_NOTAGS;
618 
619 	/*
620 	 * Ask the device what it is
621 	 */
622 #ifdef SCSIDEBUG
623 	if (((1 << sc_link->scsibus) & scsidebug_buses) &&
624 	    ((1 << target) & scsidebug_targets) &&
625 	    ((1 << lun) & scsidebug_luns))
626 		sc_link->flags |= scsidebug_level;
627 #endif /* SCSIDEBUG */
628 
629 #if defined(mvme68k)
630 	if (lun == 0) {
631 		/* XXX some drivers depend on this */
632 		scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_DEFAULT,
633 		    scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
634 		    SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
635 	}
636 #endif
637 
638 	/* Now go ask the device all about itself. */
639 	rslt = scsi_inquire(sc_link, &inqbuf, scsi_autoconf | SCSI_SILENT);
640 	if (rslt != 0) {
641 		SC_DEBUG(sc_link, SDEV_DB2, ("Bad LUN. rslt = %i\n", rslt));
642 		if (lun == 0)
643 			rslt = EINVAL;
644 		goto bad;
645 	}
646 
647 	switch (inqbuf.device & SID_QUAL) {
648 	case SID_QUAL_RSVD:
649 	case SID_QUAL_BAD_LU:
650 	case SID_QUAL_LU_OFFLINE:
651 		SC_DEBUG(sc_link, SDEV_DB1,
652 		    ("Bad LUN. SID_QUAL = 0x%02x\n", inqbuf.device & SID_QUAL));
653 		goto bad;
654 
655 	case SID_QUAL_LU_OK:
656 		if ((inqbuf.device & SID_TYPE) == T_NODEVICE) {
657 			SC_DEBUG(sc_link, SDEV_DB1,
658 		    	    ("Bad LUN. SID_TYPE = T_NODEVICE\n"));
659 			goto bad;
660 		}
661 		break;
662 
663 	default:
664 		break;
665 	}
666 
667 	if (lun == 0)
668 		bcopy(&inqbuf, inqbuflun0, sizeof *inqbuflun0);
669 	else if (((1 << sc_link->scsibus) & scsiforcelun_buses) &&
670 	    ((1 << target) & scsiforcelun_targets))
671 		;
672 	else if (sc_link->flags & SDEV_UMASS)
673 		;
674 	else if (memcmp(&inqbuf, inqbuflun0, sizeof inqbuf) == 0) {
675 		/* The device doesn't distinguish between LUNs. */
676 		SC_DEBUG(sc_link, SDEV_DB1, ("IDENTIFY not supported.\n"));
677 		rslt = EINVAL;
678 		goto bad;
679 	}
680 
681 	finger = (const struct scsi_quirk_inquiry_pattern *)scsi_inqmatch(
682 	    &inqbuf, scsi_quirk_patterns,
683 	    sizeof(scsi_quirk_patterns)/sizeof(scsi_quirk_patterns[0]),
684 	    sizeof(scsi_quirk_patterns[0]), &priority);
685 
686 	/*
687 	 * Based upon the inquiry flags we got back, and if we're
688 	 * at SCSI-2 or better, remove some limiting quirks.
689 	 */
690 	if ((inqbuf.version & SID_ANSII) >= 2) {
691 		if ((inqbuf.flags & SID_CmdQue) != 0)
692 			sc_link->quirks &= ~SDEV_NOTAGS;
693 		if ((inqbuf.flags & SID_Sync) != 0)
694 			sc_link->quirks &= ~SDEV_NOSYNC;
695 		if ((inqbuf.flags & SID_WBus16) != 0)
696 			sc_link->quirks &= ~SDEV_NOWIDE;
697 	}
698 	/*
699 	 * Now apply any quirks from the table.
700 	 */
701 	if (priority != 0)
702 		sc_link->quirks |= finger->quirks;
703 	sc_link->scsi_version = inqbuf.version;
704 
705 	/*
706 	 * Save INQUIRY "flags" (SID_Linked, etc.) for low-level drivers.
707 	 */
708 	sc_link->inquiry_flags = inqbuf.flags;
709 	memcpy(&sc_link->inqdata, &inqbuf, sizeof(sc_link->inqdata));
710 
711 	/*
712 	 * note what BASIC type of device it is
713 	 */
714 	if ((inqbuf.dev_qual2 & SID_REMOVABLE) != 0)
715 		sc_link->flags |= SDEV_REMOVABLE;
716 
717 	sa.sa_sc_link = sc_link;
718 	sa.sa_inqbuf = &inqbuf;
719 
720 	if ((cf = config_search(scsibussubmatch, (struct device *)scsi, &sa)) == 0) {
721 		scsibusprint(&sa, scsi->sc_dev.dv_xname);
722 		printf(" not configured\n");
723 		goto bad;
724 	}
725 
726 	/*
727 	 * Braindead USB devices, especially some x-in-1 media readers, try to
728 	 * 'help' by pretending any LUN is actually LUN 0 until they see a
729 	 * different LUN used in a command. So do an INQUIRY on LUN 1 at this
730 	 * point (since we are done with the data in inqbuf) to prevent such
731 	 * helpfulness before it causes confusion.
732 	 */
733 	if (lun == 0 && (sc_link->flags & SDEV_UMASS) &&
734 	    scsi->sc_link[target][1] == NULL && sc_link->luns > 1) {
735 		sc_link->lun = 1;
736 		scsi_inquire(sc_link, &inqbuf, scsi_autoconf | SCSI_SILENT);
737 	    	sc_link->lun = 0;
738 	}
739 
740 	scsi->sc_link[target][lun] = sc_link;
741 
742 	/*
743 	 * Generate a TEST_UNIT_READY command. This gives drivers waiting for
744 	 * valid quirks data a chance to set wide/sync/tag options
745 	 * appropriately. It also clears any outstanding ACA conditions that
746 	 * INQUIRY may leave behind.
747 	 *
748 	 * Do this now so that any messages generated by config_attach() do not
749 	 * have negotiation messages inserted into their midst.
750 	 */
751 	scsi_test_unit_ready(sc_link, TEST_READY_RETRIES_DEFAULT,
752 	    scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
753 	    SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
754 
755 	config_attach((struct device *)scsi, cf, &sa, scsibusprint);
756 
757 	return (0);
758 
759 bad:
760 	free(sc_link, M_DEVBUF);
761 	return (rslt);
762 }
763 
764 /*
765  * Return a priority based on how much of the inquiry data matches
766  * the patterns for the particular driver.
767  */
768 const void *
scsi_inqmatch(inqbuf,base,nmatches,matchsize,bestpriority)769 scsi_inqmatch(inqbuf, base, nmatches, matchsize, bestpriority)
770 	struct scsi_inquiry_data *inqbuf;
771 	const void *base;
772 	int nmatches, matchsize;
773 	int *bestpriority;
774 {
775 	u_int8_t type;
776 	boolean removable;
777 	const void *bestmatch;
778 
779 	/* Include the qualifier to catch vendor-unique types. */
780 	type = inqbuf->device;
781 	removable = inqbuf->dev_qual2 & SID_REMOVABLE ? T_REMOV : T_FIXED;
782 
783 	for (*bestpriority = 0, bestmatch = 0; nmatches--; base += matchsize) {
784 		struct scsi_inquiry_pattern *match = (void *)base;
785 		int priority, len;
786 
787 		if (type != match->type)
788 			continue;
789 		if (removable != match->removable)
790 			continue;
791 		priority = 2;
792 		len = strlen(match->vendor);
793 		if (bcmp(inqbuf->vendor, match->vendor, len))
794 			continue;
795 		priority += len;
796 		len = strlen(match->product);
797 		if (bcmp(inqbuf->product, match->product, len))
798 			continue;
799 		priority += len;
800 		len = strlen(match->revision);
801 		if (bcmp(inqbuf->revision, match->revision, len))
802 			continue;
803 		priority += len;
804 
805 #if SCSIDEBUG
806 		printf("scsi_inqmatch: %d/%d/%d <%s, %s, %s>\n",
807 		    priority, match->type, match->removable,
808 		    match->vendor, match->product, match->revision);
809 #endif
810 		if (priority > *bestpriority) {
811 			*bestpriority = priority;
812 			bestmatch = base;
813 		}
814 	}
815 
816 	return (bestmatch);
817 }
818