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

📄 tmscsim.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -