📄 tmscsim.c
字号:
pSRB->Segmentx.length = pcmd->request_bufflen; } else pSRB->SGcount = 0; pSRB->SGIndex = 0; pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; pSRB->MsgCnt = 0; if( pDCB->DevType != TYPE_TAPE ) pSRB->RetryCnt = 1; else pSRB->RetryCnt = 0; pSRB->SRBStatus = 0; pSRB->SRBFlag = 0; pSRB->SRBState = 0; pSRB->TotalXferredLen = 0; pSRB->SGPhysAddr = 0; pSRB->SGToBeXferLen = 0; pSRB->ScsiPhase = 0; pSRB->EndMessage = 0; SendSRB( pcmd, pACB, pSRB ); restore_flags(flags); return;}/*********************************************************************** * Function: * DC390_bios_param * * Description: * Return the disk geometry for the given SCSI device. ***********************************************************************/#ifdef VERSION_ELF_1_2_13int DC390_bios_param(Disk *disk, int devno, int geom[])#elseint DC390_bios_param(Disk *disk, kdev_t devno, int geom[])#endif{ int heads, sectors, cylinders; PACB pACB; pACB = (PACB) disk->device->host->hostdata; heads = 64; sectors = 32; cylinders = disk->capacity / (heads * sectors); if ( (pACB->Gmode2 & GREATER_1G) && (cylinders > 1024) ) { heads = 255; sectors = 63; cylinders = disk->capacity / (heads * sectors); } geom[0] = heads; geom[1] = sectors; geom[2] = cylinders; return (0);}/*********************************************************************** * Function : int DC390_abort (Scsi_Cmnd *cmd) * * Purpose : Abort an errant SCSI command * * Inputs : cmd - command to abort * * Returns : 0 on success, -1 on failure. ***********************************************************************/intDC390_abort (Scsi_Cmnd *cmd){ ULONG flags; PACB pACB; PDCB pDCB, pdcb; PSRB pSRB, psrb; USHORT count, i; PSCSICMD pcmd, pcmd1; int status;#ifdef DC390_DEBUG0 printk("DC390 : Abort Cmd.");#endif save_flags(flags); cli(); pACB = (PACB) cmd->host->hostdata; pDCB = pACB->pLinkDCB; pdcb = pDCB; while( (pDCB->UnitSCSIID != cmd->target) || (pDCB->UnitSCSILUN != cmd->lun) ) { pDCB = pDCB->pNextDCB; if( pDCB == pdcb ) goto NOT_RUN; } if( pDCB->QIORBCnt ) { pcmd = pDCB->pQIORBhead; if( pcmd == cmd ) { pDCB->pQIORBhead = pcmd->next; pcmd->next = NULL; pDCB->QIORBCnt--; status = SCSI_ABORT_SUCCESS; goto ABO_X; } for( count = pDCB->QIORBCnt, i=0; i<count-1; i++) { if( pcmd->next == cmd ) { pcmd1 = pcmd->next; pcmd->next = pcmd1->next; pcmd1->next = NULL; pDCB->QIORBCnt--; status = SCSI_ABORT_SUCCESS; goto ABO_X; } else { pcmd = pcmd->next; } } } pSRB = pDCB->pWaitingSRB; if( !pSRB ) goto ON_GOING; if( pSRB->pcmd == cmd ) { pDCB->pWaitingSRB = pSRB->pNextSRB; goto IN_WAIT; } else { psrb = pSRB; if( !(psrb->pNextSRB) ) goto ON_GOING; while( psrb->pNextSRB->pcmd != cmd ) { psrb = psrb->pNextSRB; if( !(psrb->pNextSRB) ) goto ON_GOING; } pSRB = psrb->pNextSRB; psrb->pNextSRB = pSRB->pNextSRB; if( pSRB == pDCB->pWaitLast ) pDCB->pWaitLast = psrb; /* No check for psrb == NULL ? */IN_WAIT: pSRB->pNextSRB = pACB->pFreeSRB; pACB->pFreeSRB = pSRB; cmd->next = NULL; status = SCSI_ABORT_SUCCESS; goto ABO_X; }ON_GOING: pSRB = pDCB->pGoingSRB; for( count = pDCB->GoingSRBCnt, i=0; i<count; i++) { if( pSRB->pcmd != cmd ) pSRB = pSRB->pNextSRB; else { if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) ) { status = SCSI_ABORT_BUSY; goto ABO_X; } else { status = SCSI_ABORT_SNOOZE; goto ABO_X; } } }NOT_RUN: status = SCSI_ABORT_NOT_RUNNING;ABO_X: cmd->result = DID_ABORT << 16; cmd->scsi_done(cmd); restore_flags(flags); return( status );}static voidResetDevParam( PACB pACB ){ PDCB pDCB, pdcb; pDCB = pACB->pLinkDCB; if( pDCB == NULL ) return; pdcb = pDCB; do { pDCB->SyncMode &= ~SYNC_NEGO_DONE; pDCB->SyncPeriod = 0; pDCB->SyncOffset = 0; pDCB->CtrlR3 = FAST_CLK; pDCB->CtrlR4 &= NEGATE_REQACKDATA; pDCB->CtrlR4 |= EATER_25NS; pDCB = pDCB->pNextDCB; } while( pdcb != pDCB );}static voidRecoverSRB( PACB pACB ){ PDCB pDCB, pdcb; PSRB psrb, psrb2; USHORT cnt, i; pDCB = pACB->pLinkDCB; if( pDCB == NULL ) return; pdcb = pDCB; do { cnt = pdcb->GoingSRBCnt; psrb = pdcb->pGoingSRB; for (i=0; i<cnt; i++) { psrb2 = psrb; psrb = psrb->pNextSRB;/* 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 );}/*********************************************************************** * Function : int DC390_reset (Scsi_Cmnd *cmd, ...) * * Purpose : perform a hard reset on the SCSI bus * * Inputs : cmd - command which caused the SCSI RESET * * Returns : 0 on success. ***********************************************************************/#ifdef VERSION_2_0_0int DC390_reset(Scsi_Cmnd *cmd, unsigned int resetFlags)#elseint DC390_reset (Scsi_Cmnd *cmd)#endif{ USHORT ioport; unsigned long flags; PACB pACB; UCHAR bval; USHORT i;#ifdef DC390_DEBUG1 printk("DC390: RESET,");#endif pACB = (PACB ) cmd->host->hostdata; ioport = pACB->IOPortBase; save_flags(flags); cli(); bval = inb(ioport+CtrlReg1); bval |= DIS_INT_ON_SCSI_RST; outb(bval,ioport+CtrlReg1); /* disable interrupt */ DC390_ResetSCSIBus( pACB ); for( i=0; i<500; i++ ) udelay(1000); bval = inb(ioport+CtrlReg1); bval &= ~DIS_INT_ON_SCSI_RST; outb(bval,ioport+CtrlReg1); /* re-enable interrupt */ bval = DMA_IDLE_CMD; outb(bval,ioport+DMA_Cmd); bval = CLEAR_FIFO_CMD; outb(bval,ioport+ScsiCmd); ResetDevParam( pACB ); DoingSRB_Done( pACB ); pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; DoWaitingSRB( pACB ); restore_flags(flags);#ifdef DC390_DEBUG1 printk("DC390: RESET1,");#endif return( SCSI_RESET_SUCCESS );}#include "scsiiom.c"/*********************************************************************** * Function : static void DC390_initDCB * * Purpose : initialize the internal structures for a given DCB * * Inputs : cmd - pointer to this scsi cmd request block structure * ***********************************************************************/void DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd ){ PEEprom prom; UCHAR bval; USHORT index; if( pACB->DeviceCnt == 0 ) { pACB->pLinkDCB = pDCB; pACB->pDCBRunRobin = pDCB; pDCB->pNextDCB = pDCB; pPrevDCB = pDCB; } else pPrevDCB->pNextDCB = pDCB; pDCB->pDCBACB = pACB; pDCB->QIORBCnt = 0; pDCB->UnitSCSIID = cmd->target; pDCB->UnitSCSILUN = cmd->lun; pDCB->pWaitingSRB = NULL; pDCB->pGoingSRB = NULL; pDCB->GoingSRBCnt = 0; pDCB->pActiveSRB = NULL; pDCB->TagMask = 0; pDCB->MaxCommand = 1; pDCB->AdaptIndex = pACB->AdapterIndex; index = pACB->AdapterIndex; pDCB->DCBFlag = 0; prom = (PEEprom) &eepromBuf[index][cmd->target << 2]; pDCB->DevMode = prom->EE_MODE1; pDCB->AdpMode = eepromBuf[index][EE_MODE2]; if( pDCB->DevMode & EN_DISCONNECT_ ) bval = 0xC0; else bval = 0x80; bval |= cmd->lun; pDCB->IdentifyMsg = bval; pDCB->SyncMode = 0; if( pDCB->DevMode & SYNC_NEGO_ ) { if( !(cmd->lun) || CurrSyncOffset ) pDCB->SyncMode = SYNC_ENABLE; } pDCB->SyncPeriod = 0; pDCB->SyncOffset = 0; pDCB->NegoPeriod = (clock_period1[prom->EE_SPEED] * 25) >> 2; pDCB->CtrlR1 = pACB->AdaptSCSIID; if( pDCB->DevMode & PARITY_CHK_ ) pDCB->CtrlR1 |= PARITY_ERR_REPO; pDCB->CtrlR3 = FAST_CLK; pDCB->CtrlR4 = EATER_25NS; if( pDCB->AdpMode & ACTIVE_NEGATION) pDCB->CtrlR4 |= NEGATE_REQACKDATA;}/*********************************************************************** * Function : static void DC390_initSRB * * Purpose : initialize the internal structures for a given SRB * * Inputs : psrb - pointer to this scsi request block structure * ***********************************************************************/void DC390_initSRB( PSRB psrb ){#ifndef VERSION_ELF_1_2_13#ifdef DC390_DEBUG0 printk("DC390 init: %08lx %08lx,",(ULONG)psrb,(ULONG)virt_to_bus(psrb));#endif psrb->PhysSRB = virt_to_bus( psrb );#else psrb->PhysSRB = (ULONG) psrb;#endif}void DC390_linkSRB( PACB pACB ){ USHORT count, i; PSRB psrb; 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; psrb = (PSRB) &pACB->SRB_array[i]; DC390_initSRB( psrb ); }}/*********************************************************************** * Function : static void DC390_initACB * * Purpose : initialize the internal structures for a given SCSI host * * Inputs : psh - pointer to this host adapter's structure * ***********************************************************************/void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ){ PACB pACB; USHORT i; psh->can_queue = MAX_CMD_QUEUE; psh->cmd_per_lun = MAX_CMD_PER_LUN; psh->this_id = (int) eepromBuf[index][EE_ADAPT_SCSI_ID]; psh->io_port = io_port; psh->n_io_port = 0x80; psh->irq = Irq; pACB = (PACB) psh->hostdata;#ifndef VERSION_ELF_1_2_13 psh->max_id = 8;#ifdef CONFIG_SCSI_MULTI_LUN if( eepromBuf[index][EE_MODE2] & LUN_CHECK ) psh->max_lun = 8; else#endif psh->max_lun = 1;#endif pACB->max_id = 7; if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID] ) pACB->max_id--;#ifdef CONFIG_SCSI_MULTI_LUN if( eepromBuf[index][EE_MODE2] & LUN_CHECK ) pACB->max_lun = 7; else#endif pACB->max_lun = 0; pACB->pScsiHost = psh; pACB->IOPortBase = (USHORT) io_port; pACB->pLinkDCB = NULL; pACB->pDCBRunRobin = NULL; pACB->pActiveDCB = NULL; pACB->pFreeSRB = pACB->SRB_array; pACB->SRBCount = MAX_SRB_CNT; pACB->AdapterIndex = index; pACB->status = 0; pACB->AdaptSCSIID = eepromBuf[index][EE_ADAPT_SCSI_ID]; pACB->HostID_Bit = (1 << pACB->AdaptSCSIID); pACB->AdaptSCSILUN = 0; pACB->DeviceCnt = 0; pACB->IRQLevel = Irq; pACB->TagMaxNum = eepromBuf[index][EE_TAG_CMD_NUM] << 2; pACB->ACBFlag = 0; pACB->scan_devices = 1; pACB->Gmode2 = eepromBuf[index][EE_MODE2]; if( eepromBuf[index][EE_MODE2] & LUN_CHECK ) pACB->LUNchk = 1; pACB->pDCB_free = &pACB->DCB_array[0]; DC390_linkSRB( pACB ); pACB->pTmpSRB = &pACB->TmpSRB; DC390_initSRB( pACB->pTmpSRB ); for(i=0; i<MAX_SCSI_ID; i++) pACB->DCBmap[i] = 0;}/*********************************************************************** * Function : static int DC390_initAdapter * * Purpose : initialize the SCSI chip ctrl registers * * Inputs : psh - pointer to this host adapter's structure * ***********************************************************************/int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ){ USHORT ioport; UCHAR bval; PACB pACB, pacb; USHORT used_irq = 0; pacb = pACB_start; if( pacb != NULL ) { for ( ; (pacb != (PACB) -1) ; ) { if( pacb->IRQLevel == Irq ) { used_irq = 1; break; } else pacb = pacb->pNextACB; } } if( !used_irq ) {#ifdef VERSION_ELF_1_2_13 if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT, "tmscsim"))#else if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT | SA_SHIRQ, "tmscsim", NULL))#endif { printk("DC390: register IRQ error!\n"); return( -1 ); } } request_region(io_port,psh->n_io_port,"tmscsim"); ioport = (USHORT) io_port; pACB = (PACB) psh->hostdata; bval = SEL_TIMEOUT; /* 250ms selection timeout */ outb(bval,ioport+Scsi_TimeOut); bval = CLK_FREQ_40MHZ; /* Conversion factor = 0 , 40MHz clock */ outb(bval,ioport+Clk_Factor); bval = NOP_CMD; /* NOP cmd - clear command register */ outb(bval,ioport+ScsiCmd); bval = EN_FEATURE+EN_SCSI2_CMD; /* Enable Feature and SCSI-2 */ outb(bval,ioport+CtrlReg2); bval = FAST_CLK; /* fast clock */ outb(bval,ioport+CtrlReg3); bval = EATER_25NS; if( eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION ) bval |= NEGATE_REQACKDATA; outb(bval,ioport+CtrlReg4); bval = DIS_INT_ON_SCSI_RST; /* Disable SCSI bus reset interrupt */ outb(bval,ioport+CtrlReg1); return(0);}voidDC390_EnableCfg( USHORT mechnum, UCHAR regval ){ ULONG wlval; if(mechnum == 2) { outb(mech2bus, PCI_CFG2_FORWARD_REG); outb(mech2CfgSPenR, PCI_CFG2_ENABLE_REG); } else { regval &= 0xFC; wlval = mech1addr; wlval |= (((ULONG)regval) & 0xff); outl(wlval, PCI_CFG1_ADDRESS_REG); }}voidDC390_DisableCfg( USHORT mechnum ){ if(mechnum == 2) outb(0, PCI_CFG2_ENABLE_REG); else outl(0, PCI_CFG1_ADDRESS_REG);}UCHARDC390_inByte( USHORT mechnum, UCHAR regval ){ UCHAR bval; ULONG wval; ULONG flags; save_flags(flags); cli(); DC390_EnableCfg( mechnum, regval ); if(mechnum == 2) { wval = mech2Agent; wval <<= 8; wval |= ((USHORT) regval) & 0xff; bval = inb(wval); } else { regval &= 3; bval = inb(PCI_CFG1_DATA_REG | regval); } DC390_DisableCfg(mechnum); restore_flags(flags); return(bval);}USHORTDC390_inWord( USHORT mechnum, UCHAR regval ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -