scsiconf.c revision 1.109 1 /* $NetBSD: scsiconf.c,v 1.109 1998/10/08 18:46:15 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * Originally written by Julian Elischer (julian (at) tfs.com)
41 * for TRW Financial Systems for use under the MACH(2.5) operating system.
42 *
43 * TRW Financial Systems, in accordance with their agreement with Carnegie
44 * Mellon University, makes this software available to CMU to distribute
45 * or use in any manner that they see fit as long as this message is kept with
46 * the software. For this reason TFS also grants any other persons or
47 * organisations permission to use or modify this software.
48 *
49 * TFS supplies this software to be publicly redistributed
50 * on the understanding that TFS is not responsible for the correct
51 * functioning of this software in any circumstances.
52 *
53 * Ported to run under 386BSD by Julian Elischer (julian (at) tfs.com) Sept 1992
54 */
55
56 #include <sys/types.h>
57 #include <sys/param.h>
58 #include <sys/systm.h>
59 #include <sys/malloc.h>
60 #include <sys/device.h>
61
62 #include <dev/scsipi/scsi_all.h>
63 #include <dev/scsipi/scsipi_all.h>
64 #include <dev/scsipi/scsiconf.h>
65
66 #include "locators.h"
67
68 #if 0
69 #if NCALS > 0
70 { T_PROCESSOR, T_FIXED, 1,
71 0, 0, 0 },
72 #endif /* NCALS */
73 #if NBLL > 0
74 { T_PROCESSOR, T_FIXED, 1,
75 "AEG ", "READER ", "V1.0" },
76 #endif /* NBLL */
77 #if NKIL > 0
78 { T_SCANNER, T_FIXED, 0,
79 "KODAK ", "IL Scanner 900 ", 0 },
80 #endif /* NKIL */
81 #endif
82
83 /*
84 * Declarations
85 */
86 void scsi_probedev __P((struct scsibus_softc *, int, int));
87 int scsi_probe_bus __P((int bus, int target, int lun));
88
89 struct scsipi_device probe_switch = {
90 NULL,
91 NULL,
92 NULL,
93 NULL,
94 };
95
96 int scsibusmatch __P((struct device *, struct cfdata *, void *));
97 void scsibusattach __P((struct device *, struct device *, void *));
98 int scsibussubmatch __P((struct device *, struct cfdata *, void *));
99
100 struct cfattach scsibus_ca = {
101 sizeof(struct scsibus_softc), scsibusmatch, scsibusattach
102 };
103
104 extern struct cfdriver scsibus_cd;
105
106 int scsibusprint __P((void *, const char *));
107
108
109 int
110 scsiprint(aux, pnp)
111 void *aux;
112 const char *pnp;
113 {
114 struct scsipi_link *l = aux;
115
116 /* only "scsibus"es can attach to "scsi"s; easy. */
117 if (pnp)
118 printf("scsibus at %s", pnp);
119
120 /* don't print channel if the controller says there can be only one. */
121 if (l->scsipi_scsi.channel != SCSI_CHANNEL_ONLY_ONE)
122 printf(" channel %d", l->scsipi_scsi.channel);
123
124 return (UNCONF);
125 }
126
127 int
128 scsibusmatch(parent, cf, aux)
129 struct device *parent;
130 struct cfdata *cf;
131 void *aux;
132 {
133 struct scsipi_link *l = aux;
134 int channel;
135
136 /*
137 * Allow single-channel controllers to specify their channel
138 * in a special way, so that it's not printed.
139 */
140 channel = (l->scsipi_scsi.channel != SCSI_CHANNEL_ONLY_ONE) ?
141 l->scsipi_scsi.channel : 0;
142
143 if (cf->cf_loc[SCSICF_CHANNEL] != channel &&
144 cf->cf_loc[SCSICF_CHANNEL] != SCSICF_CHANNEL_DEFAULT)
145 return (0);
146
147 return (1);
148 }
149
150 /*
151 * The routine called by the adapter boards to get all their
152 * devices configured in.
153 */
154 void
155 scsibusattach(parent, self, aux)
156 struct device *parent, *self;
157 void *aux;
158 {
159 struct scsibus_softc *sb = (struct scsibus_softc *)self;
160 struct scsipi_link *sc_link_proto = aux;
161 size_t nbytes;
162 int i;
163
164 sc_link_proto->scsipi_scsi.scsibus = sb->sc_dev.dv_unit;
165 sc_link_proto->scsipi_cmd = scsi_scsipi_cmd;
166 sc_link_proto->scsipi_interpret_sense = scsi_interpret_sense;
167 sc_link_proto->sc_print_addr = scsi_print_addr;
168
169 sb->adapter_link = sc_link_proto;
170 sb->sc_maxtarget = sc_link_proto->scsipi_scsi.max_target;
171 printf(": %d targets\n", sb->sc_maxtarget + 1);
172
173 /* Initialize shared data. */
174 scsipi_init();
175
176 nbytes = sb->sc_maxtarget * sizeof(struct scsipi_link **);
177 sb->sc_link = (struct scsipi_link ***)malloc(nbytes, M_DEVBUF,
178 M_NOWAIT);
179 if (sb->sc_link == NULL)
180 panic("scsibusattach: can't allocate target links");
181
182 nbytes = 8 * sizeof(struct scsipi_link *);
183 for (i = 0; i <= sb->sc_maxtarget; i++) {
184 sb->sc_link[i] = (struct scsipi_link **)malloc(nbytes,
185 M_DEVBUF, M_NOWAIT);
186 if (sb->sc_link[i] == NULL)
187 panic("scsibusattach: can't allocate lun links");
188 bzero(sb->sc_link[i], nbytes);
189 }
190
191 #if defined(SCSI_DELAY) && SCSI_DELAY > 2
192 printf("%s: waiting for scsi devices to settle\n",
193 sb->sc_dev.dv_xname);
194 #else /* SCSI_DELAY > 2 */
195 #undef SCSI_DELAY
196 #define SCSI_DELAY 2
197 #endif /* SCSI_DELAY */
198 delay(1000000 * SCSI_DELAY);
199
200 scsi_probe_bus(sb->sc_dev.dv_unit, -1, -1);
201 }
202
203 int
204 scsibussubmatch(parent, cf, aux)
205 struct device *parent;
206 struct cfdata *cf;
207 void *aux;
208 {
209 struct scsipibus_attach_args *sa = aux;
210 struct scsipi_link *sc_link = sa->sa_sc_link;
211
212 if (cf->cf_loc[SCSIBUSCF_TARGET] != SCSIBUSCF_TARGET_DEFAULT &&
213 cf->cf_loc[SCSIBUSCF_TARGET] != sc_link->scsipi_scsi.target)
214 return (0);
215 if (cf->cf_loc[SCSIBUSCF_LUN] != SCSIBUSCF_LUN_DEFAULT &&
216 cf->cf_loc[SCSIBUSCF_LUN] != sc_link->scsipi_scsi.lun)
217 return (0);
218 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
219 }
220
221 /*
222 * Probe the requested scsi bus. It must be already set up.
223 * -1 requests all set up scsi busses.
224 * target and lun optionally narrow the search if not -1
225 */
226 int
227 scsi_probe_busses(bus, target, lun)
228 int bus, target, lun;
229 {
230
231 if (bus == -1) {
232 for (bus = 0; bus < scsibus_cd.cd_ndevs; bus++)
233 if (scsibus_cd.cd_devs[bus])
234 scsi_probe_bus(bus, target, lun);
235 return (0);
236 } else
237 return (scsi_probe_bus(bus, target, lun));
238 }
239
240 /*
241 * Probe the requested scsi bus. It must be already set up.
242 * target and lun optionally narrow the search if not -1
243 */
244 int
245 scsi_probe_bus(bus, target, lun)
246 int bus, target, lun;
247 {
248 struct scsibus_softc *scsi;
249 int maxtarget, mintarget, maxlun, minlun;
250 u_int8_t scsi_addr;
251
252 if (bus < 0 || bus >= scsibus_cd.cd_ndevs)
253 return (ENXIO);
254 scsi = scsibus_cd.cd_devs[bus];
255 if (scsi == NULL)
256 return (ENXIO);
257
258 scsi_addr = scsi->adapter_link->scsipi_scsi.adapter_target;
259
260 if (target == -1) {
261 maxtarget = scsi->sc_maxtarget;
262 mintarget = 0;
263 } else {
264 if (target < 0 || target > scsi->sc_maxtarget)
265 return (EINVAL);
266 maxtarget = mintarget = target;
267 }
268
269 if (lun == -1) {
270 maxlun = 7;
271 minlun = 0;
272 } else {
273 if (lun < 0 || lun > 7)
274 return (EINVAL);
275 maxlun = minlun = lun;
276 }
277
278 for (target = mintarget; target <= maxtarget; target++) {
279 if (target == scsi_addr)
280 continue;
281 for (lun = minlun; lun <= maxlun; lun++) {
282 /*
283 * See if there's a device present, and configure it.
284 */
285 scsi_probedev(scsi, target, lun);
286 if ((scsi->moreluns & (1 << target)) == 0)
287 break;
288 /* otherwise something says we should look further */
289 }
290 }
291 return (0);
292 }
293
294 /*
295 * Print out autoconfiguration information for a subdevice.
296 *
297 * This is a slight abuse of 'standard' autoconfiguration semantics,
298 * because 'print' functions don't normally print the colon and
299 * device information. However, in this case that's better than
300 * either printing redundant information before the attach message,
301 * or having the device driver call a special function to print out
302 * the standard device information.
303 */
304 int
305 scsibusprint(aux, pnp)
306 void *aux;
307 const char *pnp;
308 {
309 struct scsipibus_attach_args *sa = aux;
310 struct scsipi_inquiry_pattern *inqbuf;
311 u_int8_t type;
312 char *dtype, *qtype;
313 char vendor[33], product[65], revision[17];
314 int target, lun;
315
316 if (pnp != NULL)
317 printf("%s", pnp);
318
319 inqbuf = &sa->sa_inqbuf;
320
321 target = sa->sa_sc_link->scsipi_scsi.target;
322 lun = sa->sa_sc_link->scsipi_scsi.lun;
323
324 type = inqbuf->type & SID_TYPE;
325
326 /*
327 * Figure out basic device type and qualifier.
328 */
329 dtype = 0;
330 switch (inqbuf->type & SID_QUAL) {
331 case SID_QUAL_LU_OK:
332 qtype = "";
333 break;
334
335 case SID_QUAL_LU_OFFLINE:
336 qtype = " offline";
337 break;
338
339 case SID_QUAL_RSVD:
340 case SID_QUAL_BAD_LU:
341 panic("scsibusprint: impossible qualifier");
342
343 default:
344 qtype = "";
345 dtype = "vendor-unique";
346 break;
347 }
348 if (dtype == 0)
349 dtype = scsipi_dtype(type);
350
351 scsipi_strvis(vendor, 33, inqbuf->vendor, 8);
352 scsipi_strvis(product, 65, inqbuf->product, 16);
353 scsipi_strvis(revision, 17, inqbuf->revision, 4);
354
355 printf(" targ %d lun %d: <%s, %s, %s> SCSI%d %d/%s %s%s",
356 target, lun, vendor, product, revision,
357 sa->scsipi_info.scsi_version & SID_ANSII, type, dtype,
358 inqbuf->removable ? "removable" : "fixed", qtype);
359
360 return (UNCONF);
361 }
362
363 struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
364 {{T_CDROM, T_REMOV,
365 "CHINON ", "CD-ROM CDS-431 ", ""}, SDEV_NOLUNS},
366 {{T_CDROM, T_REMOV,
367 "Chinon ", "CD-ROM CDS-525 ", ""}, SDEV_NOLUNS},
368 {{T_CDROM, T_REMOV,
369 "CHINON ", "CD-ROM CDS-535 ", ""}, SDEV_NOLUNS},
370 {{T_CDROM, T_REMOV,
371 "DEC ", "RRD42 (C) DEC ", ""}, SDEV_NOLUNS},
372 {{T_CDROM, T_REMOV,
373 "DENON ", "DRD-25X ", "V"}, SDEV_NOLUNS},
374 {{T_CDROM, T_REMOV,
375 "HP ", "C4324/C4325 ", ""}, SDEV_NOLUNS},
376 {{T_CDROM, T_REMOV,
377 "IMS ", "CDD521/10 ", "2.06"}, SDEV_NOLUNS},
378 {{T_CDROM, T_REMOV,
379 "MATSHITA", "CD-ROM CR-5XX ", "1.0b"}, SDEV_NOLUNS},
380 {{T_CDROM, T_REMOV,
381 "MEDAVIS ", "RENO CD-ROMX2A ", ""}, SDEV_NOLUNS},
382 {{T_CDROM, T_REMOV,
383 "MEDIAVIS", "CDR-H93MV ", "1.3"}, SDEV_NOLUNS},
384 {{T_CDROM, T_REMOV,
385 "NEC ", "CD-ROM DRIVE:55 ", ""}, SDEV_NOLUNS},
386 {{T_CDROM, T_REMOV,
387 "NEC ", "CD-ROM DRIVE:83 ", ""}, SDEV_NOLUNS},
388 {{T_CDROM, T_REMOV,
389 "NEC ", "CD-ROM DRIVE:84 ", ""}, SDEV_NOLUNS},
390 {{T_CDROM, T_REMOV,
391 "NEC ", "CD-ROM DRIVE:841", ""}, SDEV_NOLUNS},
392 {{T_CDROM, T_REMOV,
393 "PIONEER ", "CD-ROM DR-124X ", "1.01"}, SDEV_NOLUNS},
394 {{T_CDROM, T_REMOV,
395 "SONY ", "CD-ROM CDU-541 ", ""}, SDEV_NOLUNS},
396 {{T_CDROM, T_REMOV,
397 "SONY ", "CD-ROM CDU-55S ", ""}, SDEV_NOLUNS},
398 {{T_CDROM, T_REMOV,
399 "SONY ", "CD-ROM CDU-8003A", ""}, SDEV_NOLUNS},
400 {{T_CDROM, T_REMOV,
401 "SONY ", "CD-ROM CDU-8012 ", ""}, SDEV_NOLUNS},
402 {{T_CDROM, T_REMOV,
403 "TEAC ", "CD-ROM ", "1.06"}, SDEV_NOLUNS},
404 {{T_CDROM, T_REMOV,
405 "TEAC ", "CD-ROM CD-56S ", "1.0B"}, SDEV_NOLUNS},
406 {{T_CDROM, T_REMOV,
407 "TEXEL ", "CD-ROM ", "1.06"}, SDEV_NOLUNS},
408 {{T_CDROM, T_REMOV,
409 "TEXEL ", "CD-ROM DM-XX24 K", "1.10"}, SDEV_NOLUNS},
410 {{T_CDROM, T_REMOV,
411 "TOSHIBA ", "XM-4101TASUNSLCD", "1755"}, SDEV_NOLUNS},
412 {{T_CDROM, T_REMOV,
413 "ShinaKen", "CD-ROM DM-3x1S", "1.04"}, SDEV_NOLUNS},
414 {{T_CDROM, T_REMOV,
415 "JVC ", "R2626 ", "1.55"}, SDEV_NOLUNS},
416 {{T_DIRECT, T_FIXED,
417 "MICROP ", "1588-15MBSUN0669", ""}, SDEV_AUTOSAVE},
418 {{T_OPTICAL, T_REMOV,
419 "EPSON ", "OMD-5010 ", "3.08"}, SDEV_NOLUNS},
420
421 {{T_DIRECT, T_FIXED,
422 "DEC ", "RZ55 (C) DEC", ""}, SDEV_AUTOSAVE},
423 {{T_DIRECT, T_FIXED,
424 "EMULEX ", "MD21/S2 ESDI", "A00"}, SDEV_FORCELUNS|SDEV_AUTOSAVE},
425 /* Gives non-media hardware failure in response to start-unit command */
426 {{T_DIRECT, T_FIXED,
427 "HITACHI", "DK515C", "CP16"}, SDEV_NOSTARTUNIT},
428 {{T_DIRECT, T_FIXED,
429 "HITACHI", "DK515C", "CP15"}, SDEV_NOSTARTUNIT},
430 {{T_DIRECT, T_FIXED,
431 "HP ", "C372", ""}, SDEV_NOTAG},
432 {{T_DIRECT, T_FIXED,
433 "IBMRAID ", "0662S", ""}, SDEV_AUTOSAVE},
434 {{T_DIRECT, T_FIXED,
435 "IBM ", "0663H", ""}, SDEV_AUTOSAVE},
436 {{T_DIRECT, T_FIXED,
437 "IBM", "0664", ""}, SDEV_AUTOSAVE},
438 {{T_DIRECT, T_FIXED,
439 "IBM ", "H3171-S2", ""}, SDEV_NOLUNS|SDEV_AUTOSAVE},
440 {{T_DIRECT, T_FIXED,
441 "IBM ", "KZ-C", ""}, SDEV_AUTOSAVE},
442 /* Broken IBM disk */
443 {{T_DIRECT, T_FIXED,
444 "" , "DFRSS2F", ""}, SDEV_AUTOSAVE},
445 {{T_DIRECT, T_REMOV,
446 "MPL ", "MC-DISK- ", ""}, SDEV_NOLUNS},
447 {{T_DIRECT, T_FIXED,
448 "MAXTOR ", "XT-3280 ", ""}, SDEV_NOLUNS},
449 {{T_DIRECT, T_FIXED,
450 "MAXTOR ", "XT-4380S ", ""}, SDEV_NOLUNS},
451 {{T_DIRECT, T_FIXED,
452 "MAXTOR ", "MXT-1240S ", ""}, SDEV_NOLUNS},
453 {{T_DIRECT, T_FIXED,
454 "MAXTOR ", "XT-4170S ", ""}, SDEV_NOLUNS},
455 {{T_DIRECT, T_FIXED,
456 "MAXTOR ", "XT-8760S", ""}, SDEV_NOLUNS},
457 {{T_DIRECT, T_FIXED,
458 "MAXTOR ", "LXT-213S ", ""}, SDEV_NOLUNS},
459 {{T_DIRECT, T_FIXED,
460 "MAXTOR ", "LXT-213S SUN0207", ""}, SDEV_NOLUNS},
461 {{T_DIRECT, T_FIXED,
462 "MAXTOR ", "LXT-200S ", ""}, SDEV_NOLUNS},
463 {{T_DIRECT, T_FIXED,
464 "MEGADRV ", "EV1000", ""}, SDEV_NOMODESENSE},
465 {{T_DIRECT, T_FIXED,
466 "MST ", "SnapLink ", ""}, SDEV_NOLUNS},
467 {{T_DIRECT, T_FIXED,
468 "NEC ", "D3847 ", "0307"}, SDEV_NOLUNS},
469 {{T_DIRECT, T_FIXED,
470 "QUANTUM ", "ELS85S ", ""}, SDEV_AUTOSAVE},
471 {{T_DIRECT, T_FIXED,
472 "QUANTUM ", "LPS525S ", ""}, SDEV_NOLUNS},
473 {{T_DIRECT, T_FIXED,
474 "QUANTUM ", "P105S 910-10-94x", ""}, SDEV_NOLUNS},
475 {{T_DIRECT, T_FIXED,
476 "QUANTUM ", "PD1225S ", ""}, SDEV_NOLUNS},
477 {{T_DIRECT, T_FIXED,
478 "QUANTUM ", "PD210S SUN0207", ""}, SDEV_NOLUNS},
479 {{T_DIRECT, T_FIXED,
480 "RODIME ", "RO3000S ", ""}, SDEV_NOLUNS},
481 {{T_DIRECT, T_FIXED,
482 "SEAGATE ", "ST125N ", ""}, SDEV_NOLUNS},
483 {{T_DIRECT, T_FIXED,
484 "SEAGATE ", "ST157N ", ""}, SDEV_NOLUNS},
485 {{T_DIRECT, T_FIXED,
486 "SEAGATE ", "ST296 ", ""}, SDEV_NOLUNS},
487 {{T_DIRECT, T_FIXED,
488 "SEAGATE ", "ST296N ", ""}, SDEV_NOLUNS},
489 {{T_DIRECT, T_FIXED,
490 "SEAGATE ", "ST19171FC", ""}, SDEV_NOMODESENSE},
491 {{T_DIRECT, T_FIXED,
492 "SEAGATE ", "ST34501FC ", ""}, SDEV_NOMODESENSE},
493 {{T_DIRECT, T_FIXED,
494 "TOSHIBA ", "MK538FB ", "6027"}, SDEV_NOLUNS},
495 {{T_DIRECT, T_REMOV,
496 "iomega", "jaz 1GB", ""}, SDEV_NOMODESENSE},
497 {{T_DIRECT, T_REMOV,
498 "IOMEGA", "ZIP 100", ""}, SDEV_NOMODESENSE},
499 /* Letting the motor run kills floppy drives and disks quite fast. */
500 {{T_DIRECT, T_REMOV,
501 "TEAC", "FC-1", ""}, SDEV_NOSTARTUNIT},
502
503 /* XXX: QIC-36 tape behind Emulex adapter. Very broken. */
504 {{T_SEQUENTIAL, T_REMOV,
505 " ", " ", " "}, SDEV_NOLUNS},
506 {{T_SEQUENTIAL, T_REMOV,
507 "CALIPER ", "CP150 ", ""}, SDEV_NOLUNS},
508 {{T_SEQUENTIAL, T_REMOV,
509 "EXABYTE ", "EXB-8200 ", ""}, SDEV_NOLUNS},
510 {{T_SEQUENTIAL, T_REMOV,
511 "SONY ", "GY-10C ", ""}, SDEV_NOLUNS},
512 {{T_SEQUENTIAL, T_REMOV,
513 "SONY ", "SDT-2000 ", "2.09"}, SDEV_NOLUNS},
514 {{T_SEQUENTIAL, T_REMOV,
515 "SONY ", "SDT-5000 ", "3."}, SDEV_NOSYNC|SDEV_NOWIDE},
516 {{T_SEQUENTIAL, T_REMOV,
517 "SONY ", "SDT-5200 ", "3."}, SDEV_NOLUNS},
518 {{T_SEQUENTIAL, T_REMOV,
519 "TANDBERG", " TDC 3600 ", ""}, SDEV_NOLUNS},
520 /* Following entry reported as a Tandberg 3600; ref. PR1933 */
521 {{T_SEQUENTIAL, T_REMOV,
522 "ARCHIVE ", "VIPER 150 21247", ""}, SDEV_NOLUNS},
523 /* Following entry for a Cipher ST150S; ref. PR4171 */
524 {{T_SEQUENTIAL, T_REMOV,
525 "ARCHIVE ", "VIPER 1500 21247", "2.2G"}, SDEV_NOLUNS},
526 {{T_SEQUENTIAL, T_REMOV,
527 "ARCHIVE ", "Python 28454-XXX", ""}, SDEV_NOLUNS},
528 {{T_SEQUENTIAL, T_REMOV,
529 "WANGTEK ", "5099ES SCSI", ""}, SDEV_NOLUNS},
530 {{T_SEQUENTIAL, T_REMOV,
531 "WANGTEK ", "5150ES SCSI", ""}, SDEV_NOLUNS},
532 {{T_SEQUENTIAL, T_REMOV,
533 "WangDAT ", "Model 1300 ", "02.4"}, SDEV_NOSYNC|SDEV_NOWIDE},
534 {{T_SEQUENTIAL, T_REMOV,
535 "WangDAT ", "Model 2600 ", "01.7"}, SDEV_NOSYNC|SDEV_NOWIDE},
536 {{T_SEQUENTIAL, T_REMOV,
537 "WangDAT ", "Model 3200 ", "02.2"}, SDEV_NOSYNC|SDEV_NOWIDE},
538
539 {{T_SCANNER, T_FIXED,
540 "RICOH ", "IS60 ", "1R08"}, SDEV_NOLUNS},
541 {{T_SCANNER, T_FIXED,
542 "UMAX ", "Astra 1200S ", "V2.9"}, SDEV_NOLUNS},
543 {{T_SCANNER, T_FIXED,
544 "UMAX ", "Astra 1220S ", "V1.2"}, SDEV_NOLUNS},
545 {{T_SCANNER, T_FIXED,
546 "UMAX ", "UMAX S-6E ", "V2.0"}, SDEV_NOLUNS},
547 {{T_SCANNER, T_FIXED,
548 "UMAX ", "UMAX S-12 ", "V2.1"}, SDEV_NOLUNS},
549
550 {{T_PROCESSOR, T_FIXED,
551 "LITRONIC", "PCMCIA ", ""}, SDEV_NOLUNS},
552
553 {{T_CHANGER, T_REMOV,
554 "SONY ", "CDL1100 ", ""}, SDEV_NOLUNS},
555 };
556
557 /*
558 * given a target and lun, ask the device what
559 * it is, and find the correct driver table
560 * entry.
561 */
562 void
563 scsi_probedev(scsi, target, lun)
564 struct scsibus_softc *scsi;
565 int target, lun;
566 {
567 struct scsipi_link *sc_link;
568 static struct scsipi_inquiry_data inqbuf;
569 struct scsi_quirk_inquiry_pattern *finger;
570 int checkdtype, priority;
571 struct scsipibus_attach_args sa;
572 struct cfdata *cf;
573
574 /* Skip this slot if it is already attached. */
575 if (scsi->sc_link[target][lun] != NULL)
576 return;
577
578 sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
579 *sc_link = *scsi->adapter_link;
580 sc_link->scsipi_scsi.target = target;
581 sc_link->scsipi_scsi.lun = lun;
582 sc_link->device = &probe_switch;
583
584 /*
585 * Ask the device what it is
586 */
587 #if defined(SCSIDEBUG) && DEBUGTYPE == BUS_SCSI
588 if (target == DEBUGTARGET && lun == DEBUGLUN)
589 sc_link->flags |= DEBUGLEVEL;
590 #endif /* SCSIDEBUG */
591
592 (void) scsipi_test_unit_ready(sc_link,
593 SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST |
594 SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
595
596 #ifdef SCSI_2_DEF
597 /* some devices need to be told to go to SCSI2 */
598 /* However some just explode if you tell them this.. leave it out */
599 scsi_change_def(sc_link, SCSI_AUTOCONF | SCSI_SILENT);
600 #endif /* SCSI_2_DEF */
601
602 /* Now go ask the device all about itself. */
603 bzero(&inqbuf, sizeof(inqbuf));
604 if (scsipi_inquire(sc_link, &inqbuf, SCSI_AUTOCONF) != 0)
605 goto bad;
606
607 {
608 int len = inqbuf.additional_length;
609 while (len < 3)
610 inqbuf.unused[len++] = '\0';
611 while (len < 3 + 28)
612 inqbuf.unused[len++] = ' ';
613 }
614
615 sa.sa_sc_link = sc_link;
616 sa.sa_inqbuf.type = inqbuf.device;
617 sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
618 T_REMOV : T_FIXED;
619 sa.sa_inqbuf.vendor = inqbuf.vendor;
620 sa.sa_inqbuf.product = inqbuf.product;
621 sa.sa_inqbuf.revision = inqbuf.revision;
622 sa.scsipi_info.scsi_version = inqbuf.version;
623
624 finger = (struct scsi_quirk_inquiry_pattern *)scsipi_inqmatch(
625 &sa.sa_inqbuf, (caddr_t)scsi_quirk_patterns,
626 sizeof(scsi_quirk_patterns)/sizeof(scsi_quirk_patterns[0]),
627 sizeof(scsi_quirk_patterns[0]), &priority);
628
629 /*
630 * Based upon the inquiry flags we got back, and if we're
631 * at SCSI-2 or better, set some limiting quirks.
632 */
633 if ((inqbuf.version & SID_ANSII) >= 2) {
634 if ((inqbuf.flags & SID_CmdQue) == 0)
635 sc_link->quirks |= SDEV_NOTAG;
636 if ((inqbuf.flags & SID_Sync) == 0)
637 sc_link->quirks |= SDEV_NOSYNC;
638 if ((inqbuf.flags & SID_WBus16) == 0)
639 sc_link->quirks |= SDEV_NOWIDE;
640 }
641 /*
642 * Now apply any quirks from the table.
643 */
644 if (priority != 0)
645 sc_link->quirks |= finger->quirks;
646 if ((inqbuf.version & SID_ANSII) == 0 &&
647 (sc_link->quirks & SDEV_FORCELUNS) == 0)
648 sc_link->quirks |= SDEV_NOLUNS;
649 sc_link->scsipi_scsi.scsi_version = inqbuf.version;
650
651 if ((sc_link->quirks & SDEV_NOLUNS) == 0)
652 scsi->moreluns |= (1 << target);
653
654 /*
655 * note what BASIC type of device it is
656 */
657 if ((inqbuf.dev_qual2 & SID_REMOVABLE) != 0)
658 sc_link->flags |= SDEV_REMOVABLE;
659
660 /*
661 * Any device qualifier that has the top bit set (qualifier&4 != 0)
662 * is vendor specific and won't match in this switch.
663 * All we do here is throw out bad/negative responses.
664 */
665 checkdtype = 0;
666 switch (inqbuf.device & SID_QUAL) {
667 case SID_QUAL_LU_OK:
668 case SID_QUAL_LU_OFFLINE:
669 checkdtype = 1;
670 break;
671
672 case SID_QUAL_RSVD:
673 case SID_QUAL_BAD_LU:
674 goto bad;
675
676 default:
677 break;
678 }
679 if (checkdtype)
680 switch (inqbuf.device & SID_TYPE) {
681 case T_DIRECT:
682 case T_SEQUENTIAL:
683 case T_PRINTER:
684 case T_PROCESSOR:
685 case T_WORM:
686 case T_CDROM:
687 case T_SCANNER:
688 case T_OPTICAL:
689 case T_CHANGER:
690 case T_COMM:
691 case T_IT8_1:
692 case T_IT8_2:
693 case T_STORARRAY:
694 case T_ENCLOSURE:
695 default:
696 break;
697 case T_NODEVICE:
698 goto bad;
699 }
700
701 if ((cf = config_search(scsibussubmatch, (struct device *)scsi,
702 &sa)) != NULL) {
703 scsi->sc_link[target][lun] = sc_link;
704 config_attach((struct device *)scsi, cf, &sa, scsibusprint);
705 } else {
706 scsibusprint(&sa, scsi->sc_dev.dv_xname);
707 printf(" not configured\n");
708 goto bad;
709 }
710
711 return;
712
713 bad:
714 free(sc_link, M_DEVBUF);
715 return;
716 }
717