📄 tmscsim.c
字号:
pDCB->CtrlR4 |= pACB->glitch_cfg; pDCB = pDCB->pNextDCB; } while( pdcb != pDCB ); pACB->ACBFlag &= ~(RESET_DEV | RESET_DONE | RESET_DETECT);}#if 0/* Moves all SRBs from Going to Waiting for all DCBs */static void dc390_RecoverSRB( PACB pACB ){ PDCB pDCB, pdcb; PSRB psrb, psrb2; UINT cnt, i; pDCB = pACB->pLinkDCB; if( !pDCB ) return; pdcb = pDCB; do { cnt = pdcb->GoingSRBCnt; psrb = pdcb->pGoingSRB; for (i=0; i<cnt; i++) { psrb2 = psrb; psrb = psrb->pNextSRB;/* dc390_RewaitSRB( pDCB, psrb ); */ if( pdcb->pWaitingSRB ) { psrb2->pNextSRB = pdcb->pWaitingSRB; pdcb->pWaitingSRB = psrb2; } else { pdcb->pWaitingSRB = psrb2; pdcb->pWaitLast = psrb2; psrb2->pNextSRB = NULL; } } pdcb->GoingSRBCnt = 0; pdcb->pGoingSRB = NULL; pdcb->TagMask = 0; pdcb = pdcb->pNextDCB; } while( pdcb != pDCB );}#endif/*********************************************************************** * Function : int DC390_reset (Scsi_Cmnd *cmd, ...) * * Purpose : perform a hard reset on the SCSI bus * * Inputs : cmd - command which caused the SCSI RESET * resetFlags - how hard to try * * Returns : 0 on success. ***********************************************************************/int DC390_reset (Scsi_Cmnd *cmd, unsigned int resetFlags){ UCHAR bval; DC390_AFLAGS PACB pACB = (PACB) cmd->host->hostdata; printk(KERN_INFO "DC390: RESET ... "); DC390_LOCK_ACB; if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer); bval = DC390_read8 (CtrlReg1); bval |= DIS_INT_ON_SCSI_RST; DC390_write8 (CtrlReg1, bval); /* disable IRQ on bus reset */ pACB->ACBFlag |= RESET_DEV; dc390_ResetSCSIBus( pACB ); dc390_ResetDevParam( pACB ); udelay (1000); pACB->pScsiHost->last_reset = jiffies + 3*HZ/2 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]; DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); DC390_read8 (INT_Status); /* Reset Pending INT */ dc390_DoingSRB_Done( pACB, cmd ); /* dc390_RecoverSRB (pACB); */ pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; bval = DC390_read8 (CtrlReg1); bval &= ~DIS_INT_ON_SCSI_RST; DC390_write8 (CtrlReg1, bval); /* re-enable interrupt */ dc390_Waiting_process( pACB ); printk("done\n"); DC390_UNLOCK_ACB; return( SCSI_RESET_SUCCESS );}#include "scsiiom.c"/*********************************************************************** * Function : static void dc390_initDCB() * * Purpose : initialize the internal structures for a DCB (to be malloced) * * Inputs : SCSI id and lun ***********************************************************************/void dc390_initDCB( PACB pACB, PDCB *ppDCB, UCHAR id, UCHAR lun ){ PEEprom prom; UCHAR index; PDCB pDCB, pDCB2; pDCB = kmalloc (sizeof(DC390_DCB), GFP_ATOMIC); DCBDEBUG(printk (KERN_INFO "DC390: alloc mem for DCB (ID %i, LUN %i): %p\n" \ id, lun, pDCB);) *ppDCB = pDCB; pDCB2 = 0; if (!pDCB) return; if( pACB->DCBCnt == 0 ) { pACB->pLinkDCB = pDCB; pACB->pDCBRunRobin = pDCB; } else { pACB->pLastDCB->pNextDCB = pDCB; }; pACB->DCBCnt++; pDCB->pNextDCB = pACB->pLinkDCB; pACB->pLastDCB = pDCB; pDCB->pDCBACB = pACB; pDCB->TargetID = id; pDCB->TargetLUN = lun; pDCB->pWaitingSRB = NULL; pDCB->pGoingSRB = NULL; pDCB->GoingSRBCnt = 0; pDCB->WaitSRBCnt = 0; pDCB->pActiveSRB = NULL; pDCB->TagMask = 0; pDCB->MaxCommand = 1; index = pACB->AdapterIndex; pDCB->DCBFlag = 0; /* Is there a corresp. LUN==0 device ? */ if (lun != 0) pDCB2 = dc390_findDCB (pACB, id, 0); prom = (PEEprom) &dc390_eepromBuf[index][id << 2]; /* Some values are for all LUNs: Copy them */ /* In a clean way: We would have an own structure for a SCSI-ID */ if (pDCB2) { pDCB->DevMode = pDCB2->DevMode; pDCB->SyncMode = pDCB2->SyncMode; pDCB->SyncPeriod = pDCB2->SyncPeriod; pDCB->SyncOffset = pDCB2->SyncOffset; pDCB->NegoPeriod = pDCB2->NegoPeriod; pDCB->CtrlR3 = pDCB2->CtrlR3; pDCB->CtrlR4 = pDCB2->CtrlR4; pDCB->Inquiry7 = pDCB2->Inquiry7; } else { pDCB->DevMode = prom->EE_MODE1; pDCB->SyncMode = 0; pDCB->SyncPeriod = 0; pDCB->SyncOffset = 0; pDCB->NegoPeriod = (dc390_clock_period1[prom->EE_SPEED] * 25) >> 2; pDCB->CtrlR3 = FAST_CLK; pDCB->CtrlR4 = pACB->glitch_cfg | CTRL4_RESERVED; if( dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION) pDCB->CtrlR4 |= NEGATE_REQACKDATA | NEGATE_REQACK; pDCB->Inquiry7 = 0; } pACB->DCBmap[id] |= (1 << lun); dc390_updateDCB(pACB, pDCB);}/*********************************************************************** * Function : static void dc390_updateDCB() * * Purpose : Set the configuration dependent DCB parameters ***********************************************************************/void dc390_updateDCB (PACB pACB, PDCB pDCB){ pDCB->SyncMode &= EN_TAG_QUEUEING | SYNC_NEGO_DONE /*| EN_ATN_STOP*/; if (pDCB->DevMode & TAG_QUEUEING_) { //if (pDCB->SyncMode & EN_TAG_QUEUEING) pDCB->MaxCommand = pACB->TagMaxNum; } else { pDCB->SyncMode &= ~EN_TAG_QUEUEING; pDCB->MaxCommand = 1; }; if( pDCB->DevMode & SYNC_NEGO_ ) pDCB->SyncMode |= SYNC_ENABLE; else { pDCB->SyncMode &= ~(SYNC_NEGO_DONE | SYNC_ENABLE); pDCB->SyncOffset &= ~0x0f; }; //if (! (pDCB->DevMode & EN_DISCONNECT_)) pDCB->SyncMode &= ~EN_ATN_STOP; pDCB->CtrlR1 = pACB->pScsiHost->this_id; if( pDCB->DevMode & PARITY_CHK_ ) pDCB->CtrlR1 |= PARITY_ERR_REPO;}; /*********************************************************************** * Function : static void dc390_updateDCBs () * * Purpose : Set the configuration dependent DCB params for all DCBs ***********************************************************************/static void dc390_updateDCBs (PACB pACB){ int i; PDCB pDCB = pACB->pLinkDCB; for (i = 0; i < pACB->DCBCnt; i++) { dc390_updateDCB (pACB, pDCB); pDCB = pDCB->pNextDCB; };}; /*********************************************************************** * Function : static void dc390_initSRB() * * Purpose : initialize the internal structures for a given SRB * * Inputs : psrb - pointer to this scsi request block structure ***********************************************************************/static void __inline__ dc390_initSRB( PSRB psrb ){ /* psrb->PhysSRB = virt_to_phys( psrb ); */}void dc390_linkSRB( PACB pACB ){ UINT count, i; count = pACB->SRBCount; for( i=0; i<count; i++) { if( i != count-1 ) pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1]; else pACB->SRB_array[i].pNextSRB = NULL; dc390_initSRB( &pACB->SRB_array[i] ); }}/*********************************************************************** * Function : static void dc390_initACB () * * Purpose : initialize the internal structures for a given SCSI host * * Inputs : psh - pointer to this host adapter's structure * io_port, Irq, index: Resources and adapter index ***********************************************************************/void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index){ PACB pACB; UCHAR i; DC390_AFLAGS psh->can_queue = MAX_CMD_QUEUE; psh->cmd_per_lun = MAX_CMD_PER_LUN; psh->this_id = (int) dc390_eepromBuf[index][EE_ADAPT_SCSI_ID]; psh->io_port = io_port; psh->n_io_port = 0x80; psh->irq = Irq;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,50) psh->base = io_port;#else psh->base = (char*)io_port;#endif psh->unique_id = io_port; psh->dma_channel = -1; psh->last_reset = jiffies; pACB = (PACB) psh->hostdata; DC390_LOCKA_INIT; DC390_LOCK_ACB; pACB->pScsiHost = psh; pACB->IOPortBase = (USHORT) io_port; pACB->IRQLevel = Irq; DEBUG0(printk (KERN_INFO "DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n", \ index, psh->this_id, (int)io_port, Irq);) psh->max_id = 8; if( psh->max_id - 1 == dc390_eepromBuf[index][EE_ADAPT_SCSI_ID] ) psh->max_id--; psh->max_lun = 1; if( dc390_eepromBuf[index][EE_MODE2] & LUN_CHECK ) psh->max_lun = 8; pACB->pLinkDCB = NULL; pACB->pDCBRunRobin = NULL; pACB->pActiveDCB = NULL; pACB->pFreeSRB = pACB->SRB_array; pACB->SRBCount = MAX_SRB_CNT; pACB->QueryCnt = 0; pACB->pQueryHead = NULL; pACB->AdapterIndex = index; pACB->status = 0; psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID]; pACB->DeviceCnt = 0; pACB->DCBCnt = 0; pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM]; pACB->ACBFlag = 0; pACB->scan_devices = 1; pACB->MsgLen = 0; pACB->Ignore_IRQ = 0; pACB->Gmode2 = dc390_eepromBuf[index][EE_MODE2]; dc390_linkSRB( pACB ); pACB->pTmpSRB = &pACB->TmpSRB; dc390_initSRB( pACB->pTmpSRB ); for(i=0; i<MAX_SCSI_ID; i++) pACB->DCBmap[i] = 0; pACB->sel_timeout = SEL_TIMEOUT; pACB->glitch_cfg = EATER_25NS; pACB->Cmds = pACB->CmdInQ = pACB->CmdOutOfSRB = 0; pACB->SelLost = pACB->SelConn = 0; init_timer (&pACB->Waiting_Timer);}/*********************************************************************** * Function : static int dc390_initAdapter () * * Purpose : initialize the SCSI chip ctrl registers * * Inputs : psh - pointer to this host adapter's structure * io_port, Irq, index: Resources * * Outputs: 0 on success, -1 on error ***********************************************************************/int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index){ PACB pACB, pACB2; UCHAR dstate; int i; pACB = (PACB) psh->hostdata; if (check_region (io_port, psh->n_io_port)) { printk(KERN_ERR "DC390: register IO ports error!\n"); return( -1 ); } else request_region (io_port, psh->n_io_port, "tmscsim"); DC390_read8_ (INT_Status, io_port); /* Reset Pending INT */ if( (i = request_irq(Irq, do_DC390_Interrupt, DC390_IRQ, "tmscsim", pACB) )) { printk(KERN_ERR "DC390: register IRQ error!\n"); release_region (io_port, psh->n_io_port); return( -1 ); } if( !dc390_pACB_start ) { pACB2 = NULL; dc390_pACB_start = pACB; dc390_pACB_current = pACB; pACB->pNextACB = NULL; } else { pACB2 = dc390_pACB_current; dc390_pACB_current->pNextACB = pACB; dc390_pACB_current = pACB; pACB->pNextACB = NULL; }; DC390_write8 (CtrlReg1, DIS_INT_ON_SCSI_RST | psh->this_id); /* Disable SCSI bus reset interrupt */ if (pACB->Gmode2 & RST_SCSI_BUS) { dc390_ResetSCSIBus( pACB ); udelay (1000); pACB->pScsiHost->last_reset = jiffies + HZ/2 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]; /* for( i=0; i<(500 + 1000*dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]); i++ ) udelay(1000); */ }; pACB->ACBFlag = 0; DC390_read8 (INT_Status); /* Reset Pending INT */ DC390_write8 (Scsi_TimeOut, SEL_TIMEOUT); /* 250ms selection timeout */ DC390_write8 (Clk_Factor, CLK_FREQ_40MHZ); /* Conversion factor = 0 , 40MHz clock */ DC390_write8 (ScsiCmd, NOP_CMD); /* NOP cmd - clear command register */ DC390_write8 (CtrlReg2, EN_FEATURE+EN_SCSI2_CMD); /* Enable Feature and SCSI-2 */ DC390_write8 (CtrlReg3, FAST_CLK); /* fast clock */ DC390_write8 (CtrlReg4, pACB->glitch_cfg | /* glitch eater */ (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION) ? NEGATE_REQACKDATA : 0); /* Negation */ DC390_write8 (CtcReg_High, 0); /* Clear Transfer Count High: ID */ DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT); dstate = DC390_read8
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -