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

📄 dpx_rtos.c

📁 交换机中常用芯片链路复用7350的驱动源代码(vxworks中实现)
💻 C
📖 第 1 页 / 共 2 页
字号:
    psDpxDdb = (sDPX_DDB *)duplex;

   
    /* reset the Interrupt Processing Enable Flag in the device DDB */
    psDpxDdb->u1IntrProcEn = 0;
    
    u1ActiveDevNumber--;
    
    /* update the IRQ record table */
    pSysInfo = (DPX_ADAPTER_PCI_HANDLE *) (psDpxDdb->pSysInfo);
    for(i=0; i < DPX_MAX_NUM_DEVS; i++)
    {
        if(pSysInfo->irq == IrqInstalled[i].irq)
        {
            /* decrement count for the IRQ */
            (IrqInstalled[i].count)--;
            
            /* if all device has been removed for the IRQ */
            if(IrqInstalled[i].count == 0)
            {
                /* uninstall Handler in processor's interrupt vector table */
                /* sysIntDisablePIC(pSysInfo->irq); */
                pciIntDisconnect(INUM_TO_IVEC(pSysInfo->irq + INT_NUM_IRQ0),
                                    sysDuplexIntHandler );
                
                /* update the record */
                IrqInstalled[i].irq = 0;
            }
            break;
        }
    }

#if CSW_PV_FLAG 
    if(i == DPX_MAX_NUM_DEVS)
    {
        /* we didn't find the Irq in the record table, something is terrible wrong */
        printf("Duplex error: not find irq %d in the record\n", pSysInfo->irq);
        for(i=0; i < DPX_MAX_NUM_DEVS; i++)
            printf(" (%d, %d) ", IrqInstalled[i].irq, IrqInstalled[i].count);
    }     
#endif
    
    /* No DUPLEX devices are activated for all IRQs */
    if(u1ActiveDevNumber == 0)
    {       
        /* kill sysDuplexDPRtask  */
        if( sDpxDprTsk.i4Id != 0) 
        {
            /* try to graceful shutdown the task */
            u1DPRactive = 0;
            sysDuplexDelayFn(DPX_TASK_SHUTDOWN_DELAY);
            
            /* then force to delete the task */
            taskDelete( sDpxDprTsk.i4Id);
            sDpxDprTsk.i4Id = 0;
        }
        
        /* delete the message queue */
        msgQDelete(IntMsgQId);
        
     }
     
}

/*******************************************************************************
**
**  sysDuplexIntHandler
**  ___________________________________________________________________________ 
**
**  DESCRIPTION: This routine is invoked when one or more duplex devices 
**               interrupts the processor. It invokes duplexISR for each device
**               for which interrupt processing is enabled.If at least one valid
**               interrupt condition is detected by duplexISR, then this routine 
**               queues the interrupt context information for later processing
**               by sysDuplexDPRtask.
**
**  VALID STATES:  Not applicable
**
**  SIDE EFFECTS: 
**
**  INPUTS:	     None
**
**  OUTPUTS:	 None
**
**  RETURN CODES:None
**
*******************************************************************************/
VOID sysDuplexIntHandler(INT4 irq)
{
    UINT1 u1NextDev;
    sDPX_INT_CTXT sIntCtxt;
    DPX_ADAPTER_PCI_HANDLE *pSysInfo;
    
    if(psDpxGdd == DPX_NULL)
   	    return;
        
    /* initialize the sDPX_INT_CTXT */
    sIntCtxt.u1NumDevs = 0;
 
    for(u1NextDev=0; u1NextDev < DPX_MAX_NUM_DEVS; ++u1NextDev)
    { 
	    if(psDpxGdd->pDdb[u1NextDev] != DPX_NULL)
        {   
            pSysInfo = (DPX_ADAPTER_PCI_HANDLE *) (psDpxGdd->pDdb[u1NextDev]->pSysInfo);
            
            /* we only check the Duplex devices with the same IRQ and 
               their interrupt was enabled */    
            if((psDpxGdd->pDdb[u1NextDev]->u1IntrProcEn) && (irq == pSysInfo->irq)) 
            {
            	/* call duplexISR */
                if(duplexISR(psDpxGdd->pDdb[u1NextDev]))
                {
                    /* save this device handle */
                    sIntCtxt.pu4DevHandles[sIntCtxt.u1NumDevs] = 
                                          (UINT4 *)(psDpxGdd->pDdb[u1NextDev]);
                    
                    /* increment the inetrrupting device count */
                    (sIntCtxt.u1NumDevs)++; 
                }
            }
#if CSW_PV_FLAG
            softIntClr(psDpxGdd->pDdb[u1NextDev]->usrCtxt);
#endif
        }          
    }
    
    /* if at least one device has the interrupt conditions */
    if(sIntCtxt.u1NumDevs != 0) 
    {
         /* NOTE: You don't need to get an interrupt context buffer under 
                  VxWorks or QNX RTOS. However the interrupt context buffers is
                  needed when the RTOS does not support message queue buffers
                  of arbitrary length. (For example, pSOS supports message 
                  sizes of 4 long words only.)
         */
  
        /* send a message to the sysDuplexDPRtask with interrupt cotext   
           information that consists of the device handlers for interrupting       
           DUPLEX devices */
        msgQSend(IntMsgQId, (char *) &sIntCtxt, sizeof(sDPX_INT_CTXT), NO_WAIT,
                                                               MSG_PRI_NORMAL);                             
    }

}


