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

📄 usbdcorelib.c

📁 VxWorks下USB驱动的源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
    pNOTIFICATION pNotification;    /* Execute messages from the callbackQueue until a CLIENT_FNC_TERMINATE       message is received. */    do {        if (usbQueueGet (pClient->callbackQueue, &msg, OSS_BLOCK) != OK)            break;        switch (msg.msg) {        case CALLBACK_FNC_IRP_COMPLETE:            /* invoke a client's IRP callback routine.  The msg.lParam             * is a pointer to the completed USB_IRP.             */            pIrp = (pUSB_IRP) msg.lParam;            if (pIrp->userCallback != NULL)                (*pIrp->userCallback) (pIrp);            break;        case CALLBACK_FNC_NOTIFY_ATTACH:            /* invoke a client's dynamic attach routine.  The msg.lParam             * is a pointer to a NOTIFICATION structure.               *             * NOTE: We dispose of the NOTIFICATION request after             * consuming it.             */            pNotification = (pNOTIFICATION) msg.lParam;            (*pNotification->callback) (pNotification->nodeId,                                        pNotification->attachCode, pNotification->configuration,                                        pNotification->interface, pNotification->deviceClass,                                        pNotification->deviceSubClass,                                        pNotification->deviceProtocol);            OSS_FREE (pNotification);            break;        case CALLBACK_FNC_MNGMT_EVENT:            /* invoke a client's managment callback routine.  The              * msg.wParam is the management code and the msg.lParam is             * the USBD_NODE_ID of the root for the affected bus.             */            if (pClient->mngmtCallback != NULL)                (*pClient->mngmtCallback) (pClient->mngmtCallbackParam,                                           (USBD_NODE_ID) msg.lParam, msg.wParam);            break;        }    }    while (msg.msg != CALLBACK_FNC_TERMINATE);    /* Mark the callback routine as having terminated. */    OSS_SEM_GIVE (pClient->callbackExit);}/***************************************************************************** doTransferAbort - Cancel an outstanding IRP** Directs the HCD to cancel the IRP and waits for the IRP callback to* be invoked signalling that the IRP has been unlinked successfully.** RETURNS: S_usbdLib_xxxx*/LOCAL int doTransferAbort (pUSBD_PIPE pPipe,    /* Pipe owning transfer */                           pUSB_IRP pIrp    /* IRP to be cancelled */    ){    /* The callback which indicates that an IRP has been deleted is     * asynchronous.  However, when deleting an IRP (such as when     * destroying a pipe) we generally need to know when the IRP     * callback has actually been invoked - and hence the IRP unlinked     * from the list of outstanding IRPs on the pipe.     */    pPipe->irpBeingDeleted = pIrp;    pPipe->irpDeleted = FALSE;    /* Instruct the HCD to cancel the IRP */    if (usbHcdIrpCancel (&pPipe->pNode->pBus->pHcd->nexus, pIrp) != OK)        return S_usbdLib_CANNOT_CANCEL;    /* Wait for the IRP callback to be invoked. */    while (!pPipe->irpDeleted)        OSS_THREAD_SLEEP (1);    return OK;}/***************************************************************************** destroyNotify - de-allocates a USBD_NOTIFY_REQ** RETURNS: N/A*/LOCAL VOID destroyNotify (pUSBD_NOTIFY_REQ pNotify){    usbListUnlink (&pNotify->reqLink);    OSS_FREE (pNotify);}/***************************************************************************** destroyPipe - de-allocates a USBD_PIPE and its resources** RETURNS: N/A*/LOCAL VOID destroyPipe (pUSBD_PIPE pPipe){    pUSB_IRP pIrp;    pUSBD_BUS pBus;    if (pPipe != NULL) {        pPipe->pipeDeletePending = TRUE;        /* Cancel all IRPs outstanding on this pipe.         *         * NOTE: Since the IRP completion callbacks are on a different thread,         * we need to wait until all callbacks have been completed.  This         * functionality is built into doTransferAbort().         */        while ((pIrp = usbListFirst (&pPipe->irps)) != NULL)            doTransferAbort (pPipe, pIrp);        /* Release bandwidth and notify HCD that the pipe is going away. */        pBus = pPipe->pNode->pBus;        pBus->nanoseconds -= pPipe->nanoseconds;        usbHcdPipeDestroy (&pBus->pHcd->nexus, pPipe->hcdHandle);        /* Unlink pipe from owning client's list of pipes */        if (pPipe->pClient != NULL)            usbListUnlink (&pPipe->clientPipeLink);        /* Unlink pipe from owning node's list of pipes */        if (pPipe->pNode != NULL)            usbListUnlink (&pPipe->nodePipeLink);        /* Release pipe handle */        if (pPipe->handle != NULL)            usbHandleDestroy (pPipe->handle);        OSS_FREE (pPipe);    }}/***************************************************************************** destroyClient - tears down a USBD_CLIENT structure** RETURNS: N/A*/LOCAL VOID destroyClient (pUSBD_CLIENT pClient){    pUSBD_NOTIFY_REQ pNotify;    pUSBD_PIPE pPipe;    pUSBD_HCD pHcd;    UINT16 busNo;    /* unlink client from list of clients.     *     * NOTE: usbListUnlink is smart and only unlinks the structure if it is     * actually linked.     */    usbListUnlink (&pClient->clientLink);    /* destroy all notification requests outstanding for the client */    while ((pNotify = usbListFirst (&pClient->notifyReqs)) != NULL)        destroyNotify (pNotify);    /* destroy all pipes owned by this client */    while ((pPipe = usbListFirst (&pClient->pipes)) != NULL)        destroyPipe (pPipe);    /* If this client is the current SOF master for any USBs, then release     * the SOF master status.     */    pHcd = usbListFirst (&hcdList);    while (pHcd != NULL) {        for (busNo = 0; busNo < pHcd->busCount; busNo++)            if (pHcd->pBuses[busNo].pSofMasterClient == pClient)                pHcd->pBuses[busNo].pSofMasterClient = NULL;        pHcd = usbListNext (&pHcd->hcdLink);    }    /* Note: callbackQueue is always created after callbackExit and     * before callbackThread     */    if (pClient->callbackThread != NULL) {        /* Terminate the client callback thread */        usbQueuePut (pClient->callbackQueue, CALLBACK_FNC_TERMINATE, 0, 0, CALLBACK_TIMEOUT);        OSS_SEM_TAKE (pClient->callbackExit, CALLBACK_TIMEOUT);        OSS_THREAD_DESTROY (pClient->callbackThread);    }    if (pClient->callbackQueue != NULL)        usbQueueDestroy (pClient->callbackQueue);    if (pClient->callbackExit != NULL)        OSS_SEM_DESTROY (pClient->callbackExit);    if (pClient->handle != NULL)        usbHandleDestroy (pClient->handle);    OSS_FREE (pClient);}/***************************************************************************** fncClientReg - Register a new USBD client** RETURNS: S_usbdLib_xxxx*/LOCAL int fncClientReg (pURB_CLIENT_REG pUrb){    pUSBD_CLIENT pClient;    int s;    /* validate URB */    if ((s = validateUrb (pUrb, sizeof (*pUrb), NULL)) != OK)        return s;    /* Create structures/resources/etc., required by new client */    if ((pClient = OSS_CALLOC (sizeof (*pClient))) == NULL)        return S_usbdLib_OUT_OF_MEMORY;    memcpy (pClient->clientName, pUrb->clientName, USBD_NAME_LEN);    if (usbHandleCreate (USBD_CLIENT_SIG, pClient, &pClient->handle) != OK ||        OSS_SEM_CREATE (1, 0, &pClient->callbackExit) != OK ||        usbQueueCreate (CALLBACK_Q_DEPTH, &pClient->callbackQueue) != OK ||        OSS_THREAD_CREATE (clientThread, pClient, OSS_PRIORITY_INHERIT,                           "tUsbdClnt", &pClient->callbackThread) != OK)        s = S_usbdLib_OUT_OF_RESOURCES;    else {        /* The client was initialized successfully. Add it to the list */        usbListLink (&clientList, pClient, &pClient->clientLink, LINK_TAIL);        /* return the client's USBD_CLIENT_HANDLE */        pUrb->header.handle = pClient->handle;    }    if (s != OK) {        destroyClient (pClient);    }    return s;}/***************************************************************************** fncClientUnreg - Unregister a USBD client** RETURNS: S_usbdLib_xxxx*/LOCAL int fncClientUnreg (pURB_CLIENT_UNREG pUrb){    pUSBD_CLIENT pClient;    int s;    /* validate Urb */    if ((s = validateUrb (pUrb, sizeof (*pUrb), &pClient)) != OK)        return s;    /* destroy client */    destroyClient (pClient);    return s;}/***************************************************************************** fncMngmtCallbackSet - sets management callback for a client** RETURNS: S_usbdLib_xxxx*/LOCAL int fncMngmtCallbackSet (pURB_MNGMT_CALLBACK_SET pUrb){    pUSBD_CLIENT pClient;    int s;    /* validate URB */    if ((s = validateUrb (pUrb, sizeof (*pUrb), &pClient)) != OK)        return s;    /* Set the management callback */    pClient->mngmtCallback = pUrb->mngmtCallback;    pClient->mngmtCallbackParam = pUrb->mngmtCallbackParam;    return s;}/***************************************************************************** fncVersionGet - Return USBD version** RETURNS: S_usbdLib_xxxx*/LOCAL int fncVersionGet (pURB_VERSION_GET pUrb){    int s;    /* validate urb */    if ((s = validateUrb (pUrb, sizeof (*pUrb), NULL)) != OK)        return s;    /* return version information */    pUrb->version = USBD_VERSION;    strncpy ((char *) pUrb->mfg, USBD_MFG, USBD_NAME_LEN);    return s;}/***************************************************************************** releaseAddress - release a USB device address** RETURNS: N/A*/LOCAL VOID releaseAddress (pUSBD_NODE pNode){    pUSBD_BUS pBus = pNode->pBus;    pBus->adrsVec[pNode->busAddress / 8] &= ~(0x1 << (pNode->busAddress % 8));}/***************************************************************************** assignAddress - assigns a unique USB address to a node** RETURNS: TRUE if successful, else FALSE*/LOCAL BOOL assignAddress (pUSBD_NODE pNode){    pUSBD_BUS pBus = pNode->pBus;    UINT16 i;    /* Find an available address */    for (i = 1; i < USB_MAX_DEVICES; i++) {        if ((pBus->adrsVec[i / 8] & (0x1 << (i % 8))) == 0) {            /* i is the value of an unused address.  Set the device adrs. */            if (usbdAddressSet (internalClient, pNode->nodeHandle, i) == OK) {                pNode->busAddress = i;                pBus->adrsVec[i / 8] |= 0x1 << (i % 8);                return TRUE;            } else {                return FALSE;            }        }    }    return FALSE;}/***************************************************************************** notifyIfMatch - Invoke attach callback if appropriate.** Compares the device class/subclass/protocol for <pClassType> and <pNotify>.* If the two match, then invokes the callback in <pNotify> with an attach* code of <attachCode>.** RETURNS: N/A*/LOCAL VOID notifyIfMatch    (pUSBD_NODE pNode,     pUSBD_NODE_CLASS pClassType, pUSBD_CLIENT pClient, pUSBD_NOTIFY_REQ pNotify, UINT16 attachCode){    pNOTIFICATION pNotification;    /* Do the pClassType and pNotify structures contain matching class     * descriptions?     */    if (pNotify->deviceClass == USBD_NOTIFY_ALL || pClassType->deviceClass == pNotify->deviceClass) {        if (pNotify->deviceSubClass == USBD_NOTIFY_ALL ||            pClassType->deviceSubClass == pNotify->deviceSubClass) {            if (pNotify->deviceProtocol == USBD_NOTIFY_ALL ||                pClassType->deviceProtocol == pNotify->deviceProtocol) {                /* We have a match.  Schedule the client attach callback. 

⌨️ 快捷键说明

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