⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seagate.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *    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 + -