/*******************************************************************************
**
**  sysDuplexDPRtask
**  ___________________________________________________________________________ 
**
**  DESCRIPTION: This routine is spawned as a sperate task within the RTOS. It
**               retrieves interrupt status information saved for it by the
**               sysDuplexIntHandler routine and invokes the duplexDPR routine
**               for the appropriate device.
**
**  VALID STATES:  Not applicable
**
**  SIDE EFFECTS: 
**
**  INPUTS:	     None
**
**  OUTPUTS:	 None
**
**  RETURN CODES:None
**
*******************************************************************************/
VOID sysDuplexDPRtask(VOID)
{ 
     UINT1 u1NextDev;
     INT4  MsgSize;
     sDPX_INT_CTXT sIntCtxt;
     sDPX_DDB *psDpxDdb;
     
     do 
     {
     	/* wait for message sent from sysDuplexIntHandler */
        MsgSize = msgQReceive(IntMsgQId,(char *)&sIntCtxt,sizeof(sDPX_INT_CTXT),
                                                                  WAIT_FOREVER);
        if(MsgSize == ERROR)
        	continue; 

        /* check message size consistence */
        if(MsgSize != sizeof(sDPX_INT_CTXT))
                continue;
                
   
     	/* for each interrupting device, invoke duplexDPR */
        for(u1NextDev = 0; u1NextDev < sIntCtxt.u1NumDevs; u1NextDev++)
        {
            psDpxDdb = (sDPX_DDB *)(sIntCtxt.pu4DevHandles[u1NextDev]);
            duplexDPR(psDpxDdb);
           
        }        
               
        
     } while(u1DPRactive);
     
}
         
#else /** Polling mode **/
 

