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

📄 scsiiom.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
	    wval++;	}	else	    break;    }    wval |=  ( (USHORT) inb(ioport+ScsiFifo) & 7) << 8;  /* get LUN */    pDCB = pACB->pLinkDCB;    pdcb = pDCB;    while( wval != *((PUSHORT) &pDCB->UnitSCSIID) )    {	pDCB = pDCB->pNextDCB;	if( pDCB == pdcb )	    return;    }    pACB->pActiveDCB = pDCB;    if( pDCB->SyncMode & EN_TAG_QUEUING )    {	pSRB = pACB->pTmpSRB;	pDCB->pActiveSRB = pSRB;    }    else    {	pSRB = pDCB->pActiveSRB;	if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )	{	    pSRB= pACB->pTmpSRB;	    pSRB->SRBState = SRB_UNEXPECT_RESEL;	    pDCB->pActiveSRB = pSRB;	    EnableMsgOut( pACB, pSRB );	}	else	{	    if( pDCB->DCBFlag & ABORT_DEV_ )	    {		pSRB->SRBState = SRB_ABORT_SENT;		EnableMsgOut( pACB, pSRB );	    }	    else		pSRB->SRBState = SRB_DATA_XFER;	}    }    pSRB->ScsiPhase = SCSI_NOP0;    bval = pDCB->UnitSCSIID;    outb( bval, ioport+Scsi_Dest_ID);    bval = pDCB->SyncPeriod;    outb(bval, ioport+Sync_Period);    bval = pDCB->SyncOffset;    outb( bval, ioport+Sync_Offset);    bval = pDCB->CtrlR1;    outb(bval, ioport+CtrlReg1);    bval = pDCB->CtrlR3;    outb(bval, ioport+CtrlReg3);    bval = pDCB->CtrlR4;	/* ; Glitch eater */    outb(bval, ioport+CtrlReg4);    bval = MSG_ACCEPTED_CMD;	/* ;to rls the /ACK signal */    outb(bval, ioport+ScsiCmd);}static voidSRBdone( PACB pACB, PDCB pDCB, PSRB pSRB ){    PSRB   psrb;    UCHAR  bval, bval1, i, j, status;    PSCSICMD pcmd;    PSCSI_INQDATA  ptr;    USHORT disable_tag;    ULONG  flags;    PSGL   ptr2;    ULONG  swlval;    pcmd = pSRB->pcmd;    status = pSRB->TargetStatus;    if(pSRB->SRBFlag & AUTO_REQSENSE)    {	pSRB->SRBFlag &= ~AUTO_REQSENSE;	pSRB->AdaptStatus = 0;	pSRB->TargetStatus = SCSI_STAT_CHECKCOND;	if(status == SCSI_STAT_CHECKCOND)	{	    pcmd->result = DID_BAD_TARGET << 16;	    goto ckc_e;	}	if(pSRB->RetryCnt == 0)	{	    *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];	    pSRB->TotalXferredLen = pSRB->Segment1[1];	    if( (pSRB->TotalXferredLen) &&		(pSRB->TotalXferredLen >= pcmd->underflow) )		pcmd->result |= (DID_OK << 16);	    else		pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) |				SCSI_STAT_CHECKCOND;#ifdef DC390_DEBUG0	printk("Cmd=%2x,Result=%8x,XferL=%8x,",pSRB->CmdBlock[0],		(UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);#endif	    goto ckc_e;	}	else	{	    pSRB->RetryCnt--;	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = 0;	    *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];	    *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];	    if( pSRB->CmdBlock[0] == TEST_UNIT_READY )	    {		pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) |				SCSI_STAT_CHECKCOND;		goto ckc_e;	    }	    pcmd->result |= (DRIVER_SENSE << 24);	    pSRB->SGcount		 = (UCHAR) pSRB->Segment1[0];	    pSRB->ScsiCmdLen		 = (UCHAR) (pSRB->Segment1[0] >> 8);	    pSRB->SGIndex = 0;	    pSRB->TotalXferredLen = 0;	    pSRB->SGToBeXferLen = 0;	    if( pcmd->use_sg )		pSRB->pSegmentList = (PSGL) pcmd->request_buffer;	    else if( pcmd->request_buffer )	    {		pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;		pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;		pSRB->Segmentx.length = pcmd->request_bufflen;	    }	    if( DC390_StartSCSI( pACB, pDCB, pSRB ) )		RewaitSRB( pDCB, pSRB );	    return;	}    }    if( status )    {	if( status == SCSI_STAT_CHECKCOND)	{	    if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) )	    {		bval = pSRB->SGcount;		swlval = 0;		ptr2 = pSRB->pSegmentList;		for( i=pSRB->SGIndex; i < bval; i++)		{		    swlval += ptr2->length;		    ptr2++;		}#ifdef	DC390_DEBUG0		printk("XferredLen=%8x,NotXferLen=%8x,",			(UINT) pSRB->TotalXferredLen, (UINT) swlval);#endif	    }	    RequestSense( pACB, pDCB, pSRB );	    return;	}	else if( status == SCSI_STAT_QUEUEFULL )	{	    bval = (UCHAR) pDCB->GoingSRBCnt;	    bval--;	    pDCB->MaxCommand = bval;	    RewaitSRB( pDCB, pSRB );	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = 0;	    return;	}	else if(status == SCSI_STAT_SEL_TIMEOUT)	{	    pSRB->AdaptStatus = H_SEL_TIMEOUT;	    pSRB->TargetStatus = 0;	    pcmd->result = DID_BAD_TARGET << 16;	}	else	{	    pSRB->AdaptStatus = 0;	    if( pSRB->RetryCnt )	    {		pSRB->RetryCnt--;		pSRB->TargetStatus = 0;		pSRB->SGIndex = 0;		pSRB->TotalXferredLen = 0;		pSRB->SGToBeXferLen = 0;		if( pcmd->use_sg )		    pSRB->pSegmentList = (PSGL) pcmd->request_buffer;		else if( pcmd->request_buffer )		{		    pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;		    pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;		    pSRB->Segmentx.length = pcmd->request_bufflen;		}		if( DC390_StartSCSI( pACB, pDCB, pSRB ) )		    RewaitSRB( pDCB, pSRB );		return;	    }	    else	    {		pcmd->result |= (DID_ERROR << 16) | (ULONG) (pSRB->EndMessage << 8) |			       (ULONG) status;	    }	}    }    else    {	status = pSRB->AdaptStatus;	if(status & H_OVER_UNDER_RUN)	{	    pSRB->TargetStatus = 0;	    pcmd->result |= (DID_OK << 16) | (pSRB->EndMessage << 8);	}	else if( pSRB->SRBStatus & PARITY_ERROR)	{	    pcmd->result |= (DID_PARITY << 16) | (pSRB->EndMessage << 8);	}	else		       /* No error */	{	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = 0;	    pcmd->result |= (DID_OK << 16);	}    }ckc_e:    if( pACB->scan_devices )    {	if( pSRB->CmdBlock[0] == TEST_UNIT_READY )	{	    if(pcmd->result != (DID_OK << 16))	    {		if( pcmd->result & SCSI_STAT_CHECKCOND )		{		    goto RTN_OK;		}		else		{		    pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun);		    pPrevDCB->pNextDCB = pACB->pLinkDCB;		    if( (pcmd->target == pACB->max_id) &&		       ((pcmd->lun == 0) || (pcmd->lun == pACB->max_lun)) )		    {			pACB->scan_devices = 0;		    }		}	    }	    else	    {RTN_OK:		pPrevDCB->pNextDCB = pDCB;		pDCB->pNextDCB = pACB->pLinkDCB;		if( (pcmd->target == pACB->max_id) && (pcmd->lun == pACB->max_lun) )		    pACB->scan_devices = END_SCAN;	    }	}	else if( pSRB->CmdBlock[0] == INQUIRY )	{	    if( (pcmd->target == pACB->max_id) &&		(pcmd->lun == pACB->max_lun) )	    {		pACB->scan_devices = 0;	    }	    ptr = (PSCSI_INQDATA) (pcmd->request_buffer);	    if( pcmd->use_sg )		ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address);	    bval1 = ptr->DevType & SCSI_DEVTYPE;	    if(bval1 == SCSI_NODEV)	    {		pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun);		pPrevDCB->pNextDCB = pACB->pLinkDCB;	    }	    else	    {		pACB->DeviceCnt++;		pPrevDCB = pDCB;		pACB->pDCB_free = (PDCB) ((ULONG) (pACB->pDCB_free) + sizeof( DC390_DCB ));		pDCB->DevType = bval1;		if(bval1 == TYPE_DISK || bval1 == TYPE_MOD)		{		    if( (((ptr->Vers & 0x07) >= 2) || ((ptr->RDF & 0x0F) == 2)) &&			(ptr->Flags & SCSI_INQ_CMDQUEUE) &&			(pDCB->DevMode & TAG_QUEUING_) &&			(pDCB->DevMode & EN_DISCONNECT_) )		    {			disable_tag = 0;			for(i=0; i<BADDEVCNT; i++)			{			    for(j=0; j<28; j++)			    {				if( ((PUCHAR)ptr)[8+j] != baddevname1[i][j])				    break;			    }			    if(j == 28)			    {				disable_tag = 1;				break;			    }			}			if( !disable_tag )			{			    pDCB->MaxCommand = pACB->TagMaxNum;			    pDCB->SyncMode |= EN_TAG_QUEUING;			    pDCB->TagMask = 0;			}			else			{			    pDCB->SyncMode |= EN_ATN_STOP;			}		    }		}	    }	}    }    save_flags( flags );    cli();/*  ReleaseSRB( pDCB, pSRB ); */    if(pSRB == pDCB->pGoingSRB )    {	pDCB->pGoingSRB = pSRB->pNextSRB;    }    else    {	psrb = pDCB->pGoingSRB;	while( psrb->pNextSRB != pSRB )	    psrb = psrb->pNextSRB;	psrb->pNextSRB = pSRB->pNextSRB;	if( pSRB == pDCB->pGoingLast )	    pDCB->pGoingLast = psrb;    }    pSRB->pNextSRB = pACB->pFreeSRB;    pACB->pFreeSRB = pSRB;    pDCB->GoingSRBCnt--;    DoWaitingSRB( pACB );    restore_flags(flags);/*  Notify cmd done */    pcmd->scsi_done( pcmd );    if( pDCB->QIORBCnt )	DoNextCmd( pACB, pDCB );    return;}static voidDoingSRB_Done( PACB pACB ){    PDCB  pDCB, pdcb;    PSRB  psrb, psrb2;    USHORT  cnt, i;    PSCSICMD pcmd;    pDCB = pACB->pLinkDCB;    pdcb = pDCB;    do    {	cnt = pdcb->GoingSRBCnt;	psrb = pdcb->pGoingSRB;	for( i=0; i<cnt; i++)	{	    psrb2 = psrb->pNextSRB;	    pcmd = psrb->pcmd;	    pcmd->result = DID_RESET << 16;/*	    ReleaseSRB( pDCB, pSRB ); */	    psrb->pNextSRB = pACB->pFreeSRB;	    pACB->pFreeSRB = psrb;	    pcmd->scsi_done( pcmd );	    psrb  = psrb2;	}	pdcb->GoingSRBCnt = 0;;	pdcb->pGoingSRB = NULL;	pdcb->TagMask = 0;	pdcb = pdcb->pNextDCB;    }    while( pdcb != pDCB );}static voidDC390_ResetSCSIBus( PACB pACB ){    USHORT ioport;    UCHAR  bval;    ULONG  flags;    save_flags(flags);    cli();    pACB->ACBFlag |= RESET_DEV;    ioport = pACB->IOPortBase;    bval = DMA_IDLE_CMD;    outb(bval,ioport+DMA_Cmd);    bval = RST_SCSI_BUS_CMD;    outb(bval,ioport+ScsiCmd);    restore_flags(flags);    return;}static voidDC390_ScsiRstDetect( PACB pACB ){    ULONG wlval, flags;    USHORT ioport;    UCHAR  bval;#ifdef DC390_DEBUG0    printk("RST_DETEC");#endif    save_flags(flags);    sti();    wlval = jiffies + HZ;    while( jiffies < wlval );	 /* delay 1 sec */    cli();    ioport = pACB->IOPortBase;    bval = DMA_IDLE_CMD;    outb(bval,ioport+DMA_Cmd);    bval = CLEAR_FIFO_CMD;    outb(bval,ioport+ScsiCmd);    if( pACB->ACBFlag & RESET_DEV )	pACB->ACBFlag |= RESET_DONE;    else    {	pACB->ACBFlag |= RESET_DETECT;	ResetDevParam( pACB );/*	DoingSRB_Done( pACB ); ???? */	RecoverSRB( pACB );	pACB->pActiveDCB = NULL;	pACB->ACBFlag = 0;	DoWaitingSRB( pACB );    }    restore_flags(flags);    return;}static voidRequestSense( PACB pACB, PDCB pDCB, PSRB pSRB ){    PSCSICMD  pcmd;    pSRB->SRBFlag |= AUTO_REQSENSE;    pSRB->Segment0[0] = *((PULONG) &(pSRB->CmdBlock[0]));    pSRB->Segment0[1] = *((PULONG) &(pSRB->CmdBlock[4]));    pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount);    pSRB->Segment1[1] = pSRB->TotalXferredLen;    pSRB->AdaptStatus = 0;    pSRB->TargetStatus = 0;    pcmd = pSRB->pcmd;    pSRB->Segmentx.address = (PUCHAR) &(pcmd->sense_buffer);    pSRB->Segmentx.length = sizeof(pcmd->sense_buffer);    pSRB->pSegmentList = &pSRB->Segmentx;    pSRB->SGcount = 1;    pSRB->SGIndex = 0;    *((PULONG) &(pSRB->CmdBlock[0])) = 0x00000003;    pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;    *((PUSHORT) &(pSRB->CmdBlock[4])) = sizeof(pcmd->sense_buffer);    pSRB->ScsiCmdLen = 6;    pSRB->TotalXferredLen = 0;    pSRB->SGToBeXferLen = 0;    if( DC390_StartSCSI( pACB, pDCB, pSRB ) )	RewaitSRB( pDCB, pSRB );}static voidEnableMsgOut2( PACB pACB, PSRB pSRB ){    USHORT ioport;    UCHAR  bval;    ioport = pACB->IOPortBase;    pSRB->MsgCnt = 1;    bval = SET_ATN_CMD;    outb(bval, ioport+ScsiCmd);}static voidEnableMsgOut( PACB pACB, PSRB pSRB ){    pSRB->MsgOutBuf[0] = MSG_ABORT;    EnableMsgOut2( pACB, pSRB );}static voidDC390_InvalidCmd( PACB pACB ){   UCHAR bval;   USHORT ioport;   PSRB   pSRB;    pSRB = pACB->pActiveDCB->pActiveSRB;    if( pSRB->SRBState & (SRB_START_+SRB_MSGOUT) )    {	ioport = pACB->IOPortBase;	bval = CLEAR_FIFO_CMD;	outb(bval,(ioport+ScsiCmd));    }}

⌨️ 快捷键说明

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