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

📄 usbacmlib.c

📁 T2.0 USB driver.rar T2.0 USB driver.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
            if ((pRequest = OSS_CALLOC (sizeof (*pRequest))) == NULL)		{	        status = S_usbAcmLib_OUT_OF_MEMORY;		}            else	        {	        pRequest->callback = (USB_ACM_CALLBACK)callback;	        pRequest->callbackArg = arg;	        usbListLink (&reqList, pRequest, &pRequest->reqLink, LINK_TAIL);                /*                 * Perform an initial notification of all currrently                  * attached modems.                 */	 	pSioChan = usbListFirst (&sioList);	        while (pSioChan != NULL)	            {	            if (pSioChan->connected)			(*callback) (arg, 				     (SIO_CHAN *) pSioChan, 				     USB_ACM_CALLBACK_ATTACH, 				     NULL, 				     0);	            pSioChan = usbListNext (&pSioChan->sioLink);	            }	        }            OSS_MUTEX_RELEASE (acmMutex);            return ossStatus (status);        case USB_ACM_CALLBACK_SIO_TX    :        case SIO_CALLBACK_GET_TX_CHAR   :            /* Callback for getting Tx Chars : Normal VxWorks SIO Model */ 	    USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "Tx callback installed \n",                0, 0, 0, 0, 0, 0);            pSioChan->callbackStatus |= USB_ACM_CALLBACK_SIO_TX;            pSioChan->getTxCharCallback = (FUNCPTR)callback;	    pSioChan->getTxCharArg = arg;	    return OK;                case USB_ACM_CALLBACK_SIO_RX    :        case SIO_CALLBACK_PUT_RCV_CHAR  :            /* Callback for returning rx Chars : Normal VxWorks SIO Model */ 	    USB_ACM_LOG (USB_ACM_DEBUG_ATTACH, "Rx callback installed \n",                0, 0, 0, 0, 0, 0);            pSioChan->callbackStatus |= USB_ACM_CALLBACK_SIO_RX;            pSioChan->putRxCharCallback = (FUNCPTR)callback;	    pSioChan->putRxCharArg = arg;	    return OK;        default :            return ossStatus (S_usbAcmLib_BAD_PARAM);        }    return OK;    }/**************************************************************************** usbAcmCallbackRemove - De-Registers a callback for an event.** This function removess a (previously installed) <callback> callback routine * for a <callbackType> event. ** Though this function provides a way to remove the callbacks even for the* transmit and receive functionality, it is adviced that these callbacks be* not removed. Note that the <pChan> paramter shall be NULL for the Dynamic * attachment notification requests, indicating that the event is not for any * particular device. Similary, <callback> can be NULL for all the other * events other than the dynamic attachment / removal events.** Different <callbackType> events suppoted by this driver are mentioned in * usbAcmCallbackRegister. Please refer to the corresponding entry.** RETURNS: OK, or ERROR if unable to remove a callback.** ERRNO : *  S_usbAcmLib_BAD_PARAM*  S_usbAcmLib_NOT_REGISTERED**/STATUS usbAcmCallbackRemove    (    SIO_CHAN * pChan,           /* Channel for de-registering callbacks */    UINT callbackType,          /* Event the call back is to be removed */    USB_ACM_CALLBACK callback	/* callback to be unregistered */    )    {        pUSB_ACM_SIO_CHAN pSioChan = (pUSB_ACM_SIO_CHAN)pChan;    pATTACH_REQUEST pRequest;    int status = OK;    /* Check for the validity of the input paramaters */        if ((callbackType != USB_ACM_CALLBACK_ATTACH) &&         (callbackType != USB_ACM_CALLBACK_DETACH))        {        /*          * Except for attachment/removal requests, pChan should never          * be Null          */        if (pSioChan == NULL)            return ossStatus (S_usbAcmLib_BAD_PARAM);                /* Check if there is a callback for this event. */                if ((pSioChan->callbackStatus & callbackType) == 0)            return ossStatus (S_usbAcmLib_NOT_REGISTERED);                /* De-Register the callback.*/        pSioChan->callbackStatus &= ~callbackType;        /* Thats all required , return now.*/        return OK;        }    if (callback == NULL)        return ossStatus (S_usbAcmLib_BAD_PARAM);    status = S_usbAcmLib_NOT_REGISTERED;    OSS_MUTEX_TAKE (acmMutex, OSS_BLOCK);    pRequest = usbListFirst (&reqList);    while (pRequest != NULL)        {	if (callback == pRequest->callback)            {	                /* We found a matching notification request. */            destroyAttachRequest (pRequest);	    status = OK;	    break;            }        	    pRequest = usbListNext (&pRequest->reqLink);        }    OSS_MUTEX_RELEASE (acmMutex);    return ossStatus (status);            }/***************************************************************************** usbAcmSioChanLock - Marks SIO_CHAN structure as in use** A caller uses usbAcmSioChanLock() to notify usbAcmLib that* it is using the indicated SIO_CHAN structure.	 usbAcmLib maintains* a count of users using a particular SIO_CHAN structure so that it * knows when it is safe to dispose of a structure when the underlying* USB Modem is removed from the system.  As long as the "lock count"* is greater than zero, usbAcmLib will not dispose of an SIO_CHAN* structure.** RETURNS: OK, or ERROR if unable to mark SIO_CHAN structure in use.*/STATUS usbAcmSioChanLock    (    SIO_CHAN *pChan		/* SIO_CHAN to be marked as in use */    )    {    pUSB_ACM_SIO_CHAN pSioChan = (pUSB_ACM_SIO_CHAN) pChan;        pSioChan->lockCount++;    return OK;    }/***************************************************************************** usbAcmSioChanUnlock - Marks SIO_CHAN structure as unused** This function releases a lock placed on an SIO_CHAN structure.  When a* caller no longer needs an SIO_CHAN structure for which it has previously* called usbAcmSioChanLock(), then it should call this function to* release the lock.** NOTE: If the underlying USB Modem device has already been removed* from the system, then this function will automatically dispose of the* SIO_CHAN structure if this call removes the last lock on the structure.* Therefore, a caller must not reference the SIO_CHAN again structure after* making this call.** RETURNS: OK, or ERROR if unable to mark SIO_CHAN structure unused** ERRNO:  S_usbAcmLib_NOT_LOCKED**/STATUS usbAcmSioChanUnlock    (    SIO_CHAN *pChan		/* SIO_CHAN to be marked as unused */    )    {    pUSB_ACM_SIO_CHAN pSioChan = (pUSB_ACM_SIO_CHAN) pChan;    int status = OK;    OSS_MUTEX_TAKE (acmMutex, OSS_BLOCK);    if (pSioChan->lockCount == 0)	status = S_usbAcmLib_NOT_LOCKED;    else	{	        /*          * If this is the last lock and the underlying USB modem is	 * no longer connected, then dispose of the acm struct.	 */	if (--pSioChan->lockCount == 0 && !pSioChan->connected)	    destroySioChan (pSioChan);	}    OSS_MUTEX_RELEASE (acmMutex);    return ossStatus (status);    }/***************************************************************************** initiateOutput - initiates SIO model data transmission to modem.** If the output IRP is not already in use, this function fills the output* buffer by invoking the "tx char callback".  If at least one character is* available for output, the function then initiates the output IRP.** RETURNS: OK, or ERROR if unable to initiate transmission** NOMANUAL*/STATUS initiateOutput    (    pUSB_ACM_SIO_CHAN pSioChan    )    {    pUSB_IRP pIrp = &pSioChan->outIrp;    UINT16 count;    /* Return immediately if the output IRP is already in use. */    if (pSioChan->outIrpInUse)	{	logMsg(" OutIrp in Use..\n",0,0,0,0,0,0);	return ERROR; 	}    /* If there is no tx callback, return an error */    if (pSioChan->getTxCharCallback == NULL)	{	logMsg("No TxCallback \n",0,0,0,0,0,0);	return ERROR;	}    /*      * Fill the output buffer until it is full or until the tx callback     * has no more data.  Return if there is no data available.     */    count = 0;    USB_ACM_LOG(USB_ACM_DEBUG_TX," Preparing data \n",0,0,0,0,0,0);    while (count < pSioChan->outBfrLen &&	(*pSioChan->getTxCharCallback) (pSioChan->getTxCharArg, 					&pSioChan->outBfr [count]) 				      == OK)	{	count++;	}    if (count == 0)	return OK;    /* Initialize IRP */    memset (pIrp, 0, sizeof (*pIrp));    pIrp->userPtr = pSioChan;    pIrp->irpLen = sizeof (*pIrp);    pIrp->userCallback = usbAcmTxIrpCallback;    pIrp->timeout = 2000;    pIrp->transferLen = count;    pIrp->bfrCount = 1;    pIrp->bfrList [0].pid = USB_PID_OUT;    pIrp->bfrList [0].pBfr = pSioChan->outBfr;    pIrp->bfrList [0].bfrLen = count;    USB_ACM_LOG(USB_ACM_DEBUG_TX," Irp framed %d bytes\n",count,0,0,0,0,0);    pSioChan->outIrpInUse = TRUE;   /* This is a MUST */     /* Submit IRP */    if (usbdTransfer (usbdHandle, pSioChan->outPipeHandle, pIrp) != OK)	return ERROR;    USB_ACM_LOG(USB_ACM_DEBUG_TX," Data.submitted for tx \n",0,0,0,0,0,0);    /* Wait for IRP to complete or cancel by timeout */    if ( OSS_SEM_TAKE (acmIrpSem, 2000 + 1000) == ERROR )        {        printf ("ACM:initiateOutput: Fatal Error \n");        }    USB_ACM_LOG(USB_ACM_DEBUG_TX," returning \n",0,0,0,0,0,0);    return OK;    }/***************************************************************************** listenForInput - Initialize IRP to listen for input from Modem** RETURNS: OK, or ERROR if unable to submit IRP to listen for input*/LOCAL STATUS listenForInput    (    pUSB_ACM_SIO_CHAN pSioChan    )    {    pUSB_IRP pIrp = &pSioChan->inIrp;    /* Initialize IRP */    memset (pIrp, 0, sizeof (*pIrp));    pIrp->userPtr = pSioChan;    pIrp->irpLen = sizeof (*pIrp);    pIrp->userCallback = usbAcmRxIrpCallback;    pIrp->timeout = USB_TIMEOUT_NONE;    pIrp->transferLen = pSioChan->inBfrLen;    pIrp->bfrCount = 1;    pIrp->bfrList [0].pid = USB_PID_IN;    pIrp->bfrList [0].pBfr = (pUINT8) &pSioChan->inBfr;    pIrp->bfrList [0].bfrLen = pSioChan->inBfrLen;    pSioChan->inIrpInUse = TRUE;    /* Submit IRP */    if (usbdTransfer (usbdHandle, pSioChan->inPipeHandle, pIrp) != OK)	return ERROR;    return OK;    }/***************************************************************************** usbAcmTxIrpCallback - Invoked upon IRP completion/cancellation** Examines the cause of the IRP completion and re-submits the IRP.** RETURNS: N/A*/LOCAL VOID usbAcmTxIrpCallback    (    pVOID p			/* completed IRP */    )    {    pUSB_IRP pIrp = (pUSB_IRP) p;    pUSB_ACM_SIO_CHAN pSioChan = pIrp->userPtr;    pSioChan->outIrpInUse = FALSE;    if (pIrp->result != OK)        pSioChan->outErrors++;    /*     * If a Block transmission occured, we just return. Otherwise     * we'll see if some more data is to be transmitted.     */    if (pSioChan->callbackStatus | USB_ACM_CALLBACK_BLK_TX)        {        pSioChan->callbackStatus &= ~USB_ACM_CALLBACK_BLK_TX;        }    OSS_SEM_GIVE (acmIrpSem);    }/***************************************************************************** usbAcmRxIrpCallback - Invoked upon IRP completion/cancellation** Examines the cause of the IRP completion and re-submits the IRP.** RETURNS: N/A*/LOCAL VOID usbAcmRxIrpCallback    (    pVOID p			/* completed IRP */    )    {    pUSB_IRP pIrp = (pUSB_IRP) p;    pUSB_ACM_SIO_CHAN pSioChan = pIrp->userPtr;    UINT16 count;    USB_ACM_LOG(USB_ACM_DEBUG_RX," RxCallBack \n",0,0,0,0,0,0);    /* Input IRP completed */    pSioChan->inIrpInUse = FALSE;    if (pIrp->result != OK)        pSioChan->inErrors++;    /*     * If the IRP was successful then pass the data back to the client.     */    if (pIrp->result == OK)        {                /*          * How to pass the data to clients? If a BlockRxCallback is installed,         * then that callback shall be used to send back the data. Otherwise         * it shall be the Vxworks SIO model callback          */            /* Its the normal VxWorks SIO model now */          	USB_ACM_LOG(USB_ACM_DEBUG_RX," Passing data up \n",0,0,0,0,0,0);                if (pSioChan->putRxCharCallback == NULL)	    {	    logMsg("ACM: Rx Callback Null!!!\n",0,0,0,0,0,0);            ossStatus (S_usbAcmLib_NOT_REGISTERED);            return;            }        for (count = 0; count < pIrp->bfrList [0].actLen; count++)	    {	    (*pSioChan->putRxCharCallback) (pSioChan->putRxCharArg,		pIrp->bfrList [0].pBfr [count]);	    }	}	/*          * Unless the IRP was cancelled - implying the channel is being	 * shutdown, re-initiate the "in" IRP to listen for more data from	 * the modem.	 */        USB_ACM_LOG(USB_ACM_DEBUG_RX," Passing data up ..done \n",0,0,0,0,0,0);	if (pIrp->result != S_usbHcdLib_IRP_CANCELED)	    listenForInput (pSioChan);	   } /***************************************************************************** usbAcmCtrlCmdSend - Sends a Control command to the Modem.** This function sends an AT command to the modem. The response to the command* will be passed to the client via a previously installed callback for the* Modem response.** RETURNS: OK or ERROR if the command could not be sent.**/LOCAL STATUS usbAcmCtrlCmdSend    (    pUSB_ACM_SIO_CHAN pSioChan, /* Modem reference */    UINT16 request,             /* Command to send */    UINT8 * pBuf,               /* Modem command buffer */    UINT16  count               /* no of bytes in command */    )

⌨️ 快捷键说明

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