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