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

📄 scsiiom.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
    else    {	/* minx: */	*pSRB->pMsgPtr = bval;	pSRB->MsgCnt++;	pSRB->pMsgPtr++;	if( (pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG) &&	    (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG) )	{	    if( pSRB->MsgCnt == 2)	    {		pSRB->SRBState = 0;		bval = pSRB->MsgInBuf[1];		pSRB = pDCB->pGoingSRB;		psrb = pDCB->pGoingLast;		if( pSRB )		{		    for( ;; )		    {			if(pSRB->TagNumber != bval)			{			    if( pSRB == psrb )				goto  mingx0;			    pSRB = pSRB->pNextSRB;			}			else			    break;		    }		    if( pDCB->DCBFlag & ABORT_DEV_ )		    {			pSRB->SRBState = SRB_ABORT_SENT;			EnableMsgOut( pACB, pSRB );		    }		    if( !(pSRB->SRBState & SRB_DISCONNECT) )			goto  mingx0;		    pDCB->pActiveSRB = pSRB;		    pSRB->SRBState = SRB_DATA_XFER;		}		else		{mingx0:		    pSRB = pACB->pTmpSRB;		    pSRB->SRBState = SRB_UNEXPECT_RESEL;		    pDCB->pActiveSRB = pSRB;		    pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;		    EnableMsgOut2( pACB, pSRB );		}	    }	}	else if( (pSRB->MsgInBuf[0] == MSG_EXTENDED) && (pSRB->MsgCnt == 5) )	{	    pSRB->SRBState &= ~(SRB_MSGIN_MULTI+DO_SYNC_NEGO);	    if( (pSRB->MsgInBuf[1] != 3) || (pSRB->MsgInBuf[2] != 1) )	    {	/* reject_msg: */		pSRB->MsgCnt = 1;		pSRB->MsgInBuf[0] = MSG_REJECT_;		bval = SET_ATN_CMD;		outb(bval, ioport+ScsiCmd);	    }	    else if( !(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4]) )	    {set_async:		pDCB = pSRB->pSRBDCB;		pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);		pDCB->SyncPeriod = 0;		pDCB->SyncOffset = 0;		pDCB->CtrlR3 = FAST_CLK;     /* ;non_fast */		pDCB->CtrlR4 &= 0x3f;		pDCB->CtrlR4 |= EATER_25NS;  /* ; 25ns glitch eater */		goto  re_prog;	    }	    else	    {	/* set_sync: */		pDCB = pSRB->pSRBDCB;		pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;		pDCB->SyncOffset &= 0x0f0;		pDCB->SyncOffset |= pSRB->MsgInBuf[4];		pDCB->NegoPeriod = pSRB->MsgInBuf[3];		wval = (USHORT) pSRB->MsgInBuf[3];		wval = wval << 2;		wval--;		wval1 = wval / 25;		if( (wval1 * 25) != wval)		    wval1++;		bval = FAST_CLK+FAST_SCSI;		pDCB->CtrlR4 &= 0x3f;		if(wval1 >= 8)		{		    wval1--;		    bval = FAST_CLK;	    /* ;fast clock/normal scsi */		    pDCB->CtrlR4 |= EATER_25NS;   /* ;25 ns glitch eater */		}		pDCB->CtrlR3 = bval;		pDCB->SyncPeriod = (UCHAR)wval1;re_prog:		bval = pDCB->SyncPeriod;		outb(bval, ioport+Sync_Period);		bval = pDCB->SyncOffset;		outb(bval, ioport+Sync_Offset);		bval = pDCB->CtrlR3;		outb(bval, ioport+CtrlReg3);		bval = pDCB->CtrlR4;		outb(bval, ioport+CtrlReg4);		SetXferRate( pACB, pDCB);	    }	}    }min6:    *psstatus = SCSI_NOP0;    bval = MSG_ACCEPTED_CMD;    outb(bval, ioport+ScsiCmd);}static voidDataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir){    PSGL   psgl;    UCHAR  bval;    USHORT ioport;    ULONG  lval;    ioport = pACB->IOPortBase;    if( pSRB->SGIndex < pSRB->SGcount )    {	bval = DMA_IDLE_CMD | ioDir;   /* ;+EN_DMA_INT */	outb( bval, ioport+DMA_Cmd);	if( !pSRB->SGToBeXferLen )	{	    psgl = pSRB->pSegmentList;#ifndef VERSION_ELF_1_2_13	    pSRB->SGPhysAddr = virt_to_phys( psgl->address );#else	    pSRB->SGPhysAddr = (ULONG) psgl->address;#endif	    pSRB->SGToBeXferLen = (ULONG) psgl->length;	}	lval = pSRB->SGToBeXferLen;	bval = (UCHAR) lval;	outb(bval,ioport+CtcReg_Low);	lval = lval >> 8;	bval = (UCHAR) lval;	outb(bval,ioport+CtcReg_Mid);	lval = lval >> 8;	bval = (UCHAR) lval;	outb(bval,ioport+CtcReg_High);	lval = pSRB->SGToBeXferLen;	outl(lval, ioport+DMA_XferCnt);	lval = pSRB->SGPhysAddr;	outl( lval, ioport+DMA_XferAddr);	bval = DMA_COMMAND+INFO_XFER_CMD;	outb(bval, ioport+ScsiCmd);	pSRB->SRBState = SRB_DATA_XFER;	bval = DMA_IDLE_CMD | ioDir;	/* ;+EN_DMA_INT */	outb(bval, ioport+DMA_Cmd);	bval = DMA_START_CMD | ioDir;	/* ;+EN_DMA_INT */	outb(bval, ioport+DMA_Cmd);    }    else    /* xfer pad */    {	if( pSRB->SGcount )	{	    pSRB->AdaptStatus = H_OVER_UNDER_RUN;	    pSRB->SRBStatus |= OVER_RUN;	}	bval = 0;	outb(bval,ioport+CtcReg_Low);	outb(bval,ioport+CtcReg_Mid);	outb(bval,ioport+CtcReg_High);	pSRB->SRBState |= SRB_XFERPAD;	bval = DMA_COMMAND+XFER_PAD_BYTE;	outb(bval, ioport+ScsiCmd);/*	bval = DMA_IDLE_CMD | ioDir;	;+EN_DMA_INT	outb(bval, ioport+DMA_Cmd);	bval = DMA_START_CMD | ioDir;	;+EN_DMA_INT	outb(bval, ioport+DMA_Cmd);*/    }}static voidDC390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){    UCHAR  ioDir;    ioDir = WRITE_DIRECTION;    DataIO_Comm( pACB, pSRB, ioDir);}static voidDC390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){    UCHAR  ioDir;    ioDir = READ_DIRECTION;    DataIO_Comm( pACB, pSRB, ioDir);}static voidDC390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){    PDCB   pDCB;    UCHAR  bval;    PUCHAR ptr;    USHORT ioport, i,  cnt;    ioport = pACB->IOPortBase;    bval = RESET_ATN_CMD;    outb(bval, ioport+ScsiCmd);    bval = CLEAR_FIFO_CMD;    outb(bval, ioport+ScsiCmd);    if( !(pSRB->SRBFlag & AUTO_REQSENSE) )    {	cnt = (USHORT) pSRB->ScsiCmdLen;	ptr = (PUCHAR) pSRB->CmdBlock;	for(i=0; i < cnt; i++)	{	    outb(*ptr, ioport+ScsiFifo);	    ptr++;	}    }    else    {	bval = REQUEST_SENSE;	outb(bval, ioport+ScsiFifo);	pDCB = pACB->pActiveDCB;	bval = pDCB->IdentifyMsg << 5;	outb(bval, ioport+ScsiFifo);	bval = 0;	outb(bval, ioport+ScsiFifo);	outb(bval, ioport+ScsiFifo);	bval = sizeof(pSRB->pcmd->sense_buffer);	outb(bval, ioport+ScsiFifo);	bval = 0;	outb(bval, ioport+ScsiFifo);    }    pSRB->SRBState = SRB_COMMAND;    bval = INFO_XFER_CMD;    outb(bval, ioport+ScsiCmd);}static voidDC390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){    UCHAR  bval;    USHORT ioport;    ioport = pACB->IOPortBase;    bval = CLEAR_FIFO_CMD;    outb(bval, ioport+ScsiCmd);    pSRB->SRBState = SRB_STATUS;    bval = INITIATOR_CMD_CMPLTE;    outb(bval, ioport+ScsiCmd);}static voidDC390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){    UCHAR   bval;    USHORT  ioport, i, cnt;    PUCHAR  ptr;    PDCB    pDCB;    ioport = pACB->IOPortBase;    bval = CLEAR_FIFO_CMD;    outb(bval, ioport+ScsiCmd);    pDCB = pACB->pActiveDCB;    if( !(pSRB->SRBState & SRB_MSGOUT) )    {	cnt = pSRB->MsgCnt;	if( cnt )	{	    ptr = (PUCHAR) pSRB->MsgOutBuf;	    for(i=0; i < cnt; i++)	    {		outb(*ptr, ioport+ScsiFifo);		ptr++;	    }	    pSRB->MsgCnt = 0;	    if( (pDCB->DCBFlag & ABORT_DEV_) &&		(pSRB->MsgOutBuf[0] == MSG_ABORT) )		pSRB->SRBState = SRB_ABORT_SENT;	}	else	{	    bval = MSG_ABORT;	/* ??? MSG_NOP */	    if( (pSRB->CmdBlock[0] == INQUIRY ) ||		(pSRB->CmdBlock[0] == REQUEST_SENSE) ||		(pSRB->SRBFlag & AUTO_REQSENSE) )	    {		if( pDCB->SyncMode & SYNC_ENABLE )		    goto  mop1;	    }	    outb(bval, ioport+ScsiFifo);	}	bval = INFO_XFER_CMD;	outb( bval, ioport+ScsiCmd);    }    else    {mop1:	bval = MSG_EXTENDED;	outb(bval, ioport+ScsiFifo);	bval = 3;	/*    ;length of extended msg */	outb(bval, ioport+ScsiFifo);	bval = 1;	/*    ; sync nego */	outb(bval, ioport+ScsiFifo);	bval = pDCB->NegoPeriod;	outb(bval, ioport+ScsiFifo);	bval = SYNC_NEGO_OFFSET;	outb(bval, ioport+ScsiFifo);	pSRB->SRBState |= DO_SYNC_NEGO;	bval = INFO_XFER_CMD;	outb(bval, ioport+ScsiCmd);    }}static voidDC390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){    UCHAR  bval;    USHORT ioport;    ioport = pACB->IOPortBase;    bval = CLEAR_FIFO_CMD;    outb(bval, ioport+ScsiCmd);    if( !(pSRB->SRBState & SRB_MSGIN) )    {	pSRB->SRBState &= SRB_DISCONNECT;	pSRB->SRBState |= SRB_MSGIN;    }    bval = INFO_XFER_CMD;    outb(bval, ioport+ScsiCmd);}static voidDC390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus){}static voidDC390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus){}static voidSetXferRate( PACB pACB, PDCB pDCB ){    UCHAR  bval;    USHORT cnt, i;    PDCB   ptr;    if( !(pDCB->IdentifyMsg & 0x07) )    {	if( pACB->scan_devices )	{	    CurrSyncOffset = pDCB->SyncOffset;	}	else	{	    ptr = pACB->pLinkDCB;	    cnt = pACB->DeviceCnt;	    bval = pDCB->UnitSCSIID;	    for(i=0; i<cnt; i++)	    {		if( ptr->UnitSCSIID == bval )		{		    ptr->SyncPeriod = pDCB->SyncPeriod;		    ptr->SyncOffset = pDCB->SyncOffset;		    ptr->CtrlR3 = pDCB->CtrlR3;		    ptr->CtrlR4 = pDCB->CtrlR4;		    ptr->SyncMode = pDCB->SyncMode;		}		ptr = ptr->pNextDCB;	    }	}    }    return;}static voidDC390_Disconnect( PACB pACB ){    PDCB   pDCB;    PSRB   pSRB, psrb;    ULONG  flags;    USHORT ioport, i, cnt;    UCHAR  bval;#ifdef DC390_DEBUG0    printk("DISC,");#endif    save_flags(flags);    cli();    ioport = pACB->IOPortBase;    pDCB = pACB->pActiveDCB;    if (!pDCB)     {#ifdef DC390_DEBUG0	printk("ACB:%08lx->ActiveDCB:%08lx !,",(ULONG)pACB,(ULONG)pDCB);#endif	restore_flags(flags); return;     }    pSRB = pDCB->pActiveSRB;    pACB->pActiveDCB = 0;    pSRB->ScsiPhase = SCSI_NOP0;    bval = EN_SEL_RESEL;    outb(bval, ioport+ScsiCmd);    if( pSRB->SRBState & SRB_UNEXPECT_RESEL )    {	pSRB->SRBState = 0;	DoWaitingSRB( pACB );    }    else if( pSRB->SRBState & SRB_ABORT_SENT )    {	pDCB->TagMask = 0;	pDCB->DCBFlag = 0;	cnt = pDCB->GoingSRBCnt;	pDCB->GoingSRBCnt = 0;	pSRB = pDCB->pGoingSRB;	for( i=0; i < cnt; i++)	{	    psrb = pSRB->pNextSRB;	    pSRB->pNextSRB = pACB->pFreeSRB;	    pACB->pFreeSRB = pSRB;	    pSRB = psrb;	}	pDCB->pGoingSRB = 0;	DoWaitingSRB( pACB );    }    else    {	if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||	   !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )	{	/* Selection time out */	    if( !(pACB->scan_devices) )	    {		pSRB->SRBState = SRB_READY;		RewaitSRB( pDCB, pSRB);	    }	    else	    {		pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;		goto  disc1;	    }	}	else if( pSRB->SRBState & SRB_DISCONNECT )	{	    DoWaitingSRB( pACB );	}	else if( pSRB->SRBState & SRB_COMPLETED )	{disc1:	    if(pDCB->MaxCommand > 1)	    {	       bval = pSRB->TagNumber;	       pDCB->TagMask &= (~(1 << bval));   /* free tag mask */	    }	    pDCB->pActiveSRB = 0;	    pSRB->SRBState = SRB_FREE;	    SRBdone( pACB, pDCB, pSRB);	}    }    restore_flags(flags);    return;}static voidDC390_Reselect( PACB pACB ){    PDCB   pDCB, pdcb;    PSRB   pSRB;    USHORT ioport, wval;    UCHAR  bval, bval1;#ifdef DC390_DEBUG0    printk("RSEL,");#endif    ioport = pACB->IOPortBase;    pDCB = pACB->pActiveDCB;    if( pDCB )    {	/* Arbitration lost but Reselection win */	pSRB = pDCB->pActiveSRB;	if( !( pACB->scan_devices ) )	{	    pSRB->SRBState = SRB_READY;	    RewaitSRB( pDCB, pSRB);	}    }    bval = inb(ioport+ScsiFifo);	/* get ID */    bval = bval ^ pACB->HostID_Bit;    wval = 0;    bval1 = 1;    for(;;)    {	if( !(bval & bval1) )	{	    bval1 = bval1 << 1;

⌨️ 快捷键说明

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