tmscsim.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,632 行 · 第 1/4 页

C
1,632
字号
    if (tmscsim[5] != -2)	ptr[EE_DELAY] = tmscsim[5];			/* Reset delay */    if (tmscsim[4] != -2)	ptr[EE_TAG_CMD_NUM] = (u8)tmscsim[4];	/* Tagged Cmds */        /* Device Settings */    for (id = 0; id < MAX_SCSI_ID; id++)    {	if (tmscsim[2] != -2)		ptr[id<<2] = (u8)tmscsim[2];		/* EE_MODE1 */	if (tmscsim[1] != -2)		ptr[(id<<2) + 1] = (u8)tmscsim[1];	/* EE_Speed */    }}/* Handle "-1" case */static void __devinit 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");	}}static int __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 __devinit 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;}#ifndef MODULE/* Override defaults on cmdline: * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped) */static int __init dc390_setup (char *str){		int ints[8];	int i, im;	(void)get_options (str, ARRAY_SIZE(ints), ints);	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 (); */	return 1;}__setup("tmscsim=", dc390_setup);#endifstatic void __devinit dc390_EEpromOutDI(struct pci_dev *pdev, u8 *regval, u8 Carry){    u8 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 u8 __devinit dc390_EEpromInDO(struct pci_dev *pdev){    u8 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 u16 __devinit dc390_EEpromGetData1(struct pci_dev *pdev){    u8 i;    u8 carryFlag;    u16 wval;    wval = 0;    for(i=0; i<16; i++)    {	wval <<= 1;	carryFlag = dc390_EEpromInDO(pdev);	wval |= carryFlag;    }    return(wval);}static void __devinit dc390_Prepare(struct pci_dev *pdev, u8 *regval, u8 EEpromCmd){    u8 i,j;    u8 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 __devinit dc390_ReadEEprom(struct pci_dev *pdev, u16 *ptr){    u8   regval,cmd;    u8   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 __devinit dc390_interpret_delay (u8 index){    char interpd [] = {1,3,5,10,16,30,60,120};    dc390_eepromBuf[index][EE_DELAY] = interpd [dc390_eepromBuf[index][EE_DELAY]];}static u8 __devinit dc390_CheckEEpromCheckSum(struct pci_dev *pdev, u8 index){    u8  i;    char  EEbuf[128];    u16 wval, *ptr = (u16 *)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 struct dc390_dcb __inline__ *dc390_findDCB ( struct dc390_acb* pACB, u8 id, u8 lun){   struct dc390_dcb* pDCB = pACB->pLinkDCB; if (!pDCB) return NULL;   while (pDCB->TargetID != id || pDCB->TargetLUN != lun)     {	pDCB = pDCB->pNextDCB;	if (pDCB == pACB->pLinkDCB)	     return NULL;     }   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 unnecessary!) * - 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 *//* Return next free SRB */static __inline__ struct dc390_srb* dc390_Free_get ( struct dc390_acb* pACB ){    struct dc390_srb*   pSRB;    pSRB = pACB->pFreeSRB;    DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB));    if( pSRB )    {	pACB->pFreeSRB = pSRB->pNextSRB;	pSRB->pNextSRB = NULL;    }    return( pSRB );}/* Insert SRB oin top of free list */static __inline__ void dc390_Free_insert (struct dc390_acb* pACB, struct dc390_srb* pSRB){    DEBUG0(printk ("DC390: Free SRB %p\n", pSRB));    pSRB->pNextSRB = pACB->pFreeSRB;    pACB->pFreeSRB = pSRB;}/* Inserts a SRB to the top of the Waiting list */static __inline__ void dc390_Waiting_insert ( struct dc390_dcb* pDCB, struct dc390_srb* pSRB ){    DEBUG0(printk ("DC390: Insert pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid));    pSRB->pNextSRB = pDCB->pWaitingSRB;    if (!pDCB->pWaitingSRB)	pDCB->pWaitLast = pSRB;    pDCB->pWaitingSRB = pSRB;    pDCB->WaitSRBCnt++;}/* Queue SRB to waiting list */static __inline__ void dc390_Waiting_append ( struct dc390_dcb* pDCB, struct dc390_srb* pSRB){	DEBUG0(printk ("DC390: Append pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid));    if( pDCB->pWaitingSRB )	pDCB->pWaitLast->pNextSRB = pSRB;    else	pDCB->pWaitingSRB = pSRB;    pDCB->pWaitLast = pSRB;    pSRB->pNextSRB = NULL;    pDCB->WaitSRBCnt++;    pDCB->pDCBACB->CmdInQ++;}static __inline__ void dc390_Going_append (struct dc390_dcb* pDCB, struct dc390_srb* pSRB){    pDCB->GoingSRBCnt++;    DEBUG0(printk("DC390: Append SRB %p to Going\n", pSRB));    /* Append to the list of Going commands */    if( pDCB->pGoingSRB )	pDCB->pGoingLast->pNextSRB = pSRB;    else	pDCB->pGoingSRB = pSRB;    pDCB->pGoingLast = pSRB;    /* No next one in sent list */    pSRB->pNextSRB = NULL;}static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_srb* pSRB){	DEBUG0(printk("DC390: Remove SRB %p from Going\n", pSRB));   if (pSRB == pDCB->pGoingSRB)	pDCB->pGoingSRB = pSRB->pNextSRB;   else     {	struct dc390_srb* psrb = pDCB->pGoingSRB;	while (psrb && psrb->pNextSRB != pSRB)	  psrb = psrb->pNextSRB;	if (!psrb) 	  { printk (KERN_ERR "DC390: Remove non-ex. SRB %p from Going!\n", pSRB); return; }	psrb->pNextSRB = pSRB->pNextSRB;	if (pSRB == pDCB->pGoingLast)	  pDCB->pGoingLast = psrb;     }   pDCB->GoingSRBCnt--;}/* Moves SRB from Going list to the top of Waiting list */static void dc390_Going_to_Waiting ( struct dc390_dcb* pDCB, struct dc390_srb* pSRB ){    DEBUG0(printk(KERN_INFO "DC390: Going_to_Waiting (SRB %p) pid = %li\n", pSRB, pSRB->pcmd->pid));    /* Remove SRB from Going */    dc390_Going_remove (pDCB, pSRB);    /* Insert on top of Waiting */    dc390_Waiting_insert (pDCB, pSRB);    /* Tag Mask must be freed elsewhere ! (KG, 99/06/18) */}/* Moves first SRB from Waiting list to Going list */static __inline__ void dc390_Waiting_to_Going ( struct dc390_dcb* pDCB, struct dc390_srb* pSRB ){		/* Remove from waiting list */	DEBUG0(printk("DC390: Remove SRB %p from head of Waiting\n", pSRB));	pDCB->pWaitingSRB = pSRB->pNextSRB;	if( !pDCB->pWaitingSRB ) pDCB->pWaitLast = NULL;	pDCB->WaitSRBCnt--;	dc390_Going_append (pDCB, pSRB);}static void DC390_waiting_timed_out (unsigned long ptr);/* Sets the timer to wake us up */static void dc390_waiting_timer (struct dc390_acb* pACB, unsigned long to){	if (timer_pending (&pACB->Waiting_Timer)) return;	init_timer (&pACB->Waiting_Timer);	pACB->Waiting_Timer.function = DC390_waiting_timed_out;	pACB->Waiting_Timer.data = (unsigned long)pACB;	if (time_before (jiffies + to, pACB->pScsiHost->last_reset))		pACB->Waiting_Timer.expires = pACB->pScsiHost->last_reset + 1;	else		pACB->Waiting_Timer.expires = jiffies + to + 1;	add_timer (&pACB->Waiting_Timer);}/* Send the next command from the waiting list to the bus */static void dc390_Waiting_process ( struct dc390_acb* pACB ){    struct dc390_dcb *ptr, *ptr1;    struct dc390_srb *pSRB;    if( (pACB->pActiveDCB) || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) )	return;    if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);    ptr = pACB->pDCBRunRobin;    if( !ptr )      {	ptr = pACB->pLinkDCB;	pACB->pDCBRunRobin = ptr;      }    ptr1 = ptr;    if (!ptr1) return;    do       {	pACB->pDCBRunRobin = ptr1->pNextDCB;	if( !( pSRB = ptr1->pWaitingSRB ) ||	    ( ptr1->MaxCommand <= ptr1->GoingSRBCnt ))	  ptr1 = ptr1->pNextDCB;	else	  {	    /* Try to send to the bus */	    if( !dc390_StartSCSI(pACB, ptr1, pSRB) )	      dc390_Waiting_to_Going (ptr1, pSRB);	    else	      dc390_waiting_timer (pACB, HZ/5);	    break;	  }      } while (ptr1 != ptr);    return;}/* Wake up waiting queue */static void DC390_waiting_timed_out (unsigned long ptr){	struct dc390_acb* pACB = (struct dc390_acb*)ptr;	unsigned long iflags;	DEBUG0(printk ("DC390: Debug: Waiting queue woken up by timer!\n"));	spin_lock_irqsave(pACB->pScsiHost->host_lock, iflags);	dc390_Waiting_process (pACB);	spin_unlock_irqrestore(pACB->pScsiHost->host_lock, iflags);}/*********************************************************************** * Function: static void dc390_SendSRB (struct dc390_acb* pACB, struct dc390_srb* pSRB) * * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB) * ***********************************************************************/static void dc390_SendSRB( struct dc390_acb* pACB, struct dc390_srb* pSRB ){    struct dc390_dcb*   pDCB;    pDCB = pSRB->pSRBDCB;    if( (pDCB->MaxCommand <= pDCB->GoingSRBCnt) || (pACB->pActiveDCB) ||

⌨️ 快捷键说明

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