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

📄 scsiiom.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
};static void dc390_add_dev (PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr){   UCHAR bval1 = ptr->DevType & SCSI_DEVTYPE;   pDCB->DevType = bval1;   /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */	dc390_disc_tagq_set (pDCB, ptr);};voiddc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB ){    UCHAR  bval, status, i, DCB_removed;    PSCSICMD pcmd;    PSCSI_INQDATA  ptr;    PSGL   ptr2;    ULONG  swlval;    pcmd = pSRB->pcmd; DCB_removed = 0;    status = pSRB->TargetStatus;    ptr = (PSCSI_INQDATA) (pcmd->request_buffer);    if( pcmd->use_sg )	ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address);	    DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\		pSRB, pcmd->pid);)    if(pSRB->SRBFlag & AUTO_REQSENSE)    {	/* Last command was a Request Sense */	pSRB->SRBFlag &= ~AUTO_REQSENSE;	pSRB->AdaptStatus = 0;	pSRB->TargetStatus = CHECK_CONDITION << 1;#ifdef DC390_REMOVABLEDEBUG	switch (pcmd->sense_buffer[2] & 0x0f)	{	    	 case NOT_READY: printk (KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",				 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,				 status, pACB->scan_devices); break;	 case UNIT_ATTENTION: printk (KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",				      pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,				      status, pACB->scan_devices); break;	 case ILLEGAL_REQUEST: printk (KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",				       pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,				       status, pACB->scan_devices); break;	 case MEDIUM_ERROR: printk (KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",				    pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,				    status, pACB->scan_devices); break;	 case HARDWARE_ERROR: printk (KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",				      pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,				      status, pACB->scan_devices); break;	}#endif	//pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);	if (status == (CHECK_CONDITION << 1))	{	    pcmd->result = MK_RES_LNX(0,DID_BAD_TARGET,0,/*CHECK_CONDITION*/0);	    goto ckc_e;	}	if(pSRB->RetryCnt == 0)	{	    //(UINT)(pSRB->pcmd->cmnd[0]) = pSRB->Segment0[0];	    pSRB->TotalXferredLen = pSRB->SavedTotXLen;	    if( (pSRB->TotalXferredLen) &&		(pSRB->TotalXferredLen >= pcmd->underflow) )		  SET_RES_DID(pcmd->result,DID_OK)	    else		  pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);		  REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->pcmd->cmnd[0],\			(UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)	    goto ckc_e;	}	else /* Retry */	{	    pSRB->RetryCnt--;	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = 0;	    //*((PUINT) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];	    //*((PUINT) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];	    /* Don't retry on TEST_UNIT_READY */	    if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)	    {		pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);		REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\		       (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)		goto ckc_e;	    }	    SET_RES_DRV(pcmd->result,DRIVER_SENSE);	    pSRB->SGcount	 = (UCHAR) pSRB->SavedSGCount;	    //pSRB->ScsiCmdLen	 = (UCHAR) (pSRB->Segment1[0] >> 8);	    DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->target, pcmd->lun);)	    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 ) ) {		dc390_Going_to_Waiting ( pDCB, pSRB );		dc390_waiting_timer (pACB, HZ/5);	    }	    return;	}    }    if( status )    {	if( status_byte(status) == CHECK_CONDITION )	{	    REMOVABLEDEBUG(printk (KERN_INFO "DC390: Check_Condition (Cmd %02x, Id %02x, LUN %02x)\n",\		    pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);)	    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++;		}		REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n",\			(UINT) pSRB->TotalXferredLen, (UINT) swlval);)	    }	    dc390_RequestSense( pACB, pDCB, pSRB );	    return;	}	else if( status_byte(status) == QUEUE_FULL )	{	    bval = (UCHAR) pDCB->GoingSRBCnt;	    bval--;	    pDCB->MaxCommand = bval;	    dc390_freetag (pDCB, pSRB);	    dc390_Going_to_Waiting ( pDCB, pSRB );	    dc390_waiting_timer (pACB, HZ/5);	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = 0;	    return;	}	else if(status == SCSI_STAT_SEL_TIMEOUT)	{	    pSRB->AdaptStatus = H_SEL_TIMEOUT;	    pSRB->TargetStatus = 0;	    pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0);	    /* Devices are removed below ... */	}	else if (status_byte(status) == BUSY && 		 (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) &&		 pACB->scan_devices)	{	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = status;	    pcmd->result = MK_RES(0,0,pSRB->EndMessage,/*status*/0);	}	else	{   /* Another error */	    pSRB->AdaptStatus = 0;	    if( pSRB->RetryCnt )	    {	/* Retry */		//printk ("DC390: retry\n");		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 ) ) {		    dc390_Going_to_Waiting ( pDCB, pSRB );		    dc390_waiting_timer (pACB, HZ/5);		}      		return;	    }	    else	    {	/* Report error */	      //pcmd->result = MK_RES(0, DID_ERROR, pSRB->EndMessage, status);	      SET_RES_DID(pcmd->result,DID_ERROR);	      SET_RES_MSG(pcmd->result,pSRB->EndMessage);	      SET_RES_TARGET(pcmd->result,status);	    }	}    }    else    {	/*  Target status == 0 */	status = pSRB->AdaptStatus;	if(status & H_OVER_UNDER_RUN)	{	    pSRB->TargetStatus = 0;	    SET_RES_DID(pcmd->result,DID_OK);	    SET_RES_MSG(pcmd->result,pSRB->EndMessage);	}	else if( pSRB->SRBStatus & PARITY_ERROR)	{	    //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);	    SET_RES_DID(pcmd->result,DID_PARITY);	    SET_RES_MSG(pcmd->result,pSRB->EndMessage);	}	else		       /* No error */	{	    pSRB->AdaptStatus = 0;	    pSRB->TargetStatus = 0;	    SET_RES_DID(pcmd->result,DID_OK);	}    }    if ((pcmd->result & RES_DID) == 0 &&	pcmd->cmnd[0] == INQUIRY && 	pcmd->cmnd[2] == 0 &&	pcmd->request_bufflen >= 8 &&	ptr &&	(ptr->Vers & 0x07) >= 2)	    pDCB->Inquiry7 = ptr->Flags;ckc_e:    if( pACB->scan_devices )    {	if( pcmd->cmnd[0] == TEST_UNIT_READY ||	    pcmd->cmnd[0] == INQUIRY)	{#ifdef DC390_DEBUG0	    printk (KERN_INFO "DC390: %s: result: %08x", 		    (pcmd->cmnd[0] == INQUIRY? "INQUIRY": "TEST_UNIT_READY"),		    pcmd->result);	    if (pcmd->result & (DRIVER_SENSE << 24)) printk (" (sense: %02x %02x %02x %02x)\n",				   pcmd->sense_buffer[0], pcmd->sense_buffer[1],				   pcmd->sense_buffer[2], pcmd->sense_buffer[3]);	    else printk ("\n");#endif	    if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) ||	       ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&		(pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR )	    {	       /* device not present: remove */ 	       //dc390_Going_remove (pDCB, pSRB);	       dc390_remove_dev (pACB, pDCB); DCB_removed = 1;	       	       if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&		  ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)) )		 pACB->scan_devices = 0;	    }	    else	    {	        /* device present: add */		if( (pcmd->target == pACB->pScsiHost->max_id - 1) && 		    (pcmd->lun == pACB->pScsiHost->max_lun - 1) )		    pACB->scan_devices = END_SCAN ;	        /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */	    }	}    }       //if( pSRB->pcmd->cmnd[0] == INQUIRY &&     //  (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )    if( pcmd->cmnd[0] == INQUIRY && 	(pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )     {	if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed)	  {	     //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun);	     /* device not present: remove */	     //dc390_Going_remove (pDCB, pSRB);	     dc390_remove_dev (pACB, pDCB); DCB_removed = 1;	  }	else	  {	     /* device found: add */ 	     dc390_add_dev (pACB, pDCB, ptr);	     if (pACB->scan_devices) pACB->DeviceCnt++;	  }	if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&	    (pcmd->lun == pACB->pScsiHost->max_lun - 1) )	  pACB->scan_devices = 0;     };#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,30)    pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;#endif    if (!DCB_removed) dc390_Going_remove (pDCB, pSRB);    /* Add to free list */    dc390_Free_insert (pACB, pSRB);    DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid);)    DC390_UNLOCK_ACB_NI;    pcmd->scsi_done (pcmd);    DC390_LOCK_ACB_NI;    dc390_Query_to_Waiting (pACB);    dc390_Waiting_process (pACB);    return;}/* Remove all SRBs from Going list and inform midlevel */voiddc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd ){    PDCB   pDCB, pdcb;    PSRB   psrb, psrb2;    UCHAR  i;    PSCSICMD pcmd;    pDCB = pACB->pLinkDCB;    pdcb = pDCB;    if (! pdcb) return;    do    {	psrb = pdcb->pGoingSRB;	for( i=0; i<pdcb->GoingSRBCnt; i++)	{	    psrb2 = psrb->pNextSRB;	    pcmd = psrb->pcmd;	    dc390_Free_insert (pACB, psrb);#ifndef USE_NEW_EH	    /* New EH will crash on being given timed out cmnds */	    if (pcmd == cmd)		pcmd->result = MK_RES(0,DID_ABORT,0,0);	    else		pcmd->result = MK_RES(0,DID_RESET,0,0);/*	    ReleaseSRB( pDCB, pSRB ); */	    DEBUG0(printk (KERN_DEBUG "DC390: DoingSRB_Done: done pid %li\n", pcmd->pid);)	    DC390_UNLOCK_ACB_NI;	    pcmd->scsi_done( pcmd );	    DC390_LOCK_ACB_NI;#endif		    psrb  = psrb2;	}	pdcb->GoingSRBCnt = 0;;	pdcb->pGoingSRB = NULL;	pdcb->TagMask = 0;	pdcb = pdcb->pNextDCB;    } while( pdcb != pDCB );    dc390_Query_to_Waiting (pACB);}static voiddc390_ResetSCSIBus( PACB pACB ){    //DC390_write8 (ScsiCmd, RST_DEVICE_CMD);    //udelay (250);    //DC390_write8 (ScsiCmd, NOP_CMD);    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);    DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);    DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD);    pACB->Connected = 0;    return;}static voiddc390_ScsiRstDetect( PACB pACB ){    printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus);    //DEBUG0(printk(KERN_INFO "RST_DETECT,");)    if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);    DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);    /* Unlock before ? */    /* delay half a second */    udelay (1000);    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);    pACB->pScsiHost->last_reset = jiffies + 5*HZ/2		    + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];    pACB->Connected = 0;    if( pACB->ACBFlag & RESET_DEV )	pACB->ACBFlag |= RESET_DONE;    else    {   /* Reset was issued by sb else */	pACB->ACBFlag |= RESET_DETECT;	dc390_ResetDevParam( pACB );	dc390_DoingSRB_Done( pACB, 0 );	//dc390_RecoverSRB( pACB );	pACB->pActiveDCB = NULL;	pACB->ACBFlag = 0;	dc390_Waiting_process( pACB );    }    return;}static void __inline__dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB ){    PSCSICMD  pcmd;    REMOVABLEDEBUG(printk (KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n",\	    pSRB->pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);)    pSRB->SRBFlag |= AUTO_REQSENSE;    //pSRB->Segment0[0] = (UINT) pSRB->CmdBlock[0];    //pSRB->Segment0[1] = (UINT) pSRB->CmdBlock[4];    //pSRB->Segment1[0] = ((UINT)(pSRB->pcmd->cmd_len) << 8) + pSRB->SGcount;    //pSRB->Segment1[1] = pSRB->TotalXferredLen;    pSRB->SavedSGCount = pSRB->SGcount;    pSRB->SavedTotXLen = pSRB->TotalXferredLen;    pSRB->AdaptStatus = 0;    pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */    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;    //pSRB->CmdBlock[0] = REQUEST_SENSE;    //pSRB->CmdBlock[1] = pDCB->TargetLUN << 5;    //(USHORT) pSRB->CmdBlock[2] = 0;    //(USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);    //pSRB->ScsiCmdLen = 6;    pSRB->TotalXferredLen = 0;    pSRB->SGToBeXferLen = 0;    if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {	dc390_Going_to_Waiting ( pDCB, pSRB );	dc390_waiting_timer (pACB, HZ/5);    }}static void __inline__dc390_InvalidCmd( PACB pACB ){    if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )	DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);}

⌨️ 快捷键说明

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