This source file includes following definitions.
- scsiprint
- scsibusmatch
- scsibusattach
- scsibusactivate
- scsibusdetach
- scsibussubmatch
- scsibus_bioctl
- scsi_probe_bus
- scsi_probe_target
- scsi_probe_lun
- scsi_detach_bus
- scsi_detach_target
- scsi_detach_lun
- scsi_strvis
- scsibusprint
- scsi_probedev
- scsi_inqmatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #include "bio.h"
51
52 #include <sys/types.h>
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/malloc.h>
56 #include <sys/device.h>
57
58 #include <scsi/scsi_all.h>
59 #include <scsi/scsiconf.h>
60
61 #if NBIO > 0
62 #include <sys/ioctl.h>
63 #include <sys/scsiio.h>
64 #include <dev/biovar.h>
65 #endif
66
67
68
69
70 int scsi_probedev(struct scsibus_softc *, int, int);
71
72 struct scsi_device probe_switch = {
73 NULL,
74 NULL,
75 NULL,
76 NULL,
77 };
78
79 int scsibusmatch(struct device *, void *, void *);
80 void scsibusattach(struct device *, struct device *, void *);
81 int scsibusactivate(struct device *, enum devact);
82 int scsibusdetach(struct device *, int);
83
84 int scsibussubmatch(struct device *, void *, void *);
85
86 #if NBIO > 0
87 int scsibus_bioctl(struct device *, u_long, caddr_t);
88 #endif
89
90 struct cfattach scsibus_ca = {
91 sizeof(struct scsibus_softc), scsibusmatch, scsibusattach,
92 scsibusdetach, scsibusactivate
93 };
94
95 struct cfdriver scsibus_cd = {
96 NULL, "scsibus", DV_DULL
97 };
98
99 #ifdef SCSIDEBUG
100 int scsidebug_buses = SCSIDEBUG_BUSES;
101 int scsidebug_targets = SCSIDEBUG_TARGETS;
102 int scsidebug_luns = SCSIDEBUG_LUNS;
103 int scsidebug_level = SCSIDEBUG_LEVEL;
104 #endif
105
106 int scsi_autoconf = SCSI_AUTOCONF;
107
108 int scsibusprint(void *, const char *);
109
110 const u_int8_t version_to_spc [] = {
111 0,
112 1,
113 2,
114 3,
115 2,
116 3,
117 4,
118 0,
119 };
120
121 int
122 scsiprint(void *aux, const char *pnp)
123 {
124
125 if (pnp)
126 printf("scsibus at %s", pnp);
127
128 return (UNCONF);
129 }
130
131 int
132 scsibusmatch(struct device *parent, void *match, void *aux)
133 {
134 return (1);
135 }
136
137
138
139
140
141 void
142 scsibusattach(struct device *parent, struct device *self, void *aux)
143 {
144 struct scsibus_softc *sb = (struct scsibus_softc *)self;
145 struct scsibus_attach_args *saa = aux;
146 struct scsi_link *sc_link_proto = saa->saa_sc_link;
147 int nbytes, i;
148
149 if (!cold)
150 scsi_autoconf = 0;
151
152 sc_link_proto->scsibus = sb->sc_dev.dv_unit;
153 sb->adapter_link = sc_link_proto;
154 if (sb->adapter_link->adapter_buswidth == 0)
155 sb->adapter_link->adapter_buswidth = 8;
156 sb->sc_buswidth = sb->adapter_link->adapter_buswidth;
157 if (sb->adapter_link->luns == 0)
158 sb->adapter_link->luns = 8;
159
160 printf(": %d targets\n", sb->sc_buswidth);
161
162
163 scsi_init();
164
165 nbytes = sb->sc_buswidth * sizeof(struct scsi_link **);
166 sb->sc_link = malloc(nbytes, M_DEVBUF, M_NOWAIT);
167 if (sb->sc_link == NULL)
168 panic("scsibusattach: can't allocate target links");
169 nbytes = sb->adapter_link->luns * sizeof(struct scsi_link *);
170 for (i = 0; i < sb->sc_buswidth; i++) {
171 sb->sc_link[i] = malloc(nbytes, M_DEVBUF, M_NOWAIT);
172 if (sb->sc_link[i] == NULL)
173 panic("scsibusattach: can't allocate lun links");
174 bzero(sb->sc_link[i], nbytes);
175 }
176
177 #if NBIO > 0
178 if (bio_register(&sb->sc_dev, scsibus_bioctl) != 0)
179 printf("%s: unable to register bio\n", sb->sc_dev.dv_xname);
180 #endif
181
182 scsi_probe_bus(sb);
183 }
184
185 int
186 scsibusactivate(struct device *dev, enum devact act)
187 {
188 return (config_activate_children(dev, act));
189 }
190
191 int
192 scsibusdetach(struct device *dev, int type)
193 {
194 struct scsibus_softc *sb = (struct scsibus_softc *)dev;
195 int i, j, error;
196
197 #if NBIO > 0
198 bio_unregister(&sb->sc_dev);
199 #endif
200
201 if ((error = config_detach_children(dev, type)) != 0)
202 return (error);
203
204 for (i = 0; i < sb->sc_buswidth; i++) {
205 if (sb->sc_link[i] != NULL) {
206 for (j = 0; j < sb->adapter_link->luns; j++) {
207 if (sb->sc_link[i][j] != NULL)
208 free(sb->sc_link[i][j], M_DEVBUF);
209 }
210 free(sb->sc_link[i], M_DEVBUF);
211 }
212 }
213
214 free(sb->sc_link, M_DEVBUF);
215
216
217 scsi_deinit();
218
219 return (0);
220 }
221
222 int
223 scsibussubmatch(struct device *parent, void *match, void *aux)
224 {
225 struct cfdata *cf = match;
226 struct scsi_attach_args *sa = aux;
227 struct scsi_link *sc_link = sa->sa_sc_link;
228
229 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != sc_link->target)
230 return (0);
231 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != sc_link->lun)
232 return (0);
233
234 return ((*cf->cf_attach->ca_match)(parent, match, aux));
235 }
236
237 #if NBIO > 0
238 int
239 scsibus_bioctl(struct device *dev, u_long cmd, caddr_t addr)
240 {
241 struct scsibus_softc *sc = (struct scsibus_softc *)dev;
242 struct sbioc_device *sdev;
243
244 switch (cmd) {
245 case SBIOCPROBE:
246 sdev = (struct sbioc_device *)addr;
247
248 if (sdev->sd_target == -1 && sdev->sd_lun == -1)
249 return (scsi_probe_bus(sc));
250
251
252 if (sdev->sd_target == -1)
253 return (EINVAL);
254
255 if (sdev->sd_lun == -1)
256 return (scsi_probe_target(sc, sdev->sd_target));
257
258 return (scsi_probe_lun(sc, sdev->sd_target, sdev->sd_lun));
259
260 case SBIOCDETACH:
261 sdev = (struct sbioc_device *)addr;
262
263 if (sdev->sd_target == -1)
264 return (EINVAL);
265
266 if (sdev->sd_lun == -1)
267 return (scsi_detach_target(sc, sdev->sd_target, 0));
268
269 return (scsi_detach_lun(sc, sdev->sd_target, sdev->sd_lun, 0));
270
271 default:
272 return (ENOTTY);
273 }
274 }
275 #endif
276
277 int
278 scsi_probe_bus(struct scsibus_softc *sc)
279 {
280 struct scsi_link *alink = sc->adapter_link;
281 int i;
282
283 for (i = 0; i < alink->adapter_buswidth; i++)
284 scsi_probe_target(sc, i);
285
286 return (0);
287 }
288
289 int
290 scsi_probe_target(struct scsibus_softc *sc, int target)
291 {
292 struct scsi_link *alink = sc->adapter_link;
293 struct scsi_link *link;
294 struct scsi_report_luns_data *report;
295 int i, nluns, lun;
296
297 if (scsi_probe_lun(sc, target, 0) == EINVAL)
298 return (EINVAL);
299
300 link = sc->sc_link[target][0];
301 if (link == NULL)
302 return (ENXIO);
303
304 if ((link->flags & (SDEV_UMASS | SDEV_ATAPI)) == 0 &&
305 SCSISPC(link->inqdata.version) > 2) {
306 report = malloc(sizeof(*report), M_TEMP, M_WAITOK);
307 if (report == NULL)
308 goto dumbscan;
309
310 if (scsi_report_luns(link, REPORT_NORMAL, report,
311 sizeof(*report), scsi_autoconf | SCSI_SILENT |
312 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY |
313 SCSI_IGNORE_MEDIA_CHANGE, 10000) != 0) {
314 free(report, M_TEMP);
315 goto dumbscan;
316 }
317
318
319
320
321
322
323
324 nluns = _4btol(report->length) / RPL_LUNDATA_SIZE;
325 for (i = 0; i < nluns; i++) {
326 if (report->luns[i].lundata[0] != 0)
327 continue;
328 lun = report->luns[i].lundata[RPL_LUNDATA_T0LUN];
329 if (lun == 0)
330 continue;
331
332
333 sc->sc_link[target][0] = NULL;
334 scsi_probe_lun(sc, target, lun);
335 sc->sc_link[target][0] = link;
336 }
337
338 free(report, M_TEMP);
339 return (0);
340 }
341
342 dumbscan:
343 for (i = 1; i < alink->luns; i++) {
344 if (scsi_probe_lun(sc, target, i) == EINVAL)
345 break;
346 }
347
348 return (0);
349 }
350
351 int
352 scsi_probe_lun(struct scsibus_softc *sc, int target, int lun)
353 {
354 struct scsi_link *alink = sc->adapter_link;
355
356 if (target < 0 || target >= alink->adapter_buswidth ||
357 target == alink->adapter_target ||
358 lun < 0 || lun >= alink->luns)
359 return (ENXIO);
360
361 return (scsi_probedev(sc, target, lun));
362 }
363
364 int
365 scsi_detach_bus(struct scsibus_softc *sc, int flags)
366 {
367 struct scsi_link *alink = sc->adapter_link;
368 int i;
369
370 for (i = 0; i < alink->adapter_buswidth; i++)
371 scsi_detach_target(sc, i, flags);
372
373 return (0);
374 }
375
376 int
377 scsi_detach_target(struct scsibus_softc *sc, int target, int flags)
378 {
379 struct scsi_link *alink = sc->adapter_link;
380 int i, err, rv = 0, detached = 0;
381
382 if (target < 0 || target >= alink->adapter_buswidth ||
383 target == alink->adapter_target)
384 return (ENXIO);
385
386 if (sc->sc_link[target] == NULL)
387 return (ENXIO);
388
389 for (i = 0; i < alink->luns; i++) {
390 if (sc->sc_link[target][i] == NULL)
391 continue;
392
393 err = scsi_detach_lun(sc, target, i, flags);
394 if (err != 0)
395 rv = err;
396 detached = 1;
397 }
398
399 return (detached ? rv : ENXIO);
400 }
401
402 int
403 scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags)
404 {
405 struct scsi_link *alink = sc->adapter_link;
406 struct scsi_link *link;
407 int rv;
408
409 if (target < 0 || target >= alink->adapter_buswidth ||
410 target == alink->adapter_target ||
411 lun < 0 || lun >= alink->luns)
412 return (ENXIO);
413
414 if (sc->sc_link[target] == NULL)
415 return (ENXIO);
416
417 link = sc->sc_link[target][lun];
418 if (link == NULL)
419 return (ENXIO);
420
421 if (((flags & DETACH_FORCE) == 0) && (link->flags & SDEV_OPEN))
422 return (EBUSY);
423
424
425
426
427 rv = config_detach(link->device_softc, flags);
428 if (rv != 0)
429 return (rv);
430
431
432 free(link, M_DEVBUF);
433 sc->sc_link[target][lun] = NULL;
434
435 return (0);
436 }
437
438 void
439 scsi_strvis(u_char *dst, u_char *src, int len)
440 {
441 u_char last;
442
443
444 while (len > 0 && (src[0] == ' ' || src[0] == '\t' || src[0] == '\n' ||
445 src[0] == '\0' || src[0] == 0xff))
446 ++src, --len;
447 while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t' ||
448 src[len-1] == '\n' || src[len-1] == '\0' || src[len-1] == 0xff))
449 --len;
450
451 last = 0xff;
452 while (len > 0) {
453 switch (*src) {
454 case ' ':
455 case '\t':
456 case '\n':
457 case '\0':
458 case 0xff:
459
460 if (last != ' ')
461 *dst++ = ' ';
462 last = ' ';
463 break;
464 case '\\':
465
466 *dst++ = '\\';
467 *dst++ = '\\';
468 last = '\\';
469 break;
470 default:
471 if (*src < 0x20 || *src >= 0x80) {
472
473 *dst++ = '\\';
474 *dst++ = ((*src & 0300) >> 6) + '0';
475 *dst++ = ((*src & 0070) >> 3) + '0';
476 *dst++ = ((*src & 0007) >> 0) + '0';
477 } else {
478
479 *dst++ = *src;
480 }
481 last = *src;
482 break;
483 }
484 ++src, --len;
485 }
486
487 *dst++ = 0;
488 }
489
490 struct scsi_quirk_inquiry_pattern {
491 struct scsi_inquiry_pattern pattern;
492 u_int16_t quirks;
493 };
494
495 const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
496 {{T_CDROM, T_REMOV,
497 "PLEXTOR", "CD-ROM PX-40TS", "1.01"}, SDEV_NOSYNC},
498
499 {{T_DIRECT, T_FIXED,
500 "MICROP ", "1588-15MBSUN0669", ""}, SDEV_AUTOSAVE},
501 {{T_DIRECT, T_FIXED,
502 "DEC ", "RZ55 (C) DEC", ""}, SDEV_AUTOSAVE},
503 {{T_DIRECT, T_FIXED,
504 "EMULEX ", "MD21/S2 ESDI", "A00"}, SDEV_AUTOSAVE},
505 {{T_DIRECT, T_FIXED,
506 "IBMRAID ", "0662S", ""}, SDEV_AUTOSAVE},
507 {{T_DIRECT, T_FIXED,
508 "IBM ", "0663H", ""}, SDEV_AUTOSAVE},
509 {{T_DIRECT, T_FIXED,
510 "IBM", "0664", ""}, SDEV_AUTOSAVE},
511 {{T_DIRECT, T_FIXED,
512 "IBM ", "H3171-S2", ""}, SDEV_AUTOSAVE},
513 {{T_DIRECT, T_FIXED,
514 "IBM ", "KZ-C", ""}, SDEV_AUTOSAVE},
515
516 {{T_DIRECT, T_FIXED,
517 "" , "DFRSS2F", ""}, SDEV_AUTOSAVE},
518 {{T_DIRECT, T_FIXED,
519 "QUANTUM ", "ELS85S ", ""}, SDEV_AUTOSAVE},
520 {{T_DIRECT, T_REMOV,
521 "iomega", "jaz 1GB", ""}, SDEV_NOTAGS},
522 {{T_DIRECT, T_FIXED,
523 "MICROP", "4421-07", ""}, SDEV_NOTAGS},
524 {{T_DIRECT, T_FIXED,
525 "SEAGATE", "ST150176LW", "0002"}, SDEV_NOTAGS},
526 {{T_DIRECT, T_FIXED,
527 "HP", "C3725S", ""}, SDEV_NOTAGS},
528 {{T_DIRECT, T_FIXED,
529 "IBM", "DCAS", ""}, SDEV_NOTAGS},
530
531 {{T_SEQUENTIAL, T_REMOV,
532 "SONY ", "SDT-5000 ", "3."}, SDEV_NOSYNC|SDEV_NOWIDE},
533 {{T_SEQUENTIAL, T_REMOV,
534 "WangDAT ", "Model 1300 ", "02.4"}, SDEV_NOSYNC|SDEV_NOWIDE},
535 {{T_SEQUENTIAL, T_REMOV,
536 "WangDAT ", "Model 2600 ", "01.7"}, SDEV_NOSYNC|SDEV_NOWIDE},
537 {{T_SEQUENTIAL, T_REMOV,
538 "WangDAT ", "Model 3200 ", "02.2"}, SDEV_NOSYNC|SDEV_NOWIDE},
539
540
541 {{T_CDROM, T_REMOV,
542 "ALPS ELECTRIC CO.,LTD. DC544C", "", "SW03D"}, ADEV_NOTUR},
543 {{T_CDROM, T_REMOV,
544 "CR-2801TE", "", "1.07"}, ADEV_NOSENSE},
545 {{T_CDROM, T_REMOV,
546 "CREATIVECD3630E", "", "AC101"}, ADEV_NOSENSE},
547 {{T_CDROM, T_REMOV,
548 "FX320S", "", "q01"}, ADEV_NOSENSE},
549 {{T_CDROM, T_REMOV,
550 "GCD-R580B", "", "1.00"}, ADEV_LITTLETOC},
551 {{T_CDROM, T_REMOV,
552 "MATSHITA CR-574", "", "1.02"}, ADEV_NOCAPACITY},
553 {{T_CDROM, T_REMOV,
554 "MATSHITA CR-574", "", "1.06"}, ADEV_NOCAPACITY},
555 {{T_CDROM, T_REMOV,
556 "Memorex CRW-2642", "", "1.0g"}, ADEV_NOSENSE},
557 {{T_CDROM, T_REMOV,
558 "NEC CD-ROM DRIVE:273", "", "4.21"}, ADEV_NOTUR},
559 {{T_CDROM, T_REMOV,
560 "SANYO CRD-256P", "", "1.02"}, ADEV_NOCAPACITY},
561 {{T_CDROM, T_REMOV,
562 "SANYO CRD-254P", "", "1.02"}, ADEV_NOCAPACITY},
563 {{T_CDROM, T_REMOV,
564 "SANYO CRD-S54P", "", "1.08"}, ADEV_NOCAPACITY},
565 {{T_CDROM, T_REMOV,
566 "CD-ROM CDR-S1", "", "1.70"}, ADEV_NOCAPACITY},
567 {{T_CDROM, T_REMOV,
568 "CD-ROM CDR-N16", "", "1.25"}, ADEV_NOCAPACITY},
569 {{T_CDROM, T_REMOV,
570 "UJDCD8730", "", "1.14"}, ADEV_NODOORLOCK},
571 };
572
573
574
575
576
577
578
579
580
581
582
583
584 int
585 scsibusprint(void *aux, const char *pnp)
586 {
587 struct scsi_attach_args *sa = aux;
588 struct scsi_inquiry_data *inqbuf;
589 u_int8_t type;
590 int removable;
591 char *dtype, *qtype;
592 char vendor[33], product[65], revision[17];
593 int target, lun;
594
595 if (pnp != NULL)
596 printf("%s", pnp);
597
598 inqbuf = sa->sa_inqbuf;
599
600 target = sa->sa_sc_link->target;
601 lun = sa->sa_sc_link->lun;
602
603 type = inqbuf->device & SID_TYPE;
604 removable = inqbuf->dev_qual2 & SID_REMOVABLE ? 1 : 0;
605
606
607
608
609 dtype = 0;
610 switch (inqbuf->device & SID_QUAL) {
611 case SID_QUAL_LU_OK:
612 qtype = "";
613 break;
614
615 case SID_QUAL_LU_OFFLINE:
616 qtype = " offline";
617 break;
618
619 case SID_QUAL_RSVD:
620 panic("scsibusprint: qualifier == SID_QUAL_RSVD");
621
622 case SID_QUAL_BAD_LU:
623 panic("scsibusprint: qualifier == SID_QUAL_BAD_LU");
624
625 default:
626 qtype = "";
627 dtype = "vendor-unique";
628 break;
629 }
630 if (dtype == 0) {
631 switch (type) {
632 case T_DIRECT:
633 dtype = "direct";
634 break;
635 case T_SEQUENTIAL:
636 dtype = "sequential";
637 break;
638 case T_PRINTER:
639 dtype = "printer";
640 break;
641 case T_PROCESSOR:
642 dtype = "processor";
643 break;
644 case T_CDROM:
645 dtype = "cdrom";
646 break;
647 case T_WORM:
648 dtype = "worm";
649 break;
650 case T_SCANNER:
651 dtype = "scanner";
652 break;
653 case T_OPTICAL:
654 dtype = "optical";
655 break;
656 case T_CHANGER:
657 dtype = "changer";
658 break;
659 case T_COMM:
660 dtype = "communication";
661 break;
662 case T_ENCLOSURE:
663 dtype = "enclosure services";
664 break;
665 case T_RDIRECT:
666 dtype = "simplified direct";
667 break;
668 case T_NODEVICE:
669 panic("scsibusprint: device type T_NODEVICE");
670 default:
671 dtype = "unknown";
672 break;
673 }
674 }
675
676 scsi_strvis(vendor, inqbuf->vendor, 8);
677 scsi_strvis(product, inqbuf->product, 16);
678 scsi_strvis(revision, inqbuf->revision, 4);
679
680 printf(" targ %d lun %d: <%s, %s, %s> SCSI%d %d/%s %s%s",
681 target, lun, vendor, product, revision,
682 SCSISPC(inqbuf->version), type, dtype,
683 removable ? "removable" : "fixed", qtype);
684
685 return (UNCONF);
686 }
687
688
689
690
691
692
693
694 int
695 scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
696 {
697 const struct scsi_quirk_inquiry_pattern *finger;
698 static struct scsi_inquiry_data inqbuf;
699 struct scsi_attach_args sa;
700 struct scsi_link *sc_link;
701 struct cfdata *cf;
702 int priority, rslt = 0;
703
704
705 if (scsi->sc_link[target][lun] != NULL)
706 return (0);
707
708 sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
709 if (sc_link == NULL)
710 return (EINVAL);
711
712 *sc_link = *scsi->adapter_link;
713 sc_link->target = target;
714 sc_link->lun = lun;
715 sc_link->device = &probe_switch;
716
717 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_link created.\n"));
718
719
720
721
722
723
724
725 sc_link->quirks |= SDEV_NOSYNC | SDEV_NOWIDE | SDEV_NOTAGS;
726
727
728
729
730 #ifdef SCSIDEBUG
731 if (((1 << sc_link->scsibus) & scsidebug_buses) &&
732 ((1 << target) & scsidebug_targets) &&
733 ((1 << lun) & scsidebug_luns))
734 sc_link->flags |= scsidebug_level;
735 #endif
736
737 #if defined(mvme68k)
738 if (lun == 0) {
739
740 scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
741 scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
742 SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
743 }
744 #endif
745
746
747 rslt = scsi_inquire(sc_link, &inqbuf, scsi_autoconf | SCSI_SILENT);
748 if (rslt != 0) {
749 SC_DEBUG(sc_link, SDEV_DB2, ("Bad LUN. rslt = %i\n", rslt));
750 if (lun == 0)
751 rslt = EINVAL;
752 goto bad;
753 }
754
755 switch (inqbuf.device & SID_QUAL) {
756 case SID_QUAL_RSVD:
757 case SID_QUAL_BAD_LU:
758 case SID_QUAL_LU_OFFLINE:
759 SC_DEBUG(sc_link, SDEV_DB1,
760 ("Bad LUN. SID_QUAL = 0x%02x\n", inqbuf.device & SID_QUAL));
761 goto bad;
762
763 case SID_QUAL_LU_OK:
764 if ((inqbuf.device & SID_TYPE) == T_NODEVICE) {
765 SC_DEBUG(sc_link, SDEV_DB1,
766 ("Bad LUN. SID_TYPE = T_NODEVICE\n"));
767 goto bad;
768 }
769 break;
770
771 default:
772 break;
773 }
774
775 if (lun == 0 || scsi->sc_link[target][0] == NULL)
776 ;
777 else if (sc_link->flags & SDEV_UMASS)
778 ;
779 else if (memcmp(&inqbuf, &scsi->sc_link[target][0]->inqdata,
780 sizeof inqbuf) == 0) {
781
782 SC_DEBUG(sc_link, SDEV_DB1, ("IDENTIFY not supported.\n"));
783 rslt = EINVAL;
784 goto bad;
785 }
786
787 finger = (const struct scsi_quirk_inquiry_pattern *)scsi_inqmatch(
788 &inqbuf, scsi_quirk_patterns,
789 sizeof(scsi_quirk_patterns)/sizeof(scsi_quirk_patterns[0]),
790 sizeof(scsi_quirk_patterns[0]), &priority);
791
792
793
794
795
796 if (SCSISPC(inqbuf.version) >= 2) {
797 if ((inqbuf.flags & SID_CmdQue) != 0)
798 sc_link->quirks &= ~SDEV_NOTAGS;
799 if ((inqbuf.flags & SID_Sync) != 0)
800 sc_link->quirks &= ~SDEV_NOSYNC;
801 if ((inqbuf.flags & SID_WBus16) != 0)
802 sc_link->quirks &= ~SDEV_NOWIDE;
803 }
804
805
806
807 if (priority != 0)
808 sc_link->quirks |= finger->quirks;
809
810
811
812
813 memcpy(&sc_link->inqdata, &inqbuf, sizeof(sc_link->inqdata));
814
815
816
817
818 if ((inqbuf.dev_qual2 & SID_REMOVABLE) != 0)
819 sc_link->flags |= SDEV_REMOVABLE;
820
821 sa.sa_sc_link = sc_link;
822 sa.sa_inqbuf = &sc_link->inqdata;
823
824 if ((cf = config_search(scsibussubmatch, (struct device *)scsi,
825 &sa)) == 0) {
826 scsibusprint(&sa, scsi->sc_dev.dv_xname);
827 printf(" not configured\n");
828 goto bad;
829 }
830
831
832
833
834
835
836
837
838 if (lun == 0 && (sc_link->flags & SDEV_UMASS) &&
839 scsi->sc_link[target][1] == NULL && sc_link->luns > 1) {
840 sc_link->lun = 1;
841 scsi_inquire(sc_link, &inqbuf, scsi_autoconf | SCSI_SILENT);
842 sc_link->lun = 0;
843 }
844
845 scsi->sc_link[target][lun] = sc_link;
846
847
848
849
850
851
852
853
854
855
856 scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
857 scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
858 SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
859
860 config_attach((struct device *)scsi, cf, &sa, scsibusprint);
861
862 return (0);
863
864 bad:
865 free(sc_link, M_DEVBUF);
866 return (rslt);
867 }
868
869
870
871
872
873 const void *
874 scsi_inqmatch(struct scsi_inquiry_data *inqbuf, const void *_base,
875 int nmatches, int matchsize, int *bestpriority)
876 {
877 u_int8_t type;
878 int removable;
879 const void *bestmatch;
880 const unsigned char *base = (const unsigned char *)_base;
881
882
883 type = inqbuf->device;
884 removable = inqbuf->dev_qual2 & SID_REMOVABLE ? T_REMOV : T_FIXED;
885
886 for (*bestpriority = 0, bestmatch = 0; nmatches--; base += matchsize) {
887 struct scsi_inquiry_pattern *match = (void *)base;
888 int priority, len;
889
890 if (type != match->type)
891 continue;
892 if (removable != match->removable)
893 continue;
894 priority = 2;
895 len = strlen(match->vendor);
896 if (bcmp(inqbuf->vendor, match->vendor, len))
897 continue;
898 priority += len;
899 len = strlen(match->product);
900 if (bcmp(inqbuf->product, match->product, len))
901 continue;
902 priority += len;
903 len = strlen(match->revision);
904 if (bcmp(inqbuf->revision, match->revision, len))
905 continue;
906 priority += len;
907
908 #if SCSIDEBUG
909 printf("scsi_inqmatch: %d/%d/%d <%s, %s, %s>\n",
910 priority, match->type, match->removable,
911 match->vendor, match->product, match->revision);
912 #endif
913 if (priority > *bestpriority) {
914 *bestpriority = priority;
915 bestmatch = base;
916 }
917 }
918
919 return (bestmatch);
920 }