xref: /illumos-gate/usr/src/uts/common/io/scsi/conf/scsi_confsubr.c (revision bb9b6b3f59b8820022416cea99b49c50fef6e391)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Utility SCSI configuration routines
28  */
29 /*
30  * Many routines in this file have built in parallel bus assumption
31  * which might need to change as other interconnect evolve.
32  */
33 
34 #include <sys/scsi/scsi.h>
35 #include <sys/modctl.h>
36 #include <sys/bitmap.h>
37 
38 /*
39  * macro for filling in lun value for scsi-1 support
40  */
41 
42 #define	FILL_SCSI1_LUN(sd, pkt) \
43 	if ((sd->sd_address.a_lun > 0) && \
44 	    (sd->sd_inq->inq_ansi == 0x1)) { \
45 		((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \
46 		    sd->sd_address.a_lun; \
47 	}
48 
49 extern struct mod_ops mod_miscops;
50 
51 static struct modlmisc modlmisc = {
52 	&mod_miscops,	/* Type of module */
53 	"SCSI Bus Utility Routines"
54 };
55 
56 static struct modlinkage modlinkage = {
57 	MODREV_1, (void *)&modlmisc, NULL
58 };
59 
60 static void create_inquiry_props(struct scsi_device *);
61 static int get_inquiry_prop_len(char *, size_t);
62 
63 static int scsi_check_ss2_LUN_limit(struct scsi_device *);
64 static void scsi_establish_LUN_limit(struct scsi_device *);
65 static void scsi_update_parent_ss2_prop(dev_info_t *, int, int);
66 
67 static int check_vpd_page_support8083(struct scsi_device *sd,
68 		int (*callback)(), int *, int *);
69 static int send_scsi_INQUIRY(struct scsi_device *sd,
70 		int (*callback)(), uchar_t *bufaddr, size_t buflen,
71 		uchar_t evpd, uchar_t page_code, size_t *lenp);
72 
73 /*
74  * this int-array HBA-node property keeps track of strictly SCSI-2
75  * target IDs
76  */
77 #define	SS2_LUN0_TGT_LIST_PROP	"ss2-targets"
78 
79 /*
80  * for keeping track of nodes for which we do *NOT* want to probe above LUN 7
81  * (i.e. strict SCSI-2 targets)
82  *
83  * note that we could also keep track of dtype (SCSI device type) and
84  * ANSI (SCSI standard conformance level), but all currently-known cases of
85  * this problem are on SCSI-2 PROCESSOR device types
86  */
87 typedef struct ss2_lun0_info {
88 	const char	*sli_vid;	/* SCSI inquiry VID */
89 	const char	*sli_pid;	/* SCSI inquiry PID */
90 	const char	*sli_rev;	/* SCSI inquiry REV */
91 } ss2_lun0_info_t;
92 
93 /*
94  * these two workarounds are for the SCSI-2 GEM2* chips used in the
95  * D1000 and D240
96  */
97 #define	SES_D1000_VID		"SYMBIOS"
98 #define	SES_D1000_PID		"D1000"		/* the D1000 */
99 #define	SES_D1000_REV		"2"
100 
101 #define	SES_D240_VID		"SUN"
102 #define	SES_D240_PID		"D240"		/* the D240 */
103 #define	SES_D240_REV		"2"
104 
105 /*
106  * a static list of targets where we do *not* want to probe above LUN 7
107  */
108 static const ss2_lun0_info_t	scsi_probe_strict_s2_list[] = {
109 	{SES_D1000_VID, SES_D1000_PID, SES_D1000_REV},
110 	{SES_D240_VID, SES_D240_PID, SES_D240_REV},
111 };
112 
113 static const int		scsi_probe_strict_s2_size =
114 	sizeof (scsi_probe_strict_s2_list) / sizeof (struct ss2_lun0_info);
115 
116 
117 #ifdef	DEBUG
118 
119 int	scsi_probe_debug = 0;
120 
121 #define	SCSI_PROBE_DEBUG0(l, s)		\
122 		if (scsi_probe_debug >= (l)) printf(s)
123 #define	SCSI_PROBE_DEBUG1(l, s, a1)	\
124 		if (scsi_probe_debug >= (l)) printf(s, a1)
125 #define	SCSI_PROBE_DEBUG2(l, s, a1, a2)	\
126 		if (scsi_probe_debug >= (l)) printf(s, a1, a2)
127 #define	SCSI_PROBE_DEBUG3(l, s, a1, a2, a3)	\
128 		if (scsi_probe_debug >= (l)) printf(s, a1, a2, a3)
129 
130 #else	/* DEBUG */
131 
132 #define	SCSI_PROBE_DEBUG0(l, s)
133 #define	SCSI_PROBE_DEBUG1(l, s, a1)
134 #define	SCSI_PROBE_DEBUG2(l, s, a1, a2)
135 #define	SCSI_PROBE_DEBUG3(l, s, a1, a2, a3)
136 
137 #endif	/* DEBUG */
138 
139 int	scsi_test_busy_timeout = SCSI_POLL_TIMEOUT;	/* in seconds */
140 int	scsi_test_busy_delay = 10000;			/* 10msec in usec */
141 
142 /*
143  * architecture dependent allocation restrictions. For x86, we'll set
144  * dma_attr_addr_hi to scsi_max_phys_addr and dma_attr_sgllen to
145  * scsi_sgl_size during _init().
146  */
147 #if defined(__sparc)
148 ddi_dma_attr_t scsi_alloc_attr = {
149 	DMA_ATTR_V0,	/* version number */
150 	0x0,		/* lowest usable address */
151 	0xFFFFFFFFull,	/* high DMA address range */
152 	0xFFFFFFFFull,	/* DMA counter register */
153 	1,		/* DMA address alignment */
154 	1,		/* DMA burstsizes */
155 	1,		/* min effective DMA size */
156 	0xFFFFFFFFull,	/* max DMA xfer size */
157 	0xFFFFFFFFull,	/* segment boundary */
158 	1,		/* s/g list length */
159 	512,		/* granularity of device */
160 	0		/* DMA transfer flags */
161 };
162 #elif defined(__x86)
163 ddi_dma_attr_t scsi_alloc_attr = {
164 	DMA_ATTR_V0,	/* version number */
165 	0x0,		/* lowest usable address */
166 	0x0,		/* high DMA address range [set in _init()] */
167 	0xFFFFull,	/* DMA counter register */
168 	1,		/* DMA address alignment */
169 	1,		/* DMA burstsizes */
170 	1,		/* min effective DMA size */
171 	0xFFFFFFFFull,	/* max DMA xfer size */
172 	0xFFFFFFFFull,  /* segment boundary */
173 	0,		/* s/g list length */
174 	512,		/* granularity of device [set in _init()] */
175 	0		/* DMA transfer flags */
176 };
177 uint64_t scsi_max_phys_addr = 0xFFFFFFFFull;
178 int scsi_sgl_size = 0xFF;
179 #endif
180 
181 ulong_t	*scsi_pkt_bad_alloc_bitmap;
182 
183 int
184 _init()
185 {
186 	scsi_initialize_hba_interface();
187 	scsi_watch_init();
188 
189 #if defined(__x86)
190 	/* set the max physical address for iob allocs on x86 */
191 	scsi_alloc_attr.dma_attr_addr_hi = scsi_max_phys_addr;
192 
193 	/*
194 	 * set the sgllen for iob allocs on x86. If this is set less than
195 	 * the number of pages the buffer will take (taking into account
196 	 * alignment), it would force the allocator to try and allocate
197 	 * contiguous pages.
198 	 */
199 	scsi_alloc_attr.dma_attr_sgllen = scsi_sgl_size;
200 #endif
201 
202 	/* bitmap to limit scsi_pkt allocation violation messages */
203 	scsi_pkt_bad_alloc_bitmap = kmem_zalloc(BT_SIZEOFMAP(devcnt), KM_SLEEP);
204 
205 	return (mod_install(&modlinkage));
206 }
207 
208 /*
209  * there is no _fini() routine because this module is never unloaded
210  */
211 
212 int
213 _info(struct modinfo *modinfop)
214 {
215 	return (mod_info(&modlinkage, modinfop));
216 }
217 
218 #define	ROUTE	(&sd->sd_address)
219 
220 static int
221 scsi_slave_do_rqsense(struct scsi_device *sd, int (*callback)())
222 {
223 	struct scsi_pkt *rq_pkt = NULL;
224 	struct buf *rq_bp = NULL;
225 	int rval = SCSIPROBE_EXISTS;
226 
227 	/*
228 	 * prepare rqsense packet
229 	 */
230 	rq_bp = scsi_alloc_consistent_buf(ROUTE, (struct buf *)NULL,
231 	    (uint_t)SENSE_LENGTH, B_READ, callback, NULL);
232 	if (rq_bp == NULL) {
233 		rval = SCSIPROBE_NOMEM;
234 		goto out;
235 	}
236 
237 	rq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
238 	    rq_bp, CDB_GROUP0, 1, 0, PKT_CONSISTENT,
239 	    callback, NULL);
240 
241 	if (rq_pkt == NULL) {
242 		if (rq_bp->b_error == 0)
243 			rval = SCSIPROBE_NOMEM_CB;
244 		else
245 			rval = SCSIPROBE_NOMEM;
246 		goto out;
247 	}
248 	ASSERT(rq_bp->b_error == 0);
249 
250 	(void) scsi_setup_cdb((union scsi_cdb *)rq_pkt->
251 	    pkt_cdbp, SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0);
252 	FILL_SCSI1_LUN(sd, rq_pkt);
253 	rq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY|FLAG_SENSING;
254 
255 	/*
256 	 * The controller type is as yet unknown, so we
257 	 * have to do a throwaway non-extended request sense,
258 	 * and hope that that clears the check condition
259 	 * for that unit until we can find out what kind
260 	 * of drive it is. A non-extended request sense
261 	 * is specified by stating that the sense block
262 	 * has 0 length, which is taken to mean that it
263 	 * is four bytes in length.
264 	 */
265 	if (scsi_poll(rq_pkt) < 0) {
266 		rval = SCSIPROBE_FAILURE;
267 	}
268 
269 out:
270 	if (rq_pkt) {
271 		scsi_destroy_pkt(rq_pkt);
272 	}
273 	if (rq_bp) {
274 		scsi_free_consistent_buf(rq_bp);
275 	}
276 
277 	return (rval);
278 }
279 
280 /*
281  *
282  * SCSI slave probe routine - provided as a service to target drivers
283  *
284  * Mostly attempts to allocate and fill sd inquiry data..
285  */
286 
287 int
288 scsi_slave(struct scsi_device *sd, int (*callback)())
289 {
290 	struct scsi_pkt	*pkt;
291 	int		rval = SCSIPROBE_EXISTS;
292 
293 	/*
294 	 * the first test unit ready will tell us whether a target
295 	 * responded and if there was one, it will clear the unit attention
296 	 * condition
297 	 */
298 	pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, NULL,
299 	    CDB_GROUP0, sizeof (struct scsi_arq_status), 0, 0, callback, NULL);
300 
301 	if (pkt == NULL) {
302 		return (SCSIPROBE_NOMEM_CB);
303 	}
304 
305 	(void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp,
306 	    SCMD_TEST_UNIT_READY, 0, 0, 0);
307 	FILL_SCSI1_LUN(sd, pkt);
308 	pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
309 
310 	if (scsi_poll(pkt) < 0) {
311 		if (pkt->pkt_reason == CMD_INCOMPLETE)
312 			rval = SCSIPROBE_NORESP;
313 		else
314 			rval = SCSIPROBE_FAILURE;
315 
316 		if ((pkt->pkt_state & STATE_ARQ_DONE) == 0) {
317 			if (((struct scsi_status *)pkt->pkt_scbp)->sts_chk)
318 				/*
319 				 * scanner and processor devices can return a
320 				 * check condition here
321 				 */
322 				rval = scsi_slave_do_rqsense(sd, callback);
323 		}
324 
325 		if (rval != SCSIPROBE_EXISTS) {
326 			scsi_destroy_pkt(pkt);
327 			return (rval);
328 		}
329 	}
330 
331 	/*
332 	 * the second test unit ready, allows the host adapter to negotiate
333 	 * synchronous transfer period and offset
334 	 */
335 	if (scsi_poll(pkt) < 0) {
336 		if (pkt->pkt_reason == CMD_INCOMPLETE)
337 			rval = SCSIPROBE_NORESP;
338 		else
339 			rval = SCSIPROBE_FAILURE;
340 	}
341 
342 	/*
343 	 * do a rqsense if there was a check condition and ARQ was not done
344 	 */
345 	if ((pkt->pkt_state & STATE_ARQ_DONE) == 0) {
346 		if (((struct scsi_status *)pkt->pkt_scbp)->sts_chk) {
347 			rval = scsi_slave_do_rqsense(sd, callback);
348 		}
349 	}
350 
351 	/*
352 	 * call scsi_probe to do the inquiry
353 	 *
354 	 * NOTE: there is minor difference with the old scsi_slave
355 	 * implementation: busy conditions are not handled in scsi_probe.
356 	 */
357 	scsi_destroy_pkt(pkt);
358 	if (rval == SCSIPROBE_EXISTS) {
359 		return (scsi_probe(sd, callback));
360 	} else {
361 		return (rval);
362 	}
363 }
364 
365 /*
366  * Undo scsi_slave - older interface, but still supported
367  *
368  * NOTE: The 'sd_inq' inquiry data is now freed by scsi_hba/scsi_vhci code
369  * as part of free of scsi_device(9S).
370  */
371 /*ARGSUSED*/
372 void
373 scsi_unslave(struct scsi_device *sd)
374 {
375 }
376 
377 /*
378  * Undo scsi_probe
379  *
380  * NOTE: The 'sd_inq' inquiry data is now freed by scsi_hba/scsi_vhci code
381  * as part of free of scsi_device(9S).
382  */
383 /*ARGSUSED*/
384 void
385 scsi_unprobe(struct scsi_device *sd)
386 {
387 }
388 
389 /*
390  * This is like scsi_poll, but only does retry for TRAN_BUSY.
391  */
392 static int
393 scsi_test(struct scsi_pkt *pkt)
394 {
395 	int		rval = -1;
396 	int		wait_usec;
397 	int		rc;
398 	extern int	do_polled_io;
399 
400 	pkt->pkt_flags |= FLAG_NOINTR;
401 	pkt->pkt_time = SCSI_POLL_TIMEOUT;	/* in seconds */
402 
403 	if (scsi_ifgetcap(&pkt->pkt_address, "tagged-qing", 1) == 1) {
404 		pkt->pkt_flags |= FLAG_STAG;
405 	}
406 
407 	/*
408 	 * Each TRAN_BUSY response waits scsi_test_busy_delay usec up to a
409 	 * maximum of scsi_test_busy_timeout.
410 	 */
411 	for (wait_usec = 0; (wait_usec / 1000000) <= scsi_test_busy_timeout;
412 	    wait_usec += scsi_test_busy_delay) {
413 
414 		/* Initialize pkt status variables */
415 		*pkt->pkt_scbp = pkt->pkt_reason = pkt->pkt_state = 0;
416 
417 		rc = scsi_transport(pkt);
418 		if ((rc != TRAN_BUSY) || (scsi_test_busy_delay == 0) ||
419 		    (scsi_test_busy_timeout == 0))
420 			break;
421 
422 		/* transport busy, wait */
423 		if ((curthread->t_flag & T_INTR_THREAD) == 0 && !do_polled_io) {
424 			delay(drv_usectohz(scsi_test_busy_delay));
425 		} else {
426 			/* we busy wait during cpr_dump or interrupt threads */
427 			drv_usecwait(scsi_test_busy_delay);
428 		}
429 	}
430 
431 	if (rc != TRAN_ACCEPT) {
432 		goto exit;
433 	} else if (pkt->pkt_reason == CMD_INCOMPLETE && pkt->pkt_state == 0) {
434 		goto exit;
435 	} else if (pkt->pkt_reason != CMD_CMPLT) {
436 		goto exit;
437 	} else if (((*pkt->pkt_scbp) & STATUS_MASK) == STATUS_BUSY) {
438 		rval = 0;
439 	} else {
440 		rval = 0;
441 	}
442 
443 exit:
444 	return (rval);
445 }
446 
447 /*
448  * The implementation of scsi_probe now allows a particular
449  * HBA to intercept the call, for any post- or pre-processing
450  * it may need.  The default, if the HBA does not override it,
451  * is to call scsi_hba_probe(), which retains the old functionality
452  * intact.
453  */
454 int
455 scsi_probe(struct scsi_device *sd, int (*callback)())
456 {
457 	int			ret;
458 	scsi_hba_tran_t		*tran = sd->sd_address.a_hba_tran;
459 
460 	if (scsi_check_ss2_LUN_limit(sd) != 0) {
461 		/*
462 		 * caller is trying to probe a strictly-SCSI-2 device
463 		 * with a LUN that is too large, so do not allow it
464 		 */
465 		return (SCSIPROBE_NORESP);	/* skip probing this one */
466 	}
467 
468 	if (tran->tran_tgt_probe != NULL) {
469 		ret = (*tran->tran_tgt_probe)(sd, callback);
470 	} else {
471 		ret = scsi_hba_probe(sd, callback);
472 	}
473 
474 	if (ret == SCSIPROBE_EXISTS) {
475 		create_inquiry_props(sd);
476 		/* is this a strictly-SCSI-2 node ?? */
477 		scsi_establish_LUN_limit(sd);
478 	}
479 
480 	return (ret);
481 }
482 /*
483  * probe scsi device using any available path
484  *
485  */
486 int
487 scsi_hba_probe(struct scsi_device *sd, int (*callback)())
488 {
489 	return (scsi_hba_probe_pi(sd, callback, 0));
490 }
491 
492 /*
493  * probe scsi device using specific path
494  *
495  * scsi_hba_probe_pi does not do any test unit ready's which access the medium
496  * and could cause busy or not ready conditions.
497  * scsi_hba_probe_pi does 2 inquiries and a rqsense to clear unit attention
498  * and to allow sync negotiation to take place
499  * finally, scsi_hba_probe_pi does one more inquiry which should
500  * reliably tell us what kind of target we have.
501  * A scsi-2 compliant target should be able to	return inquiry with 250ms
502  * and we actually wait more than a second after reset.
503  */
504 int
505 scsi_hba_probe_pi(struct scsi_device *sd, int (*callback)(), int pi)
506 {
507 	struct scsi_pkt		*inq_pkt = NULL;
508 	struct scsi_pkt		*rq_pkt = NULL;
509 	int			rval = SCSIPROBE_NOMEM;
510 	struct buf		*inq_bp = NULL;
511 	struct buf		*rq_bp = NULL;
512 	int			(*cb_flag)();
513 	int			pass = 1;
514 
515 	if (sd->sd_inq == NULL) {
516 		sd->sd_inq = (struct scsi_inquiry *)
517 		    kmem_alloc(SUN_INQSIZE, ((callback == SLEEP_FUNC) ?
518 		    KM_SLEEP : KM_NOSLEEP));
519 		if (sd->sd_inq == NULL) {
520 			goto out;
521 		}
522 	}
523 
524 	if (callback != SLEEP_FUNC && callback != NULL_FUNC) {
525 		cb_flag = NULL_FUNC;
526 	} else {
527 		cb_flag = callback;
528 	}
529 	inq_bp = scsi_alloc_consistent_buf(ROUTE,
530 	    (struct buf *)NULL, SUN_INQSIZE, B_READ, cb_flag, NULL);
531 	if (inq_bp == NULL) {
532 		goto out;
533 	}
534 
535 	inq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
536 	    inq_bp, CDB_GROUP0, sizeof (struct scsi_arq_status),
537 	    0, PKT_CONSISTENT, callback, NULL);
538 	if (inq_pkt == NULL) {
539 		if (inq_bp->b_error == 0)
540 			rval = SCSIPROBE_NOMEM_CB;
541 		goto out;
542 	}
543 	ASSERT(inq_bp->b_error == 0);
544 
545 	(void) scsi_setup_cdb((union scsi_cdb *)inq_pkt->pkt_cdbp,
546 	    SCMD_INQUIRY, 0, SUN_INQSIZE, 0);
547 	inq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
548 
549 	/*
550 	 * set transport path
551 	 */
552 	if (pi && scsi_pkt_allocated_correctly(inq_pkt)) {
553 		inq_pkt->pkt_path_instance = pi;
554 		inq_pkt->pkt_flags |= FLAG_PKT_PATH_INSTANCE;
555 	}
556 
557 	/*
558 	 * the first inquiry will tell us whether a target
559 	 * responded
560 	 *
561 	 * The FILL_SCSI1_LUN below will find "ansi_ver != 1" on first pass
562 	 * because of bzero initilization. If this assumption turns out to be
563 	 * incorrect after we have real sd_inq data (for lun0) we will do a
564 	 * second pass during which FILL_SCSI1_LUN will place lun in CDB.
565 	 */
566 	bzero((caddr_t)sd->sd_inq, SUN_INQSIZE);
567 again:	FILL_SCSI1_LUN(sd, inq_pkt);
568 
569 	if (scsi_test(inq_pkt) < 0) {
570 		if (inq_pkt->pkt_reason == CMD_INCOMPLETE) {
571 			rval = SCSIPROBE_NORESP;
572 			goto out;
573 		} else {
574 			/*
575 			 * retry one more time
576 			 */
577 			if (scsi_test(inq_pkt) < 0) {
578 				rval = SCSIPROBE_FAILURE;
579 				goto out;
580 			}
581 		}
582 	}
583 
584 	/*
585 	 * if we are lucky, this inquiry succeeded
586 	 */
587 	if ((inq_pkt->pkt_reason == CMD_CMPLT) &&
588 	    (((*inq_pkt->pkt_scbp) & STATUS_MASK) == 0)) {
589 		goto done;
590 	}
591 
592 	/*
593 	 * the second inquiry, allows the host adapter to negotiate
594 	 * synchronous transfer period and offset
595 	 */
596 	if (scsi_test(inq_pkt) < 0) {
597 		if (inq_pkt->pkt_reason == CMD_INCOMPLETE)
598 			rval = SCSIPROBE_NORESP;
599 		else
600 			rval = SCSIPROBE_FAILURE;
601 		goto out;
602 	}
603 
604 	/*
605 	 * if target is still busy, give up now
606 	 */
607 	if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_busy) {
608 		rval = SCSIPROBE_BUSY;
609 		goto out;
610 	}
611 
612 	/*
613 	 * do a rqsense if there was a check condition and ARQ was not done
614 	 */
615 	if ((inq_pkt->pkt_state & STATE_ARQ_DONE) == 0) {
616 		if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_chk) {
617 
618 			/*
619 			 * prepare rqsense packet
620 			 * there is no real need for this because the
621 			 * check condition should have been cleared by now.
622 			 */
623 			rq_bp = scsi_alloc_consistent_buf(ROUTE,
624 			    (struct buf *)NULL,
625 			    (uint_t)SENSE_LENGTH, B_READ, cb_flag, NULL);
626 			if (rq_bp == NULL) {
627 				goto out;
628 			}
629 
630 			rq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
631 			    rq_bp, CDB_GROUP0, 1, 0, PKT_CONSISTENT, callback,
632 			    NULL);
633 
634 			if (rq_pkt == NULL) {
635 				if (rq_bp->b_error == 0)
636 					rval = SCSIPROBE_NOMEM_CB;
637 				goto out;
638 			}
639 			ASSERT(rq_bp->b_error == 0);
640 
641 			(void) scsi_setup_cdb((union scsi_cdb *)rq_pkt->
642 			    pkt_cdbp, SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0);
643 			FILL_SCSI1_LUN(sd, rq_pkt);
644 			rq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
645 
646 			/*
647 			 * set transport path
648 			 */
649 			if (pi && scsi_pkt_allocated_correctly(rq_pkt)) {
650 				rq_pkt->pkt_path_instance = pi;
651 				rq_pkt->pkt_flags |= FLAG_PKT_PATH_INSTANCE;
652 			}
653 
654 			/*
655 			 * The FILL_SCSI1_LUN above will find "inq_ansi != 1"
656 			 * on first pass, see "again" comment above.
657 			 *
658 			 * The controller type is as yet unknown, so we
659 			 * have to do a throwaway non-extended request sense,
660 			 * and hope that that clears the check condition for
661 			 * that unit until we can find out what kind of drive
662 			 * it is. A non-extended request sense is specified
663 			 * by stating that the sense block has 0 length,
664 			 * which is taken to mean that it is four bytes in
665 			 * length.
666 			 */
667 			if (scsi_test(rq_pkt) < 0) {
668 				rval = SCSIPROBE_FAILURE;
669 				goto out;
670 			}
671 		}
672 	}
673 
674 	/*
675 	 * At this point, we are guaranteed that something responded
676 	 * to this scsi bus target id. We don't know yet what
677 	 * kind of device it is, or even whether there really is
678 	 * a logical unit attached (as some SCSI target controllers
679 	 * lie about a unit being ready, e.g., the Emulex MD21).
680 	 */
681 
682 	if (scsi_test(inq_pkt) < 0) {
683 		rval = SCSIPROBE_FAILURE;
684 		goto out;
685 	}
686 
687 	if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_busy) {
688 		rval = SCSIPROBE_BUSY;
689 		goto out;
690 	}
691 
692 	/*
693 	 * Okay we sent the INQUIRY command.
694 	 *
695 	 * If enough data was transferred, we count that the
696 	 * Inquiry command succeeded, else we have to assume
697 	 * that this is a non-CCS scsi target (or a nonexistent
698 	 * target/lun).
699 	 */
700 
701 	if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_chk) {
702 		/*
703 		 * try a request sense if we have a pkt, otherwise
704 		 * just retry the inquiry one more time
705 		 */
706 		if (rq_pkt) {
707 			(void) scsi_test(rq_pkt);
708 		}
709 
710 		/*
711 		 * retry inquiry
712 		 */
713 		if (scsi_test(inq_pkt) < 0) {
714 			rval = SCSIPROBE_FAILURE;
715 			goto out;
716 		}
717 		if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_chk) {
718 			rval = SCSIPROBE_FAILURE;
719 			goto out;
720 		}
721 	}
722 
723 done:
724 	/*
725 	 * If we got a parity error on receive of inquiry data,
726 	 * we're just plain out of luck because we told the host
727 	 * adapter to not watch for parity errors.
728 	 */
729 	if ((inq_pkt->pkt_state & STATE_XFERRED_DATA) == 0 ||
730 	    ((SUN_INQSIZE - inq_pkt->pkt_resid) < SUN_MIN_INQLEN)) {
731 		rval = SCSIPROBE_NONCCS;
732 	} else {
733 		ASSERT(inq_pkt->pkt_resid >= 0);
734 		bcopy((caddr_t)inq_bp->b_un.b_addr,
735 		    (caddr_t)sd->sd_inq, (SUN_INQSIZE - inq_pkt->pkt_resid));
736 		rval = SCSIPROBE_EXISTS;
737 	}
738 
739 out:
740 	/*
741 	 * If lun > 0 we need to figure out if this is a scsi-1 device where
742 	 * the "real" lun needs to be embedded into the cdb.
743 	 */
744 	if ((rval == SCSIPROBE_EXISTS) && (pass == 1) &&
745 	    (sd->sd_address.a_lun > 0) && (sd->sd_inq->inq_ansi == 0x1)) {
746 		pass++;
747 		if (sd->sd_address.a_lun <= 7)
748 			goto again;
749 
750 		/*
751 		 * invalid lun for scsi-1,
752 		 * return probe failure.
753 		 */
754 		rval = SCSIPROBE_FAILURE;
755 	}
756 
757 	if (rq_pkt) {
758 		scsi_destroy_pkt(rq_pkt);
759 	}
760 	if (inq_pkt) {
761 		scsi_destroy_pkt(inq_pkt);
762 	}
763 	if (rq_bp) {
764 		scsi_free_consistent_buf(rq_bp);
765 	}
766 	if (inq_bp) {
767 		scsi_free_consistent_buf(inq_bp);
768 	}
769 	return (rval);
770 }
771 
772 /*
773  * Convert from a scsi_device structure pointer to a scsi_hba_tran structure
774  * pointer. The correct way to do this is
775  *
776  *	#define	DEVP_TO_TRAN(sd)	((sd)->sd_address.a_hba_tran)
777  *
778  * however we have some consumers that place their own vector in a_hba_tran. To
779  * avoid problems, we implement this using the sd_tran_safe. See
780  * scsi_hba_initchild for more details.
781  */
782 #define	DEVP_TO_TRAN(sd)	((sd)->sd_tran_safe)
783 
784 /*
785  * Function, callable from SCSA framework, to get 'human' readable REPORTDEV
786  * addressing information from scsi_device properties.
787  */
788 int
789 scsi_ua_get_reportdev(struct scsi_device *sd, char *ra, int len)
790 {
791 	/* use deprecated tran_get_bus_addr interface if it is defined */
792 	/* NOTE: tran_get_bus_addr is a poor name choice for interface */
793 	if (DEVP_TO_TRAN(sd)->tran_get_bus_addr)
794 		return ((*DEVP_TO_TRAN(sd)->tran_get_bus_addr)(sd, ra, len));
795 	return (scsi_hba_ua_get_reportdev(sd, ra, len));
796 }
797 
798 /*
799  * Function, callable from HBA driver's tran_get_bus_addr(9E) implementation,
800  * to get standard form of human readable REPORTDEV addressing information
801  * from scsi_device properties.
802  */
803 int
804 scsi_hba_ua_get_reportdev(struct scsi_device *sd, char *ra, int len)
805 {
806 	int		tgt, lun, sfunc;
807 	char		*tgt_port;
808 	scsi_lun64_t	lun64;
809 
810 	/* get device unit-address properties */
811 	tgt = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
812 	    SCSI_ADDR_PROP_TARGET, -1);
813 	if (scsi_device_prop_lookup_string(sd, SCSI_DEVICE_PROP_PATH,
814 	    SCSI_ADDR_PROP_TARGET_PORT, &tgt_port) != DDI_PROP_SUCCESS)
815 		tgt_port = NULL;
816 	if ((tgt == -1) && (tgt_port == NULL))
817 		return (0);		/* no target */
818 
819 	lun = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
820 	    SCSI_ADDR_PROP_LUN, 0);
821 	lun64 = scsi_device_prop_get_int64(sd, SCSI_DEVICE_PROP_PATH,
822 	    SCSI_ADDR_PROP_LUN64, lun);
823 	sfunc = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
824 	    SCSI_ADDR_PROP_SFUNC, -1);
825 
826 	/*
827 	 * XXX should the default be to print this in decimal for
828 	 * "human readable" form, so it matches conf files?
829 	 */
830 	if (tgt_port) {
831 		if (sfunc == -1)
832 			(void) snprintf(ra, len,
833 			    "%s %s lun %" PRIx64,
834 			    SCSI_ADDR_PROP_TARGET_PORT, tgt_port, lun64);
835 		else
836 			(void) snprintf(ra, len,
837 			    "%s %s lun %" PRIx64 " sfunc %x",
838 			    SCSI_ADDR_PROP_TARGET_PORT, tgt_port, lun64, sfunc);
839 		scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, tgt_port);
840 	} else {
841 		if (sfunc == -1)
842 			(void) snprintf(ra, len,
843 			    "%s %x lun %" PRIx64,
844 			    SCSI_ADDR_PROP_TARGET, tgt, lun64);
845 		else
846 			(void) snprintf(ra, len,
847 			    "%s %x lun %" PRIx64 " sfunc %x",
848 			    SCSI_ADDR_PROP_TARGET, tgt, lun64, sfunc);
849 	}
850 
851 	return (1);
852 }
853 
854 /*
855  * scsi_ua_get: using properties, return "unit-address" string.
856  * Called by SCSA framework, may call HBAs tran function.
857  */
858 int
859 scsi_ua_get(struct scsi_device *sd, char *ua, int len)
860 {
861 	char		*eua;
862 
863 	/* See if we already have established the unit-address. */
864 	if ((eua = scsi_device_unit_address(sd)) != NULL) {
865 		(void) strlcpy(ua, eua, len);
866 		return (1);
867 	}
868 
869 	/* Use deprecated tran_get_name interface if it is defined. */
870 	/* NOTE: tran_get_name is a poor name choice for interface */
871 	if (DEVP_TO_TRAN(sd)->tran_get_name)
872 		return ((*DEVP_TO_TRAN(sd)->tran_get_name)(sd, ua, len));
873 
874 	/* Use generic property implementation */
875 	return (scsi_hba_ua_get(sd, ua, len));
876 }
877 
878 /*
879  * scsi_hba_ua_get: using properties, return "unit-address" string.
880  * This function may be called from an HBAs tran function.
881  *
882  * Function to get "unit-address" in "name@unit-address" /devices path
883  * component form from the scsi_device unit-address properties on a node.
884  *
885  * NOTE: This function works in conjunction with scsi_hba_ua_set().
886  */
887 int
888 scsi_hba_ua_get(struct scsi_device *sd, char *ua, int len)
889 {
890 	int		tgt, lun, sfunc;
891 	char		*tgt_port;
892 	scsi_lun64_t	lun64;
893 
894 	/* get device unit-address properties */
895 	tgt = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
896 	    SCSI_ADDR_PROP_TARGET, -1);
897 	if (scsi_device_prop_lookup_string(sd, SCSI_DEVICE_PROP_PATH,
898 	    SCSI_ADDR_PROP_TARGET_PORT, &tgt_port) != DDI_PROP_SUCCESS)
899 		tgt_port = NULL;
900 	if ((tgt == -1) && (tgt_port == NULL))
901 		return (0);		/* no target */
902 
903 	lun = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
904 	    SCSI_ADDR_PROP_LUN, 0);
905 	lun64 = scsi_device_prop_get_int64(sd, SCSI_DEVICE_PROP_PATH,
906 	    SCSI_ADDR_PROP_LUN64, lun);
907 	sfunc = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
908 	    SCSI_ADDR_PROP_SFUNC, -1);
909 	if (tgt_port) {
910 		if (sfunc == -1)
911 			(void) snprintf(ua, len, "%s,%" PRIx64,
912 			    tgt_port, lun64);
913 		else
914 			(void) snprintf(ua, len, "%s,%" PRIx64 ",%x",
915 			    tgt_port, lun64, sfunc);
916 		scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, tgt_port);
917 	} else {
918 		if (sfunc == -1)
919 			(void) snprintf(ua, len, "%x,%" PRIx64, tgt, lun64);
920 		else
921 			(void) snprintf(ua, len, "%x,%" PRIx64 ",%x",
922 			    tgt, lun64, sfunc);
923 	}
924 	return (1);
925 }
926 
927 void
928 create_inquiry_props(struct scsi_device *sd)
929 {
930 	struct scsi_inquiry *inq = sd->sd_inq;
931 
932 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, sd->sd_dev,
933 	    INQUIRY_DEVICE_TYPE, (int)inq->inq_dtype);
934 
935 	/*
936 	 * Create the following properties:
937 	 *
938 	 * inquiry-vendor-id	Vendor id (INQUIRY data bytes 8-15)
939 	 * inquiry-product-id	Product id (INQUIRY data bytes 16-31)
940 	 * inquiry-revision-id	Product Rev level (INQUIRY data bytes 32-35)
941 	 *
942 	 * Note we don't support creation of these properties for scsi-1
943 	 * devices (as the vid, pid and revision were not defined) and we
944 	 * don't create the property if they are of zero length when
945 	 * stripped of Nulls and spaces.
946 	 */
947 	if (inq->inq_ansi != 1) {
948 		if (ddi_prop_exists(DDI_DEV_T_NONE, sd->sd_dev,
949 		    DDI_PROP_TYPE_STRING, INQUIRY_VENDOR_ID) == 0)
950 			(void) scsi_device_prop_update_inqstring(sd,
951 			    INQUIRY_VENDOR_ID,
952 			    inq->inq_vid, sizeof (inq->inq_vid));
953 
954 		if (ddi_prop_exists(DDI_DEV_T_NONE, sd->sd_dev,
955 		    DDI_PROP_TYPE_STRING, INQUIRY_PRODUCT_ID) == 0)
956 			(void) scsi_device_prop_update_inqstring(sd,
957 			    INQUIRY_PRODUCT_ID,
958 			    inq->inq_pid, sizeof (inq->inq_pid));
959 
960 		if (ddi_prop_exists(DDI_DEV_T_NONE, sd->sd_dev,
961 		    DDI_PROP_TYPE_STRING, INQUIRY_REVISION_ID) == 0)
962 			(void) scsi_device_prop_update_inqstring(sd,
963 			    INQUIRY_REVISION_ID,
964 			    inq->inq_revision, sizeof (inq->inq_revision));
965 	}
966 }
967 
968 /*
969  * Create 'inquiry' string properties.  An 'inquiry' string gets special
970  * treatment to trim trailing blanks (etc) and ensure null termination.
971  */
972 int
973 scsi_device_prop_update_inqstring(struct scsi_device *sd,
974     char *name, char *data, size_t len)
975 {
976 	int	ilen;
977 	char	*data_string;
978 	int	rv;
979 
980 	ilen = get_inquiry_prop_len(data, len);
981 	ASSERT(ilen <= (int)len);
982 	if (ilen <= 0)
983 		return (DDI_PROP_INVAL_ARG);
984 
985 	/* ensure null termination */
986 	data_string = kmem_zalloc(ilen + 1, KM_SLEEP);
987 	bcopy(data, data_string, ilen);
988 	rv = ndi_prop_update_string(DDI_DEV_T_NONE,
989 	    sd->sd_dev, name, data_string);
990 	kmem_free(data_string, ilen + 1);
991 	return (rv);
992 }
993 
994 /*
995  * This routine returns the true length of the inquiry properties that are to
996  * be created by removing the padded spaces at the end of the inquiry data.
997  * This routine was designed for trimming spaces from the vid, pid and revision
998  * which are defined as being left aligned.  In addition, we return 0 length
999  * if the property is full of all 0's or spaces, indicating to the caller that
1000  * the device was not ready to return the proper inquiry data as per note 65 in
1001  * the scsi-2 spec.
1002  */
1003 static int
1004 get_inquiry_prop_len(char *property, size_t length)
1005 {
1006 	int retval;
1007 	int trailer;
1008 	char *p;
1009 
1010 	retval = length;
1011 
1012 	/*
1013 	 * The vid, pid and revision are left-aligned ascii fields within the
1014 	 * inquiry data.  Here we trim the end of these fields by discounting
1015 	 * length associated with trailing spaces or NULL bytes.  The remaining
1016 	 * bytes shall be only graphics codes - 0x20 through 0x7e as per the
1017 	 * scsi spec definition.  If we have all 0's or spaces, we return 0
1018 	 * length.  For devices that store inquiry data on the device, they
1019 	 * can return 0's or spaces in these fields until the data is avail-
1020 	 * able from the device (See NOTE 65 in the scsi-2 specification
1021 	 * around the inquiry command.)  We don't want to create a property in
1022 	 * the case of a device not able to return valid data.
1023 	 */
1024 	trailer = 1;
1025 	for (p = property + length - 1; p >= property; p--) {
1026 		if (trailer) {
1027 			if ((*p == ' ') || (*p == '\0')) {
1028 				retval--;
1029 				continue;
1030 			}
1031 			trailer = 0;
1032 		}
1033 
1034 		/* each char must be within 0x20 - 0x7e */
1035 		if (*p < 0x20 || *p > 0x7e) {
1036 			retval = -1;
1037 			break;
1038 		}
1039 
1040 	}
1041 
1042 	return (retval);
1043 }
1044 
1045 /*
1046  * Interfaces associated with SCSI_HBA_ADDR_COMPLEX
1047  * per-scsi_device HBA private data support.
1048  */
1049 struct scsi_device *
1050 scsi_address_device(struct scsi_address *sa)
1051 {
1052 	ASSERT(sa->a_hba_tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX);
1053 	return (sa->a.a_sd);
1054 }
1055 
1056 void
1057 scsi_device_hba_private_set(struct scsi_device *sd, void *data)
1058 {
1059 	ASSERT(sd->sd_address.a_hba_tran->tran_hba_flags &
1060 	    SCSI_HBA_ADDR_COMPLEX);
1061 	sd->sd_hba_private = data;
1062 }
1063 
1064 void *
1065 scsi_device_hba_private_get(struct scsi_device *sd)
1066 {
1067 	ASSERT(sd->sd_address.a_hba_tran->tran_hba_flags &
1068 	    SCSI_HBA_ADDR_COMPLEX);
1069 	return (sd->sd_hba_private);
1070 }
1071 
1072 /*
1073  * This routine is called from the start of scsi_probe() if a tgt/LUN to be
1074  * probed *may* be a request to probe a strictly SCSI-2 target (with respect
1075  * to LUNs) -- and this probe may be for a LUN number greater than 7,
1076  * which can cause a hardware hang
1077  *
1078  * return 0 if the probe can proceed,
1079  * else return 1, meaning do *NOT* probe this target/LUN
1080  */
1081 static int
1082 scsi_check_ss2_LUN_limit(struct scsi_device *sd)
1083 {
1084 	struct scsi_address	*ap = &(sd->sd_address);
1085 	dev_info_t		*pdevi =
1086 	    (dev_info_t *)DEVI(sd->sd_dev)->devi_parent;
1087 	int			ret_val = 0;	/* default return value */
1088 	uchar_t			*tgt_list;
1089 	uint_t			tgt_nelements;
1090 	int			i;
1091 
1092 
1093 	/*
1094 	 * check for what *might* be a problem probe, only we don't
1095 	 * know yet what's really at the destination target/LUN
1096 	 */
1097 	if ((ap->a_target >= NTARGETS_WIDE) ||
1098 	    (ap->a_lun < NLUNS_PER_TARGET)) {
1099 		return (0);		/* okay to probe this target */
1100 	}
1101 
1102 	/*
1103 	 * this *might* be a problematic probe, so look to see
1104 	 * if the inquiry data matches
1105 	 */
1106 	SCSI_PROBE_DEBUG2(1, "SCSA pre-probe: checking tgt.LUN=%d.%d\n",
1107 	    ap->a_target, ap->a_lun);
1108 	SCSI_PROBE_DEBUG1(2,
1109 	    "SCSA pre-probe: scanning parent node name: %s ...\n",
1110 	    ddi_node_name(pdevi));
1111 
1112 	/*
1113 	 * look for a special property of our parent node that lists
1114 	 * the targets under it for which we do *NOT* want to probe
1115 	 * if LUN>7 -- if the property is found, look to see if our
1116 	 * target ID is on that list
1117 	 */
1118 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY,
1119 	    pdevi, DDI_PROP_DONTPASS, SS2_LUN0_TGT_LIST_PROP,
1120 	    &tgt_list, &tgt_nelements) != DDI_PROP_SUCCESS) {
1121 		/*
1122 		 * no list, so it must be okay to probe this target.LUN
1123 		 */
1124 		SCSI_PROBE_DEBUG0(3,
1125 		    "SCSA pre-probe: NO parent prop found\n");
1126 	} else {
1127 		for (i = 0; i < tgt_nelements; i++) {
1128 			if (tgt_list[i] == ap->a_target) {
1129 				/*
1130 				 * we found a match, which means we do *NOT*
1131 				 * want to probe the specified target.LUN
1132 				 */
1133 				ret_val = 1;
1134 				break;
1135 			}
1136 		}
1137 		ddi_prop_free(tgt_list);
1138 #ifdef	DEBUG
1139 		if (ret_val == 1) {
1140 			SCSI_PROBE_DEBUG2(1,
1141 			    "SCSA pre-probe: marker node FOUND for "
1142 			    "tgt.LUN=%d.%d, so SKIPPING it\n",
1143 			    ap->a_target, ap->a_lun);
1144 		} else {
1145 			SCSI_PROBE_DEBUG0(2,
1146 			    "SCSA pre-probe: NO marker node found"
1147 			    " -- OK to probe\n");
1148 		}
1149 #endif
1150 	}
1151 	return (ret_val);
1152 }
1153 
1154 
1155 /*
1156  * this routine is called from near the end of scsi_probe(),
1157  * to see if the just-probed node is on our list of strictly-SCSI-2 nodes,
1158  * and if it is we mark our parent node with this information
1159  */
1160 static void
1161 scsi_establish_LUN_limit(struct scsi_device *sd)
1162 {
1163 	struct scsi_address	*ap = &(sd->sd_address);
1164 	struct scsi_inquiry	*inq = sd->sd_inq;
1165 	dev_info_t		*devi = sd->sd_dev;
1166 	char			*vid = NULL;
1167 	char			*pid = NULL;
1168 	char			*rev = NULL;
1169 	int			i;
1170 	const ss2_lun0_info_t	*p;
1171 	int			bad_target_found = 0;
1172 
1173 
1174 	/*
1175 	 * if this inquiry data shows that we have a strictly-SCSI-2 device
1176 	 * at LUN 0, then add it to our list of strictly-SCSI-2 devices,
1177 	 * so that we can avoid probes where LUN>7 on this device later
1178 	 */
1179 	if ((ap->a_lun != 0) ||
1180 	    (ap->a_target >= NTARGETS_WIDE) ||
1181 	    (inq->inq_dtype != DTYPE_PROCESSOR) ||
1182 	    (inq->inq_ansi != 2)) {
1183 		/*
1184 		 * this can't possibly be a node we want to look at, since
1185 		 * either LUN is greater than 0, target is greater than or
1186 		 * equal to 16, device type
1187 		 * is not processor, or SCSI level is not SCSI-2,
1188 		 * so don't bother checking for a strictly SCSI-2
1189 		 * (only 8 LUN) target
1190 		 */
1191 		return;				/* don't care */
1192 	}
1193 
1194 	SCSI_PROBE_DEBUG2(1, "SCSA post-probe: LUN limit on tgt.LUN=%d.%d, "
1195 	    "SCSI-2 PROCESSOR?\n", ap->a_target, ap->a_lun);
1196 
1197 	ASSERT(devi != NULL);
1198 
1199 	/*
1200 	 * we have a node that has been probed that is: LUN=0, target<16,
1201 	 * PROCESSOR-type SCSI target, and at the SCSI-2 level, so
1202 	 * check INQ properties to see if it's in our list of strictly
1203 	 * SCSI-2 targets
1204 	 *
1205 	 * first we have to get the VID/PID/REV INQUIRY properties for
1206 	 * comparison
1207 	 */
1208 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
1209 	    INQUIRY_VENDOR_ID, &vid) != DDI_PROP_SUCCESS) {
1210 		SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n",
1211 		    INQUIRY_VENDOR_ID);
1212 		goto dun;
1213 	}
1214 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
1215 	    INQUIRY_PRODUCT_ID, &pid) != DDI_PROP_SUCCESS) {
1216 		SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n",
1217 		    INQUIRY_PRODUCT_ID);
1218 		goto dun;
1219 	}
1220 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
1221 	    INQUIRY_REVISION_ID, &rev) != DDI_PROP_SUCCESS) {
1222 		SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n",
1223 		    INQUIRY_REVISION_ID);
1224 		goto dun;
1225 	}
1226 
1227 	SCSI_PROBE_DEBUG3(3, "SCSA post-probe: looking for vid/pid/rev = "
1228 	    "\"%s\"/\"%s\"/\"%s\"\n", vid, pid, rev);
1229 
1230 	/*
1231 	 * now that we have the INQUIRY properties from the device node,
1232 	 * compare them with our known offenders
1233 	 *
1234 	 * Note: comparison is *CASE* *SENSITIVE*
1235 	 */
1236 	for (i = 0; i < scsi_probe_strict_s2_size; i++) {
1237 		p = &scsi_probe_strict_s2_list[i];
1238 
1239 		if ((strcmp(p->sli_vid, vid) == 0) &&
1240 		    (strcmp(p->sli_pid, pid) == 0) &&
1241 		    (strcmp(p->sli_rev, rev) == 0)) {
1242 			/*
1243 			 * we found a match -- do NOT want to probe this one
1244 			 */
1245 			SCSI_PROBE_DEBUG3(1,
1246 			    "SCSA post-probe: recording strict SCSI-2 node "
1247 			    "vid/pid/rev = \"%s\"/\"%s\"/\"%s\"\n",
1248 			    vid, pid, rev);
1249 
1250 			/*
1251 			 * set/update private parent-node property,
1252 			 * so we can find out about this node later
1253 			 */
1254 			bad_target_found = 1;
1255 			break;
1256 		}
1257 	}
1258 
1259 	/*
1260 	 * either add remove target number from parent property
1261 	 */
1262 	scsi_update_parent_ss2_prop(devi, ap->a_target, bad_target_found);
1263 
1264 dun:
1265 	if (vid != NULL) {
1266 		ddi_prop_free(vid);
1267 	}
1268 	if (pid != NULL) {
1269 		ddi_prop_free(pid);
1270 	}
1271 	if (rev != NULL) {
1272 		ddi_prop_free(rev);
1273 	}
1274 }
1275 
1276 
1277 /*
1278  * update the parent node to add in the supplied tgt number to the target
1279  * list property already present (if any)
1280  *
1281  * since the target list can never be longer than 16, and each target
1282  * number is also small, we can save having to alloc memory by putting
1283  * a 16-byte array on the stack and using it for property memory
1284  *
1285  * if "add_tgt" is set then add the target to the parent's property, else
1286  * remove it (if present)
1287  */
1288 static void
1289 scsi_update_parent_ss2_prop(dev_info_t *devi, int tgt, int add_tgt)
1290 {
1291 	dev_info_t	*pdevi = (dev_info_t *)DEVI(devi)->devi_parent;
1292 	uchar_t		*tgt_list;
1293 	uint_t		nelements;
1294 	uint_t		new_nelements;
1295 	int		i;
1296 	int		update_result;
1297 	uchar_t		new_tgt_list[NTARGETS_WIDE];
1298 
1299 
1300 	ASSERT(pdevi != NULL);
1301 
1302 	SCSI_PROBE_DEBUG3(3,
1303 	    "SCSA post-probe: updating parent=%s property to %s tgt=%d\n",
1304 	    ddi_node_name(pdevi), add_tgt ? "add" : "remove", tgt);
1305 
1306 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, pdevi, DDI_PROP_DONTPASS,
1307 	    SS2_LUN0_TGT_LIST_PROP, &tgt_list, &nelements) ==
1308 	    DDI_PROP_SUCCESS) {
1309 
1310 		if (add_tgt) {
1311 			/*
1312 			 * we found an existing property -- we might need
1313 			 *	to add to it
1314 			 */
1315 			for (i = 0; i < nelements; i++) {
1316 				if (tgt_list[i] == tgt) {
1317 					/* target already in list */
1318 					SCSI_PROBE_DEBUG1(2, "SCSA post-probe:"
1319 					    " tgt %d already listed\n", tgt);
1320 					ddi_prop_free(tgt_list);
1321 					return;
1322 				}
1323 			}
1324 
1325 			/*
1326 			 * need to append our target number to end of list
1327 			 *	(no need sorting list, as it's so short)
1328 			 */
1329 
1330 			/*
1331 			 * will this new entry fit ?? -- it should, since
1332 			 *	the array is 16-wide and only keep track of
1333 			 *	16 targets, but check just in case
1334 			 */
1335 			new_nelements = nelements + 1;
1336 			if (new_nelements >= NTARGETS_WIDE) {
1337 				SCSI_PROBE_DEBUG0(1, "SCSA post-probe: "
1338 				    "internal error: no room "
1339 				    "for more targets?\n");
1340 				ddi_prop_free(tgt_list);
1341 				return;
1342 			}
1343 
1344 			/* copy existing list then add our tgt number to end */
1345 			bcopy((void *)tgt_list, (void *)new_tgt_list,
1346 			    sizeof (uchar_t) * nelements);
1347 			new_tgt_list[new_nelements - 1] = (uchar_t)tgt;
1348 		} else {
1349 			/*
1350 			 * we need to remove our target number from the list,
1351 			 *	so copy all of the other target numbers,
1352 			 *	skipping ours
1353 			 */
1354 			int	tgt_removed = 0;
1355 
1356 			new_nelements = 0;
1357 			for (i = 0; i < nelements; i++) {
1358 				if (tgt_list[i] != tgt) {
1359 					new_tgt_list[new_nelements++] =
1360 					    tgt_list[i];
1361 				} else {
1362 					/* skip this target */
1363 					tgt_removed++;
1364 				}
1365 			}
1366 
1367 			if (!tgt_removed) {
1368 				SCSI_PROBE_DEBUG1(2, "SCSA post-probe:"
1369 				    " no need to remove tgt %d\n", tgt);
1370 				ddi_prop_free(tgt_list);
1371 				return;
1372 			}
1373 		}
1374 
1375 		update_result = ddi_prop_update_byte_array(DDI_DEV_T_NONE,
1376 		    pdevi, SS2_LUN0_TGT_LIST_PROP, new_tgt_list,
1377 		    new_nelements);
1378 
1379 		ddi_prop_free(tgt_list);
1380 	} else {
1381 		/*
1382 		 * no property yet
1383 		 */
1384 		if (add_tgt) {
1385 			/*
1386 			 * create a property with just our tgt
1387 			 */
1388 			new_tgt_list[0] = (uchar_t)tgt;
1389 			new_nelements = 1;	/* just one element */
1390 
1391 			update_result = ddi_prop_update_byte_array(
1392 			    DDI_DEV_T_NONE, pdevi, SS2_LUN0_TGT_LIST_PROP,
1393 			    new_tgt_list, new_nelements);
1394 		} else {
1395 			/*
1396 			 * no list so no need to remove tgt from that list
1397 			 */
1398 			return;
1399 		}
1400 	}
1401 
1402 #ifdef	DEBUG
1403 	/*
1404 	 * if we get here we have tried to add/update properties
1405 	 */
1406 	if (update_result != DDI_PROP_SUCCESS) {
1407 		SCSI_PROBE_DEBUG2(1, "SCSA post-probe: can't update parent "
1408 		    "property with tgt=%d (%d)\n", tgt, update_result);
1409 	} else {
1410 		if (add_tgt) {
1411 			SCSI_PROBE_DEBUG3(2,
1412 			    "SCSA post-probe: added tgt=%d to parent "
1413 			    "prop=\"%s\" (now %d entries)\n",
1414 			    tgt, SS2_LUN0_TGT_LIST_PROP, new_nelements);
1415 		} else {
1416 			SCSI_PROBE_DEBUG3(2,
1417 			    "SCSA post-probe: removed tgt=%d from parent "
1418 			    "prop=\"%s\" (now %d entries)\n",
1419 			    tgt, SS2_LUN0_TGT_LIST_PROP, new_nelements);
1420 		}
1421 	}
1422 #endif
1423 }
1424 
1425 
1426 /* XXX BEGIN: find a better place for this: inquiry.h? */
1427 /*
1428  * Definitions used by device id registration routines
1429  */
1430 #define	VPD_HEAD_OFFSET		3	/* size of head for vpd page */
1431 #define	VPD_PAGE_LENGTH		3	/* offset for pge length data */
1432 #define	VPD_MODE_PAGE		1	/* offset into vpd pg for "page code" */
1433 
1434 /* size for devid inquiries */
1435 #define	MAX_INQUIRY_SIZE	0xF0
1436 #define	MAX_INQUIRY_SIZE_EVPD	0xFF	/* XXX why is this longer */
1437 /* XXX END: find a better place for these */
1438 
1439 
1440 /*
1441  * Decorate devinfo node with identity properties using information obtained
1442  * from device. These properties are used by device enumeration code to derive
1443  * the devid, and guid for the device. These properties are also used to
1444  * determine if a device should be enumerated under the physical HBA (PHCI) or
1445  * the virtual HBA (VHCI, for mpxio support).
1446  *
1447  * Return zero on success. If commands that should succeed fail or allocations
1448  * fail then return failure (non-zero). It is possible for this function to
1449  * return success and not have decorated the node with any additional identity
1450  * information if the device correctly responds indicating that they are not
1451  * supported.  When failure occurs the caller should consider not making the
1452  * device accessible.
1453  */
1454 int
1455 scsi_device_identity(struct scsi_device *sd, int (*callback)())
1456 {
1457 	dev_info_t	*devi		= sd->sd_dev;
1458 	uchar_t		*inq80		= NULL;
1459 	uchar_t		*inq83		= NULL;
1460 	int		rval;
1461 	size_t		len;
1462 	int		pg80, pg83;
1463 
1464 	/* find out what pages are supported by device */
1465 	if (check_vpd_page_support8083(sd, callback, &pg80, &pg83) == -1)
1466 		return (-1);
1467 
1468 	/* if available, collect page 80 data and add as property */
1469 	if (pg80) {
1470 		inq80 = kmem_zalloc(MAX_INQUIRY_SIZE,
1471 		    ((callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP));
1472 		if (inq80 == NULL) {
1473 			rval = -1;
1474 			goto out;
1475 		}
1476 
1477 		rval = send_scsi_INQUIRY(sd, callback, inq80,
1478 		    MAX_INQUIRY_SIZE, 0x01, 0x80, &len);
1479 		if (rval)
1480 			goto out;		/* should have worked */
1481 
1482 		if (len && (ndi_prop_update_byte_array(DDI_DEV_T_NONE, devi,
1483 		    "inquiry-page-80", inq80, len) != DDI_PROP_SUCCESS)) {
1484 			cmn_err(CE_WARN, "scsi_device_identity: "
1485 			    "failed to add page80 prop");
1486 			rval = -1;
1487 			goto out;
1488 		}
1489 	}
1490 
1491 	/* if available, collect page 83 data and add as property */
1492 	if (pg83) {
1493 		inq83 = kmem_zalloc(MAX_INQUIRY_SIZE,
1494 		    ((callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP));
1495 		if (inq83 == NULL) {
1496 			rval = -1;
1497 			goto out;
1498 		}
1499 
1500 		rval = send_scsi_INQUIRY(sd, callback, inq83,
1501 		    MAX_INQUIRY_SIZE, 0x01, 0x83, &len);
1502 		if (rval)
1503 			goto out;		/* should have worked */
1504 
1505 		if (len && (ndi_prop_update_byte_array(DDI_DEV_T_NONE, devi,
1506 		    "inquiry-page-83", inq83, len) != DDI_PROP_SUCCESS)) {
1507 			cmn_err(CE_WARN, "scsi_device_identity: "
1508 			    "failed to add page83 prop");
1509 			rval = -1;
1510 			goto out;
1511 		}
1512 	}
1513 
1514 	/* Commands worked, identity information that exists has been added. */
1515 	rval = 0;
1516 
1517 	/* clean up resources */
1518 out:	if (inq80 != NULL)
1519 		kmem_free(inq80, MAX_INQUIRY_SIZE);
1520 	if (inq83 != NULL)
1521 		kmem_free(inq83, MAX_INQUIRY_SIZE);
1522 
1523 	return (rval);
1524 }
1525 
1526 /*
1527  * Send an INQUIRY command with the EVPD bit set and a page code of 0x00 to
1528  * the device, returning zero on success. Returned INQUIRY data is used to
1529  * determine which vital product pages are supported. The device idenity
1530  * information we are looking for is in pages 0x83 and/or 0x80. If the device
1531  * fails the EVPD inquiry then no pages are supported but the call succeeds.
1532  * Return -1 (failure) if there were memory allocation failures or if a
1533  * command faild that should have worked.
1534  */
1535 static int
1536 check_vpd_page_support8083(struct scsi_device *sd, int (*callback)(),
1537 	int *ppg80, int *ppg83)
1538 {
1539 	uchar_t *page_list;
1540 	int	counter;
1541 	int	rval;
1542 
1543 	/* pages are not supported */
1544 	*ppg80 = 0;
1545 	*ppg83 = 0;
1546 
1547 	/*
1548 	 * We'll set the page length to the maximum to save figuring it out
1549 	 * with an additional call.
1550 	 */
1551 	page_list =  kmem_zalloc(MAX_INQUIRY_SIZE_EVPD,
1552 	    ((callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP));
1553 	if (page_list == NULL)
1554 		return (-1);		/* memory allocation problem */
1555 
1556 	/* issue page 0 (Supported VPD Pages) INQUIRY with evpd set */
1557 	rval = send_scsi_INQUIRY(sd, callback,
1558 	    page_list, MAX_INQUIRY_SIZE_EVPD, 1, 0, NULL);
1559 
1560 	/*
1561 	 * Now we must validate that the device accepted the command (some
1562 	 * devices do not support it) and if the idenity pages we are
1563 	 * interested in are supported.
1564 	 */
1565 	if ((rval == 0) &&
1566 	    (page_list[VPD_MODE_PAGE] == 0x00)) {
1567 		/* Loop to find one of the 2 pages we need */
1568 		counter = 4;  /* Supported pages start at byte 4, with 0x00 */
1569 
1570 		/*
1571 		 * Pages are returned in ascending order, and 0x83 is the
1572 		 * last page we are hoping to find.
1573 		 */
1574 		while ((page_list[counter] <= 0x83) &&
1575 		    (counter <= (page_list[VPD_PAGE_LENGTH] +
1576 		    VPD_HEAD_OFFSET))) {
1577 			/*
1578 			 * Add 3 because page_list[3] is the number of
1579 			 * pages minus 3
1580 			 */
1581 
1582 			switch (page_list[counter]) {
1583 			case 0x80:
1584 				*ppg80 = 1;
1585 				break;
1586 			case 0x83:
1587 				*ppg83 = 1;
1588 				break;
1589 			}
1590 			counter++;
1591 		}
1592 	}
1593 
1594 	kmem_free(page_list, MAX_INQUIRY_SIZE_EVPD);
1595 	return (0);
1596 }
1597 
1598 /*
1599  * Send INQUIRY command with specified EVPD and page code.  Return
1600  * zero on success.  On success, the amount of data transferred
1601  * is returned in *lenp.
1602  */
1603 static int
1604 send_scsi_INQUIRY(struct scsi_device *sd, int (*callback)(),
1605     uchar_t *bufaddr, size_t buflen,
1606     uchar_t evpd, uchar_t page_code, size_t *lenp)
1607 {
1608 	int		(*cb_flag)();
1609 	struct buf	*inq_bp;
1610 	struct scsi_pkt *inq_pkt = NULL;
1611 	int		rval = -1;
1612 
1613 	if (lenp)
1614 		*lenp = 0;
1615 	if (callback != SLEEP_FUNC && callback != NULL_FUNC)
1616 		cb_flag = NULL_FUNC;
1617 	else
1618 		cb_flag = callback;
1619 	inq_bp = scsi_alloc_consistent_buf(ROUTE,
1620 	    (struct buf *)NULL, buflen, B_READ, cb_flag, NULL);
1621 	if (inq_bp == NULL)
1622 		goto out;		/* memory allocation problem */
1623 
1624 	inq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
1625 	    inq_bp, CDB_GROUP0, sizeof (struct scsi_arq_status),
1626 	    0, PKT_CONSISTENT, callback, NULL);
1627 	if (inq_pkt == NULL)
1628 		goto out;		/* memory allocation problem */
1629 
1630 	ASSERT(inq_bp->b_error == 0);
1631 
1632 	/* form INQUIRY cdb with specified EVPD and page code */
1633 	(void) scsi_setup_cdb((union scsi_cdb *)inq_pkt->pkt_cdbp,
1634 	    SCMD_INQUIRY, 0, buflen, 0);
1635 	inq_pkt->pkt_cdbp[1] = evpd;
1636 	inq_pkt->pkt_cdbp[2] = page_code;
1637 
1638 	inq_pkt->pkt_time = SCSI_POLL_TIMEOUT;	/* in seconds */
1639 	inq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
1640 
1641 	/*
1642 	 * Issue inquiry command thru scsi_test
1643 	 *
1644 	 * NOTE: This is important data about device identity, not sure why
1645 	 * NOPARITY is used. Also seems like we should check pkt_stat for
1646 	 * STATE_XFERRED_DATA.
1647 	 */
1648 	if ((scsi_test(inq_pkt) == 0) &&
1649 	    (inq_pkt->pkt_reason == CMD_CMPLT) &&
1650 	    (((*inq_pkt->pkt_scbp) & STATUS_MASK) == 0)) {
1651 		ASSERT(inq_pkt->pkt_resid >= 0);
1652 		ASSERT(inq_pkt->pkt_resid <= buflen);
1653 
1654 		bcopy(inq_bp->b_un.b_addr,
1655 		    bufaddr, buflen - inq_pkt->pkt_resid);
1656 		if (lenp)
1657 			*lenp = (buflen - inq_pkt->pkt_resid);
1658 		rval = 0;
1659 	}
1660 
1661 out:	if (inq_pkt)
1662 		scsi_destroy_pkt(inq_pkt);
1663 	if (inq_bp)
1664 		scsi_free_consistent_buf(inq_bp);
1665 	return (rval);
1666 }
1667