tmscsim.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,632 行 · 第 1/4 页
C
1,632 行
/************************************************************************ * FILE NAME : TMSCSIM.C * * BY : C.L. Huang, ching@tekram.com.tw * * Description: Device Driver for Tekram DC-390(T) PCI SCSI * * Bus Master Host Adapter * * (C)Copyright 1995-1996 Tekram Technology Co., Ltd. * ************************************************************************ * (C) Copyright: put under GNU GPL in 10/96 * * (see Documentation/scsi/tmscsim.txt) * ************************************************************************ * $Id: tmscsim.c,v 2.60.2.30 2000/12/20 01:07:12 garloff Exp $ * * Enhancements and bugfixes by * * Kurt Garloff <kurt@garloff.de> <garloff@suse.de> * ************************************************************************ * HISTORY: * * * * REV# DATE NAME DESCRIPTION * * 1.00 96/04/24 CLH First release * * 1.01 96/06/12 CLH Fixed bug of Media Change for Removable * * Device, scan all LUN. Support Pre2.0.10 * * 1.02 96/06/18 CLH Fixed bug of Command timeout ... * * 1.03 96/09/25 KG Added tmscsim_proc_info() * * 1.04 96/10/11 CLH Updating for support KV 2.0.x * * 1.05 96/10/18 KG Fixed bug in DC390_abort(null ptr deref)* * 1.06 96/10/25 KG Fixed module support * * 1.07 96/11/09 KG Fixed tmscsim_proc_info() * * 1.08 96/11/18 KG Fixed null ptr in DC390_Disconnect() * * 1.09 96/11/30 KG Added register the allocated IO space * * 1.10 96/12/05 CLH Modified tmscsim_proc_info(), and reset * * pending interrupt in DC390_detect() * * 1.11 97/02/05 KG/CLH Fixeds problem with partitions greater * * than 1GB * * 1.12 98/02/15 MJ Rewritten PCI probing * * 1.13 98/04/08 KG Support for non DC390, __initfunc decls,* * changed max devs from 10 to 16 * * 1.14a 98/05/05 KG Dynamic DCB allocation, add-single-dev * * for LUNs if LUN_SCAN (BIOS) not set * * runtime config using /proc interface * * 1.14b 98/05/06 KG eliminated cli (); sti (); spinlocks * * 1.14c 98/05/07 KG 2.0.x compatibility * * 1.20a 98/05/07 KG changed names of funcs to be consistent * * DC390_ (entry points), dc390_ (internal)* * reworked locking * * 1.20b 98/05/12 KG bugs: version, kfree, _ctmp * * debug output * * 1.20c 98/05/12 KG bugs: kfree, parsing, EEpromDefaults * * 1.20d 98/05/14 KG bugs: list linkage, clear flag after * * reset on startup, code cleanup * * 1.20e 98/05/15 KG spinlock comments, name space cleanup * * pLastDCB now part of ACB structure * * added stats, timeout for 2.1, TagQ bug * * RESET and INQUIRY interface commands * * 1.20f 98/05/18 KG spinlocks fixes, max_lun fix, free DCBs * * for missing LUNs, pending int * * 1.20g 98/05/19 KG Clean up: Avoid short * * 1.20h 98/05/21 KG Remove AdaptSCSIID, max_lun ... * * 1.20i 98/05/21 KG Aiiie: Bug with TagQMask * * 1.20j 98/05/24 KG Handle STAT_BUSY, handle pACB->pLinkDCB * * == 0 in remove_dev and DoingSRB_Done * * 1.20k 98/05/25 KG DMA_INT (experimental) * * 1.20l 98/05/27 KG remove DMA_INT; DMA_IDLE cmds added; * * 1.20m 98/06/10 KG glitch configurable; made some global * * vars part of ACB; use DC390_readX * * 1.20n 98/06/11 KG startup params * * 1.20o 98/06/15 KG added TagMaxNum to boot/module params * * Device Nr -> Idx, TagMaxNum power of 2 * * 1.20p 98/06/17 KG Docu updates. Reset depends on settings * * pci_set_master added; 2.0.xx: pcibios_* * * used instead of MechNum things ... * * 1.20q 98/06/23 KG Changed defaults. Added debug code for * * removable media and fixed it. TagMaxNum * * fixed for DC390. Locking: ACB, DRV for * * better IRQ sharing. Spelling: Queueing * * Parsing and glitch_cfg changes. Display * * real SyncSpeed value. Made DisConn * * functional (!) * * 1.20r 98/06/30 KG Debug macros, allow disabling DsCn, set * * BIT4 in CtrlR4, EN_PAGE_INT, 2.0 module * * param -1 fixed. * * 1.20s 98/08/20 KG Debug info on abort(), try to check PCI,* * phys_to_bus instead of phys_to_virt, * * fixed sel. process, fixed locking, * * added MODULE_XXX infos, changed IRQ * * request flags, disable DMA_INT * * 1.20t 98/09/07 KG TagQ report fixed; Write Erase DMA Stat;* * initfunc -> __init; better abort; * * Timeout for XFER_DONE & BLAST_COMPLETE; * * Allow up to 33 commands being processed * * 2.0a 98/10/14 KG Max Cmnds back to 17. DMA_Stat clearing * * all flags. Clear within while() loops * * in DataIn_0/Out_0. Null ptr in dumpinfo * * for pSRB==0. Better locking during init.* * bios_param() now respects part. table. * * 2.0b 98/10/24 KG Docu fixes. Timeout Msg in DMA Blast. * * Disallow illegal idx in INQUIRY/REMOVE * * 2.0c 98/11/19 KG Cleaned up detect/init for SMP boxes, * * Write Erase DMA (1.20t) caused problems * * 2.0d 98/12/25 KG Christmas release ;-) Message handling * * completely reworked. Handle target ini- * * tiated SDTR correctly. * * 2.0d1 99/01/25 KG Try to handle RESTORE_PTR * * 2.0d2 99/02/08 KG Check for failure of kmalloc, correct * * inclusion of scsicam.h, DelayReset * * 2.0d3 99/05/31 KG DRIVER_OK -> DID_OK, DID_NO_CONNECT, * * detect Target mode and warn. * * pcmd->result handling cleaned up. * * 2.0d4 99/06/01 KG Cleaned selection process. Found bug * * which prevented more than 16 tags. Now: * * 24. SDTR cleanup. Cleaner multi-LUN * * handling. Don't modify ControlRegs/FIFO * * when connected. * * 2.0d5 99/06/01 KG Clear DevID, Fix INQUIRY after cfg chg. * * 2.0d6 99/06/02 KG Added ADD special command to allow cfg. * * before detection. Reset SYNC_NEGO_DONE * * after a bus reset. * * 2.0d7 99/06/03 KG Fixed bugs wrt add,remove commands * * 2.0d8 99/06/04 KG Removed copying of cmnd into CmdBlock. * * Fixed Oops in _release(). * * 2.0d9 99/06/06 KG Also tag queue INQUIRY, T_U_R, ... * * Allow arb. no. of Tagged Cmnds. Max 32 * * 2.0d1099/06/20 KG TagMaxNo changes now honoured! Queueing * * clearified (renamed ..) TagMask handling* * cleaned. * * 2.0d1199/06/28 KG cmd->result now identical to 2.0d2 * * 2.0d1299/07/04 KG Changed order of processing in IRQ * * 2.0d1399/07/05 KG Don't update DCB fields if removed * * 2.0d1499/07/05 KG remove_dev: Move kfree() to the end * * 2.0d1599/07/12 KG use_new_eh_code: 0, ULONG -> UINT where * * appropriate * * 2.0d1699/07/13 KG Reenable StartSCSI interrupt, Retry msg * * 2.0d1799/07/15 KG Remove debug msg. Disable recfg. when * * there are queued cmnds * * 2.0d1899/07/18 KG Selection timeout: Don't requeue * * 2.0d1999/07/18 KG Abort: Only call scsi_done if dequeued * * 2.0d2099/07/19 KG Rst_Detect: DoingSRB_Done * * 2.0d2199/08/15 KG dev_id for request/free_irq, cmnd[0] for* * RETRY, SRBdone does DID_ABORT for the * * cmd passed by DC390_reset() * * 2.0d2299/08/25 KG dev_id fixed. can_queue: 42 * * 2.0d2399/08/25 KG Removed some debugging code. dev_id * * now is set to pACB. Use u8,u16,u32. * * 2.0d2499/11/14 KG Unreg. I/O if failed IRQ alloc. Call * * done () w/ DID_BAD_TARGET in case of * * missing DCB. We are old EH!! * * 2.0d2500/01/15 KG 2.3.3x compat from Andreas Schultz * * set unique_id. Disable RETRY message. * * 2.0d2600/01/29 KG Go to new EH. * * 2.0d2700/01/31 KG ... but maintain 2.0 compat. * * and fix DCB freeing * * 2.0d2800/02/14 KG Queue statistics fixed, dump special cmd* * Waiting_Timer for failed StartSCSI * * New EH: Don't return cmnds to ML on RST * * Use old EH (don't have new EH fns yet) * * Reset: Unlock, but refuse to queue * * 2.3 __setup function * * 2.0e 00/05/22 KG Return residual for 2.3 * * 2.0e1 00/05/25 KG Compile fixes for 2.3.99 * * 2.0e2 00/05/27 KG Jeff Garzik's pci_enable_device() * * 2.0e3 00/09/29 KG Some 2.4 changes. Don't try Sync Nego * * before INQUIRY has reported ability. * * Recognise INQUIRY as scanning command. * * 2.0e4 00/10/13 KG Allow compilation into 2.4 kernel * * 2.0e5 00/11/17 KG Store Inq.flags in DCB * * 2.0e6 00/11/22 KG 2.4 init function (Thx to O.Schumann) * * 2.4 PCI device table (Thx to A.Richter) * * 2.0e7 00/11/28 KG Allow overriding of BIOS settings * * 2.0f 00/12/20 KG Handle failed INQUIRYs during scan * * 2.1a 03/11/29 GL, KG Initial fixing for 2.6. Convert to * * use the current PCI-mapping API, update * * command-queuing. * * 2.1b 04/04/13 GL Fix for 64-bit platforms * * 2.1b1 04/01/31 GL (applied 05.04) Remove internal * * command-queuing. * * 2.1b2 04/02/01 CH (applied 05.04) Fix error-handling * * 2.1c 04/05/23 GL Update to use the new pci_driver API, * * some scsi EH updates, more cleanup. * * 2.1d 04/05/27 GL Moved setting of scan_devices to * * slave_alloc/_configure/_destroy, as * * suggested by CH. * ***********************************************************************//* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */#define DC390_IRQ SA_SHIRQ /* | SA_INTERRUPT *//* DEBUG options *///#define DC390_DEBUG0//#define DC390_DEBUG1//#define DC390_DCBDEBUG//#define DC390_PARSEDEBUG//#define DC390_REMOVABLEDEBUG//#define DC390_LOCKDEBUG//#define NOP do{}while(0)#define C_NOP/* Debug definitions */#ifdef DC390_DEBUG0# define DEBUG0(x) x#else# define DEBUG0(x) C_NOP#endif#ifdef DC390_DEBUG1# define DEBUG1(x) x#else# define DEBUG1(x) C_NOP#endif#ifdef DC390_DCBDEBUG# define DCBDEBUG(x) x#else# define DCBDEBUG(x) C_NOP#endif#ifdef DC390_PARSEDEBUG# define PARSEDEBUG(x) x#else# define PARSEDEBUG(x) C_NOP#endif#ifdef DC390_REMOVABLEDEBUG# define REMOVABLEDEBUG(x) x#else# define REMOVABLEDEBUG(x) C_NOP#endif#define DCBDEBUG1(x) C_NOP#include <linux/config.h>#include <linux/module.h>#include <linux/delay.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/pci.h>#include <linux/proc_fs.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/blkdev.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/init.h>#include <linux/spinlock.h>#include <asm/io.h>#include <scsi/scsi.h>#include <scsi/scsi_cmnd.h>#include <scsi/scsi_device.h>#include <scsi/scsi_host.h>#include <scsi/scsicam.h>#define DC390_BANNER "Tekram DC390/AM53C974"#define DC390_VERSION "2.1d 2004-05-27"#define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI static struct pci_device_id tmscsim_pci_tbl[] = { { .vendor = PCI_VENDOR_ID_AMD, .device = PCI_DEVICE_ID_AMD53C974, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, { } /* Terminating entry */};MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);#include "tmscsim.h"static u8 dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB );static void dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_Status_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_MsgOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_DataOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_DataInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_CommandPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_StatusPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_MsgOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_MsgInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_Nop_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_Nop_1( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);static void dc390_SetXferRate( struct dc390_acb* pACB, struct dc390_dcb* pDCB );static void dc390_Disconnect( struct dc390_acb* pACB );static void dc390_Reselect( struct dc390_acb* pACB );static void dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB );static void dc390_DoingSRB_Done( struct dc390_acb* pACB, struct scsi_cmnd * cmd);static void dc390_ScsiRstDetect( struct dc390_acb* pACB );static void dc390_ResetSCSIBus( struct dc390_acb* pACB );static void dc390_EnableMsgOut_Abort(struct dc390_acb*, struct dc390_srb*);static irqreturn_t do_DC390_Interrupt( int, void *, struct pt_regs *);static int dc390_initAdapter(struct Scsi_Host *psh, unsigned long io_port, u8 Irq, u8 index );static void dc390_updateDCB (struct dc390_acb* pACB, struct dc390_dcb* pDCB);static struct dc390_acb* dc390_pACB_start= NULL;static struct dc390_acb* dc390_pACB_current = NULL;static u32 dc390_laststatus = 0;static u8 dc390_adapterCnt = 0;/* Startup values, to be overriden on the commandline */static int tmscsim[] = {-2, -2, -2, -2, -2, -2};static int tmscsim_paramnum = ARRAY_SIZE(tmscsim);module_param_array(tmscsim, int, tmscsim_paramnum, 0);MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");MODULE_AUTHOR("C.L. Huang / Kurt Garloff");MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");MODULE_LICENSE("GPL");MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");static void *dc390_phase0[]={ dc390_DataOut_0, dc390_DataIn_0, dc390_Command_0, dc390_Status_0, dc390_Nop_0, dc390_Nop_0, dc390_MsgOut_0, dc390_MsgIn_0, dc390_Nop_1 };static void *dc390_phase1[]={ dc390_DataOutPhase, dc390_DataInPhase, dc390_CommandPhase, dc390_StatusPhase, dc390_Nop_0, dc390_Nop_0, dc390_MsgOutPhase, dc390_MsgInPhase, dc390_Nop_1 };#ifdef DC390_DEBUG1static char* dc390_p0_str[] = { "dc390_DataOut_0", "dc390_DataIn_0", "dc390_Command_0", "dc390_Status_0", "dc390_Nop_0", "dc390_Nop_0", "dc390_MsgOut_0", "dc390_MsgIn_0", "dc390_Nop_1" }; static char* dc390_p1_str[] = { "dc390_DataOutPhase", "dc390_DataInPhase", "dc390_CommandPhase", "dc390_StatusPhase", "dc390_Nop_0", "dc390_Nop_0", "dc390_MsgOutPhase", "dc390_MsgInPhase", "dc390_Nop_1" };#endif /* Devices erroneously pretending to be able to do TagQ */static u8 dc390_baddevname1[2][28] ={ "SEAGATE ST3390N 9546", "HP C3323-300 4269"};#define BADDEVCNT 2static char* dc390_adapname = "DC390";static u8 dc390_eepromBuf[MAX_ADAPTER_NUM][EE_LEN];static u8 dc390_clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20};static u8 dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20};/*********************************************************************** * Functions for access to DC390 EEPROM * and some to emulate it * **********************************************************************/static void __devinit dc390_EnDisableCE(u8 mode, struct pci_dev *pdev, u8 *regval){ u8 bval; bval = 0; if(mode == ENABLE_CE) *regval = 0xc0; else *regval = 0x80; pci_write_config_byte(pdev, *regval, bval); if(mode == DISABLE_CE) pci_write_config_byte(pdev, *regval, bval); udelay(160);}/* Override EEprom values with explicitly set values */static void __devinit dc390_EEprom_Override (u8 index){ u8 *ptr = (u8 *) dc390_eepromBuf[index]; u8 id; /* Adapter Settings */ if (tmscsim[0] != -2) ptr[EE_ADAPT_SCSI_ID] = (u8)tmscsim[0]; /* Adapter ID */ if (tmscsim[3] != -2) ptr[EE_MODE2] = (u8)tmscsim[3];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?