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

📄 ultraend.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_PS1 | CMD_STP);    /* Program wait states (0) */    SYS_OUT_BYTE (pDrvCtrl, LAN_ENH, 0x00);    /* put the Ultra in START mode */    SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STA);    /* Take interface out of loopback */    SYS_OUT_BYTE (pDrvCtrl, LAN_TCON, 0x00);    if (!(pDrvCtrl->flags & ULTRA_POLLING))	{	SYS_OUT_BYTE (pDrvCtrl, CTRL_INT, INT_ENABLE);	SYS_OUT_BYTE (pDrvCtrl, LAN_INTMASK,		      IM_OVWE | IM_TXEE | IM_PTXE | IM_PRXE);	}    }/******************************************************************************** ultraInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void ultraInt    (    ULTRA_DEVICE *	pDrvCtrl	/* interrupting device */    )    {    UCHAR istat;        /* Acknowledge interrupt, get Transmit/Receive status */    pDrvCtrl->istat = 0;    do	{	SYS_IN_BYTE (pDrvCtrl, LAN_INTSTAT, &istat);	SYS_OUT_BYTE (pDrvCtrl, LAN_INTSTAT, istat);	pDrvCtrl->istat |= istat;	}    while (istat != 0);    SYS_IN_BYTE (pDrvCtrl, LAN_TSTAT, &pDrvCtrl->tstat);    SYS_IN_BYTE (pDrvCtrl, LAN_RSTAT, &pDrvCtrl->rstat);    DRV_LOG (DRV_DEBUG_INT,	     "%s%d: istat %x tstat %x rstat %x flags %x\n",	     (int) DEV_NAME, pDrvCtrl->unit,	     pDrvCtrl->istat, pDrvCtrl->tstat,	     pDrvCtrl->rstat, pDrvCtrl->flags);    /* Receive-error */    if (pDrvCtrl->istat & ISTAT_RXE)	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);    /* Receive, Overwrite */    if (pDrvCtrl->istat & (ISTAT_PRX | ISTAT_OVW))	{	if (pDrvCtrl->istat & ISTAT_OVW)	    {	    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	    DRV_LOG (DRV_DEBUG_RX | DRV_DEBUG_INT | DRV_DEBUG_ERR,		     "%s%d: overwrite error\n",		     (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);	    }	if (!(pDrvCtrl->flags & ULTRA_RCV_HANDLING_FLAG))	    {	    if (netJobAdd ((FUNCPTR) ultraHandleRcvInt,			   (int) pDrvCtrl, 0, 0, 0, 0) == ERROR)		{		/* Error - will have to wait until next RX interrupt recv'd */		logMsg ("%s%d: failed to queue ultraHandleRcvInt\n",			(int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);		/* failed netJobAdd causes panic, stop device */		SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STP);		return;		}	    pDrvCtrl->flags |= ULTRA_RCV_HANDLING_FLAG;	    SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_PS0);	    SYS_IN_BYTE (pDrvCtrl, LAN_CURR, &pDrvCtrl->current);	    SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, 0);	    DRV_LOG (DRV_DEBUG_RX | DRV_DEBUG_INT,		     "%s%d: queued ultraHandleRcvInt: curr=%x next=%x\n",		     (int) DEV_NAME, pDrvCtrl->unit,		     pDrvCtrl->current, pDrvCtrl->nextPacket, 5, 6);	    }	}    /* Transmit-error, Transmit */    if (pDrvCtrl->istat & (ISTAT_TXE | ISTAT_PTX))	{	if (pDrvCtrl->istat & ISTAT_TXE)	    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1);	if ((pDrvCtrl->istat & ISTAT_TXE)	    || (pDrvCtrl->tstat & (TSTAT_ABORT | TSTAT_UNDER | TSTAT_CDH				   | TSTAT_OWC | TSTAT_PTX)))	    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);	pDrvCtrl->flags &= ~ULTRA_TX_IN_PROGRESS;	if (pDrvCtrl->flags & ULTRA_TX_BLOCKED)	    {	    DRV_LOG (DRV_DEBUG_TX | DRV_DEBUG_INT,		     "%s%d: queuing muxTxRestart\n",		     (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);	    if (netJobAdd ((FUNCPTR)muxTxRestart,			   (int) &pDrvCtrl->endObj, 0, 0, 0, 0) == ERROR)		{		/* Error - can't queue, transmitter is hung. */		logMsg ("%s%d: failed to queue muxTxRestart\n",			(int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);		/* failed netJobAdd causes panic, stop device */		SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_STP);		return;		}	    pDrvCtrl->flags &= ~ULTRA_TX_BLOCKED;	    }	}    }/******************************************************************************** ultraPacketGet - get next received message** Get next received packet into the supplied buffer.** RETURNS: length of the next packet, or a negative number if none available.*/LOCAL int ultraPacketGet    (    ULTRA_DEVICE *	pDrvCtrl,    UCHAR *		pDst    )    {    int		len;    char *	pSrc;    int		wrapSize = 0;    UINT	packetSize;    int		oldLevel;    ULTRA_HEADER * pH;    if (pDrvCtrl->nextPacket == pDrvCtrl->current)	return (0);    /* Invalidate cache and get pointer to header */    ULTRA_CACHE_INVALIDATE ((UCHAR *)(pDrvCtrl->memAddr + (ULTRA_PSTART << 8)),			    (pDrvCtrl->memSize - (ULTRA_PSTART << 8)));    pH = (ULTRA_HEADER *)(pDrvCtrl->memAddr + (pDrvCtrl->nextPacket << 8));    DRV_LOG (DRV_DEBUG_RX, "%s%d: ultraPacketGet: %02x/%d/%02x/%02x\n",	     (int) DEV_NAME, pDrvCtrl->unit,	     pH->next, (((UINT)pH->uppByteCnt << 8) + pH->lowByteCnt),	     pDrvCtrl->nextPacket, pDrvCtrl->uppByteCnt);    if ((pH->next < ULTRA_PSTART) || (pH->next >= ULTRA_PSTOP))	{	pH->next = pDrvCtrl->nextPacket + pDrvCtrl->uppByteCnt + 1;	DRV_LOG (DRV_DEBUG_RX | DRV_DEBUG_ERR,		 "%s%d: ultraPacketGet: fix pH->next (%x)\n",		 (int) DEV_NAME, pDrvCtrl->unit, pH->next, 4, 5, 6);	if (pH->next >= ULTRA_PSTOP)	    pH->next = ULTRA_PSTART + (pH->next - ULTRA_PSTOP);	}    if (pH->rstat & RSTAT_PRX)	{	/* 3Com says this status marks a packet bit-shifted in memory;	 * the data cannot be trusted but the NIC header is OK.	 */	if (pH->rstat & (RSTAT_DFR | RSTAT_DIS))	    {	    DRV_LOG (DRV_DEBUG_RX | DRV_DEBUG_ERR,		     "%s%d: ultraPacketGet: bit-shifted packet\n",		     (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);	    packetSize = -2;	    goto doneGet;	    }	}    else	{	DRV_LOG (DRV_DEBUG_RX | DRV_DEBUG_ERR,		 "%s%d: ultraPacketGet: corrupted packet\n",		 (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6);	packetSize = -2;	goto doneGet;	}    /* Compute packet size, excluding Ultra header */    pSrc = ((char *)pH) + sizeof(ULTRA_HEADER);    packetSize = (((UINT)pH->uppByteCnt << 8) + pH->lowByteCnt		  - sizeof(ULTRA_HEADER));    if ((packetSize < ULTRA_MIN_SIZE) || (packetSize > ULTRA_MAX_SIZE))	{	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	DRV_LOG (DRV_DEBUG_RX | DRV_DEBUG_ERR,		 "%s%d: ultraPacketGet: bad size packet %d\n",		 (int) DEV_NAME, pDrvCtrl->unit, packetSize, 4, 5, 6);	packetSize = -2;	goto doneGet;	}    /* copy separated frame to network buffer */    len = packetSize;    if ((pSrc+packetSize) > (char *)(pDrvCtrl->memAddr + (ULTRA_PSTOP << 8)))	{	wrapSize = (char *)(pDrvCtrl->memAddr + (ULTRA_PSTOP << 8)) - pSrc;	bcopy (pSrc, pDst, wrapSize);	len -= wrapSize;	pSrc = (char *) (pDrvCtrl->memAddr + (ULTRA_PSTART << 8));	pDst += wrapSize;	}    bcopy (pSrc, pDst, len);        DRV_LOG (DRV_DEBUG_RX, "%s%d: ultraPacketGet: c/n=%x/%x len/next=%d/%x\n",	     (int) DEV_NAME, pDrvCtrl->unit,	     pDrvCtrl->current, pDrvCtrl->nextPacket,	     (((UINT)pH->uppByteCnt << 8) + pH->lowByteCnt), pH->next); doneGet:    /* Mark packet as received. */    oldLevel = intLock ();    pDrvCtrl->nextPacket = pH->next;    pDrvCtrl->uppByteCnt = pH->uppByteCnt;    if (pDrvCtrl->nextPacket != ULTRA_PSTART)	SYS_OUT_BYTE (pDrvCtrl, LAN_BOUND, pDrvCtrl->nextPacket - 1);    else	SYS_OUT_BYTE (pDrvCtrl, LAN_BOUND, ULTRA_PSTOP - 1);    intUnlock (oldLevel);    return (packetSize);    }/******************************************************************************** ultraRecv - process the next incoming packet.** Handle one incoming packet.  The packet is checked for errors.** RETURNS: OK or ERROR.*/LOCAL STATUS ultraRecv    (    ULTRA_DEVICE *	pDrvCtrl	/* interrupting device */    )    {    int		len;    char *	pBuf;    CL_BLK_ID	pClBlk;    M_BLK_ID	pMblk;      /* MBLK to send upstream */    /* Allocate an MBLK, and a replacement buffer */    pBuf = netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->clPoolId);    if (!pBuf)	{	DRV_LOG (DRV_DEBUG_RX, "%s%d: ultraRecv: Out of clusters!\n",		 (int) DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);	pDrvCtrl->lastError.errCode = END_ERR_WARN;	pDrvCtrl->lastError.pMesg = "out of clusters";	muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);	return (ERROR);	}    /* Read in offset packet so IP header is long-aligned */    len = ultraPacketGet (pDrvCtrl, pBuf + pDrvCtrl->offset);    if (len <= 0)	{	DRV_LOG (DRV_DEBUG_RX, "%s%d: ultraRecv: bad packet (%d)\n",		 (int) DEV_NAME, pDrvCtrl->unit, len, 0, 0, 0);	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *) pBuf);	return (OK);	}    pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA);    if (!pMblk)	{	DRV_LOG (DRV_DEBUG_RX, "%s%d: ultraRecv: out of M blocks\n",		 (int) DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);	pDrvCtrl->lastError.errCode = END_ERR_WARN;	pDrvCtrl->lastError.pMesg = "out of M blocks.";	muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *) pBuf);	return (OK);	}    pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT);    if (!pClBlk)	{	DRV_LOG (DRV_DEBUG_RX, "%s%d: ultraRecv: out of CL blocks\n",		 (int) DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0);	pDrvCtrl->lastError.errCode = END_ERR_WARN;	pDrvCtrl->lastError.pMesg = "out of CL blocks.";	muxError (&pDrvCtrl->endObj, &pDrvCtrl->lastError);	netMblkFree (pDrvCtrl->endObj.pNetPool, (M_BLK_ID)pMblk);	netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *) pBuf);	return (OK);	}    /* Associate the data pointer with the MBLK */    netClBlkJoin (pClBlk, pBuf, ULTRA_BUFSIZ, NULL, 0, 0, 0);        /* Associate the data pointer with the MBLK */    netMblkClJoin (pMblk, pClBlk);    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkHdr.mLen    = len;    pMblk->mBlkPktHdr.len  = len;    pMblk->mBlkHdr.mData  += pDrvCtrl->offset;	/* match ultraPacketGet */    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);    /* Record received packet */    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);    return (OK);    }/******************************************************************************** ultraHandleRcvInt - 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 ultraHandleRcvInt    (    ULTRA_DEVICE *	pDrvCtrl	/* interrupting device */    )    {    DRV_LOG (DRV_DEBUG_RX,	     "%s%d: ultraHandleRcvInt: begin, flags=%x curr=%x next=%x\n",	     (int) DEV_NAME, pDrvCtrl->unit,	     pDrvCtrl->flags, pDrvCtrl->current, pDrvCtrl->nextPacket, 6);    while (TRUE)	{	int oldLevel;    	/* Refresh the current pointer, and check if done. */	oldLevel = intLock ();	SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, CMD_PS0);	SYS_IN_BYTE (pDrvCtrl, LAN_CURR, &pDrvCtrl->current);	SYS_OUT_BYTE (pDrvCtrl, LAN_CMD, 0);	if (pDrvCtrl->nextPacket == pDrvCtrl->current)	    {	    /* all packets consumed. */	    pDrvCtrl->flags &= ~ULTRA_RCV_HANDLING_FLAG;	    intUnlock (oldLevel);	    break;	    }	intUnlock (oldLevel);	if (ultraRecv (pDrvCtrl) == ERROR)	    {	    /*	     * ultraRecv only errors if out of clusters or the like.  We	     * need to exit this loop and let the netTask run for a bit	     * in order for it to clean up its memory.	     */	    oldLevel = intLock ();	    pDrvCtrl->flags &= ~ULTRA_RCV_HANDLING_FLAG;	    intUnlock (oldLevel);	    break;	    }	}    DRV_LOG (DRV_DEBUG_RX,	     "%s%d: ultraHandleRcvInt: done, flags=%x curr=%x next=%x\n",	     (int) DEV_NAME, pDrvCtrl->unit,	     pDrvCtrl->flags, pDrvCtrl->current, pDrvCtrl->nextPacket, 6);    }/******************************************************************************** ultraSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine.  ** RETURNS: OK or ERROR.*/LOCAL STATUS ultraSend    (    void *	pObj,		/* device ptr */    M_BLK_ID	pMblk		/* data to send */    )    {    int		oldLevel;    int		len;    UINT	transmitPage;    UCHAR *	pBuf;    ULTRA_DEVICE * pDrvCtrl = (ULTRA_DEVICE *) pObj;           /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    if (!(pDrvCtrl->flags & ULTRA_POLLING))	END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);    if (pDrvCtrl->flags & ULTRA_TX_IN_PROGRESS)	{	int cnt;	/*	 * Wait up to 1 second. Testing on a slow 486 pc platform this	 * loop never waited more than 2 ticks at 60/sec.	 */	cnt = sysClkRateGet ();	while ((pDrvCtrl->flags & ULTRA_TX_IN_PROGRESS) && (cnt-- > 0))	    taskDelay (1);	DRV_LOG (DRV_DEBUG_TX,		 "%s%d: ultraSend: TX_IN_PROGRESS: waited %d ticks\n",		 (int) DEV_NAME, pDrvCtrl->unit,		 sysClkRateGet() - cnt, 0, 0, 0);	}    /* If TX still in progress, note blocked and return ERROR */    oldLevel = intLock ();    if (pDrvCtrl->flags & ULTRA_TX_IN_PROGRESS)	{	DRV_LOG (DRV_DEBUG_TX, "%s%d: ultraSend: TX_IN_PROGRESS (flags=%x)\n",		 (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->flags, 4, 5, 6);	pDrvCtrl->flags |= ULTRA_TX_BLOCKED;	if (!(pDrvCtrl->flags & ULTRA_POLLING))	    END_TX_SEM_GIVE (&pDrvCtrl->endObj);	intUnlock (oldLevel);        return (END_ERR_BLOCK);	}    intUnlock (oldLevel);    /* Copy and free the MBLK */    transmitPage = pDrvCtrl->transmitPage [pDrvCtrl->transmitCnt & 1];    pBuf = (UCHAR *)(pDrvCtrl->memAddr + (transmitPage << 8));    len = netMblkToBufCopy (pMblk, pBuf, NULL);    len = max (len, ETHERSMALL);    netMblkClChainFree (pMblk);    DRV_LOG (DRV_DEBUG_TX, "%s%d: ultraSend, packet %d, len=%d\n",	     (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->transmitCnt, len, 5, 6);    

⌨️ 快捷键说明

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