|
|
1.1 ! root 1: /* ! 2: * scsi.c Copyright (C) 1992 Drew Eckhardt ! 3: * generic mid-level SCSI driver by ! 4: * Drew Eckhardt ! 5: * ! 6: * <[email protected]> ! 7: */ ! 8: #include <linux/config.h> ! 9: ! 10: #ifdef CONFIG_SCSI ! 11: #include <asm/system.h> ! 12: #include <linux/sched.h> ! 13: #include <linux/timer.h> ! 14: #include <linux/string.h> ! 15: ! 16: #include "scsi.h" ! 17: #include "hosts.h" ! 18: ! 19: #ifdef CONFIG_BLK_DEV_SD ! 20: #include "sd.h" ! 21: #endif ! 22: ! 23: #ifdef CONFIG_BLK_DEV_ST ! 24: #include "st.h" ! 25: #endif ! 26: ! 27: /* ! 28: static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.1 1992/04/24 18:01:50 root Exp root $"; ! 29: */ ! 30: ! 31: #define INTERNAL_ERROR (printk ("Internal error in file %s, line %s.\n", __FILE__, __LINE__), panic("")) ! 32: ! 33: static void scsi_done (int host, int result); ! 34: static void update_timeout (void); ! 35: ! 36: static int time_start; ! 37: static int time_elapsed; ! 38: ! 39: /* ! 40: global variables : ! 41: NR_SCSI_DEVICES is the number of SCSI devices we have detected, ! 42: scsi_devices an array of these specifing the address for each ! 43: (host, id, LUN) ! 44: */ ! 45: ! 46: int NR_SCSI_DEVICES=0; ! 47: Scsi_Device scsi_devices[MAX_SCSI_DEVICE]; ! 48: ! 49: #define SENSE_LENGTH 255 ! 50: /* ! 51: As the scsi do command functions are inteligent, and may need to ! 52: redo a command, we need to keep track of the last command ! 53: executed on each one. ! 54: */ ! 55: ! 56: #define WAS_RESET 0x01 ! 57: #define WAS_TIMEDOUT 0x02 ! 58: #define WAS_SENSE 0x04 ! 59: #define IS_RESETTING 0x08 ! 60: ! 61: static Scsi_Cmnd last_cmnd[MAX_SCSI_HOSTS]; ! 62: static int last_reset[MAX_SCSI_HOSTS]; ! 63: ! 64: /* ! 65: This is the number of clock ticks we should wait before we time out ! 66: and abort the command. This is for where the scsi.c module generates ! 67: the command, not where it originates from a higher level, in which ! 68: case the timeout is specified there. ! 69: ! 70: ! 71: ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT ! 72: respectively. ! 73: */ ! 74: #ifdef DEBUG ! 75: #define SCSI_TIMEOUT 500 ! 76: #else ! 77: #define SCSI_TIMEOUT 100 ! 78: #endif ! 79: #ifdef DEBUG ! 80: #define SENSE_TIMEOUT SCSI_TIMEOUT ! 81: #define ABORT_TIMEOUT SCSI_TIMEOUT ! 82: #define RESET_TIMEOUT SCSI_TIMEOUT ! 83: #else ! 84: ! 85: #define SENSE_TIMEOUT 50 ! 86: #define RESET_TIMEOUT 50 ! 87: #define ABORT_TIMEOUT 50 ! 88: #define MIN_RESET_DELAY 25 ! 89: ! 90: #endif ! 91: /* ! 92: As the actual SCSI command runs in the background, we must set up a ! 93: flag that tells scan_scsis() when the result it has is valid. ! 94: scan_scsis can set the_result to -1, and watch for it to become the ! 95: actual return code for that call. the scan_scsis_done function() is ! 96: our user specified completion function that is passed on to the ! 97: scsi_do_cmd() function. ! 98: */ ! 99: ! 100: static int the_result; ! 101: static unsigned char sense_buffer[SENSE_LENGTH]; ! 102: static void scan_scsis_done (int host, int result) ! 103: { ! 104: ! 105: #ifdef DEBUG ! 106: printk ("scan_scsis_done(%d, %06x\n\r", host, result); ! 107: #endif ! 108: the_result = result; ! 109: } ! 110: /* ! 111: Detecting SCSI devices : ! 112: We scan all present host adapter's busses, from ID 0 to ID 6. ! 113: We use the INQUIRY command, determine device type, and pass the ID / ! 114: lun address of all sequential devices to the tape driver, all random ! 115: devices to the disk driver. ! 116: */ ! 117: ! 118: static void scan_scsis (void) ! 119: { ! 120: int host_nr , dev, lun, type, maxed; ! 121: static unsigned char scsi_cmd [12]; ! 122: static unsigned char scsi_result [256]; ! 123: ! 124: for (host_nr = 0; host_nr < MAX_SCSI_HOSTS; ++host_nr) ! 125: if (scsi_hosts[host_nr].present) ! 126: { ! 127: for (dev = 0; dev < 7; ++dev) ! 128: if (scsi_hosts[host_nr].this_id != dev) ! 129: #ifdef MULTI_LUN ! 130: for (lun = 0; lun < 8; ++lun) ! 131: { ! 132: #else ! 133: { ! 134: lun = 0; ! 135: #endif ! 136: /* Build an INQUIRY command block. */ ! 137: ! 138: scsi_cmd[0] = INQUIRY; ! 139: scsi_cmd[1] = (lun << 5) & 0xe0; ! 140: scsi_cmd[2] = 0; ! 141: scsi_cmd[3] = 0; ! 142: scsi_cmd[4] = 255; ! 143: scsi_cmd[5] = 0; ! 144: the_result = -1; ! 145: #ifdef DEBUG ! 146: memset ((void *) scsi_result , 0, 255); ! 147: #endif ! 148: scsi_do_cmd (host_nr, dev, (void *) scsi_cmd, (void *) ! 149: scsi_result, 256, scan_scsis_done, ! 150: SCSI_TIMEOUT, sense_buffer, 3); ! 151: ! 152: /* Wait for valid result */ ! 153: ! 154: while (the_result < 0); ! 155: ! 156: ! 157: if (!the_result) ! 158: { ! 159: scsi_devices[NR_SCSI_DEVICES]. ! 160: host_no = host_nr; ! 161: scsi_devices[NR_SCSI_DEVICES]. ! 162: id = dev; ! 163: scsi_devices[NR_SCSI_DEVICES]. ! 164: lun = lun; ! 165: scsi_devices[NR_SCSI_DEVICES]. ! 166: removable = (0x80 & ! 167: scsi_result[1]) >> 7; ! 168: ! 169: ! 170: ! 171: /* ! 172: Currently, all sequential devices are assumed to be tapes, ! 173: all random devices disk, with the appropriate read only ! 174: flags set for ROM / WORM treated as RO. ! 175: */ ! 176: ! 177: switch (type = scsi_result[0]) ! 178: { ! 179: case TYPE_TAPE: ! 180: case TYPE_DISK: ! 181: scsi_devices[NR_SCSI_DEVICES].writeable = 1; ! 182: break; ! 183: case TYPE_WORM: ! 184: case TYPE_ROM: ! 185: scsi_devices[NR_SCSI_DEVICES].writeable = 0; ! 186: break; ! 187: default: ! 188: type = -1; ! 189: } ! 190: ! 191: scsi_devices[NR_SCSI_DEVICES].random = (type == TYPE_TAPE) ? 0 : 1; ! 192: ! 193: maxed = 0; ! 194: switch (type) ! 195: { ! 196: case -1: ! 197: break; ! 198: case TYPE_TAPE: ! 199: printk("Detected scsi tape at host %d, ID %d, lun %d \n", host_nr, dev, lun); ! 200: #ifdef CONFIG_BLK_DEV_ST ! 201: if (!(maxed = (NR_ST == MAX_ST))) ! 202: scsi_tapes[NR_ST].device = &scsi_devices[NR_SCSI_DEVICES]; ! 203: #endif ! 204: default: ! 205: printk("Detected scsi disk at host %d, ID %d, lun %d \n", host_nr, dev, lun); ! 206: #ifdef CONFIG_BLK_DEV_SD ! 207: if (!(maxed = (NR_SD >= MAX_SD))) ! 208: rscsi_disks[NR_SD].device = &scsi_devices[NR_SCSI_DEVICES]; ! 209: #endif ! 210: } ! 211: ! 212: if (maxed) ! 213: { ! 214: printk ("Already have detected maximum number of SCSI %ss Unable to \n" ! 215: "add drive at SCSI host %s, ID %d, LUN %d\n\r", (type == TYPE_TAPE) ? ! 216: "tape" : "disk", scsi_hosts[host_nr].name, ! 217: dev, lun); ! 218: type = -1; ! 219: break; ! 220: } ! 221: ! 222: else if (type != -1) ! 223: { ! 224: if (type == TYPE_TAPE) ! 225: #ifdef CONFIG_BLK_DEV_ST ! 226: ++NR_ST; ! 227: #else ! 228: ; ! 229: #endif ! 230: ! 231: else ! 232: #ifdef CONFIG_BLK_DEV_SD ! 233: ++NR_SD; ! 234: #else ! 235: ; ! 236: #endif ! 237: } ! 238: ++NR_SCSI_DEVICES; ! 239: } /* if result == DID_OK ends */ ! 240: } /* for lun ends */ ! 241: } /* if present */ ! 242: ! 243: printk("Detected " ! 244: #ifdef CONFIG_BLK_DEV_SD ! 245: "%d disk%s " ! 246: #endif ! 247: ! 248: #ifdef CONFIG_BLK_DEV_ST ! 249: "%d tape%s " ! 250: #endif ! 251: ! 252: "total.\n", ! 253: ! 254: #ifdef CONFIG_BLK_DEV_SD ! 255: NR_SD, (NR_SD != 1) ? "s" : "" ! 256: #ifdef CONFIG_BLK_DEV_ST ! 257: , ! 258: #endif ! 259: #endif ! 260: ! 261: #ifdef CONFIG_BLK_DEV_ST ! 262: NR_ST, (NR_ST != 1) ? "s" : "" ! 263: #endif ! 264: ); ! 265: } /* scan_scsis ends */ ! 266: ! 267: /* ! 268: We handle the timeout differently if it happens when a reset, ! 269: abort, etc are in process. ! 270: */ ! 271: ! 272: static unsigned char internal_timeout[MAX_SCSI_HOSTS]; ! 273: ! 274: /* Flag bits for the internal_timeout array */ ! 275: ! 276: #define NORMAL_TIMEOUT 0 ! 277: #define IN_ABORT 1 ! 278: #define IN_RESET 2 ! 279: /* ! 280: This is our time out function, called when the timer expires for a ! 281: given host adapter. It will attempt to abort the currently executing ! 282: command, that failing perform a kernel panic. ! 283: */ ! 284: ! 285: static void scsi_times_out (int host) ! 286: { ! 287: ! 288: switch (internal_timeout[host] & (IN_ABORT | IN_RESET)) ! 289: { ! 290: case NORMAL_TIMEOUT: ! 291: printk("SCSI host %d timed out - aborting command \r\n", ! 292: host); ! 293: ! 294: if (!scsi_abort (host, DID_TIME_OUT)) ! 295: return; ! 296: case IN_ABORT: ! 297: printk("SCSI host %d abort() timed out - reseting \r\n", ! 298: host); ! 299: if (!scsi_reset (host)) ! 300: return; ! 301: case IN_RESET: ! 302: case (IN_ABORT | IN_RESET): ! 303: printk("Unable to reset scsi host %d\r\n",host); ! 304: panic(""); ! 305: default: ! 306: INTERNAL_ERROR; ! 307: } ! 308: ! 309: } ! 310: ! 311: /* ! 312: This is inline because we have stack problemes if we recurse to deeply. ! 313: */ ! 314: ! 315: static void internal_cmnd (int host, unsigned char target, const void *cmnd , ! 316: void *buffer, unsigned bufflen, void (*done)(int,int)) ! 317: { ! 318: int temp; ! 319: ! 320: #ifdef DEBUG_DELAY ! 321: int clock; ! 322: #endif ! 323: ! 324: if ((host < 0) || (host > MAX_SCSI_HOSTS)) ! 325: panic ("Host number in internal_cmnd() is out of range.\n"); ! 326: ! 327: ! 328: /* ! 329: We will wait MIN_RESET_DELAY clock ticks after the last reset so ! 330: we can avoid the drive not being ready. ! 331: */ ! 332: temp = last_reset[host]; ! 333: while (jiffies < temp); ! 334: ! 335: host_timeout[host] = last_cmnd[host].timeout_per_command; ! 336: update_timeout(); ! 337: ! 338: /* ! 339: We will use a queued command if possible, otherwise we will emulate the ! 340: queing and calling of completion function ourselves. ! 341: */ ! 342: #ifdef DEBUG ! 343: printk("internal_cmnd (host = %d, target = %d, command = %08x, buffer = %08x, \n" ! 344: "bufflen = %d, done = %08x)\n", host, target, cmnd, buffer, bufflen, done); ! 345: #endif ! 346: ! 347: ! 348: if (scsi_hosts[host].can_queue) ! 349: { ! 350: #ifdef DEBUG ! 351: printk("queuecommand : routine at %08x\n", ! 352: scsi_hosts[host].queuecommand); ! 353: #endif ! 354: scsi_hosts[host].queuecommand (target, cmnd, buffer, bufflen, ! 355: done); ! 356: } ! 357: else ! 358: { ! 359: ! 360: #ifdef DEBUG ! 361: printk("command() : routine at %08x\n", scsi_hosts[host].command); ! 362: #endif ! 363: temp=scsi_hosts[host].command (target, cmnd, buffer, bufflen); ! 364: ! 365: #ifdef DEBUG_DELAY ! 366: clock = jiffies + 400; ! 367: while (jiffies < clock); ! 368: printk("done(host = %d, result = %04x) : routine at %08x\n", host, temp, done); ! 369: #endif ! 370: done(host, temp); ! 371: } ! 372: #ifdef DEBUG ! 373: printk("leaving internal_cmnd()\n"); ! 374: #endif ! 375: } ! 376: ! 377: static void scsi_request_sense (int host, unsigned char target, ! 378: unsigned char lun) ! 379: { ! 380: cli(); ! 381: host_timeout[host] = SENSE_TIMEOUT; ! 382: update_timeout(); ! 383: last_cmnd[host].flags |= WAS_SENSE; ! 384: sti(); ! 385: ! 386: last_cmnd[host].sense_cmnd[1] = lun << 5; ! 387: ! 388: internal_cmnd (host, target, (void *) last_cmnd[host].sense_cmnd, ! 389: (void *) last_cmnd[host].sense_buffer, SENSE_LENGTH, ! 390: scsi_done); ! 391: } ! 392: ! 393: ! 394: ! 395: ! 396: ! 397: /* ! 398: scsi_do_cmd sends all the commands out to the low-level driver. It ! 399: handles the specifics required for each low level driver - ie queued ! 400: or non queud. It also prevents conflicts when different high level ! 401: drivers go for the same host at the same time. ! 402: */ ! 403: ! 404: void scsi_do_cmd (int host, unsigned char target, const void *cmnd , ! 405: void *buffer, unsigned bufflen, void (*done)(int,int), ! 406: int timeout, unsigned char *sense_buffer, int retries ! 407: ) ! 408: { ! 409: int ok = 0; ! 410: ! 411: #ifdef DEBUG ! 412: int i; ! 413: printk ("scsi_do_cmd (host = %d, target = %d, buffer =%08x, " ! 414: "bufflen = %d, done = %08x, timeout = %d, retries = %d)\n" ! 415: "command : " , host, target, buffer, bufflen, done, timeout, retries); ! 416: for (i = 0; i < 10; ++i) ! 417: printk ("%02x ", ((unsigned char *) cmnd)[i]); ! 418: printk("\n"); ! 419: #endif ! 420: ! 421: if ((host >= MAX_SCSI_HOSTS) || !scsi_hosts[host].present) ! 422: { ! 423: printk ("Invalid or not present host number. %d\n", host); ! 424: panic(""); ! 425: } ! 426: ! 427: ! 428: /* ! 429: We must prevent reentrancy to the lowlevel host driver. This prevents ! 430: it - we enter a loop until the host we want to talk to is not busy. ! 431: Race conditions are prevented, as interrupts are disabled inbetween the ! 432: time we check for the host being not busy, and the time we mark it busy ! 433: ourselves. ! 434: */ ! 435: ! 436: do { ! 437: cli(); ! 438: if (host_busy[host]) ! 439: { ! 440: sti(); ! 441: #ifdef DEBUG ! 442: printk("Host %d is busy.\n" ); ! 443: #endif ! 444: while (host_busy[host]); ! 445: #ifdef DEBUG ! 446: printk("Host %d is no longer busy."); ! 447: #endif ! 448: } ! 449: else ! 450: { ! 451: host_busy[host] = 1; ! 452: ok = 1; ! 453: sti(); ! 454: } ! 455: } while (!ok); ! 456: ! 457: ! 458: /* ! 459: Our own function scsi_done (which marks the host as not busy, disables ! 460: the timeout counter, etc) will be called by us or by the ! 461: scsi_hosts[host].queuecommand() function needs to also call ! 462: the completion function for the high level driver. ! 463: ! 464: */ ! 465: ! 466: memcpy ((void *) last_cmnd[host].cmnd , (void *) cmnd, 10); ! 467: last_cmnd[host].host = host; ! 468: last_cmnd[host].target = target; ! 469: last_cmnd[host].lun = (last_cmnd[host].cmnd[1] >> 5); ! 470: last_cmnd[host].bufflen = bufflen; ! 471: last_cmnd[host].buffer = buffer; ! 472: last_cmnd[host].sense_buffer = sense_buffer; ! 473: last_cmnd[host].flags=0; ! 474: last_cmnd[host].retries=0; ! 475: last_cmnd[host].allowed=retries; ! 476: last_cmnd[host].done = done; ! 477: last_cmnd[host].timeout_per_command = timeout; ! 478: ! 479: /* Start the timer ticking. */ ! 480: ! 481: internal_timeout[host] = 0; ! 482: internal_cmnd (host, target, cmnd , buffer, bufflen, scsi_done); ! 483: ! 484: #ifdef DEBUG ! 485: printk ("Leaving scsi_do_cmd()\n"); ! 486: #endif ! 487: } ! 488: ! 489: ! 490: /* ! 491: The scsi_done() function disables the timeout timer for the scsi host, ! 492: marks the host as not busy, and calls the user specified completion ! 493: function for that host's current command. ! 494: */ ! 495: ! 496: static void reset (int host) ! 497: { ! 498: #ifdef DEBUG ! 499: printk("reset(%d)\n", host); ! 500: #endif ! 501: ! 502: last_cmnd[host].flags |= (WAS_RESET | IS_RESETTING); ! 503: scsi_reset(host); ! 504: ! 505: #ifdef DEBUG ! 506: printk("performing request sense\n"); ! 507: #endif ! 508: ! 509: scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun); ! 510: } ! 511: ! 512: ! 513: ! 514: static int check_sense (int host) ! 515: { ! 516: if (((sense_buffer[0] & 0x70) >> 4) == 7) ! 517: switch (sense_buffer[2] & 0xf) ! 518: { ! 519: case NO_SENSE: ! 520: case RECOVERED_ERROR: ! 521: return 0; ! 522: ! 523: case ABORTED_COMMAND: ! 524: case NOT_READY: ! 525: case UNIT_ATTENTION: ! 526: return SUGGEST_RETRY; ! 527: ! 528: /* these three are not supported */ ! 529: case COPY_ABORTED: ! 530: case VOLUME_OVERFLOW: ! 531: case MISCOMPARE: ! 532: ! 533: case MEDIUM_ERROR: ! 534: return SUGGEST_REMAP; ! 535: case BLANK_CHECK: ! 536: case DATA_PROTECT: ! 537: case HARDWARE_ERROR: ! 538: case ILLEGAL_REQUEST: ! 539: default: ! 540: return SUGGEST_ABORT; ! 541: } ! 542: else ! 543: return SUGGEST_RETRY; ! 544: } ! 545: ! 546: static void scsi_done (int host, int result) ! 547: { ! 548: int status=0; ! 549: int exit=0; ! 550: int checked; ! 551: int oldto; ! 552: oldto = host_timeout[host]; ! 553: host_timeout[host] = 0; ! 554: update_timeout(); ! 555: ! 556: #define FINISHED 0 ! 557: #define MAYREDO 1 ! 558: #define REDO 3 ! 559: ! 560: #ifdef DEBUG ! 561: printk("In scsi_done(host = %d, result = %06x)\n", host, result); ! 562: #endif ! 563: if (host > MAX_SCSI_HOSTS || host < 0) ! 564: { ! 565: host_timeout[host] = 0; ! 566: update_timeout(); ! 567: panic("scsi_done() called with invalid host number.\n"); ! 568: } ! 569: ! 570: switch (host_byte(result)) ! 571: { ! 572: case DID_OK: ! 573: if (last_cmnd[host].flags & IS_RESETTING) ! 574: { ! 575: last_cmnd[host].flags &= ~IS_RESETTING; ! 576: status = REDO; ! 577: break; ! 578: } ! 579: ! 580: if (status_byte(result) && (last_cmnd[host].flags & ! 581: WAS_SENSE)) ! 582: { ! 583: last_cmnd[host].flags &= ~WAS_SENSE; ! 584: cli(); ! 585: internal_timeout[host] &= ~SENSE_TIMEOUT; ! 586: sti(); ! 587: ! 588: if (!(last_cmnd[host].flags & WAS_RESET)) ! 589: reset(host); ! 590: else ! 591: { ! 592: exit = (DRIVER_HARD | SUGGEST_ABORT); ! 593: status = FINISHED; ! 594: } ! 595: } ! 596: else switch(msg_byte(result)) ! 597: { ! 598: case COMMAND_COMPLETE: ! 599: switch (status_byte(result)) ! 600: { ! 601: case GOOD: ! 602: if (last_cmnd[host].flags & WAS_SENSE) ! 603: { ! 604: #ifdef DEBUG ! 605: printk ("In scsi_done, GOOD status, COMMAND COMPLETE, parsing sense information.\n"); ! 606: #endif ! 607: ! 608: last_cmnd[host].flags &= ~WAS_SENSE; ! 609: cli(); ! 610: internal_timeout[host] &= ~SENSE_TIMEOUT; ! 611: sti(); ! 612: ! 613: switch (checked = check_sense(host)) ! 614: { ! 615: case 0: ! 616: #ifdef DEBUG ! 617: printk("NO SENSE. status = REDO\n"); ! 618: #endif ! 619: ! 620: host_timeout[host] = oldto; ! 621: update_timeout(); ! 622: status = REDO; ! 623: break; ! 624: case SUGGEST_REMAP: ! 625: case SUGGEST_RETRY: ! 626: #ifdef DEBUG ! 627: printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n"); ! 628: #endif ! 629: ! 630: status = MAYREDO; ! 631: exit = SUGGEST_RETRY; ! 632: break; ! 633: case SUGGEST_ABORT: ! 634: #ifdef DEBUG ! 635: printk("SENSE SUGGEST ABORT - status = FINISHED"); ! 636: #endif ! 637: ! 638: status = FINISHED; ! 639: exit = DRIVER_SENSE; ! 640: break; ! 641: default: ! 642: printk ("Internal error %s %s \n", __FILE__, ! 643: __LINE__); ! 644: } ! 645: } ! 646: else ! 647: { ! 648: #ifdef DEBUG ! 649: printk("COMMAND COMPLETE message returned, status = FINISHED. \n"); ! 650: #endif ! 651: ! 652: exit = DRIVER_OK; ! 653: status = FINISHED; ! 654: } ! 655: break; ! 656: ! 657: case CHECK_CONDITION: ! 658: ! 659: #ifdef DEBUG ! 660: printk("CHECK CONDITION message returned, performing request sense.\n"); ! 661: #endif ! 662: ! 663: scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun); ! 664: break; ! 665: ! 666: case CONDITION_GOOD: ! 667: case INTERMEDIATE_GOOD: ! 668: case INTERMEDIATE_C_GOOD: ! 669: #ifdef DEBUG ! 670: printk("CONDITION GOOD, INTERMEDIATE GOOD, or INTERMEDIATE CONDITION GOOD recieved and ignored. \n"); ! 671: #endif ! 672: break; ! 673: ! 674: case BUSY: ! 675: #ifdef DEBUG ! 676: printk("BUSY message returned, performing REDO"); ! 677: #endif ! 678: host_timeout[host] = oldto; ! 679: update_timeout(); ! 680: status = REDO; ! 681: break; ! 682: ! 683: case RESERVATION_CONFLICT: ! 684: reset(host); ! 685: exit = DRIVER_SOFT | SUGGEST_ABORT; ! 686: status = MAYREDO; ! 687: break; ! 688: default: ! 689: printk ("Internal error %s %s \n" ! 690: "status byte = %d \n", __FILE__, ! 691: __LINE__, status_byte(result)); ! 692: ! 693: } ! 694: break; ! 695: default: ! 696: panic ("unsupported message byte recieved."); ! 697: } ! 698: break; ! 699: case DID_TIME_OUT: ! 700: #ifdef DEBUG ! 701: printk("Host returned DID_TIME_OUT - "); ! 702: #endif ! 703: ! 704: if (last_cmnd[host].flags & WAS_TIMEDOUT) ! 705: { ! 706: #ifdef DEBUG ! 707: printk("Aborting\n"); ! 708: #endif ! 709: exit = (DRIVER_TIMEOUT | SUGGEST_ABORT); ! 710: } ! 711: else ! 712: { ! 713: #ifdef DEBUG ! 714: printk ("Retrying.\n"); ! 715: #endif ! 716: last_cmnd[host].flags |= WAS_TIMEDOUT; ! 717: status = REDO; ! 718: } ! 719: break; ! 720: case DID_BUS_BUSY: ! 721: case DID_PARITY: ! 722: status = REDO; ! 723: break; ! 724: case DID_NO_CONNECT: ! 725: #ifdef DEBUG ! 726: printk("Couldn't connect.\n"); ! 727: #endif ! 728: exit = (DRIVER_HARD | SUGGEST_ABORT); ! 729: break; ! 730: case DID_ERROR: ! 731: status = MAYREDO; ! 732: exit = (DRIVER_HARD | SUGGEST_ABORT); ! 733: break; ! 734: case DID_BAD_TARGET: ! 735: case DID_ABORT: ! 736: exit = (DRIVER_INVALID | SUGGEST_ABORT); ! 737: break; ! 738: default : ! 739: exit = (DRIVER_ERROR | SUGGEST_DIE); ! 740: } ! 741: ! 742: switch (status) ! 743: { ! 744: case FINISHED: ! 745: break; ! 746: case MAYREDO: ! 747: ! 748: #ifdef DEBUG ! 749: printk("In MAYREDO, allowing %d retries, have %d\n\r", ! 750: last_cmnd[host].allowed, last_cmnd[host].retries); ! 751: #endif ! 752: ! 753: if ((++last_cmnd[host].retries) < last_cmnd[host].allowed) ! 754: { ! 755: if ((last_cmnd[host].retries >= (last_cmnd[host].allowed >> 1)) ! 756: && !(last_cmnd[host].flags & WAS_RESET)) ! 757: reset(host); ! 758: break; ! 759: ! 760: } ! 761: else ! 762: { ! 763: status = FINISHED; ! 764: break; ! 765: } ! 766: /* fall through to REDO */ ! 767: ! 768: case REDO: ! 769: if (last_cmnd[host].flags & WAS_SENSE) ! 770: scsi_request_sense (host, last_cmnd[host].target, ! 771: last_cmnd[host].lun); ! 772: else ! 773: internal_cmnd (host, last_cmnd[host].target, ! 774: last_cmnd[host].cmnd, ! 775: last_cmnd[host].buffer, ! 776: last_cmnd[host].bufflen, scsi_done); ! 777: break; ! 778: default: ! 779: INTERNAL_ERROR; ! 780: } ! 781: ! 782: if (status == FINISHED) ! 783: { ! 784: #ifdef DEBUG ! 785: printk("Calling done function - at address %08x\n", last_cmnd[host].done); ! 786: #endif ! 787: last_cmnd[host].done (host, (result | ((exit & 0xff) << 24))); ! 788: host_busy[host] = 0; ! 789: } ! 790: ! 791: ! 792: #undef FINISHED ! 793: #undef REDO ! 794: #undef MAYREDO ! 795: ! 796: } ! 797: ! 798: /* ! 799: The scsi_abort function interfaces with the abort() function of the host ! 800: we are aborting, and causes the current command to not complete. The ! 801: caller should deal with any error messages or status returned on the ! 802: next call. ! 803: ! 804: This will not be called rentrantly for a given host. ! 805: */ ! 806: ! 807: /* ! 808: Since we're nice guys and specified that abort() and reset() ! 809: can be non-reentrant. The internal_timeout flags are used for ! 810: this. ! 811: */ ! 812: ! 813: ! 814: int scsi_abort (int host, int why) ! 815: { ! 816: int temp, oldto; ! 817: ! 818: while(1) ! 819: { ! 820: cli(); ! 821: if (internal_timeout[host] & IN_ABORT) ! 822: { ! 823: sti(); ! 824: while (internal_timeout[host] & IN_ABORT); ! 825: } ! 826: else ! 827: { ! 828: internal_timeout[host] |= IN_ABORT; ! 829: host_timeout[host] = ABORT_TIMEOUT; ! 830: update_timeout(); ! 831: ! 832: oldto = host_timeout[host]; ! 833: ! 834: sti(); ! 835: if (!host_busy[host] || !scsi_hosts[host].abort(why)) ! 836: temp = 0; ! 837: else ! 838: temp = 1; ! 839: ! 840: cli(); ! 841: internal_timeout[host] &= ~IN_ABORT; ! 842: host_timeout[host]=oldto; ! 843: update_timeout(); ! 844: sti(); ! 845: return temp; ! 846: } ! 847: } ! 848: } ! 849: ! 850: int scsi_reset (int host) ! 851: { ! 852: int temp, oldto; ! 853: ! 854: while (1) { ! 855: cli(); ! 856: if (internal_timeout[host] & IN_RESET) ! 857: { ! 858: sti(); ! 859: while (internal_timeout[host] & IN_RESET); ! 860: } ! 861: else ! 862: { ! 863: oldto = host_timeout[host]; ! 864: host_timeout[host] = RESET_TIMEOUT; ! 865: update_timeout(); ! 866: internal_timeout[host] |= IN_RESET; ! 867: ! 868: if (host_busy[host]) ! 869: { ! 870: sti(); ! 871: if (!(last_cmnd[host].flags & IS_RESETTING) && !(internal_timeout[host] & IN_ABORT)) ! 872: scsi_abort(host, DID_RESET); ! 873: ! 874: temp = scsi_hosts[host].reset(); ! 875: } ! 876: else ! 877: { ! 878: host_busy[host]=1; ! 879: ! 880: sti(); ! 881: temp = scsi_hosts[host].reset(); ! 882: last_reset[host] = jiffies; ! 883: host_busy[host]=0; ! 884: } ! 885: ! 886: cli(); ! 887: host_timeout[host] = oldto; ! 888: update_timeout(); ! 889: internal_timeout[host] &= ~IN_RESET; ! 890: sti(); ! 891: return temp; ! 892: } ! 893: } ! 894: } ! 895: ! 896: ! 897: static void scsi_main_timeout(void) ! 898: { ! 899: /* ! 900: We must not enter update_timeout with a timeout condition still pending. ! 901: */ ! 902: ! 903: int i, timed_out; ! 904: ! 905: do { ! 906: cli(); ! 907: ! 908: /* ! 909: Find all timers such that they have 0 or negative (shouldn't happen) ! 910: time remaining on them. ! 911: */ ! 912: ! 913: for (i = timed_out = 0; i < MAX_SCSI_HOSTS; ++i) ! 914: if (host_timeout[i] != 0 && host_timeout[i] <= time_elapsed) ! 915: { ! 916: sti(); ! 917: host_timeout[i] = 0; ! 918: scsi_times_out(i); ! 919: ++timed_out; ! 920: } ! 921: ! 922: update_timeout(); ! 923: } while (timed_out); ! 924: sti(); ! 925: } ! 926: ! 927: /* ! 928: These are used to keep track of things. ! 929: */ ! 930: ! 931: static int time_start, time_elapsed; ! 932: ! 933: /* ! 934: The strategy is to cause the timer code to call scsi_times_out() ! 935: when the soonest timeout is pending. ! 936: */ ! 937: ! 938: static void update_timeout(void) ! 939: { ! 940: int i, least, used; ! 941: ! 942: cli(); ! 943: ! 944: /* ! 945: Figure out how much time has passed since the last time the timeouts ! 946: were updated ! 947: */ ! 948: used = (time_start) ? (jiffies - time_start) : 0; ! 949: ! 950: /* ! 951: Find out what is due to timeout soonest, and adjust all timeouts for ! 952: the amount of time that has passed since the last time we called ! 953: update_timeout. ! 954: */ ! 955: ! 956: for (i = 0, least = 0xffffffff; i < MAX_SCSI_HOSTS; ++i) ! 957: if (host_timeout[i] > 0 && (host_timeout[i] -= used) < least) ! 958: least = host_timeout[i]; ! 959: ! 960: /* ! 961: If something is due to timeout again, then we will set the next timeout ! 962: interrupt to occur. Otherwise, timeouts are disabled. ! 963: */ ! 964: ! 965: if (least != 0xffffffff) ! 966: { ! 967: time_start = jiffies; ! 968: timer_table[SCSI_TIMER].expires = (time_elapsed = least) + jiffies; ! 969: timer_active |= 1 << SCSI_TIMER; ! 970: } ! 971: else ! 972: { ! 973: timer_table[SCSI_TIMER].expires = time_start = time_elapsed = 0; ! 974: timer_active &= ~(1 << SCSI_TIMER); ! 975: } ! 976: sti(); ! 977: } ! 978: /* ! 979: scsi_dev_init() is our initialization routine, which inturn calls host ! 980: initialization, bus scanning, and sd/st initialization routines. It ! 981: should be called from main(). ! 982: */ ! 983: ! 984: static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0}; ! 985: void scsi_dev_init (void) ! 986: { ! 987: int i; ! 988: #ifdef FOO_ON_YOU ! 989: return; ! 990: #endif ! 991: timer_table[SCSI_TIMER].fn = scsi_main_timeout; ! 992: timer_table[SCSI_TIMER].expires = 0; ! 993: ! 994: scsi_init(); /* initialize all hosts */ ! 995: /* ! 996: Set up sense command in each host structure. ! 997: */ ! 998: ! 999: for (i = 0; i < MAX_SCSI_HOSTS; ++i) ! 1000: { ! 1001: memcpy ((void *) last_cmnd[i].sense_cmnd, (void *) generic_sense, ! 1002: 6); ! 1003: last_reset[i] = 0; ! 1004: } ! 1005: ! 1006: scan_scsis(); /* scan for scsi devices */ ! 1007: ! 1008: #ifdef CONFIG_BLK_DEV_SD ! 1009: sd_init(); /* init scsi disks */ ! 1010: #endif ! 1011: ! 1012: #ifdef CONFIG_BLK_DEV_ST ! 1013: st_init(); /* init scsi tapes */ ! 1014: #endif ! 1015: } ! 1016: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.