📄 u14-34f.c
字号:
/* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * * 26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111 * Added command line option (et:[y|n]) to use the existing * translation (returned by scsicam_bios_param) as disk geometry. * The default is et:n, which uses the disk geometry jumpered * on the board. * The default value et:n is compatible with all previous revisions * of this driver. * * 28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104 * Increased busy timeout from 10 msec. to 200 msec. while * processing interrupts. * * 18 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102 * Improved abort handling during the eh recovery process. * * 13 May 1998 Rev. 4.30 for linux 2.0.33 and 2.1.101 * The driver is now fully SMP safe, including the * abort and reset routines. * Added command line options (eh:[y|n]) to choose between * new_eh_code and the old scsi code. * If linux version >= 2.1.101 the default is eh:y, while the eh * option is ignored for previous releases and the old scsi code * is used. * * 18 Apr 1998 Rev. 4.20 for linux 2.0.33 and 2.1.97 * Reworked interrupt handler. * * 11 Apr 1998 rev. 4.05 for linux 2.0.33 and 2.1.95 * Major reliability improvement: when a batch with overlapping * requests is detected, requests are queued one at a time * eliminating any possible board or drive reordering. * * 10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95 * Improved SMP support (if linux version >= 2.1.95). * * 9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94 * Performance improvement: when sequential i/o is detected, * always use direct sort instead of reverse sort. * * 4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92 * io_port is now unsigned long. * * 17 Mar 1998 rev. 4.01 for linux 2.0.33 and 2.1.88 * Use new scsi error handling code (if linux version >= 2.1.88). * Use new interrupt code. * * 12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55 * Use of udelay inside the wait loops to avoid timeout * problems with fast cpus. * Removed check about useless calls to the interrupt service * routine (reported on SMP systems only). * At initialization time "sorted/unsorted" is displayed instead * of "linked/unlinked" to reinforce the fact that "linking" is * nothing but "elevator sorting" in the actual implementation. * * 17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38 * Use of serial_number_at_timeout in abort and reset processing. * Use of the __initfunc and __initdata macro in setup code. * Minor cleanups in the list_statistics code. * * 24 Feb 1997 rev. 3.00 for linux 2.0.29 and 2.1.26 * When loading as a module, parameter passing is now supported * both in 2.0 and in 2.1 style. * Fixed data transfer direction for some SCSI opcodes. * Immediate acknowledge to request sense commands. * Linked commands to each disk device are now reordered by elevator * sorting. Rare cases in which reordering of write requests could * cause wrong results are managed. * * 18 Jan 1997 rev. 2.60 for linux 2.1.21 and 2.0.28 * Added command line options to enable/disable linked commands * (lc:[y|n]), old firmware support (of:[y|n]) and to set the max * queue depth (mq:xx). Default is "u14-34f=lc:n,of:n,mq:8". * Improved command linking. * * 8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27 * Added linked command support. * * 3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27 * Added queue depth adjustment. * * 22 Nov 1996 rev. 2.30 for linux 2.1.12 and 2.0.26 * The list of i/o ports to be probed can be overwritten by the * "u14-34f=port0,port1,...." boot command line option. * Scatter/gather lists are now allocated by a number of kmalloc * calls, in order to avoid the previous size limit of 64Kb. * * 16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25 * Added multichannel support. * * 27 Sep 1996 rev. 2.12 for linux 2.1.0 * Portability cleanups (virtual/bus addressing, little/big endian * support). * * 09 Jul 1996 rev. 2.11 for linux 2.0.4 * "Data over/under-run" no longer implies a redo on all targets. * Number of internal retries is now limited. * * 16 Apr 1996 rev. 2.10 for linux 1.3.90 * New argument "reset_flags" to the reset routine. * * 21 Jul 1995 rev. 2.02 for linux 1.3.11 * Fixed Data Transfer Direction for some SCSI commands. * * 13 Jun 1995 rev. 2.01 for linux 1.2.10 * HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when * the firmware prom is not the latest one (28008-006). * * 11 Mar 1995 rev. 2.00 for linux 1.2.0 * Fixed a bug which prevented media change detection for removable * disk drives. * * 23 Feb 1995 rev. 1.18 for linux 1.1.94 * Added a check for scsi_register returning NULL. * * 11 Feb 1995 rev. 1.17 for linux 1.1.91 * U14F qualified to run with 32 sglists. * Now DEBUG_RESET is disabled by default. * * 9 Feb 1995 rev. 1.16 for linux 1.1.90 * Use host->wish_block instead of host->block. * * 8 Feb 1995 rev. 1.15 for linux 1.1.89 * Cleared target_time_out counter while performing a reset. * * 28 Jan 1995 rev. 1.14 for linux 1.1.86 * Added module support. * Log and do a retry when a disk drive returns a target status * different from zero on a recovered error. * Auto detects if U14F boards have an old firmware revision. * Max number of scatter/gather lists set to 16 for all boards * (most installation run fine using 33 sglists, while other * has problems when using more then 16). * * 16 Jan 1995 rev. 1.13 for linux 1.1.81 * Display a message if check_region detects a port address * already in use. * * 15 Dec 1994 rev. 1.12 for linux 1.1.74 * The host->block flag is set for all the detected ISA boards. * * 30 Nov 1994 rev. 1.11 for linux 1.1.68 * Redo i/o on target status CHECK_CONDITION for TYPE_DISK only. * Added optional support for using a single board at a time. * * 14 Nov 1994 rev. 1.10 for linux 1.1.63 * * 28 Oct 1994 rev. 1.09 for linux 1.1.58 Final BETA release. * 16 Jul 1994 rev. 1.00 for linux 1.1.29 Initial ALPHA release. * * This driver is a total replacement of the original UltraStor * scsi driver, but it supports ONLY the 14F and 34F boards. * It can be configured in the same kernel in which the original * ultrastor driver is configured to allow the original U24F * support. * * Multiple U14F and/or U34F host adapters are supported. * * Copyright (C) 1994-1998 Dario Ballabio (dario@milano.europe.dg.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that redistributions of source * code retain the above copyright notice and this comment without * modification. * * WARNING: if your 14/34F board has an old firmware revision (see below) * you must change "#undef" into "#define" in the following * statement. */#undef HAVE_OLD_UX4F_FIRMWARE/* * The UltraStor 14F, 24F, and 34F are a family of intelligent, high * performance SCSI-2 host adapters. * Here is the scoop on the various models: * * 14F - ISA first-party DMA HA with floppy support and WD1003 emulation. * 24F - EISA Bus Master HA with floppy support and WD1003 emulation. * 34F - VESA Local-Bus Bus Master HA (no WD1003 emulation). * * This code has been tested with up to two U14F boards, using both * firmware 28004-005/38004-004 (BIOS rev. 2.00) and the latest firmware * 28004-006/38004-005 (BIOS rev. 2.01). * * The latest firmware is required in order to get reliable operations when * clustering is enabled. ENABLE_CLUSTERING provides a performance increase * up to 50% on sequential access. * * Since the Scsi_Host_Template structure is shared among all 14F and 34F, * the last setting of use_clustering is in effect for all of these boards. * * Here a sample configuration using two U14F boards: * U14F0: ISA 0x330, BIOS 0xc8000, IRQ 11, DMA 5, SG 32, MB 16, of:n, lc:y, mq:8. U14F1: ISA 0x340, BIOS 0x00000, IRQ 10, DMA 6, SG 32, MB 16, of:n, lc:y, mq:8. * * The boot controller must have its BIOS enabled, while other boards can * have their BIOS disabled, or enabled to an higher address. * Boards are named Ux4F0, Ux4F1..., according to the port address order in * the io_port[] array. * * The following facts are based on real testing results (not on * documentation) on the above U14F board. * * - The U14F board should be jumpered for bus on time less or equal to 7 * microseconds, while the default is 11 microseconds. This is order to * get acceptable performance while using floppy drive and hard disk * together. The jumpering for 7 microseconds is: JP13 pin 15-16, * JP14 pin 7-8 and pin 9-10. * The reduction has a little impact on scsi performance. * * - If scsi bus length exceeds 3m., the scsi bus speed needs to be reduced * from 10Mhz to 5Mhz (do this by inserting a jumper on JP13 pin 7-8). * * - If U14F on board firmware is older than 28004-006/38004-005, * the U14F board is unable to provide reliable operations if the scsi * request length exceeds 16Kbyte. When this length is exceeded the * behavior is: * - adapter_status equal 0x96 or 0xa3 or 0x93 or 0x94; * - adapter_status equal 0 and target_status equal 2 on for all targets * in the next operation following the reset. * This sequence takes a long time (>3 seconds), so in the meantime * the SD_TIMEOUT in sd.c could expire giving rise to scsi aborts * (SD_TIMEOUT has been increased from 3 to 6 seconds in 1.1.31). * Because of this I had to DISABLE_CLUSTERING and to work around the * bus reset in the interrupt service routine, returning DID_BUS_BUSY * so that the operations are retried without complains from the scsi.c * code. * Any reset of the scsi bus is going to kill tape operations, since * no retry is allowed for tapes. Bus resets are more likely when the * scsi bus is under heavy load. * Requests using scatter/gather have a maximum length of 16 x 1024 bytes * when DISABLE_CLUSTERING is in effect, but unscattered requests could be * larger than 16Kbyte. * * The new firmware has fixed all the above problems. * * For U34F boards the latest bios prom is 38008-002 (BIOS rev. 2.01), * the latest firmware prom is 28008-006. Older firmware 28008-005 has * problems when using more then 16 scatter/gather lists. * * The list of i/o ports to be probed can be totally replaced by the * boot command line option: "u14-34f=port0,port1,port2,...", where the * port0, port1... arguments are ISA/VESA addresses to be probed. * For example using "u14-34f=0x230,0x340", the driver probes only the two * addresses 0x230 and 0x340 in this order; "u14-34f=0" totally disables * this driver. * * After the optional list of detection probes, other possible command line * options are: * * eh:y use new scsi code (linux 2.2 only); * eh:n use old scsi code; * et:y use disk geometry returned by scsicam_bios_param; * et:n use disk geometry jumpered on the board; * lc:y enables linked commands; * lc:n disables linked commands; * of:y enables old firmware support; * of:n disables old firmware support; * mq:xx set the max queue depth to the value xx (2 <= xx <= 8). * * The default value is: "u14-34f=lc:n,of:n,mq:8,et:n". * An example using the list of detection probes could be: * "u14-34f=0x230,0x340,lc:y,of:n,mq:4,eh:n,et:n". * * When loading as a module, parameters can be specified as well. * The above example would be (use 1 in place of y and 0 in place of n): * * modprobe u14-34f io_port=0x230,0x340 linked_comm=1 have_old_firmware=0 \ * max_queue_depth=4 use_new_eh_code=0 ext_tran=0 * * ---------------------------------------------------------------------------- * In this implementation, linked commands are designed to work with any DISK * or CD-ROM, since this linking has only the intent of clustering (time-wise) * and reordering by elevator sorting commands directed to each device, * without any relation with the actual SCSI protocol between the controller * and the device. * If Q is the queue depth reported at boot time for each device (also named * cmds/lun) and Q > 2, whenever there is already an active command to the * device all other commands to the same device (up to Q-1) are kept waiting * in the elevator sorting queue. When the active command completes, the * commands in this queue are sorted by sector address. The sort is chosen * between increasing or decreasing by minimizing the seek distance between * the sector of the commands just completed and the sector of the first * command in the list to be sorted. * Trivial math assures that the unsorted average seek distance when doing * random seeks over S sectors is S/3. * When (Q-1) requests are uniformly distributed over S sectors, the average * distance between two adjacent requests is S/((Q-1) + 1), so the sorted * average seek distance for (Q-1) random requests over S sectors is S/Q. * The elevator sorting hence divides the seek distance by a factor Q/3. * The above pure geometric remarks are valid in all cases and the * driver effectively reduces the seek distance by the predicted factor * when there are Q concurrent read i/o operations on the device, but this * does not necessarily results in a noticeable performance improvement: * your mileage may vary.... * * Note: command reordering inside a batch of queued commands could cause * wrong results only if there is at least one write request and the * intersection (sector-wise) of all requests is not empty. * When the driver detects a batch including overlapping requests * (a really rare event) strict serial (pid) order is enforced. * ---------------------------------------------------------------------------- * * The boards are named Ux4F0, Ux4F1,... according to the detection order. * * In order to support multiple ISA boards in a reliable way, * the driver sets host->wish_block = TRUE for all ISA boards. */#include <linux/version.h>#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))#define MAX_INT_PARAM 10#if defined(MODULE)#include <linux/module.h>#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26)MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");MODULE_PARM(linked_comm, "i");MODULE_PARM(have_old_firmware, "i");MODULE_PARM(link_statistics, "i");MODULE_PARM(max_queue_depth, "i");MODULE_PARM(use_new_eh_code, "i");MODULE_PARM(ext_tran, "i");MODULE_AUTHOR("Dario Ballabio");#endif#endif#include <linux/string.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/system.h>#include <asm/byteorder.h>#include <linux/proc_fs.h>#include <linux/blk.h>#include "scsi.h"#include "hosts.h"#include "sd.h"#include <asm/dma.h>#include <asm/irq.h>#include "u14-34f.h"#include <linux/stat.h>#include <linux/config.h>#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,36)#include <linux/init.h>#else#define __initfunc(A) A#define __initdata#define __init#endif#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)#include <asm/spinlock.h>#define IRQ_FLAGS#define IRQ_LOCK#define IRQ_LOCK_SAVE#define IRQ_UNLOCK#define IRQ_UNLOCK_RESTORE#define SPIN_FLAGS unsigned long spin_flags;#define SPIN_LOCK spin_lock_irq(&io_request_lock);#define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags);#define SPIN_UNLOCK spin_unlock_irq(&io_request_lock);#define SPIN_UNLOCK_RESTORE \ spin_unlock_irqrestore(&io_request_lock, spin_flags);static int use_new_eh_code = TRUE;#else#define IRQ_FLAGS unsigned long irq_flags;#define IRQ_LOCK cli();#define IRQ_LOCK_SAVE do {save_flags(irq_flags); cli();} while (0);#define IRQ_UNLOCK sti();#define IRQ_UNLOCK_RESTORE do {restore_flags(irq_flags);} while (0);#define SPIN_FLAGS#define SPIN_LOCK#define SPIN_LOCK_SAVE#define SPIN_UNLOCK#define SPIN_UNLOCK_RESTOREstatic int use_new_eh_code = FALSE;#endifstruct proc_dir_entry proc_scsi_u14_34f = { PROC_SCSI_U14_34F, 6, "u14_34f", S_IFDIR | S_IRUGO | S_IXUGO, 2};/* Values for the PRODUCT_ID ports for the 14/34F */#define PRODUCT_ID1 0x56
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -