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