/*******************************************************************************
**
**  sysDuplexIntInstallHandler  (Polling mode )
**  ___________________________________________________________________________ 
**
**  DESCRIPTION: For the polling mode, if this function is called for the first
**               time, it will spawn a DPR task, which periodically polls the 
**               interrupt status and processes the events. 
**               If the DPR task has already been running, the function will
**               simply flag the "u1IntrProcEn" in the DDB structure.
**
**  VALID STATES:  Not applicable
**
**  SIDE EFFECTS: 
**
**  INPUTS:	     duplex - device handler
**
**  OUTPUTS:	 None
**
**  RETURN CODES:
**                 DPX_SUCCESS  
**                 DPX_ERR_INVALID_DEVICE  (invalid device handle)
**                 DPX_ERR_INT_ALREADY_INSTALLED
**                 DPX_ERR_CREATE_MSG_Q 
**                 DPX_ERR_INSTALL_INT_VECTOR
**                 DPX_ERR_SPAWN_DPR_TASK
**
*******************************************************************************/
INT4 sysDuplexIntInstallHandler(DUPLEX duplex)
{
    sDPX_DDB *psDpxDdb;
    
    psDpxDdb = (sDPX_DDB *)duplex;
    
         
     /* set the Interrupt Processing Enable Flag in the device DDB */
     sysDuplexSemTake(psDpxDdb->lockId);
     psDpxDdb->u1IntrProcEn = 1;
     sysDuplexSemGive(psDpxDdb->lockId);

    if(u1ActiveDevNumber == 0)
    {
        u1DPRactive = 1;
        /* spawn sysDuplexDPRtask as a separate task in the RTOS */
        sDpxDprTsk.i4Id = taskSpawn(sDpxDprTsk.pi1Name, sDpxDprTsk.i4Pri, 
                            sDpxDprTsk.i4Opt, 
                            sDpxDprTsk.i4StckSz,sDpxDprTsk.FEntryPtr, 
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

         if( sDpxDprTsk.i4Id == ERROR)
        	return DPX_ERR_INT_INSTALL;              
     }

     u1ActiveDevNumber++;
          
     return DPX_SUCCESS;
}

/*******************************************************************************
**
**  sysDuplexIntRemoveHandler  (Polling mode )
**  ___________________________________________________________________________ 
**
**  DESCRIPTION: Remove the specified device from the list of devices for which
**               interrupt polling processing will be done.This can be achieved
**               by clear the "u1IntrProcEn" flag in the DDB structure.
**               If this is the last active device, the sysDuplexDPRtask are 
**               deleted. 
**
**  VALID STATES:  Not applicable
**
**  SIDE EFFECTS: 
**
**  INPUTS:	     duplex - device handler
**
**  OUTPUTS:	 None
**
**  RETURN CODES:None
**
*******************************************************************************/
VOID sysDuplexIntRemoveHandler(DUPLEX duplex)
{
    sDPX_DDB *psDpxDdb;
    
    psDpxDdb = (sDPX_DDB *)duplex;

   
    /* reset the Interrupt Processing Enable Flag in the device DDB */
    psDpxDdb->u1IntrProcEn = 0;
   
    
    u1ActiveDevNumber--;
        
    /* No DUPLEX devices are activated */
    if(u1ActiveDevNumber == 0)
    {       
        /* kill sysDuplexDPRtask  */
        if( sDpxDprTsk.i4Id != 0) 
        {
            /* try to graceful shutdown the task */
            u1DPRactive = 0;
            sysDuplexDelayFn(2*DPX_POLLING_DELAY);
            
            /* force to delete the task */
            taskDelete(sDpxDprTsk.i4Id);
            sDpxDprTsk.i4Id = 0;
        }
                
     }
     
}


/*******************************************************************************
**
**  sysDuplexDPRtask   (Polling mode )
**  ___________________________________________________________________________ 
**
**  DESCRIPTION: This routine is spawned as a sperate task within the RTOS. It
**               retrieves interrupt status information saved for it by the
**               sysDuplexIntHandler routine and invokes the duplexDPR routine
**               for the appropriate device.
**
**  VALID STATES:  Not applicable
**
**  SIDE EFFECTS: 
**
**  INPUTS:	     None
**
**  OUTPUTS:	 None
**
**  RETURN CODES:None
**
*******************************************************************************/
VOID sysDuplexDPRtask(VOID)
{ 
     UINT1 u1NextDev;
     sDPX_DDB *psDpxDdb;
     UINT1 u1IntrProcEn;
     
     if(psDpxGdd == DPX_NULL)
   	    return;

     
     do 
     {
         
        for(u1NextDev=0; u1NextDev < DPX_MAX_NUM_DEVS; ++u1NextDev)
        { 
	        psDpxDdb =  psDpxGdd->pDdb[u1NextDev];
            if(psDpxDdb != DPX_NULL)
            { 
                /* check this device has been activated */
                u1IntrProcEn = psDpxDdb->u1IntrProcEn;
                              
                if(u1IntrProcEn)
                    duplexDPR(psDpxDdb);
            }
           
        }
        
        /** sleep for a few milliseconds */
        sysDuplexDelayFn(DPX_POLLING_DELAY);       
               
        
     } while(u1DPRactive);
     
}

#endif

⌨️ 快捷键说明

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