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, ®val); dc390_Prepare(pdev, ®val, cmd++); *ptr++ = dc390_EEpromGetData1(pdev); dc390_EnDisableCE(DISABLE_CE, pdev, ®val); }}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 + -
显示快捷键?