Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/scsi/conf/scsi_confsubr.c
+++ new/usr/src/uts/common/io/scsi/conf/scsi_confsubr.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 /*
26 26 * Utility SCSI configuration routines
27 27 */
28 28 /*
29 29 * Many routines in this file have built in parallel bus assumption
30 30 * which might need to change as other interconnect evolve.
31 31 */
32 32
33 33 #include <sys/scsi/scsi.h>
34 34 #include <sys/modctl.h>
35 35 #include <sys/bitmap.h>
36 36 #include <sys/fm/protocol.h>
37 37
38 38 /*
39 39 * macro for filling in lun value for scsi-1 support
40 40 */
41 41
42 42 #define FILL_SCSI1_LUN(sd, pkt) \
43 43 if ((sd->sd_address.a_lun > 0) && \
44 44 (sd->sd_inq->inq_ansi == 0x1)) { \
45 45 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \
46 46 sd->sd_address.a_lun; \
↓ open down ↓ |
46 lines elided |
↑ open up ↑ |
47 47 }
48 48
49 49 extern struct mod_ops mod_miscops;
50 50
51 51 static struct modlmisc modlmisc = {
52 52 &mod_miscops, /* Type of module */
53 53 "SCSI Bus Utility Routines"
54 54 };
55 55
56 56 static struct modlinkage modlinkage = {
57 - MODREV_1, (void *)&modlmisc, NULL
57 + MODREV_1, { (void *)&modlmisc, NULL }
58 58 };
59 59
60 60 /*
61 61 * Contexts from which we call scsi_test
62 62 */
63 63 enum scsi_test_ctxt {
64 64 /*
65 65 * Those in scsi_hba_probe_pi()
66 66 */
67 67 STC_PROBE_FIRST_INQ,
68 68 STC_PROBE_FIRST_INQ_RETRY,
69 69 STC_PROBE_PARTIAL_SUCCESS,
70 70 STC_PROBE_RQSENSE1,
71 71 STC_PROBE_CHK_CLEARED,
72 72 STC_PROBE_RQSENSE2,
73 73 STC_PROBE_INQ_FINAL,
74 74 /*
75 75 * Those in check_vpd_page_support8083()
76 76 */
77 77 STC_VPD_CHECK,
78 78 /*
79 79 * Those in scsi_device_identity()
80 80 */
81 81 STC_IDENTITY_PG80,
82 82 STC_IDENTITY_PG83,
83 83 };
84 84
85 85 static void create_inquiry_props(struct scsi_device *);
86 86
87 87 static int scsi_check_ss2_LUN_limit(struct scsi_device *);
88 88 static void scsi_establish_LUN_limit(struct scsi_device *);
89 89 static void scsi_update_parent_ss2_prop(dev_info_t *, int, int);
90 90
91 91 static int check_vpd_page_support8083(struct scsi_device *sd,
92 92 int (*callback)(), int *, int *);
93 93 static int send_scsi_INQUIRY(struct scsi_device *sd,
94 94 int (*callback)(), uchar_t *bufaddr, size_t buflen,
95 95 uchar_t evpd, uchar_t page_code, size_t *lenp,
96 96 enum scsi_test_ctxt);
97 97
98 98 /*
99 99 * this int-array HBA-node property keeps track of strictly SCSI-2
100 100 * target IDs
101 101 */
102 102 #define SS2_LUN0_TGT_LIST_PROP "ss2-targets"
103 103
104 104 /*
105 105 * for keeping track of nodes for which we do *NOT* want to probe above LUN 7
106 106 * (i.e. strict SCSI-2 targets)
107 107 *
108 108 * note that we could also keep track of dtype (SCSI device type) and
109 109 * ANSI (SCSI standard conformance level), but all currently-known cases of
110 110 * this problem are on SCSI-2 PROCESSOR device types
111 111 */
112 112 typedef struct ss2_lun0_info {
113 113 const char *sli_vid; /* SCSI inquiry VID */
114 114 const char *sli_pid; /* SCSI inquiry PID */
115 115 const char *sli_rev; /* SCSI inquiry REV */
116 116 } ss2_lun0_info_t;
117 117
118 118 /*
119 119 * these two workarounds are for the SCSI-2 GEM2* chips used in the
120 120 * D1000 and D240
121 121 */
122 122 #define SES_D1000_VID "SYMBIOS"
123 123 #define SES_D1000_PID "D1000" /* the D1000 */
124 124 #define SES_D1000_REV "2"
125 125
126 126 #define SES_D240_VID "SUN"
127 127 #define SES_D240_PID "D240" /* the D240 */
128 128 #define SES_D240_REV "2"
129 129
130 130 /*
131 131 * a static list of targets where we do *not* want to probe above LUN 7
132 132 */
133 133 static const ss2_lun0_info_t scsi_probe_strict_s2_list[] = {
134 134 {SES_D1000_VID, SES_D1000_PID, SES_D1000_REV},
135 135 {SES_D240_VID, SES_D240_PID, SES_D240_REV},
136 136 };
137 137
138 138 static const int scsi_probe_strict_s2_size =
139 139 sizeof (scsi_probe_strict_s2_list) / sizeof (struct ss2_lun0_info);
140 140
141 141
142 142 #ifdef DEBUG
143 143
144 144 int scsi_probe_debug = 0;
145 145
146 146 #define SCSI_PROBE_DEBUG0(l, s) \
147 147 if (scsi_probe_debug >= (l)) printf(s)
148 148 #define SCSI_PROBE_DEBUG1(l, s, a1) \
149 149 if (scsi_probe_debug >= (l)) printf(s, a1)
150 150 #define SCSI_PROBE_DEBUG2(l, s, a1, a2) \
151 151 if (scsi_probe_debug >= (l)) printf(s, a1, a2)
152 152 #define SCSI_PROBE_DEBUG3(l, s, a1, a2, a3) \
153 153 if (scsi_probe_debug >= (l)) printf(s, a1, a2, a3)
154 154
155 155 #else /* DEBUG */
156 156
157 157 #define SCSI_PROBE_DEBUG0(l, s)
158 158 #define SCSI_PROBE_DEBUG1(l, s, a1)
159 159 #define SCSI_PROBE_DEBUG2(l, s, a1, a2)
160 160 #define SCSI_PROBE_DEBUG3(l, s, a1, a2, a3)
161 161
162 162 #endif /* DEBUG */
163 163
164 164 int scsi_test_busy_timeout = SCSI_POLL_TIMEOUT; /* in seconds */
165 165 int scsi_test_busy_delay = 10000; /* 10msec in usec */
166 166
167 167
168 168 /*
169 169 * Returns from scsi_test.
170 170 *
171 171 * SCSI_TEST_CMPLT_GOOD => TRAN_ACCEPT, CMD_CMPLT, STATUS_GOOD
172 172 *
173 173 * SCSI_TEST_CMPLT_BUSY => TRAN_ACCEPT, CMD_CMPLT, STATUS_BUSY
174 174 *
175 175 * SCSI_TEST_CMPLT_CHECK => TRAN_ACCEPT, CMD_CMPLT, STATUS_CHECK
176 176 *
177 177 * SCSI_TEST_CMPLT_OTHER => TRAN_ACCEPT, CMD_CMPLT, !STATUS_{GOOD,BUSY,CHECK}
178 178 *
179 179 * SCSI_TEST_CMD_INCOMPLETE => TRAN_ACCEPT, CMD_INCOMPLETE
180 180 *
181 181 * SCSI_TEST_NOTCMPLT => TRAN_ACCEPT, pkt_reason != CMD_{CMPLT,INCOMPLETE}
182 182 *
183 183 * SCSI_TEST_TRAN_BUSY => (Repeated) TRAN_BUSY from attempt scsi_transport
184 184 *
185 185 * SCSI_TEST_TRAN_REJECT => TRAN_BADPKT or TRAN_FATAL_ERROR
186 186 *
187 187 */
188 188 #define SCSI_TEST_CMPLT_GOOD 0x01U
189 189 #define SCSI_TEST_CMPLT_BUSY 0x02U
190 190 #define SCSI_TEST_CMPLT_CHECK 0x04U
191 191 #define SCSI_TEST_CMPLT_OTHER 0x08U
192 192
193 193 #define SCSI_TEST_CMPLTMASK \
194 194 (SCSI_TEST_CMPLT_GOOD | SCSI_TEST_CMPLT_BUSY | \
195 195 SCSI_TEST_CMPLT_CHECK | SCSI_TEST_CMPLT_OTHER)
196 196
197 197 #define SCSI_TEST_PARTCMPLTMASK \
198 198 (SCSI_TEST_CMPLTMASK & ~SCSI_TEST_CMPLT_GOOD)
199 199
200 200 #define SCSI_TEST_CMD_INCOMPLETE 0x10U
201 201 #define SCSI_TEST_NOTCMPLT 0x20U
202 202 #define SCSI_TEST_TRAN_BUSY 0x40U
203 203 #define SCSI_TEST_TRAN_REJECT 0x80U
204 204
205 205 #define SCSI_TEST_FAILMASK \
206 206 (SCSI_TEST_CMD_INCOMPLETE | SCSI_TEST_NOTCMPLT | \
207 207 SCSI_TEST_TRAN_BUSY | SCSI_TEST_TRAN_REJECT)
208 208
209 209 #define SCSI_TEST_FAILURE(x) (((x) & SCSI_TEST_FAILMASK) != 0)
210 210
211 211 /*
212 212 * architecture dependent allocation restrictions. For x86, we'll set
213 213 * dma_attr_addr_hi to scsi_max_phys_addr and dma_attr_sgllen to
214 214 * scsi_sgl_size during _init().
215 215 */
216 216 #if defined(__sparc)
217 217 ddi_dma_attr_t scsi_alloc_attr = {
218 218 DMA_ATTR_V0, /* version number */
219 219 0x0, /* lowest usable address */
220 220 0xFFFFFFFFull, /* high DMA address range */
221 221 0xFFFFFFFFull, /* DMA counter register */
222 222 1, /* DMA address alignment */
223 223 1, /* DMA burstsizes */
224 224 1, /* min effective DMA size */
225 225 0xFFFFFFFFull, /* max DMA xfer size */
226 226 0xFFFFFFFFull, /* segment boundary */
227 227 1, /* s/g list length */
228 228 512, /* granularity of device */
229 229 0 /* DMA transfer flags */
230 230 };
231 231 #elif defined(__x86)
232 232 ddi_dma_attr_t scsi_alloc_attr = {
233 233 DMA_ATTR_V0, /* version number */
234 234 0x0, /* lowest usable address */
235 235 0x0, /* high DMA address range [set in _init()] */
236 236 0xFFFFull, /* DMA counter register */
237 237 1, /* DMA address alignment */
238 238 1, /* DMA burstsizes */
239 239 1, /* min effective DMA size */
240 240 0xFFFFFFFFull, /* max DMA xfer size */
241 241 0xFFFFFFFFull, /* segment boundary */
242 242 0, /* s/g list length */
243 243 512, /* granularity of device [set in _init()] */
244 244 0 /* DMA transfer flags */
245 245 };
246 246 uint64_t scsi_max_phys_addr = 0xFFFFFFFFull;
247 247 int scsi_sgl_size = 0xFF;
248 248 #endif
249 249
250 250 ulong_t *scsi_pkt_bad_alloc_bitmap;
251 251
252 252 int
253 253 _init()
254 254 {
255 255 scsi_initialize_hba_interface();
256 256 scsi_watch_init();
257 257
258 258 #if defined(__x86)
259 259 /* set the max physical address for iob allocs on x86 */
260 260 scsi_alloc_attr.dma_attr_addr_hi = scsi_max_phys_addr;
261 261
262 262 /*
263 263 * set the sgllen for iob allocs on x86. If this is set less than
264 264 * the number of pages the buffer will take (taking into account
265 265 * alignment), it would force the allocator to try and allocate
266 266 * contiguous pages.
267 267 */
268 268 scsi_alloc_attr.dma_attr_sgllen = scsi_sgl_size;
269 269 #endif
270 270
271 271 /* bitmap to limit scsi_pkt allocation violation messages */
272 272 scsi_pkt_bad_alloc_bitmap = kmem_zalloc(BT_SIZEOFMAP(devcnt), KM_SLEEP);
273 273
274 274 return (mod_install(&modlinkage));
275 275 }
276 276
277 277 /*
278 278 * there is no _fini() routine because this module is never unloaded
279 279 */
280 280
281 281 int
282 282 _info(struct modinfo *modinfop)
283 283 {
284 284 return (mod_info(&modlinkage, modinfop));
285 285 }
286 286
287 287 #define ROUTE (&sd->sd_address)
288 288
289 289 static int
290 290 scsi_slave_do_rqsense(struct scsi_device *sd, int (*callback)())
291 291 {
292 292 struct scsi_pkt *rq_pkt = NULL;
293 293 struct buf *rq_bp = NULL;
294 294 int rval = SCSIPROBE_EXISTS;
295 295
296 296 /*
297 297 * prepare rqsense packet
298 298 */
299 299 rq_bp = scsi_alloc_consistent_buf(ROUTE, (struct buf *)NULL,
300 300 (uint_t)SENSE_LENGTH, B_READ, callback, NULL);
301 301 if (rq_bp == NULL) {
302 302 rval = SCSIPROBE_NOMEM;
303 303 goto out;
304 304 }
305 305
306 306 rq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
307 307 rq_bp, CDB_GROUP0, 1, 0, PKT_CONSISTENT,
308 308 callback, NULL);
309 309
310 310 if (rq_pkt == NULL) {
311 311 if (rq_bp->b_error == 0)
312 312 rval = SCSIPROBE_NOMEM_CB;
313 313 else
314 314 rval = SCSIPROBE_NOMEM;
315 315 goto out;
316 316 }
317 317 ASSERT(rq_bp->b_error == 0);
318 318
319 319 (void) scsi_setup_cdb((union scsi_cdb *)rq_pkt->
320 320 pkt_cdbp, SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0);
321 321 FILL_SCSI1_LUN(sd, rq_pkt);
322 322 rq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY|FLAG_SENSING;
323 323
324 324 /*
325 325 * The controller type is as yet unknown, so we
326 326 * have to do a throwaway non-extended request sense,
327 327 * and hope that that clears the check condition
328 328 * for that unit until we can find out what kind
329 329 * of drive it is. A non-extended request sense
330 330 * is specified by stating that the sense block
331 331 * has 0 length, which is taken to mean that it
332 332 * is four bytes in length.
333 333 */
334 334 if (scsi_poll(rq_pkt) < 0) {
335 335 rval = SCSIPROBE_FAILURE;
336 336 }
337 337
338 338 out:
339 339 if (rq_pkt) {
340 340 scsi_destroy_pkt(rq_pkt);
341 341 }
342 342 if (rq_bp) {
343 343 scsi_free_consistent_buf(rq_bp);
344 344 }
345 345
346 346 return (rval);
347 347 }
348 348
349 349 /*
350 350 *
351 351 * SCSI slave probe routine - provided as a service to target drivers
352 352 *
353 353 * Mostly attempts to allocate and fill sd inquiry data..
354 354 */
355 355
356 356 int
357 357 scsi_slave(struct scsi_device *sd, int (*callback)())
358 358 {
359 359 struct scsi_pkt *pkt;
360 360 int rval = SCSIPROBE_EXISTS;
361 361
362 362 /*
363 363 * the first test unit ready will tell us whether a target
364 364 * responded and if there was one, it will clear the unit attention
365 365 * condition
366 366 */
367 367 pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, NULL,
368 368 CDB_GROUP0, sizeof (struct scsi_arq_status), 0, 0, callback, NULL);
369 369
370 370 if (pkt == NULL) {
371 371 return (SCSIPROBE_NOMEM_CB);
372 372 }
373 373
374 374 (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp,
375 375 SCMD_TEST_UNIT_READY, 0, 0, 0);
376 376 FILL_SCSI1_LUN(sd, pkt);
377 377 pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
378 378
379 379 if (scsi_poll(pkt) < 0) {
380 380 if (pkt->pkt_reason == CMD_INCOMPLETE)
381 381 rval = SCSIPROBE_NORESP;
382 382 else
383 383 rval = SCSIPROBE_FAILURE;
384 384
385 385 if ((pkt->pkt_state & STATE_ARQ_DONE) == 0) {
386 386 if (((struct scsi_status *)pkt->pkt_scbp)->sts_chk)
387 387 /*
388 388 * scanner and processor devices can return a
389 389 * check condition here
390 390 */
391 391 rval = scsi_slave_do_rqsense(sd, callback);
392 392 }
393 393
394 394 if (rval != SCSIPROBE_EXISTS) {
395 395 scsi_destroy_pkt(pkt);
396 396 return (rval);
397 397 }
398 398 }
399 399
400 400 /*
401 401 * the second test unit ready, allows the host adapter to negotiate
402 402 * synchronous transfer period and offset
403 403 */
404 404 if (scsi_poll(pkt) < 0) {
405 405 if (pkt->pkt_reason == CMD_INCOMPLETE)
406 406 rval = SCSIPROBE_NORESP;
407 407 else
408 408 rval = SCSIPROBE_FAILURE;
409 409 }
410 410
411 411 /*
412 412 * do a rqsense if there was a check condition and ARQ was not done
413 413 */
414 414 if ((pkt->pkt_state & STATE_ARQ_DONE) == 0) {
415 415 if (((struct scsi_status *)pkt->pkt_scbp)->sts_chk) {
416 416 rval = scsi_slave_do_rqsense(sd, callback);
417 417 }
418 418 }
419 419
420 420 /*
421 421 * call scsi_probe to do the inquiry
422 422 *
423 423 * NOTE: there is minor difference with the old scsi_slave
424 424 * implementation: busy conditions are not handled in scsi_probe.
425 425 */
426 426 scsi_destroy_pkt(pkt);
427 427 if (rval == SCSIPROBE_EXISTS) {
428 428 return (scsi_probe(sd, callback));
429 429 } else {
430 430 return (rval);
431 431 }
432 432 }
433 433
434 434 /*
435 435 * Undo scsi_slave - older interface, but still supported
436 436 *
437 437 * NOTE: The 'sd_inq' inquiry data is now freed by scsi_hba/scsi_vhci code
438 438 * as part of free of scsi_device(9S).
439 439 */
440 440 /*ARGSUSED*/
441 441 void
442 442 scsi_unslave(struct scsi_device *sd)
443 443 {
444 444 }
445 445
446 446 /*
447 447 * Undo scsi_probe
448 448 *
449 449 * NOTE: The 'sd_inq' inquiry data is now freed by scsi_hba/scsi_vhci code
450 450 * as part of free of scsi_device(9S).
451 451 */
452 452 /*ARGSUSED*/
453 453 void
454 454 scsi_unprobe(struct scsi_device *sd)
455 455 {
456 456 }
457 457
458 458 /*
459 459 * We log all scsi_test failures (as long as we are SE_HP etc). The
460 460 * following table controls the "driver-assessment" payload item
461 461 * in the ereports we raise. If a scsi_test return features in the
462 462 * retry mask then the calling context will retry; if it features in
463 463 * the fatal mask then the caller will not retry (although higher-level
464 464 * software might); if in neither (which shouldn't happen - you either
465 465 * retry or give up) default to 'retry'.
466 466 */
467 467 static const struct scsi_test_profile {
468 468 enum scsi_test_ctxt stp_ctxt; /* Calling context */
469 469 uint32_t stp_retrymask; /* Returns caller will retry for */
470 470 uint32_t stp_fatalmask; /* Returns caller considers fatal */
471 471 } scsi_test_profile[] = {
472 472 /*
473 473 * This caller will retry on SCSI_TEST_FAILMASK as long as it was
474 474 * not SCSI_TEST_CMD_INCOMPLETE which is terminal. A return from
475 475 * SCSI_TEST_PARTCMPLTMASK (command complete but status other than
476 476 * STATUS_GOOD) is not terminal and we'll move on to the context
477 477 * of STC_PROBE_PARTIAL_SUCCESS so that's a retry, too.
478 478 */
479 479 {
480 480 STC_PROBE_FIRST_INQ,
481 481 SCSI_TEST_FAILMASK & ~SCSI_TEST_CMD_INCOMPLETE |
482 482 SCSI_TEST_PARTCMPLTMASK,
483 483 SCSI_TEST_CMD_INCOMPLETE
484 484 },
485 485
486 486 /*
487 487 * If the first inquiry fails outright we always retry just once
488 488 * (except for SCSI_TEST_CMD_INCOMPLETE as above). A return in
489 489 * SCSI_TEST_FAILMASK is terminal; for SCSI_TEST_PARTCMPLTMASK
490 490 * we will retry at STC_PROBE_PARTIAL_SUCCESS.
491 491 */
492 492 {
493 493 STC_PROBE_FIRST_INQ_RETRY,
494 494 SCSI_TEST_PARTCMPLTMASK,
495 495 SCSI_TEST_FAILMASK
496 496 },
497 497
498 498 /*
499 499 * If we've met with partial success we retry at caller context
500 500 * STC_PROBE_PARTIAL_SUCCESS. Any SCSI_TEST_FAILMASK return
501 501 * here is terminal, as too is SCSI_TEST_CMPLT_BUSY. A return in
502 502 * SCSI_TEST_PARTCMPLTMASK and we will continue with further
503 503 * inquiry attempts.
504 504 */
505 505 {
506 506 STC_PROBE_PARTIAL_SUCCESS,
507 507 SCSI_TEST_PARTCMPLTMASK & ~SCSI_TEST_CMPLT_BUSY,
508 508 SCSI_TEST_FAILMASK | SCSI_TEST_CMPLT_BUSY
509 509 },
510 510
511 511 /*
512 512 * If we get past the above target busy case then we will
513 513 * perform a sense request if scsi_test indicates STATUS_CHECK
514 514 * and ARQ was not done. We are not interested in logging telemetry
515 515 * for transports that do not perform ARQ automatically.
516 516 */
517 517 {
518 518 STC_PROBE_RQSENSE1,
519 519 0,
520 520 0
521 521 },
522 522
523 523 /*
524 524 * If "something" responded to the probe but then the next inquiry
525 525 * sees a change of heart then we fail the probe on any of
526 526 * SCSI_TEST_FAILMASK or SCSI_TEST_CMPLT_BUSY. For other values
527 527 * in SCSI_TEST_PARTCMPLTMASK we soldier on.
528 528 */
529 529 {
530 530 STC_PROBE_CHK_CLEARED,
531 531 SCSI_TEST_PARTCMPLTMASK & ~SCSI_TEST_CMPLT_BUSY,
532 532 SCSI_TEST_FAILMASK | SCSI_TEST_CMPLT_BUSY
533 533 },
534 534
535 535 /*
536 536 * If after all that there we still have STATUS_CHECK from the
537 537 * inquiry status then we resend the sense request but the
538 538 * result is ignored (just clearing the condition). Do not
539 539 * log.
540 540 */
541 541 {
542 542 STC_PROBE_RQSENSE2,
543 543 0,
544 544 0
545 545 },
546 546
547 547 /*
548 548 * After the above sense request we once again send an inquiry.
549 549 * If it fails outright or STATUS_CHECK persists we give up.
550 550 * Any partial result is considered success.
551 551 */
552 552 {
553 553 STC_PROBE_INQ_FINAL,
554 554 0,
555 555 SCSI_TEST_FAILMASK | SCSI_TEST_CMPLT_CHECK
556 556 },
557 557
558 558 /*
559 559 * check_vpd_page_support8083 called from scsi_device_identity
560 560 * performs an inquiry with EVPD set (and page necessarily 0)
561 561 * to see what pages are supported.
562 562 *
563 563 * Some devices do not support this command and therefore
564 564 * check_vpd_page_support8083 only returns an error of kmem_zalloc
565 565 * fails. If the send_scsi_INQUIRY does not meet with complete
566 566 * success (SCSI_TEST_CMPLT_GOOD) it returns -1, othewise 0.
567 567 * So any scsi_test failure here will cause us to assume no page
568 568 * 80/83 support, and we will proceed without devid support.
569 569 * So -1 returns from send_scsi_INQUIRY are not terminal.
570 570 */
571 571 {
572 572 STC_VPD_CHECK,
573 573 0,
574 574 0
575 575 },
576 576
577 577 /*
578 578 * If the above inquiry claims pg80 support then scsi_device_identity
579 579 * will perform a send_scsi_INQUIRY to retrieve that page.
580 580 * Anything other than SCSI_TEST_CMPLT_GOOD is a failure and will
581 581 * cause scsi_device_identity to return non-zero at which point the
582 582 * caller goes to SCSIPROBE_FAILURE.
583 583 */
584 584 {
585 585 STC_IDENTITY_PG80,
586 586 0,
587 587 SCSI_TEST_FAILMASK | SCSI_TEST_CMPLTMASK
588 588 },
589 589
590 590 /*
591 591 * Similarly for pg83
592 592 */
593 593 {
594 594 STC_IDENTITY_PG83,
595 595 0,
596 596 SCSI_TEST_FAILMASK | SCSI_TEST_CMPLTMASK
597 597 }
598 598 };
599 599
600 600 int scsi_test_ereport_disable = 0;
601 601
602 602 extern int e_devid_cache_path_to_devid(char *, char *, char *, ddi_devid_t *);
603 603
604 604 static void
605 605 scsi_test_ereport_post(struct scsi_pkt *pkt, enum scsi_test_ctxt ctxt,
606 606 uint32_t stresult)
607 607 {
608 608 char *nodename = NULL, *devidstr_buf = NULL, *devidstr = NULL;
609 609 const struct scsi_test_profile *tp = &scsi_test_profile[ctxt];
610 610 char ua[SCSI_MAXNAMELEN], nodenamebuf[SCSI_MAXNAMELEN];
611 611 union scsi_cdb *cdbp = (union scsi_cdb *)pkt->pkt_cdbp;
612 612 struct scsi_address *ap = &pkt->pkt_address;
613 613 char *tgt_port, *tpl0 = NULL;
614 614 ddi_devid_t devid = NULL;
615 615 dev_info_t *probe, *hba;
616 616 struct scsi_device *sd;
617 617 scsi_lun64_t lun64;
618 618 const char *d_ass;
619 619 const char *class;
620 620 char *pathbuf;
621 621 nvlist_t *pl;
622 622 uint64_t wwn;
623 623 int err = 0;
624 624 int dad = 0;
625 625 size_t len;
626 626 int lun;
627 627
628 628 if (scsi_test_ereport_disable)
629 629 return;
630 630
631 631 ASSERT(tp->stp_ctxt == ctxt);
632 632
633 633 if ((sd = scsi_address_device(ap)) == NULL)
634 634 return; /* Not SCSI_HBA_ADDR_COMPLEX */
635 635
636 636 probe = sd->sd_dev;
637 637 hba = ddi_get_parent(probe);
638 638
639 639 /*
640 640 * We only raise telemetry for SE_HP style enumeration
641 641 */
642 642 if (!ndi_dev_is_hotplug_node(hba))
643 643 return;
644 644
645 645 /*
646 646 * scsi_fm_ereport_post will use the hba for the fm-enabled devinfo
647 647 */
648 648 if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(hba)))
649 649 return;
650 650
651 651 /*
652 652 * Retrieve the unit address we were probing and the target
653 653 * port component thereof.
654 654 */
655 655 if (!scsi_ua_get(sd, ua, sizeof (ua)) ||
656 656 scsi_device_prop_lookup_string(sd, SCSI_DEVICE_PROP_PATH,
657 657 SCSI_ADDR_PROP_TARGET_PORT, &tgt_port) != DDI_PROP_SUCCESS)
658 658 return;
659 659
660 660 /*
661 661 * Determine whether unit address is location based or identity (wwn)
662 662 * based. If we can't convert the target port address to a wwn then
663 663 * we're location based.
664 664 */
665 665 if (scsi_wwnstr_to_wwn(tgt_port, &wwn) == DDI_FAILURE)
666 666 return;
667 667
668 668 /*
669 669 * Get lun and lun64
670 670 */
671 671 lun = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
672 672 SCSI_ADDR_PROP_LUN, 0);
673 673 lun64 = scsi_device_prop_get_int64(sd, SCSI_DEVICE_PROP_PATH,
674 674 SCSI_ADDR_PROP_LUN64, lun);
675 675
676 676 /*
677 677 * We are guaranteed not to be in interrupt or any other
678 678 * problematic context. So instead of repeated varargs
679 679 * style calls to scsi_fm_ereport_post for each flavour of
680 680 * ereport we have the luxury of being able to allocate
681 681 * and build an nvlist here.
682 682 *
683 683 * The ereports we raise here are all under the category
684 684 * ereport.io.scsi.cmd.disk category, namely
685 685 *
686 686 * ereport.io.scsi.cmd.disk.
687 687 * {dev.rqs.derr,dev.serr,tran}.
688 688 *
689 689 * For all ereports we also add the scsi_test specific payload.
690 690 * If we have it then we always include the devid in the payload
691 691 * (but only in the detector for device-as-detector ereports).
692 692 *
693 693 * Inherited From Member Name
694 694 * -------------------- -------------------
695 695 * .cmd driver-assessment
696 696 * .cmd op-code
697 697 * .cmd cdb
698 698 * .cmd pkt-reason
699 699 * .cmd pkt-state
700 700 * .cmd pkt-stats
701 701 * .cmd.disk stat-code
702 702 * - scsi-test-return
703 703 * - scsi-test-context
704 704 */
705 705
706 706 if (nvlist_alloc(&pl, NV_UNIQUE_NAME, 0) != 0)
707 707 return;
708 708
709 709 err |= nvlist_add_uint8(pl, "op-code", cdbp->scc_cmd);
710 710 err |= nvlist_add_uint8_array(pl, "cdb", pkt->pkt_cdbp,
711 711 pkt->pkt_cdblen);
712 712 err |= nvlist_add_uint8(pl, "pkt-reason", pkt->pkt_reason);
713 713 err |= nvlist_add_uint32(pl, "pkt-state", pkt->pkt_state);
714 714 err |= nvlist_add_uint32(pl, "pkt-stats", pkt->pkt_statistics);
715 715 err |= nvlist_add_uint32(pl, "stat-code", *pkt->pkt_scbp);
716 716 err |= nvlist_add_uint32(pl, "scsi-test-return", stresult);
717 717 err |= nvlist_add_int32(pl, "scsi-test-context", ctxt);
718 718
719 719 switch (stresult) {
720 720 case SCSI_TEST_CMPLT_BUSY:
721 721 dad = 1;
722 722 class = "cmd.disk.dev.serr";
723 723 break;
724 724
725 725 case SCSI_TEST_CMPLT_CHECK:
726 726 dad = 1;
727 727
728 728 if ((pkt->pkt_state & STATE_ARQ_DONE)) {
729 729 struct scsi_arq_status *arqstat;
730 730 uint8_t key, asc, ascq;
731 731 uint8_t *sensep;
732 732
733 733 class = "cmd.disk.dev.rqs.derr";
734 734 arqstat = (struct scsi_arq_status *)pkt->pkt_scbp;
735 735 sensep = (uint8_t *)&arqstat->sts_sensedata;
736 736 key = scsi_sense_key(sensep);
737 737 asc = scsi_sense_asc(sensep);
738 738 ascq = scsi_sense_ascq(sensep);
739 739
740 740 /*
741 741 * Add to payload.
742 742 */
743 743 err |= nvlist_add_uint8(pl, "key", key);
744 744 err |= nvlist_add_uint8(pl, "asc", asc);
745 745 err |= nvlist_add_uint8(pl, "ascq", ascq);
746 746 err |= nvlist_add_uint8_array(pl, "sense-data",
747 747 sensep, sizeof (arqstat->sts_sensedata));
748 748 } else {
749 749 class = "cmd.disk.dev.serr";
750 750 }
751 751
752 752 break;
753 753
754 754 case SCSI_TEST_CMPLT_OTHER:
755 755 dad = 1;
756 756 class = "cmd.disk.dev.serr";
757 757 break;
758 758
759 759 case SCSI_TEST_CMD_INCOMPLETE:
760 760 case SCSI_TEST_NOTCMPLT:
761 761 case SCSI_TEST_TRAN_BUSY:
762 762 case SCSI_TEST_TRAN_REJECT:
763 763 class = "cmd.disk.tran";
764 764 break;
765 765 }
766 766
767 767 /*
768 768 * Determine driver-assessment and add to payload.
769 769 */
770 770 if (dad) {
771 771 /*
772 772 * While higher level software can retry the enumeration
773 773 * the belief is that any device-as-detector style error
774 774 * will be persistent and will survive retries. So we
775 775 * can make a local determination of driver assessment.
776 776 * Some day it may be more elegant to raise an ereport from
777 777 * scsi_tgtmap_scsi_deactivate to confirm retries failed,
778 778 * and correlate that ereport during diagnosis.
779 779 */
780 780 if (stresult & tp->stp_fatalmask)
781 781 d_ass = (const char *)"fatal";
782 782 else if (stresult & tp->stp_retrymask)
783 783 d_ass = (const char *)"retry";
784 784 else
785 785 d_ass = (const char *)"retry";
786 786 } else {
787 787 /* We do not diagnose transport errors (yet) */
788 788 d_ass = (const char *)"retry";
789 789 }
790 790
791 791 err |= nvlist_add_string(pl, "driver-assessment", d_ass);
792 792
793 793 /*
794 794 * If we're hoping for a device-as-detector style ereport then
795 795 * we're going to need a devid for the detector FMRI. We
796 796 * don't have the devid because the target won't talk to us.
797 797 * But we do know which hba iport we were probing out of, and
798 798 * we know the unit address that was being probed (but not
799 799 * what type of device is or should be there). So we
800 800 * search the devid cache for any cached devid matching
801 801 * path <iport-path>/<nodename>@<unit-address> with nodename
802 802 * wildcarded. If a match is made we are returned not only the
803 803 * devid but also the nodename for the path that cached that
804 804 * entry.
805 805 *
806 806 * We also attempt to dig up a devid even for transport errors;
807 807 * we'll include that in the payload but not in the detector FMRI.
808 808 */
809 809
810 810 pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
811 811 (void) ddi_pathname(hba, pathbuf);
812 812
813 813 if (e_devid_cache_path_to_devid(pathbuf, ua, nodenamebuf,
814 814 &devid) == DDI_SUCCESS) {
815 815 nodename = nodenamebuf;
816 816 devidstr = devidstr_buf = ddi_devid_str_encode(devid, NULL);
817 817 kmem_free(devid, ddi_devid_sizeof(devid));
818 818 err |= nvlist_add_string(pl, "devid", devidstr);
819 819 }
820 820
821 821 /*
822 822 * If this is lun 0 we will include the target-port-l0id
823 823 * in the dev scheme detector for device-as-detector.
824 824 */
825 825 if (dad && (lun == 0 || lun64 == 0))
826 826 tpl0 = tgt_port;
827 827
828 828 /* Construct the devpath to use in the detector */
829 829 (void) ddi_pathname(hba, pathbuf);
830 830 len = strlen(pathbuf);
831 831 (void) snprintf(pathbuf + len, MAXPATHLEN - len, "/%s@%s",
832 832 nodename ? nodename : "unknown", ua);
833 833
834 834 /*
835 835 * Let's review.
836 836 *
837 837 * Device-as-detector ereports for which the attempted lookup of
838 838 * devid and nodename succeeded:
839 839 *
840 840 * - pathbuf has the full device path including nodename we
841 841 * dug up from the devid cache
842 842 *
843 843 * - class is one of cmd.disk.{dev.rqs.derr,dev.serr}
844 844 *
845 845 * - devidstr is non NULL and a valid devid string
846 846 *
847 847 * Would-be device-as-detector ereport for which the attempted lookup
848 848 * of devid failed:
849 849 *
850 850 * - pathbuf has a device path with leaf nodename of "unknown"
851 851 * but still including the unit-address
852 852 * - class is one of cmd.disk.{dev.rqs.derr,dev.serr}
853 853 *
854 854 * Transport errors:
855 855 *
856 856 * class is cmd.disk.tran
857 857 * devidstr is NULL
858 858 *
859 859 * - we may have succeeded in looking up a devid and nodename -
860 860 * the devid we'll have added to the payload but we must not
861 861 * add to detector FMRI, and if we have have nodename then
862 862 * we have a full devpath otherwise one with "unknown" for
863 863 * nodename
864 864 */
865 865
866 866 if (err)
867 867 (void) nvlist_add_boolean_value(pl, "payload-incomplete",
868 868 B_TRUE);
869 869
870 870 scsi_fm_ereport_post(
871 871 sd,
872 872 0, /* path_instance - always 0 */
873 873 pathbuf, /* devpath for detector */
874 874 class, /* ereport class suffix */
875 875 0, /* ENA - generate for us */
876 876 dad ? devidstr : NULL, /* dtcr devid, dev-as-det only */
877 877 tpl0, /* target-port-l0id */
878 878 DDI_SLEEP,
879 879 pl, /* preconstructed payload */
880 880 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
881 881 NULL);
882 882
883 883 nvlist_free(pl);
884 884 if (devidstr_buf)
885 885 ddi_devid_str_free(devidstr_buf);
886 886 kmem_free(pathbuf, MAXPATHLEN);
887 887 }
888 888
889 889 #ifdef DEBUG
890 890 /*
891 891 * Testing - fake scsi_test fails
892 892 */
893 893 char scsi_test_fail_ua[SCSI_MAXNAMELEN]; /* unit address to object to */
894 894 int scsi_test_fail_rc = TRAN_ACCEPT; /* scsi_transport return */
895 895 uchar_t scsi_test_fail_pkt_reason = CMD_CMPLT; /* pkt_reason */
896 896 uchar_t scsi_test_fail_status = STATUS_BUSY; /* status */
897 897 uint_t scsi_test_fail_repeat = (uint_t)-1; /* number of times to fail ua */
898 898 #endif
899 899
900 900 /*
901 901 * This is like scsi_poll, but only does retry for TRAN_BUSY.
902 902 */
903 903 static uint32_t
904 904 scsi_test(struct scsi_pkt *pkt, enum scsi_test_ctxt ctxt)
905 905 {
906 906 uint32_t rval;
907 907 int wait_usec;
908 908 int rc;
909 909 extern int do_polled_io;
910 910
911 911 pkt->pkt_flags |= FLAG_NOINTR;
912 912 pkt->pkt_time = SCSI_POLL_TIMEOUT; /* in seconds */
913 913
914 914 if (scsi_ifgetcap(&pkt->pkt_address, "tagged-qing", 1) == 1) {
915 915 pkt->pkt_flags |= FLAG_STAG;
916 916 }
917 917
918 918 /*
919 919 * Each TRAN_BUSY response waits scsi_test_busy_delay usec up to a
920 920 * maximum of scsi_test_busy_timeout.
921 921 */
922 922 for (wait_usec = 0; (wait_usec / 1000000) <= scsi_test_busy_timeout;
923 923 wait_usec += scsi_test_busy_delay) {
924 924
925 925 /* Initialize pkt status variables */
926 926 *pkt->pkt_scbp = pkt->pkt_reason = pkt->pkt_state = 0;
927 927
928 928 rc = scsi_transport(pkt);
929 929 if ((rc != TRAN_BUSY) || (scsi_test_busy_delay == 0) ||
930 930 (scsi_test_busy_timeout == 0))
931 931 break;
932 932
933 933 /* transport busy, wait */
934 934 if ((curthread->t_flag & T_INTR_THREAD) == 0 && !do_polled_io) {
935 935 delay(drv_usectohz(scsi_test_busy_delay));
936 936 } else {
937 937 /* we busy wait during cpr_dump or interrupt threads */
938 938 drv_usecwait(scsi_test_busy_delay);
939 939 }
940 940 }
941 941
942 942 #ifdef DEBUG
943 943 if (scsi_test_fail_ua[0] != '\0' && scsi_test_fail_repeat > 0) {
944 944 struct scsi_address *ap = &pkt->pkt_address;
945 945 struct scsi_device *sd;
946 946 dev_info_t *probe;
947 947 char ua[SCSI_MAXNAMELEN];
948 948
949 949 if ((sd = scsi_address_device(ap)) != NULL) {
950 950 probe = sd->sd_dev;
951 951
952 952 if (probe && scsi_ua_get(sd, ua, sizeof (ua)) &&
953 953 strncmp(ua, scsi_test_fail_ua, sizeof (ua)) == 0) {
954 954 scsi_test_fail_repeat--;
955 955 rc = scsi_test_fail_rc;
956 956 if (rc == TRAN_ACCEPT)
957 957 pkt->pkt_reason =
958 958 scsi_test_fail_pkt_reason;
959 959 *pkt->pkt_scbp = scsi_test_fail_status;
960 960 if (scsi_test_fail_status == STATUS_CHECK)
961 961 pkt->pkt_state |= STATE_ARQ_DONE;
962 962
963 963 }
964 964 }
965 965 }
966 966 #endif
967 967
968 968 switch (rc) {
969 969 case TRAN_ACCEPT:
970 970 switch (pkt->pkt_reason) {
971 971 case CMD_CMPLT:
972 972 switch ((*pkt->pkt_scbp) & STATUS_MASK) {
973 973 case STATUS_GOOD:
974 974 rval = SCSI_TEST_CMPLT_GOOD;
975 975 break;
976 976
977 977 case STATUS_BUSY:
978 978 rval = SCSI_TEST_CMPLT_BUSY;
979 979 break;
980 980
981 981 case STATUS_CHECK:
982 982 rval = SCSI_TEST_CMPLT_CHECK;
983 983 break;
984 984
985 985 default:
986 986 rval = SCSI_TEST_CMPLT_OTHER;
987 987 break;
988 988 }
989 989 break;
990 990
991 991 case CMD_INCOMPLETE:
992 992 rval = SCSI_TEST_CMD_INCOMPLETE;
993 993 break;
994 994
995 995 default:
996 996 rval = SCSI_TEST_NOTCMPLT;
997 997 break;
998 998 }
999 999 break;
1000 1000
1001 1001 case TRAN_BUSY:
1002 1002 rval = SCSI_TEST_TRAN_BUSY;
1003 1003 break;
1004 1004
1005 1005 default:
1006 1006 rval = SCSI_TEST_TRAN_REJECT;
1007 1007 break;
1008 1008 }
1009 1009
1010 1010 if (rval != SCSI_TEST_CMPLT_GOOD)
1011 1011 scsi_test_ereport_post(pkt, ctxt, rval);
1012 1012
1013 1013 return (rval);
1014 1014 }
1015 1015
1016 1016 /*
1017 1017 * The implementation of scsi_probe now allows a particular
1018 1018 * HBA to intercept the call, for any post- or pre-processing
1019 1019 * it may need. The default, if the HBA does not override it,
1020 1020 * is to call scsi_hba_probe(), which retains the old functionality
1021 1021 * intact.
1022 1022 */
1023 1023 int
1024 1024 scsi_probe(struct scsi_device *sd, int (*callback)())
1025 1025 {
1026 1026 int ret, retry = 0;
1027 1027 int lr_cap, sr_ret;
1028 1028 scsi_hba_tran_t *tran = sd->sd_address.a_hba_tran;
1029 1029
1030 1030 if (scsi_check_ss2_LUN_limit(sd) != 0) {
1031 1031 /*
1032 1032 * caller is trying to probe a strictly-SCSI-2 device
1033 1033 * with a LUN that is too large, so do not allow it
1034 1034 */
1035 1035 return (SCSIPROBE_NORESP); /* skip probing this one */
1036 1036 }
1037 1037 again:
1038 1038 ret = lr_cap = sr_ret = -1;
1039 1039 if (tran->tran_tgt_probe != NULL) {
1040 1040 ret = (*tran->tran_tgt_probe)(sd, callback);
1041 1041 } else {
1042 1042 ret = scsi_hba_probe(sd, callback);
1043 1043 }
1044 1044
1045 1045 if ((ret != SCSIPROBE_EXISTS) && (retry == 0)) {
1046 1046 lr_cap = (*tran->tran_getcap)(&sd->sd_address, "lun-reset", 1);
1047 1047 sr_ret = scsi_reset(&sd->sd_address, RESET_LUN);
1048 1048 if ((sr_ret != 1) && (lr_cap == 1)) {
1049 1049 cmn_err(CE_WARN, "scsi_probe(%d): scsi_reset failed(%d)"
1050 1050 " lun-reset cap(%d)", ret, sr_ret, lr_cap);
1051 1051 }
1052 1052 retry = 1;
1053 1053 goto again;
1054 1054 }
1055 1055
1056 1056 if (ret == SCSIPROBE_EXISTS) {
1057 1057 create_inquiry_props(sd);
1058 1058 /* is this a strictly-SCSI-2 node ?? */
1059 1059 scsi_establish_LUN_limit(sd);
1060 1060 }
1061 1061
1062 1062 return (ret);
1063 1063 }
1064 1064 /*
1065 1065 * probe scsi device using any available path
1066 1066 *
1067 1067 */
1068 1068 int
1069 1069 scsi_hba_probe(struct scsi_device *sd, int (*callback)())
1070 1070 {
1071 1071 return (scsi_hba_probe_pi(sd, callback, 0));
1072 1072 }
1073 1073
1074 1074 /*
1075 1075 * probe scsi device using specific path
1076 1076 *
1077 1077 * scsi_hba_probe_pi does not do any test unit ready's which access the medium
1078 1078 * and could cause busy or not ready conditions.
1079 1079 * scsi_hba_probe_pi does 2 inquiries and a rqsense to clear unit attention
1080 1080 * and to allow sync negotiation to take place
1081 1081 * finally, scsi_hba_probe_pi does one more inquiry which should
1082 1082 * reliably tell us what kind of target we have.
1083 1083 * A scsi-2 compliant target should be able to return inquiry with 250ms
1084 1084 * and we actually wait more than a second after reset.
1085 1085 */
1086 1086 int
1087 1087 scsi_hba_probe_pi(struct scsi_device *sd, int (*callback)(), int pi)
1088 1088 {
1089 1089 struct scsi_pkt *inq_pkt = NULL;
1090 1090 struct scsi_pkt *rq_pkt = NULL;
1091 1091 int rval = SCSIPROBE_NOMEM;
1092 1092 struct buf *inq_bp = NULL;
1093 1093 struct buf *rq_bp = NULL;
1094 1094 int (*cb_flag)();
1095 1095 int pass = 1;
1096 1096 uint32_t str;
1097 1097
1098 1098 if (sd->sd_inq == NULL) {
1099 1099 sd->sd_inq = (struct scsi_inquiry *)
1100 1100 kmem_alloc(SUN_INQSIZE, ((callback == SLEEP_FUNC) ?
1101 1101 KM_SLEEP : KM_NOSLEEP));
1102 1102 if (sd->sd_inq == NULL) {
1103 1103 goto out;
1104 1104 }
1105 1105 }
1106 1106
1107 1107 if (callback != SLEEP_FUNC && callback != NULL_FUNC) {
1108 1108 cb_flag = NULL_FUNC;
1109 1109 } else {
1110 1110 cb_flag = callback;
1111 1111 }
1112 1112 inq_bp = scsi_alloc_consistent_buf(ROUTE,
1113 1113 (struct buf *)NULL, SUN_INQSIZE, B_READ, cb_flag, NULL);
1114 1114 if (inq_bp == NULL) {
1115 1115 goto out;
1116 1116 }
1117 1117
1118 1118 inq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
1119 1119 inq_bp, CDB_GROUP0, sizeof (struct scsi_arq_status),
1120 1120 0, PKT_CONSISTENT, callback, NULL);
1121 1121 if (inq_pkt == NULL) {
1122 1122 if (inq_bp->b_error == 0)
1123 1123 rval = SCSIPROBE_NOMEM_CB;
1124 1124 goto out;
1125 1125 }
1126 1126 ASSERT(inq_bp->b_error == 0);
1127 1127
1128 1128 (void) scsi_setup_cdb((union scsi_cdb *)inq_pkt->pkt_cdbp,
1129 1129 SCMD_INQUIRY, 0, SUN_INQSIZE, 0);
1130 1130 inq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
1131 1131
1132 1132 /*
1133 1133 * set transport path
1134 1134 */
1135 1135 if (pi && scsi_pkt_allocated_correctly(inq_pkt)) {
1136 1136 inq_pkt->pkt_path_instance = pi;
1137 1137 inq_pkt->pkt_flags |= FLAG_PKT_PATH_INSTANCE;
1138 1138 }
1139 1139
1140 1140 /*
1141 1141 * the first inquiry will tell us whether a target
1142 1142 * responded
1143 1143 *
1144 1144 * The FILL_SCSI1_LUN below will find "ansi_ver != 1" on first pass
1145 1145 * because of bzero initilization. If this assumption turns out to be
1146 1146 * incorrect after we have real sd_inq data (for lun0) we will do a
1147 1147 * second pass during which FILL_SCSI1_LUN will place lun in CDB.
1148 1148 */
1149 1149 bzero((caddr_t)sd->sd_inq, SUN_INQSIZE);
1150 1150 again: FILL_SCSI1_LUN(sd, inq_pkt);
1151 1151
1152 1152 str = scsi_test(inq_pkt, STC_PROBE_FIRST_INQ);
1153 1153 if (SCSI_TEST_FAILURE(str)) {
1154 1154 if (str == SCSI_TEST_CMD_INCOMPLETE) {
1155 1155 rval = SCSIPROBE_NORESP;
1156 1156 goto out;
1157 1157 }
1158 1158
1159 1159 /*
1160 1160 * Retry one more time for anything other than CMD_INCOMPLETE.
1161 1161 */
1162 1162 str = scsi_test(inq_pkt, STC_PROBE_FIRST_INQ_RETRY);
1163 1163 if (SCSI_TEST_FAILURE(str)) {
1164 1164 rval = SCSIPROBE_FAILURE;
1165 1165 goto out;
1166 1166 }
1167 1167 }
1168 1168
1169 1169 /*
1170 1170 * Did the inquiry complete and transfer inquiry information,
1171 1171 * perhaps after retry?
1172 1172 */
1173 1173 if (str == SCSI_TEST_CMPLT_GOOD)
1174 1174 goto done;
1175 1175
1176 1176 /*
1177 1177 * We get here for SCSI_TEST_CMPLT_{BUSY,CHECK,OTHER}. We term
1178 1178 * this "partial success" in that at least something is talking
1179 1179 * to us.
1180 1180 *
1181 1181 * A second inquiry allows the host adapter to negotiate
1182 1182 * synchronous transfer period and offset
1183 1183 */
1184 1184 str = scsi_test(inq_pkt, STC_PROBE_PARTIAL_SUCCESS);
1185 1185 if (SCSI_TEST_FAILURE(str)) {
1186 1186 if (str == SCSI_TEST_CMD_INCOMPLETE)
1187 1187 rval = SCSIPROBE_NORESP;
1188 1188 else
1189 1189 rval = SCSIPROBE_FAILURE;
1190 1190 goto out;
1191 1191 }
1192 1192
1193 1193 /*
1194 1194 * If target is still busy, give up now.
1195 1195 * XXX There's no interval between retries - scsi_test should
1196 1196 * probably have a builtin retry on target busy.
1197 1197 */
1198 1198 if (str == SCSI_TEST_CMPLT_BUSY) {
1199 1199 rval = SCSIPROBE_BUSY;
1200 1200 goto out;
1201 1201 }
1202 1202
1203 1203 /*
1204 1204 * At this point we are SCSI_TEST_CMPLT_GOOD, SCSI_TEST_CMPLT_CHECK
1205 1205 * or SCSI_TEST_CMPLT_OTHER.
1206 1206 *
1207 1207 * Do a rqsense if there was a check condition and ARQ was not done
1208 1208 */
1209 1209 if (str == SCSI_TEST_CMPLT_CHECK &&
1210 1210 (inq_pkt->pkt_state & STATE_ARQ_DONE) == 0) {
1211 1211 /*
1212 1212 * prepare rqsense packet
1213 1213 * there is no real need for this because the
1214 1214 * check condition should have been cleared by now.
1215 1215 */
1216 1216 rq_bp = scsi_alloc_consistent_buf(ROUTE, (struct buf *)NULL,
1217 1217 (uint_t)SENSE_LENGTH, B_READ, cb_flag, NULL);
1218 1218 if (rq_bp == NULL) {
1219 1219 goto out;
1220 1220 }
1221 1221
1222 1222 rq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
1223 1223 rq_bp, CDB_GROUP0, 1, 0, PKT_CONSISTENT, callback, NULL);
1224 1224
1225 1225 if (rq_pkt == NULL) {
1226 1226 if (rq_bp->b_error == 0)
1227 1227 rval = SCSIPROBE_NOMEM_CB;
1228 1228 goto out;
1229 1229 }
1230 1230 ASSERT(rq_bp->b_error == 0);
1231 1231
1232 1232 (void) scsi_setup_cdb((union scsi_cdb *)rq_pkt->
1233 1233 pkt_cdbp, SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0);
1234 1234 FILL_SCSI1_LUN(sd, rq_pkt);
1235 1235 rq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
1236 1236
1237 1237 /*
1238 1238 * set transport path
1239 1239 */
1240 1240 if (pi && scsi_pkt_allocated_correctly(rq_pkt)) {
1241 1241 rq_pkt->pkt_path_instance = pi;
1242 1242 rq_pkt->pkt_flags |= FLAG_PKT_PATH_INSTANCE;
1243 1243 }
1244 1244
1245 1245 /*
1246 1246 * The FILL_SCSI1_LUN above will find "inq_ansi != 1"
1247 1247 * on first pass, see "again" comment above.
1248 1248 *
1249 1249 * The controller type is as yet unknown, so we
1250 1250 * have to do a throwaway non-extended request sense,
1251 1251 * and hope that that clears the check condition for
1252 1252 * that unit until we can find out what kind of drive
1253 1253 * it is. A non-extended request sense is specified
1254 1254 * by stating that the sense block has 0 length,
1255 1255 * which is taken to mean that it is four bytes in
1256 1256 * length.
1257 1257 */
1258 1258 if (SCSI_TEST_FAILURE(scsi_test(rq_pkt, STC_PROBE_RQSENSE1))) {
1259 1259 rval = SCSIPROBE_FAILURE;
1260 1260 goto out;
1261 1261 }
1262 1262 }
1263 1263
1264 1264 /*
1265 1265 * At this point, we are guaranteed that something responded
1266 1266 * to this scsi bus target id. We don't know yet what
1267 1267 * kind of device it is, or even whether there really is
1268 1268 * a logical unit attached (as some SCSI target controllers
1269 1269 * lie about a unit being ready, e.g., the Emulex MD21).
1270 1270 */
1271 1271
1272 1272 str = scsi_test(inq_pkt, STC_PROBE_CHK_CLEARED);
1273 1273 if (SCSI_TEST_FAILURE(str)) {
1274 1274 rval = SCSIPROBE_FAILURE;
1275 1275 goto out;
1276 1276 }
1277 1277
1278 1278 if (str == SCSI_TEST_CMPLT_BUSY) {
1279 1279 rval = SCSIPROBE_BUSY;
1280 1280 goto out;
1281 1281 }
1282 1282
1283 1283 /*
1284 1284 * Okay we sent the INQUIRY command.
1285 1285 *
1286 1286 * If enough data was transferred, we count that the
1287 1287 * Inquiry command succeeded, else we have to assume
1288 1288 * that this is a non-CCS scsi target (or a nonexistent
1289 1289 * target/lun).
1290 1290 */
1291 1291
1292 1292 if (str == SCSI_TEST_CMPLT_CHECK) {
1293 1293 /*
1294 1294 * try a request sense if we have a pkt, otherwise
1295 1295 * just retry the inquiry one more time
1296 1296 */
1297 1297 if (rq_pkt)
1298 1298 (void) scsi_test(rq_pkt, STC_PROBE_RQSENSE2);
1299 1299
1300 1300 /*
1301 1301 * retry inquiry
1302 1302 */
1303 1303 str = scsi_test(inq_pkt, STC_PROBE_INQ_FINAL);
1304 1304 if (SCSI_TEST_FAILURE(str)) {
1305 1305 rval = SCSIPROBE_FAILURE;
1306 1306 goto out;
1307 1307 } else if (str == SCSI_TEST_CMPLT_CHECK) {
1308 1308 rval = SCSIPROBE_FAILURE;
1309 1309 goto out;
1310 1310 }
1311 1311 }
1312 1312
1313 1313 done:
1314 1314 /*
1315 1315 * If we got a parity error on receive of inquiry data,
1316 1316 * we're just plain out of luck because we told the host
1317 1317 * adapter to not watch for parity errors.
1318 1318 */
1319 1319 if ((inq_pkt->pkt_state & STATE_XFERRED_DATA) == 0 ||
1320 1320 ((SUN_INQSIZE - inq_pkt->pkt_resid) < SUN_MIN_INQLEN)) {
1321 1321 rval = SCSIPROBE_NONCCS;
1322 1322 } else {
1323 1323 ASSERT(inq_pkt->pkt_resid >= 0);
1324 1324 bcopy((caddr_t)inq_bp->b_un.b_addr,
1325 1325 (caddr_t)sd->sd_inq, (SUN_INQSIZE - inq_pkt->pkt_resid));
1326 1326 rval = SCSIPROBE_EXISTS;
1327 1327 }
1328 1328
1329 1329 out:
1330 1330 /*
1331 1331 * If lun > 0 we need to figure out if this is a scsi-1 device where
1332 1332 * the "real" lun needs to be embedded into the cdb.
1333 1333 */
1334 1334 if ((rval == SCSIPROBE_EXISTS) && (pass == 1) &&
1335 1335 (sd->sd_address.a_lun > 0) && (sd->sd_inq->inq_ansi == 0x1)) {
1336 1336 pass++;
1337 1337 if (sd->sd_address.a_lun <= 7)
1338 1338 goto again;
1339 1339
1340 1340 /*
1341 1341 * invalid lun for scsi-1,
1342 1342 * return probe failure.
1343 1343 */
1344 1344 rval = SCSIPROBE_FAILURE;
1345 1345 }
1346 1346
1347 1347 if (rq_pkt) {
1348 1348 scsi_destroy_pkt(rq_pkt);
1349 1349 }
1350 1350 if (inq_pkt) {
1351 1351 scsi_destroy_pkt(inq_pkt);
1352 1352 }
1353 1353 if (rq_bp) {
1354 1354 scsi_free_consistent_buf(rq_bp);
1355 1355 }
1356 1356 if (inq_bp) {
1357 1357 scsi_free_consistent_buf(inq_bp);
1358 1358 }
1359 1359 return (rval);
1360 1360 }
1361 1361
1362 1362 /*
1363 1363 * Convert from a scsi_device structure pointer to a scsi_hba_tran structure
1364 1364 * pointer. The correct way to do this is
1365 1365 *
1366 1366 * #define DEVP_TO_TRAN(sd) ((sd)->sd_address.a_hba_tran)
1367 1367 *
1368 1368 * however we have some consumers that place their own vector in a_hba_tran. To
1369 1369 * avoid problems, we implement this using the sd_tran_safe. See
1370 1370 * scsi_hba_initchild for more details.
1371 1371 */
1372 1372 #define DEVP_TO_TRAN(sd) ((sd)->sd_tran_safe)
1373 1373
1374 1374 /*
1375 1375 * Function, callable from SCSA framework, to get 'human' readable REPORTDEV
1376 1376 * addressing information from scsi_device properties.
1377 1377 */
1378 1378 int
1379 1379 scsi_ua_get_reportdev(struct scsi_device *sd, char *ra, int len)
1380 1380 {
1381 1381 /* use deprecated tran_get_bus_addr interface if it is defined */
1382 1382 /* NOTE: tran_get_bus_addr is a poor name choice for interface */
1383 1383 if (DEVP_TO_TRAN(sd)->tran_get_bus_addr)
1384 1384 return ((*DEVP_TO_TRAN(sd)->tran_get_bus_addr)(sd, ra, len));
1385 1385 return (scsi_hba_ua_get_reportdev(sd, ra, len));
1386 1386 }
1387 1387
1388 1388 /*
1389 1389 * Function, callable from HBA driver's tran_get_bus_addr(9E) implementation,
1390 1390 * to get standard form of human readable REPORTDEV addressing information
1391 1391 * from scsi_device properties.
1392 1392 */
1393 1393 int
1394 1394 scsi_hba_ua_get_reportdev(struct scsi_device *sd, char *ra, int len)
1395 1395 {
1396 1396 int tgt, lun, sfunc;
1397 1397 char *tgt_port;
1398 1398 scsi_lun64_t lun64;
1399 1399
1400 1400 /* get device unit-address properties */
1401 1401 tgt = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
1402 1402 SCSI_ADDR_PROP_TARGET, -1);
1403 1403 if (scsi_device_prop_lookup_string(sd, SCSI_DEVICE_PROP_PATH,
1404 1404 SCSI_ADDR_PROP_TARGET_PORT, &tgt_port) != DDI_PROP_SUCCESS)
1405 1405 tgt_port = NULL;
1406 1406 if ((tgt == -1) && (tgt_port == NULL))
1407 1407 return (0); /* no target */
1408 1408
1409 1409 lun = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
1410 1410 SCSI_ADDR_PROP_LUN, 0);
1411 1411 lun64 = scsi_device_prop_get_int64(sd, SCSI_DEVICE_PROP_PATH,
1412 1412 SCSI_ADDR_PROP_LUN64, lun);
1413 1413 sfunc = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
1414 1414 SCSI_ADDR_PROP_SFUNC, -1);
1415 1415
1416 1416 /*
1417 1417 * XXX should the default be to print this in decimal for
1418 1418 * "human readable" form, so it matches conf files?
1419 1419 */
1420 1420 if (tgt_port) {
1421 1421 if (sfunc == -1)
1422 1422 (void) snprintf(ra, len,
1423 1423 "%s %s lun %" PRIx64,
1424 1424 SCSI_ADDR_PROP_TARGET_PORT, tgt_port, lun64);
1425 1425 else
1426 1426 (void) snprintf(ra, len,
1427 1427 "%s %s lun %" PRIx64 " sfunc %x",
1428 1428 SCSI_ADDR_PROP_TARGET_PORT, tgt_port, lun64, sfunc);
1429 1429 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, tgt_port);
1430 1430 } else {
1431 1431 if (sfunc == -1)
1432 1432 (void) snprintf(ra, len,
1433 1433 "%s %x lun %" PRIx64,
1434 1434 SCSI_ADDR_PROP_TARGET, tgt, lun64);
1435 1435 else
1436 1436 (void) snprintf(ra, len,
1437 1437 "%s %x lun %" PRIx64 " sfunc %x",
1438 1438 SCSI_ADDR_PROP_TARGET, tgt, lun64, sfunc);
1439 1439 }
1440 1440
1441 1441 return (1);
1442 1442 }
1443 1443
1444 1444 /*
1445 1445 * scsi_ua_get: using properties, return "unit-address" string.
1446 1446 * Called by SCSA framework, may call HBAs tran function.
1447 1447 */
1448 1448 int
1449 1449 scsi_ua_get(struct scsi_device *sd, char *ua, int len)
1450 1450 {
1451 1451 char *eua;
1452 1452
1453 1453 /* See if we already have established the unit-address. */
1454 1454 if ((eua = scsi_device_unit_address(sd)) != NULL) {
1455 1455 (void) strlcpy(ua, eua, len);
1456 1456 return (1);
1457 1457 }
1458 1458
1459 1459 /* Use deprecated tran_get_name interface if it is defined. */
1460 1460 /* NOTE: tran_get_name is a poor name choice for interface */
1461 1461 if (DEVP_TO_TRAN(sd)->tran_get_name)
1462 1462 return ((*DEVP_TO_TRAN(sd)->tran_get_name)(sd, ua, len));
1463 1463
1464 1464 /* Use generic property implementation */
1465 1465 return (scsi_hba_ua_get(sd, ua, len));
1466 1466 }
1467 1467
1468 1468 /*
1469 1469 * scsi_hba_ua_get: using properties, return "unit-address" string.
1470 1470 * This function may be called from an HBAs tran function.
1471 1471 *
1472 1472 * Function to get "unit-address" in "name@unit-address" /devices path
1473 1473 * component form from the scsi_device unit-address properties on a node.
1474 1474 *
1475 1475 * NOTE: This function works in conjunction with scsi_hba_ua_set().
1476 1476 */
1477 1477 int
1478 1478 scsi_hba_ua_get(struct scsi_device *sd, char *ua, int len)
1479 1479 {
1480 1480 int tgt, lun, sfunc;
1481 1481 char *tgt_port;
1482 1482 scsi_lun64_t lun64;
1483 1483
1484 1484 /* get device unit-address properties */
1485 1485 tgt = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
1486 1486 SCSI_ADDR_PROP_TARGET, -1);
1487 1487 if (scsi_device_prop_lookup_string(sd, SCSI_DEVICE_PROP_PATH,
1488 1488 SCSI_ADDR_PROP_TARGET_PORT, &tgt_port) != DDI_PROP_SUCCESS)
1489 1489 tgt_port = NULL;
1490 1490 if ((tgt == -1) && (tgt_port == NULL))
1491 1491 return (0); /* no target */
1492 1492
1493 1493 lun = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
1494 1494 SCSI_ADDR_PROP_LUN, 0);
1495 1495 lun64 = scsi_device_prop_get_int64(sd, SCSI_DEVICE_PROP_PATH,
1496 1496 SCSI_ADDR_PROP_LUN64, lun);
1497 1497 sfunc = scsi_device_prop_get_int(sd, SCSI_DEVICE_PROP_PATH,
1498 1498 SCSI_ADDR_PROP_SFUNC, -1);
1499 1499 if (tgt_port) {
1500 1500 if (sfunc == -1)
1501 1501 (void) snprintf(ua, len, "%s,%" PRIx64,
1502 1502 tgt_port, lun64);
1503 1503 else
1504 1504 (void) snprintf(ua, len, "%s,%" PRIx64 ",%x",
1505 1505 tgt_port, lun64, sfunc);
1506 1506 scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, tgt_port);
1507 1507 } else {
1508 1508 if (sfunc == -1)
1509 1509 (void) snprintf(ua, len, "%x,%" PRIx64, tgt, lun64);
1510 1510 else
1511 1511 (void) snprintf(ua, len, "%x,%" PRIx64 ",%x",
1512 1512 tgt, lun64, sfunc);
1513 1513 }
1514 1514 return (1);
1515 1515 }
1516 1516
1517 1517 static void
1518 1518 create_inquiry_props(struct scsi_device *sd)
1519 1519 {
1520 1520 struct scsi_inquiry *inq = sd->sd_inq;
1521 1521
1522 1522 (void) ndi_prop_update_int(DDI_DEV_T_NONE, sd->sd_dev,
1523 1523 INQUIRY_DEVICE_TYPE, (int)inq->inq_dtype);
1524 1524
1525 1525 /*
1526 1526 * Create the following properties:
1527 1527 *
1528 1528 * inquiry-vendor-id Vendor id (INQUIRY data bytes 8-15)
1529 1529 * inquiry-product-id Product id (INQUIRY data bytes 16-31)
1530 1530 * inquiry-revision-id Product Rev level (INQUIRY data bytes 32-35)
1531 1531 *
1532 1532 * NOTE: We don't support creation of these properties for scsi-1
1533 1533 * devices (as the vid, pid and revision were not defined) and we
1534 1534 * don't create the property if they are of zero length when
1535 1535 * stripped of Nulls and spaces.
1536 1536 *
1537 1537 * NOTE: The first definition of these properties sticks. This gives
1538 1538 * a transport the ability to provide a higher-quality definition
1539 1539 * than the standard SCSI INQUIRY data.
1540 1540 */
1541 1541 if (inq->inq_ansi != 1) {
1542 1542 if (ddi_prop_exists(DDI_DEV_T_NONE, sd->sd_dev,
1543 1543 DDI_PROP_TYPE_STRING, INQUIRY_VENDOR_ID) == 0)
1544 1544 (void) scsi_device_prop_update_inqstring(sd,
1545 1545 INQUIRY_VENDOR_ID,
1546 1546 inq->inq_vid, sizeof (inq->inq_vid));
1547 1547
1548 1548 if (ddi_prop_exists(DDI_DEV_T_NONE, sd->sd_dev,
1549 1549 DDI_PROP_TYPE_STRING, INQUIRY_PRODUCT_ID) == 0)
1550 1550 (void) scsi_device_prop_update_inqstring(sd,
1551 1551 INQUIRY_PRODUCT_ID,
1552 1552 inq->inq_pid, sizeof (inq->inq_pid));
1553 1553
1554 1554 if (ddi_prop_exists(DDI_DEV_T_NONE, sd->sd_dev,
1555 1555 DDI_PROP_TYPE_STRING, INQUIRY_REVISION_ID) == 0)
1556 1556 (void) scsi_device_prop_update_inqstring(sd,
1557 1557 INQUIRY_REVISION_ID,
1558 1558 inq->inq_revision, sizeof (inq->inq_revision));
1559 1559 }
1560 1560 }
1561 1561
1562 1562 /*
1563 1563 * Create 'inquiry' string properties. An 'inquiry' string gets special
1564 1564 * treatment to trim trailing blanks (etc) and ensure null termination.
1565 1565 */
1566 1566 int
1567 1567 scsi_device_prop_update_inqstring(struct scsi_device *sd,
1568 1568 char *name, char *data, size_t len)
1569 1569 {
1570 1570 int ilen;
1571 1571 char *data_string;
1572 1572 int rv;
1573 1573
1574 1574 ilen = scsi_ascii_inquiry_len(data, len);
1575 1575 ASSERT(ilen <= (int)len);
1576 1576 if (ilen <= 0)
1577 1577 return (DDI_PROP_INVAL_ARG);
1578 1578
1579 1579 /* ensure null termination */
1580 1580 data_string = kmem_zalloc(ilen + 1, KM_SLEEP);
1581 1581 bcopy(data, data_string, ilen);
1582 1582 rv = ndi_prop_update_string(DDI_DEV_T_NONE,
1583 1583 sd->sd_dev, name, data_string);
1584 1584 kmem_free(data_string, ilen + 1);
1585 1585 return (rv);
1586 1586 }
1587 1587
1588 1588 /*
1589 1589 * Interfaces associated with SCSI_HBA_ADDR_COMPLEX
1590 1590 * per-scsi_device HBA private data support.
1591 1591 *
1592 1592 * scsi_address_device returns NULL if we're not SCSI_HBA_ADDR_COMPLEX,
1593 1593 * thereby allowing use of scsi_address_device as a test for
1594 1594 * SCSI_HBA_ADDR_COMPLEX.
1595 1595 */
1596 1596 struct scsi_device *
1597 1597 scsi_address_device(struct scsi_address *sa)
1598 1598 {
1599 1599 return ((sa->a_hba_tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX) ?
1600 1600 sa->a.a_sd : NULL);
1601 1601 }
1602 1602
1603 1603 void
1604 1604 scsi_device_hba_private_set(struct scsi_device *sd, void *data)
1605 1605 {
1606 1606 ASSERT(sd->sd_address.a_hba_tran->tran_hba_flags &
1607 1607 SCSI_HBA_ADDR_COMPLEX);
1608 1608 sd->sd_hba_private = data;
1609 1609 }
1610 1610
1611 1611 void *
1612 1612 scsi_device_hba_private_get(struct scsi_device *sd)
1613 1613 {
1614 1614 ASSERT(sd->sd_address.a_hba_tran->tran_hba_flags &
1615 1615 SCSI_HBA_ADDR_COMPLEX);
1616 1616 return (sd->sd_hba_private);
1617 1617 }
1618 1618
1619 1619 /*
1620 1620 * This routine is called from the start of scsi_probe() if a tgt/LUN to be
1621 1621 * probed *may* be a request to probe a strictly SCSI-2 target (with respect
1622 1622 * to LUNs) -- and this probe may be for a LUN number greater than 7,
1623 1623 * which can cause a hardware hang
1624 1624 *
1625 1625 * return 0 if the probe can proceed,
1626 1626 * else return 1, meaning do *NOT* probe this target/LUN
1627 1627 */
1628 1628 static int
1629 1629 scsi_check_ss2_LUN_limit(struct scsi_device *sd)
1630 1630 {
1631 1631 struct scsi_address *ap = &(sd->sd_address);
1632 1632 dev_info_t *pdevi =
1633 1633 (dev_info_t *)DEVI(sd->sd_dev)->devi_parent;
1634 1634 int ret_val = 0; /* default return value */
1635 1635 uchar_t *tgt_list;
1636 1636 uint_t tgt_nelements;
1637 1637 int i;
1638 1638
1639 1639
1640 1640 /*
1641 1641 * check for what *might* be a problem probe, only we don't
1642 1642 * know yet what's really at the destination target/LUN
1643 1643 */
1644 1644 if ((ap->a_target >= NTARGETS_WIDE) ||
1645 1645 (ap->a_lun < NLUNS_PER_TARGET)) {
1646 1646 return (0); /* okay to probe this target */
1647 1647 }
1648 1648
1649 1649 /*
1650 1650 * this *might* be a problematic probe, so look to see
1651 1651 * if the inquiry data matches
1652 1652 */
1653 1653 SCSI_PROBE_DEBUG2(1, "SCSA pre-probe: checking tgt.LUN=%d.%d\n",
1654 1654 ap->a_target, ap->a_lun);
1655 1655 SCSI_PROBE_DEBUG1(2,
1656 1656 "SCSA pre-probe: scanning parent node name: %s ...\n",
1657 1657 ddi_node_name(pdevi));
1658 1658
1659 1659 /*
1660 1660 * look for a special property of our parent node that lists
1661 1661 * the targets under it for which we do *NOT* want to probe
1662 1662 * if LUN>7 -- if the property is found, look to see if our
1663 1663 * target ID is on that list
1664 1664 */
1665 1665 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, pdevi,
1666 1666 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, SS2_LUN0_TGT_LIST_PROP,
1667 1667 &tgt_list, &tgt_nelements) != DDI_PROP_SUCCESS) {
1668 1668 /*
1669 1669 * no list, so it must be okay to probe this target.LUN
1670 1670 */
1671 1671 SCSI_PROBE_DEBUG0(3,
1672 1672 "SCSA pre-probe: NO parent prop found\n");
1673 1673 } else {
1674 1674 for (i = 0; i < tgt_nelements; i++) {
1675 1675 if (tgt_list[i] == ap->a_target) {
1676 1676 /*
1677 1677 * we found a match, which means we do *NOT*
1678 1678 * want to probe the specified target.LUN
1679 1679 */
1680 1680 ret_val = 1;
1681 1681 break;
1682 1682 }
1683 1683 }
1684 1684 ddi_prop_free(tgt_list);
1685 1685 #ifdef DEBUG
1686 1686 if (ret_val == 1) {
1687 1687 SCSI_PROBE_DEBUG2(1,
1688 1688 "SCSA pre-probe: marker node FOUND for "
1689 1689 "tgt.LUN=%d.%d, so SKIPPING it\n",
1690 1690 ap->a_target, ap->a_lun);
1691 1691 } else {
1692 1692 SCSI_PROBE_DEBUG0(2,
1693 1693 "SCSA pre-probe: NO marker node found"
1694 1694 " -- OK to probe\n");
1695 1695 }
1696 1696 #endif
1697 1697 }
1698 1698 return (ret_val);
1699 1699 }
1700 1700
1701 1701
1702 1702 /*
1703 1703 * this routine is called from near the end of scsi_probe(),
1704 1704 * to see if the just-probed node is on our list of strictly-SCSI-2 nodes,
1705 1705 * and if it is we mark our parent node with this information
1706 1706 */
1707 1707 static void
1708 1708 scsi_establish_LUN_limit(struct scsi_device *sd)
1709 1709 {
1710 1710 struct scsi_address *ap = &(sd->sd_address);
1711 1711 struct scsi_inquiry *inq = sd->sd_inq;
1712 1712 dev_info_t *devi = sd->sd_dev;
1713 1713 char *vid = NULL;
1714 1714 char *pid = NULL;
1715 1715 char *rev = NULL;
1716 1716 int i;
1717 1717 const ss2_lun0_info_t *p;
1718 1718 int bad_target_found = 0;
1719 1719
1720 1720
1721 1721 /*
1722 1722 * if this inquiry data shows that we have a strictly-SCSI-2 device
1723 1723 * at LUN 0, then add it to our list of strictly-SCSI-2 devices,
1724 1724 * so that we can avoid probes where LUN>7 on this device later
1725 1725 */
1726 1726 if ((ap->a_lun != 0) ||
1727 1727 (ap->a_target >= NTARGETS_WIDE) ||
1728 1728 (inq->inq_dtype != DTYPE_PROCESSOR) ||
1729 1729 (inq->inq_ansi != 2)) {
1730 1730 /*
1731 1731 * this can't possibly be a node we want to look at, since
1732 1732 * either LUN is greater than 0, target is greater than or
1733 1733 * equal to 16, device type
1734 1734 * is not processor, or SCSI level is not SCSI-2,
1735 1735 * so don't bother checking for a strictly SCSI-2
1736 1736 * (only 8 LUN) target
1737 1737 */
1738 1738 return; /* don't care */
1739 1739 }
1740 1740
1741 1741 SCSI_PROBE_DEBUG2(1, "SCSA post-probe: LUN limit on tgt.LUN=%d.%d, "
1742 1742 "SCSI-2 PROCESSOR?\n", ap->a_target, ap->a_lun);
1743 1743
1744 1744 ASSERT(devi != NULL);
1745 1745
1746 1746 /*
1747 1747 * we have a node that has been probed that is: LUN=0, target<16,
1748 1748 * PROCESSOR-type SCSI target, and at the SCSI-2 level, so
1749 1749 * check INQ properties to see if it's in our list of strictly
1750 1750 * SCSI-2 targets
1751 1751 *
1752 1752 * first we have to get the VID/PID/REV INQUIRY properties for
1753 1753 * comparison
1754 1754 */
1755 1755 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi,
1756 1756 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1757 1757 INQUIRY_VENDOR_ID, &vid) != DDI_PROP_SUCCESS) {
1758 1758 SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n",
1759 1759 INQUIRY_VENDOR_ID);
1760 1760 goto dun;
1761 1761 }
1762 1762 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi,
1763 1763 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1764 1764 INQUIRY_PRODUCT_ID, &pid) != DDI_PROP_SUCCESS) {
1765 1765 SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n",
1766 1766 INQUIRY_PRODUCT_ID);
1767 1767 goto dun;
1768 1768 }
1769 1769 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi,
1770 1770 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1771 1771 INQUIRY_REVISION_ID, &rev) != DDI_PROP_SUCCESS) {
1772 1772 SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n",
1773 1773 INQUIRY_REVISION_ID);
1774 1774 goto dun;
1775 1775 }
1776 1776
1777 1777 SCSI_PROBE_DEBUG3(3, "SCSA post-probe: looking for vid/pid/rev = "
1778 1778 "\"%s\"/\"%s\"/\"%s\"\n", vid, pid, rev);
1779 1779
1780 1780 /*
1781 1781 * now that we have the INQUIRY properties from the device node,
1782 1782 * compare them with our known offenders
1783 1783 *
1784 1784 * Note: comparison is *CASE* *SENSITIVE*
1785 1785 */
1786 1786 for (i = 0; i < scsi_probe_strict_s2_size; i++) {
1787 1787 p = &scsi_probe_strict_s2_list[i];
1788 1788
1789 1789 if ((strcmp(p->sli_vid, vid) == 0) &&
1790 1790 (strcmp(p->sli_pid, pid) == 0) &&
1791 1791 (strcmp(p->sli_rev, rev) == 0)) {
1792 1792 /*
1793 1793 * we found a match -- do NOT want to probe this one
1794 1794 */
1795 1795 SCSI_PROBE_DEBUG3(1,
1796 1796 "SCSA post-probe: recording strict SCSI-2 node "
1797 1797 "vid/pid/rev = \"%s\"/\"%s\"/\"%s\"\n",
1798 1798 vid, pid, rev);
1799 1799
1800 1800 /*
1801 1801 * set/update private parent-node property,
1802 1802 * so we can find out about this node later
1803 1803 */
1804 1804 bad_target_found = 1;
1805 1805 break;
1806 1806 }
1807 1807 }
1808 1808
1809 1809 /*
1810 1810 * either add remove target number from parent property
1811 1811 */
1812 1812 scsi_update_parent_ss2_prop(devi, ap->a_target, bad_target_found);
1813 1813
1814 1814 dun:
1815 1815 if (vid != NULL) {
1816 1816 ddi_prop_free(vid);
1817 1817 }
1818 1818 if (pid != NULL) {
1819 1819 ddi_prop_free(pid);
1820 1820 }
1821 1821 if (rev != NULL) {
1822 1822 ddi_prop_free(rev);
1823 1823 }
1824 1824 }
1825 1825
1826 1826
1827 1827 /*
1828 1828 * update the parent node to add in the supplied tgt number to the target
1829 1829 * list property already present (if any)
1830 1830 *
1831 1831 * since the target list can never be longer than 16, and each target
1832 1832 * number is also small, we can save having to alloc memory by putting
1833 1833 * a 16-byte array on the stack and using it for property memory
1834 1834 *
1835 1835 * if "add_tgt" is set then add the target to the parent's property, else
1836 1836 * remove it (if present)
1837 1837 */
1838 1838 static void
1839 1839 scsi_update_parent_ss2_prop(dev_info_t *devi, int tgt, int add_tgt)
1840 1840 {
1841 1841 dev_info_t *pdevi = (dev_info_t *)DEVI(devi)->devi_parent;
1842 1842 uchar_t *tgt_list;
1843 1843 uint_t nelements;
1844 1844 uint_t new_nelements;
1845 1845 int i;
1846 1846 int update_result;
1847 1847 uchar_t new_tgt_list[NTARGETS_WIDE];
1848 1848
1849 1849
1850 1850 ASSERT(pdevi != NULL);
1851 1851
1852 1852 SCSI_PROBE_DEBUG3(3,
1853 1853 "SCSA post-probe: updating parent=%s property to %s tgt=%d\n",
1854 1854 ddi_node_name(pdevi), add_tgt ? "add" : "remove", tgt);
1855 1855
1856 1856 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, pdevi,
1857 1857 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1858 1858 SS2_LUN0_TGT_LIST_PROP, &tgt_list, &nelements) ==
1859 1859 DDI_PROP_SUCCESS) {
1860 1860
1861 1861 if (add_tgt) {
1862 1862 /*
1863 1863 * we found an existing property -- we might need
1864 1864 * to add to it
1865 1865 */
1866 1866 for (i = 0; i < nelements; i++) {
1867 1867 if (tgt_list[i] == tgt) {
1868 1868 /* target already in list */
1869 1869 SCSI_PROBE_DEBUG1(2, "SCSA post-probe:"
1870 1870 " tgt %d already listed\n", tgt);
1871 1871 ddi_prop_free(tgt_list);
1872 1872 return;
1873 1873 }
1874 1874 }
1875 1875
1876 1876 /*
1877 1877 * need to append our target number to end of list
1878 1878 * (no need sorting list, as it's so short)
1879 1879 */
1880 1880
1881 1881 /*
1882 1882 * will this new entry fit ?? -- it should, since
1883 1883 * the array is 16-wide and only keep track of
1884 1884 * 16 targets, but check just in case
1885 1885 */
1886 1886 new_nelements = nelements + 1;
1887 1887 if (new_nelements >= NTARGETS_WIDE) {
1888 1888 SCSI_PROBE_DEBUG0(1, "SCSA post-probe: "
1889 1889 "internal error: no room "
1890 1890 "for more targets?\n");
1891 1891 ddi_prop_free(tgt_list);
1892 1892 return;
1893 1893 }
1894 1894
1895 1895 /* copy existing list then add our tgt number to end */
1896 1896 bcopy((void *)tgt_list, (void *)new_tgt_list,
1897 1897 sizeof (uchar_t) * nelements);
1898 1898 new_tgt_list[new_nelements - 1] = (uchar_t)tgt;
1899 1899 } else {
1900 1900 /*
1901 1901 * we need to remove our target number from the list,
1902 1902 * so copy all of the other target numbers,
1903 1903 * skipping ours
1904 1904 */
1905 1905 int tgt_removed = 0;
1906 1906
1907 1907 new_nelements = 0;
1908 1908 for (i = 0; i < nelements; i++) {
1909 1909 if (tgt_list[i] != tgt) {
1910 1910 new_tgt_list[new_nelements++] =
1911 1911 tgt_list[i];
1912 1912 } else {
1913 1913 /* skip this target */
1914 1914 tgt_removed++;
1915 1915 }
1916 1916 }
1917 1917
1918 1918 if (!tgt_removed) {
1919 1919 SCSI_PROBE_DEBUG1(2, "SCSA post-probe:"
1920 1920 " no need to remove tgt %d\n", tgt);
1921 1921 ddi_prop_free(tgt_list);
1922 1922 return;
1923 1923 }
1924 1924 }
1925 1925
1926 1926 update_result = ddi_prop_update_byte_array(DDI_DEV_T_NONE,
1927 1927 pdevi, SS2_LUN0_TGT_LIST_PROP, new_tgt_list,
1928 1928 new_nelements);
1929 1929
1930 1930 ddi_prop_free(tgt_list);
1931 1931 } else {
1932 1932 /*
1933 1933 * no property yet
1934 1934 */
1935 1935 if (add_tgt) {
1936 1936 /*
1937 1937 * create a property with just our tgt
1938 1938 */
1939 1939 new_tgt_list[0] = (uchar_t)tgt;
1940 1940 new_nelements = 1; /* just one element */
1941 1941
1942 1942 update_result = ddi_prop_update_byte_array(
1943 1943 DDI_DEV_T_NONE, pdevi, SS2_LUN0_TGT_LIST_PROP,
1944 1944 new_tgt_list, new_nelements);
1945 1945 } else {
1946 1946 /*
1947 1947 * no list so no need to remove tgt from that list
1948 1948 */
1949 1949 return;
1950 1950 }
1951 1951 }
1952 1952
1953 1953 #ifdef DEBUG
1954 1954 /*
1955 1955 * if we get here we have tried to add/update properties
1956 1956 */
1957 1957 if (update_result != DDI_PROP_SUCCESS) {
1958 1958 SCSI_PROBE_DEBUG2(1, "SCSA post-probe: can't update parent "
1959 1959 "property with tgt=%d (%d)\n", tgt, update_result);
1960 1960 } else {
1961 1961 if (add_tgt) {
1962 1962 SCSI_PROBE_DEBUG3(2,
1963 1963 "SCSA post-probe: added tgt=%d to parent "
1964 1964 "prop=\"%s\" (now %d entries)\n",
1965 1965 tgt, SS2_LUN0_TGT_LIST_PROP, new_nelements);
1966 1966 } else {
1967 1967 SCSI_PROBE_DEBUG3(2,
1968 1968 "SCSA post-probe: removed tgt=%d from parent "
1969 1969 "prop=\"%s\" (now %d entries)\n",
1970 1970 tgt, SS2_LUN0_TGT_LIST_PROP, new_nelements);
1971 1971 }
1972 1972 }
1973 1973 #endif
1974 1974 }
1975 1975
1976 1976
1977 1977 /* XXX BEGIN: find a better place for this: inquiry.h? */
1978 1978 /*
1979 1979 * Definitions used by device id registration routines
1980 1980 */
1981 1981 #define VPD_HEAD_OFFSET 3 /* size of head for vpd page */
1982 1982 #define VPD_PAGE_LENGTH 3 /* offset for pge length data */
1983 1983 #define VPD_MODE_PAGE 1 /* offset into vpd pg for "page code" */
1984 1984
1985 1985 /* size for devid inquiries */
1986 1986 #define MAX_INQUIRY_SIZE 0xF0
1987 1987 #define MAX_INQUIRY_SIZE_EVPD 0xFF /* XXX why is this longer */
1988 1988 /* XXX END: find a better place for these */
1989 1989
1990 1990
1991 1991 /*
1992 1992 * Decorate devinfo node with identity properties using information obtained
1993 1993 * from device. These properties are used by device enumeration code to derive
1994 1994 * the devid, and guid for the device. These properties are also used to
1995 1995 * determine if a device should be enumerated under the physical HBA (PHCI) or
1996 1996 * the virtual HBA (VHCI, for mpxio support).
1997 1997 *
1998 1998 * Return zero on success. If commands that should succeed fail or allocations
1999 1999 * fail then return failure (non-zero). It is possible for this function to
2000 2000 * return success and not have decorated the node with any additional identity
2001 2001 * information if the device correctly responds indicating that they are not
2002 2002 * supported. When failure occurs the caller should consider not making the
2003 2003 * device accessible.
2004 2004 */
2005 2005 int
2006 2006 scsi_device_identity(struct scsi_device *sd, int (*callback)())
2007 2007 {
2008 2008 dev_info_t *devi = sd->sd_dev;
2009 2009 uchar_t *inq80 = NULL;
2010 2010 uchar_t *inq83 = NULL;
2011 2011 int rval;
2012 2012 size_t len;
2013 2013 int pg80, pg83;
2014 2014
2015 2015 /* find out what pages are supported by device */
2016 2016 if (check_vpd_page_support8083(sd, callback, &pg80, &pg83) == -1)
2017 2017 return (-1);
2018 2018
2019 2019 /* if available, collect page 80 data and add as property */
2020 2020 if (pg80) {
2021 2021 inq80 = kmem_zalloc(MAX_INQUIRY_SIZE,
2022 2022 ((callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP));
2023 2023 if (inq80 == NULL) {
2024 2024 rval = -1;
2025 2025 goto out;
2026 2026 }
2027 2027
2028 2028 rval = send_scsi_INQUIRY(sd, callback, inq80,
2029 2029 MAX_INQUIRY_SIZE, 0x01, 0x80, &len, STC_IDENTITY_PG80);
2030 2030 if (rval)
2031 2031 goto out; /* should have worked */
2032 2032
2033 2033 if (len && (ndi_prop_update_byte_array(DDI_DEV_T_NONE, devi,
2034 2034 "inquiry-page-80", inq80, len) != DDI_PROP_SUCCESS)) {
2035 2035 cmn_err(CE_WARN, "scsi_device_identity: "
2036 2036 "failed to add page80 prop");
2037 2037 rval = -1;
2038 2038 goto out;
2039 2039 }
2040 2040 }
2041 2041
2042 2042 /* if available, collect page 83 data and add as property */
2043 2043 if (pg83) {
2044 2044 inq83 = kmem_zalloc(MAX_INQUIRY_SIZE,
2045 2045 ((callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP));
2046 2046 if (inq83 == NULL) {
2047 2047 rval = -1;
2048 2048 goto out;
2049 2049 }
2050 2050
2051 2051 rval = send_scsi_INQUIRY(sd, callback, inq83,
2052 2052 MAX_INQUIRY_SIZE, 0x01, 0x83, &len, STC_IDENTITY_PG83);
2053 2053 if (rval)
2054 2054 goto out; /* should have worked */
2055 2055
2056 2056 if (len && (ndi_prop_update_byte_array(DDI_DEV_T_NONE, devi,
2057 2057 "inquiry-page-83", inq83, len) != DDI_PROP_SUCCESS)) {
2058 2058 cmn_err(CE_WARN, "scsi_device_identity: "
2059 2059 "failed to add page83 prop");
2060 2060 rval = -1;
2061 2061 goto out;
2062 2062 }
2063 2063 }
2064 2064
2065 2065 /* Commands worked, identity information that exists has been added. */
2066 2066 rval = 0;
2067 2067
2068 2068 /* clean up resources */
2069 2069 out: if (inq80 != NULL)
2070 2070 kmem_free(inq80, MAX_INQUIRY_SIZE);
2071 2071 if (inq83 != NULL)
2072 2072 kmem_free(inq83, MAX_INQUIRY_SIZE);
2073 2073
2074 2074 return (rval);
2075 2075 }
2076 2076
2077 2077 /*
2078 2078 * Send an INQUIRY command with the EVPD bit set and a page code of 0x00 to
2079 2079 * the device, returning zero on success. Returned INQUIRY data is used to
2080 2080 * determine which vital product pages are supported. The device idenity
2081 2081 * information we are looking for is in pages 0x83 and/or 0x80. If the device
2082 2082 * fails the EVPD inquiry then no pages are supported but the call succeeds.
2083 2083 * Return -1 (failure) if there were memory allocation failures or if a
2084 2084 * command faild that should have worked.
2085 2085 */
2086 2086 static int
2087 2087 check_vpd_page_support8083(struct scsi_device *sd, int (*callback)(),
2088 2088 int *ppg80, int *ppg83)
2089 2089 {
2090 2090 uchar_t *page_list;
2091 2091 int counter;
2092 2092 int rval;
2093 2093
2094 2094 /* pages are not supported */
2095 2095 *ppg80 = 0;
2096 2096 *ppg83 = 0;
2097 2097
2098 2098 /*
2099 2099 * We'll set the page length to the maximum to save figuring it out
2100 2100 * with an additional call.
2101 2101 */
2102 2102 page_list = kmem_zalloc(MAX_INQUIRY_SIZE_EVPD,
2103 2103 ((callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP));
2104 2104 if (page_list == NULL)
2105 2105 return (-1); /* memory allocation problem */
2106 2106
2107 2107 /* issue page 0 (Supported VPD Pages) INQUIRY with evpd set */
2108 2108 rval = send_scsi_INQUIRY(sd, callback,
2109 2109 page_list, MAX_INQUIRY_SIZE_EVPD, 1, 0, NULL, STC_VPD_CHECK);
2110 2110
2111 2111 /*
2112 2112 * Now we must validate that the device accepted the command (some
2113 2113 * devices do not support it) and if the idenity pages we are
2114 2114 * interested in are supported.
2115 2115 */
2116 2116 if ((rval == 0) &&
2117 2117 (page_list[VPD_MODE_PAGE] == 0x00)) {
2118 2118 /* Loop to find one of the 2 pages we need */
2119 2119 counter = 4; /* Supported pages start at byte 4, with 0x00 */
2120 2120
2121 2121 /*
2122 2122 * Pages are returned in ascending order, and 0x83 is the
2123 2123 * last page we are hoping to find.
2124 2124 */
2125 2125 while ((page_list[counter] <= 0x83) &&
2126 2126 (counter <= (page_list[VPD_PAGE_LENGTH] +
2127 2127 VPD_HEAD_OFFSET))) {
2128 2128 /*
2129 2129 * Add 3 because page_list[3] is the number of
2130 2130 * pages minus 3
2131 2131 */
2132 2132
2133 2133 switch (page_list[counter]) {
2134 2134 case 0x80:
2135 2135 *ppg80 = 1;
2136 2136 break;
2137 2137 case 0x83:
2138 2138 *ppg83 = 1;
2139 2139 break;
2140 2140 }
2141 2141 counter++;
2142 2142 }
2143 2143 }
2144 2144
2145 2145 kmem_free(page_list, MAX_INQUIRY_SIZE_EVPD);
2146 2146 return (0);
2147 2147 }
2148 2148
2149 2149 /*
2150 2150 * Send INQUIRY command with specified EVPD and page code. Return
2151 2151 * zero on success. On success, the amount of data transferred
2152 2152 * is returned in *lenp.
2153 2153 */
2154 2154 static int
2155 2155 send_scsi_INQUIRY(struct scsi_device *sd, int (*callback)(),
2156 2156 uchar_t *bufaddr, size_t buflen,
2157 2157 uchar_t evpd, uchar_t page_code, size_t *lenp,
2158 2158 enum scsi_test_ctxt ctxt)
2159 2159 {
2160 2160 int (*cb_flag)();
2161 2161 struct buf *inq_bp;
2162 2162 struct scsi_pkt *inq_pkt = NULL;
2163 2163 int rval = -1;
2164 2164
2165 2165 if (lenp)
2166 2166 *lenp = 0;
2167 2167 if (callback != SLEEP_FUNC && callback != NULL_FUNC)
2168 2168 cb_flag = NULL_FUNC;
2169 2169 else
2170 2170 cb_flag = callback;
2171 2171 inq_bp = scsi_alloc_consistent_buf(ROUTE,
2172 2172 (struct buf *)NULL, buflen, B_READ, cb_flag, NULL);
2173 2173 if (inq_bp == NULL)
2174 2174 goto out; /* memory allocation problem */
2175 2175
2176 2176 inq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL,
2177 2177 inq_bp, CDB_GROUP0, sizeof (struct scsi_arq_status),
2178 2178 0, PKT_CONSISTENT, callback, NULL);
2179 2179 if (inq_pkt == NULL)
2180 2180 goto out; /* memory allocation problem */
2181 2181
2182 2182 ASSERT(inq_bp->b_error == 0);
2183 2183
2184 2184 /* form INQUIRY cdb with specified EVPD and page code */
2185 2185 (void) scsi_setup_cdb((union scsi_cdb *)inq_pkt->pkt_cdbp,
2186 2186 SCMD_INQUIRY, 0, buflen, 0);
2187 2187 inq_pkt->pkt_cdbp[1] = evpd;
2188 2188 inq_pkt->pkt_cdbp[2] = page_code;
2189 2189
2190 2190 inq_pkt->pkt_time = SCSI_POLL_TIMEOUT; /* in seconds */
2191 2191 inq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY;
2192 2192
2193 2193 /*
2194 2194 * Issue inquiry command thru scsi_test
2195 2195 *
2196 2196 * NOTE: This is important data about device identity, not sure why
2197 2197 * NOPARITY is used. Also seems like we should check pkt_stat for
2198 2198 * STATE_XFERRED_DATA.
2199 2199 */
2200 2200 if (scsi_test(inq_pkt, ctxt) == SCSI_TEST_CMPLT_GOOD) {
2201 2201 ASSERT(inq_pkt->pkt_resid >= 0);
2202 2202 ASSERT(inq_pkt->pkt_resid <= buflen);
2203 2203
2204 2204 bcopy(inq_bp->b_un.b_addr,
2205 2205 bufaddr, buflen - inq_pkt->pkt_resid);
2206 2206 if (lenp)
2207 2207 *lenp = (buflen - inq_pkt->pkt_resid);
2208 2208 rval = 0;
2209 2209 }
2210 2210
2211 2211 /*
2212 2212 * XXX We should retry on target busy
2213 2213 */
2214 2214
2215 2215 out: if (inq_pkt)
2216 2216 scsi_destroy_pkt(inq_pkt);
2217 2217 if (inq_bp)
2218 2218 scsi_free_consistent_buf(inq_bp);
2219 2219 return (rval);
2220 2220 }
↓ open down ↓ |
2153 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX