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