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

📄 usbacmlib.c

📁 T2.0 USB driver.rar T2.0 USB driver.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
* RETURNS: pointer to newly created structure, or NULL if failure*/LOCAL pUSB_ACM_SIO_CHAN createSioChan    (    USBD_NODE_ID nodeId,    UINT16 configuration,    UINT16 interface,    UINT16 deviceProtocol    )    {    pUSB_ACM_SIO_CHAN pSioChan;    /* Try to allocate space for a new modem struct and its buffers */    if ((pSioChan = OSS_CALLOC (sizeof (*pSioChan))) == NULL )        {        USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "Out of Memory \n", 	    0, 0, 0, 0, 0, 0);        return NULL;        }    if((pSioChan->outBfr = OSS_MALLOC (ACM_OUT_BFR_SIZE)) == NULL)	{	destroySioChan (pSioChan);        USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "Out of Memory \n",            0, 0, 0, 0, 0, 0);       	return NULL;	}    if ((pSioChan->inBfr = OSS_MALLOC (ACM_IN_BFR_SIZE)) == NULL)        {	destroySioChan (pSioChan);        USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "Out of Memory \n",            0, 0, 0, 0, 0, 0);	return NULL;	}        pSioChan->sioChan.pDrvFuncs = &usbAcmSioDrvFuncs;    pSioChan->nodeId = nodeId;    pSioChan->mode = SIO_MODE_INT;    pSioChan->connected = TRUE;    pSioChan->callbackStatus = 0x0;     /* No callbacks installed */        /* Configure the Modem. */    if (configureSioChan (pSioChan, configuration, interface) != OK)	{	destroySioChan (pSioChan);	return NULL;	}    /* Link the newly created structure. */    usbListLink (&sioList, pSioChan, &pSioChan->sioLink, LINK_TAIL);    USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "SIOCHAN created \n",            0, 0, 0, 0, 0, 0);    return pSioChan;    }/***************************************************************************** findSioChan - Searches for a USB_ACM_SIO_CHAN for indicated node ID** RETURNS: pointer to matching USB_ACM_SIO_CHAN or NULL if not found*/LOCAL pUSB_ACM_SIO_CHAN findSioChan    (    USBD_NODE_ID nodeId    )    {    pUSB_ACM_SIO_CHAN pSioChan = usbListFirst (&sioList);    while (pSioChan != NULL)	{	if (pSioChan->nodeId == nodeId)	    break;	pSioChan = usbListNext (&pSioChan->sioLink);	}    return pSioChan;    }/***************************************************************************** usbAcmAttachCallback - called by USBD when a modem is attached/removed** The USBD will invoke this callback when a USB modem is attached to or* removed from the system.  <nodeId> is the USBD_NODE_ID of the node being* attached or removed.	<attachAction> is USBD_DYNA_ATTACH or USBD_DYNA_REMOVE.* modems report their class information at the interface level,* so <configuration> and <interface> will indicate the configuratin/interface* that reports itself as a modem.  <deviceClass> and <deviceSubClass> * will match the class/subclass for which we registered.  <deviceProtocol>* shall be USB_COMM_PROTOCOL_COMMONAT.** NOTE: The USBD will invoke this function once for each configuration/* interface which reports itself as a modem.  So, it is possible that* a single device insertion/removal may trigger multiple callbacks.  We* ignore all callbacks except the first for a given device.** RETURNS: N/A*/LOCAL VOID usbAcmAttachCallback    (    USBD_NODE_ID nodeId,     UINT16 attachAction,     UINT16 configuration,    UINT16 interface,    UINT16 deviceClass,     UINT16 deviceSubClass,     UINT16 deviceProtocol    )    {    pUSB_ACM_SIO_CHAN pSioChan;    OSS_MUTEX_TAKE (acmMutex, OSS_BLOCK);    /*      * Depending on the attach code, add a new modem or remove one     * that's already been created.     */    switch (attachAction)	{	case USBD_DYNA_ATTACH:	    /*              * A new device is being attached.	Check if we already 	     * have a structure for this device.	     */	    if (findSioChan (nodeId) != NULL)		break;            USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "New ACM device found \n",                0, 0, 0, 0, 0, 0);            /*              * Create a new structure to manage this device.  If there's	     * an error, there's nothing we can do about it, so skip the	     * device and return immediately. 	     */	    if ((pSioChan = createSioChan (nodeId, configuration, interface,		deviceProtocol)) == NULL)                {                USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "Could not create \                    SIO_CHAN \n", 0, 0, 0, 0, 0, 0);		break;                }	    /*              * Notify registered callers that a new modem has been	     * added and a new channel created.	     */	    notifyAttach (pSioChan, USB_ACM_CALLBACK_ATTACH);            usbAcmOpen ((SIO_CHAN *)pSioChan);	    break;	case USBD_DYNA_REMOVE:	    /*              * A device is being detached.  Check if we have any	     * structures to manage this device.	     */	    if ((pSioChan = findSioChan (nodeId)) == NULL)		break;	    /* The device has been disconnected. */	    pSioChan->connected = FALSE;	    /*              * Notify registered callers that the modem has been	     * removed and the channel disabled. 	     *	     * NOTE: We temporarily increment the channel's lock count	     * to prevent usbAcmSioChanUnlock() from destroying the	     * structure while we're still using it.	     */	    pSioChan->lockCount++;	    notifyAttach (pSioChan, USB_ACM_CALLBACK_DETACH);	    pSioChan->lockCount--;	    /*              * If no callers have the channel structure locked, destroy	     * it now.	If it is locked, it will be destroyed later during	     * a call to usbAcmUnlock().	     */	    if (pSioChan->lockCount == 0)		destroySioChan (pSioChan);	    break;	}    OSS_MUTEX_RELEASE (acmMutex);    }/***************************************************************************** destroyAttachRequest - disposes of an ATTACH_REQUEST structure** RETURNS: N/A* NOMANUAL*/LOCAL VOID destroyAttachRequest    (    pATTACH_REQUEST pRequest    )    {    /* Unlink request */    usbListUnlink (&pRequest->reqLink);    /* Dispose of structure */    OSS_FREE (pRequest);    }/***************************************************************************** destroySioChan - disposes of a USB_PRN_ACM_CHAN structure** Unlinks the indicated USB_ACM_SIO_CHAN structure and de-allocates* resources associated with the channel.** RETURNS: N/A*/LOCAL VOID destroySioChan    (    pUSB_ACM_SIO_CHAN pSioChan    )    {    if (pSioChan != NULL)	{	/* Unlink the structure. */	usbListUnlink (&pSioChan->sioLink);	/* Release pipes and wait for IRPs to be cancelled if necessary. */	if (pSioChan->outPipeHandle != NULL)	    usbdPipeDestroy (usbdHandle, pSioChan->outPipeHandle);	if (pSioChan->inPipeHandle != NULL)	    usbdPipeDestroy (usbdHandle, pSioChan->inPipeHandle);	if (pSioChan->intrPipeHandle != NULL)	    usbdPipeDestroy (usbdHandle, pSioChan->intrPipeHandle);	while (pSioChan->outIrpInUse || pSioChan->inIrpInUse                 || pSioChan->intrIrpInUse)            {	    OSS_THREAD_SLEEP (1);            }	/* release buffers */	if (pSioChan->outBfr != NULL)	    OSS_FREE (pSioChan->outBfr);	if (pSioChan->inBfr != NULL)	    OSS_FREE (pSioChan->inBfr);	/* Release structure. */	OSS_FREE (pSioChan);	}    }    /***************************************************************************** doShutdown - shuts down USB ACM SIO driver** <errCode> should be OK or S_usbAcmLib_xxxx.  This value will be* passed to ossStatus() and the return value from ossStatus() is the* return value of this function.** RETURNS: OK, or ERROR per value of <errCode> passed by caller*/LOCAL STATUS doShutdown    (    int errCode    )    {    pATTACH_REQUEST pRequest;    USB_ACM_SIO_CHAN * pSioChan;    /* Dispose of any outstanding notification requests */    while ((pRequest = usbListFirst (&reqList)) != NULL)	destroyAttachRequest (pRequest);    /* Dispose of any open connections. */    while ((pSioChan = usbListFirst (&sioList)) != NULL)	destroySioChan (pSioChan);	    /*      * Release our connection to the USBD.  The USBD automatically      * releases any outstanding dynamic attach requests when a client     * unregisters.     */    if (usbdHandle != NULL)	{	usbdClientUnregister (usbdHandle);	usbdHandle = NULL;	}    /* Release resources. */    if (acmMutex != NULL)	{	OSS_MUTEX_DESTROY (acmMutex);	acmMutex = NULL;	}    if (acmIrpSem != NULL)        {        OSS_SEM_DESTROY (acmIrpSem);        acmIrpSem = NULL;        }    return ossStatus (errCode);    }/**************************************************************************** usbAcmLibInit - initialize USB ACM SIO driver.** Initializes the USB ACM SIO driver.  The USB acm SIO driver* maintains an initialization count, so calls to this function may be* nested. This function will regsiter the driver as a client for the USBD. It* also registers itself for a notification (by usbd) when a ACM device* is dynamically attached / removed from the USB.** RETURNS: OK, or ERROR if unable to initialize.** ERRNO:**   S_usbAcmLib_OUT_OF_RESOURCES*   S_usbAcmLib_USBD_FAULT*/STATUS usbAcmLibInit (void)    {    /*      * If not already initialized, then initialize internal structures     * and connection to USBD.     */    initCount++;    if (initCount > 1)        return OK;               /* Initialize lists, structures, resources. */    memset (&sioList, 0, sizeof (sioList));    memset (&reqList, 0, sizeof (reqList));    acmMutex = NULL;    usbdHandle = NULL;    acmIrpSem = NULL;    if (OSS_MUTEX_CREATE (&acmMutex) != OK)        return doShutdown (S_usbAcmLib_OUT_OF_RESOURCES);    if (OSS_SEM_CREATE (1, 0 , &acmIrpSem) != OK)        return (doShutdown (S_usbAcmLib_OUT_OF_RESOURCES));    /* Establish connection to USBD */    if (usbdClientRegister (ACM_CLIENT_NAME, &usbdHandle) != OK 	||        usbdDynamicAttachRegister (usbdHandle, 				   USB_CLASS_COMMDEVICE,				   USB_SUBCLASS_ACM, 				   USB_COMM_PROTOCOL_COMMONAT,					   usbAcmAttachCallback) 				  != OK)            {	    return doShutdown (S_usbAcmLib_USBD_FAULT);	    }        return OK;    }/**************************************************************************** usbAcmCallbackRegister - Installs a callback for an event.** This function installs a callback for a <callbackType> event. If the event* occurs, the client will be notified via the installed <callback> function.* <arg> is a client specific argument, used as a parameter to the <callback>* routine.** The macro USB_ACM_CALLBACK defines a callback routine which will be invoked* by usbAcmLib when any of these events happen, provided that the user* registered a callback for such an event. This macro is compatible with the* SIO TxCallback and RxCallback definitions and provides additional * functionality for registering for attachment/removal.* * Note that all these fields are not required for all of the events.* They will be filled with NULL or ZERO (0) when the callback is executed.*** .CS* * typedef STATUS (*USB_ACM_CALLBACK)    (    pVOID       arg,	            /@ caller-defined argument @/    SIO_CHAN * pChan,		    /@ pointer to affected SIO_CHAN @/    UINT16 callbackType,	    /@ defined as USB_ACM_CALLBACK_xxxx @/    UINT8 * pBuf,                   /@ pointer to data buffer, if any data @/                                    /@ transfer is involved. Otherwise NULL @/    UINT16 count                    /@ No of bytes of data transferred @/                                    /@ if a data transfer is involved. @/                                    /@ 0 otherwise. @/    );** .CE** Note that the <pChan> paramter shall be NULL for the Dynamic attachment* notification requests, indicating that the event is not for any particular* device.** Care should be taken not to install multiple callbacks for the same event* for the same <pChan>. How-ever this is not applicable for the dynamic * attachment event notification requests.** Different <callbackType> events suppoted by this driver are** .IP "USB_ACM_CALLBACK_ATTACH"*  Used to get notified of dynamic attachment / removal of usb modems. * .IP "USB_ACM_CALLBACK_SIO_TX"*  Used for transmitting characters. This is equivalent to SIO_CALLBACK_GET_TX_CHAR.* .IP "USB_ACM_CALLBACK_SIO_RX"*  Used for receiving characters. This is equivalent to SIO_CALLBACK_PUT_RCV_CHAR.** RETURNS: OK, or ERROR if unable to install.** ERRNO : S_usbAcmLib_OUT_OF_MEMORY,  S_usbAcmLib_BAD_PARAM**/int usbAcmCallbackRegister     (    SIO_CHAN * pChan,               /* Channel for the callback */    int      callbackType,          /* Callback type. see above */    FUNCPTR  callback,      	    /* the callback routine */    pVOID   arg                     /* User defined argument */    )    {    pUSB_ACM_SIO_CHAN pSioChan = (pUSB_ACM_SIO_CHAN)pChan;    pATTACH_REQUEST pRequest;    int status = OK;        if (callback == NULL)	{        return ossStatus (S_usbAcmLib_BAD_PARAM);	}    if ((callbackType != USB_ACM_CALLBACK_ATTACH) &&         (callbackType != USB_ACM_CALLBACK_DETACH))        {        if (pSioChan == NULL)	    {	    return ossStatus (S_usbAcmLib_BAD_PARAM);	    }        }    switch (callbackType)        {        case USB_ACM_CALLBACK_ATTACH :        case USB_ACM_CALLBACK_DETACH :            /* Client wants to get notified of attachment/removal of modems */            /* Create a new request structure to track this callback request */            OSS_MUTEX_TAKE (acmMutex, OSS_BLOCK);

⌨️ 快捷键说明

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