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