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

📄 iolicomend.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
            }        }    else        clDesc.memArea = (char *) (pDrvCtrl->rxBdBase + pDrvCtrl->rxBdNum);    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    /* Initialize the net buffer pool with transmit buffers */     if (netPoolInit (pDrvCtrl->endObj.pNetPool, &oliMclBlkConfig,                     &clDesc, 1, NULL) == ERROR)        {        END_LOG_MSG (END_DEBUG_LOAD, "%s%d - netPoolInit failed\n",        		DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);        return (ERROR);        }     /* Save the cluster pool id */     pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,                                      OLI_BUFSIZ, FALSE);     /* Setup the receive ring */    for (ix = 0; ix < pDrvCtrl->rxBdNum; ix++)        {        pBuf = (char *) NET_BUF_ALLOC();        if (pBuf == NULL)            {            END_LOG_MSG (END_DEBUG_LOAD, "%s%d - netClusterGet failed\n",            		DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);            return (ERROR);            }		pBuf += pDrvCtrl->offset;        pDrvCtrl->rxBdBase[ix].dataPointer = pBuf;        }     END_LOG_MSG (END_DEBUG_LOAD, "Memory setup complete\n", 0, 0, 0, 0, 0, 0);    return (OK);    }/********************************************************************************* iOlicomStart - start the device** This function initializes the device and calls BSP functions to connect* interrupts and start the device running in interrupt mode.** The complement of this routine is iOlicomStop.  Once a unit is reset by* iOlicomStop, it may be re-initialized to a running state by this routine.** RETURNS: OK if successful, otherwise ERROR*/LOCAL STATUS iOlicomStart    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    STATUS	result;    int		ix;    ULONG	addrC;    END_LOG_MSG (END_DEBUG_LOAD, "iOlicomStart()\n", 0, 0, 0, 0, 0, 0);    /* Select bank 0 of the Olicom register set */    SELECTBANK(pDrvCtrl->pcmcia.oliAddr, 0);    /* reset the device */    iOlicomReset (pDrvCtrl);    /* initialize the device */    iOlicomInit (pDrvCtrl);    /* initialize flags */     DRV_FLAGS_CLR(OLI_POLLING | OLI_TX_CLEANING | OLI_TX_STOP);    /* initialize receive buffer descriptors */    for (ix = 0; ix < pDrvCtrl->rxBdNum; ix++)        pDrvCtrl->rxBdBase[ix].statusMode = RX_BD_EMPTY;    pDrvCtrl->rxBdNext = 0;    /* initialize transmit buffer descriptors */    for (ix = 0; ix < pDrvCtrl->txBdNum; ix++)        {	pDrvCtrl->txBdBase[ix].dataPointer = 		(UCHAR *) addrC = (RAM_TX_BASE + (ix * OLI_MAX_XMT));        PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R12), addrC);        PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R13),                                 (addrC >> 8));        PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R14),                                TX_BD_READY);        PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R15),                                (TX_BD_READY >> 8));        }    pDrvCtrl->txBdNext = 0;    pDrvCtrl->txBdIndexC = 0;    /* configure promiscuous mode and multicast addresses list */    iOlicomConfig(pDrvCtrl);    /* connect interrupt */    SYS_INT_CONNECT (pDrvCtrl, iOlicomInt, (int)pDrvCtrl, &result);    if (result == ERROR)	return ERROR;    END_LOG_MSG (END_DEBUG_LOAD, "Interrupt connected.\n", 0, 0, 0, 0, 0, 0);    /* set running & up flags */    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));     /* enable interrupt */    SYS_INT_ENABLE (pDrvCtrl);    END_LOG_MSG (END_DEBUG_LOAD, "Interrupt enabled.\n", 0, 0, 0, 0, 0, 0);    return (OK);    }/********************************************************************************* iOlicomIntHandle - interrupt service for card interrupts** This routine is called when an interrupt has been detected from the Olicom* card.** RETURNS: N/A.*/void iOlicomIntHandle    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    int		cardStat;    int		intStat;    /*     * Read the card configuration state to verify this is a card I/O     * interrupt.     */    cardStat = PCMCIA_ATTR_READ((int)(pDrvCtrl->pcmcia.oliAttribMem +					    CARDCONFREG1));    END_LOG_MSG (END_DEBUG_INT, "cardStat (config Reg 1) = 0x%X\n",	    cardStat, 0, 0, 0, 0, 0);    /* I/O Interrupt, examine card to find out what */    if (cardStat & CREG1_INT_IO)	{	END_LOG_MSG (END_DEBUG_INT, "I/O interrupt\n",		    0, 0, 0, 0, 0, 0);	/*	 * Read the chip's interrupt status register to find out why	 * an IRQ was raised.	 */	intStat = PCMCIA_IO_READ((int)(pDrvCtrl->pcmcia.oliAddr + I595_R1));	END_LOG_MSG (END_DEBUG_INT, "intStat (595 Reg 1) = 0x%X\n",		intStat, 0, 0, 0, 0, 0);	/*	 * Decode the interrupt down and take action accordingly. Note	 * that there may be multiple IRQ sources pending.	 */	/* handle receive events */	if (intStat & BNK0_RX_IT)	    {	    /* netTask handles any input packets */	    if (! DRV_FLAGS_ISSET(OLI_RCV_HANDLING))		{		DRV_FLAGS_SET(OLI_RCV_HANDLING);		(void)netJobAdd ((FUNCPTR)iOlicomRxIntHandle,			    (int)pDrvCtrl, 0,0,0,0);		}	    /* Acknowledge receive interrupt */	    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr +			    I595_R1), BNK0_RX_IT);	    }	/* handle transmitter events */	if (intStat & BNK0_TX_IT)	    {	    /*	     * clean the transmit buffer descriptor queue if we have	     * received a transmit interrupt and if we are not already	     * cleaning this transmit queue.	     */	    if (! DRV_FLAGS_ISSET(OLI_TX_CLEANING))		{		DRV_FLAGS_SET(OLI_TX_CLEANING);		(void)netJobAdd ((FUNCPTR)iOlicomTxBdQueueClean,			    (int)pDrvCtrl, 0,0,0,0);		}	    /* Acknowledge transmit interrupts */	    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr +			    I595_R1), BNK0_TX_IT);	    }	/* Acknowledge all other interrupts - ignore events */	PCMCIA_IO_WRITE((int) (pDrvCtrl->pcmcia.oliAddr + I595_R1),			     ~(BNK0_TX_IT | BNK0_RX_IT));	if (DRV_FLAGS_ISSET(OLI_TX_STOP))	    /* cause a restart */	    {	    DRV_FLAGS_CLR(OLI_TX_STOP);	    netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj,			    0, 0, 0, 0);	    }	}    return;    }/********************************************************************************* iOlicomRxIntHandle - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** RETURNS: N/A.*/LOCAL void iOlicomRxIntHandle    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    RX_BD *	pRxBd = iOlicomPacketGet (pDrvCtrl);        END_LOG_MSG (END_DEBUG_RX, ("iOlicomRxIntHandle\n"), 0, 0, 0, 0, 0, 0);    do        {        DRV_FLAGS_SET (OLI_RCV_HANDLING);	while (pRxBd != NULL)	    {	    iOlicomRecv (pDrvCtrl, pRxBd);	    pRxBd = iOlicomPacketGet (pDrvCtrl);	    }        DRV_FLAGS_CLR (OLI_RCV_HANDLING);	/* check once more after resetting flags */	pRxBd = iOlicomPacketGet (pDrvCtrl);        }    while (pRxBd != NULL);    }/********************************************************************************* iOlicomPacketGet - get next received message** Get next recevied message.  Returns NULL if none are* ready.** RETURNS: ptr to next packet, or NULL if none ready.*/LOCAL RX_BD * iOlicomPacketGet    (    END_DEVICE *	pDrvCtrl	/* pointer to END_DEVICE structure */    )    {    int		start;    int		event;    int		status;    int		length;    int		s;    int		nextStop;    char *	pData;    RX_BD *     pRxBd = &pDrvCtrl->rxBdBase[pDrvCtrl->rxBdNext];    END_LOG_MSG (END_DEBUG_RX, "iOlicomPacketGet oliAddr=0x%X\n",    		pDrvCtrl->pcmcia.oliAddr, 0, 0, 0, 0, 0);	    /*     * The RCV STOP register points to the last pair of bytes     * BEFORE the start of the next packet so we must add two     * bytes to reach the correct address.     */     s = intLock();    start = PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R6);    start |= (PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R7) << 8);    start += 2;    /* Handle the roll over case */    if (start > RAM_RX_LIMIT)	start -= RAM_RX_BASE;     END_LOG_MSG (END_DEBUG_RX, "start= 0x%X\n", start, 0, 0, 0, 0, 0);    /* Set up address from where we wish to start reading data */    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R12), start);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R13), (start >> 8));     /* The first word describes the state of reception. */    READ_R14_R15 (event);    /* The following bit will be set once the packet is complete in memory */     if (!(event & RCV_EOF))	{	intUnlock(s);	return ((RX_BD *) NULL);	}    /* Collect the status of the packet */    READ_R14_R15 (status);    /* get next packet pointer */    READ_R14_R15 (nextStop);    /* The next stop value is 2 bytes back in the circular buffer */    nextStop -= 2;    /* Handle the roll over case */    if (nextStop < RAM_RX_BASE)	nextStop += RAM_RX_BASE;    /* get packet length */    READ_R14_R15 (length);    END_LOG_MSG (END_DEBUG_RX, "length= 0x%X\n", length, 0, 0, 0, 0, 0);    /* Check for errors */    if (!(status & RCV_OK))        {        /* Bump input error packet counter */        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	/* Update the STOP register from the next packet pointer */	PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R6), nextStop);	PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R7),				    (nextStop >> 8));	intUnlock(s);        return ((RX_BD *) NULL);        }    /* check if a receive buffer descriptor is available */    if (!(pRxBd->statusMode & RX_BD_EMPTY))        {        /* Bump input error packet counter */        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	/* Update the STOP register from the next packet pointer */	PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R6), nextStop);	PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R7),				    (nextStop >> 8));        intUnlock(s);        return ((RX_BD *) NULL);        }    /*     * We always read an even number of bytes from the controller,     * so adjust the length if necessary.     */     if ((length & ODD_MSK) != 0)        ++length;    pRxBd->dataLength = length;             /* Read the data from the Rx ring buffer */     for (pData = pRxBd->dataPointer; length != 0; length -=2)	READ_PTR_R14_R15 (pData);     /* Update the STOP register from the next packet pointer */    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R6), nextStop);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R7),				(nextStop >> 8));    /* Update status buffer descriptor */    pRxBd->statusMode = 0;    /* incr buffer descriptor count */    pDrvCtrl->rxBdNext = (pDrvCtrl->rxBdNext + 1) % pDrvCtrl->rxBdNum;    intUnlock(s);    return (pRxBd);    }/********************************************************************************* iOlicomRecv - process the next incoming packet** This routine processes an input frame, then passes it up to the higher* level in a form it expects.** RETURNS: OK, always.*/LOCAL STATUS iOlicomRecv    (    END_DEVICE *	pDrvCtrl,	/* pointer to END_DEVICE structure */    RX_BD *		pRxBd    )    {    END_OBJ *   pOliObj = &pDrvCtrl->endObj;    M_BLK_ID    pMblk;      /* MBLK to send upstream */    CL_BLK_ID   pClBlk;     /* pointer to clBlk */    char *      pBuf;       /* A replacement buffer for the current RxD */    char *      pData;      /* Data pointer for the current RxD */    int         len;        /* Len of the current data */    END_LOG_MSG (END_DEBUG_RX, "iOlicomRecv\n", 0, 0, 0, 0, 0, 0);    /* Allocate an MBLK, and a replacement buffer */     pMblk = NET_MBLK_ALLOC();    pBuf  = NET_BUF_ALLOC();

⌨️ 快捷键说明

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