|
|
1.1 ! root 1: /* ! 2: * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. ! 3: * ! 4: * 26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111 ! 5: * Added command line option (et:[y|n]) to use the existing ! 6: * translation (returned by scsicam_bios_param) as disk geometry. ! 7: * The default is et:n, which uses the disk geometry jumpered ! 8: * on the board. ! 9: * The default value et:n is compatible with all previous revisions ! 10: * of this driver. ! 11: * ! 12: * 28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104 ! 13: * Increased busy timeout from 10 msec. to 200 msec. while ! 14: * processing interrupts. ! 15: * ! 16: * 18 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102 ! 17: * Improved abort handling during the eh recovery process. ! 18: * ! 19: * 13 May 1998 Rev. 4.30 for linux 2.0.33 and 2.1.101 ! 20: * The driver is now fully SMP safe, including the ! 21: * abort and reset routines. ! 22: * Added command line options (eh:[y|n]) to choose between ! 23: * new_eh_code and the old scsi code. ! 24: * If linux version >= 2.1.101 the default is eh:y, while the eh ! 25: * option is ignored for previous releases and the old scsi code ! 26: * is used. ! 27: * ! 28: * 18 Apr 1998 Rev. 4.20 for linux 2.0.33 and 2.1.97 ! 29: * Reworked interrupt handler. ! 30: * ! 31: * 11 Apr 1998 rev. 4.05 for linux 2.0.33 and 2.1.95 ! 32: * Major reliability improvement: when a batch with overlapping ! 33: * requests is detected, requests are queued one at a time ! 34: * eliminating any possible board or drive reordering. ! 35: * ! 36: * 10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95 ! 37: * Improved SMP support (if linux version >= 2.1.95). ! 38: * ! 39: * 9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94 ! 40: * Performance improvement: when sequential i/o is detected, ! 41: * always use direct sort instead of reverse sort. ! 42: * ! 43: * 4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92 ! 44: * io_port is now unsigned long. ! 45: * ! 46: * 17 Mar 1998 rev. 4.01 for linux 2.0.33 and 2.1.88 ! 47: * Use new scsi error handling code (if linux version >= 2.1.88). ! 48: * Use new interrupt code. ! 49: * ! 50: * 12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55 ! 51: * Use of udelay inside the wait loops to avoid timeout ! 52: * problems with fast cpus. ! 53: * Removed check about useless calls to the interrupt service ! 54: * routine (reported on SMP systems only). ! 55: * At initialization time "sorted/unsorted" is displayed instead ! 56: * of "linked/unlinked" to reinforce the fact that "linking" is ! 57: * nothing but "elevator sorting" in the actual implementation. ! 58: * ! 59: * 17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38 ! 60: * Use of serial_number_at_timeout in abort and reset processing. ! 61: * Use of the __initfunc and __initdata macro in setup code. ! 62: * Minor cleanups in the list_statistics code. ! 63: * ! 64: * 24 Feb 1997 rev. 3.00 for linux 2.0.29 and 2.1.26 ! 65: * When loading as a module, parameter passing is now supported ! 66: * both in 2.0 and in 2.1 style. ! 67: * Fixed data transfer direction for some SCSI opcodes. ! 68: * Immediate acknowledge to request sense commands. ! 69: * Linked commands to each disk device are now reordered by elevator ! 70: * sorting. Rare cases in which reordering of write requests could ! 71: * cause wrong results are managed. ! 72: * ! 73: * 18 Jan 1997 rev. 2.60 for linux 2.1.21 and 2.0.28 ! 74: * Added command line options to enable/disable linked commands ! 75: * (lc:[y|n]), old firmware support (of:[y|n]) and to set the max ! 76: * queue depth (mq:xx). Default is "u14-34f=lc:n,of:n,mq:8". ! 77: * Improved command linking. ! 78: * ! 79: * 8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27 ! 80: * Added linked command support. ! 81: * ! 82: * 3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27 ! 83: * Added queue depth adjustment. ! 84: * ! 85: * 22 Nov 1996 rev. 2.30 for linux 2.1.12 and 2.0.26 ! 86: * The list of i/o ports to be probed can be overwritten by the ! 87: * "u14-34f=port0,port1,...." boot command line option. ! 88: * Scatter/gather lists are now allocated by a number of kmalloc ! 89: * calls, in order to avoid the previous size limit of 64Kb. ! 90: * ! 91: * 16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25 ! 92: * Added multichannel support. ! 93: * ! 94: * 27 Sep 1996 rev. 2.12 for linux 2.1.0 ! 95: * Portability cleanups (virtual/bus addressing, little/big endian ! 96: * support). ! 97: * ! 98: * 09 Jul 1996 rev. 2.11 for linux 2.0.4 ! 99: * "Data over/under-run" no longer implies a redo on all targets. ! 100: * Number of internal retries is now limited. ! 101: * ! 102: * 16 Apr 1996 rev. 2.10 for linux 1.3.90 ! 103: * New argument "reset_flags" to the reset routine. ! 104: * ! 105: * 21 Jul 1995 rev. 2.02 for linux 1.3.11 ! 106: * Fixed Data Transfer Direction for some SCSI commands. ! 107: * ! 108: * 13 Jun 1995 rev. 2.01 for linux 1.2.10 ! 109: * HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when ! 110: * the firmware prom is not the latest one (28008-006). ! 111: * ! 112: * 11 Mar 1995 rev. 2.00 for linux 1.2.0 ! 113: * Fixed a bug which prevented media change detection for removable ! 114: * disk drives. ! 115: * ! 116: * 23 Feb 1995 rev. 1.18 for linux 1.1.94 ! 117: * Added a check for scsi_register returning NULL. ! 118: * ! 119: * 11 Feb 1995 rev. 1.17 for linux 1.1.91 ! 120: * U14F qualified to run with 32 sglists. ! 121: * Now DEBUG_RESET is disabled by default. ! 122: * ! 123: * 9 Feb 1995 rev. 1.16 for linux 1.1.90 ! 124: * Use host->wish_block instead of host->block. ! 125: * ! 126: * 8 Feb 1995 rev. 1.15 for linux 1.1.89 ! 127: * Cleared target_time_out counter while performing a reset. ! 128: * ! 129: * 28 Jan 1995 rev. 1.14 for linux 1.1.86 ! 130: * Added module support. ! 131: * Log and do a retry when a disk drive returns a target status ! 132: * different from zero on a recovered error. ! 133: * Auto detects if U14F boards have an old firmware revision. ! 134: * Max number of scatter/gather lists set to 16 for all boards ! 135: * (most installation run fine using 33 sglists, while other ! 136: * has problems when using more then 16). ! 137: * ! 138: * 16 Jan 1995 rev. 1.13 for linux 1.1.81 ! 139: * Display a message if check_region detects a port address ! 140: * already in use. ! 141: * ! 142: * 15 Dec 1994 rev. 1.12 for linux 1.1.74 ! 143: * The host->block flag is set for all the detected ISA boards. ! 144: * ! 145: * 30 Nov 1994 rev. 1.11 for linux 1.1.68 ! 146: * Redo i/o on target status CHECK_CONDITION for TYPE_DISK only. ! 147: * Added optional support for using a single board at a time. ! 148: * ! 149: * 14 Nov 1994 rev. 1.10 for linux 1.1.63 ! 150: * ! 151: * 28 Oct 1994 rev. 1.09 for linux 1.1.58 Final BETA release. ! 152: * 16 Jul 1994 rev. 1.00 for linux 1.1.29 Initial ALPHA release. ! 153: * ! 154: * This driver is a total replacement of the original UltraStor ! 155: * scsi driver, but it supports ONLY the 14F and 34F boards. ! 156: * It can be configured in the same kernel in which the original ! 157: * ultrastor driver is configured to allow the original U24F ! 158: * support. ! 159: * ! 160: * Multiple U14F and/or U34F host adapters are supported. ! 161: * ! 162: * Copyright (C) 1994-1998 Dario Ballabio ([email protected]) ! 163: * ! 164: * Redistribution and use in source and binary forms, with or without ! 165: * modification, are permitted provided that redistributions of source ! 166: * code retain the above copyright notice and this comment without ! 167: * modification. ! 168: * ! 169: * WARNING: if your 14/34F board has an old firmware revision (see below) ! 170: * you must change "#undef" into "#define" in the following ! 171: * statement. ! 172: */ ! 173: #undef HAVE_OLD_UX4F_FIRMWARE ! 174: /* ! 175: * The UltraStor 14F, 24F, and 34F are a family of intelligent, high ! 176: * performance SCSI-2 host adapters. ! 177: * Here is the scoop on the various models: ! 178: * ! 179: * 14F - ISA first-party DMA HA with floppy support and WD1003 emulation. ! 180: * 24F - EISA Bus Master HA with floppy support and WD1003 emulation. ! 181: * 34F - VESA Local-Bus Bus Master HA (no WD1003 emulation). ! 182: * ! 183: * This code has been tested with up to two U14F boards, using both ! 184: * firmware 28004-005/38004-004 (BIOS rev. 2.00) and the latest firmware ! 185: * 28004-006/38004-005 (BIOS rev. 2.01). ! 186: * ! 187: * The latest firmware is required in order to get reliable operations when ! 188: * clustering is enabled. ENABLE_CLUSTERING provides a performance increase ! 189: * up to 50% on sequential access. ! 190: * ! 191: * Since the Scsi_Host_Template structure is shared among all 14F and 34F, ! 192: * the last setting of use_clustering is in effect for all of these boards. ! 193: * ! 194: * Here a sample configuration using two U14F boards: ! 195: * ! 196: U14F0: ISA 0x330, BIOS 0xc8000, IRQ 11, DMA 5, SG 32, MB 16, of:n, lc:y, mq:8. ! 197: U14F1: ISA 0x340, BIOS 0x00000, IRQ 10, DMA 6, SG 32, MB 16, of:n, lc:y, mq:8. ! 198: * ! 199: * The boot controller must have its BIOS enabled, while other boards can ! 200: * have their BIOS disabled, or enabled to an higher address. ! 201: * Boards are named Ux4F0, Ux4F1..., according to the port address order in ! 202: * the io_port[] array. ! 203: * ! 204: * The following facts are based on real testing results (not on ! 205: * documentation) on the above U14F board. ! 206: * ! 207: * - The U14F board should be jumpered for bus on time less or equal to 7 ! 208: * microseconds, while the default is 11 microseconds. This is order to ! 209: * get acceptable performance while using floppy drive and hard disk ! 210: * together. The jumpering for 7 microseconds is: JP13 pin 15-16, ! 211: * JP14 pin 7-8 and pin 9-10. ! 212: * The reduction has a little impact on scsi performance. ! 213: * ! 214: * - If scsi bus length exceeds 3m., the scsi bus speed needs to be reduced ! 215: * from 10Mhz to 5Mhz (do this by inserting a jumper on JP13 pin 7-8). ! 216: * ! 217: * - If U14F on board firmware is older than 28004-006/38004-005, ! 218: * the U14F board is unable to provide reliable operations if the scsi ! 219: * request length exceeds 16Kbyte. When this length is exceeded the ! 220: * behavior is: ! 221: * - adapter_status equal 0x96 or 0xa3 or 0x93 or 0x94; ! 222: * - adapter_status equal 0 and target_status equal 2 on for all targets ! 223: * in the next operation following the reset. ! 224: * This sequence takes a long time (>3 seconds), so in the meantime ! 225: * the SD_TIMEOUT in sd.c could expire giving rise to scsi aborts ! 226: * (SD_TIMEOUT has been increased from 3 to 6 seconds in 1.1.31). ! 227: * Because of this I had to DISABLE_CLUSTERING and to work around the ! 228: * bus reset in the interrupt service routine, returning DID_BUS_BUSY ! 229: * so that the operations are retried without complains from the scsi.c ! 230: * code. ! 231: * Any reset of the scsi bus is going to kill tape operations, since ! 232: * no retry is allowed for tapes. Bus resets are more likely when the ! 233: * scsi bus is under heavy load. ! 234: * Requests using scatter/gather have a maximum length of 16 x 1024 bytes ! 235: * when DISABLE_CLUSTERING is in effect, but unscattered requests could be ! 236: * larger than 16Kbyte. ! 237: * ! 238: * The new firmware has fixed all the above problems. ! 239: * ! 240: * For U34F boards the latest bios prom is 38008-002 (BIOS rev. 2.01), ! 241: * the latest firmware prom is 28008-006. Older firmware 28008-005 has ! 242: * problems when using more then 16 scatter/gather lists. ! 243: * ! 244: * The list of i/o ports to be probed can be totally replaced by the ! 245: * boot command line option: "u14-34f=port0,port1,port2,...", where the ! 246: * port0, port1... arguments are ISA/VESA addresses to be probed. ! 247: * For example using "u14-34f=0x230,0x340", the driver probes only the two ! 248: * addresses 0x230 and 0x340 in this order; "u14-34f=0" totally disables ! 249: * this driver. ! 250: * ! 251: * After the optional list of detection probes, other possible command line ! 252: * options are: ! 253: * ! 254: * eh:y use new scsi code (linux 2.2 only); ! 255: * eh:n use old scsi code; ! 256: * et:y use disk geometry returned by scsicam_bios_param; ! 257: * et:n use disk geometry jumpered on the board; ! 258: * lc:y enables linked commands; ! 259: * lc:n disables linked commands; ! 260: * of:y enables old firmware support; ! 261: * of:n disables old firmware support; ! 262: * mq:xx set the max queue depth to the value xx (2 <= xx <= 8). ! 263: * ! 264: * The default value is: "u14-34f=lc:n,of:n,mq:8,et:n". ! 265: * An example using the list of detection probes could be: ! 266: * "u14-34f=0x230,0x340,lc:y,of:n,mq:4,eh:n,et:n". ! 267: * ! 268: * When loading as a module, parameters can be specified as well. ! 269: * The above example would be (use 1 in place of y and 0 in place of n): ! 270: * ! 271: * modprobe u14-34f io_port=0x230,0x340 linked_comm=1 have_old_firmware=0 \ ! 272: * max_queue_depth=4 use_new_eh_code=0 ext_tran=0 ! 273: * ! 274: * ---------------------------------------------------------------------------- ! 275: * In this implementation, linked commands are designed to work with any DISK ! 276: * or CD-ROM, since this linking has only the intent of clustering (time-wise) ! 277: * and reordering by elevator sorting commands directed to each device, ! 278: * without any relation with the actual SCSI protocol between the controller ! 279: * and the device. ! 280: * If Q is the queue depth reported at boot time for each device (also named ! 281: * cmds/lun) and Q > 2, whenever there is already an active command to the ! 282: * device all other commands to the same device (up to Q-1) are kept waiting ! 283: * in the elevator sorting queue. When the active command completes, the ! 284: * commands in this queue are sorted by sector address. The sort is chosen ! 285: * between increasing or decreasing by minimizing the seek distance between ! 286: * the sector of the commands just completed and the sector of the first ! 287: * command in the list to be sorted. ! 288: * Trivial math assures that the unsorted average seek distance when doing ! 289: * random seeks over S sectors is S/3. ! 290: * When (Q-1) requests are uniformly distributed over S sectors, the average ! 291: * distance between two adjacent requests is S/((Q-1) + 1), so the sorted ! 292: * average seek distance for (Q-1) random requests over S sectors is S/Q. ! 293: * The elevator sorting hence divides the seek distance by a factor Q/3. ! 294: * The above pure geometric remarks are valid in all cases and the ! 295: * driver effectively reduces the seek distance by the predicted factor ! 296: * when there are Q concurrent read i/o operations on the device, but this ! 297: * does not necessarily results in a noticeable performance improvement: ! 298: * your mileage may vary.... ! 299: * ! 300: * Note: command reordering inside a batch of queued commands could cause ! 301: * wrong results only if there is at least one write request and the ! 302: * intersection (sector-wise) of all requests is not empty. ! 303: * When the driver detects a batch including overlapping requests ! 304: * (a really rare event) strict serial (pid) order is enforced. ! 305: * ---------------------------------------------------------------------------- ! 306: * ! 307: * The boards are named Ux4F0, Ux4F1,... according to the detection order. ! 308: * ! 309: * In order to support multiple ISA boards in a reliable way, ! 310: * the driver sets host->wish_block = TRUE for all ISA boards. ! 311: */ ! 312: ! 313: #include <linux/version.h> ! 314: ! 315: #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) ! 316: #define MAX_INT_PARAM 10 ! 317: ! 318: #if defined(MODULE) ! 319: #include <linux/module.h> ! 320: ! 321: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26) ! 322: MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i"); ! 323: MODULE_PARM(linked_comm, "i"); ! 324: MODULE_PARM(have_old_firmware, "i"); ! 325: MODULE_PARM(link_statistics, "i"); ! 326: MODULE_PARM(max_queue_depth, "i"); ! 327: MODULE_PARM(use_new_eh_code, "i"); ! 328: MODULE_PARM(ext_tran, "i"); ! 329: MODULE_AUTHOR("Dario Ballabio"); ! 330: #endif ! 331: ! 332: #endif ! 333: ! 334: #include <linux/string.h> ! 335: #include <linux/sched.h> ! 336: #include <linux/kernel.h> ! 337: #include <linux/ioport.h> ! 338: #include <linux/delay.h> ! 339: #include <asm/io.h> ! 340: #include <asm/system.h> ! 341: #include <asm/byteorder.h> ! 342: #include <linux/proc_fs.h> ! 343: #include <linux/blk.h> ! 344: #include "scsi.h" ! 345: #include "hosts.h" ! 346: #include "sd.h" ! 347: #include <asm/dma.h> ! 348: #include <asm/irq.h> ! 349: #include "u14-34f.h" ! 350: #include <linux/stat.h> ! 351: #include <linux/config.h> ! 352: ! 353: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,36) ! 354: #include <linux/init.h> ! 355: #else ! 356: #define __initfunc(A) A ! 357: #define __initdata ! 358: #define __init ! 359: #endif ! 360: ! 361: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) ! 362: #include <asm/spinlock.h> ! 363: #define IRQ_FLAGS ! 364: #define IRQ_LOCK ! 365: #define IRQ_LOCK_SAVE ! 366: #define IRQ_UNLOCK ! 367: #define IRQ_UNLOCK_RESTORE ! 368: #define SPIN_FLAGS unsigned long spin_flags; ! 369: #define SPIN_LOCK spin_lock_irq(&io_request_lock); ! 370: #define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags); ! 371: #define SPIN_UNLOCK spin_unlock_irq(&io_request_lock); ! 372: #define SPIN_UNLOCK_RESTORE \ ! 373: spin_unlock_irqrestore(&io_request_lock, spin_flags); ! 374: static int use_new_eh_code = TRUE; ! 375: #else ! 376: #define IRQ_FLAGS unsigned long irq_flags; ! 377: #define IRQ_LOCK cli(); ! 378: #define IRQ_LOCK_SAVE do {save_flags(irq_flags); cli();} while (0); ! 379: #define IRQ_UNLOCK sti(); ! 380: #define IRQ_UNLOCK_RESTORE do {restore_flags(irq_flags);} while (0); ! 381: #define SPIN_FLAGS ! 382: #define SPIN_LOCK ! 383: #define SPIN_LOCK_SAVE ! 384: #define SPIN_UNLOCK ! 385: #define SPIN_UNLOCK_RESTORE ! 386: static int use_new_eh_code = FALSE; ! 387: #endif ! 388: ! 389: struct proc_dir_entry proc_scsi_u14_34f = { ! 390: PROC_SCSI_U14_34F, 6, "u14_34f", ! 391: S_IFDIR | S_IRUGO | S_IXUGO, 2 ! 392: }; ! 393: ! 394: /* Values for the PRODUCT_ID ports for the 14/34F */ ! 395: #define PRODUCT_ID1 0x56 ! 396: #define PRODUCT_ID2 0x40 /* NOTE: Only upper nibble is used */ ! 397: ! 398: /* Subversion values */ ! 399: #define ISA 0 ! 400: #define ESA 1 ! 401: ! 402: #define OP_HOST_ADAPTER 0x1 ! 403: #define OP_SCSI 0x2 ! 404: #define OP_RESET 0x4 ! 405: #define DTD_SCSI 0x0 ! 406: #define DTD_IN 0x1 ! 407: #define DTD_OUT 0x2 ! 408: #define DTD_NONE 0x3 ! 409: #define HA_CMD_INQUIRY 0x1 ! 410: #define HA_CMD_SELF_DIAG 0x2 ! 411: #define HA_CMD_READ_BUFF 0x3 ! 412: #define HA_CMD_WRITE_BUFF 0x4 ! 413: ! 414: #undef DEBUG_LINKED_COMMANDS ! 415: #undef DEBUG_DETECT ! 416: #undef DEBUG_INTERRUPT ! 417: #undef DEBUG_RESET ! 418: #undef DEBUG_GENERATE_ERRORS ! 419: #undef DEBUG_GENERATE_ABORTS ! 420: #undef DEBUG_GEOMETRY ! 421: ! 422: #define MAX_ISA 3 ! 423: #define MAX_VESA 1 ! 424: #define MAX_EISA 0 ! 425: #define MAX_PCI 0 ! 426: #define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI) ! 427: #define MAX_CHANNEL 1 ! 428: #define MAX_LUN 8 ! 429: #define MAX_TARGET 8 ! 430: #define MAX_MAILBOXES 16 ! 431: #define MAX_SGLIST 32 ! 432: #define MAX_SAFE_SGLIST 16 ! 433: #define MAX_INTERNAL_RETRIES 64 ! 434: #define MAX_CMD_PER_LUN 2 ! 435: #define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN) ! 436: ! 437: #define SKIP ULONG_MAX ! 438: #define FALSE 0 ! 439: #define TRUE 1 ! 440: #define FREE 0 ! 441: #define IN_USE 1 ! 442: #define LOCKED 2 ! 443: #define IN_RESET 3 ! 444: #define IGNORE 4 ! 445: #define READY 5 ! 446: #define ABORTING 6 ! 447: #define NO_DMA 0xff ! 448: #define MAXLOOP 10000 ! 449: ! 450: #define REG_LCL_MASK 0 ! 451: #define REG_LCL_INTR 1 ! 452: #define REG_SYS_MASK 2 ! 453: #define REG_SYS_INTR 3 ! 454: #define REG_PRODUCT_ID1 4 ! 455: #define REG_PRODUCT_ID2 5 ! 456: #define REG_CONFIG1 6 ! 457: #define REG_CONFIG2 7 ! 458: #define REG_OGM 8 ! 459: #define REG_ICM 12 ! 460: #define REGION_SIZE 13 ! 461: #define BSY_ASSERTED 0x01 ! 462: #define IRQ_ASSERTED 0x01 ! 463: #define CMD_RESET 0xc0 ! 464: #define CMD_OGM_INTR 0x01 ! 465: #define CMD_CLR_INTR 0x01 ! 466: #define CMD_ENA_INTR 0x81 ! 467: #define ASOK 0x00 ! 468: #define ASST 0x91 ! 469: ! 470: #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0]) ! 471: #define YESNO(a) ((a) ? 'y' : 'n') ! 472: #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) ! 473: ! 474: #define PACKED __attribute__((packed)) ! 475: ! 476: struct sg_list { ! 477: unsigned int address; /* Segment Address */ ! 478: unsigned int num_bytes; /* Segment Length */ ! 479: }; ! 480: ! 481: /* MailBox SCSI Command Packet */ ! 482: struct mscp { ! 483: unsigned char opcode: 3; /* type of command */ ! 484: unsigned char xdir: 2; /* data transfer direction */ ! 485: unsigned char dcn: 1; /* disable disconnect */ ! 486: unsigned char ca: 1; /* use cache (if available) */ ! 487: unsigned char sg: 1; /* scatter/gather operation */ ! 488: unsigned char target: 3; /* SCSI target id */ ! 489: unsigned char channel: 2; /* SCSI channel number */ ! 490: unsigned char lun: 3; /* SCSI logical unit number */ ! 491: unsigned int data_address PACKED; /* transfer data pointer */ ! 492: unsigned int data_len PACKED; /* length in bytes */ ! 493: unsigned int link_address PACKED; /* for linking command chains */ ! 494: unsigned char clink_id; /* identifies command in chain */ ! 495: unsigned char use_sg; /* (if sg is set) 8 bytes per list */ ! 496: unsigned char sense_len; ! 497: unsigned char scsi_cdbs_len; /* 6, 10, or 12 */ ! 498: unsigned char scsi_cdbs[12]; /* SCSI commands */ ! 499: unsigned char adapter_status; /* non-zero indicates HA error */ ! 500: unsigned char target_status; /* non-zero indicates target error */ ! 501: unsigned int sense_addr PACKED; ! 502: Scsi_Cmnd *SCpnt; ! 503: unsigned int index; /* cp index */ ! 504: struct sg_list *sglist; ! 505: }; ! 506: ! 507: struct hostdata { ! 508: struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */ ! 509: unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */ ! 510: unsigned int last_cp_used; /* Index of last mailbox used */ ! 511: unsigned int iocount; /* Total i/o done for this board */ ! 512: int board_number; /* Number of this board */ ! 513: char board_name[16]; /* Name of this board */ ! 514: char board_id[256]; /* data from INQUIRY on this board */ ! 515: int in_reset; /* True if board is doing a reset */ ! 516: int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */ ! 517: int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */ ! 518: unsigned int retries; /* Number of internal retries */ ! 519: unsigned long last_retried_pid; /* Pid of last retried command */ ! 520: unsigned char subversion; /* Bus type, either ISA or ESA */ ! 521: unsigned char heads; ! 522: unsigned char sectors; ! 523: ! 524: /* slot != 0 for the U24F, slot == 0 for both the U14F and U34F */ ! 525: unsigned char slot; ! 526: }; ! 527: ! 528: static struct Scsi_Host *sh[MAX_BOARDS + 1]; ! 529: static const char *driver_name = "Ux4F"; ! 530: static char sha[MAX_BOARDS]; ! 531: ! 532: /* Initialize num_boards so that ihdlr can work while detect is in progress */ ! 533: static unsigned int num_boards = MAX_BOARDS; ! 534: ! 535: static unsigned long io_port[] __initdata = { ! 536: ! 537: /* Space for MAX_INT_PARAM ports usable while loading as a module */ ! 538: SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, ! 539: SKIP, SKIP, ! 540: ! 541: /* Possible ISA/VESA ports */ ! 542: 0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140, ! 543: ! 544: /* End of list */ ! 545: 0x0 ! 546: }; ! 547: ! 548: #define HD(board) ((struct hostdata *) &sh[board]->hostdata) ! 549: #define BN(board) (HD(board)->board_name) ! 550: ! 551: #define SWAP_BYTE(x) ((unsigned long)( \ ! 552: (((unsigned long)(x) & 0x000000ffU) << 24) | \ ! 553: (((unsigned long)(x) & 0x0000ff00U) << 8) | \ ! 554: (((unsigned long)(x) & 0x00ff0000U) >> 8) | \ ! 555: (((unsigned long)(x) & 0xff000000U) >> 24))) ! 556: ! 557: #if defined(__BIG_ENDIAN) ! 558: #define H2DEV(x) SWAP_BYTE(x) ! 559: #else ! 560: #define H2DEV(x) (x) ! 561: #endif ! 562: ! 563: #define DEV2H(x) H2DEV(x) ! 564: #define V2DEV(addr) ((addr) ? H2DEV(virt_to_bus((void *)addr)) : 0) ! 565: #define DEV2V(addr) ((addr) ? DEV2H(bus_to_virt((unsigned long)addr)) : 0) ! 566: ! 567: static void do_interrupt_handler(int, void *, struct pt_regs *); ! 568: static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int); ! 569: static int do_trace = FALSE; ! 570: static int setup_done = FALSE; ! 571: static int link_statistics = 0; ! 572: static int ext_tran = FALSE; ! 573: ! 574: #if defined(HAVE_OLD_UX4F_FIRMWARE) ! 575: static int have_old_firmware = TRUE; ! 576: #else ! 577: static int have_old_firmware = FALSE; ! 578: #endif ! 579: ! 580: #if defined(CONFIG_SCSI_U14_34F_LINKED_COMMANDS) ! 581: static int linked_comm = TRUE; ! 582: #else ! 583: static int linked_comm = FALSE; ! 584: #endif ! 585: ! 586: #if defined(CONFIG_SCSI_U14_34F_MAX_TAGS) ! 587: static int max_queue_depth = CONFIG_SCSI_U14_34F_MAX_TAGS; ! 588: #else ! 589: static int max_queue_depth = MAX_CMD_PER_LUN; ! 590: #endif ! 591: ! 592: static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) { ! 593: Scsi_Device *dev; ! 594: int j, ntag = 0, nuntag = 0, tqd, utqd; ! 595: IRQ_FLAGS ! 596: ! 597: IRQ_LOCK_SAVE ! 598: j = ((struct hostdata *) host->hostdata)->board_number; ! 599: ! 600: for(dev = devlist; dev; dev = dev->next) { ! 601: ! 602: if (dev->host != host) continue; ! 603: ! 604: if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm)) ! 605: ntag++; ! 606: else ! 607: nuntag++; ! 608: } ! 609: ! 610: utqd = MAX_CMD_PER_LUN; ! 611: ! 612: tqd = (host->can_queue - utqd * nuntag) / (ntag ? ntag : 1); ! 613: ! 614: if (tqd > max_queue_depth) tqd = max_queue_depth; ! 615: ! 616: if (tqd < MAX_CMD_PER_LUN) tqd = MAX_CMD_PER_LUN; ! 617: ! 618: for(dev = devlist; dev; dev = dev->next) { ! 619: char *tag_suffix = "", *link_suffix = ""; ! 620: ! 621: if (dev->host != host) continue; ! 622: ! 623: if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm)) ! 624: dev->queue_depth = tqd; ! 625: else ! 626: dev->queue_depth = utqd; ! 627: ! 628: if (TLDEV(dev->type)) { ! 629: if (linked_comm && dev->queue_depth > 2) ! 630: link_suffix = ", sorted"; ! 631: else ! 632: link_suffix = ", unsorted"; ! 633: } ! 634: ! 635: if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue) ! 636: tag_suffix = ", tagged"; ! 637: else if (dev->tagged_supported && TLDEV(dev->type)) ! 638: tag_suffix = ", untagged"; ! 639: ! 640: printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n", ! 641: BN(j), host->host_no, dev->channel, dev->id, dev->lun, ! 642: dev->queue_depth, link_suffix, tag_suffix); ! 643: } ! 644: ! 645: IRQ_UNLOCK_RESTORE ! 646: return; ! 647: } ! 648: ! 649: static inline int wait_on_busy(unsigned long iobase, unsigned int loop) { ! 650: ! 651: while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED) { ! 652: udelay(1L); ! 653: if (--loop == 0) return TRUE; ! 654: } ! 655: ! 656: return FALSE; ! 657: } ! 658: ! 659: static int board_inquiry(unsigned int j) { ! 660: struct mscp *cpp; ! 661: unsigned int time, limit = 0; ! 662: ! 663: cpp = &HD(j)->cp[0]; ! 664: memset(cpp, 0, sizeof(struct mscp)); ! 665: cpp->opcode = OP_HOST_ADAPTER; ! 666: cpp->xdir = DTD_IN; ! 667: cpp->data_address = V2DEV(HD(j)->board_id); ! 668: cpp->data_len = H2DEV(sizeof(HD(j)->board_id)); ! 669: cpp->scsi_cdbs_len = 6; ! 670: cpp->scsi_cdbs[0] = HA_CMD_INQUIRY; ! 671: ! 672: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 673: printk("%s: board_inquiry, adapter busy.\n", BN(j)); ! 674: return TRUE; ! 675: } ! 676: ! 677: HD(j)->cp_stat[0] = IGNORE; ! 678: ! 679: /* Clear the interrupt indication */ ! 680: outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR); ! 681: ! 682: /* Store pointer in OGM address bytes */ ! 683: outl(V2DEV(cpp), sh[j]->io_port + REG_OGM); ! 684: ! 685: /* Issue OGM interrupt */ ! 686: outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR); ! 687: ! 688: SPIN_UNLOCK ! 689: IRQ_UNLOCK ! 690: time = jiffies; ! 691: while ((jiffies - time) < HZ && limit++ < 20000) udelay(100L); ! 692: IRQ_LOCK ! 693: SPIN_LOCK ! 694: ! 695: if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) { ! 696: HD(j)->cp_stat[0] = FREE; ! 697: printk("%s: board_inquiry, err 0x%x.\n", BN(j), cpp->adapter_status); ! 698: return TRUE; ! 699: } ! 700: ! 701: return FALSE; ! 702: } ! 703: ! 704: __initfunc (static inline int port_detect \ ! 705: (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt)) { ! 706: unsigned char irq, dma_channel, subversion, i; ! 707: unsigned char in_byte; ! 708: char *bus_type, dma_name[16]; ! 709: ! 710: /* Allowed BIOS base addresses (NULL indicates reserved) */ ! 711: void *bios_segment_table[8] = { ! 712: NULL, ! 713: (void *) 0xc4000, (void *) 0xc8000, (void *) 0xcc000, (void *) 0xd0000, ! 714: (void *) 0xd4000, (void *) 0xd8000, (void *) 0xdc000 ! 715: }; ! 716: ! 717: /* Allowed IRQs */ ! 718: unsigned char interrupt_table[4] = { 15, 14, 11, 10 }; ! 719: ! 720: /* Allowed DMA channels for ISA (0 indicates reserved) */ ! 721: unsigned char dma_channel_table[4] = { 5, 6, 7, 0 }; ! 722: ! 723: /* Head/sector mappings */ ! 724: struct { ! 725: unsigned char heads; ! 726: unsigned char sectors; ! 727: } mapping_table[4] = { ! 728: { 16, 63 }, { 64, 32 }, { 64, 63 }, { 64, 32 } ! 729: }; ! 730: ! 731: struct config_1 { ! 732: unsigned char bios_segment: 3; ! 733: unsigned char removable_disks_as_fixed: 1; ! 734: unsigned char interrupt: 2; ! 735: unsigned char dma_channel: 2; ! 736: } config_1; ! 737: ! 738: struct config_2 { ! 739: unsigned char ha_scsi_id: 3; ! 740: unsigned char mapping_mode: 2; ! 741: unsigned char bios_drive_number: 1; ! 742: unsigned char tfr_port: 2; ! 743: } config_2; ! 744: ! 745: char name[16]; ! 746: ! 747: sprintf(name, "%s%d", driver_name, j); ! 748: ! 749: if(check_region(port_base, REGION_SIZE)) { ! 750: printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base); ! 751: return FALSE; ! 752: } ! 753: ! 754: if (inb(port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) return FALSE; ! 755: ! 756: in_byte = inb(port_base + REG_PRODUCT_ID2); ! 757: ! 758: if ((in_byte & 0xf0) != PRODUCT_ID2) return FALSE; ! 759: ! 760: *(char *)&config_1 = inb(port_base + REG_CONFIG1); ! 761: *(char *)&config_2 = inb(port_base + REG_CONFIG2); ! 762: ! 763: irq = interrupt_table[config_1.interrupt]; ! 764: dma_channel = dma_channel_table[config_1.dma_channel]; ! 765: subversion = (in_byte & 0x0f); ! 766: ! 767: /* Board detected, allocate its IRQ */ ! 768: if (request_irq(irq, do_interrupt_handler, ! 769: SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0), ! 770: driver_name, (void *) &sha[j])) { ! 771: printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq); ! 772: return FALSE; ! 773: } ! 774: ! 775: if (subversion == ISA && request_dma(dma_channel, driver_name)) { ! 776: printk("%s: unable to allocate DMA channel %u, detaching.\n", ! 777: name, dma_channel); ! 778: free_irq(irq, &sha[j]); ! 779: return FALSE; ! 780: } ! 781: ! 782: if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING; ! 783: ! 784: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) ! 785: tpnt->use_new_eh_code = use_new_eh_code; ! 786: #else ! 787: use_new_eh_code = FALSE; ! 788: #endif ! 789: ! 790: sh[j] = scsi_register(tpnt, sizeof(struct hostdata)); ! 791: ! 792: if (sh[j] == NULL) { ! 793: printk("%s: unable to register host, detaching.\n", name); ! 794: ! 795: free_irq(irq, &sha[j]); ! 796: ! 797: if (subversion == ISA) free_dma(dma_channel); ! 798: ! 799: return FALSE; ! 800: } ! 801: ! 802: sh[j]->io_port = port_base; ! 803: sh[j]->unique_id = port_base; ! 804: sh[j]->n_io_port = REGION_SIZE; ! 805: sh[j]->base = bios_segment_table[config_1.bios_segment]; ! 806: sh[j]->irq = irq; ! 807: sh[j]->sg_tablesize = MAX_SGLIST; ! 808: sh[j]->this_id = config_2.ha_scsi_id; ! 809: sh[j]->can_queue = MAX_MAILBOXES; ! 810: sh[j]->cmd_per_lun = MAX_CMD_PER_LUN; ! 811: sh[j]->select_queue_depths = select_queue_depths; ! 812: ! 813: #if defined(DEBUG_DETECT) ! 814: { ! 815: unsigned char sys_mask, lcl_mask; ! 816: ! 817: sys_mask = inb(sh[j]->io_port + REG_SYS_MASK); ! 818: lcl_mask = inb(sh[j]->io_port + REG_LCL_MASK); ! 819: printk("SYS_MASK 0x%x, LCL_MASK 0x%x.\n", sys_mask, lcl_mask); ! 820: } ! 821: #endif ! 822: ! 823: /* Probably a bogus host scsi id, set it to the dummy value */ ! 824: if (sh[j]->this_id == 0) sh[j]->this_id = -1; ! 825: ! 826: /* If BIOS is disabled, force enable interrupts */ ! 827: if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK); ! 828: ! 829: /* Register the I/O space that we use */ ! 830: request_region(sh[j]->io_port, sh[j]->n_io_port, driver_name); ! 831: ! 832: memset(HD(j), 0, sizeof(struct hostdata)); ! 833: HD(j)->heads = mapping_table[config_2.mapping_mode].heads; ! 834: HD(j)->sectors = mapping_table[config_2.mapping_mode].sectors; ! 835: HD(j)->subversion = subversion; ! 836: HD(j)->board_number = j; ! 837: ! 838: if (have_old_firmware) sh[j]->sg_tablesize = MAX_SAFE_SGLIST; ! 839: ! 840: if (HD(j)->subversion == ESA) { ! 841: sh[j]->unchecked_isa_dma = FALSE; ! 842: sh[j]->dma_channel = NO_DMA; ! 843: sprintf(BN(j), "U34F%d", j); ! 844: bus_type = "VESA"; ! 845: } ! 846: else { ! 847: sh[j]->wish_block = TRUE; ! 848: sh[j]->unchecked_isa_dma = TRUE; ! 849: disable_dma(dma_channel); ! 850: clear_dma_ff(dma_channel); ! 851: set_dma_mode(dma_channel, DMA_MODE_CASCADE); ! 852: enable_dma(dma_channel); ! 853: sh[j]->dma_channel = dma_channel; ! 854: sprintf(BN(j), "U14F%d", j); ! 855: bus_type = "ISA"; ! 856: } ! 857: ! 858: sh[j]->max_channel = MAX_CHANNEL - 1; ! 859: sh[j]->max_id = MAX_TARGET; ! 860: sh[j]->max_lun = MAX_LUN; ! 861: ! 862: if (HD(j)->subversion == ISA && !board_inquiry(j)) { ! 863: HD(j)->board_id[40] = 0; ! 864: ! 865: if (strcmp(&HD(j)->board_id[32], "06000600")) { ! 866: printk("%s: %s.\n", BN(j), &HD(j)->board_id[8]); ! 867: printk("%s: firmware %s is outdated, FW PROM should be 28004-006.\n", ! 868: BN(j), &HD(j)->board_id[32]); ! 869: sh[j]->hostt->use_clustering = DISABLE_CLUSTERING; ! 870: sh[j]->sg_tablesize = MAX_SAFE_SGLIST; ! 871: } ! 872: } ! 873: ! 874: if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST"); ! 875: else sprintf(dma_name, "DMA %u", dma_channel); ! 876: ! 877: for (i = 0; i < sh[j]->can_queue; i++) ! 878: if (! ((&HD(j)->cp[i])->sglist = kmalloc( ! 879: sh[j]->sg_tablesize * sizeof(struct sg_list), ! 880: (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) { ! 881: printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i); ! 882: u14_34f_release(sh[j]); ! 883: return FALSE; ! 884: } ! 885: ! 886: if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) ! 887: max_queue_depth = MAX_TAGGED_CMD_PER_LUN; ! 888: ! 889: if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN; ! 890: ! 891: if (j == 0) { ! 892: printk("UltraStor 14F/34F: Copyright (C) 1994-1998 Dario Ballabio.\n"); ! 893: printk("%s config options -> of:%c, lc:%c, mq:%d, eh:%c, et:%c.\n", ! 894: driver_name, YESNO(have_old_firmware), YESNO(linked_comm), ! 895: max_queue_depth, YESNO(use_new_eh_code), YESNO(ext_tran)); ! 896: } ! 897: ! 898: printk("%s: %s 0x%03lx, BIOS 0x%05x, IRQ %u, %s, SG %d, MB %d.\n", ! 899: BN(j), bus_type, (unsigned long)sh[j]->io_port, (int)sh[j]->base, ! 900: sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue); ! 901: ! 902: if (sh[j]->max_id > 8 || sh[j]->max_lun > 8) ! 903: printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n", ! 904: BN(j), sh[j]->max_id, sh[j]->max_lun); ! 905: ! 906: for (i = 0; i <= sh[j]->max_channel; i++) ! 907: printk("%s: SCSI channel %u enabled, host target ID %d.\n", ! 908: BN(j), i, sh[j]->this_id); ! 909: ! 910: return TRUE; ! 911: } ! 912: ! 913: __initfunc (void u14_34f_setup(char *str, int *ints)) { ! 914: int i, argc = ints[0]; ! 915: char *cur = str, *pc; ! 916: ! 917: if (argc > 0) { ! 918: ! 919: if (argc > MAX_INT_PARAM) argc = MAX_INT_PARAM; ! 920: ! 921: for (i = 0; i < argc; i++) io_port[i] = ints[i + 1]; ! 922: ! 923: io_port[i] = 0; ! 924: setup_done = TRUE; ! 925: } ! 926: ! 927: while (cur && (pc = strchr(cur, ':'))) { ! 928: int val = 0, c = *++pc; ! 929: ! 930: if (c == 'n' || c == 'N') val = FALSE; ! 931: else if (c == 'y' || c == 'Y') val = TRUE; ! 932: else val = (int) simple_strtoul(pc, NULL, 0); ! 933: ! 934: if (!strncmp(cur, "lc:", 3)) linked_comm = val; ! 935: else if (!strncmp(cur, "of:", 3)) have_old_firmware = val; ! 936: else if (!strncmp(cur, "mq:", 3)) max_queue_depth = val; ! 937: else if (!strncmp(cur, "ls:", 3)) link_statistics = val; ! 938: else if (!strncmp(cur, "eh:", 3)) use_new_eh_code = val; ! 939: else if (!strncmp(cur, "et:", 3)) ext_tran = val; ! 940: ! 941: if ((cur = strchr(cur, ','))) ++cur; ! 942: } ! 943: ! 944: return; ! 945: } ! 946: ! 947: __initfunc (int u14_34f_detect(Scsi_Host_Template *tpnt)) { ! 948: unsigned int j = 0, k; ! 949: IRQ_FLAGS ! 950: ! 951: IRQ_LOCK_SAVE ! 952: tpnt->proc_dir = &proc_scsi_u14_34f; ! 953: ! 954: #if defined(MODULE) ! 955: /* io_port could have been modified when loading as a module */ ! 956: if(io_port[0] != SKIP) { ! 957: setup_done = TRUE; ! 958: io_port[MAX_INT_PARAM] = 0; ! 959: } ! 960: #endif ! 961: ! 962: for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL; ! 963: ! 964: for (k = 0; io_port[k]; k++) { ! 965: ! 966: if (io_port[k] == SKIP) continue; ! 967: ! 968: if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) j++; ! 969: } ! 970: ! 971: num_boards = j; ! 972: IRQ_UNLOCK_RESTORE ! 973: return j; ! 974: } ! 975: ! 976: static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) { ! 977: unsigned int k, data_len = 0; ! 978: struct scatterlist *sgpnt; ! 979: ! 980: sgpnt = (struct scatterlist *) SCpnt->request_buffer; ! 981: ! 982: for (k = 0; k < SCpnt->use_sg; k++) { ! 983: cpp->sglist[k].address = V2DEV(sgpnt[k].address); ! 984: cpp->sglist[k].num_bytes = H2DEV(sgpnt[k].length); ! 985: data_len += sgpnt[k].length; ! 986: } ! 987: ! 988: cpp->use_sg = SCpnt->use_sg; ! 989: cpp->data_address = V2DEV(cpp->sglist); ! 990: cpp->data_len = H2DEV(data_len); ! 991: } ! 992: ! 993: static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { ! 994: unsigned int i, j, k; ! 995: struct mscp *cpp; ! 996: ! 997: static const unsigned char data_out_cmds[] = { ! 998: 0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e, ! 999: 0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40, ! 1000: 0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b ! 1001: }; ! 1002: ! 1003: static const unsigned char data_none_cmds[] = { ! 1004: 0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e, ! 1005: 0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47, ! 1006: 0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5 ! 1007: }; ! 1008: ! 1009: /* j is the board number */ ! 1010: j = ((struct hostdata *) SCpnt->host->hostdata)->board_number; ! 1011: ! 1012: if (SCpnt->host_scribble) ! 1013: panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", ! 1014: BN(j), SCpnt->pid, SCpnt); ! 1015: ! 1016: /* i is the mailbox number, look for the first free mailbox ! 1017: starting from last_cp_used */ ! 1018: i = HD(j)->last_cp_used + 1; ! 1019: ! 1020: for (k = 0; k < sh[j]->can_queue; k++, i++) { ! 1021: ! 1022: if (i >= sh[j]->can_queue) i = 0; ! 1023: ! 1024: if (HD(j)->cp_stat[i] == FREE) { ! 1025: HD(j)->last_cp_used = i; ! 1026: break; ! 1027: } ! 1028: } ! 1029: ! 1030: if (k == sh[j]->can_queue) { ! 1031: printk("%s: qcomm, no free mailbox.\n", BN(j)); ! 1032: return 1; ! 1033: } ! 1034: ! 1035: /* Set pointer to control packet structure */ ! 1036: cpp = &HD(j)->cp[i]; ! 1037: ! 1038: memset(cpp, 0, sizeof(struct mscp) - sizeof(struct sg_list *)); ! 1039: SCpnt->scsi_done = done; ! 1040: cpp->index = i; ! 1041: SCpnt->host_scribble = (unsigned char *) &cpp->index; ! 1042: ! 1043: if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", ! 1044: BN(j), i, SCpnt->channel, SCpnt->target, ! 1045: SCpnt->lun, SCpnt->pid); ! 1046: ! 1047: cpp->xdir = DTD_IN; ! 1048: ! 1049: for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++) ! 1050: if (SCpnt->cmnd[0] == data_out_cmds[k]) { ! 1051: cpp->xdir = DTD_OUT; ! 1052: break; ! 1053: } ! 1054: ! 1055: if (cpp->xdir == DTD_IN) ! 1056: for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++) ! 1057: if (SCpnt->cmnd[0] == data_none_cmds[k]) { ! 1058: cpp->xdir = DTD_NONE; ! 1059: break; ! 1060: } ! 1061: ! 1062: cpp->opcode = OP_SCSI; ! 1063: cpp->channel = SCpnt->channel; ! 1064: cpp->target = SCpnt->target; ! 1065: cpp->lun = SCpnt->lun; ! 1066: cpp->SCpnt = SCpnt; ! 1067: cpp->sense_addr = V2DEV(SCpnt->sense_buffer); ! 1068: cpp->sense_len = sizeof SCpnt->sense_buffer; ! 1069: ! 1070: if (SCpnt->use_sg) { ! 1071: cpp->sg = TRUE; ! 1072: build_sg_list(cpp, SCpnt); ! 1073: } ! 1074: else { ! 1075: cpp->data_address = V2DEV(SCpnt->request_buffer); ! 1076: cpp->data_len = H2DEV(SCpnt->request_bufflen); ! 1077: } ! 1078: ! 1079: cpp->scsi_cdbs_len = SCpnt->cmd_len; ! 1080: memcpy(cpp->scsi_cdbs, SCpnt->cmnd, cpp->scsi_cdbs_len); ! 1081: ! 1082: if (linked_comm && SCpnt->device->queue_depth > 2 ! 1083: && TLDEV(SCpnt->device->type)) { ! 1084: HD(j)->cp_stat[i] = READY; ! 1085: flush_dev(SCpnt->device, SCpnt->request.sector, j, FALSE); ! 1086: return 0; ! 1087: } ! 1088: ! 1089: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1090: SCpnt->host_scribble = NULL; ! 1091: printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n", ! 1092: BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid); ! 1093: return 1; ! 1094: } ! 1095: ! 1096: /* Store pointer in OGM address bytes */ ! 1097: outl(V2DEV(cpp), sh[j]->io_port + REG_OGM); ! 1098: ! 1099: /* Issue OGM interrupt */ ! 1100: outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR); ! 1101: ! 1102: HD(j)->cp_stat[i] = IN_USE; ! 1103: return 0; ! 1104: } ! 1105: ! 1106: int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { ! 1107: int rtn; ! 1108: IRQ_FLAGS ! 1109: ! 1110: IRQ_LOCK_SAVE ! 1111: rtn = do_qcomm(SCpnt, done); ! 1112: IRQ_UNLOCK_RESTORE ! 1113: return rtn; ! 1114: } ! 1115: ! 1116: static inline int do_old_abort(Scsi_Cmnd *SCarg) { ! 1117: unsigned int i, j; ! 1118: ! 1119: j = ((struct hostdata *) SCarg->host->hostdata)->board_number; ! 1120: ! 1121: if (SCarg->host_scribble == NULL || ! 1122: (SCarg->serial_number_at_timeout && ! 1123: (SCarg->serial_number != SCarg->serial_number_at_timeout))) { ! 1124: printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", ! 1125: BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); ! 1126: return SCSI_ABORT_NOT_RUNNING; ! 1127: } ! 1128: ! 1129: i = *(unsigned int *)SCarg->host_scribble; ! 1130: printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", ! 1131: BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); ! 1132: ! 1133: if (i >= sh[j]->can_queue) ! 1134: panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); ! 1135: ! 1136: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1137: printk("%s: abort, timeout error.\n", BN(j)); ! 1138: return SCSI_ABORT_ERROR; ! 1139: } ! 1140: ! 1141: if (HD(j)->cp_stat[i] == FREE) { ! 1142: printk("%s: abort, mbox %d is free.\n", BN(j), i); ! 1143: return SCSI_ABORT_NOT_RUNNING; ! 1144: } ! 1145: ! 1146: if (HD(j)->cp_stat[i] == IN_USE) { ! 1147: printk("%s: abort, mbox %d is in use.\n", BN(j), i); ! 1148: ! 1149: if (SCarg != HD(j)->cp[i].SCpnt) ! 1150: panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", ! 1151: BN(j), i, SCarg, HD(j)->cp[i].SCpnt); ! 1152: ! 1153: if (inb(sh[j]->io_port + REG_SYS_INTR) & IRQ_ASSERTED) ! 1154: printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i); ! 1155: ! 1156: return SCSI_ABORT_SNOOZE; ! 1157: } ! 1158: ! 1159: if (HD(j)->cp_stat[i] == IN_RESET) { ! 1160: printk("%s: abort, mbox %d is in reset.\n", BN(j), i); ! 1161: return SCSI_ABORT_ERROR; ! 1162: } ! 1163: ! 1164: if (HD(j)->cp_stat[i] == LOCKED) { ! 1165: printk("%s: abort, mbox %d is locked.\n", BN(j), i); ! 1166: return SCSI_ABORT_NOT_RUNNING; ! 1167: } ! 1168: ! 1169: if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { ! 1170: SCarg->result = DID_ABORT << 16; ! 1171: SCarg->host_scribble = NULL; ! 1172: HD(j)->cp_stat[i] = FREE; ! 1173: printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", ! 1174: BN(j), i, SCarg->pid); ! 1175: SCarg->scsi_done(SCarg); ! 1176: return SCSI_ABORT_SUCCESS; ! 1177: } ! 1178: ! 1179: panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); ! 1180: } ! 1181: ! 1182: int u14_34f_old_abort(Scsi_Cmnd *SCarg) { ! 1183: int rtn; ! 1184: IRQ_FLAGS ! 1185: ! 1186: IRQ_LOCK_SAVE ! 1187: rtn = do_old_abort(SCarg); ! 1188: IRQ_UNLOCK_RESTORE ! 1189: return rtn; ! 1190: } ! 1191: ! 1192: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) ! 1193: ! 1194: static inline int do_abort(Scsi_Cmnd *SCarg) { ! 1195: unsigned int i, j; ! 1196: ! 1197: j = ((struct hostdata *) SCarg->host->hostdata)->board_number; ! 1198: ! 1199: if (SCarg->host_scribble == NULL) { ! 1200: printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", ! 1201: BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); ! 1202: return SUCCESS; ! 1203: } ! 1204: ! 1205: i = *(unsigned int *)SCarg->host_scribble; ! 1206: printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", ! 1207: BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); ! 1208: ! 1209: if (i >= sh[j]->can_queue) ! 1210: panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); ! 1211: ! 1212: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1213: printk("%s: abort, timeout error.\n", BN(j)); ! 1214: return FAILED; ! 1215: } ! 1216: ! 1217: if (HD(j)->cp_stat[i] == FREE) { ! 1218: printk("%s: abort, mbox %d is free.\n", BN(j), i); ! 1219: return SUCCESS; ! 1220: } ! 1221: ! 1222: if (HD(j)->cp_stat[i] == IN_USE) { ! 1223: printk("%s: abort, mbox %d is in use.\n", BN(j), i); ! 1224: ! 1225: if (SCarg != HD(j)->cp[i].SCpnt) ! 1226: panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", ! 1227: BN(j), i, SCarg, HD(j)->cp[i].SCpnt); ! 1228: ! 1229: if (inb(sh[j]->io_port + REG_SYS_INTR) & IRQ_ASSERTED) ! 1230: printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i); ! 1231: ! 1232: if (SCarg->eh_state == SCSI_STATE_TIMEOUT) { ! 1233: SCarg->host_scribble = NULL; ! 1234: HD(j)->cp_stat[i] = FREE; ! 1235: printk("%s, abort, mbox %d, eh_state timeout, pid %ld.\n", ! 1236: BN(j), i, SCarg->pid); ! 1237: return SUCCESS; ! 1238: } ! 1239: ! 1240: return FAILED; ! 1241: } ! 1242: ! 1243: if (HD(j)->cp_stat[i] == IN_RESET) { ! 1244: printk("%s: abort, mbox %d is in reset.\n", BN(j), i); ! 1245: return FAILED; ! 1246: } ! 1247: ! 1248: if (HD(j)->cp_stat[i] == LOCKED) { ! 1249: printk("%s: abort, mbox %d is locked.\n", BN(j), i); ! 1250: return SUCCESS; ! 1251: } ! 1252: ! 1253: if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { ! 1254: SCarg->result = DID_ABORT << 16; ! 1255: SCarg->host_scribble = NULL; ! 1256: HD(j)->cp_stat[i] = FREE; ! 1257: printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", ! 1258: BN(j), i, SCarg->pid); ! 1259: SCarg->scsi_done(SCarg); ! 1260: return SUCCESS; ! 1261: } ! 1262: ! 1263: panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); ! 1264: } ! 1265: ! 1266: int u14_34f_abort(Scsi_Cmnd *SCarg) { ! 1267: ! 1268: return do_abort(SCarg); ! 1269: } ! 1270: ! 1271: #endif /* new_eh_code */ ! 1272: ! 1273: static inline int do_old_reset(Scsi_Cmnd *SCarg) { ! 1274: unsigned int i, j, time, k, c, limit = 0; ! 1275: int arg_done = FALSE; ! 1276: Scsi_Cmnd *SCpnt; ! 1277: ! 1278: j = ((struct hostdata *) SCarg->host->hostdata)->board_number; ! 1279: printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", ! 1280: BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); ! 1281: ! 1282: if (SCarg->host_scribble == NULL) ! 1283: printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); ! 1284: ! 1285: if (SCarg->serial_number_at_timeout && ! 1286: (SCarg->serial_number != SCarg->serial_number_at_timeout)) { ! 1287: printk("%s: reset, pid %ld, reset not running.\n", BN(j), SCarg->pid); ! 1288: return SCSI_RESET_NOT_RUNNING; ! 1289: } ! 1290: ! 1291: if (HD(j)->in_reset) { ! 1292: printk("%s: reset, exit, already in reset.\n", BN(j)); ! 1293: return SCSI_RESET_ERROR; ! 1294: } ! 1295: ! 1296: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1297: printk("%s: reset, exit, timeout error.\n", BN(j)); ! 1298: return SCSI_RESET_ERROR; ! 1299: } ! 1300: ! 1301: HD(j)->retries = 0; ! 1302: ! 1303: for (c = 0; c <= sh[j]->max_channel; c++) ! 1304: for (k = 0; k < sh[j]->max_id; k++) { ! 1305: HD(j)->target_redo[k][c] = TRUE; ! 1306: HD(j)->target_to[k][c] = 0; ! 1307: } ! 1308: ! 1309: for (i = 0; i < sh[j]->can_queue; i++) { ! 1310: ! 1311: if (HD(j)->cp_stat[i] == FREE) continue; ! 1312: ! 1313: if (HD(j)->cp_stat[i] == LOCKED) { ! 1314: HD(j)->cp_stat[i] = FREE; ! 1315: printk("%s: reset, locked mbox %d forced free.\n", BN(j), i); ! 1316: continue; ! 1317: } ! 1318: ! 1319: if (!(SCpnt = HD(j)->cp[i].SCpnt)) ! 1320: panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i); ! 1321: ! 1322: if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { ! 1323: HD(j)->cp_stat[i] = ABORTING; ! 1324: printk("%s: reset, mbox %d aborting, pid %ld.\n", ! 1325: BN(j), i, SCpnt->pid); ! 1326: } ! 1327: ! 1328: else { ! 1329: HD(j)->cp_stat[i] = IN_RESET; ! 1330: printk("%s: reset, mbox %d in reset, pid %ld.\n", ! 1331: BN(j), i, SCpnt->pid); ! 1332: } ! 1333: ! 1334: if (SCpnt->host_scribble == NULL) ! 1335: panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i); ! 1336: ! 1337: if (*(unsigned int *)SCpnt->host_scribble != i) ! 1338: panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i); ! 1339: ! 1340: if (SCpnt->scsi_done == NULL) ! 1341: panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i); ! 1342: ! 1343: if (SCpnt == SCarg) arg_done = TRUE; ! 1344: } ! 1345: ! 1346: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1347: printk("%s: reset, cannot reset, timeout error.\n", BN(j)); ! 1348: return SCSI_RESET_ERROR; ! 1349: } ! 1350: ! 1351: outb(CMD_RESET, sh[j]->io_port + REG_LCL_INTR); ! 1352: printk("%s: reset, board reset done, enabling interrupts.\n", BN(j)); ! 1353: ! 1354: #if defined(DEBUG_RESET) ! 1355: do_trace = TRUE; ! 1356: #endif ! 1357: ! 1358: HD(j)->in_reset = TRUE; ! 1359: SPIN_UNLOCK ! 1360: IRQ_UNLOCK ! 1361: time = jiffies; ! 1362: while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); ! 1363: IRQ_LOCK ! 1364: SPIN_LOCK ! 1365: printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); ! 1366: ! 1367: for (i = 0; i < sh[j]->can_queue; i++) { ! 1368: ! 1369: if (HD(j)->cp_stat[i] == IN_RESET) { ! 1370: SCpnt = HD(j)->cp[i].SCpnt; ! 1371: SCpnt->result = DID_RESET << 16; ! 1372: SCpnt->host_scribble = NULL; ! 1373: ! 1374: /* This mailbox is still waiting for its interrupt */ ! 1375: HD(j)->cp_stat[i] = LOCKED; ! 1376: ! 1377: printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", ! 1378: BN(j), i, SCpnt->pid); ! 1379: } ! 1380: ! 1381: else if (HD(j)->cp_stat[i] == ABORTING) { ! 1382: SCpnt = HD(j)->cp[i].SCpnt; ! 1383: SCpnt->result = DID_RESET << 16; ! 1384: SCpnt->host_scribble = NULL; ! 1385: ! 1386: /* This mailbox was never queued to the adapter */ ! 1387: HD(j)->cp_stat[i] = FREE; ! 1388: ! 1389: printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", ! 1390: BN(j), i, SCpnt->pid); ! 1391: } ! 1392: ! 1393: else ! 1394: ! 1395: /* Any other mailbox has already been set free by interrupt */ ! 1396: continue; ! 1397: ! 1398: SCpnt->scsi_done(SCpnt); ! 1399: IRQ_LOCK ! 1400: } ! 1401: ! 1402: HD(j)->in_reset = FALSE; ! 1403: do_trace = FALSE; ! 1404: ! 1405: if (arg_done) { ! 1406: printk("%s: reset, exit, success.\n", BN(j)); ! 1407: return SCSI_RESET_SUCCESS; ! 1408: } ! 1409: else { ! 1410: printk("%s: reset, exit, wakeup.\n", BN(j)); ! 1411: return SCSI_RESET_PUNT; ! 1412: } ! 1413: } ! 1414: ! 1415: int u14_34f_old_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) { ! 1416: int rtn; ! 1417: IRQ_FLAGS ! 1418: ! 1419: IRQ_LOCK_SAVE ! 1420: rtn = do_old_reset(SCarg); ! 1421: IRQ_UNLOCK_RESTORE ! 1422: return rtn; ! 1423: } ! 1424: ! 1425: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101) ! 1426: ! 1427: static inline int do_reset(Scsi_Cmnd *SCarg) { ! 1428: unsigned int i, j, time, k, c, limit = 0; ! 1429: int arg_done = FALSE; ! 1430: Scsi_Cmnd *SCpnt; ! 1431: ! 1432: j = ((struct hostdata *) SCarg->host->hostdata)->board_number; ! 1433: printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", ! 1434: BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); ! 1435: ! 1436: if (SCarg->host_scribble == NULL) ! 1437: printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); ! 1438: ! 1439: if (HD(j)->in_reset) { ! 1440: printk("%s: reset, exit, already in reset.\n", BN(j)); ! 1441: return FAILED; ! 1442: } ! 1443: ! 1444: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1445: printk("%s: reset, exit, timeout error.\n", BN(j)); ! 1446: return FAILED; ! 1447: } ! 1448: ! 1449: HD(j)->retries = 0; ! 1450: ! 1451: for (c = 0; c <= sh[j]->max_channel; c++) ! 1452: for (k = 0; k < sh[j]->max_id; k++) { ! 1453: HD(j)->target_redo[k][c] = TRUE; ! 1454: HD(j)->target_to[k][c] = 0; ! 1455: } ! 1456: ! 1457: for (i = 0; i < sh[j]->can_queue; i++) { ! 1458: ! 1459: if (HD(j)->cp_stat[i] == FREE) continue; ! 1460: ! 1461: if (HD(j)->cp_stat[i] == LOCKED) { ! 1462: HD(j)->cp_stat[i] = FREE; ! 1463: printk("%s: reset, locked mbox %d forced free.\n", BN(j), i); ! 1464: continue; ! 1465: } ! 1466: ! 1467: if (!(SCpnt = HD(j)->cp[i].SCpnt)) ! 1468: panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i); ! 1469: ! 1470: if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { ! 1471: HD(j)->cp_stat[i] = ABORTING; ! 1472: printk("%s: reset, mbox %d aborting, pid %ld.\n", ! 1473: BN(j), i, SCpnt->pid); ! 1474: } ! 1475: ! 1476: else { ! 1477: HD(j)->cp_stat[i] = IN_RESET; ! 1478: printk("%s: reset, mbox %d in reset, pid %ld.\n", ! 1479: BN(j), i, SCpnt->pid); ! 1480: } ! 1481: ! 1482: if (SCpnt->host_scribble == NULL) ! 1483: panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i); ! 1484: ! 1485: if (*(unsigned int *)SCpnt->host_scribble != i) ! 1486: panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i); ! 1487: ! 1488: if (SCpnt->scsi_done == NULL) ! 1489: panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i); ! 1490: ! 1491: if (SCpnt == SCarg) arg_done = TRUE; ! 1492: } ! 1493: ! 1494: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1495: printk("%s: reset, cannot reset, timeout error.\n", BN(j)); ! 1496: return FAILED; ! 1497: } ! 1498: ! 1499: outb(CMD_RESET, sh[j]->io_port + REG_LCL_INTR); ! 1500: printk("%s: reset, board reset done, enabling interrupts.\n", BN(j)); ! 1501: ! 1502: #if defined(DEBUG_RESET) ! 1503: do_trace = TRUE; ! 1504: #endif ! 1505: ! 1506: HD(j)->in_reset = TRUE; ! 1507: SPIN_UNLOCK ! 1508: IRQ_UNLOCK ! 1509: time = jiffies; ! 1510: while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); ! 1511: IRQ_LOCK ! 1512: SPIN_LOCK ! 1513: printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); ! 1514: ! 1515: for (i = 0; i < sh[j]->can_queue; i++) { ! 1516: ! 1517: if (HD(j)->cp_stat[i] == IN_RESET) { ! 1518: SCpnt = HD(j)->cp[i].SCpnt; ! 1519: SCpnt->result = DID_RESET << 16; ! 1520: SCpnt->host_scribble = NULL; ! 1521: ! 1522: /* This mailbox is still waiting for its interrupt */ ! 1523: HD(j)->cp_stat[i] = LOCKED; ! 1524: ! 1525: printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", ! 1526: BN(j), i, SCpnt->pid); ! 1527: } ! 1528: ! 1529: else if (HD(j)->cp_stat[i] == ABORTING) { ! 1530: SCpnt = HD(j)->cp[i].SCpnt; ! 1531: SCpnt->result = DID_RESET << 16; ! 1532: SCpnt->host_scribble = NULL; ! 1533: ! 1534: /* This mailbox was never queued to the adapter */ ! 1535: HD(j)->cp_stat[i] = FREE; ! 1536: ! 1537: printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", ! 1538: BN(j), i, SCpnt->pid); ! 1539: } ! 1540: ! 1541: else ! 1542: ! 1543: /* Any other mailbox has already been set free by interrupt */ ! 1544: continue; ! 1545: ! 1546: SCpnt->scsi_done(SCpnt); ! 1547: IRQ_LOCK ! 1548: } ! 1549: ! 1550: HD(j)->in_reset = FALSE; ! 1551: do_trace = FALSE; ! 1552: ! 1553: if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid); ! 1554: else printk("%s: reset, exit.\n", BN(j)); ! 1555: ! 1556: return SUCCESS; ! 1557: } ! 1558: ! 1559: int u14_34f_reset(Scsi_Cmnd *SCarg) { ! 1560: ! 1561: return do_reset(SCarg); ! 1562: } ! 1563: ! 1564: #endif /* new_eh_code */ ! 1565: ! 1566: int u14_34f_biosparam(Disk *disk, kdev_t dev, int *dkinfo) { ! 1567: unsigned int j = 0; ! 1568: int size = disk->capacity; ! 1569: ! 1570: dkinfo[0] = HD(j)->heads; ! 1571: dkinfo[1] = HD(j)->sectors; ! 1572: dkinfo[2] = size / (HD(j)->heads * HD(j)->sectors); ! 1573: ! 1574: if (ext_tran && (scsicam_bios_param(disk, dev, dkinfo) < 0)) { ! 1575: dkinfo[0] = 255; ! 1576: dkinfo[1] = 63; ! 1577: dkinfo[2] = size / (dkinfo[0] * dkinfo[1]); ! 1578: } ! 1579: ! 1580: #if defined (DEBUG_GEOMETRY) ! 1581: printk ("%s: biosparam, head=%d, sec=%d, cyl=%d.\n", driver_name, ! 1582: dkinfo[0], dkinfo[1], dkinfo[2]); ! 1583: #endif ! 1584: ! 1585: return FALSE; ! 1586: } ! 1587: ! 1588: static void sort(unsigned long sk[], unsigned int da[], unsigned int n, ! 1589: unsigned int rev) { ! 1590: unsigned int i, j, k, y; ! 1591: unsigned long x; ! 1592: ! 1593: for (i = 0; i < n - 1; i++) { ! 1594: k = i; ! 1595: ! 1596: for (j = k + 1; j < n; j++) ! 1597: if (rev) { ! 1598: if (sk[j] > sk[k]) k = j; ! 1599: } ! 1600: else { ! 1601: if (sk[j] < sk[k]) k = j; ! 1602: } ! 1603: ! 1604: if (k != i) { ! 1605: x = sk[k]; sk[k] = sk[i]; sk[i] = x; ! 1606: y = da[k]; da[k] = da[i]; da[i] = y; ! 1607: } ! 1608: } ! 1609: ! 1610: return; ! 1611: } ! 1612: ! 1613: static inline int reorder(unsigned int j, unsigned long cursec, ! 1614: unsigned int ihdlr, unsigned int il[], unsigned int n_ready) { ! 1615: Scsi_Cmnd *SCpnt; ! 1616: struct mscp *cpp; ! 1617: unsigned int k, n; ! 1618: unsigned int rev = FALSE, s = TRUE, r = TRUE; ! 1619: unsigned int input_only = TRUE, overlap = FALSE; ! 1620: unsigned long sl[n_ready], pl[n_ready], ll[n_ready]; ! 1621: unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0; ! 1622: unsigned long ioseek = 0; ! 1623: ! 1624: static unsigned int flushcount = 0, batchcount = 0, sortcount = 0; ! 1625: static unsigned int readycount = 0, ovlcount = 0, inputcount = 0; ! 1626: static unsigned int readysorted = 0, revcount = 0; ! 1627: static unsigned long seeksorted = 0, seeknosort = 0; ! 1628: ! 1629: if (link_statistics && !(++flushcount % link_statistics)) ! 1630: printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"\ ! 1631: " av %ldK as %ldK.\n", flushcount, batchcount, inputcount, ! 1632: ovlcount, readycount, readysorted, sortcount, revcount, ! 1633: seeknosort / (readycount + 1), ! 1634: seeksorted / (readycount + 1)); ! 1635: ! 1636: if (n_ready <= 1) return FALSE; ! 1637: ! 1638: for (n = 0; n < n_ready; n++) { ! 1639: k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; ! 1640: ! 1641: if (!(cpp->xdir == DTD_IN)) input_only = FALSE; ! 1642: ! 1643: if (SCpnt->request.sector < minsec) minsec = SCpnt->request.sector; ! 1644: if (SCpnt->request.sector > maxsec) maxsec = SCpnt->request.sector; ! 1645: ! 1646: sl[n] = SCpnt->request.sector; ! 1647: ioseek += SCpnt->request.nr_sectors; ! 1648: ! 1649: if (!n) continue; ! 1650: ! 1651: if (sl[n] < sl[n - 1]) s = FALSE; ! 1652: if (sl[n] > sl[n - 1]) r = FALSE; ! 1653: ! 1654: if (link_statistics) { ! 1655: if (sl[n] > sl[n - 1]) ! 1656: seek += sl[n] - sl[n - 1]; ! 1657: else ! 1658: seek += sl[n - 1] - sl[n]; ! 1659: } ! 1660: ! 1661: } ! 1662: ! 1663: if (link_statistics) { ! 1664: if (cursec > sl[0]) seek += cursec - sl[0]; else seek += sl[0] - cursec; ! 1665: } ! 1666: ! 1667: if (cursec > ((maxsec + minsec) / 2)) rev = TRUE; ! 1668: ! 1669: if (ioseek > ((maxsec - minsec) / 2)) rev = FALSE; ! 1670: ! 1671: if (!((rev && r) || (!rev && s))) sort(sl, il, n_ready, rev); ! 1672: ! 1673: if (!input_only) for (n = 0; n < n_ready; n++) { ! 1674: k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; ! 1675: ll[n] = SCpnt->request.nr_sectors; pl[n] = SCpnt->pid; ! 1676: ! 1677: if (!n) continue; ! 1678: ! 1679: if ((sl[n] == sl[n - 1]) || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n])) ! 1680: || (rev && ((sl[n] + ll[n]) > sl[n - 1]))) overlap = TRUE; ! 1681: } ! 1682: ! 1683: if (overlap) sort(pl, il, n_ready, FALSE); ! 1684: ! 1685: if (link_statistics) { ! 1686: if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec; ! 1687: batchcount++; readycount += n_ready, seeknosort += seek / 1024; ! 1688: if (input_only) inputcount++; ! 1689: if (overlap) { ovlcount++; seeksorted += iseek / 1024; } ! 1690: else seeksorted += (iseek + maxsec - minsec) / 1024; ! 1691: if (rev && !r) { revcount++; readysorted += n_ready; } ! 1692: if (!rev && !s) { sortcount++; readysorted += n_ready; } ! 1693: } ! 1694: ! 1695: #if defined(DEBUG_LINKED_COMMANDS) ! 1696: if (link_statistics && (overlap || !(flushcount % link_statistics))) ! 1697: for (n = 0; n < n_ready; n++) { ! 1698: k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; ! 1699: printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\ ! 1700: " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", ! 1701: (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target, ! 1702: SCpnt->lun, SCpnt->pid, k, flushcount, n_ready, ! 1703: SCpnt->request.sector, SCpnt->request.nr_sectors, cursec, ! 1704: YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), ! 1705: YESNO(overlap), cpp->xdir); ! 1706: } ! 1707: #endif ! 1708: return overlap; ! 1709: } ! 1710: ! 1711: static void flush_dev(Scsi_Device *dev, unsigned long cursec, unsigned int j, ! 1712: unsigned int ihdlr) { ! 1713: Scsi_Cmnd *SCpnt; ! 1714: struct mscp *cpp; ! 1715: unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES]; ! 1716: ! 1717: for (k = 0; k < sh[j]->can_queue; k++) { ! 1718: ! 1719: if (HD(j)->cp_stat[k] != READY && HD(j)->cp_stat[k] != IN_USE) continue; ! 1720: ! 1721: cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; ! 1722: ! 1723: if (SCpnt->device != dev) continue; ! 1724: ! 1725: if (HD(j)->cp_stat[k] == IN_USE) return; ! 1726: ! 1727: il[n_ready++] = k; ! 1728: } ! 1729: ! 1730: if (reorder(j, cursec, ihdlr, il, n_ready)) n_ready = 1; ! 1731: ! 1732: for (n = 0; n < n_ready; n++) { ! 1733: k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; ! 1734: ! 1735: if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { ! 1736: printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\ ! 1737: " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"), ! 1738: SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k); ! 1739: HD(j)->cp_stat[k] = ABORTING; ! 1740: continue; ! 1741: } ! 1742: ! 1743: outl(V2DEV(cpp), sh[j]->io_port + REG_OGM); ! 1744: outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR); ! 1745: HD(j)->cp_stat[k] = IN_USE; ! 1746: } ! 1747: ! 1748: } ! 1749: ! 1750: static inline void ihdlr(int irq, unsigned int j) { ! 1751: Scsi_Cmnd *SCpnt; ! 1752: unsigned int i, k, c, status, tstatus, reg, ret; ! 1753: struct mscp *spp, *cpp; ! 1754: ! 1755: if (sh[j]->irq != irq) ! 1756: panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq); ! 1757: ! 1758: /* Check if this board need to be serviced */ ! 1759: if (!((reg = inb(sh[j]->io_port + REG_SYS_INTR)) & IRQ_ASSERTED)) return; ! 1760: ! 1761: HD(j)->iocount++; ! 1762: ! 1763: if (do_trace) printk("%s: ihdlr, enter, irq %d, count %d.\n", BN(j), irq, ! 1764: HD(j)->iocount); ! 1765: ! 1766: /* Check if this board is still busy */ ! 1767: if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) { ! 1768: outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR); ! 1769: printk("%s: ihdlr, busy timeout error, irq %d, reg 0x%x, count %d.\n", ! 1770: BN(j), irq, reg, HD(j)->iocount); ! 1771: return; ! 1772: } ! 1773: ! 1774: spp = (struct mscp *)DEV2V(ret = inl(sh[j]->io_port + REG_ICM)); ! 1775: cpp = spp; ! 1776: ! 1777: /* Clear interrupt pending flag */ ! 1778: outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR); ! 1779: ! 1780: #if defined(DEBUG_GENERATE_ABORTS) ! 1781: if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return; ! 1782: #endif ! 1783: ! 1784: /* Find the mailbox to be serviced on this board */ ! 1785: i = cpp - HD(j)->cp; ! 1786: ! 1787: if (cpp < HD(j)->cp || cpp >= HD(j)->cp + sh[j]->can_queue ! 1788: || i >= sh[j]->can_queue) ! 1789: panic("%s: ihdlr, invalid mscp bus address %p, cp0 %p.\n", BN(j), ! 1790: (void *)ret, HD(j)->cp); ! 1791: ! 1792: if (HD(j)->cp_stat[i] == IGNORE) { ! 1793: HD(j)->cp_stat[i] = FREE; ! 1794: return; ! 1795: } ! 1796: else if (HD(j)->cp_stat[i] == LOCKED) { ! 1797: HD(j)->cp_stat[i] = FREE; ! 1798: printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i, ! 1799: HD(j)->iocount); ! 1800: return; ! 1801: } ! 1802: else if (HD(j)->cp_stat[i] == FREE) { ! 1803: printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i, ! 1804: HD(j)->iocount); ! 1805: return; ! 1806: } ! 1807: else if (HD(j)->cp_stat[i] == IN_RESET) ! 1808: printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i); ! 1809: else if (HD(j)->cp_stat[i] != IN_USE) ! 1810: panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n", ! 1811: BN(j), i, HD(j)->cp_stat[i]); ! 1812: ! 1813: HD(j)->cp_stat[i] = FREE; ! 1814: SCpnt = cpp->SCpnt; ! 1815: ! 1816: if (SCpnt == NULL) panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i); ! 1817: ! 1818: if (SCpnt->host_scribble == NULL) ! 1819: panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i, ! 1820: SCpnt->pid, SCpnt); ! 1821: ! 1822: if (*(unsigned int *)SCpnt->host_scribble != i) ! 1823: panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", ! 1824: BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble); ! 1825: ! 1826: if (linked_comm && SCpnt->device->queue_depth > 2 ! 1827: && TLDEV(SCpnt->device->type)) ! 1828: flush_dev(SCpnt->device, SCpnt->request.sector, j, TRUE); ! 1829: ! 1830: tstatus = status_byte(spp->target_status); ! 1831: ! 1832: #if defined(DEBUG_GENERATE_ERRORS) ! 1833: if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 200) < 2)) ! 1834: spp->adapter_status = 0x01; ! 1835: #endif ! 1836: ! 1837: switch (spp->adapter_status) { ! 1838: case ASOK: /* status OK */ ! 1839: ! 1840: /* Forces a reset if a disk drive keeps returning BUSY */ ! 1841: if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) ! 1842: status = DID_ERROR << 16; ! 1843: ! 1844: /* If there was a bus reset, redo operation on each target */ ! 1845: else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK ! 1846: && HD(j)->target_redo[SCpnt->target][SCpnt->channel]) ! 1847: status = DID_BUS_BUSY << 16; ! 1848: ! 1849: /* Works around a flaw in scsi.c */ ! 1850: else if (tstatus == CHECK_CONDITION ! 1851: && SCpnt->device->type == TYPE_DISK ! 1852: && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR) ! 1853: status = DID_BUS_BUSY << 16; ! 1854: ! 1855: else ! 1856: status = DID_OK << 16; ! 1857: ! 1858: if (tstatus == GOOD) ! 1859: HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE; ! 1860: ! 1861: if (spp->target_status && SCpnt->device->type == TYPE_DISK) ! 1862: printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\ ! 1863: "target_status 0x%x, sense key 0x%x.\n", BN(j), ! 1864: SCpnt->channel, SCpnt->target, SCpnt->lun, ! 1865: SCpnt->pid, spp->target_status, ! 1866: SCpnt->sense_buffer[2]); ! 1867: ! 1868: HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0; ! 1869: ! 1870: if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0; ! 1871: ! 1872: break; ! 1873: case ASST: /* Selection Time Out */ ! 1874: ! 1875: if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1) ! 1876: status = DID_ERROR << 16; ! 1877: else { ! 1878: status = DID_TIME_OUT << 16; ! 1879: HD(j)->target_to[SCpnt->target][SCpnt->channel]++; ! 1880: } ! 1881: ! 1882: break; ! 1883: ! 1884: /* Perform a limited number of internal retries */ ! 1885: case 0x93: /* Unexpected bus free */ ! 1886: case 0x94: /* Target bus phase sequence failure */ ! 1887: case 0x96: /* Illegal SCSI command */ ! 1888: case 0xa3: /* SCSI bus reset error */ ! 1889: ! 1890: for (c = 0; c <= sh[j]->max_channel; c++) ! 1891: for (k = 0; k < sh[j]->max_id; k++) ! 1892: HD(j)->target_redo[k][c] = TRUE; ! 1893: ! 1894: ! 1895: case 0x92: /* Data over/under-run */ ! 1896: ! 1897: if (SCpnt->device->type != TYPE_TAPE ! 1898: && HD(j)->retries < MAX_INTERNAL_RETRIES) { ! 1899: ! 1900: #if defined(DID_SOFT_ERROR) ! 1901: status = DID_SOFT_ERROR << 16; ! 1902: #else ! 1903: status = DID_BUS_BUSY << 16; ! 1904: #endif ! 1905: ! 1906: HD(j)->retries++; ! 1907: HD(j)->last_retried_pid = SCpnt->pid; ! 1908: } ! 1909: else ! 1910: status = DID_ERROR << 16; ! 1911: ! 1912: break; ! 1913: case 0x01: /* Invalid command */ ! 1914: case 0x02: /* Invalid parameters */ ! 1915: case 0x03: /* Invalid data list */ ! 1916: case 0x84: /* SCSI bus abort error */ ! 1917: case 0x9b: /* Auto request sense error */ ! 1918: case 0x9f: /* Unexpected command complete message error */ ! 1919: case 0xff: /* Invalid parameter in the S/G list */ ! 1920: default: ! 1921: status = DID_ERROR << 16; ! 1922: break; ! 1923: } ! 1924: ! 1925: SCpnt->result = status | spp->target_status; ! 1926: ! 1927: #if defined(DEBUG_INTERRUPT) ! 1928: if (SCpnt->result || do_trace) ! 1929: #else ! 1930: if ((spp->adapter_status != ASOK && HD(j)->iocount > 1000) || ! 1931: (spp->adapter_status != ASOK && ! 1932: spp->adapter_status != ASST && HD(j)->iocount <= 1000) || ! 1933: do_trace || msg_byte(spp->target_status)) ! 1934: #endif ! 1935: printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\ ! 1936: " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n", ! 1937: BN(j), i, spp->adapter_status, spp->target_status, ! 1938: SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, ! 1939: reg, HD(j)->iocount); ! 1940: ! 1941: /* Set the command state to inactive */ ! 1942: SCpnt->host_scribble = NULL; ! 1943: ! 1944: SCpnt->scsi_done(SCpnt); ! 1945: ! 1946: if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq, ! 1947: HD(j)->iocount); ! 1948: ! 1949: return; ! 1950: } ! 1951: ! 1952: static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) { ! 1953: unsigned int j; ! 1954: IRQ_FLAGS ! 1955: SPIN_FLAGS ! 1956: ! 1957: /* Check if the interrupt must be processed by this handler */ ! 1958: if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return; ! 1959: ! 1960: SPIN_LOCK_SAVE ! 1961: IRQ_LOCK_SAVE ! 1962: ihdlr(irq, j); ! 1963: IRQ_UNLOCK_RESTORE ! 1964: SPIN_UNLOCK_RESTORE ! 1965: } ! 1966: ! 1967: int u14_34f_release(struct Scsi_Host *shpnt) { ! 1968: unsigned int i, j; ! 1969: IRQ_FLAGS ! 1970: ! 1971: IRQ_LOCK_SAVE ! 1972: ! 1973: for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++); ! 1974: ! 1975: if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n", ! 1976: driver_name); ! 1977: ! 1978: for (i = 0; i < sh[j]->can_queue; i++) ! 1979: if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist); ! 1980: ! 1981: free_irq(sh[j]->irq, &sha[j]); ! 1982: ! 1983: if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel); ! 1984: ! 1985: release_region(sh[j]->io_port, sh[j]->n_io_port); ! 1986: scsi_unregister(sh[j]); ! 1987: IRQ_UNLOCK_RESTORE ! 1988: return FALSE; ! 1989: } ! 1990: ! 1991: #if defined(MODULE) ! 1992: Scsi_Host_Template driver_template = ULTRASTOR_14_34F; ! 1993: ! 1994: #include "scsi_module.c" ! 1995: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.