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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * generic scsi device watch 31 */ 32 33 #if DEBUG || lint 34 #define SWDEBUG 35 #endif 36 37 /* 38 * debug goodies 39 */ 40 #ifdef SWDEBUG 41 static int swdebug = 0; 42 #define DEBUGGING ((scsi_options & SCSI_DEBUG_TGT) && sddebug > 1) 43 #define SW_DEBUG if (swdebug == 1) scsi_log 44 #define SW_DEBUG2 if (swdebug > 1) scsi_log 45 #else /* SWDEBUG */ 46 #define swdebug (0) 47 #define DEBUGGING (0) 48 #define SW_DEBUG if (0) scsi_log 49 #define SW_DEBUG2 if (0) scsi_log 50 #endif 51 52 53 54 /* 55 * Includes, Declarations and Local Data 56 */ 57 58 #include <sys/note.h> 59 #include <sys/scsi/scsi.h> 60 #include <sys/var.h> 61 #include <sys/proc.h> 62 #include <sys/thread.h> 63 #include <sys/callb.h> 64 65 /* 66 * macro for filling in lun value for scsi-1 support 67 */ 68 #define FILL_SCSI1_LUN(devp, pkt) \ 69 if ((devp->sd_address.a_lun > 0) && \ 70 (devp->sd_inq->inq_ansi == 0x1)) { \ 71 ((union scsi_cdb *)(pkt)->pkt_cdbp)->scc_lun = \ 72 devp->sd_address.a_lun; \ 73 } 74 75 char *sw_label = "scsi-watch"; 76 77 static int scsi_watch_io_time = SCSI_WATCH_IO_TIME; 78 79 /* 80 * all info resides in the scsi watch structure 81 * 82 * the monitoring is performed by one separate thread which works 83 * from a linked list of scsi_watch_request packets 84 */ 85 static struct scsi_watch { 86 kthread_t *sw_thread; /* the watch thread */ 87 kmutex_t sw_mutex; /* mutex protecting list */ 88 /* and this structure */ 89 kcondvar_t sw_cv; /* cv for waking up thread */ 90 struct scsi_watch_request *sw_head; /* head of linked list */ 91 /* of request structures */ 92 uchar_t sw_state; /* for suspend-resume */ 93 uchar_t sw_flags; /* to start at head of list */ 94 /* for watch thread */ 95 } sw; 96 97 #if !defined(lint) 98 _NOTE(MUTEX_PROTECTS_DATA(scsi_watch::sw_mutex, scsi_watch)) 99 #endif 100 101 /* 102 * Values for sw_state 103 */ 104 #define SW_RUNNING 0 105 #define SW_SUSPEND_REQUESTED 1 106 #define SW_SUSPENDED 2 107 108 /* 109 * values for sw_flags 110 */ 111 #define SW_START_HEAD 0x1 112 113 struct scsi_watch_request { 114 struct scsi_watch_request *swr_next; /* linked request list */ 115 struct scsi_watch_request *swr_prev; 116 clock_t swr_interval; /* interval between TURs */ 117 clock_t swr_timeout; /* count down */ 118 uchar_t swr_busy; /* TUR in progress */ 119 uchar_t swr_what; /* watch or stop */ 120 uchar_t swr_sense_length; /* required sense length */ 121 struct scsi_pkt *swr_pkt; /* TUR pkt itself */ 122 struct scsi_pkt *swr_rqpkt; /* request sense pkt */ 123 struct buf *swr_rqbp; /* bp for request sense data */ 124 int (*swr_callback)(); /* callback to driver */ 125 caddr_t swr_callback_arg; 126 kcondvar_t swr_terminate_cv; /* cv to wait on to cleanup */ 127 /* request synchronously */ 128 }; 129 130 #if !defined(lint) 131 _NOTE(SCHEME_PROTECTS_DATA("unshared data", scsi_watch_request)) 132 #endif 133 134 /* 135 * values for sw_what 136 */ 137 #define SWR_WATCH 0 /* device watch */ 138 #define SWR_STOP 1 /* stop monitoring and destroy swr */ 139 #define SWR_SUSPEND_REQUESTED 2 /* req. pending suspend */ 140 #define SWR_SUSPENDED 3 /* req. is suspended */ 141 142 static void scsi_watch_request_destroy(struct scsi_watch_request *swr); 143 static void scsi_watch_thread(void); 144 static void scsi_watch_request_intr(struct scsi_pkt *pkt); 145 146 /* 147 * setup, called from _init(), the thread is created when we need it 148 * and exits when there is nothing to do anymore and everything has been 149 * cleaned up (ie. resources deallocated) 150 */ 151 void 152 scsi_watch_init() 153 { 154 /* NO OTHER THREADS ARE RUNNING */ 155 mutex_init(&sw.sw_mutex, NULL, MUTEX_DRIVER, NULL); 156 cv_init(&sw.sw_cv, NULL, CV_DRIVER, NULL); 157 sw.sw_state = SW_RUNNING; 158 sw.sw_flags = 0; 159 } 160 161 /* 162 * cleaning up, called from _fini() 163 */ 164 void 165 scsi_watch_fini() 166 { 167 /* NO OTHER THREADS ARE RUNNING */ 168 /* 169 * hope and pray that the thread has exited 170 */ 171 ASSERT(sw.sw_thread == 0); 172 mutex_destroy(&sw.sw_mutex); 173 cv_destroy(&sw.sw_cv); 174 } 175 176 /* 177 * allocate an swr (scsi watch request structure) and initialize pkts 178 */ 179 #define ROUTE &devp->sd_address 180 181 opaque_t 182 scsi_watch_request_submit( 183 struct scsi_device *devp, 184 int interval, 185 int sense_length, 186 int (*callback)(), /* callback function */ 187 caddr_t cb_arg) /* device number */ 188 { 189 register struct scsi_watch_request *swr = NULL; 190 register struct scsi_watch_request *sswr, *p; 191 struct buf *bp = NULL; 192 struct scsi_pkt *rqpkt = NULL; 193 struct scsi_pkt *pkt = NULL; 194 uchar_t dtype; 195 196 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 197 "scsi_watch_request_submit: Entering ...\n"); 198 199 mutex_enter(&sw.sw_mutex); 200 if (sw.sw_thread == 0) { 201 register kthread_t *t; 202 203 t = thread_create((caddr_t)NULL, 0, scsi_watch_thread, 204 NULL, 0, &p0, TS_RUN, v.v_maxsyspri - 2); 205 sw.sw_thread = t; 206 } 207 208 for (p = sw.sw_head; p != NULL; p = p->swr_next) { 209 if ((p->swr_callback_arg == cb_arg) && 210 (p->swr_callback == callback)) 211 break; 212 } 213 214 /* update time interval for an existing request */ 215 if (p) { 216 p->swr_timeout = p->swr_interval = drv_usectohz(interval); 217 p->swr_what = SWR_WATCH; 218 cv_signal(&sw.sw_cv); 219 mutex_exit(&sw.sw_mutex); 220 return ((opaque_t)p); 221 } 222 mutex_exit(&sw.sw_mutex); 223 224 /* 225 * allocate space for scsi_watch_request 226 */ 227 swr = kmem_zalloc(sizeof (struct scsi_watch_request), KM_SLEEP); 228 229 /* 230 * allocate request sense bp and pkt and make cmd 231 * we shouldn't really need it if ARQ is enabled but it is useful 232 * if the ARQ failed. 233 */ 234 bp = scsi_alloc_consistent_buf(ROUTE, NULL, 235 sense_length, B_READ, SLEEP_FUNC, NULL); 236 237 rqpkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, 238 bp, CDB_GROUP0, 1, 0, PKT_CONSISTENT, SLEEP_FUNC, NULL); 239 240 (void) scsi_setup_cdb((union scsi_cdb *)rqpkt->pkt_cdbp, 241 SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0); 242 FILL_SCSI1_LUN(devp, rqpkt); 243 rqpkt->pkt_private = (opaque_t)swr; 244 rqpkt->pkt_time = scsi_watch_io_time; 245 rqpkt->pkt_comp = scsi_watch_request_intr; 246 rqpkt->pkt_flags |= FLAG_HEAD; 247 248 /* 249 * Create TUR pkt or a zero byte WRITE(10) based on the 250 * disk-type for reservation state. 251 * For inq_dtype of SBC (DIRECT, dtype == 0) 252 * OR for RBC devices (dtype is 0xE) AND for 253 * ANSI version of SPC/SPC-2/SPC-3 (inq_ansi == 3-5). 254 */ 255 256 dtype = devp->sd_inq->inq_dtype & DTYPE_MASK; 257 if (((dtype == 0) || (dtype == 0xE)) && 258 (devp->sd_inq->inq_ansi > 2)) { 259 pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, NULL, 260 CDB_GROUP1, sizeof (struct scsi_arq_status), 261 0, 0, SLEEP_FUNC, NULL); 262 263 (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, 264 SCMD_WRITE_G1, 0, 0, 0); 265 } else { 266 pkt = scsi_init_pkt(ROUTE, (struct scsi_pkt *)NULL, NULL, 267 CDB_GROUP0, sizeof (struct scsi_arq_status), 268 0, 0, SLEEP_FUNC, NULL); 269 270 (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, 271 SCMD_TEST_UNIT_READY, 0, 0, 0); 272 FILL_SCSI1_LUN(devp, pkt); 273 } 274 275 pkt->pkt_private = (opaque_t)swr; 276 pkt->pkt_time = scsi_watch_io_time; 277 pkt->pkt_comp = scsi_watch_request_intr; 278 if (scsi_ifgetcap(&pkt->pkt_address, "tagged-qing", 1) == 1) { 279 pkt->pkt_flags |= FLAG_STAG; 280 } 281 282 /* 283 * set the allocated resources in swr 284 */ 285 swr->swr_rqbp = bp; 286 swr->swr_rqpkt = rqpkt; 287 swr->swr_pkt = pkt; 288 swr->swr_timeout = swr->swr_interval = drv_usectohz(interval); 289 swr->swr_callback = callback; 290 swr->swr_callback_arg = cb_arg; 291 swr->swr_what = SWR_WATCH; 292 swr->swr_sense_length = (uchar_t)sense_length; 293 cv_init(&swr->swr_terminate_cv, NULL, CV_DRIVER, NULL); 294 295 /* 296 * add to the list and wake up the thread 297 */ 298 mutex_enter(&sw.sw_mutex); 299 swr->swr_next = sw.sw_head; 300 swr->swr_prev = NULL; 301 if (sw.sw_head) { 302 sw.sw_head->swr_prev = swr; 303 } 304 sw.sw_head = swr; 305 306 /* 307 * reset all timeouts, so all requests are in sync again 308 * XXX there is a small window where the watch thread releases 309 * the mutex so that could upset the resyncing 310 */ 311 sswr = swr; 312 while (sswr) { 313 sswr->swr_timeout = swr->swr_interval; 314 sswr = sswr->swr_next; 315 } 316 cv_signal(&sw.sw_cv); 317 mutex_exit(&sw.sw_mutex); 318 return ((opaque_t)swr); 319 } 320 321 322 /* 323 * called by (eg. pwr management) to resume the scsi_watch_thread 324 */ 325 void 326 scsi_watch_resume(opaque_t token) 327 { 328 struct scsi_watch_request *swr = (struct scsi_watch_request *)NULL; 329 /* 330 * Change the state to SW_RUNNING and wake up the scsi_watch_thread 331 */ 332 SW_DEBUG(0, sw_label, SCSI_DEBUG, "scsi_watch_resume:\n"); 333 mutex_enter(&sw.sw_mutex); 334 335 if (!sw.sw_head) 336 goto exit; 337 338 /* search for token */ 339 for (swr = sw.sw_head; swr; swr = swr->swr_next) { 340 if (swr == (struct scsi_watch_request *)token) 341 break; 342 } 343 344 /* if we can't find this value, then we just do nothing */ 345 if (swr == (struct scsi_watch_request *)NULL) 346 goto exit; 347 348 swr->swr_what = SWR_WATCH; 349 350 351 /* see if all swr's are awake, then start the thread again */ 352 for (swr = sw.sw_head; swr; swr = swr->swr_next) { 353 if (swr->swr_what != SWR_WATCH) 354 goto exit; 355 } 356 357 sw.sw_state = SW_RUNNING; 358 cv_signal(&sw.sw_cv); 359 360 exit: 361 mutex_exit(&sw.sw_mutex); 362 } 363 364 365 /* 366 * called by clients (eg. pwr management) to suspend the scsi_watch_thread 367 */ 368 void 369 scsi_watch_suspend(opaque_t token) 370 { 371 struct scsi_watch_request *swr = (struct scsi_watch_request *)NULL; 372 clock_t now; 373 clock_t halfsec_delay = drv_usectohz(500000); 374 375 SW_DEBUG(0, sw_label, SCSI_DEBUG, "scsi_watch_suspend:\n"); 376 377 mutex_enter(&sw.sw_mutex); 378 379 if (!sw.sw_head) 380 goto exit; 381 382 /* search for token */ 383 for (swr = sw.sw_head; swr; swr = swr->swr_next) { 384 if (swr == (struct scsi_watch_request *)token) 385 break; 386 } 387 388 /* if we can't find this value, then we just do nothing */ 389 if (swr == (struct scsi_watch_request *)NULL) 390 goto exit; 391 392 393 for (;;) { 394 if (swr->swr_busy) { 395 /* 396 * XXX: Assumes that this thread can rerun 397 * till all outstanding cmds are complete 398 */ 399 swr->swr_what = SWR_SUSPEND_REQUESTED; 400 now = ddi_get_lbolt(); 401 (void) cv_timedwait(&sw.sw_cv, &sw.sw_mutex, 402 now + halfsec_delay); 403 } else { 404 swr->swr_what = SWR_SUSPENDED; 405 break; 406 } 407 } 408 409 /* see if all swr's are suspended, then suspend the thread */ 410 for (swr = sw.sw_head; swr; swr = swr->swr_next) { 411 if (swr->swr_what != SWR_SUSPENDED) 412 goto exit; 413 } 414 415 sw.sw_state = SW_SUSPENDED; 416 417 exit: 418 mutex_exit(&sw.sw_mutex); 419 } 420 421 /* 422 * destroy swr, called for watch thread 423 */ 424 static void 425 scsi_watch_request_destroy(struct scsi_watch_request *swr) 426 { 427 ASSERT(MUTEX_HELD(&sw.sw_mutex)); 428 ASSERT(swr->swr_busy == 0); 429 430 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 431 "scsi_watch_request_destroy: Entering ...\n"); 432 433 /* 434 * remove swr from linked list and destroy pkts 435 */ 436 if (swr->swr_prev) { 437 swr->swr_prev->swr_next = swr->swr_next; 438 } 439 if (swr->swr_next) { 440 swr->swr_next->swr_prev = swr->swr_prev; 441 } 442 if (sw.sw_head == swr) { 443 sw.sw_head = swr->swr_next; 444 } 445 446 scsi_destroy_pkt(swr->swr_rqpkt); 447 scsi_free_consistent_buf(swr->swr_rqbp); 448 scsi_destroy_pkt(swr->swr_pkt); 449 cv_signal(&swr->swr_terminate_cv); 450 } 451 452 /* 453 * scsi_watch_request_terminate() 454 * called by requestor to terminate any pending watch request. 455 * if the request is currently "busy", and the caller cannot wait, failure 456 * is returned. O/w the request is cleaned up immediately. 457 */ 458 int 459 scsi_watch_request_terminate(opaque_t token, int flags) 460 { 461 struct scsi_watch_request *swr = 462 (struct scsi_watch_request *)token; 463 struct scsi_watch_request *sswr; 464 465 /* 466 * We try to clean up this request if we can. We also inform 467 * the watch thread that we mucked around the list so it has 468 * to start reading from head of list again. 469 */ 470 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 471 "scsi_watch_request_terminate: Entering(0x%p) ...\n", 472 (void *)swr); 473 mutex_enter(&sw.sw_mutex); 474 475 /* 476 * check if it is still in the list 477 */ 478 sswr = sw.sw_head; 479 while (sswr) { 480 if (sswr == swr) { 481 if (swr->swr_busy) { 482 if (flags == SCSI_WATCH_TERMINATE_NOWAIT) { 483 mutex_exit(&sw.sw_mutex); 484 return (SCSI_WATCH_TERMINATE_FAIL); 485 } else { 486 swr->swr_what = SWR_STOP; 487 cv_wait(&swr->swr_terminate_cv, 488 &sw.sw_mutex); 489 goto done; 490 } 491 } else { 492 scsi_watch_request_destroy(swr); 493 sw.sw_flags |= SW_START_HEAD; 494 goto done; 495 } 496 } 497 sswr = sswr->swr_next; 498 } 499 done: 500 mutex_exit(&sw.sw_mutex); 501 if (sswr) { 502 cv_destroy(&swr->swr_terminate_cv); 503 kmem_free((caddr_t)swr, sizeof (struct scsi_watch_request)); 504 return (SCSI_WATCH_TERMINATE_SUCCESS); 505 } else { 506 return (SCSI_WATCH_TERMINATE_FAIL); 507 } 508 } 509 510 511 /* 512 * The routines scsi_watch_thread & scsi_watch_request_intr are 513 * on different threads. 514 * If there is no work to be done by the lower level driver 515 * then swr->swr_busy will not be set. 516 * In this case we will call CALLB_CPR_SAFE_BEGIN before 517 * calling cv_timedwait. 518 * In the other case where there is work to be done by 519 * the lower level driver then the flag swr->swr_busy will 520 * be set. 521 * We cannot call CALLB_CPR_SAFE_BEGIN at this point the reason 522 * is the intr thread can interfere with our operations. So 523 * we do a cv_timedwait here. Now at the completion of the 524 * lower level driver's work we will call CALLB_CPR_SAFE_BEGIN 525 * in scsi_watch_request_intr. 526 * In all the cases we will call CALLB_CPR_SAFE_END only if 527 * we already called a CALLB_CPR_SAFE_BEGIN and this is flagged 528 * by sw_cpr_flag. 529 * Warlock has a problem when we use different locks 530 * on the same type of structure in different contexts. 531 * We use callb_cpr_t in both scsi_watch and esp_callback threads. 532 * we use different mutexe's in different threads. And 533 * this is not acceptable to warlock. To avoid this 534 * problem we use the same name for the mutex in 535 * both scsi_watch & esp_callback. when __lock_lint is not defined 536 * esp_callback uses the mutex on the stack and in scsi_watch 537 * a static variable. But when __lock_lint is defined 538 * we make a mutex which is global in esp_callback and 539 * a external mutex for scsi_watch. 540 */ 541 static int sw_cmd_count = 0; 542 static int sw_cpr_flag = 0; 543 static callb_cpr_t cpr_info; 544 #ifndef __lock_lint 545 static kmutex_t cpr_mutex; 546 #else 547 extern kmutex_t cpr_mutex; 548 #endif 549 550 #if !defined(lint) 551 _NOTE(MUTEX_PROTECTS_DATA(cpr_mutex, cpr_info)) 552 _NOTE(MUTEX_PROTECTS_DATA(cpr_mutex, sw_cmd_count)) 553 #endif 554 /* 555 * the scsi watch thread: 556 * it either wakes up if there is work to do or if the cv_timeait 557 * timed out 558 * normally, it wakes up every <delay> seconds and checks the list. 559 * the interval is not very accurate if the cv was signalled but that 560 * really doesn't matter much 561 * it is more important that we fire off all TURs simulataneously so 562 * we don't have to wake up frequently 563 */ 564 static void 565 scsi_watch_thread() 566 { 567 struct scsi_watch_request *swr, *next; 568 clock_t now; 569 clock_t last_delay = 0; 570 clock_t next_delay = 0; 571 clock_t onesec = drv_usectohz(1000000); 572 clock_t exit_delay = 60 * onesec; 573 574 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 575 "scsi_watch_thread: Entering ...\n"); 576 577 #if !defined(lint) 578 _NOTE(NO_COMPETING_THREADS_NOW); 579 #endif 580 mutex_init(&cpr_mutex, NULL, MUTEX_DRIVER, NULL); 581 CALLB_CPR_INIT(&cpr_info, 582 &cpr_mutex, callb_generic_cpr, "scsi_watch"); 583 sw_cpr_flag = 0; 584 #if !defined(lint) 585 /*LINTED*/ 586 _NOTE(COMPETING_THREADS_NOW); 587 #endif 588 /* 589 * grab the mutex and wait for work 590 */ 591 mutex_enter(&sw.sw_mutex); 592 if (sw.sw_head == NULL) { 593 cv_wait(&sw.sw_cv, &sw.sw_mutex); 594 } 595 596 /* 597 * now loop forever for work; if queue is empty exit 598 */ 599 for (;;) { 600 head: 601 swr = sw.sw_head; 602 while (swr) { 603 604 /* 605 * If state is not running, wait for scsi_watch_resume 606 * to signal restart, but before going into cv_wait 607 * need to let the PM framework know that it is safe 608 * to stop this thread for CPR 609 */ 610 if (sw.sw_state != SW_RUNNING) { 611 SW_DEBUG(0, sw_label, SCSI_DEBUG, 612 "scsi_watch_thread suspended\n"); 613 mutex_enter(&cpr_mutex); 614 if (!sw_cmd_count) { 615 CALLB_CPR_SAFE_BEGIN(&cpr_info); 616 sw_cpr_flag = 1; 617 } 618 mutex_exit(&cpr_mutex); 619 cv_wait(&sw.sw_cv, &sw.sw_mutex); 620 /* 621 * Need to let the PM framework know that it 622 * is no longer safe to stop the thread for 623 * CPR. 624 */ 625 mutex_exit(&sw.sw_mutex); 626 mutex_enter(&cpr_mutex); 627 if (sw_cpr_flag == 1) { 628 CALLB_CPR_SAFE_END( 629 &cpr_info, &cpr_mutex); 630 sw_cpr_flag = 0; 631 } 632 mutex_exit(&cpr_mutex); 633 mutex_enter(&sw.sw_mutex); 634 } 635 636 if (next_delay == 0) { 637 next_delay = swr->swr_timeout; 638 } else { 639 next_delay = min(swr->swr_timeout, next_delay); 640 } 641 642 swr->swr_timeout -= last_delay; 643 next = swr->swr_next; 644 645 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 646 "scsi_watch_thread: " 647 "swr(0x%p),what=%x,timeout=%lx," 648 "interval=%lx,delay=%lx\n", 649 (void *)swr, swr->swr_what, swr->swr_timeout, 650 swr->swr_interval, last_delay); 651 652 switch (swr->swr_what) { 653 case SWR_SUSPENDED: 654 case SWR_SUSPEND_REQUESTED: 655 /* if we are suspended, don't do anything */ 656 break; 657 658 case SWR_STOP: 659 if (swr->swr_busy == 0) { 660 scsi_watch_request_destroy(swr); 661 } 662 break; 663 664 default: 665 if (swr->swr_timeout <= 0 && !swr->swr_busy) { 666 swr->swr_busy = 1; 667 668 /* 669 * submit the cmd and let the completion 670 * function handle the result 671 * release the mutex (good practice) 672 * this should be safe even if the list 673 * is changing 674 */ 675 mutex_exit(&sw.sw_mutex); 676 mutex_enter(&cpr_mutex); 677 sw_cmd_count++; 678 mutex_exit(&cpr_mutex); 679 SW_DEBUG((dev_info_t *)NULL, 680 sw_label, SCSI_DEBUG, 681 "scsi_watch_thread: " 682 "Starting TUR\n"); 683 if (scsi_transport(swr->swr_pkt) != 684 TRAN_ACCEPT) { 685 686 /* 687 * try again later 688 */ 689 swr->swr_busy = 0; 690 SW_DEBUG((dev_info_t *)NULL, 691 sw_label, SCSI_DEBUG, 692 "scsi_watch_thread: " 693 "Transport Failed\n"); 694 mutex_enter(&cpr_mutex); 695 sw_cmd_count--; 696 mutex_exit(&cpr_mutex); 697 } 698 mutex_enter(&sw.sw_mutex); 699 swr->swr_timeout = swr->swr_interval; 700 } 701 break; 702 } 703 swr = next; 704 if (sw.sw_flags & SW_START_HEAD) { 705 sw.sw_flags &= ~SW_START_HEAD; 706 goto head; 707 } 708 } 709 710 /* 711 * delay using cv_timedwait; we return when 712 * signalled or timed out 713 */ 714 if (sw.sw_head != NULL) { 715 if (next_delay <= 0) { 716 next_delay = onesec; 717 } 718 } else { 719 next_delay = exit_delay; 720 } 721 now = ddi_get_lbolt(); 722 723 mutex_enter(&cpr_mutex); 724 if (!sw_cmd_count) { 725 CALLB_CPR_SAFE_BEGIN(&cpr_info); 726 sw_cpr_flag = 1; 727 } 728 mutex_exit(&cpr_mutex); 729 /* 730 * if we return from cv_timedwait because we were 731 * signalled, the delay is not accurate but that doesn't 732 * really matter 733 */ 734 (void) cv_timedwait(&sw.sw_cv, &sw.sw_mutex, now + next_delay); 735 mutex_exit(&sw.sw_mutex); 736 mutex_enter(&cpr_mutex); 737 if (sw_cpr_flag == 1) { 738 CALLB_CPR_SAFE_END(&cpr_info, &cpr_mutex); 739 sw_cpr_flag = 0; 740 } 741 mutex_exit(&cpr_mutex); 742 mutex_enter(&sw.sw_mutex); 743 last_delay = next_delay; 744 next_delay = 0; 745 746 /* 747 * is there still work to do? 748 */ 749 if (sw.sw_head == NULL) { 750 break; 751 } 752 } 753 754 /* 755 * no more work to do, reset sw_thread and exit 756 */ 757 sw.sw_thread = 0; 758 mutex_exit(&sw.sw_mutex); 759 #ifndef __lock_lint 760 mutex_enter(&cpr_mutex); 761 CALLB_CPR_EXIT(&cpr_info); 762 #endif 763 mutex_destroy(&cpr_mutex); 764 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 765 "scsi_watch_thread: Exiting ...\n"); 766 } 767 768 /* 769 * callback completion function for scsi watch pkt 770 */ 771 #define SCBP(pkt) ((struct scsi_status *)(pkt)->pkt_scbp) 772 #define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_MASK) 773 774 static void 775 scsi_watch_request_intr(struct scsi_pkt *pkt) 776 { 777 struct scsi_watch_result result; 778 struct scsi_watch_request *swr = 779 (struct scsi_watch_request *)pkt->pkt_private; 780 struct scsi_status *rqstatusp; 781 struct scsi_extended_sense *rqsensep = NULL; 782 int amt = 0; 783 784 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 785 "scsi_watch_intr: Entering ...\n"); 786 787 /* 788 * first check if it is the TUR or RQS pkt 789 */ 790 if (pkt == swr->swr_pkt) { 791 if (SCBP_C(pkt) != STATUS_GOOD && 792 SCBP_C(pkt) != STATUS_RESERVATION_CONFLICT) { 793 if (SCBP(pkt)->sts_chk && 794 ((pkt->pkt_state & STATE_ARQ_DONE) == 0)) { 795 796 /* 797 * submit the request sense pkt 798 */ 799 SW_DEBUG((dev_info_t *)NULL, 800 sw_label, SCSI_DEBUG, 801 "scsi_watch_intr: " 802 "Submitting a Request Sense " 803 "Packet\n"); 804 if (scsi_transport(swr->swr_rqpkt) != 805 TRAN_ACCEPT) { 806 807 /* 808 * just give up and try again later 809 */ 810 SW_DEBUG((dev_info_t *)NULL, 811 sw_label, SCSI_DEBUG, 812 "scsi_watch_intr: " 813 "Request Sense " 814 "Transport Failed\n"); 815 goto done; 816 } 817 818 /* 819 * wait for rqsense to complete 820 */ 821 return; 822 823 } else if (SCBP(pkt)->sts_chk) { 824 825 /* 826 * check the autorequest sense data 827 */ 828 struct scsi_arq_status *arqstat = 829 (struct scsi_arq_status *)pkt->pkt_scbp; 830 831 rqstatusp = &arqstat->sts_rqpkt_status; 832 rqsensep = &arqstat->sts_sensedata; 833 amt = swr->swr_sense_length - 834 arqstat->sts_rqpkt_resid; 835 SW_DEBUG((dev_info_t *)NULL, 836 sw_label, SCSI_DEBUG, 837 "scsi_watch_intr: " 838 "Auto Request Sense, amt=%x\n", amt); 839 } 840 } 841 842 } else if (pkt == swr->swr_rqpkt) { 843 844 /* 845 * check the request sense data 846 */ 847 rqstatusp = (struct scsi_status *)pkt->pkt_scbp; 848 rqsensep = (struct scsi_extended_sense *) 849 swr->swr_rqbp->b_un.b_addr; 850 amt = swr->swr_sense_length - pkt->pkt_resid; 851 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 852 "scsi_watch_intr: " 853 "Request Sense Completed, amt=%x\n", amt); 854 } else { 855 856 /* 857 * should not reach here!!! 858 */ 859 scsi_log((dev_info_t *)NULL, sw_label, CE_PANIC, 860 "scsi_watch_intr: Bad Packet(0x%p)", (void *)pkt); 861 } 862 863 if (rqsensep) { 864 865 /* 866 * check rqsense status and data 867 */ 868 if (rqstatusp->sts_busy || rqstatusp->sts_chk) { 869 870 /* 871 * try again later 872 */ 873 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 874 "scsi_watch_intr: " 875 "Auto Request Sense Failed - " 876 "Busy or Check Condition\n"); 877 goto done; 878 } 879 880 SW_DEBUG((dev_info_t *)NULL, sw_label, SCSI_DEBUG, 881 "scsi_watch_intr: " 882 "es_key=%x, adq=%x, amt=%x\n", 883 rqsensep->es_key, rqsensep->es_add_code, amt); 884 } 885 886 /* 887 * callback to target driver to do the real work 888 */ 889 result.statusp = SCBP(swr->swr_pkt); 890 result.sensep = rqsensep; 891 result.actual_sense_length = (uchar_t)amt; 892 result.pkt = swr->swr_pkt; 893 894 if ((*swr->swr_callback)(swr->swr_callback_arg, &result)) { 895 swr->swr_what = SWR_STOP; 896 } 897 898 done: 899 swr->swr_busy = 0; 900 mutex_enter(&cpr_mutex); 901 sw_cmd_count --; 902 if (!sw_cmd_count) { 903 CALLB_CPR_SAFE_BEGIN(&cpr_info); 904 sw_cpr_flag = 1; 905 } 906 mutex_exit(&cpr_mutex); 907 } 908