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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Utility SCSI configuration routines 30 */ 31 /* 32 * Many routines in this file have built in parallel bus assumption 33 * which might need to change as other interconnect evolve. 34 */ 35 36 37 #include <sys/scsi/scsi.h> 38 #include <sys/modctl.h> 39 40 /* 41 * macro for filling in lun value for scsi-1 support 42 */ 43 44 #define FILL_SCSI1_LUN(devp, pkt) \ 45 if ((devp->sd_address.a_lun > 0) && \ 46 (devp->sd_inq->inq_ansi == 0x1)) { \ 47 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \ 48 devp->sd_address.a_lun; \ 49 } 50 51 extern struct mod_ops mod_miscops; 52 53 static struct modlmisc modlmisc = { 54 &mod_miscops, /* Type of module */ 55 "SCSI Bus Utility Routines" 56 }; 57 58 static struct modlinkage modlinkage = { 59 MODREV_1, (void *)&modlmisc, NULL 60 }; 61 62 static void create_inquiry_props(struct scsi_device *); 63 static int get_inquiry_prop_len(char *, size_t); 64 65 static int scsi_check_ss2_LUN_limit(struct scsi_device *); 66 static void scsi_establish_LUN_limit(struct scsi_device *); 67 static void scsi_update_parent_ss2_prop(dev_info_t *, int, int); 68 69 /* 70 * this int-array HBA-node property keeps track of strictly SCSI-2 71 * target IDs 72 */ 73 #define SS2_LUN0_TGT_LIST_PROP "ss2-targets" 74 75 /* 76 * for keeping track of nodes for which we do *NOT* want to probe above LUN 7 77 * (i.e. strict SCSI-2 targets) 78 * 79 * note that we could also keep track of dtype (SCSI device type) and 80 * ANSI (SCSI standard conformance level), but all currently-known cases of 81 * this problem are on SCSI-2 PROCESSOR device types 82 */ 83 typedef struct ss2_lun0_info { 84 const char *sli_vid; /* SCSI inquiry VID */ 85 const char *sli_pid; /* SCSI inquiry PID */ 86 const char *sli_rev; /* SCSI inquiry REV */ 87 } ss2_lun0_info_t; 88 89 /* 90 * these two workarounds are for the SCSI-2 GEM2* chips used in the 91 * D1000 and D240 92 */ 93 #define SES_D1000_VID "SYMBIOS" 94 #define SES_D1000_PID "D1000" /* the D1000 */ 95 #define SES_D1000_REV "2" 96 97 #define SES_D240_VID "SUN" 98 #define SES_D240_PID "D240" /* the D240 */ 99 #define SES_D240_REV "2" 100 101 /* 102 * a static list of targets where we do *not* want to probe above LUN 7 103 */ 104 static const ss2_lun0_info_t scsi_probe_strict_s2_list[] = { 105 {SES_D1000_VID, SES_D1000_PID, SES_D1000_REV}, 106 {SES_D240_VID, SES_D240_PID, SES_D240_REV}, 107 }; 108 109 static const int scsi_probe_strict_s2_size = 110 sizeof (scsi_probe_strict_s2_list) / sizeof (struct ss2_lun0_info); 111 112 113 #ifdef DEBUG 114 115 int scsi_probe_debug = 0; 116 117 #define SCSI_PROBE_DEBUG0(l, s) \ 118 if (scsi_probe_debug >= (l)) printf(s) 119 #define SCSI_PROBE_DEBUG1(l, s, a1) \ 120 if (scsi_probe_debug >= (l)) printf(s, a1) 121 #define SCSI_PROBE_DEBUG2(l, s, a1, a2) \ 122 if (scsi_probe_debug >= (l)) printf(s, a1, a2) 123 #define SCSI_PROBE_DEBUG3(l, s, a1, a2, a3) \ 124 if (scsi_probe_debug >= (l)) printf(s, a1, a2, a3) 125 126 #else /* DEBUG */ 127 128 #define SCSI_PROBE_DEBUG0(l, s) 129 #define SCSI_PROBE_DEBUG1(l, s, a1) 130 #define SCSI_PROBE_DEBUG2(l, s, a1, a2) 131 #define SCSI_PROBE_DEBUG3(l, s, a1, a2, a3) 132 133 #endif /* DEBUG */ 134 135 int scsi_test_busy_timeout = SCSI_POLL_TIMEOUT; /* in seconds */ 136 int scsi_test_busy_delay = 10000; /* 10msec in usec */ 137 138 /* 139 * architecture dependent allocation restrictions. For x86, we'll set 140 * dma_attr_addr_hi to scsi_max_phys_addr and dma_attr_sgllen to 141 * scsi_sgl_size during _init(). 142 */ 143 #if defined(__sparc) 144 ddi_dma_attr_t scsi_alloc_attr = { 145 DMA_ATTR_V0, /* version number */ 146 0x0, /* lowest usable address */ 147 0xFFFFFFFFull, /* high DMA address range */ 148 0xFFFFFFFFull, /* DMA counter register */ 149 1, /* DMA address alignment */ 150 1, /* DMA burstsizes */ 151 1, /* min effective DMA size */ 152 0xFFFFFFFFull, /* max DMA xfer size */ 153 0xFFFFFFFFull, /* segment boundary */ 154 1, /* s/g list length */ 155 512, /* granularity of device */ 156 0 /* DMA transfer flags */ 157 }; 158 #elif defined(__x86) 159 ddi_dma_attr_t scsi_alloc_attr = { 160 DMA_ATTR_V0, /* version number */ 161 0x0, /* lowest usable address */ 162 0x0, /* high DMA address range [set in _init()] */ 163 0xFFFFull, /* DMA counter register */ 164 1, /* DMA address alignment */ 165 1, /* DMA burstsizes */ 166 1, /* min effective DMA size */ 167 0xFFFFFFFFull, /* max DMA xfer size */ 168 0xFFFFFFFFull, /* segment boundary */ 169 0, /* s/g list length */ 170 512, /* granularity of device [set in _init()] */ 171 0 /* DMA transfer flags */ 172 }; 173 uint64_t scsi_max_phys_addr = 0xFFFFFFFFull; 174 int scsi_sgl_size = 0xFF; 175 #endif 176 177 178 int 179 _init() 180 { 181 scsi_initialize_hba_interface(); 182 scsi_watch_init(); 183 184 #if defined(__x86) 185 /* set the max physical address for iob allocs on x86 */ 186 scsi_alloc_attr.dma_attr_addr_hi = scsi_max_phys_addr; 187 188 /* 189 * set the sgllen for iob allocs on x86. If this is set less than 190 * the number of pages the buffer will take (taking into account 191 * alignment), it would force the allocator to try and allocate 192 * contiguous pages. 193 */ 194 scsi_alloc_attr.dma_attr_sgllen = scsi_sgl_size; 195 #endif 196 197 return (mod_install(&modlinkage)); 198 } 199 200 /* 201 * there is no _fini() routine because this module is never unloaded 202 */ 203 204 int 205 _info(struct modinfo *modinfop) 206 { 207 return (mod_info(&modlinkage, modinfop)); 208 } 209 210 #define ROUTE (&devp->sd_address) 211 212 static int 213 scsi_slave_do_rqsense(struct scsi_device *devp, int (*callback)()) 214 { 215 struct scsi_pkt *rq_pkt = NULL; 216 struct buf *rq_bp = NULL; 217 int rval = SCSIPROBE_EXISTS; 218 219 /* 220 * prepare rqsense packet 221 */ 222 rq_bp = scsi_alloc_consistent_buf(ROUTE, 223 (struct buf *)NULL, 224 (uint_t)SENSE_LENGTH, B_READ, callback, NULL); 225 if (rq_bp == NULL) { 226 rval = SCSIPROBE_NOMEM; 227 goto out; 228 } 229 230 rq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, 231 rq_bp, CDB_GROUP0, 1, 0, PKT_CONSISTENT, 232 callback, NULL); 233 234 if (rq_pkt == NULL) { 235 if (rq_bp->b_error == 0) 236 rval = SCSIPROBE_NOMEM_CB; 237 else 238 rval = SCSIPROBE_NOMEM; 239 goto out; 240 } 241 ASSERT(rq_bp->b_error == 0); 242 243 (void) scsi_setup_cdb((union scsi_cdb *)rq_pkt-> 244 pkt_cdbp, SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0); 245 FILL_SCSI1_LUN(devp, rq_pkt); 246 rq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY|FLAG_SENSING; 247 248 /* 249 * The controller type is as yet unknown, so we 250 * have to do a throwaway non-extended request sense, 251 * and hope that that clears the check condition 252 * for that unit until we can find out what kind 253 * of drive it is. A non-extended request sense 254 * is specified by stating that the sense block 255 * has 0 length, which is taken to mean that it 256 * is four bytes in length. 257 */ 258 if (scsi_poll(rq_pkt) < 0) { 259 rval = SCSIPROBE_FAILURE; 260 } 261 262 out: 263 if (rq_pkt) { 264 scsi_destroy_pkt(rq_pkt); 265 } 266 if (rq_bp) { 267 scsi_free_consistent_buf(rq_bp); 268 } 269 270 return (rval); 271 } 272 273 /* 274 * 275 * SCSI slave probe routine - provided as a service to target drivers 276 * 277 * Mostly attempts to allocate and fill devp inquiry data.. 278 */ 279 280 int 281 scsi_slave(struct scsi_device *devp, int (*callback)()) 282 { 283 struct scsi_pkt *pkt; 284 int rval = SCSIPROBE_EXISTS; 285 286 /* 287 * the first test unit ready will tell us whether a target 288 * responded and if there was one, it will clear the unit attention 289 * condition 290 */ 291 pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, NULL, 292 CDB_GROUP0, sizeof (struct scsi_arq_status), 0, 0, callback, NULL); 293 294 if (pkt == NULL) { 295 return (SCSIPROBE_NOMEM_CB); 296 } 297 298 (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, 299 SCMD_TEST_UNIT_READY, 0, 0, 0); 300 FILL_SCSI1_LUN(devp, pkt); 301 pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY; 302 303 if (scsi_poll(pkt) < 0) { 304 if (pkt->pkt_reason == CMD_INCOMPLETE) 305 rval = SCSIPROBE_NORESP; 306 else 307 rval = SCSIPROBE_FAILURE; 308 309 if ((pkt->pkt_state & STATE_ARQ_DONE) == 0) { 310 if (((struct scsi_status *)pkt->pkt_scbp)->sts_chk) 311 /* 312 * scanner and processor devices can return a 313 * check condition here 314 */ 315 rval = scsi_slave_do_rqsense(devp, callback); 316 } 317 318 if (rval != SCSIPROBE_EXISTS) { 319 scsi_destroy_pkt(pkt); 320 return (rval); 321 } 322 } 323 324 /* 325 * the second test unit ready, allows the host adapter to negotiate 326 * synchronous transfer period and offset 327 */ 328 if (scsi_poll(pkt) < 0) { 329 if (pkt->pkt_reason == CMD_INCOMPLETE) 330 rval = SCSIPROBE_NORESP; 331 else 332 rval = SCSIPROBE_FAILURE; 333 } 334 335 /* 336 * do a rqsense if there was a check condition and ARQ was not done 337 */ 338 if ((pkt->pkt_state & STATE_ARQ_DONE) == 0) { 339 if (((struct scsi_status *)pkt->pkt_scbp)->sts_chk) { 340 rval = scsi_slave_do_rqsense(devp, callback); 341 } 342 } 343 344 /* 345 * call scsi_probe to do the inquiry 346 * XXX there is minor difference with the old scsi_slave implementation: 347 * busy conditions are not handled in scsi_probe. 348 */ 349 scsi_destroy_pkt(pkt); 350 if (rval == SCSIPROBE_EXISTS) { 351 return (scsi_probe(devp, callback)); 352 } else { 353 return (rval); 354 } 355 } 356 357 358 /* 359 * Undo scsi_slave - older interface, but still supported 360 */ 361 void 362 scsi_unslave(struct scsi_device *devp) 363 { 364 if (devp->sd_inq) { 365 kmem_free((caddr_t)devp->sd_inq, SUN_INQSIZE); 366 devp->sd_inq = (struct scsi_inquiry *)NULL; 367 } 368 } 369 370 371 /* 372 * Undo scsi_probe 373 */ 374 void 375 scsi_unprobe(struct scsi_device *devp) 376 { 377 if (devp->sd_inq) { 378 kmem_free((caddr_t)devp->sd_inq, SUN_INQSIZE); 379 devp->sd_inq = (struct scsi_inquiry *)NULL; 380 } 381 } 382 383 /* 384 * This is like scsi_poll, but only does retry for TRAN_BUSY. 385 */ 386 static int 387 scsi_test(struct scsi_pkt *pkt) 388 { 389 int rval = -1; 390 int wait_usec; 391 int rc; 392 extern int do_polled_io; 393 394 pkt->pkt_flags |= FLAG_NOINTR; 395 pkt->pkt_time = SCSI_POLL_TIMEOUT; /* in seconds */ 396 397 if (scsi_ifgetcap(&pkt->pkt_address, "tagged-qing", 1) == 1) { 398 pkt->pkt_flags |= FLAG_STAG; 399 } 400 401 /* 402 * Each TRAN_BUSY response waits scsi_test_busy_delay usec up to a 403 * maximum of scsi_test_busy_timeout. 404 */ 405 for (wait_usec = 0; (wait_usec / 1000000) <= scsi_test_busy_timeout; 406 wait_usec += scsi_test_busy_delay) { 407 408 /* Initialize pkt status variables */ 409 *pkt->pkt_scbp = pkt->pkt_reason = pkt->pkt_state = 0; 410 411 rc = scsi_transport(pkt); 412 if ((rc != TRAN_BUSY) || (scsi_test_busy_delay == 0) || 413 (scsi_test_busy_timeout == 0)) 414 break; 415 416 /* transport busy, wait */ 417 if ((curthread->t_flag & T_INTR_THREAD) == 0 && !do_polled_io) { 418 delay(drv_usectohz(scsi_test_busy_delay)); 419 } else { 420 /* we busy wait during cpr_dump or interrupt threads */ 421 drv_usecwait(scsi_test_busy_delay); 422 } 423 } 424 425 if (rc != TRAN_ACCEPT) { 426 goto exit; 427 } else if (pkt->pkt_reason == CMD_INCOMPLETE && pkt->pkt_state == 0) { 428 goto exit; 429 } else if (pkt->pkt_reason != CMD_CMPLT) { 430 goto exit; 431 } else if (((*pkt->pkt_scbp) & STATUS_MASK) == STATUS_BUSY) { 432 rval = 0; 433 } else { 434 rval = 0; 435 } 436 437 exit: 438 return (rval); 439 } 440 441 /* 442 * The implementation of scsi_probe now allows a particular 443 * HBA to intercept the call, for any post- or pre-processing 444 * it may need. The default, if the HBA does not override it, 445 * is to call scsi_hba_probe(), which retains the old functionality 446 * intact. 447 */ 448 int 449 scsi_probe(struct scsi_device *devp, int (*callback)()) 450 { 451 int ret; 452 scsi_hba_tran_t *hba_tran = devp->sd_address.a_hba_tran; 453 454 455 if (scsi_check_ss2_LUN_limit(devp) != 0) { 456 /* 457 * caller is trying to probe a strictly-SCSI-2 device 458 * with a LUN that is too large, so do not allow it 459 */ 460 return (SCSIPROBE_NORESP); /* skip probing this one */ 461 } 462 463 if (hba_tran->tran_tgt_probe != NULL) { 464 ret = (*hba_tran->tran_tgt_probe)(devp, callback); 465 } else { 466 ret = scsi_hba_probe(devp, callback); 467 } 468 469 if (ret == SCSIPROBE_EXISTS) { 470 create_inquiry_props(devp); 471 /* is this a strictly-SCSI-2 node ?? */ 472 scsi_establish_LUN_limit(devp); 473 } 474 475 return (ret); 476 } 477 478 /* 479 * scsi_hba_probe does not do any test unit ready's which access the medium 480 * and could cause busy or not ready conditions. 481 * scsi_hba_probe does 2 inquiries and a rqsense to clear unit attention 482 * and to allow sync negotiation to take place 483 * finally, scsi_hba_probe does one more inquiry which should 484 * reliably tell us what kind of target we have. 485 * A scsi-2 compliant target should be able to return inquiry with 250ms 486 * and we actually wait more than a second after reset. 487 */ 488 int 489 scsi_hba_probe(struct scsi_device *devp, int (*callback)()) 490 { 491 struct scsi_pkt *inq_pkt = NULL; 492 struct scsi_pkt *rq_pkt = NULL; 493 int rval = SCSIPROBE_NOMEM; 494 struct buf *inq_bp = NULL; 495 struct buf *rq_bp = NULL; 496 int (*cb_flag)(); 497 int pass = 1; 498 499 if (devp->sd_inq == NULL) { 500 devp->sd_inq = (struct scsi_inquiry *) 501 kmem_alloc(SUN_INQSIZE, ((callback == SLEEP_FUNC) ? 502 KM_SLEEP : KM_NOSLEEP)); 503 if (devp->sd_inq == NULL) { 504 goto out; 505 } 506 } 507 508 if (callback != SLEEP_FUNC && callback != NULL_FUNC) { 509 cb_flag = NULL_FUNC; 510 } else { 511 cb_flag = callback; 512 } 513 inq_bp = scsi_alloc_consistent_buf(ROUTE, 514 (struct buf *)NULL, SUN_INQSIZE, B_READ, cb_flag, NULL); 515 if (inq_bp == NULL) { 516 goto out; 517 } 518 519 inq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, 520 inq_bp, CDB_GROUP0, sizeof (struct scsi_arq_status), 521 0, PKT_CONSISTENT, callback, NULL); 522 if (inq_pkt == NULL) { 523 if (inq_bp->b_error == 0) 524 rval = SCSIPROBE_NOMEM_CB; 525 goto out; 526 } 527 ASSERT(inq_bp->b_error == 0); 528 529 (void) scsi_setup_cdb((union scsi_cdb *)inq_pkt->pkt_cdbp, 530 SCMD_INQUIRY, 0, SUN_INQSIZE, 0); 531 inq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY; 532 533 /* 534 * the first inquiry will tell us whether a target 535 * responded 536 * 537 * The FILL_SCSI1_LUN below will find "ansi_ver != 1" on first pass 538 * because of bzero initilization. If this assumption turns out to be 539 * incorrect after we have real sd_inq data (for lun0) we will do a 540 * second pass during which FILL_SCSI1_LUN will place lun in CDB. 541 */ 542 bzero((caddr_t)devp->sd_inq, SUN_INQSIZE); 543 again: FILL_SCSI1_LUN(devp, inq_pkt); 544 545 if (scsi_test(inq_pkt) < 0) { 546 if (inq_pkt->pkt_reason == CMD_INCOMPLETE) { 547 rval = SCSIPROBE_NORESP; 548 goto out; 549 } else { 550 /* 551 * retry one more time 552 */ 553 if (scsi_test(inq_pkt) < 0) { 554 rval = SCSIPROBE_FAILURE; 555 goto out; 556 } 557 } 558 } 559 560 /* 561 * if we are lucky, this inquiry succeeded 562 */ 563 if ((inq_pkt->pkt_reason == CMD_CMPLT) && 564 (((*inq_pkt->pkt_scbp) & STATUS_MASK) == 0)) { 565 goto done; 566 } 567 568 /* 569 * the second inquiry, allows the host adapter to negotiate 570 * synchronous transfer period and offset 571 */ 572 if (scsi_test(inq_pkt) < 0) { 573 if (inq_pkt->pkt_reason == CMD_INCOMPLETE) 574 rval = SCSIPROBE_NORESP; 575 else 576 rval = SCSIPROBE_FAILURE; 577 goto out; 578 } 579 580 /* 581 * if target is still busy, give up now 582 */ 583 if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_busy) { 584 rval = SCSIPROBE_BUSY; 585 goto out; 586 } 587 588 /* 589 * do a rqsense if there was a check condition and ARQ was not done 590 */ 591 if ((inq_pkt->pkt_state & STATE_ARQ_DONE) == 0) { 592 if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_chk) { 593 594 /* 595 * prepare rqsense packet 596 * there is no real need for this because the 597 * check condition should have been cleared by now. 598 */ 599 rq_bp = scsi_alloc_consistent_buf(ROUTE, 600 (struct buf *)NULL, 601 (uint_t)SENSE_LENGTH, B_READ, cb_flag, NULL); 602 if (rq_bp == NULL) { 603 goto out; 604 } 605 606 rq_pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, 607 rq_bp, CDB_GROUP0, 1, 0, PKT_CONSISTENT, callback, 608 NULL); 609 610 if (rq_pkt == NULL) { 611 if (rq_bp->b_error == 0) 612 rval = SCSIPROBE_NOMEM_CB; 613 goto out; 614 } 615 ASSERT(rq_bp->b_error == 0); 616 617 (void) scsi_setup_cdb((union scsi_cdb *)rq_pkt-> 618 pkt_cdbp, SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0); 619 FILL_SCSI1_LUN(devp, rq_pkt); 620 rq_pkt->pkt_flags = FLAG_NOINTR|FLAG_NOPARITY; 621 622 /* 623 * The FILL_SCSI1_LUN above will find "inq_ansi != 1" 624 * on first pass, see "again" comment above. 625 * 626 * The controller type is as yet unknown, so we 627 * have to do a throwaway non-extended request sense, 628 * and hope that that clears the check condition for 629 * that unit until we can find out what kind of drive 630 * it is. A non-extended request sense is specified 631 * by stating that the sense block has 0 length, 632 * which is taken to mean that it is four bytes in 633 * length. 634 */ 635 if (scsi_test(rq_pkt) < 0) { 636 rval = SCSIPROBE_FAILURE; 637 goto out; 638 } 639 } 640 } 641 642 /* 643 * At this point, we are guaranteed that something responded 644 * to this scsi bus target id. We don't know yet what 645 * kind of device it is, or even whether there really is 646 * a logical unit attached (as some SCSI target controllers 647 * lie about a unit being ready, e.g., the Emulex MD21). 648 */ 649 650 if (scsi_test(inq_pkt) < 0) { 651 rval = SCSIPROBE_FAILURE; 652 goto out; 653 } 654 655 if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_busy) { 656 rval = SCSIPROBE_BUSY; 657 goto out; 658 } 659 660 /* 661 * Okay we sent the INQUIRY command. 662 * 663 * If enough data was transferred, we count that the 664 * Inquiry command succeeded, else we have to assume 665 * that this is a non-CCS scsi target (or a nonexistent 666 * target/lun). 667 */ 668 669 if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_chk) { 670 /* 671 * try a request sense if we have a pkt, otherwise 672 * just retry the inquiry one more time 673 */ 674 if (rq_pkt) { 675 (void) scsi_test(rq_pkt); 676 } 677 678 /* 679 * retry inquiry 680 */ 681 if (scsi_test(inq_pkt) < 0) { 682 rval = SCSIPROBE_FAILURE; 683 goto out; 684 } 685 if (((struct scsi_status *)inq_pkt->pkt_scbp)->sts_chk) { 686 rval = SCSIPROBE_FAILURE; 687 goto out; 688 } 689 } 690 691 done: 692 /* 693 * If we got a parity error on receive of inquiry data, 694 * we're just plain out of luck because we told the host 695 * adapter to not watch for parity errors. 696 */ 697 if ((inq_pkt->pkt_state & STATE_XFERRED_DATA) == 0 || 698 ((SUN_INQSIZE - inq_pkt->pkt_resid) < SUN_MIN_INQLEN)) { 699 rval = SCSIPROBE_NONCCS; 700 } else { 701 bcopy((caddr_t)inq_bp->b_un.b_addr, 702 (caddr_t)devp->sd_inq, SUN_INQSIZE); 703 rval = SCSIPROBE_EXISTS; 704 } 705 706 out: 707 /* 708 * If lun > 0 we need to figure out if this is a scsi-1 device where 709 * the "real" lun needs to be embeded into the cdb. 710 */ 711 if ((rval == SCSIPROBE_EXISTS) && (pass == 1) && 712 (devp->sd_address.a_lun > 0) && (devp->sd_inq->inq_ansi == 0x1)) { 713 pass++; 714 if (devp->sd_address.a_lun <= 7) 715 goto again; 716 717 /* 718 * invalid lun for scsi-1, 719 * return probe failure. 720 */ 721 rval = SCSIPROBE_FAILURE; 722 } 723 724 if (rq_pkt) { 725 scsi_destroy_pkt(rq_pkt); 726 } 727 if (inq_pkt) { 728 scsi_destroy_pkt(inq_pkt); 729 } 730 if (rq_bp) { 731 scsi_free_consistent_buf(rq_bp); 732 } 733 if (inq_bp) { 734 scsi_free_consistent_buf(inq_bp); 735 } 736 return (rval); 737 } 738 739 740 #define A_TO_TRAN(ap) (ap->a_hba_tran) 741 742 /* 743 * Function to get target and lun identifiers from HBA driver. 744 */ 745 int 746 scsi_get_bus_addr(struct scsi_device *devp, char *name, int len) 747 { 748 struct scsi_address *ap = &devp->sd_address; 749 750 if ((A_TO_TRAN(ap)->tran_get_bus_addr) == NULL) { 751 (void) sprintf(name, "%x,%x", ap->a_target, ap->a_lun); 752 return (1); 753 } 754 return (*A_TO_TRAN(ap)->tran_get_bus_addr)(devp, name, len); 755 } 756 757 /* 758 * Function to get name from HBA driver. 759 */ 760 int 761 scsi_get_name(struct scsi_device *devp, char *name, int len) 762 { 763 struct scsi_address *ap = &devp->sd_address; 764 765 if ((A_TO_TRAN(ap)->tran_get_name) == NULL) { 766 (void) sprintf(name, "%x,%x", ap->a_target, ap->a_lun); 767 return (1); 768 } 769 return (*A_TO_TRAN(ap)->tran_get_name)(devp, name, len); 770 } 771 772 void 773 create_inquiry_props(struct scsi_device *devp) 774 { 775 struct scsi_inquiry *inq = devp->sd_inq; 776 777 (void) ndi_prop_update_int(DDI_DEV_T_NONE, devp->sd_dev, 778 INQUIRY_DEVICE_TYPE, (int)inq->inq_dtype); 779 780 /* 781 * Create the following properties: 782 * 783 * inquiry-vendor-id Vendor id (INQUIRY data bytes 8-15) 784 * inquiry-product-id Product id (INQUIRY data bytes 16-31) 785 * inquiry-revision-id Product Rev level (INQUIRY data bytes 32-35) 786 * 787 * Note we don't support creation of these properties for scsi-1 788 * devices (as the vid, pid and revision were not defined) and we 789 * don't create the property if they are of zero length when 790 * stripped of Nulls and spaces. 791 */ 792 if (inq->inq_ansi != 1) { 793 if (ddi_prop_exists(DDI_DEV_T_NONE, devp->sd_dev, 794 DDI_PROP_TYPE_STRING, INQUIRY_VENDOR_ID) == 0) 795 (void) scsi_hba_prop_update_inqstring(devp, 796 INQUIRY_VENDOR_ID, 797 inq->inq_vid, sizeof (inq->inq_vid)); 798 799 if (ddi_prop_exists(DDI_DEV_T_NONE, devp->sd_dev, 800 DDI_PROP_TYPE_STRING, INQUIRY_PRODUCT_ID) == 0) 801 (void) scsi_hba_prop_update_inqstring(devp, 802 INQUIRY_PRODUCT_ID, 803 inq->inq_pid, sizeof (inq->inq_pid)); 804 805 if (ddi_prop_exists(DDI_DEV_T_NONE, devp->sd_dev, 806 DDI_PROP_TYPE_STRING, INQUIRY_REVISION_ID) == 0) 807 (void) scsi_hba_prop_update_inqstring(devp, 808 INQUIRY_REVISION_ID, 809 inq->inq_revision, sizeof (inq->inq_revision)); 810 } 811 } 812 813 /* 814 * Create 'inquiry' string properties. An 'inquiry' string gets special 815 * treatment to trim trailing blanks (etc) and ensure null termination. 816 */ 817 int 818 scsi_hba_prop_update_inqstring(struct scsi_device *devp, 819 char *name, char *data, size_t len) 820 { 821 int ilen; 822 char *data_string; 823 int rv; 824 825 ilen = get_inquiry_prop_len(data, len); 826 ASSERT(ilen <= (int)len); 827 if (ilen <= 0) 828 return (DDI_PROP_INVAL_ARG); 829 830 /* ensure null termination */ 831 data_string = kmem_zalloc(ilen + 1, KM_SLEEP); 832 bcopy(data, data_string, ilen); 833 rv = ndi_prop_update_string(DDI_DEV_T_NONE, 834 devp->sd_dev, name, data_string); 835 kmem_free(data_string, ilen + 1); 836 return (rv); 837 } 838 839 /* 840 * This routine returns the true length of the inquiry properties that are to 841 * be created by removing the padded spaces at the end of the inquiry data. 842 * This routine was designed for trimming spaces from the vid, pid and revision 843 * which are defined as being left aligned. In addition, we return 0 length 844 * if the property is full of all 0's or spaces, indicating to the caller that 845 * the device was not ready to return the proper inquiry data as per note 65 in 846 * the scsi-2 spec. 847 */ 848 static int 849 get_inquiry_prop_len(char *property, size_t length) 850 { 851 int retval; 852 int trailer; 853 char *p; 854 855 retval = length; 856 857 /* 858 * The vid, pid and revision are left-aligned ascii fields within the 859 * inquiry data. Here we trim the end of these fields by discounting 860 * length associated with trailing spaces or NULL bytes. The remaining 861 * bytes shall be only graphics codes - 0x20 through 0x7e as per the 862 * scsi spec definition. If we have all 0's or spaces, we return 0 863 * length. For devices that store inquiry data on the device, they 864 * can return 0's or spaces in these fields until the data is avail- 865 * able from the device (See NOTE 65 in the scsi-2 specification 866 * around the inquiry command.) We don't want to create a property in 867 * the case of a device not able to return valid data. 868 */ 869 trailer = 1; 870 for (p = property + length - 1; p >= property; p--) { 871 if (trailer) { 872 if ((*p == ' ') || (*p == '\0')) { 873 retval--; 874 continue; 875 } 876 trailer = 0; 877 } 878 879 /* each char must be within 0x20 - 0x7e */ 880 if (*p < 0x20 || *p > 0x7e) { 881 retval = -1; 882 break; 883 } 884 885 } 886 887 return (retval); 888 } 889 890 891 /* 892 * this routine is called from the start of scsi_probe() if a tgt/LUN to be 893 * probed *may* be a request to probe a strictly SCSI-2 target (with respect 894 * to LUNs) -- and this probe may be for a LUN number greater than 7, 895 * which can cause a hardware hang 896 * 897 * return 0 if the probe can proceed, 898 * else return 1, meaning do *NOT* probe this target/LUN 899 */ 900 static int 901 scsi_check_ss2_LUN_limit(struct scsi_device *devp) 902 { 903 struct scsi_address *ap = &(devp->sd_address); 904 dev_info_t *pdevi = 905 (dev_info_t *)DEVI(devp->sd_dev)->devi_parent; 906 int ret_val = 0; /* default return value */ 907 uchar_t *tgt_list; 908 uint_t tgt_nelements; 909 int i; 910 911 912 /* 913 * check for what *might* be a problem probe, only we don't 914 * know yet what's really at the destination target/LUN 915 */ 916 if ((ap->a_target >= NTARGETS_WIDE) || 917 (ap->a_lun < NLUNS_PER_TARGET)) { 918 return (0); /* okay to probe this target */ 919 } 920 921 /* 922 * this *might* be a problematic probe, so look to see 923 * if the inquiry data matches 924 */ 925 SCSI_PROBE_DEBUG2(1, "SCSA pre-probe: checking tgt.LUN=%d.%d\n", 926 ap->a_target, ap->a_lun); 927 SCSI_PROBE_DEBUG1(2, 928 "SCSA pre-probe: scanning parent node name: %s ...\n", 929 ddi_node_name(pdevi)); 930 931 /* 932 * look for a special property of our parent node that lists 933 * the targets under it for which we do *NOT* want to probe 934 * if LUN>7 -- if the property is found, look to see if our 935 * target ID is on that list 936 */ 937 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, 938 pdevi, DDI_PROP_DONTPASS, SS2_LUN0_TGT_LIST_PROP, 939 &tgt_list, &tgt_nelements) != DDI_PROP_SUCCESS) { 940 /* 941 * no list, so it must be okay to probe this target.LUN 942 */ 943 SCSI_PROBE_DEBUG0(3, 944 "SCSA pre-probe: NO parent prop found\n"); 945 } else { 946 for (i = 0; i < tgt_nelements; i++) { 947 if (tgt_list[i] == ap->a_target) { 948 /* 949 * we found a match, which means we do *NOT* 950 * want to probe the specified target.LUN 951 */ 952 ret_val = 1; 953 break; 954 } 955 } 956 ddi_prop_free(tgt_list); 957 #ifdef DEBUG 958 if (ret_val == 1) { 959 SCSI_PROBE_DEBUG2(1, 960 "SCSA pre-probe: marker node FOUND for " 961 "tgt.LUN=%d.%d, so SKIPPING it\n", 962 ap->a_target, ap->a_lun); 963 } else { 964 SCSI_PROBE_DEBUG0(2, 965 "SCSA pre-probe: NO marker node found" 966 " -- OK to probe\n"); 967 } 968 #endif 969 } 970 return (ret_val); 971 } 972 973 974 /* 975 * this routine is called from near the end of scsi_probe(), 976 * to see if the just-probed node is on our list of strictly-SCSI-2 nodes, 977 * and if it is we mark our parent node with this information 978 */ 979 static void 980 scsi_establish_LUN_limit(struct scsi_device *devp) 981 { 982 struct scsi_address *ap = &(devp->sd_address); 983 struct scsi_inquiry *inq = devp->sd_inq; 984 dev_info_t *devi = devp->sd_dev; 985 char *vid = NULL; 986 char *pid = NULL; 987 char *rev = NULL; 988 int i; 989 const ss2_lun0_info_t *p; 990 int bad_target_found = 0; 991 992 993 /* 994 * if this inquiry data shows that we have a strictly-SCSI-2 device 995 * at LUN 0, then add it to our list of strictly-SCSI-2 devices, 996 * so that we can avoid probes where LUN>7 on this device later 997 */ 998 if ((ap->a_lun != 0) || 999 (ap->a_target >= NTARGETS_WIDE) || 1000 (inq->inq_dtype != DTYPE_PROCESSOR) || 1001 (inq->inq_ansi != 2)) { 1002 /* 1003 * this can't possibly be a node we want to look at, since 1004 * either LUN is greater than 0, target is greater than or 1005 * eqaual to 16, device type 1006 * is not processor, or SCSI level is not SCSI-2, 1007 * so don't bother checking for a strictly SCSI-2 1008 * (only 8 LUN) target 1009 */ 1010 return; /* don't care */ 1011 } 1012 1013 SCSI_PROBE_DEBUG2(1, "SCSA post-probe: LUN limit on tgt.LUN=%d.%d, " 1014 "SCSI-2 PROCESSOR?\n", ap->a_target, ap->a_lun); 1015 1016 ASSERT(devi != NULL); 1017 1018 /* 1019 * we have a node that has been probed that is: LUN=0, target<16, 1020 * PROCESSOR-type SCSI target, and at the SCSI-2 level, so 1021 * check INQ properties to see if it's in our list of strictly 1022 * SCSI-2 targets 1023 * 1024 * first we have to get the VID/PID/REV INQUIRY properties for 1025 * comparison 1026 */ 1027 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, 1028 INQUIRY_VENDOR_ID, &vid) != DDI_PROP_SUCCESS) { 1029 SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n", 1030 INQUIRY_VENDOR_ID); 1031 goto dun; 1032 } 1033 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, 1034 INQUIRY_PRODUCT_ID, &pid) != DDI_PROP_SUCCESS) { 1035 SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n", 1036 INQUIRY_PRODUCT_ID); 1037 goto dun; 1038 } 1039 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, 1040 INQUIRY_REVISION_ID, &rev) != DDI_PROP_SUCCESS) { 1041 SCSI_PROBE_DEBUG1(2, "SCSA post-probe: prop \"%s\" missing\n", 1042 INQUIRY_REVISION_ID); 1043 goto dun; 1044 } 1045 1046 SCSI_PROBE_DEBUG3(3, "SCSA post-probe: looking for vid/pid/rev = " 1047 "\"%s\"/\"%s\"/\"%s\"\n", vid, pid, rev); 1048 1049 /* 1050 * now that we have the INQUIRY properties from the device node, 1051 * compare them with our known offenders 1052 * 1053 * Note: comparison is *CASE* *SENSITIVE* 1054 */ 1055 for (i = 0; i < scsi_probe_strict_s2_size; i++) { 1056 p = &scsi_probe_strict_s2_list[i]; 1057 1058 if ((strcmp(p->sli_vid, vid) == 0) && 1059 (strcmp(p->sli_pid, pid) == 0) && 1060 (strcmp(p->sli_rev, rev) == 0)) { 1061 /* 1062 * we found a match -- do NOT want to probe this one 1063 */ 1064 SCSI_PROBE_DEBUG3(1, 1065 "SCSA post-probe: recording strict SCSI-2 node " 1066 "vid/pid/rev = \"%s\"/\"%s\"/\"%s\"\n", 1067 vid, pid, rev); 1068 1069 /* 1070 * set/update private parent-node property, 1071 * so we can find out about this node later 1072 */ 1073 bad_target_found = 1; 1074 break; 1075 } 1076 } 1077 1078 /* 1079 * either add remove target number from parent property 1080 */ 1081 scsi_update_parent_ss2_prop(devi, ap->a_target, bad_target_found); 1082 1083 dun: 1084 if (vid != NULL) { 1085 ddi_prop_free(vid); 1086 } 1087 if (pid != NULL) { 1088 ddi_prop_free(pid); 1089 } 1090 if (rev != NULL) { 1091 ddi_prop_free(rev); 1092 } 1093 } 1094 1095 1096 /* 1097 * update the parent node to add in the supplied tgt number to the target 1098 * list property already present (if any) 1099 * 1100 * since the target list can never be longer than 16, and each target 1101 * number is also small, we can save having to alloc memory by putting 1102 * a 16-byte array on the stack and using it for property memory 1103 * 1104 * if "add_tgt" is set then add the target to the parent's property, else 1105 * remove it (if present) 1106 */ 1107 static void 1108 scsi_update_parent_ss2_prop(dev_info_t *devi, int tgt, int add_tgt) 1109 { 1110 dev_info_t *pdevi = (dev_info_t *)DEVI(devi)->devi_parent; 1111 uchar_t *tgt_list; 1112 uint_t nelements; 1113 uint_t new_nelements; 1114 int i; 1115 int update_result; 1116 uchar_t new_tgt_list[NTARGETS_WIDE]; 1117 1118 1119 ASSERT(pdevi != NULL); 1120 1121 SCSI_PROBE_DEBUG3(3, 1122 "SCSA post-probe: updating parent=%s property to %s tgt=%d\n", 1123 ddi_node_name(pdevi), add_tgt ? "add" : "remove", tgt); 1124 1125 if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, pdevi, DDI_PROP_DONTPASS, 1126 SS2_LUN0_TGT_LIST_PROP, &tgt_list, &nelements) == 1127 DDI_PROP_SUCCESS) { 1128 1129 if (add_tgt) { 1130 /* 1131 * we found an existing property -- we might need 1132 * to add to it 1133 */ 1134 for (i = 0; i < nelements; i++) { 1135 if (tgt_list[i] == tgt) { 1136 /* target already in list */ 1137 SCSI_PROBE_DEBUG1(2, "SCSA post-probe:" 1138 " tgt %d already listed\n", tgt); 1139 ddi_prop_free(tgt_list); 1140 return; 1141 } 1142 } 1143 1144 /* 1145 * need to append our target number to end of list 1146 * (no need sorting list, as it's so short) 1147 */ 1148 1149 /* 1150 * will this new entry fit ?? -- it should, since 1151 * the array is 16-wide and only keep track of 1152 * 16 targets, but check just in case 1153 */ 1154 new_nelements = nelements + 1; 1155 if (new_nelements >= NTARGETS_WIDE) { 1156 SCSI_PROBE_DEBUG0(1, "SCSA post-probe: " 1157 "internal error: no room " 1158 "for more targets?\n"); 1159 ddi_prop_free(tgt_list); 1160 return; 1161 } 1162 1163 /* copy existing list then add our tgt number to end */ 1164 bcopy((void *)tgt_list, (void *)new_tgt_list, 1165 sizeof (uchar_t) * nelements); 1166 new_tgt_list[new_nelements - 1] = (uchar_t)tgt; 1167 } else { 1168 /* 1169 * we need to remove our target number from the list, 1170 * so copy all of the other target numbers, 1171 * skipping ours 1172 */ 1173 int tgt_removed = 0; 1174 1175 new_nelements = 0; 1176 for (i = 0; i < nelements; i++) { 1177 if (tgt_list[i] != tgt) { 1178 new_tgt_list[new_nelements++] = 1179 tgt_list[i]; 1180 } else { 1181 /* skip this target */ 1182 tgt_removed++; 1183 } 1184 } 1185 1186 if (!tgt_removed) { 1187 SCSI_PROBE_DEBUG1(2, "SCSA post-probe:" 1188 " no need to remove tgt %d\n", tgt); 1189 ddi_prop_free(tgt_list); 1190 return; 1191 } 1192 } 1193 1194 update_result = ddi_prop_update_byte_array(DDI_DEV_T_NONE, 1195 pdevi, SS2_LUN0_TGT_LIST_PROP, new_tgt_list, 1196 new_nelements); 1197 1198 ddi_prop_free(tgt_list); 1199 } else { 1200 /* 1201 * no property yet 1202 */ 1203 if (add_tgt) { 1204 /* 1205 * create a property with just our tgt 1206 */ 1207 new_tgt_list[0] = (uchar_t)tgt; 1208 new_nelements = 1; /* just one element */ 1209 1210 update_result = ddi_prop_update_byte_array( 1211 DDI_DEV_T_NONE, pdevi, SS2_LUN0_TGT_LIST_PROP, 1212 new_tgt_list, new_nelements); 1213 } else { 1214 /* 1215 * no list so no need to remove tgt from that list 1216 */ 1217 return; 1218 } 1219 } 1220 1221 #ifdef DEBUG 1222 /* 1223 * if we get here we have tried to add/update properties 1224 */ 1225 if (update_result != DDI_PROP_SUCCESS) { 1226 SCSI_PROBE_DEBUG2(1, "SCSA post-probe: can't update parent " 1227 "property with tgt=%d (%d)\n", tgt, update_result); 1228 } else { 1229 if (add_tgt) { 1230 SCSI_PROBE_DEBUG3(2, 1231 "SCSA post-probe: added tgt=%d to parent " 1232 "prop=\"%s\" (now %d entries)\n", 1233 tgt, SS2_LUN0_TGT_LIST_PROP, new_nelements); 1234 } else { 1235 SCSI_PROBE_DEBUG3(2, 1236 "SCSA post-probe: removed tgt=%d from parent " 1237 "prop=\"%s\" (now %d entries)\n", 1238 tgt, SS2_LUN0_TGT_LIST_PROP, new_nelements); 1239 } 1240 } 1241 #endif 1242 } 1243