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

📄 scsiio.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
static voidDC390W_MsgReject( PACB pACB ){    PDCB pDCB;    PSRB pSRB;    ULONG wlval;    USHORT ioport;    UCHAR bval;#ifdef DC390W_DEBUG0    printk("Msgrjt,");#endif    pDCB = pACB->pActiveDCB;    pSRB = pDCB->pActiveSRB;    wlval = pACB->jmp_clear_ack;    if(pSRB->SRBState & DO_WIDE_NEGO)    {	pSRB->SRBState &= ~DO_WIDE_NEGO;	pDCB->DCBscntl3 &= ~EN_WIDE_SCSI;	AdjustTemp( pACB, pDCB, pSRB );	SetXferRate( pACB, pDCB );	if( pDCB->DevMode & SYNC_NEGO_ )	{	    *((PULONG) &(pSRB->MsgOutBuf[0])) = 0x00010301;	    pSRB->MsgOutBuf[3] = pDCB->NegoPeriod;	    pSRB->MsgOutBuf[4] = SYNC_NEGO_OFFSET;	    pSRB->__msgout0[0] = 5;	    pSRB->SRBState |= DO_SYNC_NEGO;	    wlval = pACB->jmp_set_atn;	}    }    else    {	if(pSRB->SRBState & DO_SYNC_NEGO)	{	    pSRB->SRBState &= ~DO_SYNC_NEGO;	    pDCB->DCBsxfer = 0; /* reject sync msg, set aync */	    if( pACB->AdaptType == DC390W )		bval = SYNC_CLK_F2+ASYNC_CLK_F2;	    else		bval = SYNC_CLK_F4+ASYNC_CLK_F4;	    pDCB->DCBscntl3 = bval;	    SetXferRate(pACB,pDCB);	    wlval = pACB->jmp_clear_ack;	}    }    ioport = pACB->IOPortBase;    bval = pDCB->DCBscntl3;    outb(bval,ioport+SCNTL3);    bval = pDCB->DCBsxfer;    outb(bval,ioport+SXFER);    outl(wlval,(ioport+DSP));    return;}static voidAdjustTemp( PACB pACB, PDCB pDCB, PSRB pSRB ){    USHORT ioport;    ULONG wlval;    wlval = pSRB->ReturnAddr;    if(wlval <= pACB->jmp_table8)    {	if(pDCB->DCBscntl3 & EN_WIDE_SCSI)	    wlval +=  jmp_table16;    }    else    {	if((pDCB->DCBscntl3 & EN_WIDE_SCSI) == 0)	    wlval -= jmp_table16;    }    pSRB->ReturnAddr = wlval;    ioport = pACB->IOPortBase;    outl(wlval,(ioport+TEMP));    return;}static voidSetXferRate( PACB pACB, PDCB pDCB ){    UCHAR  bval;    USHORT cnt, i;    PDCB   ptr;    if( !(pDCB->IdentifyMsg & 0x07) )    {	if( pACB->scan_devices )	{	    CurrDCBscntl3 = pDCB->DCBscntl3;	}	else	{	    ptr = pACB->pLinkDCB;	    cnt = pACB->DeviceCnt;	    bval = pDCB->UnitSCSIID;	    for(i=0; i<cnt; i++)	    {		if( ptr->UnitSCSIID == bval )		{		    ptr->DCBsxfer = pDCB->DCBsxfer;		    ptr->DCBscntl3 = pDCB->DCBscntl3;		}		ptr = ptr->pNextDCB;	    }	}    }    return;}static voidDC390W_UnknownMsg( PACB pACB ){    PSRB pSRB;    ULONG wlval;    USHORT ioport;    pSRB = pACB->pActiveDCB->pActiveSRB;    pSRB->__msgout0[0] = 1;    pSRB->MsgOutBuf[0] = MSG_REJECT_;    wlval = pACB->jmp_set_atn;    ioport = pACB->IOPortBase;    outl(wlval,(ioport+DSP));    return;}static voidDC390W_MessageExtnd( PACB pACB ){    DC390W_UnknownMsg( pACB );}static voidDC390W_Disconnected( PACB pACB ){    PDCB pDCB;    PSRB pSRB;    ULONG  wlval, flags;    USHORT ioport;    UCHAR bval;#ifdef DC390W_DEBUG0    printk("Discnet,");#endif    save_flags(flags);    cli();    pDCB = pACB->pActiveDCB;    if (! pDCB)     {#ifdef DC390W_DEBUG0	printk("ACB:%08lx->ActiveDCB:%08lx !,", (ULONG)pACB, (ULONG)pDCB);#endif	restore_flags(flags); return;     }    pSRB = pDCB->pActiveSRB;    ioport = pACB->IOPortBase;    bval = inb(ioport+SCRATCHA);    pSRB->ScratchABuf = bval;    pSRB->SRBState |= SRB_DISCONNECT;	/* 1.02 */    wlval = pACB->jmp_reselect;    outl(wlval,(ioport+DSP));    pACB->pActiveDCB = 0;    DoWaitingSRB( pACB );    restore_flags(flags);    return;}static voidDC390W_Reselected( PACB pACB ){#ifdef DC390W_DEBUG0    printk("Rsel,");#endif    pACB->msgin123[0] = 0x80;	 /* set identify byte 80h */    DC390W_Reselected1(pACB);    return;}static voidDC390W_Reselected1( PACB pACB ){    PDCB   pDCB;    PSRB   pSRB;    USHORT ioport, wval;    ULONG  wlval, flags;    UCHAR  bval;#ifdef DC390W_DEBUG0    printk("Rsel1,");#endif    ioport = pACB->IOPortBase;    pDCB = pACB->pActiveDCB;    if(pDCB)    {	pSRB = pDCB->pActiveSRB;	RewaitSRB( pDCB, pSRB );    }    wval = (USHORT) (pACB->msgin123[0]);    wval = (wval & 7) << 8;		/* get LUN */    wval |= (USHORT) (inb(ioport+SSID) & 0x0f); /* get ID */    pDCB = pACB->pLinkDCB;    while( *((PUSHORT) &pDCB->UnitSCSIID) != wval )	pDCB = pDCB->pNextDCB;    pACB->pActiveDCB = pDCB;    bval = pDCB->DCBscntl3;    outb(bval,ioport+SCNTL3);    bval = pDCB->DCBsxfer;    outb(bval,ioport+SXFER);    bval = pDCB->DCBscntl0;    outb(bval,ioport+SCNTL0);    if(pDCB->MaxCommand > 1)    {	wlval = pACB->jmp_reselecttag;	outl(wlval,(ioport+DSP));    }    else    {	pSRB = pDCB->pActiveSRB;	if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )	{	    save_flags(flags);	    cli();	    pSRB = pACB->pFreeSRB;	    pACB->pFreeSRB = pSRB->pNextSRB;	    restore_flags(flags);	    pSRB->SRBState = SRB_UNEXPECT_RESEL;	    pDCB->pActiveSRB = pSRB;	    pSRB->MsgOutBuf[0] = MSG_ABORT;	    pSRB->__msgout0[0] = 1;	}	pSRB->SRBState &= ~SRB_DISCONNECT;	wlval = pSRB->PhysSRB;	outl(wlval,(ioport+DSA));	wlval = pSRB->ReturnAddr;	outl(wlval,(ioport+TEMP));	bval = pSRB->ScratchABuf;	outb(bval,ioport+SCRATCHA);	if( pSRB->SRBState & SRB_UNEXPECT_RESEL )	    wlval = pACB->jmp_set_atn;	else	    wlval = pACB->jmp_clear_ack;	outl(wlval,(ioport+DSP));    }    return;}static voidDC390W_ReselectedT( PACB pACB ){    PDCB pDCB;    PSRB pSRB, psrb1;    USHORT ioport;    ULONG wlval, flags;    UCHAR bval;#ifdef DC390W_DEBUG0    printk("RselT,");#endif    ioport = pACB->IOPortBase;    bval = pACB->msgin123[1];    pDCB = pACB->pActiveDCB;    pSRB = pDCB->pGoingSRB;    psrb1 = pDCB->pGoingLast;    if( !pSRB )	goto  UXP_RSL;    for(;;)    {	if(pSRB->TagNumber != bval)	{	    if( pSRB != psrb1 )		pSRB = pSRB->pNextSRB;	    else		goto  UXP_RSL;	}	else	    break;    }    if( !(pSRB->SRBState & SRB_DISCONNECT) )    {UXP_RSL:	    save_flags(flags);	    cli();	    pSRB = pACB->pFreeSRB;	    pACB->pFreeSRB = pSRB->pNextSRB;	    restore_flags(flags);	    pSRB->SRBState = SRB_UNEXPECT_RESEL;	    pDCB->pActiveSRB = pSRB;	    pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;	    pSRB->__msgout0[0] = 1;    }    else    {	pSRB->SRBState &= ~SRB_DISCONNECT;	pDCB->pActiveSRB = pSRB;    }    wlval = pSRB->PhysSRB;    outl(wlval,(ioport+DSA));    wlval = pSRB->ReturnAddr;    outl(wlval,(ioport+TEMP));    bval = pSRB->ScratchABuf;    outb(bval,ioport+SCRATCHA);    if( pSRB->SRBState & SRB_UNEXPECT_RESEL )	wlval = pACB->jmp_set_atn;    else	wlval = pACB->jmp_clear_ack;    outl(wlval,(ioport+DSP));    return;}static voidDC390W_RestorePtr( PACB pACB ){   PSRB pSRB;   USHORT ioport;   ULONG wlval;   pSRB = pACB->pActiveDCB->pActiveSRB;   wlval = pSRB->ReturnAddr;   ioport = pACB->IOPortBase;   outl(wlval,(ioport+TEMP));   wlval = inl(ioport+DSP);   outl(wlval,(ioport+DSP));   return;}static voidPhaseMismatch( PACB pACB ){    USHORT  ioport;    ULONG   wlval,swlval;    USHORT  wval;    UCHAR   bval,phase;    PDCB    pDCB;#ifdef DC390W_DEBUG0    printk("Mismatch,");#endif    ioport = pACB->IOPortBase;    bval = inb(ioport+SCRATCHA);    if(bval & OVER_RUN_)	/* xfer PAD */    {	bval = inb(ioport+STEST3);	bval |= CLR_SCSI_FIFO;	outb(bval,ioport+STEST3);	bval = CLR_DMA_FIFO;	outb(bval,ioport+CTEST3);	wlval = pACB->jmp_next; 	 /* check phase */	outl(wlval,(ioport+DSP));	return;    }    pDCB = pACB->pActiveDCB;    wlval = inl(ioport+DBC);    phase = (UCHAR)((wlval & 0x07000000) >> 24);    wlval &= 0xffffff;	/* bytes not xferred */    if( phase == SCSI_DATA_IN )    {	swlval = pACB->jmp_din8;	if( pDCB->DCBscntl3 & EN_WIDE_SCSI )	     swlval += jmp_din16;	DataIOcommon(pACB,swlval,wlval);    }    else if( phase == SCSI_DATA_OUT )    {	wval = (USHORT)inb(ioport+CTEST5);	wval <<= 8;	bval = inb(ioport+DFIFO);	wval |= (USHORT) bval;	wval -= ((USHORT)(wlval & 0xffff));	wval &= 0x3ff;	wlval += (ULONG)wval;  /* # of bytes remains in FIFO */	bval = inb(ioport+SSTAT0);	if(bval & SODR_LSB_FULL)	   wlval++;	       /* data left in Scsi Output Data Buffer */	if(bval & SODL_LSB_FULL)	   wlval++;	       /* data left in Scsi Output Data Latch */	swlval = pACB->jmp_dout8;	if(pDCB->DCBscntl3 & EN_WIDE_SCSI)	{	   swlval += jmp_dout16;	   bval = inb(ioport+SSTAT2);	   if(bval & SODR_MSB_FULL)	       wlval++;	   if(bval & SODL_MSB_FULL)	       wlval++;	}	bval = inb(ioport+STEST3);	bval |= CLR_SCSI_FIFO;	outb(bval,ioport+STEST3);	bval = CLR_DMA_FIFO;	outb(bval,ioport+CTEST3);	DataIOcommon(pACB,swlval,wlval);    }    else    {	bval = inb(ioport+STEST3);	bval |= CLR_SCSI_FIFO;	outb(bval,ioport+STEST3);	bval = CLR_DMA_FIFO;	outb(bval,ioport+CTEST3);	if(phase == SCSI_MSG_OUT)	    wlval = pACB->jmp_clear_atn;	else	    wlval = pACB->jmp_next;	/* check phase */	outl(wlval,(ioport+DSP));    }    return;}static voidDataIOcommon( PACB pACB, ULONG	Swlval, ULONG  Cwlval ){    /* Swlval - script address */    /* Cwlval - bytes not xferred */    PDCB pDCB;    PSRB pSRB;    PSGE Segptr;    USHORT ioport;    ULONG  wlval,swlval,dataXferCnt;    UCHAR  bval,bvald;    ioport = pACB->IOPortBase;    wlval = inl((ioport+DSP));    pDCB = pACB->pActiveDCB;    pSRB = pDCB->pActiveSRB;    wlval -= Swlval;    bval = inb(ioport+SBCL);    bval &= 0x07;    if(bval == SCSI_MSG_IN)    {	bval = pDCB->DCBscntl3;	bval &= ~EN_WIDE_SCSI;	outb(bval,ioport+SCNTL3);	bval = inb(ioport+SBDL);	bvald = pDCB->DCBscntl3;    /* enable WIDE SCSI */	outb(bvald,ioport+SCNTL3);	if(bval == MSG_DISCONNECT || bval == MSG_SAVE_PTR)	{	    Segptr = (PSGE)((ULONG) &(pSRB->Segment0[0][0]) + wlval);	    dataXferCnt = Segptr->SGXLen - Cwlval;	    Segptr->SGXLen = Cwlval;		/* modified count */	    Segptr->SGXPtr += dataXferCnt;	/* modified address */	    swlval = pACB->jmp_table8;	    if(pDCB->DCBscntl3 & EN_WIDE_SCSI)		swlval += jmp_table16;	    wlval <<= 1;	    swlval += wlval;	    swlval = swlval - ((MAX_SG_LIST_BUF+1) * 16);	    pSRB->ReturnAddr = swlval;	}    }    else if( Cwlval )	/* Remaining not xferred -- UNDER_RUN */    {	Segptr = (PSGE)((ULONG) &(pSRB->Segment0[0][0]) + wlval);	dataXferCnt = Segptr->SGXLen - Cwlval;	Segptr->SGXLen = Cwlval;	    /* modified count */	Segptr->SGXPtr += dataXferCnt;	    /* modified address */	swlval = pACB->jmp_table8;	if(pDCB->DCBscntl3 & EN_WIDE_SCSI)	    swlval += jmp_table16;	wlval <<= 1;	swlval += wlval;	swlval = swlval - ((MAX_SG_LIST_BUF+1) * 16);	pSRB->RemainSegPtr = swlval;    }/* pm__1: */    wlval = pSRB->ReturnAddr;    outl(wlval,(ioport+TEMP));    wlval = pACB->jmp_next;    outl(wlval,(ioport+DSP));    return;}static voidDC390W_CmdCompleted( PACB pACB ){    PDCB pDCB;    PSRB pSRB;    USHORT ioport;    ULONG  wlval, flags;    UCHAR  bval;#ifdef DC390W_DEBUG0    printk("Cmplete,");#endif    save_flags(flags);    cli();    pDCB = pACB->pActiveDCB;    pSRB = pDCB->pActiveSRB;    pDCB->pActiveSRB = NULL;    ioport = pACB->IOPortBase;    bval  = inb(ioport+SCRATCHA);    pSRB->ScratchABuf = bval;		/* save status */    bval = pSRB->TagNumber;    if(pDCB->MaxCommand > 1)

⌨️ 快捷键说明

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