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