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