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

📄 tmscsim.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 if (error) { printk (KERN_ERR "DC390_detect: Error reading PCI config registers!\n"); continue; }#endif #include "tmscsim.h"#ifndef __init# define __init#endifUCHAR dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB );void dc390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);void dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);void dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);void dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);void dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus);static void dc390_SetXferRate( PACB pACB, PDCB pDCB );void dc390_Disconnect( PACB pACB );void dc390_Reselect( PACB pACB );void dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB );void dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd );static void dc390_ScsiRstDetect( PACB pACB );static void dc390_ResetSCSIBus( PACB pACB );static void __inline__ dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB );static void __inline__ dc390_InvalidCmd( PACB pACB );static void __inline__ dc390_EnableMsgOut_Abort (PACB, PSRB);static void dc390_remove_dev (PACB pACB, PDCB pDCB);void do_DC390_Interrupt( int, void *, struct pt_regs *);int    dc390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, UCHAR index );void   dc390_initDCB( PACB pACB, PDCB *ppDCB, UCHAR id, UCHAR lun);void   dc390_updateDCB (PACB pACB, PDCB pDCB);#ifdef MODULE static int DC390_release(struct Scsi_Host *host); static int dc390_shutdown (struct Scsi_Host *host);#endif//static PSHT	dc390_pSHT_start = NULL;//static PSH	dc390_pSH_start = NULL;//static PSH	dc390_pSH_current = NULL;static PACB	dc390_pACB_start= NULL;static PACB	dc390_pACB_current = NULL;static ULONG	dc390_lastabortedpid = 0;static UINT	dc390_laststatus = 0;static UCHAR	dc390_adapterCnt = 0;/* Startup values, to be overriden on the commandline */int tmscsim[] = {-2, -2, -2, -2, -2, -2};# if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)MODULE_PARM(tmscsim, "1-6i");MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");# endif#if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)MODULE_AUTHOR("C.L. Huang / Kurt Garloff");MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");#endifstatic PVOID 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 PVOID 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 */UCHAR  dc390_baddevname1[2][28] ={       "SEAGATE ST3390N         9546",       "HP      C3323-300       4269"};#define BADDEVCNT	2static char*  dc390_adapname = "DC390";UCHAR  dc390_eepromBuf[MAX_ADAPTER_NUM][EE_LEN];UCHAR  dc390_clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20};UCHAR  dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20};#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,30)struct proc_dir_entry	DC390_proc_scsi_tmscsim ={       PROC_SCSI_DC390T, 7 ,"tmscsim",       S_IFDIR | S_IRUGO | S_IXUGO, 2       };#endif/*********************************************************************** * Functions for access to DC390 EEPROM * and some to emulate it * **********************************************************************/static void __init dc390_EnDisableCE( UCHAR mode, PDEVDECL, PUCHAR regval ){    UCHAR 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 __init dc390_EEprom_Override (UCHAR index){    PUCHAR ptr;    UCHAR  id;    ptr = (PUCHAR) dc390_eepromBuf[index];        /* Adapter Settings */    if (tmscsim[0] != -2)	ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0];	/* Adapter ID */    if (tmscsim[3] != -2)	ptr[EE_MODE2] = (UCHAR)tmscsim[3];    if (tmscsim[5] != -2)	ptr[EE_DELAY] = tmscsim[5];			/* Reset delay */    if (tmscsim[4] != -2)	ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4];	/* Tagged Cmds */        /* Device Settings */    for (id = 0; id < MAX_SCSI_ID; id++)    {	if (tmscsim[2] != -2)		ptr[id<<2] = (UCHAR)tmscsim[2];		/* EE_MODE1 */	if (tmscsim[1] != -2)		ptr[(id<<2) + 1] = (UCHAR)tmscsim[1];	/* EE_Speed */    };}/* Handle "-1" case */static void __init dc390_check_for_safe_settings (void){	if (tmscsim[0] == -1 || tmscsim[0] > 15) /* modules-2.0.0 passes -1 as string */	{		tmscsim[0] = 7; tmscsim[1] = 4;		tmscsim[2] = 0x09; tmscsim[3] = 0x0f;		tmscsim[4] = 2; tmscsim[5] = 10;		printk (KERN_INFO "DC390: Using safe settings.\n");	}}#ifndef CONFIG_SCSI_DC390T_NOGENSUPPint __initdata tmscsim_def[] = {7, 0 /* 10MHz */,		PARITY_CHK_ | SEND_START_ | EN_DISCONNECT_		| SYNC_NEGO_ | TAG_QUEUEING_,		MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION		/* | NO_SEEK */# ifdef CONFIG_SCSI_MULTI_LUN		| LUN_CHECK# endif		, 3 /* 16 Tags per LUN */, 1 /* s delay after Reset */ };/* Copy defaults over set values where missing */static void __init dc390_fill_with_defaults (void){	int i;	PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x %08x\n", tmscsim[0],\		      tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4], tmscsim[5]);)	for (i = 0; i < 6; i++)	{		if (tmscsim[i] < 0 || tmscsim[i] > 255)			tmscsim[i] = tmscsim_def[i];	}	/* Sanity checks */	if (tmscsim[0] >   7) tmscsim[0] =   7;	if (tmscsim[1] >   7) tmscsim[1] =   4;	if (tmscsim[4] >   5) tmscsim[4] =   4;	if (tmscsim[5] > 180) tmscsim[5] = 180;};#endif/* Override defaults on cmdline: * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped) */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13)void __init dc390_setup (char *str){		int ints[8];	int i, im;	(void)get_options (str, ARRAY_SIZE(ints), ints);#elsevoid __init dc390_setup (char *str, int *ints){	int i, im;#endif	im = ints[0];	if (im > 6)	{		printk (KERN_NOTICE "DC390: ignore extra params!\n");		im = 6;	};	for (i = 0; i < im; i++)		tmscsim[i] = ints[i+1];	/* dc390_checkparams (); */};#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)#ifndef MODULE__setup("tmscsim=", dc390_setup);#endif#endifstatic void __init dc390_EEpromOutDI( PDEVDECL, PUCHAR regval, UCHAR Carry ){    UCHAR bval;    bval = 0;    if(Carry)    {	bval = 0x40;	*regval = 0x80;	PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);    }    udelay(160);    bval |= 0x80;    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);    udelay(160);    bval = 0;    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);    udelay(160);}static UCHAR __init dc390_EEpromInDO( PDEVDECL ){    UCHAR bval;    PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x80);    udelay(160);    PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x40);    udelay(160);    PCI_READ_CONFIG_BYTE(PDEV, 0x00, &bval);    if(bval == 0x22)	return(1);    else	return(0);}static USHORT __init dc390_EEpromGetData1( PDEVDECL ){    UCHAR i;    UCHAR carryFlag;    USHORT wval;    wval = 0;    for(i=0; i<16; i++)    {	wval <<= 1;	carryFlag = dc390_EEpromInDO(PDEV);	wval |= carryFlag;    }    return(wval);}static void __init dc390_Prepare( PDEVDECL, PUCHAR regval, UCHAR EEpromCmd ){    UCHAR i,j;    UCHAR carryFlag;    carryFlag = 1;    j = 0x80;    for(i=0; i<9; i++)    {	dc390_EEpromOutDI(PDEV,regval,carryFlag);	carryFlag = (EEpromCmd & j) ? 1 : 0;	j >>= 1;    }}static void __init dc390_ReadEEprom( PDEVDECL, PUSHORT ptr){    UCHAR   regval,cmd;    UCHAR   i;    cmd = EEPROM_READ;    for(i=0; i<0x40; i++)    {	dc390_EnDisableCE(ENABLE_CE, PDEV, &regval);	dc390_Prepare(PDEV, &regval, cmd++);	*ptr++ = dc390_EEpromGetData1(PDEV);	dc390_EnDisableCE(DISABLE_CE, PDEV, &regval);    }}static void __init dc390_interpret_delay (UCHAR index){    char interpd [] = {1,3,5,10,16,30,60,120};    dc390_eepromBuf[index][EE_DELAY] = interpd [dc390_eepromBuf[index][EE_DELAY]];};static UCHAR __init dc390_CheckEEpromCheckSum( PDEVDECL, UCHAR index ){    UCHAR  i;    char  EEbuf[128];    USHORT wval, *ptr = (PUSHORT)EEbuf;    dc390_ReadEEprom( PDEV, ptr );    memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID);    memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], 	    &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID);    dc390_interpret_delay (index);        wval = 0;    for(i=0; i<0x40; i++, ptr++)	wval += *ptr;    return (wval == 0x1234 ? 0 : 1);}/*********************************************************************** * Functions for the management of the internal structures  * (DCBs, SRBs, Queueing) * **********************************************************************/static PDCB __inline__ dc390_findDCB ( PACB pACB, UCHAR id, UCHAR lun){   PDCB pDCB = pACB->pLinkDCB; if (!pDCB) return 0;   while (pDCB->TargetID != id || pDCB->TargetLUN != lun)     {	pDCB = pDCB->pNextDCB;	if (pDCB == pACB->pLinkDCB)	  {	     DCBDEBUG(printk (KERN_WARNING "DC390: DCB not found (DCB=%p, DCBmap[%2x]=%2x)\n",		     pDCB, id, pACB->DCBmap[id]);)	     return 0;	  }     };   DCBDEBUG1( printk (KERN_DEBUG "DCB %p (%02x,%02x) found.\n",	\		      pDCB, pDCB->TargetID, pDCB->TargetLUN);)   return pDCB;};/* Queueing philosphy: * There are a couple of lists: * - Query: Contains the Scsi Commands not yet turned into SRBs (per ACB) *   (Note: For new EH, it is unecessary!) * - Waiting: Contains a list of SRBs not yet sent (per DCB) * - Free: List of free SRB slots *  * If there are no waiting commands for the DCB, the new one is sent to the bus * otherwise the oldest one is taken from the Waiting list and the new one is  * queued to the Waiting List *  * Lists are managed using two pointers and eventually a counter */#if 0/* Look for a SCSI cmd in a SRB queue */static PSRB dc390_find_cmd_in_SRBq (PSCSICMD cmd, PSRB queue){    PSRB q = queue;    while (q)    {	if (q->pcmd == cmd) return q;	q = q->pNextSRB;	if (q == queue) return 0;    }    return q;};#endif    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -