1 /* $NetBSD: scsi_base.c,v 1.28 1995/01/26 12:05:51 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995 Charles Hannum. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Charles Hannum. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Originally written by Julian Elischer (julian@dialix.oz.au) 34 */ 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/kernel.h> 39 #include <sys/buf.h> 40 #include <sys/uio.h> 41 #include <sys/malloc.h> 42 #include <sys/errno.h> 43 #include <sys/device.h> 44 45 #include <scsi/scsi_all.h> 46 #include <scsi/scsi_disk.h> 47 #include <scsi/scsiconf.h> 48 49 #ifdef DDB 50 int Debugger(); 51 #else /* DDB */ 52 #define Debugger() 53 #endif /* DDB */ 54 55 void scsi_error __P((struct scsi_xfer *, int)); 56 57 LIST_HEAD(xs_free_list, scsi_xfer) xs_free_list; 58 59 /* 60 * Get a scsi transfer structure for the caller. Charge the structure 61 * to the device that is referenced by the sc_link structure. If the 62 * sc_link structure has no 'credits' then the device already has the 63 * maximum number or outstanding operations under way. In this stage, 64 * wait on the structure so that when one is freed, we are awoken again 65 * If the SCSI_NOSLEEP flag is set, then do not wait, but rather, return 66 * a NULL pointer, signifying that no slots were available 67 * Note in the link structure, that we are waiting on it. 68 */ 69 70 struct scsi_xfer * 71 scsi_get_xs(sc_link, flags) 72 struct scsi_link *sc_link; /* who to charge the xs to */ 73 int flags; /* if this call can sleep */ 74 { 75 struct scsi_xfer *xs; 76 int s; 77 78 SC_DEBUG(sc_link, SDEV_DB3, ("scsi_get_xs\n")); 79 s = splbio(); 80 while (sc_link->openings <= 0) { 81 SC_DEBUG(sc_link, SDEV_DB3, ("sleeping\n")); 82 if ((flags & SCSI_NOSLEEP) != 0) { 83 splx(s); 84 return 0; 85 } 86 sc_link->flags |= SDEV_WAITING; 87 (void) tsleep(sc_link, PRIBIO, "getxs", 0); 88 } 89 sc_link->openings--; 90 if (xs = xs_free_list.lh_first) { 91 LIST_REMOVE(xs, free_list); 92 splx(s); 93 } else { 94 splx(s); 95 SC_DEBUG(sc_link, SDEV_DB3, ("making\n")); 96 xs = malloc(sizeof(*xs), M_DEVBUF, 97 ((flags & SCSI_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK)); 98 if (!xs) { 99 sc_print_addr(sc_link); 100 printf("cannot allocate scsi xs\n"); 101 return 0; 102 } 103 } 104 105 SC_DEBUG(sc_link, SDEV_DB3, ("returning\n")); 106 xs->flags = INUSE | flags; 107 return xs; 108 } 109 110 /* 111 * Given a scsi_xfer struct, and a device (referenced through sc_link) 112 * return the struct to the free pool and credit the device with it 113 * If another process is waiting for an xs, do a wakeup, let it proceed 114 */ 115 void 116 scsi_free_xs(xs, flags) 117 struct scsi_xfer *xs; 118 int flags; 119 { 120 struct scsi_link *sc_link = xs->sc_link; 121 122 xs->flags &= ~INUSE; 123 LIST_INSERT_HEAD(&xs_free_list, xs, free_list); 124 125 SC_DEBUG(sc_link, SDEV_DB3, ("scsi_free_xs\n")); 126 /* if was 0 and someone waits, wake them up */ 127 sc_link->openings++; 128 if ((sc_link->flags & SDEV_WAITING) != 0) { 129 sc_link->flags &= ~SDEV_WAITING; 130 wakeup(sc_link); 131 } else { 132 if (sc_link->device->start) { 133 SC_DEBUG(sc_link, SDEV_DB2, ("calling private start()\n")); 134 (*(sc_link->device->start)) (sc_link->device_softc); 135 } 136 } 137 } 138 139 /* 140 * Make a scsi_xfer, and return a pointer to it. 141 */ 142 static __inline struct scsi_xfer * 143 scsi_make_xs(sc_link, scsi_cmd, cmdlen, data_addr, datalen, 144 retries, timeout, bp, flags) 145 struct scsi_link *sc_link; 146 struct scsi_generic *scsi_cmd; 147 int cmdlen; 148 u_char *data_addr; 149 int datalen; 150 int retries; 151 int timeout; 152 struct buf *bp; 153 int flags; 154 { 155 struct scsi_xfer *xs; 156 157 if ((xs = scsi_get_xs(sc_link, flags)) == NULL) 158 return NULL; 159 160 /* 161 * Fill out the scsi_xfer structure. We don't know whose context 162 * the cmd is in, so copy it. 163 */ 164 xs->sc_link = sc_link; 165 bcopy(scsi_cmd, &xs->cmdstore, cmdlen); 166 xs->cmd = &xs->cmdstore; 167 xs->cmdlen = cmdlen; 168 xs->data = data_addr; 169 xs->datalen = datalen; 170 xs->retries = retries; 171 xs->timeout = timeout; 172 xs->bp = bp; 173 174 return xs; 175 } 176 177 /* 178 * Find out from the device what its capacity is. 179 */ 180 u_long 181 scsi_size(sc_link, flags) 182 struct scsi_link *sc_link; 183 int flags; 184 { 185 struct scsi_read_cap_data rdcap; 186 struct scsi_read_capacity scsi_cmd; 187 u_long size; 188 189 /* 190 * make up a scsi command and ask the scsi driver to do 191 * it for you. 192 */ 193 bzero(&scsi_cmd, sizeof(scsi_cmd)); 194 scsi_cmd.opcode = READ_CAPACITY; 195 196 /* 197 * If the command works, interpret the result as a 4 byte 198 * number of blocks 199 */ 200 if (scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd, 201 sizeof(scsi_cmd), (u_char *)&rdcap, sizeof(rdcap), 202 2, 20000, NULL, flags | SCSI_DATA_IN) != 0) { 203 sc_print_addr(sc_link); 204 printf("could not get size\n"); 205 return 0; 206 } else { 207 size = rdcap.addr_0 + 1; 208 size += rdcap.addr_1 << 8; 209 size += rdcap.addr_2 << 16; 210 size += rdcap.addr_3 << 24; 211 } 212 return size; 213 } 214 215 /* 216 * Get scsi driver to send a "are you ready?" command 217 */ 218 int 219 scsi_test_unit_ready(sc_link, flags) 220 struct scsi_link *sc_link; 221 int flags; 222 { 223 struct scsi_test_unit_ready scsi_cmd; 224 225 bzero(&scsi_cmd, sizeof(scsi_cmd)); 226 scsi_cmd.opcode = TEST_UNIT_READY; 227 228 return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, 229 sizeof(scsi_cmd), 0, 0, 2, 10000, NULL, flags); 230 } 231 232 /* 233 * Do a scsi operation, asking a device to run as SCSI-II if it can. 234 */ 235 int 236 scsi_change_def(sc_link, flags) 237 struct scsi_link *sc_link; 238 int flags; 239 { 240 struct scsi_changedef scsi_cmd; 241 242 bzero(&scsi_cmd, sizeof(scsi_cmd)); 243 scsi_cmd.opcode = CHANGE_DEFINITION; 244 scsi_cmd.how = SC_SCSI_2; 245 246 return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, 247 sizeof(scsi_cmd), 0, 0, 2, 100000, NULL, flags); 248 } 249 250 /* 251 * Do a scsi operation asking a device what it is 252 * Use the scsi_cmd routine in the switch table. 253 */ 254 int 255 scsi_inquire(sc_link, inqbuf, flags) 256 struct scsi_link *sc_link; 257 struct scsi_inquiry_data *inqbuf; 258 int flags; 259 { 260 struct scsi_inquiry scsi_cmd; 261 262 bzero(&scsi_cmd, sizeof(scsi_cmd)); 263 scsi_cmd.opcode = INQUIRY; 264 scsi_cmd.length = sizeof(struct scsi_inquiry_data); 265 266 return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, 267 sizeof(scsi_cmd), (u_char *) inqbuf, 268 sizeof(struct scsi_inquiry_data), 2, 10000, NULL, 269 SCSI_DATA_IN | flags); 270 } 271 272 /* 273 * Prevent or allow the user to remove the media 274 */ 275 int 276 scsi_prevent(sc_link, type, flags) 277 struct scsi_link *sc_link; 278 int type, flags; 279 { 280 struct scsi_prevent scsi_cmd; 281 282 bzero(&scsi_cmd, sizeof(scsi_cmd)); 283 scsi_cmd.opcode = PREVENT_ALLOW; 284 scsi_cmd.how = type; 285 return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, 286 sizeof(scsi_cmd), 0, 0, 2, 5000, NULL, flags); 287 } 288 289 /* 290 * Get scsi driver to send a "start up" command 291 */ 292 int 293 scsi_start(sc_link, type, flags) 294 struct scsi_link *sc_link; 295 int type, flags; 296 { 297 struct scsi_start_stop scsi_cmd; 298 299 bzero(&scsi_cmd, sizeof(scsi_cmd)); 300 scsi_cmd.opcode = START_STOP; 301 scsi_cmd.byte2 = 0x00; 302 scsi_cmd.how = type; 303 return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd, 304 sizeof(scsi_cmd), 0, 0, 2, 305 type == SSS_START ? 30000 : 10000, NULL, flags); 306 } 307 308 /* 309 * This routine is called by the scsi interrupt when the transfer is complete. 310 */ 311 void 312 scsi_done(xs) 313 struct scsi_xfer *xs; 314 { 315 struct scsi_link *sc_link = xs->sc_link; 316 int error; 317 318 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_done\n")); 319 #ifdef SCSIDEBUG 320 if ((sc_link->flags & SDEV_DB1) != 0) 321 show_scsi_cmd(xs); 322 #endif /* SCSIDEBUG */ 323 324 /* 325 * If it's a user level request, bypass all usual completion processing, 326 * let the user work it out.. We take reponsibility for freeing the 327 * xs when the user returns. (and restarting the device's queue). 328 */ 329 if ((xs->flags & SCSI_USER) != 0) { 330 SC_DEBUG(sc_link, SDEV_DB3, ("calling user done()\n")); 331 scsi_user_done(xs); /* to take a copy of the sense etc. */ 332 SC_DEBUG(sc_link, SDEV_DB3, ("returned from user done()\n ")); 333 334 scsi_free_xs(xs, SCSI_NOSLEEP); /* restarts queue too */ 335 SC_DEBUG(sc_link, SDEV_DB3, ("returning to adapter\n")); 336 return; 337 } 338 339 /* 340 * If the device has it's own done routine, call it first. 341 * If it returns a legit error value, return that, otherwise 342 * it wants us to continue with normal processing. 343 */ 344 if (sc_link->device->done) { 345 SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n")); 346 error = (*sc_link->device->done) (xs); 347 if (error == EJUSTRETURN) 348 goto done; 349 SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n")); 350 } 351 if (xs->bp == NULL) { 352 /* 353 * if it's a normal upper level request, then ask 354 * the upper level code to handle error checking 355 * rather than doing it here at interrupt time 356 */ 357 wakeup(xs); 358 return; 359 } 360 /* 361 * Go and handle errors now. 362 * If it returns ERESTART then we should RETRY 363 */ 364 retry: 365 if (sc_err1(xs, 1) == ERESTART) { 366 switch ((*(sc_link->adapter->scsi_cmd)) (xs)) { 367 case SUCCESSFULLY_QUEUED: 368 return; 369 370 case TRY_AGAIN_LATER: 371 xs->error = XS_BUSY; 372 case COMPLETE: 373 goto retry; 374 } 375 } 376 done: 377 scsi_free_xs(xs, SCSI_NOSLEEP); 378 } 379 380 int 381 scsi_execute_xs(xs) 382 struct scsi_xfer *xs; 383 { 384 int error; 385 int s; 386 387 xs->flags &= ~ITSDONE; 388 xs->error = XS_NOERROR; 389 xs->resid = xs->datalen; 390 391 retry: 392 /* 393 * Do the transfer. If we are polling we will return: 394 * COMPLETE, Was poll, and scsi_done has been called 395 * TRY_AGAIN_LATER, Adapter short resources, try again 396 * 397 * if under full steam (interrupts) it will return: 398 * SUCCESSFULLY_QUEUED, will do a wakeup when complete 399 * TRY_AGAIN_LATER, (as for polling) 400 * After the wakeup, we must still check if it succeeded 401 * 402 * If we have a bp however, all the error proccessing 403 * and the buffer code both expect us to return straight 404 * to them, so as soon as the command is queued, return 405 */ 406 switch ((*(xs->sc_link->adapter->scsi_cmd)) (xs)) { 407 case SUCCESSFULLY_QUEUED: 408 if (xs->bp) 409 return EJUSTRETURN; 410 s = splbio(); 411 while ((xs->flags & ITSDONE) == 0) 412 tsleep(xs, PRIBIO + 1, "scsi_scsi_cmd", 0); 413 splx(s); 414 case COMPLETE: /* Polling command completed ok */ 415 if (xs->bp) 416 return EJUSTRETURN; 417 doit: 418 SC_DEBUG(xs->sc_link, SDEV_DB3, ("back in cmd()\n")); 419 if ((error = sc_err1(xs, 0)) != ERESTART) 420 return error; 421 goto retry; 422 423 case TRY_AGAIN_LATER: /* adapter resource shortage */ 424 xs->error = XS_BUSY; 425 goto doit; 426 427 default: 428 panic("scsi_execute_xs: invalid return code"); 429 } 430 431 #ifdef DIAGNOSTIC 432 panic("scsi_execute_xs: impossible"); 433 #endif 434 } 435 436 /* 437 * ask the scsi driver to perform a command for us. 438 * tell it where to read/write the data, and how 439 * long the data is supposed to be. If we have a buf 440 * to associate with the transfer, we need that too. 441 */ 442 int 443 scsi_scsi_cmd(sc_link, scsi_cmd, cmdlen, data_addr, datalen, 444 retries, timeout, bp, flags) 445 struct scsi_link *sc_link; 446 struct scsi_generic *scsi_cmd; 447 int cmdlen; 448 u_char *data_addr; 449 int datalen; 450 int retries; 451 int timeout; 452 struct buf *bp; 453 int flags; 454 { 455 struct scsi_xfer *xs; 456 int error; 457 458 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_cmd\n")); 459 460 #ifdef DIAGNOSTIC 461 if (bp != 0 && (flags & SCSI_NOSLEEP) == 0) 462 panic("scsi_scsi_cmd: buffer without nosleep"); 463 #endif 464 465 if ((xs = scsi_make_xs(sc_link, scsi_cmd, cmdlen, data_addr, datalen, 466 retries, timeout, bp, flags)) == NULL) 467 return ENOMEM; 468 469 if ((error = scsi_execute_xs(xs)) == EJUSTRETURN) 470 return 0; 471 472 /* 473 * we have finished with the xfer stuct, free it and 474 * check if anyone else needs to be started up. 475 */ 476 scsi_free_xs(xs, flags); 477 return error; 478 } 479 480 int 481 sc_err1(xs, async) 482 struct scsi_xfer *xs; 483 int async; 484 { 485 int error; 486 487 SC_DEBUG(xs->sc_link, SDEV_DB3, ("sc_err1,err = 0x%x \n", xs->error)); 488 489 /* 490 * If it has a buf, we might be working with 491 * a request from the buffer cache or some other 492 * piece of code that requires us to process 493 * errors at inetrrupt time. We have probably 494 * been called by scsi_done() 495 */ 496 switch (xs->error) { 497 case XS_NOERROR: /* nearly always hit this one */ 498 error = 0; 499 break; 500 501 case XS_SENSE: 502 if ((error = scsi_interpret_sense(xs)) == ERESTART) 503 goto retry; 504 SC_DEBUG(xs->sc_link, SDEV_DB3, 505 ("scsi_interpret_sense returned %d\n", error)); 506 break; 507 508 case XS_BUSY: 509 if (xs->retries) { 510 if ((xs->flags & SCSI_POLL) != 0) 511 delay(1000000); 512 else if ((xs->flags & SCSI_NOSLEEP) == 0) 513 tsleep(&lbolt, PRIBIO, "scbusy", 0); 514 else 515 #if 0 516 timeout(scsi_requeue, xs, hz); 517 #else 518 goto lose; 519 #endif 520 } 521 case XS_TIMEOUT: 522 retry: 523 if (xs->retries--) { 524 xs->error = XS_NOERROR; 525 xs->flags &= ~ITSDONE; 526 return ERESTART; 527 } 528 case XS_DRIVER_STUFFUP: 529 lose: 530 error = EIO; 531 break; 532 533 case XS_SELTIMEOUT: 534 /* XXX Disable device? */ 535 error = EIO; 536 break; 537 538 default: 539 sc_print_addr(xs->sc_link); 540 printf("unknown error category from scsi driver\n"); 541 error = EIO; 542 break; 543 } 544 545 scsi_error(xs, error); 546 return error; 547 } 548 549 void 550 scsi_error(xs, error) 551 struct scsi_xfer *xs; 552 int error; 553 { 554 struct buf *bp = xs->bp; 555 556 if (bp) { 557 if (error) { 558 bp->b_error = error; 559 bp->b_flags |= B_ERROR; 560 bp->b_resid = bp->b_bcount; 561 } else { 562 bp->b_error = 0; 563 bp->b_resid = xs->resid; 564 } 565 biodone(bp); 566 } 567 } 568 569 /* 570 * Look at the returned sense and act on the error, determining 571 * the unix error number to pass back. (0 = report no error) 572 * 573 * THIS IS THE DEFAULT ERROR HANDLER 574 */ 575 int 576 scsi_interpret_sense(xs) 577 struct scsi_xfer *xs; 578 { 579 struct scsi_sense_data *sense; 580 struct scsi_link *sc_link = xs->sc_link; 581 u_int8_t key; 582 u_int32_t info; 583 int error; 584 585 static char *error_mes[] = { 586 "soft error (corrected)", 587 "not ready", "medium error", 588 "non-media hardware failure", "illegal request", 589 "unit attention", "readonly device", 590 "no data found", "vendor unique", 591 "copy aborted", "command aborted", 592 "search returned equal", "volume overflow", 593 "verify miscompare", "unknown error key" 594 }; 595 596 sense = &xs->sense; 597 #ifdef SCSIDEBUG 598 if ((sc_link->flags & SDEV_DB1) != 0) { 599 int count; 600 printf("code%x valid%x ", 601 sense->error_code & SSD_ERRCODE, 602 sense->error_code & SSD_ERRCODE_VALID ? 1 : 0); 603 printf("seg%x key%x ili%x eom%x fmark%x\n", 604 sense->extended_segment, 605 sense->extended_flags & SSD_KEY, 606 sense->extended_flags & SSD_ILI ? 1 : 0, 607 sense->extended_flags & SSD_EOM ? 1 : 0, 608 sense->extended_flags & SSD_FILEMARK ? 1 : 0); 609 printf("info: %x %x %x %x followed by %d extra bytes\n", 610 sense->extended_info[0], 611 sense->extended_info[1], 612 sense->extended_info[2], 613 sense->extended_info[3], 614 sense->extended_extra_len); 615 printf("extra: "); 616 for (count = 0; count < sense->extended_extra_len; count++) 617 printf("%x ", sense->extended_extra_bytes[count]); 618 printf("\n"); 619 } 620 #endif /*SCSIDEBUG */ 621 /* 622 * If the device has it's own error handler, call it first. 623 * If it returns a legit error value, return that, otherwise 624 * it wants us to continue with normal error processing. 625 */ 626 if (sc_link->device->err_handler) { 627 SC_DEBUG(sc_link, SDEV_DB2, ("calling private err_handler()\n")); 628 error = (*sc_link->device->err_handler) (xs); 629 if (error != -1) 630 return error; /* error >= 0 better ? */ 631 } 632 /* otherwise use the default */ 633 switch (sense->error_code & SSD_ERRCODE) { 634 /* 635 * If it's code 70, use the extended stuff and interpret the key 636 */ 637 case 0x71: /* delayed error */ 638 sc_print_addr(sc_link); 639 key = sense->extended_flags & SSD_KEY; 640 printf(" DELAYED ERROR, key = 0x%x\n", key); 641 case 0x70: 642 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) { 643 bcopy(sense->extended_info, &info, sizeof info); 644 info = ntohl(info); 645 } else 646 info = 0; 647 key = sense->extended_flags & SSD_KEY; 648 649 switch (key) { 650 case 0x0: /* NO SENSE */ 651 case 0x1: /* RECOVERED ERROR */ 652 if (xs->resid == xs->datalen) 653 xs->resid = 0; /* not short read */ 654 case 0xc: /* EQUAL */ 655 error = 0; 656 break; 657 case 0x2: /* NOT READY */ 658 if ((sc_link->flags & SDEV_REMOVABLE) != 0) 659 sc_link->flags &= ~SDEV_MEDIA_LOADED; 660 if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0) 661 return 0; 662 if ((xs->flags & SCSI_SILENT) != 0) 663 return EIO; 664 error = EIO; 665 break; 666 case 0x5: /* ILLEGAL REQUEST */ 667 if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0) 668 return 0; 669 error = EINVAL; 670 break; 671 case 0x6: /* UNIT ATTENTION */ 672 if ((sc_link->flags & SDEV_REMOVABLE) != 0) 673 sc_link->flags &= ~SDEV_MEDIA_LOADED; 674 if ((xs->flags & SCSI_IGNORE_MEDIA_CHANGE) != 0 || 675 /* XXX Should reupload any transient state. */ 676 (sc_link->flags & SDEV_REMOVABLE) == 0) 677 return ERESTART; 678 if ((xs->flags & SCSI_SILENT) != 0) 679 return EIO; 680 error = EIO; 681 break; 682 case 0x7: /* DATA PROTECT */ 683 error = EACCES; 684 break; 685 case 0x8: /* BLANK CHECK */ 686 error = 0; 687 break; 688 case 0xd: /* VOLUME OVERFLOW */ 689 error = ENOSPC; 690 break; 691 default: 692 error = EIO; 693 break; 694 } 695 696 if (key) { 697 sc_print_addr(sc_link); 698 printf("%s", error_mes[key - 1]); 699 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) { 700 switch (key) { 701 case 0x2: /* NOT READY */ 702 case 0x5: /* ILLEGAL REQUEST */ 703 case 0x6: /* UNIT ATTENTION */ 704 case 0x7: /* DATA PROTECT */ 705 break; 706 case 0x8: /* BLANK CHECK */ 707 printf(", requested size: %d (decimal)", 708 info); 709 break; 710 default: 711 printf(", info = %d (decimal)", info); 712 } 713 } 714 if (sense->extended_extra_len != 0) { 715 int n; 716 printf(", data ="); 717 for (n = 0; n < sense->extended_extra_len; n++) 718 printf(" %02x", sense->extended_extra_bytes[n]); 719 } 720 printf("\n"); 721 } 722 return error; 723 724 /* 725 * Not code 70, just report it 726 */ 727 default: 728 sc_print_addr(sc_link); 729 printf("error code %d", 730 sense->error_code & SSD_ERRCODE); 731 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) { 732 printf(" at block no. %d (decimal)", 733 (sense->XXX_unextended_blockhi << 16) + 734 (sense->XXX_unextended_blockmed << 8) + 735 (sense->XXX_unextended_blocklow)); 736 } 737 printf("\n"); 738 return EIO; 739 } 740 } 741 742 /* 743 * Utility routines often used in SCSI stuff 744 */ 745 746 /* 747 * convert a physical address to 3 bytes, 748 * MSB at the lowest address, 749 * LSB at the highest. 750 */ 751 void 752 lto3b(val, bytes) 753 u_int32_t val; 754 u_int8_t *bytes; 755 { 756 757 *bytes++ = (val & 0xff0000) >> 16; 758 *bytes++ = (val & 0xff00) >> 8; 759 *bytes = val & 0xff; 760 } 761 762 /* 763 * The reverse of lto3b 764 */ 765 u_int32_t 766 _3btol(bytes) 767 u_int8_t *bytes; 768 { 769 u_int32_t rc; 770 771 rc = (*bytes++ << 16); 772 rc += (*bytes++ << 8); 773 rc += *bytes; 774 return (rc); 775 } 776 777 /* 778 * Print out the scsi_link structure's address info. 779 */ 780 void 781 sc_print_addr(sc_link) 782 struct scsi_link *sc_link; 783 { 784 785 printf("%s(%s:%d:%d): ", 786 sc_link->device_softc ? 787 ((struct device *)sc_link->device_softc)->dv_xname : "probe", 788 ((struct device *)sc_link->adapter_softc)->dv_xname, 789 sc_link->target, sc_link->lun); 790 } 791 792 #ifdef SCSIDEBUG 793 /* 794 * Given a scsi_xfer, dump the request, in all it's glory 795 */ 796 void 797 show_scsi_xs(xs) 798 struct scsi_xfer *xs; 799 { 800 printf("xs(0x%x): ", xs); 801 printf("flg(0x%x)", xs->flags); 802 printf("sc_link(0x%x)", xs->sc_link); 803 printf("retr(0x%x)", xs->retries); 804 printf("timo(0x%x)", xs->timeout); 805 printf("cmd(0x%x)", xs->cmd); 806 printf("len(0x%x)", xs->cmdlen); 807 printf("data(0x%x)", xs->data); 808 printf("len(0x%x)", xs->datalen); 809 printf("res(0x%x)", xs->resid); 810 printf("err(0x%x)", xs->error); 811 printf("bp(0x%x)", xs->bp); 812 show_scsi_cmd(xs); 813 } 814 815 void 816 show_scsi_cmd(xs) 817 struct scsi_xfer *xs; 818 { 819 u_char *b = (u_char *) xs->cmd; 820 int i = 0; 821 822 sc_print_addr(xs->sc_link); 823 printf("command: "); 824 825 if ((xs->flags & SCSI_RESET) == 0) { 826 while (i < xs->cmdlen) { 827 if (i) 828 printf(","); 829 printf("%x", b[i++]); 830 } 831 printf("-[%d bytes]\n", xs->datalen); 832 if (xs->datalen) 833 show_mem(xs->data, min(64, xs->datalen)); 834 } else 835 printf("-RESET-\n"); 836 } 837 838 void 839 show_mem(address, num) 840 u_char *address; 841 int num; 842 { 843 int x; 844 845 printf("------------------------------"); 846 for (x = 0; x < num; x++) { 847 if ((x % 16) == 0) 848 printf("\n%03d: ", x); 849 printf("%02x ", *address++); 850 } 851 printf("\n------------------------------\n"); 852 } 853 #endif /*SCSIDEBUG */ 854