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

📄 usbdcorelib.c

📁 VxWorks下USB驱动的源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** initHubIrp - initialize IRP used to listen for hub status** RETURNS: TRUE if successful, else FALSE*/LOCAL BOOL initHubIrp (pUSBD_NODE pNode){    pUSB_IRP pIrp = &pNode->hubIrp;    /* initialize IRP */    memset (pIrp, 0, sizeof (*pIrp));    pIrp->userPtr = pNode;    pIrp->irpLen = sizeof (USB_IRP);    pIrp->userCallback = hubIrpCallback;    pIrp->flags = USB_FLAG_SHORT_OK;    pIrp->timeout = USB_TIMEOUT_NONE;    pIrp->transferLen = HUB_STATUS_LEN (pNode);    pIrp->bfrCount = 1;    pIrp->bfrList[0].pid = USB_PID_IN;    pIrp->bfrList[0].pBfr = (pUINT8) pNode->pHubStatus;    pIrp->bfrList[0].bfrLen = pIrp->transferLen;    memset (pNode->pHubStatus, 0, MAX_HUB_STATUS_LEN);    /* submit the IRP. */    if (usbdTransfer (internalClient, pNode->hubStatusPipe, pIrp) != OK)        return FALSE;    return TRUE;}/***************************************************************************** initHubNode - initialize a hub** RETURNS: TRUE if successful, else FALSE*/LOCAL BOOL initHubNode (pUSBD_NODE pNode){    pUSB_CONFIG_DESCR pCfgDescr;    pUSB_INTERFACE_DESCR pIfDescr;    pUSB_ENDPOINT_DESCR pEpDescr;    pUSB_HUB_DESCR pHubDescrBuf;    UINT8 *pConfDescrBfr;    UINT16 actLen;    UINT16 port;    pConfDescrBfr = OSS_MALLOC (USB_MAX_DESCR_LEN);    pHubDescrBuf = OSS_MALLOC (sizeof (USB_HUB_DESCR));    /* Read the hub's descriptors. */    if (usbdDescriptorGet (internalClient,                           pNode->nodeHandle,                           USB_RT_STANDARD | USB_RT_DEVICE,                           USB_DESCR_CONFIGURATION, 0, 0, USB_MAX_DESCR_LEN, pConfDescrBfr, &actLen)        != OK) {        OSS_FREE (pConfDescrBfr);        OSS_FREE (pHubDescrBuf);        return FALSE;    }    if ((pCfgDescr = usbDescrParse (pConfDescrBfr, actLen, USB_DESCR_CONFIGURATION))        == NULL || (pIfDescr = usbDescrParse (pConfDescrBfr, actLen, USB_DESCR_INTERFACE))        == NULL || (pEpDescr = usbDescrParse (pConfDescrBfr, actLen, USB_DESCR_ENDPOINT))        == NULL) {        OSS_FREE (pConfDescrBfr);        OSS_FREE (pHubDescrBuf);        return FALSE;    }    if (usbdDescriptorGet (internalClient,                           pNode->nodeHandle,                           USB_RT_CLASS | USB_RT_DEVICE,                           USB_DESCR_HUB,                           0, 0, sizeof (USB_HUB_DESCR), (UINT8 *) pHubDescrBuf, &actLen)        != OK || actLen < USB_HUB_DESCR_LEN) {        OSS_FREE (pConfDescrBfr);        OSS_FREE (pHubDescrBuf);        return FALSE;    }    /* We now have all important descriptors for this hub.  Pick out     * important information and configure hub.     */    /* Record hub power capability */    pNode->pwrGoodDelay = pHubDescrBuf->pwrOn2PwrGood * 2;  /* 2 msec per unit */    pNode->hubContrCurrent = pHubDescrBuf->hubContrCurrent;    if ((pCfgDescr->attributes & USB_ATTR_SELF_POWERED) != 0) {        pNode->selfPowered = TRUE;        pNode->maxPowerPerPort = USB_POWER_SELF_POWERED;    } else {        pNode->selfPowered = FALSE;        pNode->maxPowerPerPort = USB_POWER_BUS_POWERED;    }    pNode->numPorts = pHubDescrBuf->nbrPorts;    /* If this hub is not already at the maximum USB topology depth, then     * create a pipe to monitor it's status and enable each of its ports.     */    if (pNode->topologyDepth < USB_MAX_TOPOLOGY_DEPTH) {        /* Set the hub's configuration. */        if (usbdConfigurationSet (internalClient,                                  pNode->nodeHandle,                                  pCfgDescr->configurationValue, pNode->hubContrCurrent)            != OK) {            OSS_FREE (pConfDescrBfr);            OSS_FREE (pHubDescrBuf);            return FALSE;        }        /* Create a pipe for interrupt transfers from this device. */        if (usbdPipeCreate (internalClient,                            pNode->nodeHandle,                            pEpDescr->endpointAddress,                            pCfgDescr->configurationValue,                            0,                            USB_XFRTYPE_INTERRUPT,                            USB_DIR_IN,                            FROM_LITTLEW (pEpDescr->maxPacketSize),                            HUB_STATUS_LEN (pNode), pEpDescr->interval, &pNode->hubStatusPipe)            != OK) {            OSS_FREE (pConfDescrBfr);            OSS_FREE (pHubDescrBuf);            return FALSE;        }        /* Allocate structures for downstream nodes. */        if ((pNode->pPorts = OSS_CALLOC (pNode->numPorts * sizeof (USBD_PORT)))            == NULL) {            OSS_FREE (pConfDescrBfr);            OSS_FREE (pHubDescrBuf);            return FALSE;        }        /* Initialize each hub port */        for (port = 0; port < pNode->numPorts; port++) {            /* Enable power to the port */            usbdFeatureSet (internalClient, pNode->nodeHandle,                            USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_PORT_POWER, port + 1);        }        OSS_THREAD_SLEEP (pNode->pwrGoodDelay); /* let power stabilize */        /* Initialize an IRP to listen for status changes on the hub */        if (!initHubIrp (pNode)) {            OSS_FREE (pConfDescrBfr);            OSS_FREE (pHubDescrBuf);            return FALSE;        }    }    OSS_FREE (pConfDescrBfr);    OSS_FREE (pHubDescrBuf);    return TRUE;}/***************************************************************************** createNode - Creates and initializes new USBD_NODE** If the node is a hub, then automatically initializes hub.** RETURNS: pointer to newly created USBD_NODE, or*	   NULL if not successful*/LOCAL pUSBD_NODE createNode (pUSBD_BUS pBus,    /* node's parent bus */                             USBD_NODE_ID rootId,   /* root id */                             USBD_NODE_ID parentHubId,  /* parent hub id */                             UINT16 parentHubPort,  /* parent hub port no */                             UINT16 nodeSpeed,  /* node speed */                             UINT16 topologyDepth   /* this node's depth in topology */    ){    pUSBD_NODE pNode;    pUSBD_PIPE pPipe;    UINT16 actLen;    /* Allocate/initialize USBD_NODE */    if ((pNode = OSS_CALLOC (sizeof (*pNode))) == NULL)        return NULL;    /*      * The hub status buffer gets touched by hardware.  Ensure that      * it does not span a cache line     */    if ((pNode->pHubStatus = OSS_CALLOC (MAX_HUB_STATUS_LEN)) == NULL) {        OSS_FREE (pNode);        return NULL;    }    if (usbHandleCreate (USBD_NODE_SIG, pNode, &pNode->nodeHandle) != OK ||        OSS_SEM_CREATE (1, 1, &pNode->controlSem) != OK) {        destroyNode (pNode);        return NULL;    }    pNode->pBus = pBus;    pNode->nodeInfo.nodeSpeed = nodeSpeed;    pNode->nodeInfo.parentHubId = parentHubId;    pNode->nodeInfo.parentHubPort = parentHubPort;    pNode->nodeInfo.rootId = (rootId == 0) ? pNode->nodeHandle : rootId;    pNode->topologyDepth = topologyDepth;    /* Create a pipe for control transfers to this device. */    if (usbdPipeCreate (internalClient, pNode->nodeHandle, USB_ENDPOINT_CONTROL,                        0, 0, USB_XFRTYPE_CONTROL, USB_DIR_INOUT, USB_MIN_CTRL_PACKET_SIZE, 0, 0,                        &pNode->controlPipe) != OK) {        destroyNode (pNode);        return NULL;    }    /* Read the device descriptor to get the maximum payload size and to     * determine if this is a hub or not.     *     * NOTE: We read only the first 8 bytes of the device descriptor (which     * takes us through the maxPacketSize field) as suggested by the USB     * spec.     */    if (usbdDescriptorGet (internalClient, pNode->nodeHandle,                           USB_RT_STANDARD | USB_RT_DEVICE, USB_DESCR_DEVICE, 0, 0,                           USB_MIN_CTRL_PACKET_SIZE, (pUINT8) & pNode->devDescr, &actLen) != OK ||        actLen < USB_MIN_CTRL_PACKET_SIZE) {        destroyNode (pNode);        return NULL;    }    /* Now that we've read the device descriptor, we know the actual     * packet size supported by the control pipe.  Update the pipe     * accordingly.     */    validatePipe (pNode->controlPipe, &pPipe);    pPipe->maxPacketSize = pNode->devDescr.maxPacketSize0;  /* field is byte wide */    /* Set a unique address for this device. */    if (!assignAddress (pNode)) {        destroyNode (pNode);        return NULL;    }    /* Notify the HCD of the change in device address and max packet size */    usbHcdPipeModify (&pBus->pHcd->nexus, pPipe->hcdHandle,                      pNode->busAddress, pPipe->maxPacketSize);    /* If this is a hub node, it requires additional initialization.  Otherwise,     * we're done unless and until a client performs additional I/O to this     * device.     */    if (pNode->devDescr.deviceClass == USB_CLASS_HUB) {        pNode->nodeInfo.nodeType = USB_NODETYPE_HUB;        if (!initHubNode (pNode)) {            destroyNode (pNode);            return NULL;        }    } else {        pNode->nodeInfo.nodeType = USB_NODETYPE_DEVICE;    }    /* Read the device class type(s) from the device and notify interested     * clients of the device's insertion.     */    interrogateDeviceClass (pNode, pNode->devDescr.deviceClass,                            pNode->devDescr.deviceSubClass, pNode->devDescr.deviceProtocol);    notifyClients (pNode, USBD_DYNA_ATTACH);    return pNode;}/***************************************************************************** checkHubStatus - checks hub status and updates hub as necessary** Note: We take a Node ID as our parameter (instead of, say, a pointer* to a USBD_NODE structure) so that we can validate the node upon entry.* There are cases where this routine may be called when the underlying* node has already disappeared.** RETURNS: N/A*/LOCAL VOID checkHubStatus (USBD_NODE_ID nodeId){    pUSBD_NODE pNode;    pUSB_IRP pIrp;    UINT16 port;    UINT8 portMask;    UINT8 statusIndex;    /* Is the node still valid? */    if (!validateNode (nodeId, &pNode))        return;    pIrp = &pNode->hubIrp;    /* Determine what status is available.     *     * The hubStatus vector contains one bit for the hub itself and      * then one bit for each port.     */    if (pIrp->result == OK) {        port = 0;        statusIndex = 0;        portMask = USB_HUB_ENDPOINT_STS_PORT0;        while (port < pNode->numPorts && statusIndex < pIrp->bfrList[0].actLen) {            if ((*(pNode->pHubStatus + statusIndex) & portMask) != 0) {                /* This port appears to have status to report */                updateHubPort (pNode, port);            }            port++;            portMask <<= 1;            if (portMask == 0) {                portMask = 0x01;    /* next byte starts with bit 0 */                statusIndex++;            }        }    }    /* resubmit the IRP */    if (pIrp->result != S_usbHcdLib_IRP_CANCELED)        initHubIrp (pNode);}/***************************************************************************** busThread - bus monitor thread** A separate busThread() thread is spawned for each bus currently* attached to the USBD.  This thread is responsible for monitoring and* responding to bus events, like the attachment and removal of devices.* Using a separate thread for each bus helps to ensure that one bus's * behavior won't affect the throughput of other buses.** By convention, the <param> is a pointer to the USBD_BUS structure* for the associated bus.  This thread waits on the bus queue* in the bus structure.  At the time this thread is first created,* the USBD_BUS structure is only guaranteed to have an initialized* queue...other fields may not yet be initialized.** RETURNS: N/A*/LOCAL VOID busThread (pVOID param   /* thread parameter */    ){    pUSBD_BUS pBus = (pUSBD_BUS) param;    USB_MESSAGE msg;    /* Execute messages from the busQueue until a BUS_FNC_TERMINATE       message is received. */    do {        if (usbQueueGet (pBus->busQueue, &msg, OSS_BLOCK) != OK)            break;        switch (msg.msg) {        case BUS_FNC_UPDATE_HUB:            OSS_MUTEX_TAKE (structMutex, OSS_BLOCK);            checkHubStatus ((USBD_NODE_ID) msg.lParam);            OSS_MUTEX_RELEASE (structMutex);            break;        }    }    while (msg.msg != BUS_FNC_TERMINATE);    /* Mark the callback routine as having terminated. */    OSS_SEM_GIVE (pBus->busExit);}/***************************************************************************** hcdMngmtCallback - invoked when HCD detects managment event** RETURNS: N/A*/LOCAL VOID hcdMngmtCallback (pVOID mngmtCallbackParam,  /* caller-defined param */                             HCD_CLIENT_HANDLE handle,  /* handle to host controller */                             UINT16 busNo,  /* bus number */                             UINT16 mngmtCode   /* management code */    ){    pUSBD_HCD pHcd = (pUSBD_HCD) mngmtCallbackParam;    pUSBD_BUS pBus;    pUSBD_CLIENT pClient;    /* In an unusual case, this routine could be invoked by the HCD     * before we have completely initialized our structures.  In that     * case, just ignore the event.     */

⌨️ 快捷键说明

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