1 /* 2 * Common functions for CAM "type" (peripheral) drivers. 3 * 4 * Copyright (c) 1997, 1998 Justin T. Gibbs. 5 * Copyright (c) 1997, 1998 Kenneth D. Merry. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $Id$ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/types.h> 35 #include <sys/malloc.h> 36 #include <sys/kernel.h> 37 #include <sys/buf.h> 38 #include <sys/proc.h> 39 #include <sys/devicestat.h> 40 #include <vm/vm.h> 41 #include <vm/vm_extern.h> 42 43 #include <cam/cam.h> 44 #include <cam/cam_conf.h> 45 #include <cam/cam_ccb.h> 46 #include <cam/cam_xpt_periph.h> 47 #include <cam/cam_periph.h> 48 #include <cam/cam_debug.h> 49 50 #include <cam/scsi/scsi_all.h> 51 #include <cam/scsi/scsi_message.h> 52 #include <cam/scsi/scsi_da.h> 53 #include <cam/scsi/scsi_pass.h> 54 55 static u_int camperiphnextunit(struct periph_driver *p_drv, 56 u_int newunit, int wired); 57 static u_int camperiphunit(struct periph_driver *p_drv, 58 path_id_t path_id_t, 59 target_id_t target, lun_id_t lun); 60 static void camperiphdone(struct cam_periph *periph, 61 union ccb *done_ccb); 62 static void camperiphfree(struct cam_periph *periph); 63 64 cam_status 65 cam_periph_alloc(periph_ctor_t *periph_ctor, periph_dtor_t *periph_dtor, 66 periph_start_t *periph_start, char *name, cam_periph_type type, 67 struct cam_path *path, ac_callback_t *ac_callback, 68 ac_code code, void *arg) 69 { 70 struct periph_driver **p_drv; 71 struct cam_periph *periph; 72 struct cam_periph *cur_periph; 73 path_id_t path_id; 74 target_id_t target_id; 75 lun_id_t lun_id; 76 cam_status status; 77 u_int init_level; 78 int s; 79 80 init_level = 0; 81 /* 82 * Handle Hot-Plug scenarios. If there is already a peripheral 83 * of our type assigned to this path, we are likely waiting for 84 * final close on an old, invalidated, peripheral. If this is 85 * the case, queue up a deferred call to the peripheral's async 86 * handler. If it looks like a mistaken re-alloation, complain. 87 */ 88 if ((periph = cam_periph_find(path, name)) != NULL) { 89 90 if ((periph->flags & CAM_PERIPH_INVALID) != 0 91 && (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) == 0) { 92 periph->flags |= CAM_PERIPH_NEW_DEV_FOUND; 93 periph->deferred_callback = ac_callback; 94 periph->deferred_ac = code; 95 return (CAM_REQ_INPROG); 96 } else { 97 printf("cam_periph_alloc: attempt to re-allocate " 98 "valid device %s%d rejected\n", 99 periph->periph_name, periph->unit_number); 100 } 101 return (CAM_REQ_INVALID); 102 } 103 104 periph = (struct cam_periph *)malloc(sizeof(*periph), M_DEVBUF, 105 M_NOWAIT); 106 107 if (periph == NULL) 108 return (CAM_RESRC_UNAVAIL); 109 110 init_level++; 111 112 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items; 113 *p_drv != NULL; p_drv++) { 114 if (strcmp((*p_drv)->driver_name, name) == 0) 115 break; 116 } 117 118 path_id = xpt_path_path_id(path); 119 target_id = xpt_path_target_id(path); 120 lun_id = xpt_path_lun_id(path); 121 bzero(periph, sizeof(*periph)); 122 cam_init_pinfo(&periph->pinfo); 123 periph->periph_start = periph_start; 124 periph->periph_dtor = periph_dtor; 125 periph->type = type; 126 periph->periph_name = name; 127 periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id); 128 periph->immediate_priority = CAM_PRIORITY_NONE; 129 periph->refcount = 0; 130 SLIST_INIT(&periph->ccb_list); 131 status = xpt_create_path(&path, periph, path_id, target_id, lun_id); 132 if (status != CAM_REQ_CMP) 133 goto failure; 134 135 periph->path = path; 136 init_level++; 137 138 status = xpt_add_periph(periph); 139 140 if (status != CAM_REQ_CMP) 141 goto failure; 142 143 s = splsoftcam(); 144 cur_periph = TAILQ_FIRST(&(*p_drv)->units); 145 while (cur_periph != NULL 146 && cur_periph->unit_number < periph->unit_number) 147 cur_periph = TAILQ_NEXT(cur_periph, unit_links); 148 149 if (cur_periph != NULL) 150 TAILQ_INSERT_BEFORE(cur_periph, periph, unit_links); 151 else { 152 TAILQ_INSERT_TAIL(&(*p_drv)->units, periph, unit_links); 153 (*p_drv)->generation++; 154 } 155 156 splx(s); 157 158 init_level++; 159 160 status = periph_ctor(periph, arg); 161 162 if (status == CAM_REQ_CMP) 163 init_level++; 164 165 failure: 166 switch (init_level) { 167 case 4: 168 /* Initialized successfully */ 169 break; 170 case 3: 171 s = splsoftcam(); 172 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); 173 splx(s); 174 xpt_remove_periph(periph); 175 case 2: 176 xpt_free_path(periph->path); 177 case 1: 178 free(periph, M_DEVBUF); 179 case 0: 180 /* No cleanup to perform. */ 181 break; 182 default: 183 panic("cam_periph_alloc: Unkown init level"); 184 } 185 return(status); 186 } 187 188 /* 189 * Find a peripheral structure with the specified path, target, lun, 190 * and (optionally) type. If the name is NULL, this function will return 191 * the first peripheral driver that matches the specified path. 192 */ 193 struct cam_periph * 194 cam_periph_find(struct cam_path *path, char *name) 195 { 196 struct periph_driver **p_drv; 197 struct cam_periph *periph; 198 int s; 199 200 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items; 201 *p_drv != NULL; p_drv++) { 202 203 if (name != NULL && (strcmp((*p_drv)->driver_name, name) != 0)) 204 continue; 205 206 s = splsoftcam(); 207 for (periph = TAILQ_FIRST(&(*p_drv)->units); periph != NULL; 208 periph = TAILQ_NEXT(periph, unit_links)) { 209 if (xpt_path_comp(periph->path, path) == 0) { 210 splx(s); 211 return(periph); 212 } 213 } 214 splx(s); 215 if (name != NULL) 216 return(NULL); 217 } 218 return(NULL); 219 } 220 221 cam_status 222 cam_periph_acquire(struct cam_periph *periph) 223 { 224 int s; 225 226 if (periph == NULL) 227 return(CAM_REQ_CMP_ERR); 228 229 s = splsoftcam(); 230 periph->refcount++; 231 splx(s); 232 233 return(CAM_REQ_CMP); 234 } 235 236 void 237 cam_periph_release(struct cam_periph *periph) 238 { 239 int s; 240 241 if (periph == NULL) 242 return; 243 244 s = splsoftcam(); 245 if ((--periph->refcount == 0) 246 && (periph->flags & CAM_PERIPH_INVALID)) { 247 camperiphfree(periph); 248 } 249 splx(s); 250 251 } 252 253 /* 254 * Look for the next unit number that is not currently in use for this 255 * peripheral type starting at "newunit". Also exclude unit numbers that 256 * are reserved by for future "hardwiring" unless we already know that this 257 * is a potential wired device. Only assume that the device is "wired" the 258 * first time through the loop since after that we'll be looking at unit 259 * numbers that did not match a wiring entry. 260 */ 261 static u_int 262 camperiphnextunit(struct periph_driver *p_drv, u_int newunit, int wired) 263 { 264 struct cam_periph *periph; 265 struct cam_periph_config *periph_conf; 266 char *periph_name; 267 u_int i; 268 int s; 269 270 s = splsoftcam(); 271 periph_name = p_drv->driver_name; 272 for (;;newunit++) { 273 274 for (periph = TAILQ_FIRST(&p_drv->units); 275 periph != NULL && periph->unit_number != newunit; 276 periph = TAILQ_NEXT(periph, unit_links)) 277 ; 278 279 if (periph != NULL && periph->unit_number == newunit) { 280 if (wired != 0) { 281 xpt_print_path(periph->path); 282 printf("Duplicate Wired Device entry!\n"); 283 xpt_print_path(periph->path); 284 printf("Second device will not be wired\n"); 285 wired = 0; 286 } 287 continue; 288 } 289 290 for (periph_conf = cam_pinit; 291 wired == 0 && periph_conf->periph_name != NULL; 292 periph_conf++) { 293 294 /* 295 * Don't match entries like "da 4" as a wired down 296 * device, but do match entries like "da 4 target 5" 297 * or even "da 4 scbus 1". 298 */ 299 if (IS_SPECIFIED(periph_conf->periph_unit) 300 && (!strcmp(periph_name, periph_conf->periph_name)) 301 && (IS_SPECIFIED(periph_conf->target) 302 || IS_SPECIFIED(periph_conf->pathid)) 303 && (newunit == periph_conf->periph_unit)) 304 break; 305 } 306 307 if (wired != 0 || periph_conf->periph_name == NULL) 308 break; 309 } 310 splx(s); 311 return (newunit); 312 } 313 314 static u_int 315 camperiphunit(struct periph_driver *p_drv, path_id_t pathid, 316 target_id_t target, lun_id_t lun) 317 { 318 struct cam_periph_config *periph_conf; 319 u_int unit; 320 int hit; 321 322 unit = 0; 323 hit = 0; 324 325 for (periph_conf = cam_pinit; 326 periph_conf->periph_name != NULL; 327 periph_conf++, hit = 0) { 328 329 if (!strcmp(p_drv->driver_name, periph_conf->periph_name) 330 && IS_SPECIFIED(periph_conf->periph_unit)) { 331 332 if (IS_SPECIFIED(periph_conf->pathid)) { 333 334 if (pathid != periph_conf->pathid) 335 continue; 336 hit++; 337 } 338 339 if (IS_SPECIFIED(periph_conf->target)) { 340 341 if (target != periph_conf->target) 342 continue; 343 hit++; 344 } 345 346 if (IS_SPECIFIED(periph_conf->lun)) { 347 348 if (lun != periph_conf->lun) 349 continue; 350 hit++; 351 } 352 353 if (hit != 0) { 354 unit = periph_conf->periph_unit; 355 break; 356 } 357 } 358 } 359 360 /* 361 * Either start from 0 looking for the next unit or from 362 * the unit number given in the periph_conf. This way, 363 * if we have wildcard matches, we don't return the same 364 * unit number twice. 365 */ 366 unit = camperiphnextunit(p_drv, unit, /*wired*/hit); 367 368 return (unit); 369 } 370 371 void 372 cam_periph_invalidate(struct cam_periph *periph) 373 { 374 int s; 375 376 periph->flags |= CAM_PERIPH_INVALID; 377 periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND; 378 379 s = splsoftcam(); 380 if (periph->refcount == 0) 381 camperiphfree(periph); 382 else if (periph->refcount < 0) 383 printf("cam_invalidate_periph: refcount < 0!!\n"); 384 splx(s); 385 } 386 387 static void 388 camperiphfree(struct cam_periph *periph) 389 { 390 int s; 391 struct periph_driver **p_drv; 392 393 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items; 394 *p_drv != NULL; p_drv++) { 395 if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0) 396 break; 397 } 398 399 if (periph->periph_dtor != NULL) 400 periph->periph_dtor(periph); 401 402 s = splsoftcam(); 403 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); 404 (*p_drv)->generation++; 405 splx(s); 406 407 xpt_remove_periph(periph); 408 409 if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) { 410 union ccb ccb; 411 void *arg; 412 413 switch (periph->deferred_ac) { 414 case AC_FOUND_DEVICE: 415 ccb.ccb_h.func_code = XPT_GDEV_TYPE; 416 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1); 417 xpt_action(&ccb); 418 arg = &ccb; 419 break; 420 case AC_PATH_REGISTERED: 421 ccb.ccb_h.func_code = XPT_PATH_INQ; 422 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1); 423 xpt_action(&ccb); 424 arg = &ccb; 425 break; 426 default: 427 arg = NULL; 428 break; 429 } 430 periph->deferred_callback(NULL, periph->deferred_ac, 431 periph->path, arg); 432 } 433 xpt_free_path(periph->path); 434 free(periph, M_DEVBUF); 435 } 436 437 /* 438 * Wait interruptibly for an exclusive lock. 439 */ 440 int 441 cam_periph_lock(struct cam_periph *periph, int priority) 442 { 443 int error; 444 int s; 445 446 while ((periph->flags & CAM_PERIPH_LOCKED) != 0) { 447 periph->flags |= CAM_PERIPH_LOCK_WANTED; 448 if ((error = tsleep(periph, priority, "caplck", 0)) != 0) 449 return error; 450 } 451 452 if (cam_periph_acquire(periph) != CAM_REQ_CMP) 453 return(ENXIO); 454 455 periph->flags |= CAM_PERIPH_LOCKED; 456 return 0; 457 } 458 459 /* 460 * Unlock and wake up any waiters. 461 */ 462 void 463 cam_periph_unlock(struct cam_periph *periph) 464 { 465 periph->flags &= ~CAM_PERIPH_LOCKED; 466 if ((periph->flags & CAM_PERIPH_LOCK_WANTED) != 0) { 467 periph->flags &= ~CAM_PERIPH_LOCK_WANTED; 468 wakeup(periph); 469 } 470 471 cam_periph_release(periph); 472 } 473 474 /* 475 * Map user virtual pointers into kernel virtual address space, so we can 476 * access the memory. This won't work on physical pointers, for now it's 477 * up to the caller to check for that. (XXX KDM -- should we do that here 478 * instead?) This also only works for up to MAXPHYS memory. Since we use 479 * buffers to map stuff in and out, we're limited to the buffer size. 480 */ 481 int 482 cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) 483 { 484 int flags, numbufs, i; 485 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS]; 486 u_int32_t lengths[CAM_PERIPH_MAXMAPS]; 487 u_int32_t dirs[CAM_PERIPH_MAXMAPS]; 488 489 switch(ccb->ccb_h.func_code) { 490 case XPT_DEV_MATCH: 491 if (ccb->cdm.pattern_buf_len > MAXPHYS) { 492 printf("cam_periph_mapmem: attempt to map %u bytes, " 493 "which is greater than MAXPHYS(%d)\n", 494 ccb->cdm.pattern_buf_len, MAXPHYS); 495 return(E2BIG); 496 } else if (ccb->cdm.match_buf_len > MAXPHYS) { 497 printf("cam_periph_mapmem: attempt to map %u bytes, " 498 "which is greater than MAXPHYS(%d)\n", 499 ccb->cdm.match_buf_len, MAXPHYS); 500 return(E2BIG); 501 } 502 if (ccb->cdm.match_buf_len == 0) { 503 printf("cam_periph_mapmem: invalid match buffer " 504 "length 0\n"); 505 return(EINVAL); 506 } 507 if (ccb->cdm.pattern_buf_len > 0) { 508 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns; 509 lengths[0] = ccb->cdm.pattern_buf_len; 510 dirs[0] = CAM_DIR_OUT; 511 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches; 512 lengths[1] = ccb->cdm.match_buf_len; 513 dirs[1] = CAM_DIR_IN; 514 numbufs = 2; 515 } else { 516 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches; 517 lengths[0] = ccb->cdm.match_buf_len; 518 dirs[0] = CAM_DIR_IN; 519 numbufs = 1; 520 } 521 break; 522 case XPT_SCSI_IO: 523 if (ccb->csio.dxfer_len > MAXPHYS) { 524 printf("cam_periph_mapmem: attempt to map %u bytes, " 525 "which is greater than MAXPHYS(%d)\n", 526 ccb->csio.dxfer_len, MAXPHYS); 527 return(E2BIG); 528 } 529 530 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) 531 return(0); 532 533 data_ptrs[0] = &ccb->csio.data_ptr; 534 lengths[0] = ccb->csio.dxfer_len;; 535 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; 536 numbufs = 1; 537 break; 538 default: 539 return(EINVAL); 540 break; /* NOTREACHED */ 541 } 542 543 /* this keeps the current process from getting swapped */ 544 /* 545 * XXX KDM should I use P_NOSWAP instead? 546 */ 547 curproc->p_flag |= P_PHYSIO; 548 549 for (i = 0; i < numbufs; i++) { 550 flags = 0; 551 552 if (dirs[i] & CAM_DIR_IN) { 553 flags = B_READ; 554 if (useracc(*data_ptrs[i], lengths[i], B_READ) == 0){ 555 printf("cam_periph_mapmem: error, " 556 "address %#lx, length %d isn't " 557 "user accessible for READ\n", 558 (u_long)(*data_ptrs[i]), lengths[i]); 559 /* 560 * If we've already mapped one or more 561 * buffers for this CCB, unmap it (them). 562 */ 563 if (i > 0) 564 cam_periph_unmapmem(ccb, mapinfo); 565 else 566 curproc->p_flag &= ~P_PHYSIO; 567 568 return(EACCES); 569 } 570 } 571 572 /* 573 * XXX this check is really bogus, since B_WRITE currently 574 * is all 0's, and so it is "set" all the time. 575 */ 576 if (dirs[i] & CAM_DIR_OUT) { 577 flags |= B_WRITE; 578 if (useracc(*data_ptrs[i], lengths[i], B_WRITE) == 0){ 579 printf("cam_periph_mapmem: error, " 580 "address %#lx, length %d isn't " 581 "user accessible for WRITE\n", 582 (u_long)(*data_ptrs[i]), lengths[i]); 583 /* 584 * If we've already mapped one or more 585 * buffers for this CCB, unmap it (them). 586 */ 587 if (i > 0) 588 cam_periph_unmapmem(ccb, mapinfo); 589 else 590 curproc->p_flag &= ~P_PHYSIO; 591 592 return(EACCES); 593 } 594 } 595 596 /* 597 * Get the buffer. 598 */ 599 mapinfo->bp[i] = getpbuf(); 600 601 /* save the buffer's data address */ 602 mapinfo->bp[i]->b_saveaddr = mapinfo->bp[i]->b_data; 603 604 /* put our pointer in the data slot */ 605 mapinfo->bp[i]->b_data = *data_ptrs[i]; 606 607 /* set the transfer length, we know it's < 64K */ 608 mapinfo->bp[i]->b_bufsize = lengths[i]; 609 610 /* set the flags */ 611 mapinfo->bp[i]->b_flags = flags | B_PHYS | B_BUSY; 612 613 /* map the buffer into kernel memory */ 614 vmapbuf(mapinfo->bp[i]); 615 616 /* set our pointer to the new mapped area */ 617 *data_ptrs[i] = mapinfo->bp[i]->b_data; 618 619 mapinfo->num_bufs_used++; 620 } 621 622 return(0); 623 } 624 625 /* 626 * Unmap memory segments mapped into kernel virtual address space by 627 * cam_periph_mapmem(). 628 */ 629 void 630 cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) 631 { 632 int numbufs, i; 633 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS]; 634 635 if (mapinfo->num_bufs_used <= 0) { 636 /* allow ourselves to be swapped once again */ 637 curproc->p_flag &= ~P_PHYSIO; 638 return; 639 } 640 641 switch (ccb->ccb_h.func_code) { 642 case XPT_DEV_MATCH: 643 numbufs = min(mapinfo->num_bufs_used, 2); 644 645 if (numbufs == 1) { 646 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches; 647 } else { 648 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns; 649 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches; 650 } 651 break; 652 case XPT_SCSI_IO: 653 data_ptrs[0] = &ccb->csio.data_ptr; 654 numbufs = min(mapinfo->num_bufs_used, 1); 655 break; 656 default: 657 /* allow ourselves to be swapped once again */ 658 curproc->p_flag &= ~P_PHYSIO; 659 return; 660 break; /* NOTREACHED */ 661 } 662 663 for (i = 0; i < numbufs; i++) { 664 /* Set the user's pointer back to the original value */ 665 *data_ptrs[i] = mapinfo->bp[i]->b_saveaddr; 666 667 /* unmap the buffer */ 668 vunmapbuf(mapinfo->bp[i]); 669 670 /* clear the flags we set above */ 671 mapinfo->bp[i]->b_flags &= ~(B_PHYS|B_BUSY); 672 673 /* release the buffer */ 674 relpbuf(mapinfo->bp[i]); 675 } 676 677 /* allow ourselves to be swapped once again */ 678 curproc->p_flag &= ~P_PHYSIO; 679 } 680 681 union ccb * 682 cam_periph_getccb(struct cam_periph *periph, u_int32_t priority) 683 { 684 struct ccb_hdr *ccb_h; 685 int s; 686 687 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdgetccb\n")); 688 689 s = splsoftcam(); 690 691 while (periph->ccb_list.slh_first == NULL) { 692 if (periph->immediate_priority > priority) 693 periph->immediate_priority = priority; 694 xpt_schedule(periph, priority); 695 if ((periph->ccb_list.slh_first != NULL) 696 && (periph->ccb_list.slh_first->pinfo.priority == priority)) 697 break; 698 tsleep(&periph->ccb_list, PRIBIO, "cgticb", 0); 699 } 700 701 ccb_h = periph->ccb_list.slh_first; 702 SLIST_REMOVE_HEAD(&periph->ccb_list, periph_links.sle); 703 splx(s); 704 return ((union ccb *)ccb_h); 705 } 706 707 void 708 cam_periph_ccbwait(union ccb *ccb) 709 { 710 int s; 711 712 s = splsoftcam(); 713 if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX) 714 || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)) 715 tsleep(&ccb->ccb_h.cbfcnp, PRIBIO, "cbwait", 0); 716 717 splx(s); 718 } 719 720 int 721 cam_periph_ioctl(struct cam_periph *periph, int cmd, caddr_t addr, 722 int (*error_routine)(union ccb *ccb, 723 cam_flags camflags, 724 u_int32_t sense_flags)) 725 { 726 union ccb *ccb; 727 int error; 728 int found; 729 730 error = found = 0; 731 732 switch(cmd){ 733 case CAMGETPASSTHRU: 734 ccb = cam_periph_getccb(periph, /* priority */ 1); 735 xpt_setup_ccb(&ccb->ccb_h, 736 ccb->ccb_h.path, 737 /*priority*/1); 738 ccb->ccb_h.func_code = XPT_GDEVLIST; 739 740 /* 741 * Basically, the point of this is that we go through 742 * getting the list of devices, until we find a passthrough 743 * device. In the current version of the CAM code, the 744 * only way to determine what type of device we're dealing 745 * with is by its name. 746 */ 747 while (found == 0) { 748 ccb->cgdl.index = 0; 749 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS; 750 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) { 751 752 /* we want the next device in the list */ 753 xpt_action(ccb); 754 if (strncmp(ccb->cgdl.periph_name, 755 "pass", 4) == 0){ 756 found = 1; 757 break; 758 } 759 } 760 if ((ccb->cgdl.status == CAM_GDEVLIST_LAST_DEVICE) && 761 (found == 0)) { 762 ccb->cgdl.periph_name[0] = '\0'; 763 ccb->cgdl.unit_number = 0; 764 break; 765 } 766 } 767 768 /* copy the result back out */ 769 bcopy(ccb, addr, sizeof(union ccb)); 770 771 /* and release the ccb */ 772 xpt_release_ccb(ccb); 773 774 break; 775 default: 776 error = ENOTTY; 777 break; 778 } 779 return(error); 780 } 781 782 int 783 cam_periph_runccb(union ccb *ccb, 784 int (*error_routine)(union ccb *ccb, 785 cam_flags camflags, 786 u_int32_t sense_flags), 787 cam_flags camflags, u_int32_t sense_flags, 788 struct devstat *ds) 789 { 790 int error; 791 792 error = 0; 793 794 /* 795 * If the user has supplied a stats structure, and if we understand 796 * this particular type of ccb, record the transaction start. 797 */ 798 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO)) 799 devstat_start_transaction(ds); 800 801 xpt_action(ccb); 802 803 do { 804 cam_periph_ccbwait(ccb); 805 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 806 error = 0; 807 else if (error_routine != NULL) 808 error = (*error_routine)(ccb, camflags, sense_flags); 809 else 810 error = 0; 811 812 } while (error == ERESTART); 813 814 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) 815 cam_release_devq(ccb->ccb_h.path, 816 /* relsim_flags */0, 817 /* openings */0, 818 /* timeout */0, 819 /* getcount_only */ FALSE); 820 821 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO)) 822 devstat_end_transaction(ds, 823 ccb->csio.dxfer_len, 824 ccb->csio.tag_action & 0xf, 825 ((ccb->ccb_h.flags & CAM_DIR_MASK) == 826 CAM_DIR_NONE) ? DEVSTAT_NO_DATA : 827 (ccb->ccb_h.flags & CAM_DIR_OUT) ? 828 DEVSTAT_WRITE : 829 DEVSTAT_READ); 830 831 return(error); 832 } 833 834 u_int32_t 835 cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, 836 u_int32_t openings, u_int32_t timeout, 837 int getcount_only) 838 { 839 struct ccb_relsim crs; 840 841 xpt_setup_ccb(&crs.ccb_h, path, 842 /*priority*/1); 843 crs.ccb_h.func_code = XPT_REL_SIMQ; 844 crs.ccb_h.flags = getcount_only ? CAM_DEV_QFREEZE : 0; 845 crs.release_flags = relsim_flags; 846 crs.openings = openings; 847 crs.release_timeout = timeout; 848 xpt_action((union ccb *)&crs); 849 return (crs.qfrozen_cnt); 850 } 851 852 #define saved_ccb_ptr ppriv_ptr0 853 static void 854 camperiphdone(struct cam_periph *periph, union ccb *done_ccb) 855 { 856 cam_status status; 857 int frozen; 858 int sense; 859 struct scsi_start_stop_unit *scsi_cmd; 860 u_int32_t relsim_flags, timeout; 861 u_int32_t qfrozen_cnt; 862 863 status = done_ccb->ccb_h.status; 864 frozen = (status & CAM_DEV_QFRZN) != 0; 865 sense = (status & CAM_AUTOSNS_VALID) != 0; 866 status &= CAM_STATUS_MASK; 867 868 timeout = 0; 869 relsim_flags = 0; 870 871 /* 872 * Unfreeze the queue once if it is already frozen.. 873 */ 874 if (frozen != 0) { 875 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path, 876 /*relsim_flags*/0, 877 /*openings*/0, 878 /*timeout*/0, 879 /*getcount_only*/0); 880 } 881 882 switch (status) { 883 884 case CAM_REQ_CMP: 885 886 /* 887 * If we have successfully taken a device from the not 888 * ready to ready state, re-scan the device and re-get the 889 * inquiry information. Many devices (mostly disks) don't 890 * properly report their inquiry information unless they 891 * are spun up. 892 */ 893 if (done_ccb->ccb_h.func_code == XPT_SCSI_IO) { 894 scsi_cmd = (struct scsi_start_stop_unit *) 895 &done_ccb->csio.cdb_io.cdb_bytes; 896 897 if (scsi_cmd->opcode == START_STOP_UNIT) 898 xpt_async(AC_INQ_CHANGED, 899 done_ccb->ccb_h.path, NULL); 900 } 901 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb, 902 sizeof(union ccb)); 903 904 xpt_action(done_ccb); 905 906 break; 907 case CAM_SCSI_STATUS_ERROR: 908 scsi_cmd = (struct scsi_start_stop_unit *) 909 &done_ccb->csio.cdb_io.cdb_bytes; 910 if (sense != 0) { 911 struct scsi_sense_data *sense; 912 int error_code, sense_key, asc, ascq; 913 914 sense = &done_ccb->csio.sense_data; 915 scsi_extract_sense(sense, &error_code, 916 &sense_key, &asc, &ascq); 917 918 /* 919 * If the error is "invalid field in CDB", 920 * and the load/eject flag is set, turn the 921 * flag off and try again. This is just in 922 * case the drive in question barfs on the 923 * load eject flag. The CAM code should set 924 * the load/eject flag by default for 925 * removable media. 926 */ 927 928 /* XXX KDM 929 * Should we check to see what the specific 930 * scsi status is?? Or does it not matter 931 * since we already know that there was an 932 * error, and we know what the specific 933 * error code was, and we know what the 934 * opcode is.. 935 */ 936 if ((scsi_cmd->opcode == START_STOP_UNIT) && 937 ((scsi_cmd->how & SSS_LOEJ) != 0) && 938 (asc == 0x24) && (ascq == 0x00) && 939 (done_ccb->ccb_h.retry_count > 0)) { 940 941 scsi_cmd->how &= ~SSS_LOEJ; 942 943 xpt_action(done_ccb); 944 945 } else if (done_ccb->ccb_h.retry_count > 0) { 946 /* 947 * In this case, the error recovery 948 * command failed, but we've got 949 * some retries left on it. Give 950 * it another try. 951 */ 952 953 /* set the timeout to .5 sec */ 954 relsim_flags = 955 RELSIM_RELEASE_AFTER_TIMEOUT; 956 timeout = 500; 957 958 xpt_action(done_ccb); 959 960 break; 961 962 } else { 963 /* 964 * Copy the original CCB back and 965 * send it back to the caller. 966 */ 967 bcopy(done_ccb->ccb_h.saved_ccb_ptr, 968 done_ccb, sizeof(union ccb)); 969 970 xpt_action(done_ccb); 971 } 972 } else { 973 /* 974 * Eh?? The command failed, but we don't 975 * have any sense. What's up with that? 976 * Fire the CCB again to return it to the 977 * caller. 978 */ 979 bcopy(done_ccb->ccb_h.saved_ccb_ptr, 980 done_ccb, sizeof(union ccb)); 981 982 xpt_action(done_ccb); 983 984 } 985 break; 986 default: 987 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb, 988 sizeof(union ccb)); 989 990 xpt_action(done_ccb); 991 992 break; 993 } 994 995 /* decrement the retry count */ 996 if (done_ccb->ccb_h.retry_count > 0) 997 done_ccb->ccb_h.retry_count--; 998 999 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path, 1000 /*relsim_flags*/relsim_flags, 1001 /*openings*/0, 1002 /*timeout*/timeout, 1003 /*getcount_only*/0); 1004 } 1005 1006 /* 1007 * Generic error handler. Peripheral drivers usually filter 1008 * out the errors that they handle in a unique mannor, then 1009 * call this function. 1010 */ 1011 int 1012 cam_periph_error(union ccb *ccb, cam_flags camflags, 1013 u_int32_t sense_flags, union ccb *save_ccb) 1014 { 1015 cam_status status; 1016 int frozen; 1017 int sense; 1018 int error; 1019 int openings; 1020 int retry; 1021 u_int32_t relsim_flags; 1022 u_int32_t timeout; 1023 1024 status = ccb->ccb_h.status; 1025 frozen = (status & CAM_DEV_QFRZN) != 0; 1026 sense = (status & CAM_AUTOSNS_VALID) != 0; 1027 status &= CAM_STATUS_MASK; 1028 relsim_flags = 0; 1029 1030 1031 switch (status) { 1032 case CAM_REQ_CMP: 1033 /* decrement the number of retries */ 1034 retry = ccb->ccb_h.retry_count > 0; 1035 if (retry) 1036 ccb->ccb_h.retry_count--; 1037 error = 0; 1038 break; 1039 case CAM_SCSI_STATUS_ERROR: 1040 1041 switch (ccb->csio.scsi_status) { 1042 case SCSI_STATUS_OK: 1043 case SCSI_STATUS_COND_MET: 1044 case SCSI_STATUS_INTERMED: 1045 case SCSI_STATUS_INTERMED_COND_MET: 1046 error = 0; 1047 break; 1048 case SCSI_STATUS_CMD_TERMINATED: 1049 case SCSI_STATUS_CHECK_COND: 1050 if (sense != 0) { 1051 struct scsi_sense_data *sense; 1052 int error_code, sense_key, asc, ascq; 1053 struct cam_periph *periph; 1054 scsi_sense_action err_action; 1055 struct ccb_getdev cgd; 1056 1057 sense = &ccb->csio.sense_data; 1058 scsi_extract_sense(sense, &error_code, 1059 &sense_key, &asc, &ascq); 1060 periph = xpt_path_periph(ccb->ccb_h.path); 1061 1062 /* 1063 * Grab the inquiry data for this device. 1064 */ 1065 xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path, 1066 /*priority*/ 1); 1067 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 1068 xpt_action((union ccb *)&cgd); 1069 1070 err_action = scsi_error_action(asc, ascq, 1071 &cgd.inq_data); 1072 1073 /* 1074 * Send a Test Unit Ready to the device. 1075 * If the 'many' flag is set, we send 120 1076 * test unit ready commands, one every half 1077 * second. Otherwise, we just send one TUR. 1078 * We only want to do this if the retry 1079 * count has not been exhausted. 1080 */ 1081 if (((err_action & SS_MASK) == SS_TUR) 1082 && save_ccb != NULL 1083 && ccb->ccb_h.retry_count > 0) { 1084 1085 /* decrement the number of retries */ 1086 if ((err_action & 1087 SSQ_DECREMENT_COUNT) != 0) { 1088 retry = 1; 1089 ccb->ccb_h.retry_count--; 1090 } 1091 1092 bcopy(ccb, save_ccb, sizeof(*save_ccb)); 1093 1094 /* 1095 * We retry this one every half 1096 * second for a minute. If the 1097 * device hasn't become ready in a 1098 * minute's time, it's unlikely to 1099 * ever become ready. If the table 1100 * doesn't specify SSQ_MANY, we can 1101 * only try this once. Oh well. 1102 */ 1103 if ((err_action & SSQ_MANY) != 0) 1104 scsi_test_unit_ready(&ccb->csio, 1105 /*retries*/120, 1106 camperiphdone, 1107 MSG_SIMPLE_Q_TAG, 1108 SSD_FULL_SIZE, 1109 /*timeout*/5000); 1110 else 1111 scsi_test_unit_ready(&ccb->csio, 1112 /*retries*/1, 1113 camperiphdone, 1114 MSG_SIMPLE_Q_TAG, 1115 SSD_FULL_SIZE, 1116 /*timeout*/5000); 1117 1118 /* release the queue after .5 sec. */ 1119 relsim_flags = 1120 RELSIM_RELEASE_AFTER_TIMEOUT; 1121 timeout = 500; 1122 /* 1123 * Drop the priority to 0 so that 1124 * we are the first to execute. Also 1125 * freeze the queue after this command 1126 * is sent so that we can restore the 1127 * old csio and have it queued in the 1128 * proper order before we let normal 1129 * transactions go to the drive. 1130 */ 1131 ccb->ccb_h.pinfo.priority = 0; 1132 ccb->ccb_h.flags |= CAM_DEV_QFREEZE; 1133 1134 /* 1135 * Save a pointer to the original 1136 * CCB in the new CCB. 1137 */ 1138 ccb->ccb_h.saved_ccb_ptr = save_ccb; 1139 1140 error = ERESTART; 1141 } 1142 /* 1143 * Send a start unit command to the device, 1144 * and then retry the command. We only 1145 * want to do this if the retry count has 1146 * not been exhausted. If the user 1147 * specified 0 retries, then we follow 1148 * their request and do not retry. 1149 */ 1150 else if (((err_action & SS_MASK) == SS_START) 1151 && save_ccb != NULL 1152 && ccb->ccb_h.retry_count > 0) { 1153 int le; 1154 1155 /* decrement the number of retries */ 1156 retry = 1; 1157 ccb->ccb_h.retry_count--; 1158 1159 /* 1160 * Check for removable media and 1161 * set load/eject flag 1162 * appropriately. 1163 */ 1164 if (SID_IS_REMOVABLE(&cgd.inq_data)) 1165 le = TRUE; 1166 else 1167 le = FALSE; 1168 1169 /* 1170 * Attempt to start the drive up. 1171 * 1172 * Save the current ccb so it can 1173 * be restored and retried once the 1174 * drive is started up. 1175 */ 1176 bcopy(ccb, save_ccb, sizeof(*save_ccb)); 1177 1178 scsi_start_stop(&ccb->csio, 1179 /*retries*/1, 1180 camperiphdone, 1181 MSG_SIMPLE_Q_TAG, 1182 /*start*/TRUE, 1183 /*load/eject*/le, 1184 /*immediate*/FALSE, 1185 SSD_FULL_SIZE, 1186 /*timeout*/50000); 1187 /* 1188 * Drop the priority to 0 so that 1189 * we are the first to execute. Also 1190 * freeze the queue after this command 1191 * is sent so that we can restore the 1192 * old csio and have it queued in the 1193 * proper order before we let normal 1194 * transactions go to the drive. 1195 */ 1196 ccb->ccb_h.pinfo.priority = 0; 1197 ccb->ccb_h.flags |= CAM_DEV_QFREEZE; 1198 1199 /* 1200 * Save a pointer to the original 1201 * CCB in the new CCB. 1202 */ 1203 ccb->ccb_h.saved_ccb_ptr = save_ccb; 1204 1205 error = ERESTART; 1206 } else if ((sense_flags & SF_RETRY_UA) != 0) { 1207 /* 1208 * XXX KDM this is a *horrible* 1209 * hack. 1210 */ 1211 error = scsi_interpret_sense(ccb, 1212 sense_flags, 1213 &relsim_flags, 1214 &openings, 1215 &timeout, 1216 err_action); 1217 } 1218 1219 /* 1220 * Theoretically, this code should send a 1221 * test unit ready to the given device, and 1222 * if it returns and error, send a start 1223 * unit command. Since we don't yet have 1224 * the capability to do two-command error 1225 * recovery, just send a start unit. 1226 * XXX KDM fix this! 1227 */ 1228 else if (((err_action & SS_MASK) == SS_TURSTART) 1229 && save_ccb != NULL 1230 && ccb->ccb_h.retry_count > 0) { 1231 int le; 1232 1233 /* decrement the number of retries */ 1234 retry = 1; 1235 ccb->ccb_h.retry_count--; 1236 1237 /* 1238 * Check for removable media and 1239 * set load/eject flag 1240 * appropriately. 1241 */ 1242 if (SID_IS_REMOVABLE(&cgd.inq_data)) 1243 le = TRUE; 1244 else 1245 le = FALSE; 1246 1247 /* 1248 * Attempt to start the drive up. 1249 * 1250 * Save the current ccb so it can 1251 * be restored and retried once the 1252 * drive is started up. 1253 */ 1254 bcopy(ccb, save_ccb, sizeof(*save_ccb)); 1255 1256 scsi_start_stop(&ccb->csio, 1257 /*retries*/1, 1258 camperiphdone, 1259 MSG_SIMPLE_Q_TAG, 1260 /*start*/TRUE, 1261 /*load/eject*/le, 1262 /*immediate*/FALSE, 1263 SSD_FULL_SIZE, 1264 /*timeout*/50000); 1265 1266 /* release the queue after .5 sec. */ 1267 relsim_flags = 1268 RELSIM_RELEASE_AFTER_TIMEOUT; 1269 timeout = 500; 1270 /* 1271 * Drop the priority to 0 so that 1272 * we are the first to execute. Also 1273 * freeze the queue after this command 1274 * is sent so that we can restore the 1275 * old csio and have it queued in the 1276 * proper order before we let normal 1277 * transactions go to the drive. 1278 */ 1279 ccb->ccb_h.pinfo.priority = 0; 1280 ccb->ccb_h.flags |= CAM_DEV_QFREEZE; 1281 1282 /* 1283 * Save a pointer to the original 1284 * CCB in the new CCB. 1285 */ 1286 ccb->ccb_h.saved_ccb_ptr = save_ccb; 1287 1288 error = ERESTART; 1289 } else { 1290 error = scsi_interpret_sense(ccb, 1291 sense_flags, 1292 &relsim_flags, 1293 &openings, 1294 &timeout, 1295 err_action); 1296 } 1297 } else if (ccb->csio.scsi_status == 1298 SCSI_STATUS_CHECK_COND) { 1299 /* no point in decrementing the retry count */ 1300 panic("cam_periph_error: scsi status of " 1301 "CHECK COND returned but no sense " 1302 "information is availible. " 1303 "Controller should have returned " 1304 "CAM_AUTOSENSE_FAILED"); 1305 /* NOTREACHED */ 1306 error = EIO; 1307 } else if (ccb->ccb_h.retry_count > 0) { 1308 /* 1309 * XXX KDM shouldn't there be a better 1310 * argument to return?? 1311 */ 1312 error = EIO; 1313 } else { 1314 /* decrement the number of retries */ 1315 retry = ccb->ccb_h.retry_count > 0; 1316 if (retry) 1317 ccb->ccb_h.retry_count--; 1318 /* 1319 * If it was aborted with no 1320 * clue as to the reason, just 1321 * retry it again. 1322 */ 1323 error = ERESTART; 1324 } 1325 break; 1326 case SCSI_STATUS_QUEUE_FULL: 1327 { 1328 /* no decrement */ 1329 struct ccb_getdev cgd; 1330 1331 /* 1332 * First off, find out what the current 1333 * transaction counts are. 1334 */ 1335 xpt_setup_ccb(&cgd.ccb_h, 1336 ccb->ccb_h.path, 1337 /*priority*/1); 1338 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 1339 xpt_action((union ccb *)&cgd); 1340 1341 /* 1342 * If we were the only transaction active, treat 1343 * the QUEUE FULL as if it were a BUSY condition. 1344 */ 1345 if (cgd.dev_active != 0) { 1346 /* 1347 * Reduce the number of openings to 1348 * be 1 less than the amount it took 1349 * to get a queue full bounded by the 1350 * minimum allowed tag count for this 1351 * device. 1352 */ 1353 openings = cgd.dev_active; 1354 if (openings < cgd.mintags) 1355 openings = cgd.mintags; 1356 if (openings < cgd.dev_active+cgd.dev_openings) 1357 relsim_flags = RELSIM_ADJUST_OPENINGS; 1358 else { 1359 /* 1360 * Some devices report queue full for 1361 * temporary resource shortages. For 1362 * this reason, we allow a minimum 1363 * tag count to be entered via a 1364 * quirk entry to prevent the queue 1365 * count on these devices from falling 1366 * to a pessimisticly low value. We 1367 * still wait for the next successful 1368 * completion, however, before queueing 1369 * more transactions to the device. 1370 */ 1371 relsim_flags = 1372 RELSIM_RELEASE_AFTER_CMDCMPLT; 1373 } 1374 timeout = 0; 1375 error = ERESTART; 1376 break; 1377 } 1378 /* FALLTHROUGH */ 1379 } 1380 case SCSI_STATUS_BUSY: 1381 /* 1382 * Restart the queue after either another 1383 * command completes or a 1 second timeout. 1384 */ 1385 /* 1386 * XXX KDM ask JTG about this again, do we need to 1387 * be looking at the retry count here? 1388 */ 1389 error = ERESTART; 1390 relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT 1391 | RELSIM_RELEASE_AFTER_CMDCMPLT; 1392 timeout = 1000; 1393 break; 1394 case SCSI_STATUS_RESERV_CONFLICT: 1395 error = EIO; 1396 break; 1397 default: 1398 error = EIO; 1399 break; 1400 } 1401 break; 1402 case CAM_REQ_CMP_ERR: 1403 case CAM_AUTOSENSE_FAIL: 1404 case CAM_CMD_TIMEOUT: 1405 case CAM_UNEXP_BUSFREE: 1406 case CAM_UNCOR_PARITY: 1407 case CAM_DATA_RUN_ERR: 1408 /* decrement the number of retries */ 1409 retry = ccb->ccb_h.retry_count > 0; 1410 if (retry) { 1411 ccb->ccb_h.retry_count--; 1412 error = ERESTART; 1413 } else { 1414 error = EIO; 1415 } 1416 break; 1417 case CAM_UA_ABORT: 1418 case CAM_UA_TERMIO: 1419 case CAM_MSG_REJECT_REC: 1420 /* XXX Don't know that these are correct */ 1421 error = EIO; 1422 break; 1423 case CAM_SEL_TIMEOUT: 1424 { 1425 struct cam_path *newpath; 1426 1427 error = ENXIO; 1428 1429 /* Should we do more if we can't create the path?? */ 1430 if (xpt_create_path(&newpath, xpt_path_periph(ccb->ccb_h.path), 1431 xpt_path_path_id(ccb->ccb_h.path), 1432 xpt_path_target_id(ccb->ccb_h.path), 1433 CAM_LUN_WILDCARD) != CAM_REQ_CMP) 1434 break; 1435 /* 1436 * Let peripheral drivers know that this device has gone 1437 * away. 1438 */ 1439 xpt_async(AC_LOST_DEVICE, newpath, NULL); 1440 xpt_free_path(newpath); 1441 1442 break; 1443 } 1444 case CAM_REQ_INVALID: 1445 case CAM_PATH_INVALID: 1446 case CAM_DEV_NOT_THERE: 1447 case CAM_NO_HBA: 1448 case CAM_PROVIDE_FAIL: 1449 case CAM_REQ_TOO_BIG: 1450 error = EINVAL; 1451 break; 1452 case CAM_SCSI_BUS_RESET: 1453 case CAM_BDR_SENT: 1454 case CAM_REQUEUE_REQ: 1455 /* Unconditional requeue, dammit */ 1456 error = ERESTART; 1457 break; 1458 case CAM_RESRC_UNAVAIL: 1459 case CAM_BUSY: 1460 /* timeout??? */ 1461 default: 1462 /* decrement the number of retries */ 1463 retry = ccb->ccb_h.retry_count > 0; 1464 if (retry) { 1465 ccb->ccb_h.retry_count--; 1466 error = ERESTART; 1467 } else { 1468 /* Check the sense codes */ 1469 error = EIO; 1470 } 1471 break; 1472 } 1473 1474 /* Attempt a retry */ 1475 if (error == ERESTART || error == 0) { 1476 if (frozen != 0) 1477 ccb->ccb_h.status &= ~CAM_DEV_QFRZN; 1478 1479 if (error == ERESTART) 1480 xpt_action(ccb); 1481 1482 if (frozen != 0) { 1483 cam_release_devq(ccb->ccb_h.path, 1484 relsim_flags, 1485 openings, 1486 timeout, 1487 /*getcount_only*/0); 1488 } 1489 } 1490 1491 1492 return (error); 1493 } 1494