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