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

📄 scsiio.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
       pDCB->TagMask &= (~(1 << bval));   /* free tag mask */    pACB->pActiveDCB = NULL;		/* no active device */    wlval = pACB->jmp_reselect; 	/* enable reselection */    outl(wlval,(ioport+DSP));    SRBdone( pACB, pDCB, pSRB);    restore_flags(flags);    return;}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;    PSGE   ptr1;    PSGL   ptr2;    ULONG  wlval,swlval;    pcmd = pSRB->pcmd;    status = pACB->status;    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][0];	    pSRB->XferredLen = pSRB->Segment0[2][1];	    if( (pSRB->XferredLen) &&		(pSRB->XferredLen >= pcmd->underflow) )	    {		pcmd->result |= (DID_OK << 16);	    }	    else		pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) |				SCSI_STAT_CHECKCOND;	    goto ckc_e;	}	else	{	    pSRB->RetryCnt--;	    pSRB->TargetStatus = 0;	    *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0][0];	    *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[0][1];	    *((PULONG) &(pSRB->CmdBlock[8])) = pSRB->Segment0[1][0];	    pSRB->__command[0]		     = pSRB->Segment0[1][1] & 0xff;	    pSRB->SGcount		     = (UCHAR) (pSRB->Segment0[1][1] >> 8);	    *((PULONG) &(pSRB->pSegmentList))= pSRB->Segment0[2][0];	    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);	    PrepareSG(pACB,pDCB,pSRB);	    pSRB->XferredLen = 0;	    DC390W_StartSCSI( pACB, pDCB, pSRB );	    return;	}    }    if( status )    {	if( status == SCSI_STAT_CHECKCOND)	{	    if( !(pSRB->ScratchABuf & SRB_OK) && (pSRB->SGcount) && (pSRB->RemainSegPtr) )	    {		wlval = pSRB->RemainSegPtr;		swlval = pACB->jmp_table8;		if(pDCB->DCBscntl3 & EN_WIDE_SCSI)		    swlval += jmp_table16;		swlval -= wlval;		swlval >>= 4;		bval = (UCHAR) swlval;		wlval = 0;		ptr1 = (PSGE) &pSRB->Segment0[MAX_SG_LIST_BUF+1][0];		for( i=0; i< bval; i++)		{		    wlval += ptr1->SGXLen;		    ptr1--;		}		bval = pSRB->SGcount;		swlval = 0;		ptr2 = pSRB->pSegmentList;		for( i=0; i< bval; i++)		{		    swlval += ptr2->length;		    ptr2++;		}		pSRB->XferredLen = swlval - wlval;		pSRB->RemainSegPtr = 0;#ifdef	DC390W_DEBUG0		printk("XferredLen=%8x,NotXferLen=%8x,",(UINT) pSRB->XferredLen,(UINT) wlval);#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 if(status == SCSI_STAT_UNEXP_BUS_F)	{	    pSRB->AdaptStatus = H_UNEXP_BUS_FREE;	    pSRB->TargetStatus = 0;	    pcmd->result |= DID_NO_CONNECT << 16;	}	else if(status == SCSI_STAT_BUS_RST_DETECT )	{	    pSRB->AdaptStatus = H_ABORT;	    pSRB->TargetStatus = 0;	    pcmd->result = DID_RESET << 16;	}	else	{	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = status;	    if( pSRB->RetryCnt )	    {		pSRB->RetryCnt--;		pSRB->TargetStatus = 0;		PrepareSG(pACB,pDCB,pSRB);		pSRB->XferredLen = 0;		DC390W_StartSCSI( pACB, pDCB, pSRB );		return;	    }	    else	    {		pcmd->result |= (DID_ERROR << 16) | (ULONG) (pACB->msgin123[0] << 8) |			       (ULONG) status;	    }	}    }    else    {	status = pSRB->ScratchABuf;	if(status & OVER_RUN_)	{	    pSRB->AdaptStatus = H_OVER_UNDER_RUN;	    pSRB->TargetStatus = 0;	    pcmd->result |= (DID_OK << 16) | (pACB->msgin123[0] << 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( DC390W_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] != baddevname[i][j])				    break;			    }			    if(j == 28)			    {				disable_tag = 1;				break;			    }			}			if( !disable_tag )			{			    pDCB->MaxCommand = pACB->TagMaxNum;			    pDCB->TagMask = 0;			}		    }		}	    }	}    }    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 voidDC390W_ResetSCSIBus( PACB pACB ){    USHORT ioport;    UCHAR  bval;    ULONG  flags;    save_flags(flags);    cli();    pACB->ACBFlag |= RESET_DEV;    ioport = pACB->IOPortBase;    bval = ABORT_OP;    outb(bval,ioport+ISTAT);    udelay(25);    bval = 0;    outb(bval,ioport+ISTAT);    bval = ASSERT_RST;    outb(bval,ioport+SCNTL1);    udelay(25); 	 /* 25 us */    bval = 0;    outb(bval,ioport+SCNTL1);    restore_flags(flags);    return;}static voidDC390W_ResetSCSIBus2( PACB pACB ){    USHORT ioport;    UCHAR  bval;    ULONG  flags;    save_flags(flags);    cli();    ioport = pACB->IOPortBase;    bval = ASSERT_RST;    outb(bval,ioport+SCNTL1);    udelay(25); 	 /* 25 us */    bval = 0;    outb(bval,ioport+SCNTL1);    restore_flags(flags);    return;}static voidDC390W_ScsiRstDetect( PACB pACB ){    ULONG wlval, flags;    USHORT ioport;    UCHAR  bval;    save_flags(flags);    sti();#ifdef DC390W_DEBUG0    printk("Reset_Detect0,");#endif/* delay 1 sec */    wlval = jiffies + HZ;    while( jiffies < wlval );/*  USHORT  i;    for( i=0; i<1000; i++ )	udelay(1000); */    cli();    ioport = pACB->IOPortBase;    bval = inb(ioport+STEST3);    bval |= CLR_SCSI_FIFO;    outb(bval,ioport+STEST3);    bval = CLR_DMA_FIFO;    outb(bval,ioport+CTEST3);    if( pACB->ACBFlag & RESET_DEV )	pACB->ACBFlag |= RESET_DONE;    else    {	pACB->ACBFlag |= RESET_DETECT;	ResetDevParam( pACB );/*	DoingSRB_Done( pACB ); ???? */	RecoverSRB( pACB );	pACB->pActiveDCB = NULL;	wlval = pACB->jmp_reselect;	outl(wlval,(ioport+DSP));	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][0] = *((PULONG) &(pSRB->CmdBlock[0]));    pSRB->Segment0[0][1] = *((PULONG) &(pSRB->CmdBlock[4]));    pSRB->Segment0[1][0] = *((PULONG) &(pSRB->CmdBlock[8]));    pSRB->Segment0[1][1] = pSRB->__command[0] | (pSRB->SGcount << 8);    pSRB->Segment0[2][0] = *((PULONG) &(pSRB->pSegmentList));    pSRB->Segment0[2][1] = pSRB->XferredLen;    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;    *((PULONG) &(pSRB->CmdBlock[0])) = 0x00000003;    pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;    *((PUSHORT) &(pSRB->CmdBlock[4])) = sizeof(pcmd->sense_buffer);    pSRB->__command[0] = 6;    PrepareSG( pACB, pDCB, pSRB );    pSRB->XferredLen = 0;    DC390W_StartSCSI( pACB, pDCB, pSRB );    return;}static voidDC390W_MessageOut( PACB pACB ){    DC390W_FatalError( pACB );}static voidDC390W_FatalError( PACB pACB ){    PSRB  pSRB;    PDCB  pDCB;    ULONG flags;#ifdef DC390W_DEBUG0   printk("DC390W: Fatal Error!!\n");#endif    pDCB = pACB->pActiveDCB;    pSRB = pDCB->pActiveSRB;    if( pSRB->SRBState & SRB_UNEXPECT_RESEL )    {	save_flags(flags);	cli();	pSRB->SRBState &= ~SRB_UNEXPECT_RESEL;	pSRB->pNextSRB = pACB->pFreeSRB;	pACB->pFreeSRB = pSRB;	pACB->pActiveDCB = NULL;	pDCB->pActiveSRB = NULL;	restore_flags(flags);	DoWaitingSRB( pACB );    }    else	DC390W_ResetSCSIBus(pACB);    return;}static voidDC390W_Debug( PACB pACB ){   ULONG wlval;   USHORT ioport;   ioport = pACB->IOPortBase;   wlval = inl(ioport+DSP);   outl(wlval,(ioport+DSP));   return;}

⌨️ 快捷键说明

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