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

📄 tmscsim.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Append to Query List */static void dc390_Query_append( PSCSICMD cmd, PACB pACB ){    DEBUG0(printk ("DC390: Append cmd %li to Query\n", cmd->pid);)    if( !pACB->QueryCnt )	pACB->pQueryHead = cmd;    else	pACB->pQueryTail->next = cmd;    pACB->pQueryTail = cmd;    pACB->QueryCnt++;    pACB->CmdOutOfSRB++;    cmd->next = NULL;}/* Return next cmd from Query list */static PSCSICMD dc390_Query_get ( PACB pACB ){    PSCSICMD  pcmd;    pcmd = pACB->pQueryHead;    if (!pcmd) return pcmd;    DEBUG0(printk ("DC390: Get cmd %li from Query\n", pcmd->pid);)    pACB->pQueryHead = pcmd->next;    pcmd->next = NULL;    if (!pACB->pQueryHead) pACB->pQueryTail = NULL;    pACB->QueryCnt--;    return( pcmd );}/* Return next free SRB */static __inline__ PSRB dc390_Free_get ( PACB pACB ){    PSRB   pSRB;    pSRB = pACB->pFreeSRB;    DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB);)    if( pSRB )    {	pACB->pFreeSRB = pSRB->pNextSRB;	pSRB->pNextSRB = NULL;    }    return( pSRB );}/* Insert SRB oin top of free list */static __inline__ void dc390_Free_insert (PACB pACB, PSRB pSRB){    DEBUG0(printk ("DC390: Free SRB %p\n", pSRB);)    pSRB->pNextSRB = pACB->pFreeSRB;    pACB->pFreeSRB = pSRB;}/* Inserts a SRB to the top of the Waiting list */static __inline__ void dc390_Waiting_insert ( PDCB pDCB, PSRB pSRB ){    DEBUG0(printk ("DC390: Insert pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid);)    pSRB->pNextSRB = pDCB->pWaitingSRB;    if (!pDCB->pWaitingSRB)	pDCB->pWaitLast = pSRB;    pDCB->pWaitingSRB = pSRB;    pDCB->WaitSRBCnt++;}/* Queue SRB to waiting list */static __inline__ void dc390_Waiting_append ( PDCB pDCB, PSRB pSRB){    DEBUG0(printk ("DC390: Append pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid);)    if( pDCB->pWaitingSRB )	pDCB->pWaitLast->pNextSRB = pSRB;    else	pDCB->pWaitingSRB = pSRB;    pDCB->pWaitLast = pSRB;    pSRB->pNextSRB = NULL;    pDCB->WaitSRBCnt++;    pDCB->pDCBACB->CmdInQ++;}static __inline__ void dc390_Going_append (PDCB pDCB, PSRB pSRB){    pDCB->GoingSRBCnt++;    DEBUG0(printk("DC390: Append SRB %p to Going\n", pSRB);)    /* Append to the list of Going commands */    if( pDCB->pGoingSRB )	pDCB->pGoingLast->pNextSRB = pSRB;    else	pDCB->pGoingSRB = pSRB;    pDCB->pGoingLast = pSRB;    /* No next one in sent list */    pSRB->pNextSRB = NULL;};static __inline__ void dc390_Going_remove (PDCB pDCB, PSRB pSRB){   DEBUG0(printk("DC390: Remove SRB %p from Going\n", pSRB);)   if (pSRB == pDCB->pGoingSRB)	pDCB->pGoingSRB = pSRB->pNextSRB;   else     {	PSRB psrb = pDCB->pGoingSRB;	while (psrb && psrb->pNextSRB != pSRB)	  psrb = psrb->pNextSRB;	if (!psrb) 	  { printk (KERN_ERR "DC390: Remove non-ex. SRB %p from Going!\n", pSRB); return; }	psrb->pNextSRB = pSRB->pNextSRB;	if (pSRB == pDCB->pGoingLast)	  pDCB->pGoingLast = psrb;     }   pDCB->GoingSRBCnt--;};/* Moves SRB from Going list to the top of Waiting list */static void dc390_Going_to_Waiting ( PDCB pDCB, PSRB pSRB ){    DEBUG0(printk(KERN_INFO "DC390: Going_to_Waiting (SRB %p) pid = %li\n", pSRB, pSRB->pcmd->pid);)    /* Remove SRB from Going */    dc390_Going_remove (pDCB, pSRB);    /* Insert on top of Waiting */    dc390_Waiting_insert (pDCB, pSRB);    /* Tag Mask must be freed elsewhere ! (KG, 99/06/18) */}/* Moves first SRB from Waiting list to Going list */static __inline__ void dc390_Waiting_to_Going ( PDCB pDCB, PSRB pSRB ){		/* Remove from waiting list */	DEBUG0(printk("DC390: Remove SRB %p from head of Waiting\n", pSRB);)	pDCB->pWaitingSRB = pSRB->pNextSRB;	if( !pDCB->pWaitingSRB ) pDCB->pWaitLast = NULL;	pDCB->WaitSRBCnt--;	dc390_Going_append (pDCB, pSRB);}/* 2.0 timer compatibility */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,30) static inline int timer_pending(struct timer_list * timer) {	return timer->prev != NULL; } #define time_after(a,b)         ((long)(b) - (long)(a) < 0) #define time_before(a,b)        time_after(b,a)#endifvoid DC390_waiting_timed_out (unsigned long ptr);/* Sets the timer to wake us up */static void dc390_waiting_timer (PACB pACB, unsigned long to){	if (timer_pending (&pACB->Waiting_Timer)) return;	init_timer (&pACB->Waiting_Timer);	pACB->Waiting_Timer.function = DC390_waiting_timed_out;	pACB->Waiting_Timer.data = (unsigned long)pACB;	if (time_before (jiffies + to, pACB->pScsiHost->last_reset))		pACB->Waiting_Timer.expires = pACB->pScsiHost->last_reset + 1;	else		pACB->Waiting_Timer.expires = jiffies + to + 1;	add_timer (&pACB->Waiting_Timer);}/* Send the next command from the waiting list to the bus */static void dc390_Waiting_process ( PACB pACB ){    PDCB   ptr, ptr1;    PSRB   pSRB;    if( (pACB->pActiveDCB) || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) )	return;    if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);    ptr = pACB->pDCBRunRobin;    if( !ptr )      {	ptr = pACB->pLinkDCB;	pACB->pDCBRunRobin = ptr;      }    ptr1 = ptr;    if (!ptr1) return;    do       {	pACB->pDCBRunRobin = ptr1->pNextDCB;	if( !( pSRB = ptr1->pWaitingSRB ) ||	    ( ptr1->MaxCommand <= ptr1->GoingSRBCnt ))	  ptr1 = ptr1->pNextDCB;	else	  {	    /* Try to send to the bus */	    if( !dc390_StartSCSI(pACB, ptr1, pSRB) )	      dc390_Waiting_to_Going (ptr1, pSRB);	    else	      dc390_waiting_timer (pACB, HZ/5);	    break;	  }      } while (ptr1 != ptr);    return;}/* Wake up waiting queue */void DC390_waiting_timed_out (unsigned long ptr){	PACB pACB = (PACB)ptr;	DC390_IFLAGS	DC390_AFLAGS	DEBUG0(printk ("DC390: Debug: Waiting queue woken up by timer!\n");)	DC390_LOCK_IO;	DC390_LOCK_ACB;	dc390_Waiting_process (pACB);	DC390_UNLOCK_ACB;	DC390_UNLOCK_IO;}/*********************************************************************** * Function: static void dc390_SendSRB (PACB pACB, PSRB pSRB) * * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB) * ***********************************************************************/static void dc390_SendSRB( PACB pACB, PSRB pSRB ){    PDCB   pDCB;    pDCB = pSRB->pSRBDCB;    if( (pDCB->MaxCommand <= pDCB->GoingSRBCnt) || (pACB->pActiveDCB) ||	(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) )    {	dc390_Waiting_append (pDCB, pSRB);	dc390_Waiting_process (pACB);	return;    }#if 0    if( pDCB->pWaitingSRB )    {	dc390_Waiting_append (pDCB, pSRB);/*	pSRB = GetWaitingSRB(pDCB); */	/* non-existent */	pSRB = pDCB->pWaitingSRB;	/* Remove from waiting list */	pDCB->pWaitingSRB = pSRB->pNextSRB;	pSRB->pNextSRB = NULL;	if (!pDCB->pWaitingSRB) pDCB->pWaitLast = NULL;    }#endif	    if (!dc390_StartSCSI(pACB, pDCB, pSRB))	dc390_Going_append (pDCB, pSRB);    else {	dc390_Waiting_insert (pDCB, pSRB);	dc390_waiting_timer (pACB, HZ/5);    };}/*********************************************************************** * Function: static void dc390_BuildSRB (Scsi_Cmd *pcmd, PDCB pDCB,  * 					 PSRB pSRB) * * Purpose: Prepare SRB for being sent to Device DCB w/ command *pcmd * ***********************************************************************/static void dc390_BuildSRB (Scsi_Cmnd* pcmd, PDCB pDCB, PSRB pSRB){    pSRB->pSRBDCB = pDCB;    pSRB->pcmd = pcmd;    //pSRB->ScsiCmdLen = pcmd->cmd_len;    //memcpy (pSRB->CmdBlock, pcmd->cmnd, pcmd->cmd_len);        if( pcmd->use_sg )    {	pSRB->SGcount = (UCHAR) pcmd->use_sg;	pSRB->pSegmentList = (PSGL) pcmd->request_buffer;    }    else if( pcmd->request_buffer )    {	pSRB->SGcount = 1;	pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;	pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;	pSRB->Segmentx.length = pcmd->request_bufflen;    }    else	pSRB->SGcount = 0;    pSRB->SGIndex = 0;    pSRB->AdaptStatus = 0;    pSRB->TargetStatus = 0;    pSRB->MsgCnt = 0;    if( pDCB->DevType != TYPE_TAPE )	pSRB->RetryCnt = 1;    else	pSRB->RetryCnt = 0;    pSRB->SRBStatus = 0;    pSRB->SRBFlag = 0;    pSRB->SRBState = 0;    pSRB->TotalXferredLen = 0;    pSRB->SGBusAddr = 0;    pSRB->SGToBeXferLen = 0;    pSRB->ScsiPhase = 0;    pSRB->EndMessage = 0;    pSRB->TagNumber = 255;};/* Put cmnd from Query to Waiting list and send next Waiting cmnd */static void dc390_Query_to_Waiting (PACB pACB){    Scsi_Cmnd *pcmd;    PSRB   pSRB;    PDCB   pDCB;    if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) )	return;    while (pACB->QueryCnt)    {	pSRB = dc390_Free_get ( pACB );	if (!pSRB) return;	pcmd = dc390_Query_get ( pACB );	if (!pcmd) { dc390_Free_insert (pACB, pSRB); return; }; /* should not happen */	pDCB = dc390_findDCB (pACB, pcmd->target, pcmd->lun);	if (!pDCB) 	{ 		dc390_Free_insert (pACB, pSRB);		printk (KERN_ERR "DC390: Command in queue to non-existing device!\n");		pcmd->result = MK_RES(DRIVER_ERROR,DID_ERROR,0,0);		DC390_UNLOCK_ACB_NI;		pcmd->done (pcmd);		DC390_LOCK_ACB_NI;	};	dc390_BuildSRB (pcmd, pDCB, pSRB);	dc390_Waiting_append ( pDCB, pSRB );    }}/*********************************************************************** * Function : static int DC390_queue_command (Scsi_Cmnd *cmd, *					       void (*done)(Scsi_Cmnd *)) * * Purpose : enqueues a SCSI command * * Inputs : cmd - SCSI command, done - callback function called on  *	    completion, with a pointer to the command descriptor. * * Returns : (depending on kernel version) * 2.0.x: always return 0 * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x *	  TO BE DONE: *	  new model: return 0 if successful *	  	     return 1 if command cannot be queued (queue full) *		     command will be inserted in midlevel queue then ... * ***********************************************************************/int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)){    PDCB   pDCB;    PSRB   pSRB;    DC390_AFLAGS    PACB   pACB = (PACB) cmd->host->hostdata;    DEBUG0(/*  if(pACB->scan_devices) */	\	printk(KERN_INFO "DC390: Queue Cmd=%02x,Tgt=%d,LUN=%d (pid=%li)\n",\		cmd->cmnd[0],cmd->target,cmd->lun,cmd->pid);)    DC390_LOCK_ACB;        /* Assume BAD_TARGET; will be cleared later */    cmd->result = DID_BAD_TARGET << 16;       /* TODO: Change the policy: Alway accept TEST_UNIT_READY or INQUIRY      * commands and alloc a DCB for the device if not yet there. DCB will     * be removed in dc390_SRBdone if SEL_TIMEOUT */    if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )	pACB->scan_devices = 0;    else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )	pACB->scan_devices = 0;    if ( ( cmd->target >= pACB->pScsiHost->max_id ) || 	 (cmd->lun >= pACB->pScsiHost->max_lun) )    {/*	printk ("DC390: Ignore target %d lun %d\n",		cmd->target, cmd->lun); */	DC390_UNLOCK_ACB;	//return (1);	done (cmd);	return (0);    }    if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) &&        !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )    {        pACB->scan_devices = 1;	dc390_initDCB( pACB, &pDCB, cmd->target, cmd->lun );	if (!pDCB)	  {	    printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n", 		    cmd->target, cmd->lun);	    DC390_UNLOCK_ACB;	    printk ("DC390: No DCB in queue_command!\n");#ifdef USE_NEW_EH	    return (1);#else	    done (cmd);	    return (0);#endif	  };                }    else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )    {	printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",		cmd->target, cmd->lun); 	DC390_UNLOCK_ACB;	//return (1);	done (cmd);	return (0);    }    else    {	pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);	if (!pDCB)	 {  /* should never happen */

⌨️ 快捷键说明

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