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

📄 muxlib.c

📁 vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* RETURNS: OK; ENETDOWN, if <pCookie> does not represent a valid driver;* or ERROR, if the driver's registered endMCastAddrGet() or nptMCastAddrGet() * routines fail.** ERRNO: S_muxLib_NO_DEVICE*/int muxMCastAddrGet    (    void *        pCookie, /* binding instance from muxBind() or muxTkBind() */    MULTI_TABLE * pTable   /* pointer to a table to be filled and returned. */    )    {    int       error;    END_OBJ * pEnd;    pEnd = PCOOKIE_TO_ENDOBJ (pCookie);    if (pEnd == NULL)	{        errnoSet(S_muxLib_NO_DEVICE);	error = ENETDOWN;	}    else 	{	error = pEnd->pFuncTable->mCastAddrGet(pEnd, pTable);	}    return (error);    }/******************************************************************************** muxUnbind - detach a network service from the specified device** This routine disconnects a network service from the specified device.  The* <pCookie> argument indicates the service/device binding returned by the* muxBind() or muxTkBind() routine. The <type> and <stackRcvRtn> arguments* must also match the values given to the original muxBind() or muxTkBind()* call.** NOTE: If muxUnbind() returns ERROR, and 'errno' is set to EINVAL, this* indicates that the device is not bound to the service.** RETURNS: OK; or ERROR, if muxUnbind() fails.* * VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call muxUnBind() from within the kernel * protection domain only, and the data referenced in the <stackRcvRtn> and  * <pCookie> parameters must reside in the kernel protection domain.  * This restriction does not apply under non-AE versions of VxWorks.  ** ERRNO: EINVAL, S_muxLib_NO_DEVICE*/STATUS muxUnbind    (    void *  pCookie, 	/* binding instance from muxBind() or muxTkBind() */    long    type, 	/* type passed to muxBind() or muxTkBind() call */    FUNCPTR stackRcvRtn /* pointer to stack receive routine */    )    {    int error;    END_OBJ * 	   pEnd;    NET_PROTOCOL * pNode;    FUNCPTR        netStackRcvRtn = NULL;    pEnd = PCOOKIE_TO_ENDOBJ (pCookie);    if (pEnd == NULL)	{        errnoSet (S_muxLib_NO_DEVICE);	error = EINVAL;	return error;	}    else         {        /* Find and remove the matching binding. */	for (pNode = (NET_PROTOCOL *)lstFirst (&pEnd->protocols); 	     pNode != NULL; 	     pNode = (NET_PROTOCOL *)lstNext(&pNode->node))	    {            if (pNode->pNptCookie != pCookie)                continue;            /*             * If necessary, fetch the actual stack receive routine             * instead of the wrapper installed for END devices.             */            if (pNode->nptFlag)                {                MUX_ID muxId = (MUX_ID)pNode->pSpare;                if (muxId)                    netStackRcvRtn = muxId->netStackRcvRtn;                }            else                netStackRcvRtn = pNode->stackRcvRtn;            /* This test should always succeed since the entry matches. */            if (netStackRcvRtn == stackRcvRtn && pNode->type == type)                {                if (pNode->type == MUX_PROTO_SNARF)                    (pEnd->snarfCount)--;                if (pNode->type == MUX_PROTO_OUTPUT)                    pEnd->outputFilter = NULL;                lstDelete (&pEnd->protocols, &pNode->node);                muxTkUnbindUpdate (pNode->pNptCookie);                KHEAP_FREE( (char *)pNode);                return (OK);                }            }        }    errnoSet (EINVAL);    return (ERROR);    }    /******************************************************************************** muxDevUnload - unloads a device from the MUX** This routine unloads a device from the MUX.  This breaks any network* connections that use the device.  When this routine is called, each service* bound to the device disconnects from it with the stackShutdownRtn() routine* that was registered by the service.  The stackShutdownRtn() should call* muxUnbind() to detach from the device.  Then, muxDevUnload() calls the* device's endUnload() or nptUnload() routine.** .IP <pName>* Expects a pointer to a string containing the name of the device, for example* 'ln' or 'ei'** .IP <unit>* Expects the unit number of the device indicated by <pName>** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call muxDevUnLoad() from within the kernel * protection domain only. This restriction does not apply under non-AE * versions of VxWorks.  ** RETURNS: OK, on success; ERROR, if the specified device was not found* or some other error occurred; or the error value returned by the driver's* unload() routine.** ERRNO: S_muxLib_UNLOAD_FAILED, S_muxLib_NO_DEVICE**/STATUS muxDevUnload    (    char * pName, 	/* a string containing the name of the device */			/* for example, ln or ei */    int    unit         /* the unit number */    )    {    int            error;    END_OBJ *      pEnd = NULL;    NET_PROTOCOL * pNetNode;    NET_PROTOCOL * pNetNodeNext;    END_TBL_ROW *  pNode;    void * pTemp = NULL;    pEnd = endFindByName (pName, unit);    if (pEnd != NULL)	{        semTake (muxLibState.lock, WAIT_FOREVER);        /*          * Find which row we're in. We know it's here because          * the endFindByName() routine was successful.         */        for (pNode = (END_TBL_ROW *)lstFirst (&endList); pNode != NULL;              pNode = (END_TBL_ROW *)lstNext (&pNode->node))            {            if (STREQ(pNode->name, pName))                break;            }        /* First we shutdown all of the protocols. */        for (pNetNode = (NET_PROTOCOL *) lstFirst (&pEnd->protocols);	     pNetNode != NULL; pNetNode = pNetNodeNext)             {	    /* Save pointer to next node as shutdown rtn will free pNetNode */	    pNetNodeNext = (NET_PROTOCOL *) lstNext (&pNetNode->node);            if (pNetNode->stackShutdownRtn != NULL)		{		/*		 * stackShutdownRtn() is expected to call muxUnbind() which 		 * will free the NET_PROTOCOL node, so that operation is not                 * necessary here. The END and NPT devices use different                 * shutdown prototypes. Select the appropriate format.                 */                if (pNetNode->nptFlag)                    {                    MUX_ID muxId = (MUX_ID)pNetNode->pSpare;                    void * pSpare = NULL;                    pSpare = (muxId) ? muxId->pNetCallbackId : NULL;                    pNetNode->stackShutdownRtn(pSpare);                    }                else                    pNetNode->stackShutdownRtn (pEnd, pNetNode->pSpare);		}	    else		{		/*		 * If no shutdown rtn then muxUnbind () will not be called and		 * we need to free the pNetNode ourselves.		 */		lstDelete (&pEnd->protocols, &pNetNode->node);		KHEAP_FREE ((char *)pNetNode);		}	    }   	/* Release BIB and delete node before unloading device driver */        muxTkUnloadUpdate (pEnd);        lstDelete (&pNode->units, &pEnd->node); 	/* remember the device specific value for backward compatibility purpose */	pTemp = pEnd->devObject.pDevice;        /* Unload (destroy) the end object */	error = pEnd->pFuncTable->unload (pEnd); 	/*	 * XXX Freeing END_OBJ(or DRV_CTRL) should be done by END, not here.         * In futre, this code will be removed.	 */	if (pTemp == pEnd)            {            /* for backward compatibility, free the end_object */            KHEAP_FREE ((char *)pTemp);            }        /*        * XXX I don't see how 'unload' can really fail. There's nothing the mux	* can do to recover or continue using the END_OBJ.  All the protocols are	* already gone.        */        if (error != OK)            {            errnoSet (S_muxLib_UNLOAD_FAILED);            semGive (muxLibState.lock);            return (ERROR);            }         /* Is this row empty?  If so, remove it. */        if (lstCount (&pNode->units) == 0)            {            lstDelete (&endList, &pNode->node);            KHEAP_FREE ((char *)pNode);            }        error = OK;        semGive (muxLibState.lock);        }    else        {        errnoSet (S_muxLib_NO_DEVICE);        error = ERROR;        }        return (error);    }#endif	/* STANDALONE_AGENT *//******************************************************************************** muxLinkHeaderCreate - attach a link-level header to a packet** This routine constructs a link-level header using the source address* of the device indicated by the <pCookie> argument as returned from the* muxBind() routine.** The <pDstAddr> argument provides an M_BLK_ID buffer containing the* link-level destination address.* Alternatively, the <bcastFlag> argument, if TRUE, indicates that the* routine should use the link-level broadcast address, if available for* the device. Although other information contained in the <pDstAddr>* argument must be accurate, the address data itself is ignored in that case.** The <pPacket> argument contains the contents of the resulting link-level* frame.  This routine prepends the new link-level header to the initial* 'mBlk' in that network packet if space is available or allocates a new* 'mBlk'-'clBlk'-cluster triplet and prepends it to the 'mBlk' chain. * When construction of the header is complete, it returns an M_BLK_ID that * points to the initial 'mBlk' in the assembled link-level frame.** RETURNS: M_BLK_ID or NULL.** ERRNO: S_muxLib_INVALID_ARGS*/M_BLK_ID muxLinkHeaderCreate    (    void * 	pCookie, 	/* protocol/device binding from muxBind() */    M_BLK_ID 	pPacket, 	/* structure containing frame contents */    M_BLK_ID 	pSrcAddr,	/* structure containing source address */    M_BLK_ID 	pDstAddr, 	/* structure containing destination address */    BOOL 	bcastFlag 	/* use broadcast destination (if available)? */    )    {    END_OBJ * 	pEnd;    M_BLK_ID	pMblkHdr = NULL;    pEnd = PCOOKIE_TO_ENDOBJ (pCookie);    if (pEnd == NULL)        {        errnoSet(S_muxLib_INVALID_ARGS);        return (NULL);         }    if (pEnd->pFuncTable->formAddress != NULL)        {        pMblkHdr = pEnd->pFuncTable->formAddress (pPacket, pSrcAddr,                                                  pDstAddr, bcastFlag);        }    else        {        switch (pEnd->mib2Tbl.ifType)            {            case M2_ifType_ethernet_csmacd:            case M2_ifType_iso88023_csmacd:                M_PREPEND(pPacket, SIZEOF_ETHERHEADER, M_DONTWAIT);                if ( pPacket == NULL)                    return NULL;                if (bcastFlag)                    bcopy (etherbroadcastaddr, pPacket->m_data, 6);                else                    bcopy(pDstAddr->m_data, pPacket->m_data, pDstAddr->m_len);                bcopy(pSrcAddr->m_data, pPacket->m_data + pDstAddr->m_len,                      pSrcAddr->m_len);                ((struct ether_header *)pPacket->m_data)->ether_type =                      pDstAddr->mBlkHdr.reserved;                pMblkHdr = pPacket;                break;            default:                break;            }        }    return (pMblkHdr);    }/******************************************************************************** muxAddressForm - form a frame with a link-layer address** Use this routine to create a frame with an appropriate link-layer address.  * As input, this function expects the source address, the destination address, * and the data you want to include in the frame. When control returns from the * muxAddressForm() call, the <pMblk> parameter references a frame ready for * transmission.  Internally, muxAddressForm() either prepended the link-layer * header to the data buffer supplied in <pMblk> (if there was enough room) or * it allocated a new 'mBlk'-'clBlk'-cluster and prepended the new 'mBlk' to * the 'mBlk' chain supplied in <pMblk>.** NOTE: You should set the 'pDstAddr.mBlkHdr.reserved' field to the network* service type.** .IP <pCookie> 13* Expects the cookie returned from the muxBind().  This cookie * indicates the device to which the MUX has bound this protocol. * .IP <pMblk>* Expects a pointer to the 'mBlk' structure that contains the packet. * .IP <pSrcAddr>* Expects a pointer to the 'mBlk' that contains the source address.* .IP <pDstAddr>* Expects a pointer to the 'mBlk' that contains the destination address.** NOTE: This routine is used only with ENDs, and is not needed for NPT* drivers.** VXWORKS AE PROTECTION DO

⌨️ 快捷键说明

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