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

📄 muxlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
/* muxLib.c - MUX network interface library *//* Copyright 1984 - 1999 Wind River Systems, Inc. *//*modification history--------------------02r,31mar99,spm  removed \040 codes from muxMCastAddrGet() entry (SPR #26268)02q,03mar99,pul  fix for SPR# 2428502p,02mar99,pul  fixed the return value for muxUnbind(): SPR# 24293020,13nov98,n_s  added muxDevStopAll function.  Added reboot hook in                 muxLibInit so that muxDevStop all is called prior to reboot.                  spr #2322902n,09sep98,ham  corrected the comprison of ifTypes and MUX_MAX_IFTYPE.02m,09sep98,ham  cont'd SPR#22298.02l,08sep98,ham  moved MUX_MAX_TYPE to h/muxLib.h, SPR#22298.02k,21aug98,n_s  fixed ifInUnknownProtos update in muxReceive, ifOutNUcastPkts                 update in muxSend (). spr 21074.02j,16jul98,n_s  Added semGive () to ERROR condition for driver unload call in                 muxDevUnload ().02i,13jul98,n_s  fixed muxDevLoad () to limit device name strcpy () to                  END_NAME_MAX.  spr # 2164202h,13jul98,n_s  fixed muxBind () to clear malloc'd NET_PROTOCOL. spr # 2164402g,24jun98,n_s  fixed muxUnbind () to check NET_PROTOCOL node for type 02f,15jun98,n_s  fixed muxDevUnload () and muxUnbind (). spr # 2154202e,13feb98,n_s  fixed endFindByName () to handle multiple devices.                  spr # 21055.02d,02feb98,spm  removed unneeded '&' operator and corrected spacing02c,17jan98,gnn  fixed a bug in the output filter with passing LL_HDR_INFO.02b,17jan98,gnn  changed output routines so they can be BOOL like receive                 routines.02a,17jan98,kbw  made man page fixes01z,14dec97,kbw  made man page fixes01y,10dec97,kbw  made man page fixes01x,08dec97,gnn  END code review fixes.01w,21oct97,kbw  made man page fixes01v,08oct97,vin  fixed muxPacketAddrGet().01u,07oct97,vin  fixed a problem with calling muxIoctl, removed IFF_LOAN01t,03oct97,gnn  added error routine and cleaned up function prototypes01s,25sep97,gnn  SENS beta feedback fixes01r,25aug97,gnn  documenatation changs to make mangen happy.01q,25aug97,gnn  fixed a bug in the restart routine.01p,22aug97,gnn  updated polled mode support.01o,19aug97,gnn  changes due to new buffering scheme.01n,12aug97,gnn  changes necessitated by MUX/END update.01m,31jul97,kbw  fixed man page bug that broke build, comment in comment01l,31jul97,kbw  fixed man page problems found in beta review01k,15may97,gnn  removed many warnings.                 added code to handle MUX_PROTO_OUTPUT.01j,30apr97,jag  man edits for funtion muxBufInit()01i,17apr97,gnn  removed muxDevStart from muxDevLoad.01h,07apr97,gnn  added errnoSet calls                 added muxDevNameGet.                 modified the way muxDevLoad works.01g,12mar97,gnn  fixed a bug in muxReceive's calling API.01f,03feb97,gnn  Modified muxBuf code to be more generic and support other,                 non-TMD systems.01e,29jan97,gnn  Removed the code to start the tNetTask.01d,21jan97,gnn  Added muxBuf* code to handle buffering system.                 Added code to handle the new SNARF option.                 Removed all loaning and reference counting stuff.                 Removed TxBuf stuff.01e,23oct96,gnn  name changes to follow coding standards.                 removed some compiler warnings.01d,22oct96,gnn  added routines to start and stop drivers.                 added code to handle buffer loaning startup requests on                 both the protocol and device side.                 replaced netVectors with netBuffers.01c,23sep96,gnn	 moved some generic code to here from the driver.01b,22Apr96,gnn	 filling in with real code.01a,21Mar96,gnn	 written.*/ /*DESCRIPTIONThis library provides the routines that define the MUX interface, a facilitythat handles communication between the data link layer and the networkprotocol layer.  Using the MUX, the VxWorks network stack has decoupled thedata link and network layers.  Thus, drivers and protocols no longer need knowledge of each other's internals.  As a result, the network driver and protocol are nearly independent of each another.  This independence makes it much easier to add a new drivers or protocols.  For example, if you add a new END, all existing MUX-based protocols can use the newdriver.  Likewise, if you add a new MUX-based protocol, any existing END can use the MUX to access the new protocol.  INCLUDE FILES: errno.h, lstLib.h, logLib.h, string.h,m2Lib.h, bufLib.h, if.h, end.h, muxLib.hSEE ALSO.I "Network Protocol Toolkit User's Guide"*//* includes */#include "vxWorks.h"#include "taskLib.h"#include "stdio.h"#include "errno.h"#include "errnoLib.h"#include "lstLib.h"#include "logLib.h"#include "string.h"#include "m2Lib.h"#include "net/if.h"		/* Needed for IFF_LOAN flag. */#include "bufLib.h"#include "semLib.h"#include "end.h" /* Necessary for any END as well as the MUX */#include "muxLib.h"#include "etherLib.h"#include "rebootLib.h"/* defints */#define STREQ(A, B) (strcmp(A, B) == 0 ? 1 : 0)#define NET_TASK_NAME "tNetTask"/* globals */int muxDebug = 0;SEM_ID muxLock = NULL;                  /* To lock on muxDevLoads. *//* locals */LOCAL LIST endList;LOCAL LIST addrResList[MUX_MAX_IFTYPE + 1]; /* IFT_xxx begins from 1 *//* forward declarations *//********************************************************************************* muxLibInit - initialize global state for the MUX** This routine initializes all global state for the MUX.** RETURNS: OK or ERROR.*/STATUS muxLibInit (void)    {    int count;        if (muxLock != NULL)        return (OK);        muxLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);    if (muxLock == NULL)        return (ERROR);    /* Initialize our lists to empty. */    /* addrResList[0] will not be used because IFT_xxx begins from 1 */    for (count = 0; count <= MUX_MAX_IFTYPE; count++)        lstInit (&addrResList[count]);        lstInit (&endList);        /* Add hook to stop all ENDs when the system reboots */    if (rebootHookAdd ((FUNCPTR) muxDevStopAll) != OK)	{	return (ERROR);	}        return (OK);    }        /******************************************************************************* * muxDevLoad - load a driver into the MUX* * The muxDevLoad() routine loads a network driver into the MUX.  Internally, * this routine calls the specified endLoad() to initialize the software state * of the device.  After the device is initialized, muxDevStart() must be called * to start the device. * .IP <unit> 15* Expects the unit number of the device. * .IP <endLoad> * Expects a pointer to the network driver's endLoad() entry point. * .IP <pInitString> * Expects a pointer to an initialization string, a colon-delimited list of * options.  The muxDevLoad() routine passes this along blindly to * the endLoad() function.* .IP <loaning> * Expects a boolean value that tells the MUX whether the driver * supports buffer loaning on this device.  If the low-level device cannot * support buffer loaning, passing in TRUE has no effect.  * .IP <pBSP>* This argument is passed blindly to the driver, which may or may not use it.  * It is provided so that the BSP can pass in tables of functions that the* driver can use but which are specific to the particular BSP on which* it runs.* * RETURNS: A pointer to the new device or NULL if an error occurred.** ERRNO: S_muxLib_LOAD_FAILED*/END_OBJ* muxDevLoad    (    int unit,                   /* unit number fo device */    END_OBJ* (*endLoad) (char*, void*),	/* load function of the driver  */    char* pInitString,		/* init string for this driver  */    BOOL loaning,		/* we loan buffers  */    void* pBSP                  /* for BSP group  */    )    {    extern LIST endList;    END_OBJ* pNew;    END_TBL_ROW* pNode;    char initString [END_INIT_STR_MAX];    char devName [END_NAME_MAX];    BOOL found = FALSE;        bzero ( (char *)initString, END_INIT_STR_MAX);    bzero ( (char *)devName, END_NAME_MAX);    /* Let's mutually exclude here, wouldn't you say? */    semTake (muxLock, WAIT_FOREVER);        /*     * Loading a device is a two pass algorithm.     *     * This is Pass 1.     *     * In the first pass we as the device what its name is.  If that name     * exists in our table then we add the new node to the end of the     * already existing list.  If not then we create a new row in the     * table, and place the new node as the zero'th (0) element in the node's     * list.     */    if (endLoad ( (char *)devName, NULL) != 0)        {        goto muxLoadErr;        }    if (endFindByName ( (char *)devName, unit) != NULL)        {        goto muxLoadErr;        }    for (pNode = (END_TBL_ROW *)lstFirst(&endList); pNode != NULL; 	pNode = (END_TBL_ROW *)lstNext(&pNode->node))	{	if (STREQ (pNode->name, (char *)devName))            {            found = TRUE;            break;            }	}    /*  If there is no row for this device then add it. */        if (!found)        {        pNode = malloc(sizeof(END_TBL_ROW));        if (pNode == NULL)            {            goto muxLoadErr;            }        bzero ((char *)pNode, sizeof(END_TBL_ROW));        strncpy(pNode->name, devName, END_NAME_MAX - 1);	pNode->name [END_NAME_MAX - 1] = EOS;        lstAdd(&endList, &pNode->node);        }    /*     * This is Pass 2.     *     * Now that we can determine a unique number we assign that number, to     * the device and actually load it.     */        sprintf ( (char *)initString, "%d:%s", unit, pInitString);    pNew = (END_OBJ *)endLoad ( (char *)initString, pBSP);    if (pNew == NULL)        {        goto muxLoadErr;        }    muxIoctl (pNew, EIOCSFLAGS, (char *)pNew->flags);        /*      * Leave this stuff last to prevent a race condition.  The condition     * would be that the driver could call the receive routine      * (it should always of course check to make sure there is one)     * before the buffer pool was set up.  This would be bad.     *     */    lstAdd(&pNode->units, &pNew->node);    pNew->receiveRtn = (FUNCPTR)muxReceive;    semGive (muxLock);    return (pNew);    muxLoadErr:    errnoSet (S_muxLib_LOAD_FAILED);    semGive (muxLock);    return (NULL);    }/****************************************************************************** * muxDevStart - start a device by calling its start routine** This routine starts a device that is already initialized and loaded * into the MUX.  Internally, muxDevStart() calls the device's endStart(), * which handles registering the driver's interrupt service routine and * whatever else is needed to allow the device to handle receiving and * transmitting.  This call to endStart() provides a device-dependent way * to put the device into a running state. * * .IP <pCookie>* Expects a pointer to the END_OBJ returned from the muxDevLoad() that * loaded this driver into the MUX.  This "cookie" is an identifier for the * device. * .LP** RETURNS: OK, ENETDOWN if <pCookie> does not represent a valid device,*          or ERROR if the start routine for the device fails.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxDevStart    (    void* pCookie    /* a pointer to cookie returned by muxDevLoad() */    )    {    int error;    END_OBJ* pEnd;    pEnd = (END_OBJ *)pCookie;    if (pEnd == NULL)	{        errnoSet (S_muxLib_NO_DEVICE);	error = ENETDOWN;	}    else	{	error = pEnd->pFuncTable->start(pEnd);	}    if (error == OK)        {        pEnd->mib2Tbl.ifAdminStatus = M2_ifAdminStatus_up;        pEnd->mib2Tbl.ifOperStatus = M2_ifOperStatus_up;        }        return (error);    }/****************************************************************************** * muxDevStop - stop a device by calling its stop routine** This routine stops the device specified in the <pCookie> parameter.* Internally, muxDevStop() calls the device's own stop routine, thus* putting the device into a stopped state in a device-dependent manner. * * .IP <pCookie> * Expects the pointer returned as the function value of the muxDevLoad() * call for this device.  This pointer identifies the device to which the * MUX has bound this protocol. * .LP** RETURNS: OK, ENETDOWN if <pCookie> does not represent a valid device, or*          ERROR if the stop routine for the device fails.** ERRNO: S_muxLib_NO_DEVICE*/STATUS muxDevStop    (    void* pCookie    /* pointer to cookie that identifies the device */    )    {    int error;    END_OBJ* pEnd;    pEnd = (END_OBJ *)pCookie;    if (pEnd == NULL)	{        errnoSet (S_muxLib_NO_DEVICE);	error = ENETDOWN;	}    else	{	error = pEnd->pFuncTable->stop(pEnd);	}    return (error);    }/******************************************************************************** muxShow - all configured Enhanced Network Drivers** If a driver is specified  <pDevName> and <unit>, this routine reports the* name and type of each protocol bound to it.* If a <pDevName> is not given, the entire list of devices and their protocols* is shown.** .IP <pDevName> 20* Expects a pointer to a string containing the device name, or NULL* .IP <unit>* Expects a unit number for the device* .LP** RETURNS: N/A*/void muxShow    (    char *pDevName,  /* pointer to device name */    int unit         /* unit number for the device */    )    {    int curr;    NET_PROTOCOL* pProto;    END_OBJ* pEnd;     END_TBL_ROW* pNode;        /* If the name is not NULL then find the specific interface to show. */    if (pDevName != NULL)	{	pEnd = endFindByName(pDevName, unit);	if (pEnd == NULL)	    {	    printf("Device %s unit %d not found.\n", pDevName, unit);	    return;	    }	printf("Device: %s Unit: %d\n", pEnd->devObject.name,               pEnd->devObject.unit);        printf("Description: %s\n", pEnd->devObject.description);        /* See if there is an output protocol. */        if (pEnd->outputFilter != NULL)            {	    printf("Output protocol: Recv 0x%lx\n",                   (unsigned long)pEnd->outputFilter);            }        /* List the rest of the regular protocols for the device. */	curr = 0;	for (pProto = (NET_PROTOCOL *)lstFirst(&pEnd->protocols);	    pProto != NULL; 	    pProto = (NET_PROTOCOL *)lstNext(&pProto->node))	    {	    printf("Protocol: %s\tType: %ld\tRecv 0x%lx\tShutdown 0x%lx\n",                    pProto->name, pProto->type,                   (unsigned long)pProto->stackRcvRtn,		   (unsigned long) pProto->stackShutdownRtn);	    curr++;	    }	}    else  /* Show ALL configured ENDs. */	{	for (pNode = (END_TBL_ROW *)lstFirst(&endList); pNode != NULL;              pNode = (END_TBL_ROW *)lstNext(&pNode->node))            {            for (pEnd = (END_OBJ *)lstFirst(&pNode->units); pEnd != NULL;                  pEnd = (END_OBJ *)lstNext(&pEnd->node))                {                printf("Device: %s Unit: %d\n", pEnd->devObject.name,                       pEnd->devObject.unit);                printf("Description: %s\n", pEnd->devObject.description);                if (pEnd->outputFilter != NULL)                    {                    printf("Output protocol: Recv 0x%lx\n",                           (unsigned long)pEnd->outputFilter);                    }                curr = 0;                for (pProto = (NET_PROTOCOL *)lstFirst(&pEnd->protocols);                     pProto != NULL;                      pProto = (NET_PROTOCOL *)lstNext(&pProto->node))                    {                    printf("Protocol: %s\tType: %ld\tRecv 0x%lx\tShutdown 0x%lx\n",                            pProto->name, pProto->type,                           (unsigned long)pProto->stackRcvRtn,                           (unsigned long)pProto->stackShutdownRtn);                    curr++;                    }                }	    }	}

⌨️ 快捷键说明

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