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