xref: /openbsd-src/sys/scsi/scsiconf.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: scsiconf.c,v 1.188 2014/07/12 18:50:25 tedu 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 "bio.h"
51 #include "mpath.h"
52 
53 #include <sys/types.h>
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/malloc.h>
57 #include <sys/pool.h>
58 #include <sys/device.h>
59 #include <sys/buf.h>
60 #include <sys/lock.h>
61 
62 #include <scsi/scsi_all.h>
63 #include <scsi/scsiconf.h>
64 #include <scsi/mpathvar.h>
65 
66 #if NBIO > 0
67 #include <sys/ioctl.h>
68 #include <sys/scsiio.h>
69 #include <dev/biovar.h>
70 #endif
71 
72 /*
73  * Declarations
74  */
75 int	scsi_probedev(struct scsibus_softc *, int, int);
76 
77 void	scsi_devid(struct scsi_link *);
78 int	scsi_devid_pg80(struct scsi_link *);
79 int	scsi_devid_pg83(struct scsi_link *);
80 int	scsi_devid_wwn(struct scsi_link *);
81 
82 int	scsibusmatch(struct device *, void *, void *);
83 void	scsibusattach(struct device *, struct device *, void *);
84 int	scsibusactivate(struct device *, int);
85 int	scsibusdetach(struct device *, int);
86 
87 int	scsibussubmatch(struct device *, void *, void *);
88 
89 #if NBIO > 0
90 int	scsibus_bioctl(struct device *, u_long, caddr_t);
91 #endif
92 
93 struct cfattach scsibus_ca = {
94 	sizeof(struct scsibus_softc), scsibusmatch, scsibusattach,
95 	scsibusdetach, scsibusactivate
96 };
97 
98 struct cfdriver scsibus_cd = {
99 	NULL, "scsibus", DV_DULL
100 };
101 
102 #ifdef SCSIDEBUG
103 u_int32_t scsidebug_buses = SCSIDEBUG_BUSES;
104 u_int32_t scsidebug_targets = SCSIDEBUG_TARGETS;
105 u_int32_t scsidebug_luns = SCSIDEBUG_LUNS;
106 int scsidebug_level = SCSIDEBUG_LEVEL;
107 #endif
108 
109 int scsi_autoconf = SCSI_AUTOCONF;
110 
111 int scsibusprint(void *, const char *);
112 void scsibus_printlink(struct scsi_link *);
113 
114 int scsi_activate_bus(struct scsibus_softc *, int);
115 int scsi_activate_target(struct scsibus_softc *, int, int);
116 int scsi_activate_lun(struct scsibus_softc *, int, int, int);
117 
118 const u_int8_t version_to_spc [] = {
119 	0, /* 0x00: The device does not claim conformance to any standard. */
120 	1, /* 0x01: (Obsolete) SCSI-1 in olden times. */
121 	2, /* 0x02: (Obsolete) SCSI-2 in olden times. */
122 	3, /* 0x03: The device complies to ANSI INCITS 301-1997 (SPC-3). */
123 	2, /* 0x04: The device complies to ANSI INCITS 351-2001 (SPC-2). */
124 	3, /* 0x05: The device complies to ANSI INCITS 408-2005 (SPC-3). */
125 	4, /* 0x06: The device complies to SPC-4. */
126 	0, /* 0x07: RESERVED. */
127 };
128 
129 int
130 scsiprint(void *aux, const char *pnp)
131 {
132 	/* only "scsibus"es can attach to "scsi"s; easy. */
133 	if (pnp)
134 		printf("scsibus at %s", pnp);
135 
136 	return (UNCONF);
137 }
138 
139 int
140 scsibusmatch(struct device *parent, void *match, void *aux)
141 {
142 	return (1);
143 }
144 
145 /*
146  * The routine called by the adapter boards to get all their
147  * devices configured in.
148  */
149 void
150 scsibusattach(struct device *parent, struct device *self, void *aux)
151 {
152 	struct scsibus_softc		*sb = (struct scsibus_softc *)self;
153 	struct scsibus_attach_args	*saa = aux;
154 	struct scsi_link		*sc_link_proto = saa->saa_sc_link;
155 
156 	if (!cold)
157 		scsi_autoconf = 0;
158 
159 	sc_link_proto->bus = sb;
160 	sc_link_proto->scsibus = sb->sc_dev.dv_unit;
161 	sb->adapter_link = sc_link_proto;
162 	if (sb->adapter_link->adapter_buswidth == 0)
163 		sb->adapter_link->adapter_buswidth = 8;
164 	sb->sc_buswidth = sb->adapter_link->adapter_buswidth;
165 	if (sb->adapter_link->luns == 0)
166 		sb->adapter_link->luns = 8;
167 
168 	printf(": %d targets", sb->sc_buswidth);
169 	if (sb->adapter_link->adapter_target < sb->sc_buswidth)
170 		printf(", initiator %d", sb->adapter_link->adapter_target);
171 	if (sb->adapter_link->port_wwn != 0x0 &&
172 	    sb->adapter_link->node_wwn != 0x0) {
173 		printf(", WWPN %016llx, WWNN %016llx",
174 		    sb->adapter_link->port_wwn, sb->adapter_link->node_wwn);
175 	}
176 	printf("\n");
177 
178 	/* Initialize shared data. */
179 	scsi_init();
180 
181 	SLIST_INIT(&sb->sc_link);
182 
183 #if NBIO > 0
184 	if (bio_register(&sb->sc_dev, scsibus_bioctl) != 0)
185 		printf("%s: unable to register bio\n", sb->sc_dev.dv_xname);
186 #endif
187 
188 	scsi_probe_bus(sb);
189 }
190 
191 int
192 scsibusactivate(struct device *dev, int act)
193 {
194 	struct scsibus_softc *sc = (struct scsibus_softc *)dev;
195 
196 	return scsi_activate(sc, -1, -1, act);
197 }
198 
199 int
200 scsi_activate(struct scsibus_softc *sc, int target, int lun, int act)
201 {
202 	if (target == -1 && lun == -1)
203 		return scsi_activate_bus(sc, act);
204 
205 	if (target == -1)
206 		return 0;
207 
208 	if (lun == -1)
209 		return scsi_activate_target(sc, target, act);
210 
211 	return scsi_activate_lun(sc, target, lun, act);
212 }
213 
214 int
215 scsi_activate_bus(struct scsibus_softc *sc, int act)
216 {
217 	int target, rv = 0, r;
218 
219 	for (target = 0; target < sc->sc_buswidth; target++) {
220 		r = scsi_activate_target(sc, target, act);
221 		if (r)
222 			rv = r;
223 	}
224 	return (rv);
225 }
226 
227 int
228 scsi_activate_target(struct scsibus_softc *sc, int target, int act)
229 {
230 	int lun, rv = 0, r;
231 
232 	for (lun = 0; lun < sc->adapter_link->luns; lun++) {
233 		r = scsi_activate_lun(sc, target, lun, act);
234 		if (r)
235 			rv = r;
236 	}
237 	return (rv);
238 }
239 
240 int
241 scsi_activate_lun(struct scsibus_softc *sc, int target, int lun, int act)
242 {
243 	struct scsi_link *link;
244 	struct device *dev;
245 	int rv = 0;
246 
247 	link = scsi_get_link(sc, target, lun);
248 	if (link == NULL)
249 		return (0);
250 
251 	dev = link->device_softc;
252 	switch (act) {
253 	case DVACT_DEACTIVATE:
254 		atomic_setbits_int(&link->state, SDEV_S_DYING);
255 		config_deactivate(dev);
256 		break;
257 	default:
258 		rv = config_suspend(dev, act);
259 		break;
260 	}
261 	return (rv);
262 }
263 
264 int
265 scsibusdetach(struct device *dev, int type)
266 {
267 	struct scsibus_softc		*sb = (struct scsibus_softc *)dev;
268 	int				error;
269 
270 #if NBIO > 0
271 	bio_unregister(&sb->sc_dev);
272 #endif
273 
274 	error = scsi_detach_bus(sb, type);
275 	if (error != 0)
276 		return (error);
277 
278 	KASSERT(SLIST_EMPTY(&sb->sc_link));
279 
280 	return (0);
281 }
282 
283 int
284 scsibussubmatch(struct device *parent, void *match, void *aux)
285 {
286 	struct cfdata			*cf = match;
287 	struct scsi_attach_args		*sa = aux;
288 	struct scsi_link		*sc_link = sa->sa_sc_link;
289 
290 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != sc_link->target)
291 		return (0);
292 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != sc_link->lun)
293 		return (0);
294 
295 	return ((*cf->cf_attach->ca_match)(parent, match, aux));
296 }
297 
298 #if NBIO > 0
299 int
300 scsibus_bioctl(struct device *dev, u_long cmd, caddr_t addr)
301 {
302 	struct scsibus_softc		*sc = (struct scsibus_softc *)dev;
303 	struct sbioc_device		*sdev;
304 
305 	switch (cmd) {
306 	case SBIOCPROBE:
307 		sdev = (struct sbioc_device *)addr;
308 		return (scsi_probe(sc, sdev->sd_target, sdev->sd_lun));
309 
310 	case SBIOCDETACH:
311 		sdev = (struct sbioc_device *)addr;
312 		return (scsi_detach(sc, sdev->sd_target, sdev->sd_lun, 0));
313 
314 	default:
315 		return (ENOTTY);
316 	}
317 }
318 #endif
319 
320 int
321 scsi_probe_bus(struct scsibus_softc *sc)
322 {
323 	struct scsi_link *alink = sc->adapter_link;
324 	int i;
325 
326 	for (i = 0; i < alink->adapter_buswidth; i++)
327 		scsi_probe_target(sc, i);
328 
329 	return (0);
330 }
331 
332 int
333 scsi_probe_target(struct scsibus_softc *sc, int target)
334 {
335 	struct scsi_link *alink = sc->adapter_link;
336 	struct scsi_link *link;
337 	struct scsi_report_luns_data *report;
338 	int i, nluns, lun;
339 
340 	if (scsi_probe_lun(sc, target, 0) == EINVAL)
341 		return (EINVAL);
342 
343 	link = scsi_get_link(sc, target, 0);
344 	if (link == NULL)
345 		return (ENXIO);
346 
347 	if ((link->flags & (SDEV_UMASS | SDEV_ATAPI)) == 0 &&
348 	    SCSISPC(link->inqdata.version) > 2) {
349 		report = dma_alloc(sizeof(*report), PR_WAITOK);
350 		if (report == NULL)
351 			goto dumbscan;
352 
353 		if (scsi_report_luns(link, REPORT_NORMAL, report,
354 		    sizeof(*report), scsi_autoconf | SCSI_SILENT |
355 		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY |
356 		    SCSI_IGNORE_MEDIA_CHANGE, 10000) != 0) {
357 			dma_free(report, sizeof(*report));
358 			goto dumbscan;
359 		}
360 
361 		/*
362 		 * XXX In theory we should check if data is full, which
363 		 * would indicate it needs to be enlarged and REPORT
364 		 * LUNS tried again. Solaris tries up to 3 times with
365 		 * larger sizes for data.
366 		 */
367 		nluns = _4btol(report->length) / RPL_LUNDATA_SIZE;
368 		for (i = 0; i < nluns; i++) {
369 			if (report->luns[i].lundata[0] != 0)
370 				continue;
371 			lun = report->luns[i].lundata[RPL_LUNDATA_T0LUN];
372 			if (lun == 0)
373 				continue;
374 
375 			/* Probe the provided LUN. Don't check LUN 0. */
376 			scsi_remove_link(sc, link);
377 			scsi_probe_lun(sc, target, lun);
378 			scsi_add_link(sc, link);
379 		}
380 
381 		dma_free(report, sizeof(*report));
382 		return (0);
383 	}
384 
385 dumbscan:
386 	for (i = 1; i < alink->luns; i++) {
387 		if (scsi_probe_lun(sc, target, i) == EINVAL)
388 			break;
389 	}
390 
391 	return (0);
392 }
393 
394 int
395 scsi_probe(struct scsibus_softc *sc, int target, int lun)
396 {
397 	if (target == -1 && lun == -1)
398 		return (scsi_probe_bus(sc));
399 
400 	/* specific lun and wildcard target is bad */
401 	if (target == -1)
402 		return (EINVAL);
403 
404 	if (lun == -1)
405 		return (scsi_probe_target(sc, target));
406 
407 	return (scsi_probe_lun(sc, target, lun));
408 }
409 
410 int
411 scsi_probe_lun(struct scsibus_softc *sc, int target, int lun)
412 {
413 	struct scsi_link *alink = sc->adapter_link;
414 
415 	if (target < 0 || target >= alink->adapter_buswidth ||
416 	    target == alink->adapter_target ||
417 	    lun < 0 || lun >= alink->luns)
418 		return (ENXIO);
419 
420 	return (scsi_probedev(sc, target, lun));
421 }
422 
423 int
424 scsi_detach_bus(struct scsibus_softc *sc, int flags)
425 {
426 	struct scsi_link *alink = sc->adapter_link;
427 	int i, err, rv = 0;
428 
429 	for (i = 0; i < alink->adapter_buswidth; i++) {
430 		err = scsi_detach_target(sc, i, flags);
431 		if (err != 0 && err != ENXIO)
432 			rv = err;
433 	}
434 
435 	return (rv);
436 }
437 
438 int
439 scsi_detach(struct scsibus_softc *sc, int target, int lun, int flags)
440 {
441 	if (target == -1 && lun == -1)
442 		return (scsi_detach_bus(sc, flags));
443 
444 	/* specific lun and wildcard target is bad */
445 	if (target == -1)
446 		return (EINVAL);
447 
448 	if (lun == -1)
449 		return (scsi_detach_target(sc, target, flags));
450 
451 	return (scsi_detach_lun(sc, target, lun, flags));
452 }
453 
454 int
455 scsi_detach_target(struct scsibus_softc *sc, int target, int flags)
456 {
457 	struct scsi_link *alink = sc->adapter_link;
458 	int i, err, rv = 0;
459 
460 	if (target < 0 || target >= alink->adapter_buswidth ||
461 	    target == alink->adapter_target)
462 		return (ENXIO);
463 
464 	for (i = 0; i < alink->luns; i++) { /* nicer backwards? */
465 		if (scsi_get_link(sc, target, i) == NULL)
466 			continue;
467 
468 		err = scsi_detach_lun(sc, target, i, flags);
469 		if (err != 0 && err != ENXIO)
470 			rv = err;
471 	}
472 
473 	return (rv);
474 }
475 
476 int
477 scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags)
478 {
479 	struct scsi_link *alink = sc->adapter_link;
480 	struct scsi_link *link;
481 	int rv;
482 
483 	if (target < 0 || target >= alink->adapter_buswidth ||
484 	    target == alink->adapter_target ||
485 	    lun < 0 || lun >= alink->luns)
486 		return (ENXIO);
487 
488 	link = scsi_get_link(sc, target, lun);
489 	if (link == NULL)
490 		return (ENXIO);
491 
492 	if (((flags & DETACH_FORCE) == 0) && (link->flags & SDEV_OPEN))
493 		return (EBUSY);
494 
495 	/* detaching a device from scsibus is a five step process... */
496 
497 	/* 1. wake up processes sleeping for an xs */
498 	scsi_link_shutdown(link);
499 
500 	/* 2. detach the device */
501 	rv = config_detach(link->device_softc, flags);
502 
503 	if (rv != 0)
504 		return (rv);
505 
506 	/* 3. if its using the openings io allocator, clean it up */
507 	if (ISSET(link->flags, SDEV_OWN_IOPL)) {
508 		scsi_iopool_destroy(link->pool);
509 		free(link->pool, M_DEVBUF, 0);
510 	}
511 
512 	/* 4. free up its state in the adapter */
513 	if (alink->adapter->dev_free != NULL)
514 		alink->adapter->dev_free(link);
515 
516 	/* 5. free up its state in the midlayer */
517 	if (link->id != NULL)
518 		devid_free(link->id);
519 	scsi_remove_link(sc, link);
520 	free(link, M_DEVBUF, 0);
521 
522 	return (0);
523 }
524 
525 struct scsi_link *
526 scsi_get_link(struct scsibus_softc *sc, int target, int lun)
527 {
528 	struct scsi_link *link;
529 
530 	SLIST_FOREACH(link, &sc->sc_link, bus_list)
531 		if (link->target == target && link->lun == lun)
532 			return (link);
533 
534 	return (NULL);
535 }
536 
537 void
538 scsi_add_link(struct scsibus_softc *sc, struct scsi_link *link)
539 {
540 	SLIST_INSERT_HEAD(&sc->sc_link, link, bus_list);
541 }
542 
543 void
544 scsi_remove_link(struct scsibus_softc *sc, struct scsi_link *link)
545 {
546 	SLIST_REMOVE(&sc->sc_link, link, scsi_link, bus_list);
547 }
548 
549 void
550 scsi_strvis(u_char *dst, u_char *src, int len)
551 {
552 	u_char				last;
553 
554 	/* Trim leading and trailing whitespace and NULs. */
555 	while (len > 0 && (src[0] == ' ' || src[0] == '\t' || src[0] == '\n' ||
556 	    src[0] == '\0' || src[0] == 0xff))
557 		++src, --len;
558 	while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t' ||
559 	    src[len-1] == '\n' || src[len-1] == '\0' || src[len-1] == 0xff))
560 		--len;
561 
562 	last = 0xff;
563 	while (len > 0) {
564 		switch (*src) {
565 		case ' ':
566 		case '\t':
567 		case '\n':
568 		case '\0':
569 		case 0xff:
570 			/* collapse whitespace and NULs to a single space */
571 			if (last != ' ')
572 				*dst++ = ' ';
573 			last = ' ';
574 			break;
575 		case '\\':
576 			/* quote characters */
577 			*dst++ = '\\';
578 			*dst++ = '\\';
579 			last = '\\';
580 			break;
581 		default:
582 			if (*src < 0x20 || *src >= 0x80) {
583 				/* non-printable characters */
584 				*dst++ = '\\';
585 				*dst++ = ((*src & 0300) >> 6) + '0';
586 				*dst++ = ((*src & 0070) >> 3) + '0';
587 				*dst++ = ((*src & 0007) >> 0) + '0';
588 			} else {
589 				/* normal characters */
590 				*dst++ = *src;
591 			}
592 			last = *src;
593 			break;
594 		}
595 		++src, --len;
596 	}
597 
598 	*dst++ = 0;
599 }
600 
601 struct scsi_quirk_inquiry_pattern {
602 	struct scsi_inquiry_pattern	pattern;
603 	u_int16_t			quirks;
604 };
605 
606 const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
607 	{{T_CDROM, T_REMOV,
608 	 "PLEXTOR", "CD-ROM PX-40TS", "1.01"},    SDEV_NOSYNC},
609 
610 	{{T_DIRECT, T_FIXED,
611 	 "MICROP  ", "1588-15MBSUN0669", ""},     SDEV_AUTOSAVE},
612 	{{T_DIRECT, T_FIXED,
613 	 "DEC     ", "RZ55     (C) DEC", ""},     SDEV_AUTOSAVE},
614 	{{T_DIRECT, T_FIXED,
615 	 "EMULEX  ", "MD21/S2     ESDI", "A00"},  SDEV_AUTOSAVE},
616 	{{T_DIRECT, T_FIXED,
617 	 "IBMRAID ", "0662S",            ""},     SDEV_AUTOSAVE},
618 	{{T_DIRECT, T_FIXED,
619 	 "IBM     ", "0663H",            ""},     SDEV_AUTOSAVE},
620 	{{T_DIRECT, T_FIXED,
621 	 "IBM",	  "0664",		 ""},	  SDEV_AUTOSAVE},
622 	{{T_DIRECT, T_FIXED,
623 	 "IBM     ", "H3171-S2",         ""},	  SDEV_AUTOSAVE},
624 	{{T_DIRECT, T_FIXED,
625 	 "IBM     ", "KZ-C",		 ""},	  SDEV_AUTOSAVE},
626 	/* Broken IBM disk */
627 	{{T_DIRECT, T_FIXED,
628 	 ""	   , "DFRSS2F",		 ""},	  SDEV_AUTOSAVE},
629 	{{T_DIRECT, T_FIXED,
630 	 "QUANTUM ", "ELS85S          ", ""},	  SDEV_AUTOSAVE},
631 	{{T_DIRECT, T_REMOV,
632 	 "iomega", "jaz 1GB",		 ""},	  SDEV_NOTAGS},
633         {{T_DIRECT, T_FIXED,
634          "MICROP", "4421-07",		 ""},     SDEV_NOTAGS},
635         {{T_DIRECT, T_FIXED,
636          "SEAGATE", "ST150176LW",        "0002"}, SDEV_NOTAGS},
637         {{T_DIRECT, T_FIXED,
638          "HP", "C3725S",		 ""},     SDEV_NOTAGS},
639         {{T_DIRECT, T_FIXED,
640          "IBM", "DCAS",			 ""},     SDEV_NOTAGS},
641 
642 	{{T_SEQUENTIAL, T_REMOV,
643 	 "SONY    ", "SDT-5000        ", "3."},   SDEV_NOSYNC|SDEV_NOWIDE},
644 	{{T_SEQUENTIAL, T_REMOV,
645 	 "WangDAT ", "Model 1300      ", "02.4"}, SDEV_NOSYNC|SDEV_NOWIDE},
646 	{{T_SEQUENTIAL, T_REMOV,
647 	 "WangDAT ", "Model 2600      ", "01.7"}, SDEV_NOSYNC|SDEV_NOWIDE},
648 	{{T_SEQUENTIAL, T_REMOV,
649 	 "WangDAT ", "Model 3200      ", "02.2"}, SDEV_NOSYNC|SDEV_NOWIDE},
650 
651 	/* ATAPI device quirks */
652         {{T_CDROM, T_REMOV,
653          "CR-2801TE", "", "1.07"},              ADEV_NOSENSE},
654         {{T_CDROM, T_REMOV,
655          "CREATIVECD3630E", "", "AC101"},       ADEV_NOSENSE},
656         {{T_CDROM, T_REMOV,
657          "FX320S", "", "q01"},                  ADEV_NOSENSE},
658         {{T_CDROM, T_REMOV,
659          "GCD-R580B", "", "1.00"},              ADEV_LITTLETOC},
660         {{T_CDROM, T_REMOV,
661          "MATSHITA CR-574", "", "1.02"},        ADEV_NOCAPACITY},
662         {{T_CDROM, T_REMOV,
663          "MATSHITA CR-574", "", "1.06"},        ADEV_NOCAPACITY},
664         {{T_CDROM, T_REMOV,
665          "Memorex CRW-2642", "", "1.0g"},       ADEV_NOSENSE},
666         {{T_CDROM, T_REMOV,
667          "SANYO CRD-256P", "", "1.02"},         ADEV_NOCAPACITY},
668         {{T_CDROM, T_REMOV,
669          "SANYO CRD-254P", "", "1.02"},         ADEV_NOCAPACITY},
670         {{T_CDROM, T_REMOV,
671          "SANYO CRD-S54P", "", "1.08"},         ADEV_NOCAPACITY},
672         {{T_CDROM, T_REMOV,
673          "CD-ROM  CDR-S1", "", "1.70"},         ADEV_NOCAPACITY}, /* Sanyo */
674         {{T_CDROM, T_REMOV,
675          "CD-ROM  CDR-N16", "", "1.25"},        ADEV_NOCAPACITY}, /* Sanyo */
676         {{T_CDROM, T_REMOV,
677          "UJDCD8730", "", "1.14"},              ADEV_NODOORLOCK}, /* Acer */
678 };
679 
680 
681 void
682 scsibus_printlink(struct scsi_link *link)
683 {
684 	char				vendor[33], product[65], revision[17];
685 	struct scsi_inquiry_data	*inqbuf;
686 	u_int8_t			type;
687 	int				removable;
688 	char				*dtype = NULL, *qtype = NULL;
689 
690 	inqbuf = &link->inqdata;
691 
692 	type = inqbuf->device & SID_TYPE;
693 	removable = inqbuf->dev_qual2 & SID_REMOVABLE ? 1 : 0;
694 
695 	/*
696 	 * Figure out basic device type and qualifier.
697 	 */
698 	switch (inqbuf->device & SID_QUAL) {
699 	case SID_QUAL_LU_OK:
700 		qtype = "";
701 		break;
702 
703 	case SID_QUAL_LU_OFFLINE:
704 		qtype = " offline";
705 		break;
706 
707 	case SID_QUAL_RSVD:
708 		panic("scsibusprint: qualifier == SID_QUAL_RSVD");
709 	case SID_QUAL_BAD_LU:
710 		panic("scsibusprint: qualifier == SID_QUAL_BAD_LU");
711 
712 	default:
713 		qtype = "";
714 		dtype = "vendor-unique";
715 		break;
716 	}
717 	if (dtype == NULL) {
718 		switch (type) {
719 		case T_DIRECT:
720 			dtype = "direct";
721 			break;
722 		case T_SEQUENTIAL:
723 			dtype = "sequential";
724 			break;
725 		case T_PRINTER:
726 			dtype = "printer";
727 			break;
728 		case T_PROCESSOR:
729 			dtype = "processor";
730 			break;
731 		case T_CDROM:
732 			dtype = "cdrom";
733 			break;
734 		case T_WORM:
735 			dtype = "worm";
736 			break;
737 		case T_SCANNER:
738 			dtype = "scanner";
739 			break;
740 		case T_OPTICAL:
741 			dtype = "optical";
742 			break;
743 		case T_CHANGER:
744 			dtype = "changer";
745 			break;
746 		case T_COMM:
747 			dtype = "communication";
748 			break;
749 		case T_ENCLOSURE:
750 			dtype = "enclosure services";
751 			break;
752 		case T_RDIRECT:
753 			dtype = "simplified direct";
754 			break;
755 		case T_NODEVICE:
756 			panic("scsibusprint: device type T_NODEVICE");
757 		default:
758 			dtype = "unknown";
759 			break;
760 		}
761 	}
762 
763 	scsi_strvis(vendor, inqbuf->vendor, 8);
764 	scsi_strvis(product, inqbuf->product, 16);
765 	scsi_strvis(revision, inqbuf->revision, 4);
766 
767 	printf(" targ %d lun %d: <%s, %s, %s> ", link->target, link->lun,
768 	    vendor, product, revision);
769 	if (link->flags & SDEV_ATAPI)
770 		printf("ATAPI");
771 	else
772 		printf("SCSI%d", SCSISPC(inqbuf->version));
773 	printf(" %d/%s %s%s", type, dtype, removable ? "removable" : "fixed",
774 	    qtype);
775 
776 	if (link->id != NULL && link->id->d_type != DEVID_NONE) {
777 		u_int8_t *id = (u_int8_t *)(link->id + 1);
778 		int i;
779 
780 		switch (link->id->d_type) {
781 		case DEVID_NAA:
782 			printf(" naa.");
783 			break;
784 		case DEVID_EUI:
785 			printf(" eui.");
786 			break;
787 		case DEVID_T10:
788 			printf(" t10.");
789 			break;
790 		case DEVID_SERIAL:
791 			printf(" serial.");
792 			break;
793 		case DEVID_WWN:
794 			printf(" wwn.");
795 			break;
796 		}
797 
798 		if (ISSET(link->id->d_flags, DEVID_F_PRINT)) {
799 			for (i = 0; i < link->id->d_len; i++) {
800 				if (id[i] == '\0' || id[i] == ' ') {
801 					/* skip leading blanks */
802 					/* collapse multiple blanks into one */
803 					if (i > 0 && id[i-1] != id[i])
804 						printf("_");
805 				} else if (id[i] < 0x20 || id[i] >= 0x80) {
806 					/* non-printable characters */
807 					printf("~");
808 				} else {
809 					/* normal characters */
810 					printf("%c", id[i]);
811 				}
812 			}
813 		} else {
814 			for (i = 0; i < link->id->d_len; i++)
815 				printf("%02x", id[i]);
816 		}
817 	}
818 }
819 
820 /*
821  * Print out autoconfiguration information for a subdevice.
822  *
823  * This is a slight abuse of 'standard' autoconfiguration semantics,
824  * because 'print' functions don't normally print the colon and
825  * device information.  However, in this case that's better than
826  * either printing redundant information before the attach message,
827  * or having the device driver call a special function to print out
828  * the standard device information.
829  */
830 int
831 scsibusprint(void *aux, const char *pnp)
832 {
833 	struct scsi_attach_args		*sa = aux;
834 
835 	if (pnp != NULL)
836 		printf("%s", pnp);
837 
838 	scsibus_printlink(sa->sa_sc_link);
839 
840 	return (UNCONF);
841 }
842 
843 /*
844  * Given a target and lun, ask the device what it is, and find the correct
845  * driver table entry.
846  *
847  * Return 0 if further LUNs are possible, EINVAL if not.
848  */
849 int
850 scsi_probedev(struct scsibus_softc *scsi, int target, int lun)
851 {
852 	const struct scsi_quirk_inquiry_pattern *finger;
853 	struct scsi_inquiry_data *inqbuf, *usbinqbuf;
854 	struct scsi_attach_args sa;
855 	struct scsi_link *sc_link, *link0;
856 	struct cfdata *cf;
857 	int priority, rslt = 0;
858 
859 	/* Skip this slot if it is already attached and try the next LUN. */
860 	if (scsi_get_link(scsi, target, lun) != NULL)
861 		return (0);
862 
863 	sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
864 	if (sc_link == NULL)
865 		return (EINVAL);
866 
867 	*sc_link = *scsi->adapter_link;
868 	sc_link->target = target;
869 	sc_link->lun = lun;
870 	sc_link->interpret_sense = scsi_interpret_sense;
871 	sc_link->node_wwn = sc_link->port_wwn = 0;
872 	TAILQ_INIT(&sc_link->queue);
873 
874 	SC_DEBUG(sc_link, SDEV_DB2, ("scsi_link created.\n"));
875 
876 	/* ask the adapter if this will be a valid device */
877 	if (scsi->adapter_link->adapter->dev_probe != NULL &&
878 	    scsi->adapter_link->adapter->dev_probe(sc_link) != 0) {
879 		if (lun == 0)
880 			rslt = EINVAL;
881 		goto free;
882 	}
883 
884 	/*
885 	 * If we havent been given an io pool by now then fall back to
886 	 * using sc_link->openings.
887 	 */
888 	if (sc_link->pool == NULL) {
889 		sc_link->pool = malloc(sizeof(*sc_link->pool),
890 		    M_DEVBUF, M_NOWAIT);
891 		if (sc_link->pool == NULL) {
892 			rslt = ENOMEM;
893 			goto bad;
894 		}
895 		scsi_iopool_init(sc_link->pool, sc_link,
896 		    scsi_default_get, scsi_default_put);
897 
898 		SET(sc_link->flags, SDEV_OWN_IOPL);
899 	}
900 
901 	/*
902 	 * Tell drivers that are paying attention to avoid sync/wide/tags until
903 	 * INQUIRY data has been processed and the quirks information is
904 	 * complete. Some drivers set bits in quirks before we get here, so
905 	 * just add NOTAGS, NOWIDE and NOSYNC.
906 	 */
907 	sc_link->quirks |= SDEV_NOSYNC | SDEV_NOWIDE | SDEV_NOTAGS;
908 
909 	/*
910 	 * Ask the device what it is
911 	 */
912 #ifdef SCSIDEBUG
913 	if (((scsi->sc_dev.dv_unit < 32) &&
914 	     ((1U << scsi->sc_dev.dv_unit) & scsidebug_buses)) &&
915 	    ((target < 32) && ((1U << target) & scsidebug_targets)) &&
916 	    ((lun < 32) && ((1U << lun) & scsidebug_luns)))
917 		sc_link->flags |= scsidebug_level;
918 #endif /* SCSIDEBUG */
919 
920 	if (lun == 0) {
921 		/* Clear any outstanding errors. */
922 		scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
923 		    scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
924 		    SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
925 	}
926 
927 	/* Now go ask the device all about itself. */
928 	inqbuf = dma_alloc(sizeof(*inqbuf), PR_NOWAIT | PR_ZERO);
929 	if (inqbuf == NULL) {
930 		rslt = ENOMEM;
931 		goto bad;
932 	}
933 
934 	rslt = scsi_inquire(sc_link, inqbuf, scsi_autoconf | SCSI_SILENT);
935 	bcopy(inqbuf, &sc_link->inqdata, sizeof(sc_link->inqdata));
936 	dma_free(inqbuf, sizeof(*inqbuf));
937 
938 	if (rslt != 0) {
939 		SC_DEBUG(sc_link, SDEV_DB2, ("Bad LUN. rslt = %i\n", rslt));
940 		if (lun == 0)
941 			rslt = EINVAL;
942 		goto bad;
943 	}
944 	inqbuf = &sc_link->inqdata;
945 
946 	switch (inqbuf->device & SID_QUAL) {
947 	case SID_QUAL_RSVD:
948 	case SID_QUAL_BAD_LU:
949 	case SID_QUAL_LU_OFFLINE:
950 		SC_DEBUG(sc_link, SDEV_DB1, ("Bad LUN. SID_QUAL = 0x%02x\n",
951 		    inqbuf->device & SID_QUAL));
952 		goto bad;
953 
954 	case SID_QUAL_LU_OK:
955 		if ((inqbuf->device & SID_TYPE) == T_NODEVICE) {
956 			SC_DEBUG(sc_link, SDEV_DB1,
957 		    	    ("Bad LUN. SID_TYPE = T_NODEVICE\n"));
958 			goto bad;
959 		}
960 		break;
961 
962 	default:
963 		break;
964 	}
965 
966 	scsi_devid(sc_link);
967 
968 	link0 = scsi_get_link(scsi, target, 0);
969 	if (lun == 0 || link0 == NULL)
970 		;
971 	else if (sc_link->flags & SDEV_UMASS)
972 		;
973 	else if (sc_link->id != NULL && !DEVID_CMP(link0->id, sc_link->id))
974 		;
975 	else if (memcmp(inqbuf, &link0->inqdata, sizeof(*inqbuf)) == 0) {
976 		/* The device doesn't distinguish between LUNs. */
977 		SC_DEBUG(sc_link, SDEV_DB1, ("IDENTIFY not supported.\n"));
978 		rslt = EINVAL;
979 		goto free_devid;
980 	}
981 
982 	finger = (const struct scsi_quirk_inquiry_pattern *)scsi_inqmatch(
983 	    inqbuf, scsi_quirk_patterns,
984 	    nitems(scsi_quirk_patterns),
985 	    sizeof(scsi_quirk_patterns[0]), &priority);
986 
987 	/*
988 	 * Based upon the inquiry flags we got back, and if we're
989 	 * at SCSI-2 or better, remove some limiting quirks.
990 	 */
991 	if (SCSISPC(inqbuf->version) >= 2) {
992 		if ((inqbuf->flags & SID_CmdQue) != 0)
993 			sc_link->quirks &= ~SDEV_NOTAGS;
994 		if ((inqbuf->flags & SID_Sync) != 0)
995 			sc_link->quirks &= ~SDEV_NOSYNC;
996 		if ((inqbuf->flags & SID_WBus16) != 0)
997 			sc_link->quirks &= ~SDEV_NOWIDE;
998 	} else
999 		/* Older devices do not have SYNCHRONIZE CACHE capability. */
1000 		sc_link->quirks |= SDEV_NOSYNCCACHE;
1001 
1002 	/*
1003 	 * Now apply any quirks from the table.
1004 	 */
1005 	if (priority != 0)
1006 		sc_link->quirks |= finger->quirks;
1007 
1008 	/*
1009 	 * If the device can't use tags, >1 opening may confuse it.
1010 	 */
1011 	if (ISSET(sc_link->quirks, SDEV_NOTAGS))
1012 		sc_link->openings = 1;
1013 
1014 	/*
1015 	 * note what BASIC type of device it is
1016 	 */
1017 	if ((inqbuf->dev_qual2 & SID_REMOVABLE) != 0)
1018 		sc_link->flags |= SDEV_REMOVABLE;
1019 
1020 	sa.sa_sc_link = sc_link;
1021 	sa.sa_inqbuf = &sc_link->inqdata;
1022 
1023 	if ((cf = config_search(scsibussubmatch, (struct device *)scsi,
1024 	    &sa)) == 0) {
1025 		scsibusprint(&sa, scsi->sc_dev.dv_xname);
1026 		printf(" not configured\n");
1027 		goto free_devid;
1028 	}
1029 
1030 	/*
1031 	 * Braindead USB devices, especially some x-in-1 media readers, try to
1032 	 * 'help' by pretending any LUN is actually LUN 0 until they see a
1033 	 * different LUN used in a command. So do an INQUIRY on LUN 1 at this
1034 	 * point to prevent such helpfulness before it causes confusion.
1035 	 */
1036 	if (lun == 0 && (sc_link->flags & SDEV_UMASS) &&
1037 	    scsi_get_link(scsi, target, 1) == NULL && sc_link->luns > 1 &&
1038 	    (usbinqbuf = dma_alloc(sizeof(*usbinqbuf), M_NOWAIT)) != NULL) {
1039 
1040 		sc_link->lun = 1;
1041 		scsi_inquire(sc_link, usbinqbuf, scsi_autoconf | SCSI_SILENT);
1042 	    	sc_link->lun = 0;
1043 
1044 		dma_free(usbinqbuf, sizeof(*usbinqbuf));
1045 	}
1046 
1047 	scsi_add_link(scsi, sc_link);
1048 
1049 	/*
1050 	 * Generate a TEST_UNIT_READY command. This gives drivers waiting for
1051 	 * valid quirks data a chance to set wide/sync/tag options
1052 	 * appropriately. It also clears any outstanding ACA conditions that
1053 	 * INQUIRY may leave behind.
1054 	 *
1055 	 * Do this now so that any messages generated by config_attach() do not
1056 	 * have negotiation messages inserted into their midst.
1057 	 */
1058 	scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
1059 	    scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST |
1060 	    SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
1061 
1062 	config_attach((struct device *)scsi, cf, &sa, scsibusprint);
1063 
1064 	return (0);
1065 
1066 free_devid:
1067 	if (sc_link->id)
1068 		devid_free(sc_link->id);
1069 bad:
1070 	if (ISSET(sc_link->flags, SDEV_OWN_IOPL))
1071 		free(sc_link->pool, M_DEVBUF, 0);
1072 
1073 	if (scsi->adapter_link->adapter->dev_free != NULL)
1074 		scsi->adapter_link->adapter->dev_free(sc_link);
1075 free:
1076 	free(sc_link, M_DEVBUF, 0);
1077 	return (rslt);
1078 }
1079 
1080 /*
1081  * Return a priority based on how much of the inquiry data matches
1082  * the patterns for the particular driver.
1083  */
1084 const void *
1085 scsi_inqmatch(struct scsi_inquiry_data *inqbuf, const void *_base,
1086     int nmatches, int matchsize, int *bestpriority)
1087 {
1088 	u_int8_t			type;
1089 	int				removable;
1090 	const void			*bestmatch;
1091 	const unsigned char		*base = (const unsigned char *)_base;
1092 
1093 	/* Include the qualifier to catch vendor-unique types. */
1094 	type = inqbuf->device;
1095 	removable = inqbuf->dev_qual2 & SID_REMOVABLE ? T_REMOV : T_FIXED;
1096 
1097 	for (*bestpriority = 0, bestmatch = 0; nmatches--; base += matchsize) {
1098 		struct scsi_inquiry_pattern *match = (void *)base;
1099 		int priority, len;
1100 
1101 		if (type != match->type)
1102 			continue;
1103 		if (removable != match->removable)
1104 			continue;
1105 		priority = 2;
1106 		len = strlen(match->vendor);
1107 		if (bcmp(inqbuf->vendor, match->vendor, len))
1108 			continue;
1109 		priority += len;
1110 		len = strlen(match->product);
1111 		if (bcmp(inqbuf->product, match->product, len))
1112 			continue;
1113 		priority += len;
1114 		len = strlen(match->revision);
1115 		if (bcmp(inqbuf->revision, match->revision, len))
1116 			continue;
1117 		priority += len;
1118 
1119 #ifdef SCSIDEBUG
1120 		printf("scsi_inqmatch: %d/%d/%d <%s, %s, %s>\n",
1121 		    priority, match->type, match->removable,
1122 		    match->vendor, match->product, match->revision);
1123 #endif
1124 		if (priority > *bestpriority) {
1125 			*bestpriority = priority;
1126 			bestmatch = base;
1127 		}
1128 	}
1129 
1130 	return (bestmatch);
1131 }
1132 
1133 void
1134 scsi_devid(struct scsi_link *link)
1135 {
1136 	struct {
1137 		struct scsi_vpd_hdr hdr;
1138 		u_int8_t list[32];
1139 	} __packed *pg;
1140 	int pg80 = 0, pg83 = 0, i;
1141 	size_t len;
1142 
1143 	if (link->id != NULL)
1144 		return;
1145 
1146 	pg = dma_alloc(sizeof(*pg), PR_WAITOK | PR_ZERO);
1147 
1148 	if (SCSISPC(link->inqdata.version) >= 2) {
1149 		if (scsi_inquire_vpd(link, pg, sizeof(*pg), SI_PG_SUPPORTED,
1150 		    scsi_autoconf) != 0)
1151 			goto wwn;
1152 
1153 		len = MIN(sizeof(pg->list), _2btol(pg->hdr.page_length));
1154 		for (i = 0; i < len; i++) {
1155 			switch (pg->list[i]) {
1156 			case SI_PG_SERIAL:
1157 				pg80 = 1;
1158 				break;
1159 			case SI_PG_DEVID:
1160 				pg83 = 1;
1161 				break;
1162 			}
1163 		}
1164 
1165 		if (pg83 && scsi_devid_pg83(link) == 0)
1166 			goto done;
1167 		if (pg80 && scsi_devid_pg80(link) == 0)
1168 			goto done;
1169 	}
1170 
1171 wwn:
1172 	scsi_devid_wwn(link);
1173 done:
1174 	dma_free(pg, sizeof(*pg));
1175 }
1176 
1177 int
1178 scsi_devid_pg83(struct scsi_link *link)
1179 {
1180 	struct scsi_vpd_hdr *hdr = NULL;
1181 	struct scsi_vpd_devid_hdr dhdr, chdr;
1182 	u_int8_t *pg = NULL, *id;
1183 	int type, idtype = 0;
1184 	u_char idflags;
1185 	int len, pos;
1186 	int rv;
1187 
1188 	hdr = dma_alloc(sizeof(*hdr), PR_WAITOK | PR_ZERO);
1189 
1190 	rv = scsi_inquire_vpd(link, hdr, sizeof(*hdr), SI_PG_DEVID,
1191 	    scsi_autoconf);
1192 	if (rv != 0)
1193 		goto done;
1194 
1195 	len = sizeof(*hdr) + _2btol(hdr->page_length);
1196 	pg = dma_alloc(len, PR_WAITOK | PR_ZERO);
1197 
1198 	rv = scsi_inquire_vpd(link, pg, len, SI_PG_DEVID, scsi_autoconf);
1199 	if (rv != 0)
1200 		goto done;
1201 
1202 	pos = sizeof(*hdr);
1203 
1204 	do {
1205 		if (len - pos < sizeof(dhdr)) {
1206 			rv = EIO;
1207 			goto done;
1208 		}
1209 		memcpy(&dhdr, &pg[pos], sizeof(dhdr));
1210 		pos += sizeof(dhdr);
1211 		if (len - pos < dhdr.len) {
1212 			rv = EIO;
1213 			goto done;
1214 		}
1215 
1216 		if (VPD_DEVID_ASSOC(dhdr.flags) == VPD_DEVID_ASSOC_LU) {
1217 			type = VPD_DEVID_TYPE(dhdr.flags);
1218 			switch (type) {
1219 			case VPD_DEVID_TYPE_NAA:
1220 			case VPD_DEVID_TYPE_EUI64:
1221 			case VPD_DEVID_TYPE_T10:
1222 				if (type >= idtype) {
1223 					idtype = type;
1224 
1225 					chdr = dhdr;
1226 					id = &pg[pos];
1227 				}
1228 				break;
1229 
1230 			default:
1231 				/* skip */
1232 				break;
1233 			}
1234 		}
1235 
1236 		pos += dhdr.len;
1237 	} while (idtype != VPD_DEVID_TYPE_NAA && len != pos);
1238 
1239 	if (idtype > 0) {
1240 		switch (VPD_DEVID_TYPE(chdr.flags)) {
1241 		case VPD_DEVID_TYPE_NAA:
1242 			idtype = DEVID_NAA;
1243 			break;
1244 		case VPD_DEVID_TYPE_EUI64:
1245 			idtype = DEVID_EUI;
1246 			break;
1247 		case VPD_DEVID_TYPE_T10:
1248 			idtype = DEVID_T10;
1249 			break;
1250 		}
1251 		switch (VPD_DEVID_CODE(chdr.pi_code)) {
1252 		case VPD_DEVID_CODE_ASCII:
1253 		case VPD_DEVID_CODE_UTF8:
1254 			idflags = DEVID_F_PRINT;
1255 			break;
1256 		default:
1257 			idflags = 0;
1258 			break;
1259 		}
1260 		link->id = devid_alloc(idtype, idflags, chdr.len, id);
1261 	} else
1262 		rv = ENODEV;
1263 
1264 done:
1265 	if (pg)
1266 		dma_free(pg, len);
1267 	if (hdr)
1268 		dma_free(hdr, sizeof(*hdr));
1269 	return (rv);
1270 }
1271 
1272 int
1273 scsi_devid_pg80(struct scsi_link *link)
1274 {
1275 	struct scsi_vpd_hdr *hdr = NULL;
1276 	u_int8_t *pg = NULL;
1277 	char *id;
1278 	int pglen, len;
1279 	int rv;
1280 
1281 	hdr = dma_alloc(sizeof(*hdr), PR_WAITOK | PR_ZERO);
1282 
1283 	rv = scsi_inquire_vpd(link, hdr, sizeof(*hdr), SI_PG_SERIAL,
1284 	    scsi_autoconf);
1285 	if (rv != 0)
1286 		goto freehdr;
1287 
1288 	len = _2btol(hdr->page_length);
1289 	if (len == 0) {
1290 		rv = EINVAL;
1291 		goto freehdr;
1292 	}
1293 
1294 	pglen = sizeof(*hdr) + len;
1295 	pg = dma_alloc(pglen, PR_WAITOK | PR_ZERO);
1296 
1297 	rv = scsi_inquire_vpd(link, pg, pglen, SI_PG_SERIAL, scsi_autoconf);
1298 	if (rv != 0)
1299 		goto free;
1300 
1301 	id = malloc(sizeof(link->inqdata.vendor) +
1302 	    sizeof(link->inqdata.product) + len, M_TEMP, M_WAITOK);
1303 	memcpy(id, link->inqdata.vendor, sizeof(link->inqdata.vendor));
1304 	memcpy(id + sizeof(link->inqdata.vendor), link->inqdata.product,
1305 	    sizeof(link->inqdata.product));
1306 	memcpy(id + sizeof(link->inqdata.vendor) +
1307 	    sizeof(link->inqdata.product), pg + sizeof(*hdr), len);
1308 
1309 	link->id = devid_alloc(DEVID_SERIAL, DEVID_F_PRINT,
1310 	    sizeof(link->inqdata.vendor) + sizeof(link->inqdata.product) + len,
1311 	    id);
1312 
1313 	free(id, M_TEMP, 0);
1314 
1315 free:
1316 	dma_free(pg, pglen);
1317 freehdr:
1318 	dma_free(hdr, sizeof(*hdr));
1319 	return (rv);
1320 }
1321 
1322 int
1323 scsi_devid_wwn(struct scsi_link *link)
1324 {
1325 	u_int64_t wwnn;
1326 
1327 	if (link->lun != 0 || link->node_wwn == 0)
1328 		return (EOPNOTSUPP);
1329 
1330 	wwnn = htobe64(link->node_wwn);
1331 	link->id = devid_alloc(DEVID_WWN, 0, sizeof(wwnn), (u_int8_t *)&wwnn);
1332 
1333 	return (0);
1334 }
1335 
1336 /*
1337  * scsi_minphys member of struct scsi_adapter for drivers which don't
1338  * need any specific routine.
1339  */
1340 void
1341 scsi_minphys(struct buf *bp, struct scsi_link *sl)
1342 {
1343 	minphys(bp);
1344 }
1345 
1346 struct devid *
1347 devid_alloc(u_int8_t type, u_int8_t flags, u_int8_t len, u_int8_t *id)
1348 {
1349 	struct devid *d;
1350 
1351 	d = malloc(sizeof(*d) + len, M_DEVBUF, M_WAITOK|M_CANFAIL);
1352 	if (d == NULL)
1353 		return (NULL);
1354 
1355 	d->d_type = type;
1356 	d->d_flags = flags;
1357 	d->d_len = len;
1358 	d->d_refcount = 1;
1359 	memcpy(d + 1, id, len);
1360 
1361 	return (d);
1362 }
1363 
1364 struct devid *
1365 devid_copy(struct devid *d)
1366 {
1367 	d->d_refcount++;
1368 	return (d);
1369 }
1370 
1371 void
1372 devid_free(struct devid *d)
1373 {
1374 	if (--d->d_refcount == 0)
1375 		free(d, M_DEVBUF, 0);
1376 }
1377