📄 seagate.c
字号:
/* * seagate.c Copyright (C) 1992, 1993 Drew Eckhardt * low level scsi driver for ST01/ST02, Future Domain TMC-885, * TMC-950 by Drew Eckhardt <drew@colorado.edu> * * Note : TMC-880 boards don't work because they have two bits in * the status register flipped, I'll fix this "RSN" * [why do I have strong feeling that above message is from 1993? :-) * pavel@ucw.cz] * * This card does all the I/O via memory mapped I/O, so there is no need * to check or allocate a region of the I/O address space. *//* 1996 - to use new read{b,w,l}, write{b,w,l}, and phys_to_virt * macros, replaced assembler routines with C. There's probably a * performance hit, but I only have a cdrom and can't tell. Define * SEAGATE_USE_ASM if you want the old assembler code -- SJT * * 1998-jul-29 - created DPRINTK macros and made it work under * linux 2.1.112, simplified some #defines etc. <pavel@ucw.cz> * * Aug 2000 - aeb - deleted seagate_st0x_biosparam(). It would try to * read the physical disk geometry, a bad mistake. Of course it doesnt * matter much what geometry one invents, but on large disks it * returned 256 (or more) heads, causing all kind of failures. * Of course this means that people might see a different geometry now, * so boot parameters may be necessary in some cases. *//* * Configuration : * To use without BIOS -DOVERRIDE=base_address -DCONTROLLER=FD or SEAGATE * -DIRQ will override the default of 5. * Note: You can now set these options from the kernel's "command line". * The syntax is: * * st0x=ADDRESS,IRQ (for a Seagate controller) * or: * tmc8xx=ADDRESS,IRQ (for a TMC-8xx or TMC-950 controller) * eg: * tmc8xx=0xC8000,15 * * will configure the driver for a TMC-8xx style controller using IRQ 15 * with a base address of 0xC8000. * * -DARBITRATE * Will cause the host adapter to arbitrate for the * bus for better SCSI-II compatibility, rather than just * waiting for BUS FREE and then doing its thing. Should * let us do one command per Lun when I integrate my * reorganization changes into the distribution sources. * * -DDEBUG=65535 * Will activate debug code. * * -DFAST or -DFAST32 * Will use blind transfers where possible * * -DPARITY * This will enable parity. * * -DSEAGATE_USE_ASM * Will use older seagate assembly code. should be (very small amount) * Faster. * * -DSLOW_RATE=50 * Will allow compatibility with broken devices that don't * handshake fast enough (ie, some CD ROM's) for the Seagate * code. * * 50 is some number, It will let you specify a default * transfer rate if handshaking isn't working correctly. * * -DOLDCNTDATASCEME There is a new sceme to set the CONTROL * and DATA reigsters which complies more closely * with the SCSI2 standard. This hopefully eliminates * the need to swap the order these registers are * 'messed' with. It makes the following two options * obsolete. To reenable the old sceme define this. * * The following to options are patches from the SCSI.HOWTO * * -DSWAPSTAT This will swap the definitions for STAT_MSG and STAT_CD. * * -DSWAPCNTDATA This will swap the order that seagate.c messes with * the CONTROL an DATA registers. */#include <linux/module.h>#include <asm/io.h>#include <asm/system.h>#include <linux/spinlock.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/string.h>#include <linux/proc_fs.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/blk.h>#include "scsi.h"#include "hosts.h"#include "seagate.h"#include "constants.h"#include <linux/stat.h>#include <asm/uaccess.h>#include "sd.h"#include <scsi/scsi_ioctl.h>#ifdef DEBUG#define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0)#else#define DPRINTK( when, msg... ) do { } while (0)#endif#define DANY( msg... ) DPRINTK( 0xffff, msg );#ifndef IRQ#define IRQ 5#endif#ifdef FAST32#define FAST#endif#undef LINKED /* Linked commands are currently broken! */#if defined(OVERRIDE) && !defined(CONTROLLER)#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type#endif/* Thanks to Brian Antoine for the example code in his Messy-Loss ST-01 driver, and Mitsugu Suzuki for information on the ST-01 SCSI host.*//* CONTROL defines*/#define CMD_RST 0x01#define CMD_SEL 0x02#define CMD_BSY 0x04#define CMD_ATTN 0x08#define CMD_START_ARB 0x10#define CMD_EN_PARITY 0x20#define CMD_INTR 0x40#define CMD_DRVR_ENABLE 0x80/* STATUS*/#ifdef SWAPSTAT #define STAT_MSG 0x08 #define STAT_CD 0x02#else #define STAT_MSG 0x02 #define STAT_CD 0x08#endif#define STAT_BSY 0x01#define STAT_IO 0x04#define STAT_REQ 0x10#define STAT_SEL 0x20#define STAT_PARITY 0x40#define STAT_ARB_CMPL 0x80/* REQUESTS*/#define REQ_MASK (STAT_CD | STAT_IO | STAT_MSG)#define REQ_DATAOUT 0#define REQ_DATAIN STAT_IO#define REQ_CMDOUT STAT_CD#define REQ_STATIN (STAT_CD | STAT_IO)#define REQ_MSGOUT (STAT_MSG | STAT_CD)#define REQ_MSGIN (STAT_MSG | STAT_CD | STAT_IO)extern volatile int seagate_st0x_timeout;#ifdef PARITY #define BASE_CMD CMD_EN_PARITY#else #define BASE_CMD 0#endif/* Debugging code*/#define PHASE_BUS_FREE 1#define PHASE_ARBITRATION 2#define PHASE_SELECTION 4#define PHASE_DATAIN 8 #define PHASE_DATAOUT 0x10#define PHASE_CMDOUT 0x20#define PHASE_MSGIN 0x40#define PHASE_MSGOUT 0x80#define PHASE_STATUSIN 0x100#define PHASE_ETC (PHASE_DATAIN | PHASE_DATAOUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN)#define PRINT_COMMAND 0x200#define PHASE_EXIT 0x400#define PHASE_RESELECT 0x800#define DEBUG_FAST 0x1000#define DEBUG_SG 0x2000#define DEBUG_LINKED 0x4000#define DEBUG_BORKEN 0x8000/* * Control options - these are timeouts specified in .01 seconds. *//* 30, 20 work */#define ST0X_BUS_FREE_DELAY 25#define ST0X_SELECTION_DELAY 25#define SEAGATE 1 /* these determine the type of the controller */#define FD 2#define ST0X_ID_STR "Seagate ST-01/ST-02"#define FD_ID_STR "TMC-8XX/TMC-950"static int internal_command (unsigned char target, unsigned char lun, const void *cmnd, void *buff, int bufflen, int reselect);static int incommand; /* set if arbitration has finished and we are in some command phase. */static unsigned int base_address = 0; /* Where the card ROM starts, used to calculate memory mapped register location. */static unsigned long st0x_cr_sr; /* control register write, status register read. 256 bytes in length. Read is status of SCSI BUS, as per STAT masks. */static unsigned long st0x_dr; /* data register, read write 256 bytes in length. */static volatile int st0x_aborted = 0; /* set when we are aborted, ie by a time out, etc. */static unsigned char controller_type = 0; /* set to SEAGATE for ST0x boards or FD for TMC-8xx boards */static int irq = IRQ;MODULE_PARM(base_address, "i");MODULE_PARM(controller_type, "b");MODULE_PARM(irq, "i");#define retcode(result) (((result) << 16) | (message << 8) | status)#define STATUS ((u8) isa_readb(st0x_cr_sr))#define DATA ((u8) isa_readb(st0x_dr))#define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); }#define WRITE_DATA(d) { isa_writeb((d), st0x_dr); }void st0x_setup (char *str, int *ints){ controller_type = SEAGATE; base_address = ints[1]; irq = ints[2];}void tmc8xx_setup (char *str, int *ints){ controller_type = FD; base_address = ints[1]; irq = ints[2];}#ifndef OVERRIDEstatic unsigned int seagate_bases[] ={ 0xc8000, 0xca000, 0xcc000, 0xce000, 0xdc000, 0xde000};typedef struct{ const unsigned char *signature; unsigned offset; unsigned length; unsigned char type;}Signature;static const Signature __initdata signatures[] ={ {"ST01 v1.7 (C) Copyright 1987 Seagate", 15, 37, SEAGATE}, {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE},/* * The following two lines are NOT mistakes. One detects ROM revision * 3.0.0, the other 3.2. Since seagate has only one type of SCSI adapter, * and this is not going to change, the "SEAGATE" and "SCSI" together * are probably "good enough" */ {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE}, {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},/* * However, future domain makes several incompatible SCSI boards, so specific * signatures must be used. */ {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD}, {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD}, {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90", 5, 47, FD}, {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90", 5, 47, FD}, {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD}, {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD}, {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD}, {"FUTURE DOMAIN TMC-950", 5, 21, FD}, /* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */ {"IBM F1 V1.2009/22/93", 5, 25, FD},};#define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))#endif /* n OVERRIDE *//* * hostno stores the hostnumber, as told to us by the init routine. */static int hostno = -1;static void seagate_reconnect_intr (int, void *, struct pt_regs *);static void do_seagate_reconnect_intr (int, void *, struct pt_regs *);#ifdef FASTstatic int fast = 1;#else#define fast 0#endif#ifdef SLOW_RATE/* * Support for broken devices : * The Seagate board has a handshaking problem. Namely, a lack * thereof for slow devices. You can blast 600K/second through * it if you are polling for each byte, more if you do a blind * transfer. In the first case, with a fast device, REQ will * transition high-low or high-low-high before your loop restarts * and you'll have no problems. In the second case, the board * will insert wait states for up to 13.2 usecs for REQ to * transition low->high, and everything will work. * * However, there's nothing in the state machine that says * you *HAVE* to see a high-low-high set of transitions before * sending the next byte, and slow things like the Trantor CD ROMS * will break because of this. * * So, we need to slow things down, which isn't as simple as it * seems. We can't slow things down period, because then people * who don't recompile their kernels will shoot me for ruining * their performance. We need to do it on a case per case basis. * * The best for performance will be to, only for borken devices * (this is stored on a per-target basis in the scsi_devices array) * * Wait for a low->high transition before continuing with that * transfer. If we timeout, continue anyways. We don't need * a long timeout, because REQ should only be asserted until the * corresponding ACK is received and processed. * * Note that we can't use the system timer for this, because of * resolution, and we *really* can't use the timer chip since * gettimeofday() and the beeper routines use that. So, * the best thing for us to do will be to calibrate a timing * loop in the initialization code using the timer chip before * gettimeofday() can screw with it. * * FIXME: this is broken (not borken :-). Empty loop costs less than * loop with ISA access in it! -- pavel@ucw.cz */static int borken_calibration = 0;static void __init borken_init (void){ register int count = 0, start = jiffies + 1, stop = start + 25; while (time_before(jiffies, start)) ; for (; time_before(jiffies, stop); ++count) ;/* * Ok, we now have a count for .25 seconds. Convert to a * count per second and divide by transfer rate in K. */ borken_calibration = (count * 4) / (SLOW_RATE * 1024); if (borken_calibration < 1) borken_calibration = 1;}static inline void borken_wait (void){ register int count; for (count = borken_calibration; count && (STATUS & STAT_REQ); --count) ;#if (DEBUG & DEBUG_BORKEN) if (count) printk ("scsi%d : borken timeout\n", hostno);#endif}#endif /* def SLOW_RATE *//* These beasts only live on ISA, and ISA means 8MHz. Each ULOOP() * contains at least one ISA access, which takes more than 0.125 * usec. So if we loop 8 times time in usec, we are safe. */#define ULOOP( i ) for (clock = i*8;;)#define TIMEOUT (!(clock--))int __init seagate_st0x_detect (Scsi_Host_Template * tpnt){ struct Scsi_Host *instance; int i, j; tpnt->proc_name = "seagate";/* * First, we try for the manual override. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -