1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 #include <sys/types.h> 29 #include <sys/kmem.h> 30 #include <sys/debug.h> 31 #include <sys/scsi/scsi.h> 32 33 #include "ghd.h" 34 35 /* ghd_poll() function codes: */ 36 typedef enum { 37 GHD_POLL_REQUEST, /* wait for a specific request */ 38 GHD_POLL_DEVICE, /* wait for a specific device to idle */ 39 GHD_POLL_ALL /* wait for the whole bus to idle */ 40 } gpoll_t; 41 42 /* 43 * Local functions: 44 */ 45 static gcmd_t *ghd_doneq_get(ccc_t *cccp); 46 static void ghd_doneq_pollmode_enter(ccc_t *cccp); 47 static void ghd_doneq_pollmode_exit(ccc_t *cccp); 48 static uint_t ghd_doneq_process(caddr_t arg); 49 static void ghd_do_reset_notify_callbacks(ccc_t *cccp); 50 51 static int ghd_poll(ccc_t *cccp, gpoll_t polltype, ulong_t polltime, 52 gcmd_t *poll_gcmdp, gtgt_t *gtgtp, void *intr_status); 53 54 55 /* 56 * Local configuration variables 57 */ 58 #define DEFAULT_GHD_TIMEOUT 50000 /* Amount of time to poll(50ms) */ 59 60 ulong_t ghd_tran_abort_timeout = DEFAULT_GHD_TIMEOUT; 61 ulong_t ghd_tran_abort_lun_timeout = DEFAULT_GHD_TIMEOUT; 62 ulong_t ghd_tran_reset_target_timeout = DEFAULT_GHD_TIMEOUT; 63 ulong_t ghd_tran_reset_bus_timeout = DEFAULT_GHD_TIMEOUT; 64 65 static int 66 ghd_doneq_init(ccc_t *cccp) 67 { 68 ddi_iblock_cookie_t iblock; 69 70 L2_INIT(&cccp->ccc_doneq); 71 cccp->ccc_hba_pollmode = TRUE; 72 73 if (ddi_add_softintr(cccp->ccc_hba_dip, DDI_SOFTINT_LOW, 74 &cccp->ccc_doneq_softid, &iblock, NULL, 75 ghd_doneq_process, (caddr_t)cccp) != DDI_SUCCESS) { 76 GDBG_ERROR(("ghd_doneq_init: add softintr failed cccp 0x%p\n", 77 (void *)cccp)); 78 return (FALSE); 79 } 80 81 mutex_init(&cccp->ccc_doneq_mutex, NULL, MUTEX_DRIVER, iblock); 82 ghd_doneq_pollmode_exit(cccp); 83 return (TRUE); 84 } 85 86 /* 87 * ghd_complete(): 88 * 89 * The HBA driver calls this entry point when it's completely 90 * done processing a request. 91 * 92 * See the GHD_COMPLETE_INLINE() macro in ghd.h for the actual code. 93 */ 94 95 void 96 ghd_complete(ccc_t *cccp, gcmd_t *gcmdp) 97 { 98 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 99 GHD_COMPLETE_INLINE(cccp, gcmdp); 100 } 101 102 103 /* 104 * ghd_doneq_put_head(): 105 * 106 * Mark the request done and prepend it to the doneq. 107 * See the GHD_DONEQ_PUT_HEAD_INLINE() macros in ghd.h for 108 * the actual code. 109 */ 110 void 111 ghd_doneq_put_head(ccc_t *cccp, gcmd_t *gcmdp) 112 { 113 GHD_DONEQ_PUT_HEAD_INLINE(cccp, gcmdp) 114 } 115 116 /* 117 * ghd_doneq_put_tail(): 118 * 119 * Mark the request done and append it to the doneq. 120 * See the GHD_DONEQ_PUT_TAIL_INLINE() macros in ghd.h for 121 * the actual code. 122 */ 123 void 124 ghd_doneq_put_tail(ccc_t *cccp, gcmd_t *gcmdp) 125 { 126 GHD_DONEQ_PUT_TAIL_INLINE(cccp, gcmdp) 127 } 128 129 static gcmd_t * 130 ghd_doneq_get(ccc_t *cccp) 131 { 132 kmutex_t *doneq_mutexp = &cccp->ccc_doneq_mutex; 133 gcmd_t *gcmdp; 134 135 mutex_enter(doneq_mutexp); 136 if ((gcmdp = L2_next(&cccp->ccc_doneq)) != NULL) 137 L2_delete(&gcmdp->cmd_q); 138 mutex_exit(doneq_mutexp); 139 return (gcmdp); 140 } 141 142 143 static void 144 ghd_doneq_pollmode_enter(ccc_t *cccp) 145 { 146 kmutex_t *doneq_mutexp = &cccp->ccc_doneq_mutex; 147 148 mutex_enter(doneq_mutexp); 149 cccp->ccc_hba_pollmode = TRUE; 150 mutex_exit(doneq_mutexp); 151 } 152 153 154 static void 155 ghd_doneq_pollmode_exit(ccc_t *cccp) 156 { 157 kmutex_t *doneq_mutexp = &cccp->ccc_doneq_mutex; 158 159 mutex_enter(doneq_mutexp); 160 cccp->ccc_hba_pollmode = FALSE; 161 mutex_exit(doneq_mutexp); 162 163 /* trigger software interrupt for the completion callbacks */ 164 if (!L2_EMPTY(&cccp->ccc_doneq)) { 165 /* 166 * If we are panicking we should just call the completion 167 * function directly as we can not use soft interrupts 168 * or timeouts during panic. 169 */ 170 if (!ddi_in_panic()) 171 ddi_trigger_softintr(cccp->ccc_doneq_softid); 172 else 173 (void) ghd_doneq_process((caddr_t)cccp); 174 } 175 } 176 177 178 /* ***************************************************************** */ 179 180 /* 181 * 182 * ghd_doneq_process() 183 * 184 * This function is called directly from the software interrupt 185 * handler. 186 * 187 * The doneq is protected by a separate mutex than the 188 * HBA mutex in order to avoid mutex contention on MP systems. 189 * 190 */ 191 192 static uint_t 193 ghd_doneq_process(caddr_t arg) 194 { 195 ccc_t *cccp = (ccc_t *)arg; 196 kmutex_t *doneq_mutexp; 197 gcmd_t *gcmdp; 198 int rc = DDI_INTR_UNCLAIMED; 199 200 doneq_mutexp = &cccp->ccc_doneq_mutex; 201 202 for (;;) { 203 mutex_enter(doneq_mutexp); 204 /* skip if FLAG_NOINTR request in progress */ 205 if (cccp->ccc_hba_pollmode) 206 break; 207 /* pop the first one from the done Q */ 208 if ((gcmdp = L2_next(&cccp->ccc_doneq)) == NULL) 209 break; 210 L2_delete(&gcmdp->cmd_q); 211 212 if (gcmdp->cmd_flags & GCMDFLG_RESET_NOTIFY) { 213 /* special request; processed here and discarded */ 214 ghd_do_reset_notify_callbacks(cccp); 215 ghd_gcmd_free(gcmdp); 216 mutex_exit(doneq_mutexp); 217 continue; 218 } 219 220 /* 221 * drop the mutex since completion 222 * function can re-enter the top half via 223 * ghd_transport() 224 */ 225 mutex_exit(doneq_mutexp); 226 gcmdp->cmd_state = GCMD_STATE_IDLE; 227 (*cccp->ccc_hba_complete)(cccp->ccc_hba_handle, gcmdp, TRUE); 228 #ifdef notyet 229 /* I don't think this is ever necessary */ 230 rc = DDI_INTR_CLAIMED; 231 #endif 232 } 233 mutex_exit(doneq_mutexp); 234 return (rc); 235 } 236 237 static void 238 ghd_do_reset_notify_callbacks(ccc_t *cccp) 239 { 240 ghd_reset_notify_list_t *rnp; 241 L2el_t *rnl = &cccp->ccc_reset_notify_list; 242 243 ASSERT(mutex_owned(&cccp->ccc_doneq_mutex)); 244 245 /* lock the reset notify list while we operate on it */ 246 mutex_enter(&cccp->ccc_reset_notify_mutex); 247 248 for (rnp = (ghd_reset_notify_list_t *)L2_next(rnl); 249 rnp != NULL; 250 rnp = (ghd_reset_notify_list_t *)L2_next(&rnp->l2_link)) { 251 252 /* don't call if HBA driver didn't set it */ 253 if (cccp->ccc_hba_reset_notify_callback) { 254 (*cccp->ccc_hba_reset_notify_callback)(rnp->gtgtp, 255 rnp->callback, rnp->arg); 256 } 257 } 258 mutex_exit(&cccp->ccc_reset_notify_mutex); 259 } 260 261 262 /* ***************************************************************** */ 263 264 265 /* 266 * ghd_register() 267 * 268 * Do the usual interrupt handler setup stuff. 269 * 270 * Also, set up three mutexes: the wait queue mutex, the HBA 271 * mutex, and the done queue mutex. The permitted locking 272 * orders are: 273 * 274 * 1. enter(waitq) 275 * 2. enter(activel) 276 * 3. enter(doneq) 277 * 4. enter(HBA) then enter(activel) 278 * 5. enter(HBA) then enter(doneq) 279 * 6. enter(HBA) then enter(waitq) 280 * 7. enter(waitq) then tryenter(HBA) 281 * 282 * Note: cases 6 and 7 won't deadlock because case 7 is always 283 * mutex_tryenter() call. 284 * 285 */ 286 287 288 int 289 ghd_register(char *labelp, 290 ccc_t *cccp, 291 dev_info_t *dip, 292 int inumber, 293 void *hba_handle, 294 int (*ccballoc)(gtgt_t *, gcmd_t *, int, int, int, int), 295 void (*ccbfree)(gcmd_t *), 296 void (*sg_func)(gcmd_t *, ddi_dma_cookie_t *, int, int), 297 int (*hba_start)(void *, gcmd_t *), 298 void (*hba_complete)(void *, gcmd_t *, int), 299 uint_t (*int_handler)(caddr_t), 300 int (*get_status)(void *, void *), 301 void (*process_intr)(void *, void *), 302 int (*timeout_func)(void *, gcmd_t *, gtgt_t *, gact_t, int), 303 tmr_t *tmrp, 304 void (*hba_reset_notify_callback)(gtgt_t *, 305 void (*)(caddr_t), caddr_t)) 306 { 307 308 cccp->ccc_label = labelp; 309 cccp->ccc_hba_dip = dip; 310 cccp->ccc_ccballoc = ccballoc; 311 cccp->ccc_ccbfree = ccbfree; 312 cccp->ccc_sg_func = sg_func; 313 cccp->ccc_hba_start = hba_start; 314 cccp->ccc_hba_complete = hba_complete; 315 cccp->ccc_process_intr = process_intr; 316 cccp->ccc_get_status = get_status; 317 cccp->ccc_hba_handle = hba_handle; 318 cccp->ccc_hba_reset_notify_callback = hba_reset_notify_callback; 319 320 /* initialize the HBA's list headers */ 321 CCCP_INIT(cccp); 322 323 if (ddi_get_iblock_cookie(dip, inumber, &cccp->ccc_iblock) 324 != DDI_SUCCESS) { 325 326 return (FALSE); 327 } 328 329 mutex_init(&cccp->ccc_hba_mutex, NULL, MUTEX_DRIVER, cccp->ccc_iblock); 330 331 mutex_init(&cccp->ccc_waitq_mutex, NULL, MUTEX_DRIVER, 332 cccp->ccc_iblock); 333 334 mutex_init(&cccp->ccc_reset_notify_mutex, NULL, MUTEX_DRIVER, 335 cccp->ccc_iblock); 336 337 /* Establish interrupt handler */ 338 if (ddi_add_intr(dip, inumber, &cccp->ccc_iblock, NULL, 339 int_handler, (caddr_t)hba_handle) != DDI_SUCCESS) { 340 mutex_destroy(&cccp->ccc_hba_mutex); 341 mutex_destroy(&cccp->ccc_waitq_mutex); 342 mutex_destroy(&cccp->ccc_reset_notify_mutex); 343 344 return (FALSE); 345 } 346 347 if (ghd_timer_attach(cccp, tmrp, timeout_func) == FALSE) { 348 ddi_remove_intr(cccp->ccc_hba_dip, 0, cccp->ccc_iblock); 349 mutex_destroy(&cccp->ccc_hba_mutex); 350 mutex_destroy(&cccp->ccc_waitq_mutex); 351 mutex_destroy(&cccp->ccc_reset_notify_mutex); 352 353 return (FALSE); 354 } 355 356 if (ghd_doneq_init(cccp)) { 357 358 return (TRUE); 359 } 360 361 /* 362 * ghd_doneq_init() returned error: 363 */ 364 365 ghd_timer_detach(cccp); 366 ddi_remove_intr(cccp->ccc_hba_dip, 0, cccp->ccc_iblock); 367 mutex_destroy(&cccp->ccc_hba_mutex); 368 mutex_destroy(&cccp->ccc_waitq_mutex); 369 mutex_destroy(&cccp->ccc_reset_notify_mutex); 370 371 return (FALSE); 372 373 } 374 375 376 void 377 ghd_unregister(ccc_t *cccp) 378 { 379 ghd_timer_detach(cccp); 380 ddi_remove_intr(cccp->ccc_hba_dip, 0, cccp->ccc_iblock); 381 ddi_remove_softintr(cccp->ccc_doneq_softid); 382 mutex_destroy(&cccp->ccc_hba_mutex); 383 mutex_destroy(&cccp->ccc_waitq_mutex); 384 mutex_destroy(&cccp->ccc_doneq_mutex); 385 } 386 387 388 389 int 390 ghd_intr(ccc_t *cccp, void *intr_status) 391 { 392 int (*statfunc)(void *, void *) = cccp->ccc_get_status; 393 void (*processfunc)(void *, void *) = cccp->ccc_process_intr; 394 kmutex_t *waitq_mutexp = &cccp->ccc_waitq_mutex; 395 kmutex_t *hba_mutexp = &cccp->ccc_hba_mutex; 396 void *handle = cccp->ccc_hba_handle; 397 int rc = DDI_INTR_UNCLAIMED; 398 int more; 399 400 401 mutex_enter(hba_mutexp); 402 403 GDBG_INTR(("ghd_intr(): cccp=0x%p status=0x%p\n", 404 (void *)cccp, intr_status)); 405 406 for (;;) { 407 more = FALSE; 408 409 /* process the interrupt status */ 410 while ((*statfunc)(handle, intr_status)) { 411 (*processfunc)(handle, intr_status); 412 rc = DDI_INTR_CLAIMED; 413 more = TRUE; 414 } 415 mutex_enter(waitq_mutexp); 416 if (ghd_waitq_process_and_mutex_hold(cccp)) { 417 ASSERT(mutex_owned(hba_mutexp)); 418 mutex_exit(waitq_mutexp); 419 continue; 420 } 421 if (more) { 422 mutex_exit(waitq_mutexp); 423 continue; 424 } 425 GDBG_INTR(("ghd_intr(): done cccp=0x%p status=0x%p rc %d\n", 426 (void *)cccp, intr_status, rc)); 427 /* 428 * Release the mutexes in the opposite order that they 429 * were acquired to prevent requests queued by 430 * ghd_transport() from getting hung up in the wait queue. 431 */ 432 mutex_exit(hba_mutexp); 433 mutex_exit(waitq_mutexp); 434 return (rc); 435 } 436 } 437 438 static int 439 ghd_poll(ccc_t *cccp, 440 gpoll_t polltype, 441 ulong_t polltime, 442 gcmd_t *poll_gcmdp, 443 gtgt_t *gtgtp, 444 void *intr_status) 445 { 446 gcmd_t *gcmdp; 447 L2el_t gcmd_hold_queue; 448 int got_it = FALSE; 449 clock_t poll_lbolt; 450 clock_t start_lbolt; 451 clock_t current_lbolt; 452 453 454 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 455 L2_INIT(&gcmd_hold_queue); 456 457 /* Que hora es? */ 458 poll_lbolt = drv_usectohz((clock_t)polltime); 459 start_lbolt = ddi_get_lbolt(); 460 461 /* unqueue and save all CMD/CCBs until I find the right one */ 462 while (!got_it) { 463 464 /* Give up yet? */ 465 current_lbolt = ddi_get_lbolt(); 466 if (poll_lbolt && (current_lbolt - start_lbolt >= poll_lbolt)) 467 break; 468 469 /* 470 * delay 1 msec each time around the loop (this is an 471 * arbitrary delay value, any value should work) except 472 * zero because some devices don't like being polled too 473 * fast and it saturates the bus on an MP system. 474 */ 475 drv_usecwait(1000); 476 477 /* 478 * check for any new device status 479 */ 480 if ((*cccp->ccc_get_status)(cccp->ccc_hba_handle, intr_status)) 481 (*cccp->ccc_process_intr)(cccp->ccc_hba_handle, 482 intr_status); 483 484 /* 485 * If something completed then try to start the 486 * next request from the wait queue. Don't release 487 * the HBA mutex because I don't know whether my 488 * request(s) is/are on the done queue yet. 489 */ 490 mutex_enter(&cccp->ccc_waitq_mutex); 491 (void) ghd_waitq_process_and_mutex_hold(cccp); 492 mutex_exit(&cccp->ccc_waitq_mutex); 493 494 /* 495 * Process the first of any timed-out requests. 496 */ 497 ghd_timer_poll(cccp, GHD_TIMER_POLL_ONE); 498 499 /* 500 * Unqueue all the completed requests, look for mine 501 */ 502 while (gcmdp = ghd_doneq_get(cccp)) { 503 /* 504 * If we got one and it's my request, then 505 * we're done. 506 */ 507 if (gcmdp == poll_gcmdp) { 508 poll_gcmdp->cmd_state = GCMD_STATE_IDLE; 509 got_it = TRUE; 510 continue; 511 } 512 /* fifo queue the other cmds on my local list */ 513 L2_add(&gcmd_hold_queue, &gcmdp->cmd_q, gcmdp); 514 } 515 516 517 /* 518 * Check whether we're done yet. 519 */ 520 switch (polltype) { 521 case GHD_POLL_DEVICE: 522 /* 523 * wait for everything queued on a specific device 524 */ 525 if (GDEV_NACTIVE(gtgtp->gt_gdevp) == 0) 526 got_it = TRUE; 527 break; 528 529 case GHD_POLL_ALL: 530 /* 531 * if waiting for all outstanding requests and 532 * if active list is now empty then exit 533 */ 534 if (GHBA_NACTIVE(cccp) == 0) 535 got_it = TRUE; 536 break; 537 538 case GHD_POLL_REQUEST: 539 break; 540 541 } 542 } 543 544 if (L2_EMPTY(&gcmd_hold_queue)) { 545 ASSERT(!mutex_owned(&cccp->ccc_waitq_mutex)); 546 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 547 return (got_it); 548 } 549 550 /* 551 * copy the local gcmd_hold_queue back to the doneq so 552 * that the order of completion callbacks is preserved 553 */ 554 while (gcmdp = L2_next(&gcmd_hold_queue)) { 555 L2_delete(&gcmdp->cmd_q); 556 GHD_DONEQ_PUT_TAIL(cccp, gcmdp); 557 } 558 559 ASSERT(!mutex_owned(&cccp->ccc_waitq_mutex)); 560 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 561 return (got_it); 562 } 563 564 565 /* 566 * ghd_tran_abort() 567 * 568 * Abort specific command on a target. 569 * 570 */ 571 572 int 573 ghd_tran_abort(ccc_t *cccp, gcmd_t *gcmdp, gtgt_t *gtgtp, void *intr_status) 574 { 575 gact_t action; 576 int rc; 577 578 /* 579 * call the driver's abort_cmd function 580 */ 581 582 mutex_enter(&cccp->ccc_hba_mutex); 583 ghd_doneq_pollmode_enter(cccp); 584 585 switch (gcmdp->cmd_state) { 586 case GCMD_STATE_WAITQ: 587 /* not yet started */ 588 action = GACTION_EARLY_ABORT; 589 break; 590 591 case GCMD_STATE_ACTIVE: 592 /* in progress */ 593 action = GACTION_ABORT_CMD; 594 break; 595 596 default: 597 /* everything else, probably already being aborted */ 598 rc = FALSE; 599 goto exit; 600 } 601 602 /* stop the timer and remove it from the active list */ 603 GHD_TIMER_STOP(cccp, gcmdp); 604 605 /* start a new timer and send out the abort command */ 606 ghd_timer_newstate(cccp, gcmdp, gtgtp, action, GHD_TGTREQ); 607 608 /* wait for the abort to complete */ 609 if (rc = ghd_poll(cccp, GHD_POLL_REQUEST, ghd_tran_abort_timeout, 610 gcmdp, gtgtp, intr_status)) { 611 gcmdp->cmd_state = GCMD_STATE_DONEQ; 612 GHD_DONEQ_PUT_TAIL(cccp, gcmdp); 613 } 614 615 exit: 616 ghd_doneq_pollmode_exit(cccp); 617 618 mutex_enter(&cccp->ccc_waitq_mutex); 619 ghd_waitq_process_and_mutex_exit(cccp); 620 621 return (rc); 622 } 623 624 625 /* 626 * ghd_tran_abort_lun() 627 * 628 * Abort all commands on a specific target. 629 * 630 */ 631 632 int 633 ghd_tran_abort_lun(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status) 634 { 635 int rc; 636 637 /* 638 * call the HBA driver's abort_device function 639 */ 640 641 mutex_enter(&cccp->ccc_hba_mutex); 642 ghd_doneq_pollmode_enter(cccp); 643 644 /* send out the abort device request */ 645 ghd_timer_newstate(cccp, NULL, gtgtp, GACTION_ABORT_DEV, GHD_TGTREQ); 646 647 /* wait for the device to go idle */ 648 rc = ghd_poll(cccp, GHD_POLL_DEVICE, ghd_tran_abort_lun_timeout, 649 NULL, gtgtp, intr_status); 650 651 ghd_doneq_pollmode_exit(cccp); 652 653 mutex_enter(&cccp->ccc_waitq_mutex); 654 ghd_waitq_process_and_mutex_exit(cccp); 655 656 return (rc); 657 } 658 659 660 661 /* 662 * ghd_tran_reset_target() 663 * 664 * reset the target device 665 * 666 * 667 */ 668 669 int 670 ghd_tran_reset_target(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status) 671 { 672 int rc = TRUE; 673 674 675 mutex_enter(&cccp->ccc_hba_mutex); 676 ghd_doneq_pollmode_enter(cccp); 677 678 /* send out the device reset request */ 679 ghd_timer_newstate(cccp, NULL, gtgtp, GACTION_RESET_TARGET, GHD_TGTREQ); 680 681 /* wait for the device to reset */ 682 rc = ghd_poll(cccp, GHD_POLL_DEVICE, ghd_tran_reset_target_timeout, 683 NULL, gtgtp, intr_status); 684 685 ghd_doneq_pollmode_exit(cccp); 686 687 mutex_enter(&cccp->ccc_waitq_mutex); 688 ghd_waitq_process_and_mutex_exit(cccp); 689 690 return (rc); 691 } 692 693 694 695 /* 696 * ghd_tran_reset_bus() 697 * 698 * reset the scsi bus 699 * 700 */ 701 702 int 703 ghd_tran_reset_bus(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status) 704 { 705 int rc; 706 707 mutex_enter(&cccp->ccc_hba_mutex); 708 ghd_doneq_pollmode_enter(cccp); 709 710 /* send out the bus reset request */ 711 ghd_timer_newstate(cccp, NULL, gtgtp, GACTION_RESET_BUS, GHD_TGTREQ); 712 713 /* 714 * Wait for all active requests on this HBA to complete 715 */ 716 rc = ghd_poll(cccp, GHD_POLL_ALL, ghd_tran_reset_bus_timeout, 717 NULL, NULL, intr_status); 718 719 720 ghd_doneq_pollmode_exit(cccp); 721 722 mutex_enter(&cccp->ccc_waitq_mutex); 723 ghd_waitq_process_and_mutex_exit(cccp); 724 725 return (rc); 726 } 727 728 729 int 730 ghd_transport(ccc_t *cccp, 731 gcmd_t *gcmdp, 732 gtgt_t *gtgtp, 733 ulong_t timeout, 734 int polled, 735 void *intr_status) 736 { 737 gdev_t *gdevp = gtgtp->gt_gdevp; 738 739 ASSERT(!mutex_owned(&cccp->ccc_hba_mutex)); 740 ASSERT(!mutex_owned(&cccp->ccc_waitq_mutex)); 741 742 if (polled) { 743 /* 744 * Grab the HBA mutex so no other requests are started 745 * until after this one completes. 746 */ 747 mutex_enter(&cccp->ccc_hba_mutex); 748 749 GDBG_START(("ghd_transport: polled" 750 " cccp 0x%p gdevp 0x%p gtgtp 0x%p gcmdp 0x%p\n", 751 (void *)cccp, (void *)gdevp, (void *)gtgtp, (void *)gcmdp)); 752 753 /* 754 * Lock the doneq so no other thread flushes the Q. 755 */ 756 ghd_doneq_pollmode_enter(cccp); 757 } 758 #if defined(GHD_DEBUG) || defined(__lint) 759 else { 760 GDBG_START(("ghd_transport: non-polled" 761 " cccp 0x%p gdevp 0x%p gtgtp 0x%p gcmdp 0x%p\n", 762 (void *)cccp, (void *)gdevp, (void *)gtgtp, (void *)gcmdp)); 763 } 764 #endif 765 /* 766 * add this request to the tail of the waitq 767 */ 768 gcmdp->cmd_waitq_level = 1; 769 mutex_enter(&cccp->ccc_waitq_mutex); 770 L2_add(&GDEV_QHEAD(gdevp), &gcmdp->cmd_q, gcmdp); 771 772 /* 773 * Add this request to the packet timer active list and start its 774 * abort timer. 775 */ 776 gcmdp->cmd_state = GCMD_STATE_WAITQ; 777 ghd_timer_start(cccp, gcmdp, timeout); 778 779 780 /* 781 * Check the device wait queue throttle and perhaps move 782 * some requests to the end of the HBA wait queue. 783 */ 784 ghd_waitq_shuffle_up(cccp, gdevp); 785 786 if (!polled) { 787 /* 788 * See if the HBA mutex is available but use the 789 * tryenter so I don't deadlock. 790 */ 791 if (!mutex_tryenter(&cccp->ccc_hba_mutex)) { 792 /* The HBA mutex isn't available */ 793 GDBG_START(("ghd_transport: !mutex cccp 0x%p\n", 794 (void *)cccp)); 795 mutex_exit(&cccp->ccc_waitq_mutex); 796 return (TRAN_ACCEPT); 797 } 798 GDBG_START(("ghd_transport: got mutex cccp 0x%p\n", 799 (void *)cccp)); 800 801 /* 802 * start as many requests as possible from the head 803 * of the HBA wait queue 804 */ 805 806 ghd_waitq_process_and_mutex_exit(cccp); 807 808 ASSERT(!mutex_owned(&cccp->ccc_hba_mutex)); 809 ASSERT(!mutex_owned(&cccp->ccc_waitq_mutex)); 810 811 return (TRAN_ACCEPT); 812 } 813 814 815 /* 816 * If polled mode (FLAG_NOINTR specified in scsi_pkt flags), 817 * then ghd_poll() waits until the request completes or times out 818 * before returning. 819 */ 820 821 mutex_exit(&cccp->ccc_waitq_mutex); 822 (void) ghd_poll(cccp, GHD_POLL_REQUEST, 0, gcmdp, gtgtp, intr_status); 823 ghd_doneq_pollmode_exit(cccp); 824 825 mutex_enter(&cccp->ccc_waitq_mutex); 826 ghd_waitq_process_and_mutex_exit(cccp); 827 828 /* call HBA's completion function but don't do callback to target */ 829 (*cccp->ccc_hba_complete)(cccp->ccc_hba_handle, gcmdp, FALSE); 830 831 GDBG_START(("ghd_transport: polled done cccp 0x%p\n", (void *)cccp)); 832 return (TRAN_ACCEPT); 833 } 834 835 int ghd_reset_notify(ccc_t *cccp, 836 gtgt_t *gtgtp, 837 int flag, 838 void (*callback)(caddr_t), 839 caddr_t arg) 840 { 841 ghd_reset_notify_list_t *rnp; 842 int rc = FALSE; 843 844 switch (flag) { 845 846 case SCSI_RESET_NOTIFY: 847 848 rnp = (ghd_reset_notify_list_t *)kmem_zalloc(sizeof (*rnp), 849 KM_SLEEP); 850 rnp->gtgtp = gtgtp; 851 rnp->callback = callback; 852 rnp->arg = arg; 853 854 mutex_enter(&cccp->ccc_reset_notify_mutex); 855 L2_add(&cccp->ccc_reset_notify_list, &rnp->l2_link, 856 (void *)rnp); 857 mutex_exit(&cccp->ccc_reset_notify_mutex); 858 859 rc = TRUE; 860 861 break; 862 863 case SCSI_RESET_CANCEL: 864 865 mutex_enter(&cccp->ccc_reset_notify_mutex); 866 for (rnp = (ghd_reset_notify_list_t *) 867 L2_next(&cccp->ccc_reset_notify_list); 868 rnp != NULL; 869 rnp = (ghd_reset_notify_list_t *)L2_next(&rnp->l2_link)) { 870 if (rnp->gtgtp == gtgtp && 871 rnp->callback == callback && 872 rnp->arg == arg) { 873 L2_delete(&rnp->l2_link); 874 kmem_free(rnp, sizeof (*rnp)); 875 rc = TRUE; 876 } 877 } 878 mutex_exit(&cccp->ccc_reset_notify_mutex); 879 break; 880 881 default: 882 rc = FALSE; 883 break; 884 } 885 886 return (rc); 887 } 888 889 /* 890 * freeze the HBA waitq output (see ghd_waitq_process_and_mutex_hold), 891 * presumably because of a SCSI reset, for delay milliseconds. 892 */ 893 894 void 895 ghd_freeze_waitq(ccc_t *cccp, int delay) 896 { 897 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 898 899 /* freeze the waitq for delay milliseconds */ 900 901 mutex_enter(&cccp->ccc_waitq_mutex); 902 cccp->ccc_waitq_freezetime = ddi_get_lbolt(); 903 cccp->ccc_waitq_freezedelay = delay; 904 cccp->ccc_waitq_frozen = 1; 905 mutex_exit(&cccp->ccc_waitq_mutex); 906 } 907 908 void 909 ghd_queue_hold(ccc_t *cccp) 910 { 911 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 912 913 mutex_enter(&cccp->ccc_waitq_mutex); 914 cccp->ccc_waitq_held = 1; 915 mutex_exit(&cccp->ccc_waitq_mutex); 916 } 917 918 void 919 ghd_queue_unhold(ccc_t *cccp) 920 { 921 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 922 923 mutex_enter(&cccp->ccc_waitq_mutex); 924 cccp->ccc_waitq_held = 0; 925 mutex_exit(&cccp->ccc_waitq_mutex); 926 } 927 928 929 930 /* 931 * Trigger previously-registered reset notifications 932 */ 933 934 void 935 ghd_trigger_reset_notify(ccc_t *cccp) 936 { 937 gcmd_t *gcmdp; 938 939 ASSERT(mutex_owned(&cccp->ccc_hba_mutex)); 940 941 /* create magic doneq entry */ 942 943 gcmdp = ghd_gcmd_alloc((gtgt_t *)NULL, 0, TRUE); 944 gcmdp->cmd_flags = GCMDFLG_RESET_NOTIFY; 945 946 /* put at head of doneq so it's processed ASAP */ 947 948 GHD_DONEQ_PUT_HEAD(cccp, gcmdp); 949 } 950