1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2018 Nexenta Systems, Inc. 14 */ 15 16 #include <sys/atomic.h> 17 #include <sys/cmn_err.h> 18 #include <sys/conf.h> 19 #include <sys/cpuvar.h> 20 #include <sys/ddi.h> 21 #include <sys/errno.h> 22 #include <sys/kmem.h> 23 #include <sys/kmem_impl.h> 24 #include <sys/list.h> 25 #include <sys/modctl.h> 26 #include <sys/pci.h> 27 #include <sys/scsi/scsi.h> 28 #include <sys/sunddi.h> 29 #include <sys/sysmacros.h> 30 #include <sys/time.h> 31 #include <sys/types.h> 32 33 #include "pvscsi.h" 34 #include "pvscsi_var.h" 35 36 int pvscsi_enable_msi = 1; 37 int pvscsi_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_PER_RING; 38 int pvscsi_msg_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_MSG_RING; 39 40 static int pvscsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 41 42 static void *pvscsi_sstate; 43 44 /* HBA DMA attributes */ 45 static ddi_dma_attr_t pvscsi_hba_dma_attr = { 46 .dma_attr_version = DMA_ATTR_V0, 47 .dma_attr_addr_lo = 0x0000000000000000ull, 48 .dma_attr_addr_hi = 0xFFFFFFFFFFFFFFFFull, 49 .dma_attr_count_max = 0x000000007FFFFFFFull, 50 .dma_attr_align = 0x0000000000000001ull, 51 .dma_attr_burstsizes = 0x7ff, 52 .dma_attr_minxfer = 0x00000001u, 53 .dma_attr_maxxfer = 0x00000000FFFFFFFFull, 54 .dma_attr_seg = 0x00000000FFFFFFFFull, 55 .dma_attr_sgllen = 1, 56 .dma_attr_granular = 0x00000200u, 57 .dma_attr_flags = 0 58 }; 59 60 /* DMA attributes for req/comp rings */ 61 static ddi_dma_attr_t pvscsi_ring_dma_attr = { 62 .dma_attr_version = DMA_ATTR_V0, 63 .dma_attr_addr_lo = 0x0000000000000000ull, 64 .dma_attr_addr_hi = 0xFFFFFFFFFFFFFFFFull, 65 .dma_attr_count_max = 0x000000007FFFFFFFull, 66 .dma_attr_align = 0x0000000000000001ull, 67 .dma_attr_burstsizes = 0x7ff, 68 .dma_attr_minxfer = 0x00000001u, 69 .dma_attr_maxxfer = 0x00000000FFFFFFFFull, 70 .dma_attr_seg = 0x00000000FFFFFFFFull, 71 .dma_attr_sgllen = 1, 72 .dma_attr_granular = 0x00000001u, 73 .dma_attr_flags = 0 74 }; 75 76 /* DMA attributes for buffer I/O */ 77 static ddi_dma_attr_t pvscsi_io_dma_attr = { 78 .dma_attr_version = DMA_ATTR_V0, 79 .dma_attr_addr_lo = 0x0000000000000000ull, 80 .dma_attr_addr_hi = 0xFFFFFFFFFFFFFFFFull, 81 .dma_attr_count_max = 0x000000007FFFFFFFull, 82 .dma_attr_align = 0x0000000000000001ull, 83 .dma_attr_burstsizes = 0x7ff, 84 .dma_attr_minxfer = 0x00000001u, 85 .dma_attr_maxxfer = 0x00000000FFFFFFFFull, 86 .dma_attr_seg = 0x00000000FFFFFFFFull, 87 .dma_attr_sgllen = PVSCSI_MAX_SG_SIZE, 88 .dma_attr_granular = 0x00000200u, 89 .dma_attr_flags = 0 90 }; 91 92 static ddi_device_acc_attr_t pvscsi_mmio_attr = { 93 DDI_DEVICE_ATTR_V1, 94 DDI_STRUCTURE_LE_ACC, 95 DDI_STRICTORDER_ACC, 96 DDI_DEFAULT_ACC 97 }; 98 99 static ddi_device_acc_attr_t pvscsi_dma_attrs = { 100 DDI_DEVICE_ATTR_V0, 101 DDI_STRUCTURE_LE_ACC, 102 DDI_STRICTORDER_ACC, 103 DDI_DEFAULT_ACC, 104 }; 105 106 static void 107 pvscsi_add_to_queue(pvscsi_cmd_t *cmd) 108 { 109 pvscsi_softc_t *pvs = cmd->cmd_pvs; 110 111 ASSERT(pvs != NULL); 112 ASSERT(mutex_owned(&pvs->mutex)); 113 ASSERT(!list_link_active(&(cmd)->cmd_queue_node)); 114 115 list_insert_tail(&pvs->cmd_queue, cmd); 116 pvs->cmd_queue_len++; 117 } 118 119 static void 120 pvscsi_remove_from_queue(pvscsi_cmd_t *cmd) 121 { 122 pvscsi_softc_t *pvs = cmd->cmd_pvs; 123 124 ASSERT(pvs != NULL); 125 ASSERT(mutex_owned(&pvs->mutex)); 126 ASSERT(list_link_active(&cmd->cmd_queue_node)); 127 ASSERT(pvs->cmd_queue_len > 0); 128 129 if (list_link_active(&cmd->cmd_queue_node)) { 130 list_remove(&pvs->cmd_queue, cmd); 131 pvs->cmd_queue_len--; 132 } 133 } 134 135 static uint64_t 136 pvscsi_map_ctx(pvscsi_softc_t *pvs, pvscsi_cmd_ctx_t *io_ctx) 137 { 138 return (io_ctx - pvs->cmd_ctx + 1); 139 } 140 141 static pvscsi_cmd_ctx_t * 142 pvscsi_lookup_ctx(pvscsi_softc_t *pvs, pvscsi_cmd_t *cmd) 143 { 144 pvscsi_cmd_ctx_t *ctx, *end; 145 146 end = &pvs->cmd_ctx[pvs->req_depth]; 147 for (ctx = pvs->cmd_ctx; ctx < end; ctx++) { 148 if (ctx->cmd == cmd) 149 return (ctx); 150 } 151 152 return (NULL); 153 } 154 155 static pvscsi_cmd_ctx_t * 156 pvscsi_resolve_ctx(pvscsi_softc_t *pvs, uint64_t ctx) 157 { 158 if (ctx > 0 && ctx <= pvs->req_depth) 159 return (&pvs->cmd_ctx[ctx - 1]); 160 else 161 return (NULL); 162 } 163 164 static boolean_t 165 pvscsi_acquire_ctx(pvscsi_softc_t *pvs, pvscsi_cmd_t *cmd) 166 { 167 pvscsi_cmd_ctx_t *ctx; 168 169 if (list_is_empty(&pvs->cmd_ctx_pool)) 170 return (B_FALSE); 171 172 ctx = (pvscsi_cmd_ctx_t *)list_remove_head(&pvs->cmd_ctx_pool); 173 ASSERT(ctx != NULL); 174 175 ctx->cmd = cmd; 176 cmd->ctx = ctx; 177 178 return (B_TRUE); 179 } 180 181 static void 182 pvscsi_release_ctx(pvscsi_cmd_t *cmd) 183 { 184 pvscsi_softc_t *pvs = cmd->cmd_pvs; 185 186 ASSERT(mutex_owned(&pvs->mutex)); 187 188 cmd->ctx->cmd = NULL; 189 list_insert_tail(&pvs->cmd_ctx_pool, cmd->ctx); 190 cmd->ctx = NULL; 191 } 192 193 static uint32_t 194 pvscsi_reg_read(pvscsi_softc_t *pvs, uint32_t offset) 195 { 196 uint32_t ret; 197 198 ASSERT((offset & (sizeof (uint32_t) - 1)) == 0); 199 200 ret = ddi_get32(pvs->mmio_handle, 201 (uint32_t *)(pvs->mmio_base + offset)); 202 203 return (ret); 204 } 205 206 static void 207 pvscsi_reg_write(pvscsi_softc_t *pvs, uint32_t offset, uint32_t value) 208 { 209 ASSERT((offset & (sizeof (uint32_t) - 1)) == 0); 210 211 ddi_put32(pvs->mmio_handle, (uint32_t *)(pvs->mmio_base + offset), 212 value); 213 } 214 215 static void 216 pvscsi_write_cmd_desc(pvscsi_softc_t *pvs, uint32_t cmd, void *desc, size_t len) 217 { 218 len /= sizeof (uint32_t); 219 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_COMMAND, cmd); 220 ddi_rep_put32(pvs->mmio_handle, (uint32_t *)desc, 221 (uint32_t *)(pvs->mmio_base + PVSCSI_REG_OFFSET_COMMAND_DATA), 222 len, DDI_DEV_NO_AUTOINCR); 223 } 224 225 static uint32_t 226 pvscsi_read_intr_status(pvscsi_softc_t *pvs) 227 { 228 return (pvscsi_reg_read(pvs, PVSCSI_REG_OFFSET_INTR_STATUS)); 229 } 230 231 static void 232 pvscsi_write_intr_status(pvscsi_softc_t *pvs, uint32_t val) 233 { 234 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_INTR_STATUS, val); 235 } 236 237 static void 238 pvscsi_mask_intr(pvscsi_softc_t *pvs) 239 { 240 mutex_enter(&pvs->intr_mutex); 241 242 VERIFY(pvs->intr_lock_counter >= 0); 243 244 if (++pvs->intr_lock_counter == 1) 245 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_INTR_MASK, 0); 246 247 mutex_exit(&pvs->intr_mutex); 248 } 249 250 static void 251 pvscsi_unmask_intr(pvscsi_softc_t *pvs) 252 { 253 mutex_enter(&pvs->intr_mutex); 254 255 VERIFY(pvs->intr_lock_counter > 0); 256 257 if (--pvs->intr_lock_counter == 0) { 258 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_INTR_MASK, 259 PVSCSI_INTR_CMPL_MASK | PVSCSI_INTR_MSG_MASK); 260 } 261 262 mutex_exit(&pvs->intr_mutex); 263 } 264 265 static void 266 pvscsi_reset_hba(pvscsi_softc_t *pvs) 267 { 268 pvscsi_write_cmd_desc(pvs, PVSCSI_CMD_ADAPTER_RESET, NULL, 0); 269 } 270 271 static void 272 pvscsi_reset_bus(pvscsi_softc_t *pvs) 273 { 274 pvscsi_write_cmd_desc(pvs, PVSCSI_CMD_RESET_BUS, NULL, 0); 275 } 276 277 static void 278 pvscsi_submit_nonrw_io(pvscsi_softc_t *pvs) 279 { 280 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_KICK_NON_RW_IO, 0); 281 } 282 283 static void 284 pvscsi_submit_rw_io(pvscsi_softc_t *pvs) 285 { 286 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_KICK_RW_IO, 0); 287 } 288 289 290 static int 291 pvscsi_inquiry_target(pvscsi_softc_t *pvs, int target, struct scsi_inquiry *inq) 292 { 293 int len = sizeof (struct scsi_inquiry); 294 int ret = -1; 295 struct buf *b; 296 struct scsi_address ap; 297 struct scsi_pkt *pkt; 298 uint8_t cdb[CDB_GROUP0]; 299 300 ap.a_hba_tran = pvs->tran; 301 ap.a_target = (ushort_t)target; 302 ap.a_lun = (uchar_t)0; 303 304 if ((b = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL, len, 305 B_READ, NULL_FUNC, NULL)) == NULL) 306 return (-1); 307 308 if ((pkt = scsi_init_pkt(&ap, (struct scsi_pkt *)NULL, b, 309 CDB_GROUP0, sizeof (struct scsi_arq_status), 0, 0, 310 NULL_FUNC, NULL)) == NULL) 311 goto free_buf; 312 313 cdb[0] = SCMD_INQUIRY; 314 cdb[1] = 0; 315 cdb[2] = 0; 316 cdb[3] = (len & 0xff00) >> 8; 317 cdb[4] = (len & 0x00ff); 318 cdb[5] = 0; 319 320 if (inq != NULL) 321 bzero(inq, sizeof (*inq)); 322 bcopy(cdb, pkt->pkt_cdbp, CDB_GROUP0); 323 bzero((struct scsi_inquiry *)b->b_un.b_addr, sizeof (*inq)); 324 325 if ((ret = scsi_poll(pkt)) == 0 && inq != NULL) 326 bcopy(b->b_un.b_addr, inq, sizeof (*inq)); 327 328 scsi_destroy_pkt(pkt); 329 330 free_buf: 331 scsi_free_consistent_buf(b); 332 333 return (ret); 334 } 335 336 static int 337 pvscsi_config_one(dev_info_t *pdip, pvscsi_softc_t *pvs, int target, 338 dev_info_t **childp) 339 { 340 char **compatible = NULL; 341 char *nodename = NULL; 342 dev_info_t *dip; 343 int inqrc; 344 int ncompatible = 0; 345 pvscsi_device_t *devnode; 346 struct scsi_inquiry inq; 347 348 ASSERT(DEVI_BUSY_OWNED(pdip)); 349 350 /* Inquiry target */ 351 inqrc = pvscsi_inquiry_target(pvs, target, &inq); 352 353 /* Find devnode */ 354 for (devnode = list_head(&pvs->devnodes); devnode != NULL; 355 devnode = list_next(&pvs->devnodes, devnode)) { 356 if (devnode->target == target) 357 break; 358 } 359 360 if (devnode != NULL) { 361 if (inqrc != 0) { 362 (void) ndi_devi_offline(devnode->pdip, 363 NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE); 364 list_remove(&pvs->devnodes, devnode); 365 kmem_free(devnode, sizeof (*devnode)); 366 } else if (childp != NULL) { 367 /* Target exists */ 368 *childp = devnode->pdip; 369 } 370 return (NDI_SUCCESS); 371 } else if (inqrc != 0) { 372 /* Target doesn't exist */ 373 return (NDI_FAILURE); 374 } 375 376 scsi_hba_nodename_compatible_get(&inq, NULL, inq.inq_dtype, NULL, 377 &nodename, &compatible, &ncompatible); 378 if (nodename == NULL) 379 goto free_nodename; 380 381 if (ndi_devi_alloc(pdip, nodename, DEVI_SID_NODEID, 382 &dip) != NDI_SUCCESS) { 383 dev_err(pvs->dip, CE_WARN, "!failed to alloc device instance"); 384 goto free_nodename; 385 } 386 387 if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, 388 "device-type", "scsi") != DDI_PROP_SUCCESS || 389 ndi_prop_update_int(DDI_DEV_T_NONE, dip, 390 "target", target) != DDI_PROP_SUCCESS || 391 ndi_prop_update_int(DDI_DEV_T_NONE, dip, 392 "lun", 0) != DDI_PROP_SUCCESS || 393 ndi_prop_update_int(DDI_DEV_T_NONE, dip, 394 "pm-capable", 1) != DDI_PROP_SUCCESS || 395 ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, 396 "compatible", compatible, ncompatible) != DDI_PROP_SUCCESS) { 397 dev_err(pvs->dip, CE_WARN, 398 "!failed to update props for target %d", target); 399 goto free_devi; 400 } 401 402 if ((devnode = kmem_zalloc(sizeof (*devnode), KM_NOSLEEP)) == NULL) 403 goto free_devi; 404 405 if (ndi_devi_online(dip, NDI_ONLINE_ATTACH) != NDI_SUCCESS) { 406 dev_err(pvs->dip, CE_WARN, "!failed to online target %d", 407 target); 408 kmem_free(devnode, sizeof (*devnode)); 409 goto free_devi; 410 } 411 412 devnode->target = target; 413 devnode->pdip = dip; 414 devnode->parent = pdip; 415 list_insert_tail(&pvs->devnodes, devnode); 416 417 if (childp != NULL) 418 *childp = dip; 419 420 scsi_hba_nodename_compatible_free(nodename, compatible); 421 422 return (NDI_SUCCESS); 423 424 free_devi: 425 ndi_prop_remove_all(dip); 426 (void) ndi_devi_free(dip); 427 free_nodename: 428 scsi_hba_nodename_compatible_free(nodename, compatible); 429 430 return (NDI_FAILURE); 431 } 432 433 static int 434 pvscsi_config_all(dev_info_t *pdip, pvscsi_softc_t *pvs) 435 { 436 int target; 437 438 for (target = 0; target < PVSCSI_MAXTGTS; target++) { 439 /* ndi_devi_enter is done in pvscsi_bus_config */ 440 (void) pvscsi_config_one(pdip, pvs, target, NULL); 441 } 442 443 return (NDI_SUCCESS); 444 } 445 446 static pvscsi_cmd_t * 447 pvscsi_process_comp_ring(pvscsi_softc_t *pvs) 448 { 449 pvscsi_cmd_t **pnext_cmd = NULL; 450 pvscsi_cmd_t *cmd; 451 pvscsi_cmd_t *head = NULL; 452 struct PVSCSIRingsState *sdesc = RINGS_STATE(pvs); 453 uint32_t cmp_ne = sdesc->cmpNumEntriesLog2; 454 455 ASSERT(mutex_owned(&pvs->rx_mutex)); 456 457 while (sdesc->cmpConsIdx != sdesc->cmpProdIdx) { 458 pvscsi_cmd_ctx_t *ctx; 459 struct PVSCSIRingCmpDesc *cdesc; 460 461 cdesc = CMP_RING(pvs) + (sdesc->cmpConsIdx & MASK(cmp_ne)); 462 membar_consumer(); 463 464 ctx = pvscsi_resolve_ctx(pvs, cdesc->context); 465 ASSERT(ctx != NULL); 466 467 if ((cmd = ctx->cmd) != NULL) { 468 cmd->next_cmd = NULL; 469 470 /* Save command status for further processing */ 471 cmd->cmp_stat.host_status = cdesc->hostStatus; 472 cmd->cmp_stat.scsi_status = cdesc->scsiStatus; 473 cmd->cmp_stat.data_len = cdesc->dataLen; 474 475 /* Mark this command as arrived from hardware */ 476 cmd->flags |= PVSCSI_FLAG_HW_STATUS; 477 478 if (head == NULL) { 479 head = cmd; 480 head->tail_cmd = cmd; 481 } else { 482 head->tail_cmd = cmd; 483 } 484 485 if (pnext_cmd == NULL) { 486 pnext_cmd = &cmd->next_cmd; 487 } else { 488 *pnext_cmd = cmd; 489 pnext_cmd = &cmd->next_cmd; 490 } 491 } 492 493 membar_consumer(); 494 sdesc->cmpConsIdx++; 495 } 496 497 return (head); 498 } 499 500 static pvscsi_msg_t * 501 pvscsi_process_msg_ring(pvscsi_softc_t *pvs) 502 { 503 pvscsi_msg_t *msg; 504 struct PVSCSIRingsState *sdesc = RINGS_STATE(pvs); 505 struct PVSCSIRingMsgDesc *mdesc; 506 struct PVSCSIMsgDescDevStatusChanged *desc; 507 uint32_t msg_ne = sdesc->msgNumEntriesLog2; 508 509 ASSERT(mutex_owned(&pvs->rx_mutex)); 510 511 if (sdesc->msgProdIdx == sdesc->msgConsIdx) 512 return (NULL); 513 514 mdesc = MSG_RING(pvs) + (sdesc->msgConsIdx & MASK(msg_ne)); 515 membar_consumer(); 516 517 switch (mdesc->type) { 518 case PVSCSI_MSG_DEV_ADDED: 519 case PVSCSI_MSG_DEV_REMOVED: 520 desc = (struct PVSCSIMsgDescDevStatusChanged *)mdesc; 521 msg = kmem_alloc(sizeof (pvscsi_msg_t), KM_NOSLEEP); 522 if (msg == NULL) 523 return (NULL); 524 msg->msg_pvs = pvs; 525 msg->type = mdesc->type; 526 msg->target = desc->target; 527 break; 528 default: 529 dev_err(pvs->dip, CE_WARN, "!unknown msg type: %d", 530 mdesc->type); 531 return (NULL); 532 } 533 534 membar_consumer(); 535 sdesc->msgConsIdx++; 536 537 return (msg); 538 } 539 540 static void 541 pvscsi_handle_msg(void *arg) 542 { 543 pvscsi_msg_t *msg = (pvscsi_msg_t *)arg; 544 dev_info_t *dip = msg->msg_pvs->dip; 545 int circ; 546 547 ndi_devi_enter(dip, &circ); 548 (void) pvscsi_config_one(dip, msg->msg_pvs, msg->target, NULL); 549 ndi_devi_exit(dip, circ); 550 551 kmem_free(msg, sizeof (pvscsi_msg_t)); 552 } 553 554 static int 555 pvscsi_abort_cmd(pvscsi_cmd_t *cmd, pvscsi_cmd_t **pending) 556 { 557 pvscsi_softc_t *pvs = cmd->cmd_pvs; 558 pvscsi_cmd_t *c; 559 pvscsi_cmd_t *done; 560 struct PVSCSICmdDescAbortCmd acmd; 561 562 dev_err(pvs->dip, CE_WARN, "!aborting command %p", (void *)cmd); 563 564 ASSERT(mutex_owned(&pvs->rx_mutex)); 565 ASSERT(mutex_owned(&pvs->tx_mutex)); 566 567 /* Check if the cmd was already completed by the HBA */ 568 *pending = done = pvscsi_process_comp_ring(pvs); 569 for (c = done; c != NULL; c = c->next_cmd) { 570 if (c == cmd) 571 return (CMD_CMPLT); 572 } 573 574 /* Check if cmd was really scheduled by the HBA */ 575 if (pvscsi_lookup_ctx(pvs, cmd) == NULL) 576 return (CMD_CMPLT); 577 578 /* Abort cmd in the HBA */ 579 bzero(&acmd, sizeof (acmd)); 580 acmd.target = cmd->cmd_target; 581 acmd.context = pvscsi_map_ctx(pvs, cmd->ctx); 582 pvscsi_write_cmd_desc(pvs, PVSCSI_CMD_ABORT_CMD, &acmd, sizeof (acmd)); 583 584 /* Check if cmd was completed by the HBA before it could be aborted */ 585 if ((done = pvscsi_process_comp_ring(pvs)) != NULL) { 586 done->tail_cmd->next_cmd = *pending; 587 *pending = done; 588 for (c = done; c != NULL; c = c->next_cmd) { 589 if (c == cmd) 590 return (CMD_CMPLT); 591 } 592 } 593 594 /* Release I/O ctx */ 595 mutex_enter(&pvs->mutex); 596 if (cmd->ctx != NULL) 597 pvscsi_release_ctx(cmd); 598 /* Remove cmd from the queue */ 599 pvscsi_remove_from_queue(cmd); 600 mutex_exit(&pvs->mutex); 601 602 /* Insert cmd at the beginning of the list */ 603 cmd->next_cmd = *pending; 604 *pending = cmd; 605 606 dev_err(pvs->dip, CE_WARN, "!command %p aborted", (void *)cmd); 607 608 return (CMD_ABORTED); 609 } 610 611 static void 612 pvscsi_map_buffers(pvscsi_cmd_t *cmd, struct PVSCSIRingReqDesc *rdesc) 613 { 614 int i; 615 616 ASSERT(cmd->ctx); 617 ASSERT(cmd->cmd_dmaccount > 0 && cmd->cmd_dmaccount <= 618 PVSCSI_MAX_SG_SIZE); 619 620 rdesc->dataLen = cmd->cmd_dma_count; 621 rdesc->dataAddr = 0; 622 623 if (cmd->cmd_dma_count == 0) 624 return; 625 626 if (cmd->cmd_dmaccount > 1) { 627 struct PVSCSISGElement *sgl = CMD_CTX_SGLIST_VA(cmd->ctx); 628 629 for (i = 0; i < cmd->cmd_dmaccount; i++) { 630 sgl[i].addr = cmd->cached_cookies[i].dmac_laddress; 631 sgl[i].length = cmd->cached_cookies[i].dmac_size; 632 sgl[i].flags = 0; 633 } 634 rdesc->flags |= PVSCSI_FLAG_CMD_WITH_SG_LIST; 635 rdesc->dataAddr = (uint64_t)CMD_CTX_SGLIST_PA(cmd->ctx); 636 } else { 637 rdesc->dataAddr = cmd->cached_cookies[0].dmac_laddress; 638 } 639 } 640 641 static void 642 pvscsi_comp_cmd(pvscsi_cmd_t *cmd, uint8_t status) 643 { 644 struct scsi_pkt *pkt = CMD2PKT(cmd); 645 646 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 647 STATE_GOT_STATUS); 648 if ((cmd->flags & PVSCSI_FLAG_DMA_VALID) != 0) 649 pkt->pkt_state |= STATE_XFERRED_DATA; 650 pkt->pkt_reason = CMD_CMPLT; 651 pkt->pkt_resid = 0; 652 *(pkt->pkt_scbp) = status; 653 } 654 655 static void 656 pvscsi_set_status(pvscsi_cmd_t *cmd) 657 { 658 pvscsi_softc_t *pvs = cmd->cmd_pvs; 659 struct scsi_pkt *pkt = CMD2PKT(cmd); 660 uchar_t scsi_status = cmd->cmp_stat.scsi_status; 661 uint32_t host_status = cmd->cmp_stat.host_status; 662 663 if (scsi_status != STATUS_GOOD && 664 (host_status == BTSTAT_SUCCESS || 665 (host_status == BTSTAT_LINKED_COMMAND_COMPLETED) || 666 (host_status == BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG))) { 667 if (scsi_status == STATUS_CHECK) { 668 struct scsi_arq_status *astat = (void*)(pkt->pkt_scbp); 669 uint8_t *sensedata; 670 int arq_size; 671 672 *pkt->pkt_scbp = scsi_status; 673 pkt->pkt_state |= STATE_ARQ_DONE; 674 675 if ((cmd->flags & PVSCSI_FLAG_XARQ) != 0) { 676 arq_size = (cmd->cmd_rqslen >= 677 SENSE_BUFFER_SIZE) ? SENSE_BUFFER_SIZE : 678 cmd->cmd_rqslen; 679 680 astat->sts_rqpkt_resid = SENSE_BUFFER_SIZE - 681 arq_size; 682 sensedata = (uint8_t *)&astat->sts_sensedata; 683 bcopy(cmd->arqbuf->b_un.b_addr, sensedata, 684 arq_size); 685 686 pkt->pkt_state |= STATE_XARQ_DONE; 687 } else { 688 astat->sts_rqpkt_resid = 0; 689 } 690 691 astat->sts_rqpkt_statistics = 0; 692 astat->sts_rqpkt_reason = CMD_CMPLT; 693 (*(uint8_t *)&astat->sts_rqpkt_status) = STATUS_GOOD; 694 astat->sts_rqpkt_state = STATE_GOT_BUS | 695 STATE_GOT_TARGET | STATE_SENT_CMD | 696 STATE_XFERRED_DATA | STATE_GOT_STATUS; 697 } 698 pvscsi_comp_cmd(cmd, scsi_status); 699 700 return; 701 } 702 703 switch (host_status) { 704 case BTSTAT_SUCCESS: 705 case BTSTAT_LINKED_COMMAND_COMPLETED: 706 case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG: 707 pvscsi_comp_cmd(cmd, STATUS_GOOD); 708 break; 709 case BTSTAT_DATARUN: 710 pkt->pkt_reason = CMD_DATA_OVR; 711 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 712 STATE_SENT_CMD | STATE_GOT_STATUS | 713 STATE_XFERRED_DATA); 714 pkt->pkt_resid = 0; 715 break; 716 case BTSTAT_DATA_UNDERRUN: 717 pkt->pkt_reason = pkt->pkt_state |= (STATE_GOT_BUS | 718 STATE_GOT_TARGET | STATE_SENT_CMD | STATE_GOT_STATUS); 719 pkt->pkt_resid = cmd->dma_count - cmd->cmp_stat.data_len; 720 if (pkt->pkt_resid != cmd->dma_count) 721 pkt->pkt_state |= STATE_XFERRED_DATA; 722 break; 723 case BTSTAT_SELTIMEO: 724 pkt->pkt_reason = CMD_DEV_GONE; 725 pkt->pkt_state |= STATE_GOT_BUS; 726 break; 727 case BTSTAT_TAGREJECT: 728 pkt->pkt_reason = CMD_TAG_REJECT; 729 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 730 STATE_SENT_CMD | STATE_GOT_STATUS); 731 break; 732 case BTSTAT_BADMSG: 733 pkt->pkt_reason = CMD_BADMSG; 734 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 735 STATE_SENT_CMD | STATE_GOT_STATUS); 736 break; 737 case BTSTAT_SENTRST: 738 case BTSTAT_RECVRST: 739 case BTSTAT_BUSRESET: 740 pkt->pkt_reason = CMD_RESET; 741 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 742 STATE_SENT_CMD | STATE_GOT_STATUS); 743 break; 744 case BTSTAT_ABORTQUEUE: 745 pkt->pkt_reason = CMD_ABORTED; 746 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 747 STATE_SENT_CMD | STATE_GOT_STATUS); 748 break; 749 case BTSTAT_HAHARDWARE: 750 case BTSTAT_INVPHASE: 751 case BTSTAT_HATIMEOUT: 752 case BTSTAT_NORESPONSE: 753 case BTSTAT_DISCONNECT: 754 case BTSTAT_HASOFTWARE: 755 case BTSTAT_BUSFREE: 756 case BTSTAT_SENSFAILED: 757 pkt->pkt_reason = CMD_TRAN_ERR; 758 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 759 STATE_SENT_CMD | STATE_GOT_STATUS); 760 break; 761 default: 762 dev_err(pvs->dip, CE_WARN, 763 "!unknown host status code: %d", host_status); 764 pkt->pkt_reason = CMD_TRAN_ERR; 765 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 766 STATE_SENT_CMD | STATE_GOT_STATUS); 767 break; 768 } 769 } 770 771 static void 772 pvscsi_complete_chained(void *arg) 773 { 774 pvscsi_cmd_t *cmd = (pvscsi_cmd_t *)arg; 775 pvscsi_cmd_t *c; 776 struct scsi_pkt *pkt; 777 778 while (cmd != NULL) { 779 pvscsi_softc_t *pvs = cmd->cmd_pvs; 780 781 c = cmd->next_cmd; 782 cmd->next_cmd = NULL; 783 784 pkt = CMD2PKT(cmd); 785 if (pkt == NULL) 786 return; 787 788 if ((cmd->flags & PVSCSI_FLAG_IO_IOPB) != 0 && 789 (cmd->flags & PVSCSI_FLAG_IO_READ) != 0) { 790 (void) ddi_dma_sync(cmd->cmd_dmahdl, 0, 0, 791 DDI_DMA_SYNC_FORCPU); 792 } 793 794 mutex_enter(&pvs->mutex); 795 /* Release I/O ctx */ 796 if (cmd->ctx != NULL) 797 pvscsi_release_ctx(cmd); 798 /* Remove command from queue */ 799 pvscsi_remove_from_queue(cmd); 800 mutex_exit(&pvs->mutex); 801 802 if ((cmd->flags & PVSCSI_FLAG_HW_STATUS) != 0) { 803 pvscsi_set_status(cmd); 804 } else { 805 ASSERT((cmd->flags & PVSCSI_FLAGS_NON_HW_COMPLETION) != 806 0); 807 808 if ((cmd->flags & PVSCSI_FLAG_TIMED_OUT) != 0) { 809 cmd->pkt->pkt_reason = CMD_TIMEOUT; 810 cmd->pkt->pkt_statistics |= 811 (STAT_TIMEOUT | STAT_ABORTED); 812 } else if ((cmd->flags & PVSCSI_FLAG_ABORTED) != 0) { 813 cmd->pkt->pkt_reason = CMD_ABORTED; 814 cmd->pkt->pkt_statistics |= 815 (STAT_TIMEOUT | STAT_ABORTED); 816 } else if ((cmd->flags & PVSCSI_FLAGS_RESET) != 0) { 817 cmd->pkt->pkt_reason = CMD_RESET; 818 if ((cmd->flags & PVSCSI_FLAG_RESET_BUS) != 0) { 819 cmd->pkt->pkt_statistics |= 820 STAT_BUS_RESET; 821 } else { 822 cmd->pkt->pkt_statistics |= 823 STAT_DEV_RESET; 824 } 825 } 826 } 827 828 cmd->flags |= PVSCSI_FLAG_DONE; 829 cmd->flags &= ~PVSCSI_FLAG_TRANSPORT; 830 831 if ((pkt->pkt_flags & FLAG_NOINTR) == 0 && 832 pkt->pkt_comp != NULL) 833 (*pkt->pkt_comp)(pkt); 834 835 cmd = c; 836 } 837 } 838 839 static void 840 pvscsi_dev_reset(pvscsi_softc_t *pvs, int target) 841 { 842 struct PVSCSICmdDescResetDevice cmd = { 0 }; 843 844 cmd.target = target; 845 pvscsi_write_cmd_desc(pvs, PVSCSI_CMD_RESET_DEVICE, &cmd, sizeof (cmd)); 846 } 847 848 static int 849 pvscsi_poll_cmd(pvscsi_softc_t *pvs, pvscsi_cmd_t *cmd) 850 { 851 boolean_t seen_intr; 852 int cycles = (cmd->pkt->pkt_time * 1000000) / USECS_TO_WAIT; 853 int i; 854 pvscsi_cmd_t *dcmd; 855 struct scsi_pkt *pkt = CMD2PKT(cmd); 856 857 /* 858 * Make sure we're not missing any commands completed 859 * concurrently before we have actually disabled interrupts. 860 */ 861 mutex_enter(&pvs->rx_mutex); 862 dcmd = pvscsi_process_comp_ring(pvs); 863 mutex_exit(&pvs->rx_mutex); 864 865 pvscsi_complete_chained(dcmd); 866 867 while ((cmd->flags & PVSCSI_FLAG_DONE) == 0) { 868 seen_intr = B_FALSE; 869 870 /* Disable interrupts from H/W */ 871 pvscsi_mask_intr(pvs); 872 873 /* Wait for interrupt to arrive */ 874 for (i = 0; i < cycles; i++) { 875 uint32_t status; 876 877 mutex_enter(&pvs->rx_mutex); 878 mutex_enter(&pvs->intr_mutex); 879 status = pvscsi_read_intr_status(pvs); 880 if ((status & PVSCSI_INTR_ALL_SUPPORTED) != 0) { 881 /* Check completion ring */ 882 mutex_exit(&pvs->intr_mutex); 883 dcmd = pvscsi_process_comp_ring(pvs); 884 mutex_exit(&pvs->rx_mutex); 885 seen_intr = B_TRUE; 886 break; 887 } else { 888 mutex_exit(&pvs->intr_mutex); 889 mutex_exit(&pvs->rx_mutex); 890 drv_usecwait(USECS_TO_WAIT); 891 } 892 } 893 894 /* Enable interrupts from H/W */ 895 pvscsi_unmask_intr(pvs); 896 897 if (!seen_intr) { 898 /* No interrupts seen from device during the timeout */ 899 mutex_enter(&pvs->tx_mutex); 900 mutex_enter(&pvs->rx_mutex); 901 if ((cmd->flags & PVSCSI_FLAGS_COMPLETION) != 0) { 902 /* Command was cancelled asynchronously */ 903 dcmd = NULL; 904 } else if ((pvscsi_abort_cmd(cmd, 905 &dcmd)) == CMD_ABORTED) { 906 /* Command was cancelled in hardware */ 907 pkt->pkt_state |= (STAT_TIMEOUT | STAT_ABORTED); 908 pkt->pkt_statistics |= (STAT_TIMEOUT | 909 STAT_ABORTED); 910 pkt->pkt_reason = CMD_TIMEOUT; 911 } 912 mutex_exit(&pvs->rx_mutex); 913 mutex_exit(&pvs->tx_mutex); 914 915 /* 916 * Complete commands that might be on completion list. 917 * Target command can also be on the list in case it was 918 * completed before it could be actually cancelled. 919 */ 920 break; 921 } 922 923 pvscsi_complete_chained(dcmd); 924 925 if (!seen_intr) 926 break; 927 } 928 929 return (TRAN_ACCEPT); 930 } 931 932 static void 933 pvscsi_abort_all(struct scsi_address *ap, pvscsi_softc_t *pvs, 934 pvscsi_cmd_t **pending, int marker_flag) 935 { 936 int qlen = pvs->cmd_queue_len; 937 pvscsi_cmd_t *cmd, *pcmd, *phead = NULL; 938 939 ASSERT(mutex_owned(&pvs->rx_mutex)); 940 ASSERT(mutex_owned(&pvs->tx_mutex)); 941 942 /* 943 * Try to abort all queued commands, merging commands waiting 944 * for completion into a single list to complete them at one 945 * time when mutex is released. 946 */ 947 while (qlen > 0) { 948 mutex_enter(&pvs->mutex); 949 cmd = list_remove_head(&pvs->cmd_queue); 950 ASSERT(cmd != NULL); 951 952 qlen--; 953 954 if (ap == NULL || ap->a_target == cmd->cmd_target) { 955 int c = --pvs->cmd_queue_len; 956 957 mutex_exit(&pvs->mutex); 958 959 if (pvscsi_abort_cmd(cmd, &pcmd) == CMD_ABORTED) { 960 /* 961 * Assume command is completely cancelled now, 962 * so mark it as requested. 963 */ 964 cmd->flags |= marker_flag; 965 } 966 967 qlen -= (c - pvs->cmd_queue_len); 968 969 /* 970 * Now merge current pending commands with 971 * previous ones. 972 */ 973 if (phead == NULL) { 974 phead = pcmd; 975 } else if (pcmd != NULL) { 976 phead->tail_cmd->next_cmd = pcmd; 977 phead->tail_cmd = pcmd->tail_cmd; 978 } 979 } else { 980 list_insert_tail(&pvs->cmd_queue, cmd); 981 mutex_exit(&pvs->mutex); 982 } 983 } 984 985 *pending = phead; 986 } 987 988 static void 989 pvscsi_quiesce_notify(pvscsi_softc_t *pvs) 990 { 991 mutex_enter(&pvs->mutex); 992 if (pvs->cmd_queue_len == 0 && 993 (pvs->flags & PVSCSI_HBA_QUIESCE_PENDING) != 0) { 994 pvs->flags &= ~PVSCSI_HBA_QUIESCE_PENDING; 995 cv_broadcast(&pvs->quiescevar); 996 } 997 mutex_exit(&pvs->mutex); 998 } 999 1000 static int 1001 pvscsi_transport_command(pvscsi_softc_t *pvs, pvscsi_cmd_t *cmd) 1002 { 1003 struct PVSCSIRingReqDesc *rdesc; 1004 struct PVSCSIRingsState *sdesc = RINGS_STATE(pvs); 1005 struct scsi_pkt *pkt = CMD2PKT(cmd); 1006 uint32_t req_ne = sdesc->reqNumEntriesLog2; 1007 1008 mutex_enter(&pvs->tx_mutex); 1009 mutex_enter(&pvs->mutex); 1010 if (!pvscsi_acquire_ctx(pvs, cmd)) { 1011 mutex_exit(&pvs->mutex); 1012 mutex_exit(&pvs->tx_mutex); 1013 dev_err(pvs->dip, CE_WARN, "!no free ctx available"); 1014 return (TRAN_BUSY); 1015 } 1016 1017 if ((sdesc->reqProdIdx - sdesc->cmpConsIdx) >= (1 << req_ne)) { 1018 pvscsi_release_ctx(cmd); 1019 mutex_exit(&pvs->mutex); 1020 mutex_exit(&pvs->tx_mutex); 1021 dev_err(pvs->dip, CE_WARN, "!no free I/O slots available"); 1022 return (TRAN_BUSY); 1023 } 1024 mutex_exit(&pvs->mutex); 1025 1026 cmd->flags |= PVSCSI_FLAG_TRANSPORT; 1027 1028 rdesc = REQ_RING(pvs) + (sdesc->reqProdIdx & MASK(req_ne)); 1029 1030 bzero(&rdesc->lun, sizeof (rdesc->lun)); 1031 1032 rdesc->bus = 0; 1033 rdesc->target = cmd->cmd_target; 1034 1035 if ((cmd->flags & PVSCSI_FLAG_XARQ) != 0) { 1036 bzero((void*)cmd->arqbuf->b_un.b_addr, SENSE_BUFFER_SIZE); 1037 rdesc->senseLen = SENSE_BUFFER_SIZE; 1038 rdesc->senseAddr = cmd->arqc.dmac_laddress; 1039 } else { 1040 rdesc->senseLen = 0; 1041 rdesc->senseAddr = 0; 1042 } 1043 1044 rdesc->vcpuHint = CPU->cpu_id; 1045 rdesc->cdbLen = cmd->cmdlen; 1046 bcopy(cmd->cmd_cdb, rdesc->cdb, cmd->cmdlen); 1047 1048 /* Setup tag info */ 1049 if ((cmd->flags & PVSCSI_FLAG_TAG) != 0) 1050 rdesc->tag = cmd->tag; 1051 else 1052 rdesc->tag = MSG_SIMPLE_QTAG; 1053 1054 /* Setup I/O direction and map data buffers */ 1055 if ((cmd->flags & PVSCSI_FLAG_DMA_VALID) != 0) { 1056 if ((cmd->flags & PVSCSI_FLAG_IO_READ) != 0) 1057 rdesc->flags = PVSCSI_FLAG_CMD_DIR_TOHOST; 1058 else 1059 rdesc->flags = PVSCSI_FLAG_CMD_DIR_TODEVICE; 1060 pvscsi_map_buffers(cmd, rdesc); 1061 } else { 1062 rdesc->flags = 0; 1063 } 1064 1065 rdesc->context = pvscsi_map_ctx(pvs, cmd->ctx); 1066 membar_producer(); 1067 1068 sdesc->reqProdIdx++; 1069 membar_producer(); 1070 1071 mutex_enter(&pvs->mutex); 1072 cmd->timeout_lbolt = ddi_get_lbolt() + SEC_TO_TICK(pkt->pkt_time); 1073 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD); 1074 pvscsi_add_to_queue(cmd); 1075 1076 switch (cmd->pkt->pkt_cdbp[0]) { 1077 case SCMD_READ: 1078 case SCMD_WRITE: 1079 case SCMD_READ_G1: 1080 case SCMD_WRITE_G1: 1081 case SCMD_READ_G4: 1082 case SCMD_WRITE_G4: 1083 case SCMD_READ_G5: 1084 case SCMD_WRITE_G5: 1085 ASSERT((cmd->flags & PVSCSI_FLAG_DMA_VALID) != 0); 1086 pvscsi_submit_rw_io(pvs); 1087 break; 1088 default: 1089 pvscsi_submit_nonrw_io(pvs); 1090 break; 1091 } 1092 mutex_exit(&pvs->mutex); 1093 mutex_exit(&pvs->tx_mutex); 1094 1095 return (TRAN_ACCEPT); 1096 } 1097 1098 static int 1099 pvscsi_reset_generic(pvscsi_softc_t *pvs, struct scsi_address *ap) 1100 { 1101 boolean_t bus_reset = (ap == NULL); 1102 int flags; 1103 pvscsi_cmd_t *done, *aborted; 1104 1105 flags = bus_reset ? PVSCSI_FLAG_RESET_BUS : PVSCSI_FLAG_RESET_DEV; 1106 1107 mutex_enter(&pvs->tx_mutex); 1108 mutex_enter(&pvs->rx_mutex); 1109 /* Try to process pending requests */ 1110 done = pvscsi_process_comp_ring(pvs); 1111 1112 /* Abort all pending requests */ 1113 pvscsi_abort_all(ap, pvs, &aborted, flags); 1114 1115 /* Reset at hardware level */ 1116 if (bus_reset) { 1117 pvscsi_reset_bus(pvs); 1118 /* Should never happen after bus reset */ 1119 ASSERT(pvscsi_process_comp_ring(pvs) == NULL); 1120 } else { 1121 pvscsi_dev_reset(pvs, ap->a_target); 1122 } 1123 mutex_exit(&pvs->rx_mutex); 1124 mutex_exit(&pvs->tx_mutex); 1125 1126 pvscsi_complete_chained(done); 1127 pvscsi_complete_chained(aborted); 1128 1129 return (1); 1130 } 1131 1132 static void 1133 pvscsi_cmd_ext_free(pvscsi_cmd_t *cmd) 1134 { 1135 struct scsi_pkt *pkt = CMD2PKT(cmd); 1136 1137 if ((cmd->flags & PVSCSI_FLAG_CDB_EXT) != 0) { 1138 kmem_free(pkt->pkt_cdbp, cmd->cmdlen); 1139 cmd->flags &= ~PVSCSI_FLAG_CDB_EXT; 1140 } 1141 if ((cmd->flags & PVSCSI_FLAG_SCB_EXT) != 0) { 1142 kmem_free(pkt->pkt_scbp, cmd->statuslen); 1143 cmd->flags &= ~PVSCSI_FLAG_SCB_EXT; 1144 } 1145 if ((cmd->flags & PVSCSI_FLAG_PRIV_EXT) != 0) { 1146 kmem_free(pkt->pkt_private, cmd->tgtlen); 1147 cmd->flags &= ~PVSCSI_FLAG_PRIV_EXT; 1148 } 1149 } 1150 1151 /* ARGSUSED pvs */ 1152 static int 1153 pvscsi_cmd_ext_alloc(pvscsi_softc_t *pvs, pvscsi_cmd_t *cmd, int kf) 1154 { 1155 struct scsi_pkt *pkt = CMD2PKT(cmd); 1156 void *buf; 1157 1158 if (cmd->cmdlen > sizeof (cmd->cmd_cdb)) { 1159 if ((buf = kmem_zalloc(cmd->cmdlen, kf)) == NULL) 1160 return (DDI_FAILURE); 1161 pkt->pkt_cdbp = buf; 1162 cmd->flags |= PVSCSI_FLAG_CDB_EXT; 1163 } 1164 1165 if (cmd->statuslen > sizeof (cmd->cmd_scb)) { 1166 if ((buf = kmem_zalloc(cmd->statuslen, kf)) == NULL) 1167 goto out; 1168 pkt->pkt_scbp = buf; 1169 cmd->flags |= PVSCSI_FLAG_SCB_EXT; 1170 cmd->cmd_rqslen = (cmd->statuslen - sizeof (cmd->cmd_scb)); 1171 } 1172 1173 if (cmd->tgtlen > sizeof (cmd->tgt_priv)) { 1174 if ((buf = kmem_zalloc(cmd->tgtlen, kf)) == NULL) 1175 goto out; 1176 pkt->pkt_private = buf; 1177 cmd->flags |= PVSCSI_FLAG_PRIV_EXT; 1178 } 1179 1180 return (DDI_SUCCESS); 1181 1182 out: 1183 pvscsi_cmd_ext_free(cmd); 1184 1185 return (DDI_FAILURE); 1186 } 1187 1188 static int 1189 pvscsi_setup_dma_buffer(pvscsi_softc_t *pvs, size_t length, 1190 pvscsi_dma_buf_t *buf) 1191 { 1192 ddi_dma_cookie_t cookie; 1193 uint_t ccount; 1194 1195 if ((ddi_dma_alloc_handle(pvs->dip, &pvscsi_ring_dma_attr, 1196 DDI_DMA_SLEEP, NULL, &buf->dma_handle)) != DDI_SUCCESS) { 1197 dev_err(pvs->dip, CE_WARN, "!failed to allocate DMA handle"); 1198 return (DDI_FAILURE); 1199 } 1200 1201 if ((ddi_dma_mem_alloc(buf->dma_handle, length, &pvscsi_dma_attrs, 1202 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &buf->addr, 1203 &buf->real_length, &buf->acc_handle)) != DDI_SUCCESS) { 1204 dev_err(pvs->dip, CE_WARN, 1205 "!failed to allocate %ld bytes for DMA buffer", length); 1206 ddi_dma_free_handle(&buf->dma_handle); 1207 return (DDI_FAILURE); 1208 } 1209 1210 if ((ddi_dma_addr_bind_handle(buf->dma_handle, NULL, buf->addr, 1211 buf->real_length, DDI_DMA_CONSISTENT | DDI_DMA_RDWR, DDI_DMA_SLEEP, 1212 NULL, &cookie, &ccount)) != DDI_SUCCESS) { 1213 dev_err(pvs->dip, CE_WARN, "!failed to bind DMA buffer"); 1214 ddi_dma_free_handle(&buf->dma_handle); 1215 ddi_dma_mem_free(&buf->acc_handle); 1216 return (DDI_FAILURE); 1217 } 1218 1219 /* TODO Support multipart SG regions */ 1220 ASSERT(ccount == 1); 1221 1222 buf->pa = cookie.dmac_laddress; 1223 1224 return (DDI_SUCCESS); 1225 } 1226 1227 static void 1228 pvscsi_free_dma_buffer(pvscsi_dma_buf_t *buf) 1229 { 1230 ddi_dma_free_handle(&buf->dma_handle); 1231 ddi_dma_mem_free(&buf->acc_handle); 1232 } 1233 1234 static int 1235 pvscsi_setup_sg(pvscsi_softc_t *pvs) 1236 { 1237 int i; 1238 pvscsi_cmd_ctx_t *ctx; 1239 size_t size = pvs->req_depth * sizeof (pvscsi_cmd_ctx_t); 1240 1241 ctx = pvs->cmd_ctx = kmem_zalloc(size, KM_SLEEP); 1242 1243 for (i = 0; i < pvs->req_depth; ++i, ++ctx) { 1244 list_insert_tail(&pvs->cmd_ctx_pool, ctx); 1245 if (pvscsi_setup_dma_buffer(pvs, PAGE_SIZE, 1246 &ctx->dma_buf) != DDI_SUCCESS) 1247 goto cleanup; 1248 } 1249 1250 return (DDI_SUCCESS); 1251 1252 cleanup: 1253 for (; i >= 0; --i, --ctx) { 1254 list_remove(&pvs->cmd_ctx_pool, ctx); 1255 pvscsi_free_dma_buffer(&ctx->dma_buf); 1256 } 1257 kmem_free(pvs->cmd_ctx, size); 1258 1259 return (DDI_FAILURE); 1260 } 1261 1262 static void 1263 pvscsi_free_sg(pvscsi_softc_t *pvs) 1264 { 1265 int i; 1266 pvscsi_cmd_ctx_t *ctx = pvs->cmd_ctx; 1267 1268 for (i = 0; i < pvs->req_depth; ++i, ++ctx) { 1269 list_remove(&pvs->cmd_ctx_pool, ctx); 1270 pvscsi_free_dma_buffer(&ctx->dma_buf); 1271 } 1272 1273 kmem_free(pvs->cmd_ctx, pvs->req_pages << PAGE_SHIFT); 1274 } 1275 1276 static int 1277 pvscsi_allocate_rings(pvscsi_softc_t *pvs) 1278 { 1279 /* Allocate DMA buffer for rings state */ 1280 if (pvscsi_setup_dma_buffer(pvs, PAGE_SIZE, 1281 &pvs->rings_state_buf) != DDI_SUCCESS) 1282 return (DDI_FAILURE); 1283 1284 /* Allocate DMA buffer for request ring */ 1285 pvs->req_pages = MIN(pvscsi_ring_pages, PVSCSI_MAX_NUM_PAGES_REQ_RING); 1286 pvs->req_depth = pvs->req_pages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE; 1287 if (pvscsi_setup_dma_buffer(pvs, pvs->req_pages * PAGE_SIZE, 1288 &pvs->req_ring_buf) != DDI_SUCCESS) 1289 goto free_rings_state; 1290 1291 /* Allocate completion ring */ 1292 pvs->cmp_pages = MIN(pvscsi_ring_pages, PVSCSI_MAX_NUM_PAGES_CMP_RING); 1293 if (pvscsi_setup_dma_buffer(pvs, pvs->cmp_pages * PAGE_SIZE, 1294 &pvs->cmp_ring_buf) != DDI_SUCCESS) 1295 goto free_req_buf; 1296 1297 /* Allocate message ring */ 1298 pvs->msg_pages = MIN(pvscsi_msg_ring_pages, 1299 PVSCSI_MAX_NUM_PAGES_MSG_RING); 1300 if (pvscsi_setup_dma_buffer(pvs, pvs->msg_pages * PAGE_SIZE, 1301 &pvs->msg_ring_buf) != DDI_SUCCESS) 1302 goto free_cmp_buf; 1303 1304 return (DDI_SUCCESS); 1305 1306 free_cmp_buf: 1307 pvscsi_free_dma_buffer(&pvs->cmp_ring_buf); 1308 free_req_buf: 1309 pvscsi_free_dma_buffer(&pvs->req_ring_buf); 1310 free_rings_state: 1311 pvscsi_free_dma_buffer(&pvs->rings_state_buf); 1312 1313 return (DDI_FAILURE); 1314 } 1315 1316 static void 1317 pvscsi_free_rings(pvscsi_softc_t *pvs) 1318 { 1319 pvscsi_free_dma_buffer(&pvs->msg_ring_buf); 1320 pvscsi_free_dma_buffer(&pvs->cmp_ring_buf); 1321 pvscsi_free_dma_buffer(&pvs->req_ring_buf); 1322 pvscsi_free_dma_buffer(&pvs->rings_state_buf); 1323 } 1324 1325 static void 1326 pvscsi_setup_rings(pvscsi_softc_t *pvs) 1327 { 1328 int i; 1329 struct PVSCSICmdDescSetupMsgRing cmd_msg = { 0 }; 1330 struct PVSCSICmdDescSetupRings cmd = { 0 }; 1331 uint64_t base; 1332 1333 cmd.ringsStatePPN = pvs->rings_state_buf.pa >> PAGE_SHIFT; 1334 cmd.reqRingNumPages = pvs->req_pages; 1335 cmd.cmpRingNumPages = pvs->cmp_pages; 1336 1337 /* Setup request ring */ 1338 base = pvs->req_ring_buf.pa; 1339 for (i = 0; i < pvs->req_pages; i++) { 1340 cmd.reqRingPPNs[i] = base >> PAGE_SHIFT; 1341 base += PAGE_SIZE; 1342 } 1343 1344 /* Setup completion ring */ 1345 base = pvs->cmp_ring_buf.pa; 1346 for (i = 0; i < pvs->cmp_pages; i++) { 1347 cmd.cmpRingPPNs[i] = base >> PAGE_SHIFT; 1348 base += PAGE_SIZE; 1349 } 1350 1351 bzero(RINGS_STATE(pvs), PAGE_SIZE); 1352 bzero(REQ_RING(pvs), pvs->req_pages * PAGE_SIZE); 1353 bzero(CMP_RING(pvs), pvs->cmp_pages * PAGE_SIZE); 1354 1355 /* Issue SETUP command */ 1356 pvscsi_write_cmd_desc(pvs, PVSCSI_CMD_SETUP_RINGS, &cmd, sizeof (cmd)); 1357 1358 /* Setup message ring */ 1359 cmd_msg.numPages = pvs->msg_pages; 1360 base = pvs->msg_ring_buf.pa; 1361 1362 for (i = 0; i < pvs->msg_pages; i++) { 1363 cmd_msg.ringPPNs[i] = base >> PAGE_SHIFT; 1364 base += PAGE_SIZE; 1365 } 1366 bzero(MSG_RING(pvs), pvs->msg_pages * PAGE_SIZE); 1367 1368 pvscsi_write_cmd_desc(pvs, PVSCSI_CMD_SETUP_MSG_RING, &cmd_msg, 1369 sizeof (cmd_msg)); 1370 } 1371 1372 static int 1373 pvscsi_setup_io(pvscsi_softc_t *pvs) 1374 { 1375 int offset, rcount, rn, type; 1376 int ret = DDI_FAILURE; 1377 off_t regsize; 1378 pci_regspec_t *regs; 1379 uint_t regs_length; 1380 1381 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, pvs->dip, 1382 DDI_PROP_DONTPASS, "reg", (int **)®s, 1383 ®s_length) != DDI_PROP_SUCCESS) { 1384 dev_err(pvs->dip, CE_WARN, "!failed to lookup 'reg' property"); 1385 return (DDI_FAILURE); 1386 } 1387 1388 rcount = regs_length * sizeof (int) / sizeof (pci_regspec_t); 1389 1390 for (offset = PCI_CONF_BASE0; offset <= PCI_CONF_BASE5; offset += 4) { 1391 for (rn = 0; rn < rcount; ++rn) { 1392 if (PCI_REG_REG_G(regs[rn].pci_phys_hi) == offset) { 1393 type = regs[rn].pci_phys_hi & PCI_ADDR_MASK; 1394 break; 1395 } 1396 } 1397 1398 if (rn >= rcount) 1399 continue; 1400 1401 if (type != PCI_ADDR_IO) { 1402 if (ddi_dev_regsize(pvs->dip, rn, 1403 ®size) != DDI_SUCCESS) { 1404 dev_err(pvs->dip, CE_WARN, 1405 "!failed to get size of reg %d", rn); 1406 goto out; 1407 } 1408 if (regsize == PVSCSI_MEM_SPACE_SIZE) { 1409 if (ddi_regs_map_setup(pvs->dip, rn, 1410 &pvs->mmio_base, 0, 0, 1411 &pvscsi_mmio_attr, 1412 &pvs->mmio_handle) != DDI_SUCCESS) { 1413 dev_err(pvs->dip, CE_WARN, 1414 "!failed to map MMIO BAR"); 1415 goto out; 1416 } 1417 ret = DDI_SUCCESS; 1418 break; 1419 } 1420 } 1421 } 1422 1423 out: 1424 ddi_prop_free(regs); 1425 1426 return (ret); 1427 } 1428 1429 static void 1430 pvscsi_free_io(pvscsi_softc_t *pvs) 1431 { 1432 ddi_regs_map_free(&pvs->mmio_handle); 1433 } 1434 1435 static int 1436 pvscsi_enable_intrs(pvscsi_softc_t *pvs) 1437 { 1438 int i, rc, intr_caps; 1439 1440 if ((rc = ddi_intr_get_cap(pvs->intr_htable[0], &intr_caps)) != 1441 DDI_SUCCESS) { 1442 dev_err(pvs->dip, CE_WARN, "!failed to get interrupt caps"); 1443 return (DDI_FAILURE); 1444 } 1445 1446 if ((intr_caps & DDI_INTR_FLAG_BLOCK) != 0) { 1447 if ((rc = ddi_intr_block_enable(pvs->intr_htable, 1448 pvs->intr_cnt)) != DDI_SUCCESS) { 1449 dev_err(pvs->dip, CE_WARN, 1450 "!failed to enable interrupt block"); 1451 } 1452 } else { 1453 for (i = 0; i < pvs->intr_cnt; i++) { 1454 if ((rc = ddi_intr_enable(pvs->intr_htable[i])) == 1455 DDI_SUCCESS) 1456 continue; 1457 dev_err(pvs->dip, CE_WARN, 1458 "!failed to enable interrupt"); 1459 while (--i >= 0) 1460 (void) ddi_intr_disable(pvs->intr_htable[i]); 1461 break; 1462 } 1463 } 1464 1465 /* Unmask interrupts */ 1466 if (rc == DDI_SUCCESS) { 1467 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_INTR_MASK, 1468 PVSCSI_INTR_CMPL_MASK | PVSCSI_INTR_MSG_MASK); 1469 } 1470 1471 return (rc); 1472 } 1473 1474 /* ARGSUSED arg2 */ 1475 static uint32_t 1476 pvscsi_intr_handler(caddr_t arg1, caddr_t arg2) 1477 { 1478 boolean_t handled; 1479 pvscsi_softc_t *pvs = (pvscsi_softc_t *)arg1; 1480 uint32_t status; 1481 1482 mutex_enter(&pvs->intr_mutex); 1483 if (pvs->num_pollers > 0) { 1484 mutex_exit(&pvs->intr_mutex); 1485 return (DDI_INTR_CLAIMED); 1486 } 1487 1488 if (pvscsi_enable_msi) { 1489 handled = B_TRUE; 1490 } else { 1491 status = pvscsi_read_intr_status(pvs); 1492 handled = (status & PVSCSI_INTR_ALL_SUPPORTED) != 0; 1493 if (handled) 1494 pvscsi_write_intr_status(pvs, status); 1495 } 1496 mutex_exit(&pvs->intr_mutex); 1497 1498 if (handled) { 1499 boolean_t qnotify; 1500 pvscsi_cmd_t *pending; 1501 pvscsi_msg_t *msg; 1502 1503 mutex_enter(&pvs->rx_mutex); 1504 pending = pvscsi_process_comp_ring(pvs); 1505 msg = pvscsi_process_msg_ring(pvs); 1506 mutex_exit(&pvs->rx_mutex); 1507 1508 mutex_enter(&pvs->mutex); 1509 qnotify = HBA_QUIESCE_PENDING(pvs); 1510 mutex_exit(&pvs->mutex); 1511 1512 if (pending != NULL && ddi_taskq_dispatch(pvs->comp_tq, 1513 pvscsi_complete_chained, pending, 1514 DDI_NOSLEEP) == DDI_FAILURE) 1515 pvscsi_complete_chained(pending); 1516 1517 if (msg != NULL && ddi_taskq_dispatch(pvs->msg_tq, 1518 pvscsi_handle_msg, msg, DDI_NOSLEEP) == DDI_FAILURE) { 1519 dev_err(pvs->dip, CE_WARN, 1520 "!failed to process msg type %d for target %d", 1521 msg->type, msg->target); 1522 kmem_free(msg, sizeof (pvscsi_msg_t)); 1523 } 1524 1525 if (qnotify) 1526 pvscsi_quiesce_notify(pvs); 1527 } 1528 1529 return (handled ? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED); 1530 } 1531 1532 static int 1533 pvscsi_register_isr(pvscsi_softc_t *pvs, int type) 1534 { 1535 int navail, nactual; 1536 int i; 1537 1538 if (ddi_intr_get_navail(pvs->dip, type, &navail) != DDI_SUCCESS || 1539 navail == 0) { 1540 dev_err(pvs->dip, CE_WARN, 1541 "!failed to get number of available interrupts of type %d", 1542 type); 1543 return (DDI_FAILURE); 1544 } 1545 navail = MIN(navail, PVSCSI_MAX_INTRS); 1546 1547 pvs->intr_size = navail * sizeof (ddi_intr_handle_t); 1548 if ((pvs->intr_htable = kmem_alloc(pvs->intr_size, KM_SLEEP)) == NULL) { 1549 dev_err(pvs->dip, CE_WARN, 1550 "!failed to allocate %d bytes for interrupt hashtable", 1551 pvs->intr_size); 1552 return (DDI_FAILURE); 1553 } 1554 1555 if (ddi_intr_alloc(pvs->dip, pvs->intr_htable, type, 0, navail, 1556 &nactual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS || nactual == 0) { 1557 dev_err(pvs->dip, CE_WARN, "!failed to allocate %d interrupts", 1558 navail); 1559 goto free_htable; 1560 } 1561 1562 pvs->intr_cnt = nactual; 1563 1564 if (ddi_intr_get_pri(pvs->intr_htable[0], 1565 (uint_t *)&pvs->intr_pri) != DDI_SUCCESS) { 1566 dev_err(pvs->dip, CE_WARN, "!failed to get interrupt priority"); 1567 goto free_intrs; 1568 } 1569 1570 for (i = 0; i < nactual; i++) { 1571 if (ddi_intr_add_handler(pvs->intr_htable[i], 1572 pvscsi_intr_handler, (caddr_t)pvs, NULL) != DDI_SUCCESS) { 1573 dev_err(pvs->dip, CE_WARN, 1574 "!failed to add interrupt handler"); 1575 goto free_intrs; 1576 } 1577 } 1578 1579 return (DDI_SUCCESS); 1580 1581 free_intrs: 1582 for (i = 0; i < nactual; i++) 1583 (void) ddi_intr_free(pvs->intr_htable[i]); 1584 free_htable: 1585 kmem_free(pvs->intr_htable, pvs->intr_size); 1586 1587 return (DDI_FAILURE); 1588 } 1589 1590 static void 1591 pvscsi_free_intr_resources(pvscsi_softc_t *pvs) 1592 { 1593 int i; 1594 1595 for (i = 0; i < pvs->intr_cnt; i++) { 1596 (void) ddi_intr_disable(pvs->intr_htable[i]); 1597 (void) ddi_intr_remove_handler(pvs->intr_htable[i]); 1598 (void) ddi_intr_free(pvs->intr_htable[i]); 1599 } 1600 kmem_free(pvs->intr_htable, pvs->intr_size); 1601 } 1602 1603 static int 1604 pvscsi_setup_isr(pvscsi_softc_t *pvs) 1605 { 1606 int intr_types; 1607 1608 if (ddi_intr_get_supported_types(pvs->dip, 1609 &intr_types) != DDI_SUCCESS) { 1610 dev_err(pvs->dip, CE_WARN, 1611 "!failed to get supported interrupt types"); 1612 return (DDI_FAILURE); 1613 } 1614 1615 if ((intr_types & DDI_INTR_TYPE_MSIX) != 0 && pvscsi_enable_msi) { 1616 if (pvscsi_register_isr(pvs, 1617 DDI_INTR_TYPE_MSIX) == DDI_SUCCESS) { 1618 pvs->intr_type = DDI_INTR_TYPE_MSIX; 1619 } else { 1620 dev_err(pvs->dip, CE_WARN, 1621 "!failed to install MSI-X interrupt handler"); 1622 } 1623 } else if ((intr_types & DDI_INTR_TYPE_MSI) != 0 && pvscsi_enable_msi) { 1624 if (pvscsi_register_isr(pvs, 1625 DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 1626 pvs->intr_type = DDI_INTR_TYPE_MSI; 1627 } else { 1628 dev_err(pvs->dip, CE_WARN, 1629 "!failed to install MSI interrupt handler"); 1630 } 1631 } else if ((intr_types & DDI_INTR_TYPE_FIXED) != 0) { 1632 if (pvscsi_register_isr(pvs, 1633 DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 1634 pvs->intr_type = DDI_INTR_TYPE_FIXED; 1635 } else { 1636 dev_err(pvs->dip, CE_WARN, 1637 "!failed to install FIXED interrupt handler"); 1638 } 1639 } 1640 1641 return (pvs->intr_type == 0 ? DDI_FAILURE : DDI_SUCCESS); 1642 } 1643 1644 static void 1645 pvscsi_wd_thread(pvscsi_softc_t *pvs) 1646 { 1647 clock_t now; 1648 pvscsi_cmd_t *expired, *c, *cn, **pnext; 1649 1650 mutex_enter(&pvs->mutex); 1651 for (;;) { 1652 expired = NULL; 1653 pnext = NULL; 1654 now = ddi_get_lbolt(); 1655 1656 for (c = list_head(&pvs->cmd_queue); c != NULL; ) { 1657 cn = list_next(&pvs->cmd_queue, c); 1658 1659 /* 1660 * Commands with 'FLAG_NOINTR' are watched using their 1661 * own timeouts, so we should not touch them. 1662 */ 1663 if ((c->pkt->pkt_flags & FLAG_NOINTR) == 0 && 1664 now > c->timeout_lbolt) { 1665 dev_err(pvs->dip, CE_WARN, 1666 "!expired command: %p (%ld > %ld)", 1667 (void *)c, now, c->timeout_lbolt); 1668 pvscsi_remove_from_queue(c); 1669 if (expired == NULL) 1670 expired = c; 1671 if (pnext == NULL) { 1672 pnext = &c->next_cmd; 1673 } else { 1674 *pnext = c; 1675 pnext = &c->next_cmd; 1676 } 1677 } 1678 c = cn; 1679 } 1680 mutex_exit(&pvs->mutex); 1681 1682 /* Now cancel all expired commands */ 1683 if (expired != NULL) { 1684 struct scsi_address sa = {0}; 1685 /* Build a fake SCSI address */ 1686 sa.a_hba_tran = pvs->tran; 1687 while (expired != NULL) { 1688 c = expired->next_cmd; 1689 sa.a_target = expired->cmd_target; 1690 sa.a_lun = 0; 1691 (void) pvscsi_abort(&sa, CMD2PKT(expired)); 1692 expired = c; 1693 } 1694 } 1695 1696 mutex_enter(&pvs->mutex); 1697 if ((pvs->flags & PVSCSI_DRIVER_SHUTDOWN) != 0) { 1698 /* Finish job */ 1699 break; 1700 } 1701 if (cv_reltimedwait(&pvs->wd_condvar, &pvs->mutex, 1702 SEC_TO_TICK(1), TR_CLOCK_TICK) > 0) { 1703 /* Explicitly woken up, finish job */ 1704 break; 1705 } 1706 } 1707 1708 /* Confirm thread termination */ 1709 cv_signal(&pvs->syncvar); 1710 mutex_exit(&pvs->mutex); 1711 } 1712 1713 static int 1714 pvscsi_ccache_constructor(void *buf, void *cdrarg, int kmflags) 1715 { 1716 int (*callback)(caddr_t); 1717 uint_t cookiec; 1718 pvscsi_cmd_t *cmd = (pvscsi_cmd_t *)buf; 1719 pvscsi_softc_t *pvs = cdrarg; 1720 struct scsi_address ap; 1721 1722 callback = (kmflags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 1723 ap.a_hba_tran = pvs->tran; 1724 ap.a_target = 0; 1725 ap.a_lun = 0; 1726 1727 /* Allocate a DMA handle for data transfers */ 1728 if ((ddi_dma_alloc_handle(pvs->dip, &pvs->io_dma_attr, callback, 1729 NULL, &cmd->cmd_dmahdl)) != DDI_SUCCESS) { 1730 dev_err(pvs->dip, CE_WARN, "!failed to allocate DMA handle"); 1731 return (-1); 1732 } 1733 1734 /* Setup ARQ buffer */ 1735 if ((cmd->arqbuf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL, 1736 SENSE_BUFFER_SIZE, B_READ, callback, NULL)) == NULL) { 1737 dev_err(pvs->dip, CE_WARN, "!failed to allocate ARQ buffer"); 1738 goto free_handle; 1739 } 1740 1741 if (ddi_dma_alloc_handle(pvs->dip, &pvs->hba_dma_attr, 1742 callback, NULL, &cmd->arqhdl) != DDI_SUCCESS) { 1743 dev_err(pvs->dip, CE_WARN, 1744 "!failed to allocate DMA handle for ARQ buffer"); 1745 goto free_arqbuf; 1746 } 1747 1748 if (ddi_dma_buf_bind_handle(cmd->arqhdl, cmd->arqbuf, 1749 (DDI_DMA_READ | DDI_DMA_CONSISTENT), callback, NULL, 1750 &cmd->arqc, &cookiec) != DDI_SUCCESS) { 1751 dev_err(pvs->dip, CE_WARN, "!failed to bind ARQ buffer"); 1752 goto free_arqhdl; 1753 } 1754 1755 return (0); 1756 1757 free_arqhdl: 1758 ddi_dma_free_handle(&cmd->arqhdl); 1759 free_arqbuf: 1760 scsi_free_consistent_buf(cmd->arqbuf); 1761 free_handle: 1762 ddi_dma_free_handle(&cmd->cmd_dmahdl); 1763 1764 return (-1); 1765 } 1766 1767 /* ARGSUSED cdrarg */ 1768 static void 1769 pvscsi_ccache_destructor(void *buf, void *cdrarg) 1770 { 1771 pvscsi_cmd_t *cmd = (pvscsi_cmd_t *)buf; 1772 1773 if (cmd->cmd_dmahdl != NULL) { 1774 (void) ddi_dma_unbind_handle(cmd->cmd_dmahdl); 1775 ddi_dma_free_handle(&cmd->cmd_dmahdl); 1776 cmd->cmd_dmahdl = NULL; 1777 } 1778 1779 if (cmd->arqhdl != NULL) { 1780 (void) ddi_dma_unbind_handle(cmd->arqhdl); 1781 ddi_dma_free_handle(&cmd->arqhdl); 1782 cmd->arqhdl = NULL; 1783 } 1784 1785 if (cmd->arqbuf != NULL) { 1786 scsi_free_consistent_buf(cmd->arqbuf); 1787 cmd->arqbuf = NULL; 1788 } 1789 } 1790 1791 /* tran_* entry points and setup */ 1792 /* ARGSUSED hba_dip tgt_dip hba_tran */ 1793 static int 1794 pvscsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 1795 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 1796 { 1797 pvscsi_softc_t *pvs = SDEV2PRIV(sd); 1798 1799 ASSERT(pvs != NULL); 1800 1801 if (sd->sd_address.a_target >= PVSCSI_MAXTGTS) 1802 return (DDI_FAILURE); 1803 1804 return (DDI_SUCCESS); 1805 } 1806 1807 static int 1808 pvscsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 1809 { 1810 boolean_t poll = ((pkt->pkt_flags & FLAG_NOINTR) != 0); 1811 int rc; 1812 pvscsi_cmd_t *cmd = PKT2CMD(pkt); 1813 pvscsi_softc_t *pvs = ap->a_hba_tran->tran_hba_private; 1814 1815 ASSERT(cmd->pkt == pkt); 1816 ASSERT(cmd->cmd_pvs == pvs); 1817 1818 /* 1819 * Reinitialize some fields because the packet may 1820 * have been resubmitted. 1821 */ 1822 pkt->pkt_reason = CMD_CMPLT; 1823 pkt->pkt_state = 0; 1824 pkt->pkt_statistics = 0; 1825 1826 /* Zero status byte */ 1827 *(pkt->pkt_scbp) = 0; 1828 1829 if ((cmd->flags & PVSCSI_FLAG_DMA_VALID) != 0) { 1830 ASSERT(cmd->cmd_dma_count != 0); 1831 pkt->pkt_resid = cmd->cmd_dma_count; 1832 1833 /* 1834 * Consistent packets need to be synced first 1835 * (only for data going out). 1836 */ 1837 if ((cmd->flags & PVSCSI_FLAG_IO_IOPB) != 0) { 1838 (void) ddi_dma_sync(cmd->cmd_dmahdl, 0, 0, 1839 DDI_DMA_SYNC_FORDEV); 1840 } 1841 } 1842 1843 cmd->cmd_target = ap->a_target; 1844 1845 mutex_enter(&pvs->mutex); 1846 if (HBA_IS_QUIESCED(pvs) && !poll) { 1847 mutex_exit(&pvs->mutex); 1848 return (TRAN_BUSY); 1849 } 1850 mutex_exit(&pvs->mutex); 1851 1852 rc = pvscsi_transport_command(pvs, cmd); 1853 1854 if (poll) { 1855 pvscsi_cmd_t *dcmd; 1856 boolean_t qnotify; 1857 1858 if (rc == TRAN_ACCEPT) 1859 rc = pvscsi_poll_cmd(pvs, cmd); 1860 1861 mutex_enter(&pvs->rx_mutex); 1862 dcmd = pvscsi_process_comp_ring(pvs); 1863 mutex_exit(&pvs->rx_mutex); 1864 1865 mutex_enter(&pvs->mutex); 1866 qnotify = HBA_QUIESCE_PENDING(pvs); 1867 mutex_exit(&pvs->mutex); 1868 1869 pvscsi_complete_chained(dcmd); 1870 1871 if (qnotify) 1872 pvscsi_quiesce_notify(pvs); 1873 } 1874 1875 return (rc); 1876 } 1877 1878 static int 1879 pvscsi_reset(struct scsi_address *ap, int level) 1880 { 1881 pvscsi_softc_t *pvs = AP2PRIV(ap); 1882 1883 switch (level) { 1884 case RESET_ALL: 1885 return (pvscsi_reset_generic(pvs, NULL)); 1886 case RESET_TARGET: 1887 ASSERT(ap != NULL); 1888 return (pvscsi_reset_generic(pvs, ap)); 1889 default: 1890 return (0); 1891 } 1892 } 1893 1894 static int 1895 pvscsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 1896 { 1897 boolean_t qnotify = B_FALSE; 1898 pvscsi_cmd_t *pending; 1899 pvscsi_softc_t *pvs = ap->a_hba_tran->tran_hba_private; 1900 1901 mutex_enter(&pvs->tx_mutex); 1902 mutex_enter(&pvs->rx_mutex); 1903 if (pkt != NULL) { 1904 /* Abort single command */ 1905 pvscsi_cmd_t *cmd = PKT2CMD(pkt); 1906 1907 if (pvscsi_abort_cmd(cmd, &pending) == CMD_ABORTED) { 1908 /* Assume command is completely cancelled now */ 1909 cmd->flags |= PVSCSI_FLAG_ABORTED; 1910 } 1911 } else { 1912 /* Abort all commands on the bus */ 1913 pvscsi_abort_all(ap, pvs, &pending, PVSCSI_FLAG_ABORTED); 1914 } 1915 qnotify = HBA_QUIESCE_PENDING(pvs); 1916 mutex_exit(&pvs->rx_mutex); 1917 mutex_exit(&pvs->tx_mutex); 1918 1919 pvscsi_complete_chained(pending); 1920 1921 if (qnotify) 1922 pvscsi_quiesce_notify(pvs); 1923 1924 return (1); 1925 } 1926 1927 /* ARGSUSED tgtonly */ 1928 static int 1929 pvscsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 1930 { 1931 pvscsi_softc_t *pvs = ap->a_hba_tran->tran_hba_private; 1932 1933 if (cap == NULL) 1934 return (-1); 1935 1936 switch (scsi_hba_lookup_capstr(cap)) { 1937 case SCSI_CAP_ARQ: 1938 return ((pvs->flags & PVSCSI_HBA_AUTO_REQUEST_SENSE) != 0); 1939 case SCSI_CAP_UNTAGGED_QING: 1940 return (1); 1941 default: 1942 return (-1); 1943 } 1944 } 1945 1946 /* ARGSUSED tgtonly */ 1947 static int 1948 pvscsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 1949 { 1950 pvscsi_softc_t *pvs = ap->a_hba_tran->tran_hba_private; 1951 1952 if (cap == NULL) 1953 return (-1); 1954 1955 switch (scsi_hba_lookup_capstr(cap)) { 1956 case SCSI_CAP_ARQ: 1957 mutex_enter(&pvs->mutex); 1958 if (value == 0) 1959 pvs->flags &= ~PVSCSI_HBA_AUTO_REQUEST_SENSE; 1960 else 1961 pvs->flags |= PVSCSI_HBA_AUTO_REQUEST_SENSE; 1962 mutex_exit(&pvs->mutex); 1963 return (1); 1964 default: 1965 return (0); 1966 } 1967 } 1968 1969 static void 1970 pvscsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1971 { 1972 pvscsi_cmd_t *cmd = PKT2CMD(pkt); 1973 pvscsi_softc_t *pvs = ap->a_hba_tran->tran_hba_private; 1974 1975 ASSERT(cmd->cmd_pvs == pvs); 1976 1977 if ((cmd->flags & PVSCSI_FLAG_DMA_VALID) != 0) { 1978 cmd->flags &= ~PVSCSI_FLAG_DMA_VALID; 1979 (void) ddi_dma_unbind_handle(cmd->cmd_dmahdl); 1980 } 1981 1982 if (cmd->ctx != NULL) { 1983 mutex_enter(&pvs->mutex); 1984 pvscsi_release_ctx(cmd); 1985 mutex_exit(&pvs->mutex); 1986 } 1987 1988 if ((cmd->flags & PVSCSI_FLAGS_EXT) != 0) 1989 pvscsi_cmd_ext_free(cmd); 1990 1991 kmem_cache_free(pvs->cmd_cache, cmd); 1992 } 1993 1994 static struct scsi_pkt * 1995 pvscsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, struct buf *bp, 1996 int cmdlen, int statuslen, int tgtlen, int flags, int (*callback)(), 1997 caddr_t arg) 1998 { 1999 boolean_t is_new; 2000 int kf = (callback == SLEEP_FUNC) ? KM_SLEEP: KM_NOSLEEP; 2001 int rc, i; 2002 pvscsi_cmd_t *cmd; 2003 pvscsi_softc_t *pvs; 2004 2005 pvs = ap->a_hba_tran->tran_hba_private; 2006 ASSERT(pvs != NULL); 2007 2008 /* Allocate a new SCSI packet */ 2009 if (pkt == NULL) { 2010 ddi_dma_handle_t saved_dmahdl, saved_arqhdl; 2011 struct buf *saved_arqbuf; 2012 ddi_dma_cookie_t saved_arqc; 2013 2014 is_new = B_TRUE; 2015 2016 if ((cmd = kmem_cache_alloc(pvs->cmd_cache, kf)) == NULL) 2017 return (NULL); 2018 2019 saved_dmahdl = cmd->cmd_dmahdl; 2020 saved_arqhdl = cmd->arqhdl; 2021 saved_arqbuf = cmd->arqbuf; 2022 saved_arqc = cmd->arqc; 2023 2024 bzero(cmd, sizeof (pvscsi_cmd_t) - 2025 sizeof (cmd->cached_cookies)); 2026 2027 cmd->cmd_pvs = pvs; 2028 cmd->cmd_dmahdl = saved_dmahdl; 2029 cmd->arqhdl = saved_arqhdl; 2030 cmd->arqbuf = saved_arqbuf; 2031 cmd->arqc = saved_arqc; 2032 2033 pkt = &cmd->cached_pkt; 2034 pkt->pkt_ha_private = (opaque_t)cmd; 2035 pkt->pkt_address = *ap; 2036 pkt->pkt_scbp = (uint8_t *)&cmd->cmd_scb; 2037 pkt->pkt_cdbp = (uint8_t *)&cmd->cmd_cdb; 2038 pkt->pkt_private = (opaque_t)&cmd->tgt_priv; 2039 2040 cmd->tgtlen = tgtlen; 2041 cmd->statuslen = statuslen; 2042 cmd->cmdlen = cmdlen; 2043 cmd->pkt = pkt; 2044 cmd->ctx = NULL; 2045 2046 /* Allocate extended buffers */ 2047 if ((cmdlen > sizeof (cmd->cmd_cdb)) || 2048 (statuslen > sizeof (cmd->cmd_scb)) || 2049 (tgtlen > sizeof (cmd->tgt_priv))) { 2050 if (pvscsi_cmd_ext_alloc(pvs, cmd, kf) != DDI_SUCCESS) { 2051 dev_err(pvs->dip, CE_WARN, 2052 "!extent allocation failed"); 2053 goto out; 2054 } 2055 } 2056 } else { 2057 is_new = B_FALSE; 2058 2059 cmd = PKT2CMD(pkt); 2060 cmd->flags &= PVSCSI_FLAGS_PERSISTENT; 2061 } 2062 2063 ASSERT((cmd->flags & PVSCSI_FLAG_TRANSPORT) == 0); 2064 2065 if ((flags & PKT_XARQ) != 0) 2066 cmd->flags |= PVSCSI_FLAG_XARQ; 2067 2068 /* Handle partial DMA transfers */ 2069 if (cmd->cmd_nwin > 0) { 2070 if (++cmd->cmd_winindex >= cmd->cmd_nwin) 2071 return (NULL); 2072 if (ddi_dma_getwin(cmd->cmd_dmahdl, cmd->cmd_winindex, 2073 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 2074 &cmd->cmd_dmac, &cmd->cmd_dmaccount) == DDI_FAILURE) 2075 return (NULL); 2076 goto handle_dma_cookies; 2077 } 2078 2079 /* Setup data buffer */ 2080 if (bp != NULL && bp->b_bcount > 0 && 2081 (cmd->flags & PVSCSI_FLAG_DMA_VALID) == 0) { 2082 int dma_flags; 2083 2084 ASSERT(cmd->cmd_dmahdl != NULL); 2085 2086 if ((bp->b_flags & B_READ) != 0) { 2087 cmd->flags |= PVSCSI_FLAG_IO_READ; 2088 dma_flags = DDI_DMA_READ; 2089 } else { 2090 cmd->flags &= ~PVSCSI_FLAG_IO_READ; 2091 dma_flags = DDI_DMA_WRITE; 2092 } 2093 if ((flags & PKT_CONSISTENT) != 0) { 2094 cmd->flags |= PVSCSI_FLAG_IO_IOPB; 2095 dma_flags |= DDI_DMA_CONSISTENT; 2096 } 2097 if ((flags & PKT_DMA_PARTIAL) != 0) 2098 dma_flags |= DDI_DMA_PARTIAL; 2099 2100 rc = ddi_dma_buf_bind_handle(cmd->cmd_dmahdl, bp, 2101 dma_flags, callback, arg, &cmd->cmd_dmac, 2102 &cmd->cmd_dmaccount); 2103 if (rc == DDI_DMA_PARTIAL_MAP) { 2104 (void) ddi_dma_numwin(cmd->cmd_dmahdl, 2105 &cmd->cmd_nwin); 2106 cmd->cmd_winindex = 0; 2107 (void) ddi_dma_getwin(cmd->cmd_dmahdl, 2108 cmd->cmd_winindex, &cmd->cmd_dma_offset, 2109 &cmd->cmd_dma_len, &cmd->cmd_dmac, 2110 &cmd->cmd_dmaccount); 2111 } else if (rc != 0 && rc != DDI_DMA_MAPPED) { 2112 switch (rc) { 2113 case DDI_DMA_NORESOURCES: 2114 bioerror(bp, 0); 2115 break; 2116 case DDI_DMA_BADATTR: 2117 case DDI_DMA_NOMAPPING: 2118 bioerror(bp, EFAULT); 2119 break; 2120 case DDI_DMA_TOOBIG: 2121 default: 2122 bioerror(bp, EINVAL); 2123 break; 2124 } 2125 cmd->flags &= ~PVSCSI_FLAG_DMA_VALID; 2126 goto out; 2127 } 2128 2129 handle_dma_cookies: 2130 ASSERT(cmd->cmd_dmaccount > 0); 2131 if (cmd->cmd_dmaccount > PVSCSI_MAX_SG_SIZE) { 2132 dev_err(pvs->dip, CE_WARN, 2133 "!invalid cookie count: %d (max %d)", 2134 cmd->cmd_dmaccount, PVSCSI_MAX_SG_SIZE); 2135 bioerror(bp, EINVAL); 2136 goto out; 2137 } 2138 2139 cmd->flags |= PVSCSI_FLAG_DMA_VALID; 2140 cmd->cmd_dma_count = cmd->cmd_dmac.dmac_size; 2141 cmd->cmd_total_dma_count += cmd->cmd_dmac.dmac_size; 2142 2143 cmd->cached_cookies[0] = cmd->cmd_dmac; 2144 2145 /* 2146 * Calculate total amount of bytes for this I/O and 2147 * store cookies for further processing. 2148 */ 2149 for (i = 1; i < cmd->cmd_dmaccount; i++) { 2150 ddi_dma_nextcookie(cmd->cmd_dmahdl, &cmd->cmd_dmac); 2151 cmd->cached_cookies[i] = cmd->cmd_dmac; 2152 cmd->cmd_dma_count += cmd->cmd_dmac.dmac_size; 2153 cmd->cmd_total_dma_count += cmd->cmd_dmac.dmac_size; 2154 } 2155 2156 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_total_dma_count); 2157 } 2158 2159 return (pkt); 2160 2161 out: 2162 if (is_new) 2163 pvscsi_destroy_pkt(ap, pkt); 2164 2165 return (NULL); 2166 } 2167 2168 /* ARGSUSED ap */ 2169 static void 2170 pvscsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 2171 { 2172 pvscsi_cmd_t *cmd = PKT2CMD(pkt); 2173 2174 if ((cmd->flags & PVSCSI_FLAG_DMA_VALID) != 0) { 2175 (void) ddi_dma_unbind_handle(cmd->cmd_dmahdl); 2176 cmd->flags &= ~PVSCSI_FLAG_DMA_VALID; 2177 } 2178 } 2179 2180 /* ARGSUSED ap */ 2181 static void 2182 pvscsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 2183 { 2184 pvscsi_cmd_t *cmd = PKT2CMD(pkt); 2185 2186 if (cmd->cmd_dmahdl != NULL) { 2187 (void) ddi_dma_sync(cmd->cmd_dmahdl, 0, 0, 2188 (cmd->flags & PVSCSI_FLAG_IO_READ) ? 2189 DDI_DMA_SYNC_FORCPU : DDI_DMA_SYNC_FORDEV); 2190 } 2191 2192 } 2193 2194 /* ARGSUSED ap flag callback arg */ 2195 static int 2196 pvscsi_reset_notify(struct scsi_address *ap, int flag, 2197 void (*callback)(caddr_t), caddr_t arg) 2198 { 2199 return (DDI_FAILURE); 2200 } 2201 2202 static int 2203 pvscsi_quiesce_hba(dev_info_t *dip) 2204 { 2205 pvscsi_softc_t *pvs; 2206 scsi_hba_tran_t *tran; 2207 2208 if ((tran = ddi_get_driver_private(dip)) == NULL || 2209 (pvs = TRAN2PRIV(tran)) == NULL) 2210 return (-1); 2211 2212 mutex_enter(&pvs->mutex); 2213 if (!HBA_IS_QUIESCED(pvs)) 2214 pvs->flags |= PVSCSI_HBA_QUIESCED; 2215 2216 if (pvs->cmd_queue_len != 0) { 2217 /* Outstanding commands present, wait */ 2218 pvs->flags |= PVSCSI_HBA_QUIESCE_PENDING; 2219 cv_wait(&pvs->quiescevar, &pvs->mutex); 2220 ASSERT(pvs->cmd_queue_len == 0); 2221 } 2222 mutex_exit(&pvs->mutex); 2223 2224 /* Suspend taskq delivery and complete all scheduled tasks */ 2225 ddi_taskq_suspend(pvs->msg_tq); 2226 ddi_taskq_wait(pvs->msg_tq); 2227 ddi_taskq_suspend(pvs->comp_tq); 2228 ddi_taskq_wait(pvs->comp_tq); 2229 2230 return (0); 2231 } 2232 2233 static int 2234 pvscsi_unquiesce_hba(dev_info_t *dip) 2235 { 2236 pvscsi_softc_t *pvs; 2237 scsi_hba_tran_t *tran; 2238 2239 if ((tran = ddi_get_driver_private(dip)) == NULL || 2240 (pvs = TRAN2PRIV(tran)) == NULL) 2241 return (-1); 2242 2243 mutex_enter(&pvs->mutex); 2244 if (!HBA_IS_QUIESCED(pvs)) { 2245 mutex_exit(&pvs->mutex); 2246 return (0); 2247 } 2248 ASSERT(pvs->cmd_queue_len == 0); 2249 pvs->flags &= ~PVSCSI_HBA_QUIESCED; 2250 mutex_exit(&pvs->mutex); 2251 2252 /* Resume taskq delivery */ 2253 ddi_taskq_resume(pvs->msg_tq); 2254 ddi_taskq_resume(pvs->comp_tq); 2255 2256 return (0); 2257 } 2258 2259 static int 2260 pvscsi_bus_config(dev_info_t *pdip, uint_t flags, ddi_bus_config_op_t op, 2261 void *arg, dev_info_t **childp) 2262 { 2263 char *p; 2264 int circ; 2265 int ret = NDI_FAILURE; 2266 long target = 0; 2267 pvscsi_softc_t *pvs; 2268 scsi_hba_tran_t *tran; 2269 2270 tran = ddi_get_driver_private(pdip); 2271 pvs = tran->tran_hba_private; 2272 2273 ndi_devi_enter(pdip, &circ); 2274 switch (op) { 2275 case BUS_CONFIG_ONE: 2276 if ((p = strrchr((char *)arg, '@')) != NULL && 2277 ddi_strtol(p + 1, NULL, 16, &target) == 0) 2278 ret = pvscsi_config_one(pdip, pvs, (int)target, childp); 2279 break; 2280 case BUS_CONFIG_DRIVER: 2281 case BUS_CONFIG_ALL: 2282 ret = pvscsi_config_all(pdip, pvs); 2283 break; 2284 default: 2285 break; 2286 } 2287 2288 if (ret == NDI_SUCCESS) 2289 ret = ndi_busop_bus_config(pdip, flags, op, arg, childp, 0); 2290 ndi_devi_exit(pdip, circ); 2291 2292 return (ret); 2293 } 2294 2295 static int 2296 pvscsi_hba_setup(pvscsi_softc_t *pvs) 2297 { 2298 scsi_hba_tran_t *hba_tran; 2299 2300 hba_tran = pvs->tran = scsi_hba_tran_alloc(pvs->dip, 2301 SCSI_HBA_CANSLEEP); 2302 ASSERT(pvs->tran != NULL); 2303 2304 hba_tran->tran_hba_private = pvs; 2305 hba_tran->tran_tgt_private = NULL; 2306 2307 hba_tran->tran_tgt_init = pvscsi_tgt_init; 2308 hba_tran->tran_tgt_free = NULL; 2309 hba_tran->tran_tgt_probe = scsi_hba_probe; 2310 2311 hba_tran->tran_start = pvscsi_start; 2312 hba_tran->tran_reset = pvscsi_reset; 2313 hba_tran->tran_abort = pvscsi_abort; 2314 hba_tran->tran_getcap = pvscsi_getcap; 2315 hba_tran->tran_setcap = pvscsi_setcap; 2316 hba_tran->tran_init_pkt = pvscsi_init_pkt; 2317 hba_tran->tran_destroy_pkt = pvscsi_destroy_pkt; 2318 2319 hba_tran->tran_dmafree = pvscsi_dmafree; 2320 hba_tran->tran_sync_pkt = pvscsi_sync_pkt; 2321 hba_tran->tran_reset_notify = pvscsi_reset_notify; 2322 2323 hba_tran->tran_quiesce = pvscsi_quiesce_hba; 2324 hba_tran->tran_unquiesce = pvscsi_unquiesce_hba; 2325 hba_tran->tran_bus_reset = NULL; 2326 2327 hba_tran->tran_add_eventcall = NULL; 2328 hba_tran->tran_get_eventcookie = NULL; 2329 hba_tran->tran_post_event = NULL; 2330 hba_tran->tran_remove_eventcall = NULL; 2331 2332 hba_tran->tran_bus_config = pvscsi_bus_config; 2333 2334 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2335 2336 if (scsi_hba_attach_setup(pvs->dip, &pvs->hba_dma_attr, hba_tran, 2337 SCSI_HBA_TRAN_CDB | SCSI_HBA_TRAN_SCB | SCSI_HBA_TRAN_CLONE) != 2338 DDI_SUCCESS) { 2339 dev_err(pvs->dip, CE_WARN, "!failed to attach HBA"); 2340 scsi_hba_tran_free(hba_tran); 2341 pvs->tran = NULL; 2342 return (-1); 2343 } 2344 2345 return (0); 2346 } 2347 2348 static int 2349 pvscsi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 2350 { 2351 int instance; 2352 pvscsi_softc_t *pvs; 2353 char buf[32]; 2354 2355 ASSERT(scsi_hba_iport_unit_address(dip) == NULL); 2356 2357 switch (cmd) { 2358 case DDI_ATTACH: 2359 case DDI_RESUME: 2360 break; 2361 default: 2362 return (DDI_FAILURE); 2363 } 2364 2365 instance = ddi_get_instance(dip); 2366 2367 /* Allocate softstate information */ 2368 if (ddi_soft_state_zalloc(pvscsi_sstate, instance) != DDI_SUCCESS) { 2369 cmn_err(CE_WARN, 2370 "!ddi_soft_state_zalloc() failed for instance %d", 2371 instance); 2372 return (DDI_FAILURE); 2373 } 2374 2375 if ((pvs = ddi_get_soft_state(pvscsi_sstate, instance)) == NULL) { 2376 cmn_err(CE_WARN, "!failed to get soft state for instance %d", 2377 instance); 2378 goto fail; 2379 } 2380 2381 /* 2382 * Indicate that we are 'sizeof (scsi_*(9S))' clean, we use 2383 * scsi_pkt_size() instead. 2384 */ 2385 scsi_size_clean(dip); 2386 2387 /* Setup HBA instance */ 2388 pvs->instance = instance; 2389 pvs->dip = dip; 2390 pvs->hba_dma_attr = pvscsi_hba_dma_attr; 2391 pvs->ring_dma_attr = pvscsi_ring_dma_attr; 2392 pvs->io_dma_attr = pvscsi_io_dma_attr; 2393 mutex_init(&pvs->mutex, "pvscsi instance mutex", MUTEX_DRIVER, NULL); 2394 mutex_init(&pvs->intr_mutex, "pvscsi instance interrupt mutex", 2395 MUTEX_DRIVER, NULL); 2396 mutex_init(&pvs->rx_mutex, "pvscsi rx ring mutex", MUTEX_DRIVER, NULL); 2397 mutex_init(&pvs->tx_mutex, "pvscsi tx ring mutex", MUTEX_DRIVER, NULL); 2398 list_create(&pvs->cmd_ctx_pool, sizeof (pvscsi_cmd_ctx_t), 2399 offsetof(pvscsi_cmd_ctx_t, list)); 2400 list_create(&pvs->devnodes, sizeof (pvscsi_device_t), 2401 offsetof(pvscsi_device_t, list)); 2402 list_create(&pvs->cmd_queue, sizeof (pvscsi_cmd_t), 2403 offsetof(pvscsi_cmd_t, cmd_queue_node)); 2404 cv_init(&pvs->syncvar, "pvscsi synchronization cv", CV_DRIVER, NULL); 2405 cv_init(&pvs->wd_condvar, "pvscsi watchdog cv", CV_DRIVER, NULL); 2406 cv_init(&pvs->quiescevar, "pvscsi quiesce cv", CV_DRIVER, NULL); 2407 2408 (void) sprintf(buf, "pvscsi%d_cache", instance); 2409 pvs->cmd_cache = kmem_cache_create(buf, sizeof (pvscsi_cmd_t), 0, 2410 pvscsi_ccache_constructor, pvscsi_ccache_destructor, NULL, 2411 (void *)pvs, NULL, 0); 2412 if (pvs->cmd_cache == NULL) { 2413 dev_err(pvs->dip, CE_WARN, 2414 "!failed to create a cache for SCSI commands"); 2415 goto fail; 2416 } 2417 2418 if ((pvscsi_setup_io(pvs)) != DDI_SUCCESS) { 2419 dev_err(pvs->dip, CE_WARN, "!failed to setup I/O region"); 2420 goto free_cache; 2421 } 2422 2423 pvscsi_reset_hba(pvs); 2424 2425 if ((pvscsi_allocate_rings(pvs)) != DDI_SUCCESS) { 2426 dev_err(pvs->dip, CE_WARN, "!failed to allocate DMA rings"); 2427 goto free_io; 2428 } 2429 2430 pvscsi_setup_rings(pvs); 2431 2432 if (pvscsi_setup_isr(pvs) != DDI_SUCCESS) { 2433 dev_err(pvs->dip, CE_WARN, "!failed to setup ISR"); 2434 goto free_rings; 2435 } 2436 2437 if (pvscsi_setup_sg(pvs) != DDI_SUCCESS) { 2438 dev_err(pvs->dip, CE_WARN, "!failed to setup S/G"); 2439 goto free_intr; 2440 } 2441 2442 if (pvscsi_hba_setup(pvs) != 0) { 2443 dev_err(pvs->dip, CE_WARN, "!failed to setup HBA"); 2444 goto free_sg; 2445 } 2446 2447 if ((pvs->comp_tq = ddi_taskq_create(pvs->dip, "comp_tq", 2448 MIN(UINT16_MAX, ncpus), TASKQ_DEFAULTPRI, 0)) == NULL) { 2449 dev_err(pvs->dip, CE_WARN, 2450 "!failed to create completion taskq"); 2451 goto free_sg; 2452 } 2453 2454 if ((pvs->msg_tq = ddi_taskq_create(pvs->dip, "msg_tq", 2455 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 2456 dev_err(pvs->dip, CE_WARN, 2457 "!failed to create message taskq"); 2458 goto free_comp_tq; 2459 } 2460 2461 if (pvscsi_enable_intrs(pvs) != DDI_SUCCESS) { 2462 dev_err(pvs->dip, CE_WARN, "!failed to enable interrupts"); 2463 goto free_msg_tq; 2464 } 2465 2466 /* Launch watchdog thread */ 2467 pvs->wd_thread = thread_create(NULL, 0, pvscsi_wd_thread, pvs, 0, &p0, 2468 TS_RUN, minclsyspri); 2469 2470 return (DDI_SUCCESS); 2471 2472 free_msg_tq: 2473 ddi_taskq_destroy(pvs->msg_tq); 2474 free_comp_tq: 2475 ddi_taskq_destroy(pvs->comp_tq); 2476 free_sg: 2477 pvscsi_free_sg(pvs); 2478 free_intr: 2479 pvscsi_free_intr_resources(pvs); 2480 free_rings: 2481 pvscsi_reset_hba(pvs); 2482 pvscsi_free_rings(pvs); 2483 free_io: 2484 pvscsi_free_io(pvs); 2485 free_cache: 2486 kmem_cache_destroy(pvs->cmd_cache); 2487 fail: 2488 ddi_soft_state_free(pvscsi_sstate, instance); 2489 2490 return (DDI_FAILURE); 2491 } 2492 2493 static int 2494 pvscsi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 2495 { 2496 int instance; 2497 pvscsi_softc_t *pvs; 2498 2499 switch (cmd) { 2500 case DDI_DETACH: 2501 break; 2502 default: 2503 return (DDI_FAILURE); 2504 } 2505 2506 instance = ddi_get_instance(dip); 2507 if ((pvs = ddi_get_soft_state(pvscsi_sstate, instance)) == NULL) { 2508 cmn_err(CE_WARN, "!failed to get soft state for instance %d", 2509 instance); 2510 return (DDI_FAILURE); 2511 } 2512 2513 pvscsi_reset_hba(pvs); 2514 pvscsi_free_intr_resources(pvs); 2515 2516 /* Shutdown message taskq */ 2517 ddi_taskq_wait(pvs->msg_tq); 2518 ddi_taskq_destroy(pvs->msg_tq); 2519 2520 /* Shutdown completion taskq */ 2521 ddi_taskq_wait(pvs->comp_tq); 2522 ddi_taskq_destroy(pvs->comp_tq); 2523 2524 /* Shutdown watchdog thread */ 2525 mutex_enter(&pvs->mutex); 2526 pvs->flags |= PVSCSI_DRIVER_SHUTDOWN; 2527 cv_signal(&pvs->wd_condvar); 2528 cv_wait(&pvs->syncvar, &pvs->mutex); 2529 mutex_exit(&pvs->mutex); 2530 2531 pvscsi_free_sg(pvs); 2532 pvscsi_free_rings(pvs); 2533 pvscsi_free_io(pvs); 2534 2535 kmem_cache_destroy(pvs->cmd_cache); 2536 2537 mutex_destroy(&pvs->mutex); 2538 mutex_destroy(&pvs->intr_mutex); 2539 mutex_destroy(&pvs->rx_mutex); 2540 2541 cv_destroy(&pvs->syncvar); 2542 cv_destroy(&pvs->wd_condvar); 2543 cv_destroy(&pvs->quiescevar); 2544 2545 ddi_soft_state_free(pvscsi_sstate, instance); 2546 ddi_prop_remove_all(dip); 2547 2548 return (DDI_SUCCESS); 2549 } 2550 2551 static int 2552 pvscsi_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 2553 int *rval) 2554 { 2555 int ret; 2556 2557 if (ddi_get_soft_state(pvscsi_sstate, getminor(dev)) == NULL) { 2558 cmn_err(CE_WARN, "!invalid device instance: %d", getminor(dev)); 2559 return (ENXIO); 2560 } 2561 2562 /* Try to handle command in a common way */ 2563 if ((ret = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval)) != ENOTTY) 2564 return (ret); 2565 2566 cmn_err(CE_WARN, "!unsupported IOCTL command: 0x%X", cmd); 2567 2568 return (ENXIO); 2569 } 2570 2571 static int 2572 pvscsi_quiesce(dev_info_t *devi) 2573 { 2574 scsi_hba_tran_t *tran; 2575 pvscsi_softc_t *pvs; 2576 2577 if ((tran = ddi_get_driver_private(devi)) == NULL) 2578 return (DDI_SUCCESS); 2579 2580 if ((pvs = tran->tran_hba_private) == NULL) 2581 return (DDI_SUCCESS); 2582 2583 /* Mask all interrupts from device */ 2584 pvscsi_reg_write(pvs, PVSCSI_REG_OFFSET_INTR_MASK, 0); 2585 2586 /* Reset the HBA */ 2587 pvscsi_reset_hba(pvs); 2588 2589 return (DDI_SUCCESS); 2590 } 2591 2592 /* module */ 2593 2594 static struct cb_ops pvscsi_cb_ops = { 2595 .cb_open = scsi_hba_open, 2596 .cb_close = scsi_hba_close, 2597 .cb_strategy = nodev, 2598 .cb_print = nodev, 2599 .cb_dump = nodev, 2600 .cb_read = nodev, 2601 .cb_write = nodev, 2602 .cb_ioctl = pvscsi_ioctl, 2603 .cb_devmap = nodev, 2604 .cb_mmap = nodev, 2605 .cb_segmap = nodev, 2606 .cb_chpoll = nochpoll, 2607 .cb_prop_op = ddi_prop_op, 2608 .cb_str = NULL, 2609 .cb_flag = D_MP, 2610 .cb_rev = CB_REV, 2611 .cb_aread = nodev, 2612 .cb_awrite = nodev 2613 }; 2614 2615 static struct dev_ops pvscsi_ops = { 2616 .devo_rev = DEVO_REV, 2617 .devo_refcnt = 0, 2618 .devo_getinfo = ddi_no_info, 2619 .devo_identify = nulldev, 2620 .devo_probe = nulldev, 2621 .devo_attach = pvscsi_attach, 2622 .devo_detach = pvscsi_detach, 2623 .devo_reset = nodev, 2624 .devo_cb_ops = &pvscsi_cb_ops, 2625 .devo_bus_ops = NULL, 2626 .devo_power = NULL, 2627 .devo_quiesce = pvscsi_quiesce 2628 }; 2629 2630 #define PVSCSI_IDENT "VMware PVSCSI" 2631 2632 static struct modldrv modldrv = { 2633 &mod_driverops, 2634 PVSCSI_IDENT, 2635 &pvscsi_ops, 2636 }; 2637 2638 static struct modlinkage modlinkage = { 2639 MODREV_1, 2640 &modldrv, 2641 NULL 2642 }; 2643 2644 int 2645 _init(void) 2646 { 2647 int ret; 2648 2649 if ((ret = ddi_soft_state_init(&pvscsi_sstate, 2650 sizeof (struct pvscsi_softc), PVSCSI_INITIAL_SSTATE_ITEMS)) != 0) { 2651 cmn_err(CE_WARN, "!ddi_soft_state_init() failed"); 2652 return (ret); 2653 } 2654 2655 if ((ret = scsi_hba_init(&modlinkage)) != 0) { 2656 cmn_err(CE_WARN, "!scsi_hba_init() failed"); 2657 ddi_soft_state_fini(&pvscsi_sstate); 2658 return (ret); 2659 } 2660 2661 if ((ret = mod_install(&modlinkage)) != 0) { 2662 cmn_err(CE_WARN, "!mod_install() failed"); 2663 ddi_soft_state_fini(&pvscsi_sstate); 2664 scsi_hba_fini(&modlinkage); 2665 } 2666 2667 return (ret); 2668 } 2669 2670 int 2671 _info(struct modinfo *modinfop) 2672 { 2673 return (mod_info(&modlinkage, modinfop)); 2674 } 2675 2676 int 2677 _fini(void) 2678 { 2679 int ret; 2680 2681 if ((ret = mod_remove(&modlinkage)) == 0) { 2682 ddi_soft_state_fini(&pvscsi_sstate); 2683 scsi_hba_fini(&modlinkage); 2684 } 2685 2686 return (ret); 2687 }