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