1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/ksynch.h> 28 #include <sys/ddi.h> 29 #include <sys/sunddi.h> 30 #include <sys/note.h> 31 #include <sys/scsi/scsi.h> 32 #include <sys/scsi/adapters/blk2scsa.h> 33 34 /* 35 * We implement the following SCSI-2 commands on behalf of targets: 36 * 37 * SCMD_DOORLOCK 38 * SCMD_FORMAT 39 * SCMD_INQUIRY 40 * SCMD_MODE_SENSE 41 * SCMD_READ 42 * SCMD_READ_G1 43 * SCMD_READ_CAPACITY 44 * SCMD_RELEASE 45 * SCMD_REQUEST_SENSE 46 * SCMD_RESERVE 47 * SCMD_SDIAG 48 * SCMD_START_STOP 49 * SCMD_TEST_UNIT_READY 50 * SCMD_WRITE 51 * SCMD_WRITE_G1 52 * 53 * We really should, at some point in the future, investigate offering 54 * more complete SCSI-3 commands, including the G4 and G5 variants of 55 * READ and WRITE, MODE_SELECT, PERSISTENT_RESERVE_IN, 56 * PERSISTENT_RESERVE_OUT, SYNCHRONIZE_CACHE, READ_MEDIAL_SERIAL, 57 * REPORT_LUNS, etc. 58 */ 59 60 typedef struct b2s_request_impl b2s_request_impl_t; 61 62 struct b2s_request_impl { 63 b2s_request_t ri_public; 64 struct scsi_pkt *ri_pkt; 65 struct scsi_arq_status *ri_sts; 66 buf_t *ri_bp; 67 68 size_t ri_resid; 69 b2s_nexus_t *ri_nexus; 70 b2s_leaf_t *ri_leaf; 71 void (*ri_done)(struct b2s_request_impl *); 72 }; 73 74 #define ri_lun ri_public.br_lun 75 #define ri_target ri_public.br_target 76 #define ri_cmd ri_public.br_cmd 77 #define ri_errno ri_public.br_errno 78 #define ri_count ri_public.br_count 79 #define ri_xfered ri_public.br_xfered 80 81 #define ri_flags ri_public.br_flags 82 #define ri_media ri_public.br_media 83 #define ri_inquiry ri_public.br_inquiry 84 #define ri_lba ri_public.br_lba 85 #define ri_nblks ri_public.br_nblks 86 87 struct b2s_nexus { 88 dev_info_t *n_dip; 89 struct scsi_hba_tran *n_tran; 90 void *n_private; 91 ddi_dma_attr_t *n_dma; 92 boolean_t (*n_request)(void *, b2s_request_t *); 93 94 kmutex_t n_lock; 95 kcondvar_t n_cv; 96 boolean_t n_attached; 97 list_t n_leaves; 98 }; 99 #define B2S_NEXUS_ATTACHED (1U << 0) 100 101 _NOTE(MUTEX_PROTECTS_DATA(b2s_nexus::n_lock, b2s_nexus::n_leaves)) 102 _NOTE(SCHEME_PROTECTS_DATA("stable data", b2s_nexus::n_dip)) 103 _NOTE(SCHEME_PROTECTS_DATA("stable data", b2s_nexus::n_private)) 104 _NOTE(SCHEME_PROTECTS_DATA("stable data", b2s_nexus::n_request)) 105 _NOTE(SCHEME_PROTECTS_DATA("stable data", b2s_nexus::n_dma)) 106 _NOTE(SCHEME_PROTECTS_DATA("stable data", b2s_nexus::n_tran)) 107 _NOTE(SCHEME_PROTECTS_DATA("client synchronized", b2s_nexus::n_attached)) 108 109 struct b2s_leaf { 110 b2s_nexus_t *l_nexus; 111 uint_t l_target; 112 uint_t l_lun; 113 uint32_t l_flags; 114 char *l_uuid; 115 uint32_t l_refcnt; 116 list_node_t l_node; 117 struct scsi_inquiry l_inq; 118 uint64_t l_eui; 119 }; 120 121 _NOTE(MUTEX_PROTECTS_DATA(b2s_nexus::n_lock, b2s_leaf::l_node)) 122 _NOTE(MUTEX_PROTECTS_DATA(b2s_nexus::n_lock, b2s_leaf::l_refcnt)) 123 _NOTE(MUTEX_PROTECTS_DATA(b2s_nexus::n_lock, b2s_leaf::l_uuid)) 124 _NOTE(MUTEX_PROTECTS_DATA(b2s_nexus::n_lock, b2s_leaf::l_lun)) 125 _NOTE(MUTEX_PROTECTS_DATA(b2s_nexus::n_lock, b2s_leaf::l_target)) 126 _NOTE(MUTEX_PROTECTS_DATA(b2s_nexus::n_lock, b2s_leaf::l_nexus)) 127 _NOTE(DATA_READABLE_WITHOUT_LOCK(b2s_leaf::l_uuid)) 128 _NOTE(DATA_READABLE_WITHOUT_LOCK(b2s_leaf::l_lun)) 129 _NOTE(DATA_READABLE_WITHOUT_LOCK(b2s_leaf::l_target)) 130 _NOTE(DATA_READABLE_WITHOUT_LOCK(b2s_leaf::l_nexus)) 131 132 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_hba_tran)) 133 _NOTE(SCHEME_PROTECTS_DATA("unshared data", b2s_request_impl)) 134 _NOTE(SCHEME_PROTECTS_DATA("unique per packet", scsi_arq_status)) 135 _NOTE(SCHEME_PROTECTS_DATA("unique per packet", scsi_pkt)) 136 _NOTE(SCHEME_PROTECTS_DATA("unique per packet", scsi_inquiry)) 137 _NOTE(SCHEME_PROTECTS_DATA("client synchronized", b2s_leaf::l_flags)) 138 139 /* 140 * This copies a string into a target buf, obeying the size limits 141 * of the target. It does not null terminate, ever. 142 */ 143 #define COPYSTR(src, dst) bcopy(src, dst, min(strlen(src), sizeof (dst))) 144 145 /* 146 * Thank you SCSA, for making it a PITA to deal with a single byte 147 * value by turning it into a bitfield! 148 */ 149 #define PUTSTAT(dst, val) (*((uint8_t *)(void *)&dst) = val) 150 151 struct b2s_error { 152 uint8_t e_reason; /* scsi CMD_xxx reason */ 153 uint8_t e_status; /* scsi STATUS_xxx code */ 154 uint8_t e_skey; /* sense key */ 155 uint8_t e_asc; /* additional sense code */ 156 uint8_t e_ascq; /* sense code qualifier */ 157 uint8_t e_sksv[3]; /* sense key specific-value */ 158 }; 159 160 static struct b2s_error b2s_errs[B2S_NERRS]; 161 162 static struct modlmisc modlmisc = { 163 &mod_miscops, 164 "SCSA Block Device Emulation", 165 }; 166 167 static struct modlinkage modlinkage = { 168 MODREV_1, { &modlmisc, NULL } 169 }; 170 171 /* 172 * For layers that don't provide a DMA attribute, we offer a default 173 * one. Such devices probably just want to do mapin, all of the time, 174 * but since SCSI doesn't give us a way to indicate that, we have to 175 * provide a fake attribute. Slightly wasteful, but PIO-only disk 176 * devices are going to have some performance issues anyway. 177 * 178 * For such devices, we only want to commit to transferring 64K at a time, 179 * and let the SCSA layer break it up for us. 180 */ 181 static struct ddi_dma_attr b2s_default_dma_attr = { 182 DMA_ATTR_V0, 183 0, /* lo address */ 184 0xffffffffffffffffULL, /* high address */ 185 0xffffU, /* DMA counter max */ 186 1, /* alignment */ 187 0x0c, /* burst sizes */ 188 1, /* minimum transfer size */ 189 0xffffU, /* maximum transfer size */ 190 0xffffU, /* maximum segment size */ 191 1, /* scatter/gather list length */ 192 1, /* granularity */ 193 0 /* DMA flags */ 194 }; 195 196 197 /* 198 * Private prototypes. 199 */ 200 201 static int b2s_tran_tgt_init(dev_info_t *, dev_info_t *, 202 scsi_hba_tran_t *, struct scsi_device *); 203 static void b2s_tran_tgt_free(dev_info_t *, dev_info_t *, 204 scsi_hba_tran_t *, struct scsi_device *); 205 static int b2s_tran_getcap(struct scsi_address *, char *, int); 206 static int b2s_tran_setcap(struct scsi_address *, char *, int, int); 207 static void b2s_tran_destroy_pkt(struct scsi_address *, struct scsi_pkt *); 208 static struct scsi_pkt *b2s_tran_init_pkt(struct scsi_address *, 209 struct scsi_pkt *, struct buf *, int, int, int, int, 210 int (*)(caddr_t), caddr_t); 211 static int b2s_tran_start(struct scsi_address *, struct scsi_pkt *); 212 static int b2s_tran_abort(struct scsi_address *, struct scsi_pkt *); 213 static int b2s_tran_reset(struct scsi_address *, int); 214 static int b2s_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t, void *, 215 dev_info_t **); 216 static b2s_leaf_t *b2s_hold_leaf(b2s_nexus_t *, uint_t, uint_t); 217 static dev_info_t *b2s_find_node(b2s_nexus_t *, b2s_leaf_t *); 218 static int b2s_create_node(b2s_nexus_t *, b2s_leaf_t *, dev_info_t **); 219 static int b2s_update_props(dev_info_t *, b2s_leaf_t *, char **, int); 220 static void b2s_inquiry_done(b2s_request_impl_t *); 221 static int b2s_inquiry(b2s_leaf_t *); 222 static void b2s_init_err_table(void); 223 static int b2s_scmd_inq(b2s_request_impl_t *); 224 static int b2s_scmd_tur(b2s_request_impl_t *); 225 static int b2s_scmd_doorlock(b2s_request_impl_t *); 226 static int b2s_scmd_format(b2s_request_impl_t *); 227 static int b2s_scmd_readcap(b2s_request_impl_t *); 228 static int b2s_scmd_rw(b2s_request_impl_t *); 229 static int b2s_scmd_rqs(b2s_request_impl_t *); 230 static int b2s_scmd_sdiag(b2s_request_impl_t *); 231 static int b2s_scmd_start_stop(b2s_request_impl_t *); 232 static int b2s_scmd_mode_sense(b2s_request_impl_t *); 233 static int b2s_scmd_reserve_release(b2s_request_impl_t *); 234 static void b2s_scmd_readcap_done(b2s_request_impl_t *); 235 static void b2s_scmd_mode_sense_done(b2s_request_impl_t *); 236 static void b2s_warn(b2s_leaf_t *, const char *, ...); 237 238 int 239 _init(void) 240 { 241 int rv; 242 243 b2s_init_err_table(); 244 rv = mod_install(&modlinkage); 245 return (rv); 246 } 247 248 int 249 _fini(void) 250 { 251 int rv; 252 253 rv = mod_remove(&modlinkage); 254 return (rv); 255 } 256 257 int 258 _info(struct modinfo *modinfop) 259 { 260 return (mod_info(&modlinkage, modinfop)); 261 } 262 263 int 264 b2s_mod_init(struct modlinkage *modlp) 265 { 266 return (scsi_hba_init(modlp)); 267 } 268 269 void 270 b2s_mod_fini(struct modlinkage *modlp) 271 { 272 scsi_hba_fini(modlp); 273 } 274 275 void 276 b2s_init_err_table(void) 277 { 278 int i; 279 280 /* fill up most of them with defaults */ 281 for (i = 0; i < B2S_NERRS; i++) { 282 b2s_errs[i].e_reason = CMD_CMPLT; 283 b2s_errs[i].e_status = STATUS_CHECK; 284 b2s_errs[i].e_skey = KEY_NO_SENSE; 285 b2s_errs[i].e_asc = 0; 286 b2s_errs[i].e_ascq = 0; 287 b2s_errs[i].e_sksv[0] = 0; 288 b2s_errs[i].e_sksv[1] = 0; 289 b2s_errs[i].e_sksv[2] = 0; 290 } 291 292 /* now flesh out real values */ 293 b2s_errs[B2S_EOK].e_status = STATUS_GOOD; 294 295 b2s_errs[B2S_ENOTSUP].e_skey = KEY_ILLEGAL_REQUEST; 296 b2s_errs[B2S_ENOTSUP].e_asc = 0x20; 297 298 b2s_errs[B2S_EFORMATTING].e_skey = KEY_NOT_READY; 299 b2s_errs[B2S_EFORMATTING].e_asc = 0x04; 300 b2s_errs[B2S_EFORMATTING].e_ascq = 0x04; 301 b2s_errs[B2S_EFORMATTING].e_sksv[0] = 0x80; 302 303 b2s_errs[B2S_ENOMEDIA].e_skey = KEY_NOT_READY; 304 b2s_errs[B2S_ENOMEDIA].e_asc = 0x3A; 305 306 b2s_errs[B2S_EMEDIACHG].e_skey = KEY_UNIT_ATTENTION; 307 b2s_errs[B2S_EMEDIACHG].e_asc = 0x28; 308 309 b2s_errs[B2S_ESTOPPED].e_skey = KEY_NOT_READY; 310 b2s_errs[B2S_ESTOPPED].e_asc = 0x04; 311 b2s_errs[B2S_ESTOPPED].e_ascq = 0x02; 312 313 b2s_errs[B2S_EBLKADDR].e_skey = KEY_ILLEGAL_REQUEST; 314 b2s_errs[B2S_EBLKADDR].e_asc = 0x21; 315 316 b2s_errs[B2S_EIO].e_skey = KEY_HARDWARE_ERROR; 317 b2s_errs[B2S_EIO].e_asc = 0x08; 318 b2s_errs[B2S_EIO].e_ascq = 0x00; 319 320 b2s_errs[B2S_EHARDWARE].e_skey = KEY_HARDWARE_ERROR; 321 b2s_errs[B2S_EHARDWARE].e_asc = 0x44; 322 323 b2s_errs[B2S_ENODEV].e_reason = CMD_DEV_GONE; 324 325 b2s_errs[B2S_EMEDIA].e_skey = KEY_MEDIUM_ERROR; 326 327 b2s_errs[B2S_EDOORLOCK].e_skey = KEY_NOT_READY; 328 b2s_errs[B2S_EDOORLOCK].e_asc = 0x53; 329 b2s_errs[B2S_EDOORLOCK].e_ascq = 0x02; 330 331 b2s_errs[B2S_EWPROTECT].e_skey = KEY_DATA_PROTECT; 332 b2s_errs[B2S_EWPROTECT].e_asc = 0x27; 333 334 b2s_errs[B2S_ESTARTING].e_skey = KEY_NOT_READY; 335 b2s_errs[B2S_ESTARTING].e_asc = 0x04; 336 b2s_errs[B2S_ESTARTING].e_ascq = 0x01; 337 338 b2s_errs[B2S_ETIMEDOUT].e_skey = KEY_ABORTED_COMMAND; 339 b2s_errs[B2S_ETIMEDOUT].e_asc = 0x08; 340 b2s_errs[B2S_ETIMEDOUT].e_ascq = 0x01; 341 342 /* 343 * This one, SYSTEM_RESOURCE_FAILURE, is not really legal for 344 * DTYPE_DIRECT in SCSI-2, but sd doesn't care, and reporting 345 * it this way may help diagnosis. sd will retry it in any 346 * case. 347 */ 348 b2s_errs[B2S_ENOMEM].e_skey = KEY_ABORTED_COMMAND; 349 b2s_errs[B2S_ENOMEM].e_asc = 0x55; 350 351 b2s_errs[B2S_ERESET].e_reason = CMD_RESET; 352 353 b2s_errs[B2S_EABORT].e_reason = CMD_ABORTED; 354 355 b2s_errs[B2S_ERSVD].e_status = STATUS_RESERVATION_CONFLICT; 356 357 b2s_errs[B2S_EINVAL].e_skey = KEY_ILLEGAL_REQUEST; 358 b2s_errs[B2S_EINVAL].e_asc = 0x24; 359 360 b2s_errs[B2S_EPARAM].e_skey = KEY_ILLEGAL_REQUEST; 361 b2s_errs[B2S_EPARAM].e_asc = 0x26; 362 363 b2s_errs[B2S_EBADMSG].e_reason = CMD_BADMSG; 364 } 365 366 /* 367 * Locate the the leaf node for the given target/lun. This must be 368 * called with the nexus lock held. 369 */ 370 b2s_leaf_t * 371 b2s_get_leaf(b2s_nexus_t *n, uint_t target, uint_t lun) 372 { 373 b2s_leaf_t *l; 374 375 ASSERT(mutex_owned(&n->n_lock)); 376 377 l = list_head(&n->n_leaves); 378 while (l != NULL) { 379 ASSERT(l->l_nexus == n); 380 if ((l->l_target == target) && (l->l_lun == lun)) { 381 break; 382 } 383 l = list_next(&n->n_leaves, l); 384 } 385 386 return (l); 387 } 388 389 /* 390 * Locate the the leaf node for the given target/lun, and hold it. The 391 * nexus lock must *NOT* be held. 392 */ 393 b2s_leaf_t * 394 b2s_hold_leaf(b2s_nexus_t *n, uint_t target, uint_t lun) 395 { 396 b2s_leaf_t *l; 397 398 mutex_enter(&n->n_lock); 399 l = b2s_get_leaf(n, target, lun); 400 if (l != NULL) { 401 l->l_refcnt++; 402 } 403 mutex_exit(&n->n_lock); 404 return (l); 405 } 406 407 /* 408 * Drop the hold on the leaf. 409 */ 410 void 411 b2s_rele_leaf(b2s_leaf_t *l) 412 { 413 b2s_nexus_t *n = l->l_nexus; 414 mutex_enter(&n->n_lock); 415 l->l_refcnt--; 416 if (l->l_refcnt == 0) { 417 list_remove(&n->n_leaves, l); 418 kmem_free(l->l_uuid, strlen(l->l_uuid) + 1); 419 kmem_free(l, sizeof (*l)); 420 } 421 mutex_exit(&n->n_lock); 422 } 423 424 /* 425 * This is used to walk the list of leaves safely, without requiring the 426 * nexus lock to be held. The returned leaf is held. (If the passed in 427 * lastl is not NULL, then it is released as well.) 428 * 429 * Pass NULL for lastl to start the walk. 430 */ 431 b2s_leaf_t * 432 b2s_next_leaf(b2s_nexus_t *n, b2s_leaf_t *lastl) 433 { 434 b2s_leaf_t *l; 435 436 mutex_enter(&n->n_lock); 437 if (lastl == NULL) { 438 l = list_head(&n->n_leaves); 439 } else { 440 l = list_next(&n->n_leaves, lastl); 441 } 442 if (l != NULL) { 443 l->l_refcnt++; 444 } 445 mutex_exit(&n->n_lock); 446 447 if (lastl != NULL) { 448 b2s_rele_leaf(lastl); 449 } 450 451 return (l); 452 } 453 454 void 455 b2s_request_mapin(b2s_request_t *req, caddr_t *addrp, size_t *lenp) 456 { 457 b2s_request_impl_t *ri = (void *)req; 458 buf_t *bp; 459 460 if (((bp = ri->ri_bp) != NULL) && (bp->b_bcount != 0)) { 461 *addrp = bp->b_un.b_addr; 462 *lenp = bp->b_bcount; 463 } else { 464 *addrp = 0; 465 *lenp = 0; 466 } 467 } 468 469 void 470 b2s_request_dma(b2s_request_t *req, uint_t *ndmacp, ddi_dma_cookie_t **dmacsp) 471 { 472 /* 473 * Direct DMA support was removed; SCSA can't easily deal with 474 * HBAs that have restrictions which would require partial DMA 475 * to be used. 476 */ 477 _NOTE(ARGUNUSED(req)); 478 479 *ndmacp = 0; 480 *dmacsp = NULL; 481 } 482 483 void 484 b2s_request_done_pkt(b2s_request_impl_t *ri) 485 { 486 struct scsi_pkt *pkt; 487 uint8_t status; 488 struct scsi_arq_status *sts = ri->ri_sts; 489 b2s_err_t err; 490 491 err = ri->ri_errno; 492 493 pkt = ri->ri_pkt; 494 pkt->pkt_resid = ri->ri_resid; 495 496 bzero(sts, sizeof (*sts)); 497 498 /* 499 * Make sure that the status is in range of our known errs. If we 500 * don't know it, then just cobble up a bogus one. 501 */ 502 if ((err < 0) || (err >= B2S_NERRS)) { 503 pkt->pkt_reason = CMD_TRAN_ERR; 504 } else { 505 pkt->pkt_reason = b2s_errs[err].e_reason; 506 status = b2s_errs[err].e_status; 507 } 508 509 if (pkt->pkt_reason == CMD_CMPLT) { 510 511 pkt->pkt_state = STATE_GOT_BUS | STATE_GOT_TARGET | 512 STATE_SENT_CMD | STATE_GOT_STATUS; 513 514 PUTSTAT(sts->sts_status, status); 515 516 if (status == STATUS_CHECK) { 517 /* 518 * Contingent allegiance. We need to do the 519 * ARQ thing. 520 */ 521 PUTSTAT(sts->sts_rqpkt_status, STATUS_GOOD); 522 523 sts->sts_rqpkt_reason = CMD_CMPLT; 524 sts->sts_rqpkt_resid = 0; 525 sts->sts_rqpkt_state = STATE_XFERRED_DATA | 526 STATE_GOT_BUS | STATE_GOT_STATUS; 527 528 sts->sts_sensedata.es_valid = 1; 529 sts->sts_sensedata.es_class = CLASS_EXTENDED_SENSE; 530 sts->sts_sensedata.es_key = b2s_errs[err].e_skey; 531 sts->sts_sensedata.es_add_code = b2s_errs[err].e_asc; 532 sts->sts_sensedata.es_qual_code = b2s_errs[err].e_ascq; 533 bcopy(sts->sts_sensedata.es_skey_specific, 534 b2s_errs[err].e_sksv, 3); 535 /* 536 * Stash any residue information. 537 */ 538 sts->sts_sensedata.es_info_1 = 539 (ri->ri_resid >> 24) & 0xff; 540 sts->sts_sensedata.es_info_2 = 541 (ri->ri_resid >> 16) & 0xff; 542 sts->sts_sensedata.es_info_3 = 543 (ri->ri_resid >> 8) & 0xff; 544 sts->sts_sensedata.es_info_4 = 545 (ri->ri_resid) & 0xff; 546 547 pkt->pkt_state |= STATE_ARQ_DONE; 548 } 549 550 } else if (pkt->pkt_reason == CMD_ABORTED) { 551 pkt->pkt_statistics |= STAT_ABORTED; 552 } else if (pkt->pkt_reason == CMD_RESET) { 553 pkt->pkt_statistics |= STAT_DEV_RESET; 554 } else { 555 pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET | 556 STATE_SENT_CMD; 557 } 558 559 /* 560 * N.B.: Obviously not all commands actually have a SCSI 561 * DATA-IN or DATA-OUT phase. But it doesn't matter, since 562 * sd.c only bothers to look at this flag for request sense 563 * traffic, which is always correct within our emulation. 564 * 565 * We go ahead and set it on all good packets however, since 566 * there may in the future be some additional checks to make 567 * sure a data transfer occurred. This seems safer (since 568 * then sd should examine pkt_resid) rather than leaving it 569 * off by default. 570 */ 571 if (ri->ri_errno == 0) { 572 pkt->pkt_state |= STATE_XFERRED_DATA; 573 } 574 575 /* 576 * Finally, execute the callback (unless running POLLED) 577 */ 578 if ((pkt->pkt_flags & FLAG_NOINTR) == 0) { 579 scsi_hba_pkt_comp(pkt); 580 } 581 582 } 583 584 void 585 b2s_request_done(b2s_request_t *req, b2s_err_t err, size_t resid) 586 { 587 b2s_request_impl_t *ri = (void *)req; 588 589 ri->ri_errno = err; 590 ri->ri_resid = (ssize_t)resid; 591 592 /* 593 * Post process... this is used for massaging results into 594 * what SCSI wants. 595 */ 596 if (ri->ri_done != NULL) 597 ri->ri_done(ri); 598 599 /* 600 * For SCSI packets, we have special completion handling. For 601 * internal requests, we just mark the request done so the caller 602 * can free it. 603 */ 604 if (ri->ri_pkt == NULL) { 605 b2s_nexus_t *n = ri->ri_nexus; 606 607 mutex_enter(&n->n_lock); 608 ri->ri_flags |= B2S_REQUEST_FLAG_DONE; 609 cv_broadcast(&n->n_cv); 610 mutex_exit(&n->n_lock); 611 } else { 612 b2s_request_done_pkt(ri); 613 } 614 } 615 616 int 617 b2s_tran_tgt_init(dev_info_t *hbadip, dev_info_t *tgtdip, 618 scsi_hba_tran_t *tran, struct scsi_device *sd) 619 { 620 uint_t tgt, lun; 621 b2s_nexus_t *n; 622 b2s_leaf_t *l; 623 624 _NOTE(ARGUNUSED(hbadip)); 625 _NOTE(ARGUNUSED(sd)); 626 627 /* 628 * Lookup the target and lun. 629 */ 630 tgt = (uint_t)ddi_prop_get_int(DDI_DEV_T_ANY, tgtdip, 631 DDI_PROP_DONTPASS, "target", -1); 632 633 lun = (uint_t)ddi_prop_get_int(DDI_DEV_T_ANY, tgtdip, 634 DDI_PROP_DONTPASS, "lun", -1); 635 636 n = tran->tran_hba_private; 637 638 /* 639 * Hold the leaf node as long as the devinfo node is using it. 640 */ 641 l = b2s_hold_leaf(n, tgt, lun); 642 if (l == NULL) { 643 /* 644 * Target node not found on bus. 645 */ 646 return (DDI_FAILURE); 647 } 648 tran->tran_tgt_private = l; 649 650 return (DDI_SUCCESS); 651 } 652 653 void 654 b2s_tran_tgt_free(dev_info_t *hbadip, dev_info_t *tgtdip, 655 scsi_hba_tran_t *tran, struct scsi_device *sd) 656 { 657 b2s_leaf_t *l; 658 659 _NOTE(ARGUNUSED(hbadip)); 660 _NOTE(ARGUNUSED(tgtdip)); 661 _NOTE(ARGUNUSED(sd)); 662 663 l = tran->tran_tgt_private; 664 ASSERT(l != NULL); 665 b2s_rele_leaf(l); 666 } 667 668 struct scsi_pkt * 669 b2s_tran_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 670 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 671 int (*cb)(caddr_t), caddr_t cbarg) 672 { 673 dev_info_t *dip; 674 scsi_hba_tran_t *tran; 675 b2s_request_impl_t *ri; 676 677 _NOTE(ARGUNUSED(cbarg)); 678 _NOTE(ARGUNUSED(flags)); 679 680 tran = ap->a_hba_tran; 681 dip = tran->tran_hba_dip; 682 683 /* 684 * Unconditional mapin for now, so we will always have kernel 685 * virtual addresses to work with. 686 */ 687 if (bp && (bp->b_bcount)) { 688 bp_mapin(bp); 689 } 690 691 if (pkt == NULL) { 692 /* we can only support these two kinds of callbacks */ 693 cb = (cb == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 694 pkt = scsi_hba_pkt_alloc(dip, ap, cmdlen, statuslen, 695 tgtlen, sizeof (b2s_request_impl_t), cb, NULL); 696 if (pkt == NULL) 697 return (NULL); 698 699 ri = pkt->pkt_ha_private; 700 ri->ri_pkt = pkt; 701 ri->ri_sts = (void *)pkt->pkt_scbp; 702 ri->ri_bp = bp; 703 } 704 705 return (pkt); 706 } 707 708 void 709 b2s_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 710 { 711 scsi_hba_pkt_free(ap, pkt); 712 } 713 714 int 715 b2s_tran_getcap(struct scsi_address *ap, char *cap, int whom) 716 { 717 int capid; 718 719 _NOTE(ARGUNUSED(ap)); 720 _NOTE(ARGUNUSED(whom)); 721 722 capid = scsi_hba_lookup_capstr(cap); 723 724 switch (capid) { 725 case SCSI_CAP_ARQ: 726 case SCSI_CAP_UNTAGGED_QING: 727 return (1); 728 case SCSI_CAP_DMA_MAX: 729 return (65536); 730 731 default: 732 return (-1); 733 } 734 } 735 736 int 737 b2s_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 738 { 739 b2s_request_impl_t *ri; 740 b2s_nexus_t *n = ap->a_hba_tran->tran_hba_private; 741 b2s_leaf_t *l = ap->a_hba_tran->tran_tgt_private; 742 int err; 743 744 /* 745 * We can only do the blind abort of all packets. We have 746 * no way to request an individual packet be aborted. 747 */ 748 if (pkt != NULL) { 749 return (B_FALSE); 750 } 751 752 ri = kmem_zalloc(sizeof (*ri), KM_NOSLEEP); 753 if (ri == NULL) { 754 return (B_FALSE); 755 } 756 ri->ri_cmd = B2S_CMD_ABORT; 757 ri->ri_target = l->l_target; 758 ri->ri_lun = l->l_lun; 759 ri->ri_flags = B2S_REQUEST_FLAG_HEAD; 760 ri->ri_leaf = l; 761 ri->ri_nexus = n; 762 /* leave all else null */ 763 764 /* 765 * Submit request to device driver. 766 */ 767 if (!n->n_request(n->n_private, &ri->ri_public)) { 768 /* this shouldn't happen, since we are just starting out */ 769 b2s_warn(l, "Busy trying to abort"); 770 kmem_free(ri, sizeof (*ri)); 771 return (B_FALSE); 772 } 773 774 /* 775 * Wait for command completion. 776 */ 777 mutex_enter(&n->n_lock); 778 while ((ri->ri_flags & B2S_REQUEST_FLAG_DONE) == 0) 779 cv_wait(&n->n_cv, &n->n_lock); 780 mutex_exit(&n->n_lock); 781 782 err = ri->ri_errno; 783 kmem_free(ri, sizeof (*ri)); 784 785 if (err != 0) { 786 b2s_warn(l, "Failed during abort (error %d)", err); 787 return (B_FALSE); 788 } 789 790 return (B_TRUE); 791 } 792 793 int 794 b2s_tran_reset(struct scsi_address *ap, int level) 795 { 796 b2s_request_impl_t *ri; 797 b2s_nexus_t *n = ap->a_hba_tran->tran_hba_private; 798 b2s_leaf_t *l = ap->a_hba_tran->tran_tgt_private; 799 int err; 800 801 if (level == RESET_LUN) { 802 return (B_FALSE); 803 } 804 805 ri = kmem_zalloc(sizeof (*ri), KM_NOSLEEP); 806 if (ri == NULL) { 807 return (B_FALSE); 808 } 809 ri->ri_cmd = B2S_CMD_RESET; 810 ri->ri_target = l->l_target; 811 ri->ri_lun = l->l_lun; 812 ri->ri_flags = B2S_REQUEST_FLAG_HEAD; 813 ri->ri_leaf = l; 814 ri->ri_nexus = n; 815 /* leave all else null */ 816 817 /* 818 * Submit request to device driver. 819 */ 820 if (!n->n_request(n->n_private, &ri->ri_public)) { 821 /* this shouldn't happen, since we are just starting out */ 822 b2s_warn(l, "Busy trying to reset"); 823 kmem_free(ri, sizeof (*ri)); 824 return (B_FALSE); 825 } 826 827 /* 828 * Wait for command completion. 829 */ 830 mutex_enter(&n->n_lock); 831 while ((ri->ri_flags & B2S_REQUEST_FLAG_DONE) == 0) 832 cv_wait(&n->n_cv, &n->n_lock); 833 mutex_exit(&n->n_lock); 834 835 err = ri->ri_errno; 836 kmem_free(ri, sizeof (*ri)); 837 838 if (err != 0) { 839 b2s_warn(l, "Failed during reset (error %d)", err); 840 return (B_FALSE); 841 } 842 843 return (B_TRUE); 844 } 845 846 int 847 b2s_tran_setcap(struct scsi_address *ap, char *cap, int val, int whom) 848 { 849 int capid; 850 851 _NOTE(ARGUNUSED(ap)); 852 _NOTE(ARGUNUSED(val)); 853 _NOTE(ARGUNUSED(whom)); 854 855 capid = scsi_hba_lookup_capstr(cap); 856 857 switch (capid) { 858 case SCSI_CAP_ARQ: 859 if (val == 0) { 860 return (0); 861 } else { 862 return (1); 863 } 864 865 default: 866 return (-1); 867 } 868 } 869 870 int 871 b2s_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt) 872 { 873 b2s_request_impl_t *ri = pkt->pkt_ha_private; 874 b2s_nexus_t *n = ap->a_hba_tran->tran_hba_private; 875 b2s_leaf_t *l = ap->a_hba_tran->tran_tgt_private; 876 877 ri->ri_errno = B2S_EOK; 878 ri->ri_resid = 0; 879 bzero(&ri->ri_public.br_args, sizeof (ri->ri_public.br_args)); 880 ri->ri_flags = 0; 881 ri->ri_done = NULL; 882 883 if ((n == NULL) || (l == NULL) || 884 ((l->l_flags & B2S_LEAF_DETACHED) != 0)) { 885 /* 886 * Leaf is not on the bus! 887 * 888 * We should add support for inquiry when lun != 0, 889 * even if when the lun does not exist, but lun 0 is 890 * present. But, it turns out this is not strictly 891 * required by sd(7d). 892 */ 893 b2s_request_done(&ri->ri_public, B2S_ENODEV, 0); 894 return (TRAN_ACCEPT); 895 } 896 897 ri->ri_nexus = n; 898 ri->ri_leaf = l; 899 ri->ri_target = l->l_target; 900 ri->ri_lun = l->l_lun; 901 902 if (pkt->pkt_flags & FLAG_NOINTR) 903 ri->ri_flags |= B2S_REQUEST_FLAG_POLL; 904 if (pkt->pkt_flags & FLAG_HEAD) 905 ri->ri_flags |= B2S_REQUEST_FLAG_HEAD; 906 907 switch (pkt->pkt_cdbp[0]) { 908 case SCMD_DOORLOCK: 909 return (b2s_scmd_doorlock(ri)); 910 911 case SCMD_FORMAT: 912 return (b2s_scmd_format(ri)); 913 914 case SCMD_INQUIRY: 915 return (b2s_scmd_inq(ri)); 916 917 case SCMD_REQUEST_SENSE: 918 return (b2s_scmd_rqs(ri)); 919 920 case SCMD_SDIAG: 921 return (b2s_scmd_sdiag(ri)); 922 923 case SCMD_TEST_UNIT_READY: 924 return (b2s_scmd_tur(ri)); 925 926 case SCMD_READ_CAPACITY: 927 return (b2s_scmd_readcap(ri)); 928 929 case SCMD_RELEASE: 930 case SCMD_RESERVE: 931 return (b2s_scmd_reserve_release(ri)); 932 933 case SCMD_START_STOP: 934 return (b2s_scmd_start_stop(ri)); 935 936 case SCMD_MODE_SENSE: 937 return (b2s_scmd_mode_sense(ri)); 938 939 case SCMD_READ: 940 case SCMD_READ_G1: 941 case SCMD_WRITE: 942 case SCMD_WRITE_G1: 943 return (b2s_scmd_rw(ri)); 944 945 default: 946 b2s_request_done(&ri->ri_public, B2S_ENOTSUP, 0); 947 return (TRAN_ACCEPT); 948 } 949 } 950 951 /* 952 * Publish standard properties on a newly created devinfo node. 953 */ 954 int 955 b2s_update_props(dev_info_t *dip, b2s_leaf_t *l, char **compat, int ncompat) 956 { 957 if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, "target", l->l_target) != 958 DDI_PROP_SUCCESS) { 959 return (DDI_FAILURE); 960 } 961 if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, "lun", l->l_lun) != 962 DDI_PROP_SUCCESS) { 963 return (DDI_FAILURE); 964 } 965 if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, "pm-capable", 1) != 966 DDI_PROP_SUCCESS) { 967 return (DDI_FAILURE); 968 } 969 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, "compatible", 970 compat, ncompat) != DDI_PROP_SUCCESS) { 971 return (DDI_FAILURE); 972 } 973 if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, "unique-id", 974 l->l_uuid) != DDI_PROP_SUCCESS) { 975 return (DDI_FAILURE); 976 } 977 978 if (l->l_flags & B2S_LEAF_HOTPLUGGABLE) { 979 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, dip, 980 "hotpluggable") != DDI_PROP_SUCCESS) { 981 return (DDI_FAILURE); 982 } 983 } 984 985 return (DDI_SUCCESS); 986 } 987 988 /* 989 * Find the devinfo node associated with the leaf, looking up by target and 990 * lun. (Alternatively in the future we could use a full address) 991 * 992 * This must be called with the tree lock held. 993 */ 994 dev_info_t * 995 b2s_find_node(b2s_nexus_t *n, b2s_leaf_t *l) 996 { 997 dev_info_t *dip; 998 int tgt, lun; 999 1000 dip = ddi_get_child(n->n_dip); 1001 while (dip != NULL) { 1002 1003 tgt = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1004 DDI_PROP_DONTPASS, "target", -1); 1005 1006 lun = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1007 DDI_PROP_DONTPASS, "lun", -1); 1008 1009 /* is this the right target */ 1010 if ((lun == l->l_lun) && (tgt == l->l_target)) { 1011 return (dip); 1012 } 1013 1014 dip = ddi_get_next_sibling(dip); 1015 } 1016 1017 return (NULL); 1018 1019 } 1020 1021 /* 1022 * Create and attach a devinfo node for the supplied nexus/leaf 1023 * combination. 1024 */ 1025 int 1026 b2s_create_node(b2s_nexus_t *n, b2s_leaf_t *l, dev_info_t **dipp) 1027 { 1028 dev_info_t *dip; 1029 char *name; 1030 char **compat; 1031 int ncompat; 1032 int rv; 1033 1034 /* 1035 * If the node was already created, then we're done. 1036 */ 1037 if ((dip = b2s_find_node(n, l)) != NULL) { 1038 if (dipp) 1039 *dipp = dip; 1040 return (DDI_SUCCESS); 1041 } 1042 1043 ASSERT(l != NULL); 1044 1045 /* 1046 * Perform an inquiry to collect key information. 1047 */ 1048 if (b2s_inquiry(l) != DDI_SUCCESS) { 1049 return (DDI_FAILURE); 1050 } 1051 1052 scsi_hba_nodename_compatible_get(&l->l_inq, NULL, l->l_inq.inq_dtype, 1053 NULL, &name, &compat, &ncompat); 1054 1055 if (ndi_devi_alloc(n->n_dip, name, DEVI_SID_NODEID, &dip) != 1056 NDI_SUCCESS) { 1057 scsi_hba_nodename_compatible_free(name, compat); 1058 b2s_warn(l, "Unable to create devinfo node"); 1059 return (DDI_FAILURE); 1060 } 1061 1062 if (b2s_update_props(dip, l, compat, ncompat) != DDI_SUCCESS) { 1063 scsi_hba_nodename_compatible_free(name, compat); 1064 ndi_prop_remove_all(dip); 1065 (void) ndi_devi_free(dip); 1066 b2s_warn(l, "Unable to create properties"); 1067 return (DDI_FAILURE); 1068 } 1069 scsi_hba_nodename_compatible_free(name, compat); 1070 1071 if (dipp) { 1072 /* 1073 * We were called by bus_config BUS_CONFIG_ONE, 1074 * and therefore must be done synchronously. 1075 */ 1076 rv = ndi_devi_online(dip, NDI_ONLINE_ATTACH); 1077 if (rv == NDI_SUCCESS) 1078 *dipp = dip; 1079 } else { 1080 /* 1081 * The rest of the time, asynchronous is easier and 1082 * safer (nexus could call us from interrupt context). 1083 */ 1084 rv = ndi_devi_online_async(dip, 1085 NDI_ONLINE_ATTACH | NDI_NOSLEEP); 1086 } 1087 if (rv != NDI_SUCCESS) { 1088 b2s_warn(l, "Failed to online device"); 1089 ndi_prop_remove_all(dip); 1090 (void) ndi_devi_free(dip); 1091 return (DDI_FAILURE); 1092 } 1093 1094 return (DDI_SUCCESS); 1095 } 1096 1097 int 1098 b2s_bus_config(dev_info_t *ndip, uint_t flag, ddi_bus_config_op_t op, 1099 void *arg, dev_info_t **ldip) 1100 { 1101 long val; 1102 char *ptr; 1103 int rv; 1104 scsi_hba_tran_t *tran; 1105 b2s_leaf_t *l; 1106 b2s_nexus_t *n; 1107 int circ; 1108 uint_t target, lun; 1109 1110 tran = ddi_get_driver_private(ndip); 1111 n = tran->tran_hba_private; 1112 1113 ndi_devi_enter(ndip, &circ); 1114 1115 switch (op) { 1116 case BUS_CONFIG_ONE: 1117 1118 /* 1119 * First parse out the target and lun from the 1120 * address. 1121 */ 1122 if ((ptr = strchr((char *)arg, '@')) == NULL) { 1123 rv = NDI_FAILURE; 1124 break; 1125 } 1126 ptr++; 1127 if ((ddi_strtol(ptr, &ptr, 16, &val) != 0) || 1128 (val < 0) || (*ptr != ',')) { 1129 rv = NDI_FAILURE; 1130 break; 1131 } 1132 ptr++; 1133 target = (uint_t)val; 1134 if ((ddi_strtol(ptr, &ptr, 16, &val) != 0) || 1135 (val < 0) || (*ptr != 0)) { 1136 rv = NDI_FAILURE; 1137 break; 1138 } 1139 lun = (uint_t)val; 1140 1141 /* 1142 * Now lookup the leaf, and if we have it, attempt to create 1143 * the devinfo node for it. 1144 */ 1145 rv = NDI_SUCCESS; 1146 if ((l = b2s_hold_leaf(n, target, lun)) != NULL) { 1147 if (b2s_create_node(n, l, ldip) != DDI_SUCCESS) { 1148 rv = NDI_FAILURE; 1149 } 1150 b2s_rele_leaf(l); 1151 break; 1152 } 1153 break; 1154 1155 case BUS_CONFIG_DRIVER: 1156 case BUS_CONFIG_ALL: 1157 1158 l = b2s_next_leaf(n, NULL); 1159 while (l != NULL) { 1160 (void) b2s_create_node(n, l, NULL); 1161 l = b2s_next_leaf(n, l); 1162 } 1163 1164 rv = NDI_SUCCESS; 1165 break; 1166 1167 default: 1168 rv = NDI_FAILURE; 1169 break; 1170 } 1171 1172 if (rv == NDI_SUCCESS) { 1173 rv = ndi_busop_bus_config(ndip, flag, op, arg, ldip, 0); 1174 } 1175 1176 ndi_devi_exit(ndip, circ); 1177 return (rv); 1178 } 1179 1180 void 1181 b2s_inquiry_done(b2s_request_impl_t *ri) 1182 { 1183 struct scsi_inquiry *inqp = &ri->ri_leaf->l_inq; 1184 1185 /* 1186 * The only post processing we have to do is to massage the 1187 * strings into the inquiry structure. 1188 */ 1189 COPYSTR(ri->ri_inquiry.inq_vendor, inqp->inq_vid); 1190 COPYSTR(ri->ri_inquiry.inq_product, inqp->inq_pid); 1191 COPYSTR(ri->ri_inquiry.inq_revision, inqp->inq_revision); 1192 COPYSTR(ri->ri_inquiry.inq_serial, inqp->inq_serial); 1193 } 1194 1195 int 1196 b2s_inquiry(b2s_leaf_t *l) 1197 { 1198 b2s_nexus_t *n; 1199 b2s_request_impl_t *ri; 1200 struct scsi_inquiry *inqp; 1201 int err; 1202 1203 inqp = &l->l_inq; 1204 n = l->l_nexus; 1205 1206 /* 1207 * Set up basic structure, including space padding for ASCII strings. 1208 */ 1209 bzero(inqp, sizeof (*inqp)); 1210 (void) memset(inqp->inq_vid, ' ', sizeof (inqp->inq_vid)); 1211 (void) memset(inqp->inq_pid, ' ', sizeof (inqp->inq_pid)); 1212 (void) memset(inqp->inq_revision, ' ', sizeof (inqp->inq_revision)); 1213 (void) memset(inqp->inq_serial, ' ', sizeof (inqp->inq_serial)); 1214 inqp->inq_len = sizeof (*inqp) - 4; 1215 inqp->inq_ansi = 2; 1216 inqp->inq_rdf = RDF_SCSI2; 1217 inqp->inq_dtype = DTYPE_DIRECT; 1218 if (l->l_flags & B2S_LEAF_REMOVABLE) 1219 inqp->inq_rmb = 1; 1220 1221 /* 1222 * To get product strings, we have to issue a query to the driver. 1223 */ 1224 ri = kmem_zalloc(sizeof (*ri), KM_NOSLEEP); 1225 if (ri == NULL) { 1226 return (DDI_FAILURE); 1227 } 1228 ri->ri_cmd = B2S_CMD_INQUIRY; 1229 ri->ri_target = l->l_target; 1230 ri->ri_lun = l->l_lun; 1231 ri->ri_flags = B2S_REQUEST_FLAG_HEAD; 1232 ri->ri_leaf = l; 1233 ri->ri_nexus = n; 1234 ri->ri_done = b2s_inquiry_done; 1235 /* leave all else null */ 1236 1237 /* 1238 * Submit inquiry request to device driver. 1239 */ 1240 if (!n->n_request(n->n_private, &ri->ri_public)) { 1241 /* this shouldn't happen, since we are just starting out */ 1242 b2s_warn(l, "Busy trying to collect inquiry data"); 1243 kmem_free(ri, sizeof (*ri)); 1244 return (DDI_FAILURE); 1245 } 1246 1247 /* 1248 * Wait for inquiry completion. 1249 */ 1250 mutex_enter(&n->n_lock); 1251 while ((ri->ri_flags & B2S_REQUEST_FLAG_DONE) == 0) 1252 cv_wait(&n->n_cv, &n->n_lock); 1253 mutex_exit(&n->n_lock); 1254 1255 err = ri->ri_errno; 1256 kmem_free(ri, sizeof (*ri)); 1257 1258 if (err != 0) { 1259 b2s_warn(l, "Failed during inquiry (error %d)", err); 1260 return (DDI_FAILURE); 1261 } 1262 1263 return (DDI_SUCCESS); 1264 } 1265 1266 int 1267 b2s_scmd_inq(b2s_request_impl_t *ri) 1268 { 1269 b2s_leaf_t *l = ri->ri_leaf; 1270 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1271 caddr_t ptr; 1272 size_t resid, len; 1273 uint8_t hdr[4]; 1274 const uint8_t *data; 1275 uint8_t page83[12]; 1276 1277 /* 1278 * Suppport inquiry pages: 0 is the list itself, and 80 is the 1279 * unit serial number (in ASCII). 1280 */ 1281 const uint8_t supp[3] = { 0, 0x80, 0x83 }; 1282 1283 b2s_request_mapin(&ri->ri_public, &ptr, &len); 1284 1285 hdr[2] = 0; 1286 1287 /* 1288 * We don't support the EVP data bit, and hence neither a page code. 1289 * This corresponds to the entire G0 address field (which includes 1290 * a few reserved bits). 1291 */ 1292 switch (GETG0ADDR(cdb)) { 1293 case 0x00000: /* standard SCSI inquiry */ 1294 resid = min(sizeof (l->l_inq), GETG0COUNT(cdb)); 1295 len = min(resid, len); 1296 bcopy(&l->l_inq, ptr, len); 1297 ri->ri_resid = resid - len; 1298 b2s_request_done(&ri->ri_public, B2S_EOK, 0); 1299 return (TRAN_ACCEPT); 1300 1301 case 0x10000: /* page 0 supported VPD pages */ 1302 data = supp; 1303 hdr[0] = DTYPE_DIRECT; 1304 hdr[1] = 0; /* page code */ 1305 hdr[2] = 0; 1306 hdr[3] = l->l_eui ? 3 : 2; /* page length */ 1307 break; 1308 1309 case 0x18000: /* page 80 unit serial number */ 1310 data = (uint8_t *)l->l_uuid; 1311 hdr[0] = DTYPE_DIRECT; 1312 hdr[1] = 0x80; /* page code */ 1313 hdr[2] = 0; 1314 hdr[3] = l->l_uuid ? strlen(l->l_uuid) : 0; /* page len */ 1315 break; 1316 1317 case 0x18300: /* page 83 WWN */ 1318 if (l->l_eui == 0) { 1319 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1320 return (TRAN_ACCEPT); 1321 } 1322 data = page83; 1323 hdr[0] = DTYPE_DIRECT; 1324 hdr[1] = 0x83; /* page code */ 1325 hdr[2] = 0; 1326 hdr[3] = 12; /* length, only 12 bytes */ 1327 1328 /* lun designator */ 1329 page83[0] = 1; /* binary */ 1330 page83[1] = 2; /* lun association, eui-64 type */ 1331 page83[2] = 0; /* reserved */ 1332 page83[3] = 8; /* designator length */ 1333 SCSI_WRITE64(&page83[4], l->l_eui); 1334 1335 /* Note that we don't bother with port or target ids */ 1336 break; 1337 1338 default: 1339 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1340 return (TRAN_ACCEPT); 1341 } 1342 1343 resid = min(hdr[3] + 4, GETG0COUNT(cdb)); 1344 len = min(resid, len); 1345 ri->ri_resid = resid - len; 1346 1347 /* now copy the header */ 1348 len = min(resid, 4); 1349 bcopy(hdr, ptr, len); 1350 resid -= len; 1351 1352 /* now copy the actual page data */ 1353 bcopy(data, ptr + len, resid); 1354 1355 b2s_request_done(&ri->ri_public, B2S_EOK, 0); 1356 return (TRAN_ACCEPT); 1357 } 1358 1359 int 1360 b2s_scmd_rqs(b2s_request_impl_t *ri) 1361 { 1362 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1363 size_t len, resid; 1364 caddr_t ptr; 1365 int rv; 1366 1367 /* Like inquiry, the entire G0 address field must be zero. */ 1368 if (GETG0ADDR(cdb) != 0) { 1369 rv = B2S_EINVAL; 1370 len = 0; 1371 resid = 0; 1372 } else { 1373 struct scsi_extended_sense es; 1374 1375 /* 1376 * We always use ARQ, unconditionally, so this command 1377 * can always return success. 1378 */ 1379 bzero(&es, sizeof (es)); 1380 es.es_valid = 1; 1381 es.es_class = CLASS_EXTENDED_SENSE; 1382 es.es_key = KEY_NO_SENSE; 1383 1384 resid = sizeof (es); 1385 1386 b2s_request_mapin(&ri->ri_public, &ptr, &len); 1387 1388 len = min(resid, len); 1389 bcopy(&es, ptr, len); 1390 resid -= len; 1391 1392 rv = B2S_EOK; 1393 } 1394 b2s_request_done(&ri->ri_public, rv, resid); 1395 return (TRAN_ACCEPT); 1396 } 1397 1398 int 1399 b2s_scmd_sdiag(b2s_request_impl_t *ri) 1400 { 1401 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1402 int rv; 1403 1404 /* we only support the SELFTEST bit */ 1405 if ((GETG0TAG(cdb) & 0x4) == 0) { 1406 rv = B2S_EINVAL; 1407 } else { 1408 rv = B2S_EOK; 1409 } 1410 b2s_request_done(&ri->ri_public, rv, 0); 1411 return (TRAN_ACCEPT); 1412 } 1413 1414 int 1415 b2s_scmd_tur(b2s_request_impl_t *ri) 1416 { 1417 b2s_nexus_t *n = ri->ri_nexus; 1418 1419 ri->ri_cmd = B2S_CMD_GETMEDIA; 1420 if (!n->n_request(n->n_private, &ri->ri_public)) { 1421 return (TRAN_BUSY); 1422 } 1423 return (TRAN_ACCEPT); 1424 } 1425 1426 int 1427 b2s_scmd_doorlock(b2s_request_impl_t *ri) 1428 { 1429 b2s_nexus_t *n = ri->ri_nexus; 1430 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1431 1432 /* 1433 * Bit 0 of the count indicates the "Prevent" mode. All other address 1434 * and count bits are reserved. 1435 */ 1436 if ((GETG0ADDR(cdb) != 0) || ((GETG0COUNT(cdb) & 0xFE) != 0)) { 1437 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1438 return (TRAN_ACCEPT); 1439 } 1440 1441 ri->ri_cmd = (GETG0COUNT(cdb) != 0) ? B2S_CMD_LOCK : B2S_CMD_UNLOCK; 1442 if (!n->n_request(n->n_private, &ri->ri_public)) { 1443 return (TRAN_BUSY); 1444 } 1445 return (TRAN_ACCEPT); 1446 } 1447 1448 int 1449 b2s_scmd_format(b2s_request_impl_t *ri) 1450 { 1451 b2s_nexus_t *n = ri->ri_nexus; 1452 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1453 size_t len; 1454 caddr_t ptr; 1455 1456 if (GETG0TAG(cdb) & 0x7) { 1457 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1458 return (TRAN_ACCEPT); 1459 } 1460 1461 if (GETG0TAG(cdb) & FPB_DATA) { 1462 /* 1463 * FmtData set. A defect list is attached. 1464 * 1465 * This is an awful lot of work just to support a command 1466 * option we don't ever care about. SCSI-2 says we have 1467 * to do it. 1468 * 1469 * The alternative would just be to ignore the defect list 1470 * and format options altogether. That would be a lot easier. 1471 */ 1472 1473 b2s_request_mapin(&ri->ri_public, &ptr, &len); 1474 1475 if (len < 4) { 1476 b2s_request_done(&ri->ri_public, B2S_EBADMSG, 0); 1477 return (TRAN_ACCEPT); 1478 } 1479 1480 if ((ptr[0] != 0) || (ptr[2] != 0) || (ptr[3] != 0) || 1481 ((ptr[1] & 0xF9) != 0)) { 1482 b2s_request_done(&ri->ri_public, B2S_EPARAM, 0); 1483 return (TRAN_ACCEPT); 1484 } 1485 1486 if (ptr[1] & 0x2) { 1487 ri->ri_flags |= B2S_REQUEST_FLAG_IMMED; 1488 } 1489 1490 } else if (GETG0TAG(cdb) & FPB_CMPLT) { 1491 /* 1492 * No defect list, so this bit (CmpLst) should have been zero! 1493 */ 1494 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1495 return (TRAN_ACCEPT); 1496 } 1497 1498 ri->ri_cmd = B2S_CMD_FORMAT; 1499 if (!n->n_request(n->n_private, &ri->ri_public)) { 1500 return (TRAN_BUSY); 1501 } 1502 1503 return (TRAN_ACCEPT); 1504 } 1505 1506 void 1507 b2s_scmd_readcap_done(b2s_request_impl_t *ri) 1508 { 1509 uint32_t lba; 1510 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1511 struct scsi_capacity cap; 1512 caddr_t ptr; 1513 size_t resid, len; 1514 1515 /* 1516 * Lower layer resid is meaningless here. 1517 */ 1518 if (ri->ri_errno != B2S_EOK) { 1519 return; 1520 } 1521 1522 lba = GETG1ADDR(cdb); 1523 1524 switch (GETG1COUNT(cdb)) { 1525 case 0: /* PMI == 0 */ 1526 if (lba != 0) { 1527 ri->ri_errno = B2S_EINVAL; 1528 return; 1529 } 1530 break; 1531 case 1: /* PMI == 1 */ 1532 if (lba >= ri->ri_media.media_nblks) { 1533 ri->ri_errno = B2S_EBLKADDR; 1534 return; 1535 } 1536 break; 1537 default: 1538 ri->ri_errno = B2S_EINVAL; 1539 return; 1540 } 1541 1542 /* 1543 * Note that the capacity is the LBA of the last block, not the 1544 * number of blocks. A little surprising if you don't pay close 1545 * enough attention to the spec. 1546 */ 1547 SCSI_WRITE32(&cap.capacity, ri->ri_media.media_nblks - 1); 1548 SCSI_WRITE32(&cap.lbasize, ri->ri_media.media_blksz); 1549 1550 b2s_request_mapin(&ri->ri_public, &ptr, &len); 1551 1552 if (len != 0) { 1553 resid = sizeof (cap); 1554 len = min(resid, len); 1555 bcopy(&cap, ptr, len); 1556 ri->ri_resid = resid - len; 1557 } 1558 } 1559 1560 int 1561 b2s_scmd_readcap(b2s_request_impl_t *ri) 1562 { 1563 b2s_nexus_t *n = ri->ri_nexus; 1564 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1565 1566 /* 1567 * No transfer by real target. 1568 */ 1569 ri->ri_done = b2s_scmd_readcap_done; 1570 1571 if ((GETG1TAG(cdb)) != 0) { 1572 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1573 return (TRAN_ACCEPT); 1574 } 1575 1576 ri->ri_cmd = B2S_CMD_GETMEDIA; 1577 if (!n->n_request(n->n_private, &ri->ri_public)) { 1578 return (TRAN_BUSY); 1579 } 1580 1581 return (TRAN_ACCEPT); 1582 } 1583 1584 int 1585 b2s_scmd_reserve_release(b2s_request_impl_t *ri) 1586 { 1587 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1588 1589 /* we aren't checking fields we don't care about */ 1590 if ((GETG0TAG(cdb) & 0x1) != 0) { 1591 /* extent reservations not supported */ 1592 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1593 return (TRAN_ACCEPT); 1594 } 1595 1596 /* 1597 * We don't support multi-initiator access, so we always 1598 * return success. 1599 */ 1600 1601 b2s_request_done(&ri->ri_public, B2S_EOK, 0); 1602 return (TRAN_ACCEPT); 1603 } 1604 1605 int 1606 b2s_scmd_start_stop(b2s_request_impl_t *ri) 1607 { 1608 b2s_nexus_t *n = ri->ri_nexus; 1609 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1610 uint8_t count; 1611 1612 switch (GETG0ADDR(cdb)) { 1613 case 0: 1614 break; 1615 case 0x10000: /* immed set */ 1616 ri->ri_flags |= B2S_REQUEST_FLAG_IMMED; 1617 break; 1618 default: 1619 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1620 return (TRAN_ACCEPT); 1621 } 1622 count = GETG0COUNT(cdb); 1623 if (count > 3) { 1624 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1625 return (TRAN_ACCEPT); 1626 } 1627 if (count & 0x2) 1628 ri->ri_flags |= B2S_REQUEST_FLAG_LOAD_EJECT; 1629 if (count & 0x1) { 1630 ri->ri_cmd = B2S_CMD_START; 1631 } else { 1632 ri->ri_cmd = B2S_CMD_STOP; 1633 } 1634 1635 if (!n->n_request(n->n_private, &ri->ri_public)) { 1636 return (TRAN_BUSY); 1637 } 1638 return (TRAN_ACCEPT); 1639 } 1640 1641 void 1642 b2s_scmd_mode_sense_done(b2s_request_impl_t *ri) 1643 { 1644 uchar_t *cdb = ri->ri_pkt->pkt_cdbp; 1645 uint8_t pc, page, devspec; 1646 caddr_t ptr; 1647 size_t len, resid; 1648 uint8_t data[16]; 1649 1650 if ((ri->ri_errno == 0) && 1651 ((ri->ri_media.media_flags & B2S_MEDIA_FLAG_READ_ONLY) == 0)) { 1652 devspec = 0; 1653 } else { 1654 /* this marks the media read-only */ 1655 devspec = 0x80; 1656 } 1657 1658 pc = page = cdb[2]; 1659 pc &= 0xc0; 1660 page &= 0x3f; 1661 1662 /* we do not support savable parameters, at all */ 1663 if ((pc & 0xc0) == 0x3) { 1664 ri->ri_errno = B2S_ENOSAV; 1665 ri->ri_resid = 0; 1666 return; 1667 } 1668 1669 b2s_request_mapin(&ri->ri_public, &ptr, &resid); 1670 1671 if ((page == 0x9) || (page == 0x3f)) { 1672 /* Peripheral device page */ 1673 1674 /* header */ 1675 data[0] = 9 + 3; /* length following */ 1676 data[1] = 0; /* medium type */ 1677 data[2] = devspec; /* mostly r/w flag */ 1678 data[3] = 0; /* block descriptor len */ 1679 len = min(4, resid); 1680 1681 bcopy(data, ptr, len); 1682 resid -= len; 1683 ptr += len; 1684 1685 /* page data - 9 bytes long */ 1686 bzero(data, 9); 1687 data[0] = 0x9; /* page code */ 1688 data[1] = 0x8; /* following data */ 1689 len = min(resid, 9); 1690 bcopy(data, ptr, len); 1691 resid -= len; 1692 ptr += len; 1693 } 1694 1695 if ((page == 0xa) || (page == 0x3f)) { 1696 /* Control mode page */ 1697 1698 /* header */ 1699 data[0] = 8 + 3; /* length following */ 1700 data[1] = 0; /* medium type */ 1701 data[2] = devspec; /* mostly r/w flag */ 1702 data[3] = 0; /* block descriptor len */ 1703 len = min(4, resid); 1704 1705 bcopy(data, ptr, len); 1706 resid -= len; 1707 ptr += len; 1708 1709 /* page data - 9 bytes long */ 1710 bzero(data, 8); 1711 data[0] = 0xa; /* page code */ 1712 data[1] = 0x7; /* following data */ 1713 len = min(resid, 9); 1714 bcopy(data, ptr, len); 1715 resid -= len; 1716 ptr += len; 1717 } 1718 1719 ri->ri_resid = 0; 1720 ri->ri_errno = B2S_EOK; 1721 } 1722 1723 int 1724 b2s_scmd_mode_sense(b2s_request_impl_t *ri) 1725 { 1726 b2s_nexus_t *n = ri->ri_nexus; 1727 1728 ri->ri_done = b2s_scmd_mode_sense_done; 1729 ri->ri_cmd = B2S_CMD_GETMEDIA; 1730 if (!n->n_request(n->n_private, &ri->ri_public)) { 1731 return (TRAN_BUSY); 1732 } 1733 return (TRAN_ACCEPT); 1734 } 1735 1736 int 1737 b2s_scmd_rw(b2s_request_impl_t *ri) 1738 { 1739 b2s_nexus_t *n = ri->ri_nexus; 1740 uint32_t lba; 1741 uint32_t nblks; 1742 union scsi_cdb *cdb = (void *)ri->ri_pkt->pkt_cdbp; 1743 1744 switch (GETGROUP(cdb)) { 1745 case CDB_GROUPID_0: 1746 nblks = GETG0COUNT(cdb); 1747 nblks = nblks ? nblks : 256; 1748 lba = GETG0ADDR(cdb); 1749 break; 1750 case CDB_GROUPID_1: 1751 if (GETG1TAG(cdb)) { 1752 /* we don't support relative addresses */ 1753 b2s_request_done(&ri->ri_public, B2S_EINVAL, 0); 1754 return (TRAN_ACCEPT); 1755 } 1756 lba = GETG1ADDR(cdb); 1757 nblks = GETG1COUNT(cdb); 1758 break; 1759 default: 1760 b2s_request_done(&ri->ri_public, B2S_ENOTSUP, 0); 1761 return (TRAN_ACCEPT); 1762 } 1763 1764 if (nblks == 0) { 1765 b2s_request_done(&ri->ri_public, 0, 0); 1766 return (TRAN_ACCEPT); 1767 } 1768 1769 ri->ri_nblks = nblks; 1770 ri->ri_lba = lba; 1771 ri->ri_flags |= B2S_REQUEST_FLAG_BLKS; 1772 ri->ri_cmd = (GETCMD(cdb)) == SCMD_READ ? 1773 B2S_CMD_READ : B2S_CMD_WRITE; 1774 1775 if (!n->n_request(n->n_private, &ri->ri_public)) { 1776 return (TRAN_BUSY); 1777 } 1778 return (TRAN_ACCEPT); 1779 } 1780 1781 void 1782 b2s_warn(b2s_leaf_t *l, const char *fmt, ...) 1783 { 1784 va_list ap; 1785 b2s_nexus_t *n; 1786 char msg[256]; 1787 1788 n = l->l_nexus; 1789 1790 (void) snprintf(msg, sizeof (msg), "%s%d target %d lun %d: %s", 1791 ddi_driver_name(n->n_dip), ddi_get_instance(n->n_dip), 1792 l->l_target, l->l_lun, fmt); 1793 1794 va_start(ap, fmt); 1795 vcmn_err(CE_WARN, msg, ap); 1796 va_end(ap); 1797 } 1798 1799 b2s_nexus_t * 1800 b2s_alloc_nexus(b2s_nexus_info_t *info) 1801 { 1802 b2s_nexus_t *n; 1803 struct scsi_hba_tran *tran; 1804 1805 if (info->nexus_version != B2S_VERSION_0) 1806 return (NULL); 1807 1808 n = kmem_zalloc(sizeof (*n), KM_SLEEP); 1809 mutex_init(&n->n_lock, NULL, MUTEX_DRIVER, NULL); 1810 cv_init(&n->n_cv, NULL, CV_DRIVER, NULL); 1811 list_create(&n->n_leaves, sizeof (struct b2s_leaf), 1812 offsetof(struct b2s_leaf, l_node)); 1813 1814 n->n_dip = info->nexus_dip; 1815 n->n_private = info->nexus_private; 1816 n->n_request = info->nexus_request; 1817 if (info->nexus_dma_attr != NULL) { 1818 n->n_dma = info->nexus_dma_attr; 1819 } else { 1820 n->n_dma = &b2s_default_dma_attr; 1821 } 1822 1823 tran = scsi_hba_tran_alloc(n->n_dip, SCSI_HBA_CANSLEEP); 1824 if (tran == NULL) { 1825 list_destroy(&n->n_leaves); 1826 mutex_destroy(&n->n_lock); 1827 cv_destroy(&n->n_cv); 1828 kmem_free(n, sizeof (*n)); 1829 return (NULL); 1830 } 1831 n->n_tran = tran; 1832 1833 tran->tran_hba_dip = n->n_dip; 1834 tran->tran_hba_private = n; 1835 tran->tran_tgt_private = NULL; 1836 tran->tran_tgt_init = b2s_tran_tgt_init; 1837 tran->tran_tgt_free = b2s_tran_tgt_free; 1838 tran->tran_tgt_probe = scsi_hba_probe; 1839 tran->tran_tgt_free = NULL; 1840 tran->tran_start = b2s_tran_start; 1841 tran->tran_reset = b2s_tran_reset; 1842 tran->tran_abort = b2s_tran_abort; 1843 tran->tran_getcap = b2s_tran_getcap; 1844 tran->tran_setcap = b2s_tran_setcap; 1845 tran->tran_init_pkt = b2s_tran_init_pkt; 1846 tran->tran_destroy_pkt = b2s_tran_destroy_pkt; 1847 tran->tran_hba_len = sizeof (b2s_request_impl_t); 1848 tran->tran_bus_config = b2s_bus_config; 1849 1850 return (n); 1851 } 1852 1853 void 1854 b2s_free_nexus(b2s_nexus_t *n) 1855 { 1856 b2s_leaf_t *l; 1857 1858 /* 1859 * Toss any registered leaves, if we haven't already done so. 1860 * At this point we don't care about upper layers, because the 1861 * DDI should not have allowed us to detach if there were busy 1862 * targets. 1863 */ 1864 while ((l = list_head(&n->n_leaves)) != NULL) { 1865 list_remove(&n->n_leaves, l); 1866 kmem_free(l, sizeof (struct b2s_leaf)); 1867 } 1868 list_destroy(&n->n_leaves); 1869 mutex_destroy(&n->n_lock); 1870 cv_destroy(&n->n_cv); 1871 kmem_free(n, sizeof (struct b2s_nexus)); 1872 } 1873 1874 int 1875 b2s_attach_nexus(b2s_nexus_t *n) 1876 { 1877 int rv; 1878 1879 rv = scsi_hba_attach_setup(n->n_dip, n->n_dma, n->n_tran, 1880 SCSI_HBA_TRAN_SCB | SCSI_HBA_TRAN_CDB | SCSI_HBA_TRAN_CLONE); 1881 if (rv == 0) { 1882 n->n_attached = B_TRUE; 1883 } 1884 return (rv); 1885 } 1886 1887 int 1888 b2s_detach_nexus(b2s_nexus_t *n) 1889 { 1890 int rv; 1891 1892 if (n->n_attached) { 1893 rv = scsi_hba_detach(n->n_dip); 1894 if (rv == 0) { 1895 n->n_attached = B_FALSE; 1896 } 1897 } else { 1898 rv = 0; 1899 } 1900 return ((rv == 0) ? DDI_SUCCESS : DDI_FAILURE); 1901 } 1902 1903 b2s_leaf_t * 1904 b2s_attach_leaf(b2s_nexus_t *n, b2s_leaf_info_t *info) 1905 { 1906 b2s_leaf_t *l; 1907 uint_t target = info->leaf_target; 1908 uint_t lun = info->leaf_lun; 1909 const char *uuid = info->leaf_unique_id; 1910 uint32_t flags = info->leaf_flags; 1911 uint64_t eui = info->leaf_eui; 1912 1913 if (uuid == NULL) { 1914 uuid = ""; 1915 } 1916 1917 mutex_enter(&n->n_lock); 1918 1919 /* 1920 * If the leaf already exists, it is a sign that the device 1921 * was kept around because it was still in use. In that case, 1922 * we attempt to detect the situation where the node is the same 1923 * as the previous one, and reconnect it. 1924 */ 1925 if ((l = b2s_get_leaf(n, target, lun)) != NULL) { 1926 if (strcmp(l->l_uuid, uuid) != 0) { 1927 /* 1928 * Leaf already exists, but is not the same! This 1929 * would be a good time to issue a warning. 1930 */ 1931 mutex_exit(&n->n_lock); 1932 b2s_warn(l, "Target disconnected while still in use."); 1933 b2s_warn(l, "Reconnect the previous target device."); 1934 return (NULL); 1935 } 1936 l->l_flags &= ~B2S_LEAF_DETACHED; 1937 } else { 1938 if ((l = kmem_zalloc(sizeof (*l), KM_NOSLEEP)) == NULL) { 1939 mutex_exit(&n->n_lock); 1940 b2s_warn(l, "Unable to allocate target state."); 1941 return (NULL); 1942 } 1943 l->l_nexus = n; 1944 l->l_target = target; 1945 l->l_lun = lun; 1946 l->l_flags = flags; 1947 l->l_eui = eui; 1948 1949 /* strdup would be nice here */ 1950 l->l_uuid = kmem_alloc(strlen(uuid) + 1, KM_NOSLEEP); 1951 if (l->l_uuid == NULL) { 1952 mutex_exit(&n->n_lock); 1953 kmem_free(l, sizeof (*l)); 1954 b2s_warn(l, "Unable to allocate target UUID storage."); 1955 return (NULL); 1956 } 1957 (void) strcpy(l->l_uuid, uuid); 1958 1959 list_insert_tail(&n->n_leaves, l); 1960 } 1961 1962 /* 1963 * Make sure we hold it, so that it won't be freed out from 1964 * underneath us. 1965 */ 1966 l->l_refcnt++; 1967 mutex_exit(&n->n_lock); 1968 1969 /* 1970 * If the HBA is currently attached, then we need to attach 1971 * the node right now. This supports "hotplug". Note that 1972 * if the node is a reinsert, then this should degenerate into 1973 * a NOP. 1974 */ 1975 if (n->n_attached) { 1976 int circ; 1977 ndi_devi_enter(n->n_dip, &circ); 1978 (void) b2s_create_node(n, l, NULL); 1979 ndi_devi_exit(n->n_dip, circ); 1980 } 1981 1982 return (l); 1983 } 1984 1985 void 1986 b2s_detach_leaf(b2s_leaf_t *l) 1987 { 1988 b2s_nexus_t *n = l->l_nexus; 1989 dev_info_t *dip; 1990 int circ; 1991 1992 l->l_flags |= B2S_LEAF_DETACHED; 1993 1994 /* 1995 * Search for an appropriate child devinfo. 1996 */ 1997 ndi_devi_enter(n->n_dip, &circ); 1998 dip = b2s_find_node(n, l); 1999 if (dip != NULL) { 2000 (void) ndi_devi_offline(dip, NDI_DEVI_REMOVE); 2001 } 2002 ndi_devi_exit(n->n_dip, circ); 2003 2004 b2s_rele_leaf(l); 2005 } 2006