📄 usbdcorelib.c
字号:
if (pHcd->pBuses == NULL) return; pBus = &pHcd->pBuses[busNo]; if (pBus->busThread == NULL || pBus->busQueue == NULL || pBus->pRoot == NULL || pBus->pRoot->nodeHandle == NULL) return; /* Reflect the management event to interested clients */ OSS_MUTEX_TAKE (structMutex, OSS_BLOCK); pClient = usbListFirst (&clientList); while (pClient != NULL) { if (pClient->mngmtCallback != NULL) usbQueuePut (pClient->callbackQueue, CALLBACK_FNC_MNGMT_EVENT, mngmtCode, (UINT32) pBus->pRoot->nodeHandle, OSS_BLOCK); pClient = usbListNext (&pClient->clientLink); } OSS_MUTEX_RELEASE (structMutex);}/***************************************************************************** initHcdBus - Initialize USBD_BUS element of USBD_HCD structure** <pHcd> points to the USBD_HCD being initialized. <busNo> is the index* of the HCD bus to be initialized.** RETURNS: S_usbdLib_xxxx*/LOCAL int initHcdBus (pUSBD_HCD pHcd, /* USBD_HCD being initialized */ UINT16 busNo /* Bus number to initialize */ ){ pUSBD_BUS pBus = &pHcd->pBuses[busNo]; int s = OK; /* Allocate resources for this bus. */ pBus->pHcd = pHcd; pBus->busNo = busNo; if (OSS_SEM_CREATE (1, 0, &pBus->busExit) != OK || usbQueueCreate (BUS_Q_DEPTH, &pBus->busQueue) != OK || OSS_THREAD_CREATE (busThread, pBus, OSS_PRIORITY_HIGH, "tUsbdBus", &pBus->busThread) != OK || (pBus->pRoot = createNode (pBus, 0, 0, 0, USB_SPEED_FULL, 0)) == NULL) { /* NOTE: If we fail here, destroyHcd() will clean up partially * allocate structures/resources/etc. */ return S_usbdLib_OUT_OF_RESOURCES; } return s;}/***************************************************************************** destroyHcd - tears down a USBD_HCD structure** Detaches the indicated HCD and tears down the HCD structures.** RETURNS: N/A*/LOCAL VOID destroyHcd (pUSBD_HCD pHcd){ pUSBD_BUS pBus; UINT16 busNo; /* Unlink the HCD */ usbListUnlink (&pHcd->hcdLink); /* Begin by de-allocating resources related to each bus */ for (busNo = 0; pHcd->pBuses != NULL && busNo < pHcd->busCount; busNo++) { pBus = &pHcd->pBuses[busNo]; /* Destroy all nodes associated with this bus */ destroyAllNodes (pBus->pRoot); /* NOTE: The busQueue is always allocated before the busThread. */ if (pBus->busThread != NULL) { /* Issue a terminate request to the bus thread */ usbQueuePut (pBus->busQueue, BUS_FNC_TERMINATE, 0, 0, BUS_TIMEOUT); OSS_SEM_TAKE (pBus->busExit, BUS_TIMEOUT); OSS_THREAD_DESTROY (pBus->busThread); } if (pBus->busQueue != NULL) usbQueueDestroy (pBus->busQueue); if (pBus->busExit != NULL) OSS_SEM_DESTROY (pBus->busQueue); } /* Detach the HCD */ if (pHcd->nexus.hcdExecFunc != NULL && pHcd->nexus.handle != NULL) usbHcdDetach (&pHcd->nexus); /* Release USBD_HCD resources */ if (pHcd->attachToken != NULL) usbHandleDestroy (pHcd->attachToken); OSS_FREE (pHcd);}/***************************************************************************** fncHcdAttach - Attach an HCD to the USBD** RETURNS: S_usbdLib_xxxx*/LOCAL int fncHcdAttach (pURB_HCD_ATTACH pUrb){ pUSBD_HCD pHcd = NULL; UINT16 busNo; int s; /* validate URB */ if ((s = validateUrb (pUrb, sizeof (*pUrb), NULL)) != OK) return s; /* Allocate structure for this host controller */ if ((pHcd = OSS_CALLOC (sizeof (*pHcd))) == NULL) return S_usbdLib_OUT_OF_MEMORY; /* Issue an attach request to the HCD. If it succeeds, determine the * number of buses managed by the HCD. */ if (usbHcdAttach (pUrb->hcdExecFunc, pUrb->param, hcdMngmtCallback, pHcd, &pHcd->nexus, &pHcd->busCount) != OK) { OSS_FREE (pHcd); return S_usbdLib_GENERAL_FAULT; } if ((pHcd->pBuses = OSS_CALLOC (sizeof (USBD_BUS) * pHcd->busCount)) == NULL) { destroyHcd (pHcd); return S_usbdLib_OUT_OF_MEMORY; } /* Initialize the USBD_HCD */ if (usbHandleCreate (USBD_HCD_SIG, pHcd, &pHcd->attachToken) != OK) { s = S_usbdLib_OUT_OF_RESOURCES; } else { /* Fetch information about each bus from the HCD. */ for (busNo = 0; busNo < pHcd->busCount; busNo++) { if ((s = initHcdBus (pHcd, busNo)) != OK) break; } } /* If we succeeded in initializing each bus, then the USBD_HCD * is fully initialized...link it into the list of HCDs */ if (s == OK) { usbListLink (&hcdList, pHcd, &pHcd->hcdLink, LINK_TAIL); /* Return attachToken to caller */ pUrb->attachToken = pHcd->attachToken; } else { /* Failed to attach...release allocated structs, etc. */ destroyHcd (pHcd); } return s;}/***************************************************************************** fncHcdDetach - Detach an HCD from the USBD** RETURNS: S_usbdLib_xxxx*/LOCAL int fncHcdDetach (pURB_HCD_DETACH pUrb){ pUSBD_HCD pHcd; int s; /* Validate URB */ if ((s = validateUrb (pUrb, sizeof (*pUrb), NULL)) != OK) return s; /* Validate attachToken */ if (usbHandleValidate (pUrb->attachToken, USBD_HCD_SIG, (pVOID *) & pHcd) != OK) return S_usbdLib_BAD_HANDLE; /* Detach the HCD and release HCD structures, etc. */ destroyHcd (pHcd); return s;}/***************************************************************************** fncStatisticsGet - Return USBD operating statistics** RETURNS: S_usbdLib_xxxx*/LOCAL int fncStatisticsGet (pURB_STATISTICS_GET pUrb){ pUSBD_NODE pNode; /* Validate root */ if (!validateNode (pUrb->nodeId, &pNode)) return S_usbdLib_BAD_HANDLE; /* Validate other parameters */ if (pUrb->pStatistics == NULL) return S_usbdLib_BAD_PARAM; /* Copy statistics to callers buffer */ memcpy (pUrb->pStatistics, &pNode->pBus->stats, min (pUrb->statLen, sizeof (pNode->pBus->stats))); return OK;}/***************************************************************************** fncBusCountGet - Returns number of USB buses in system** RETURNS: S_usbdLib_xxxx*/LOCAL int fncBusCountGet (pURB_BUS_COUNT_GET pUrb){ pUSBD_HCD pHcd; UINT16 busCount; busCount = 0; pHcd = usbListFirst (&hcdList); while (pHcd != NULL) { busCount += pHcd->busCount; pHcd = usbListNext (&pHcd->hcdLink); } pUrb->busCount = busCount; return OK;}/***************************************************************************** fncRootIdGet - Returns root node id for a USB** RETURNS: S_usbdLib_xxxx*/LOCAL int fncRootIdGet (pURB_ROOT_ID_GET pUrb){ pUSBD_HCD pHcd; UINT16 i; int s = OK; /* Find the HCD/bus corresponding to the index pUrb->busCount */ i = pUrb->busIndex; pHcd = usbListFirst (&hcdList); while (pHcd != NULL) { if (i < pHcd->busCount) { if (pHcd->pBuses[i].pRoot != NULL) pUrb->rootId = pHcd->pBuses[i].pRoot->nodeHandle; else s = S_usbdLib_INTERNAL_FAULT; break; } else { i -= pHcd->busCount; pHcd = usbListNext (&pHcd->hcdLink); } } if (pHcd == NULL) s = S_usbdLib_BAD_PARAM; return s;}/***************************************************************************** fncHubPortCountGet - Returns number of hubs on a port** RETURNS: S_usbdLib_xxxx*/LOCAL int fncHubPortCountGet (pURB_HUB_PORT_COUNT_GET pUrb){ pUSBD_NODE pNode; /* validate node handle */ if (!validateNode (pUrb->hubId, &pNode)) return S_usbdLib_BAD_HANDLE; if (pNode->nodeInfo.nodeType != USB_NODETYPE_HUB) return S_usbdLib_NOT_HUB; /* return number of ports on this hub */ pUrb->portCount = pNode->numPorts; return OK;}/***************************************************************************** fncNodeIdGet - Returns id of node attached to a hub port** RETURNS: S_usbdLib_xxxx*/LOCAL int fncNodeIdGet (pURB_NODE_ID_GET pUrb){ pUSBD_NODE pNode; /* validate node handle */ if (!validateNode (pUrb->hubId, &pNode)) return S_usbdLib_BAD_HANDLE; if (pNode->nodeInfo.nodeType != USB_NODETYPE_HUB) return S_usbdLib_NOT_HUB; /* If the port index is valid, return the node id, if any, attached * to this port. */ if (pUrb->portIndex >= pNode->numPorts) return S_usbdLib_BAD_PARAM; pUrb->nodeType = USB_NODETYPE_NONE; if (pNode->pPorts != NULL && pNode->pPorts[pUrb->portIndex].pNode != NULL) { pUrb->nodeType = pNode->pPorts[pUrb->portIndex].pNode->nodeInfo.nodeType; pUrb->nodeId = pNode->pPorts[pUrb->portIndex].pNode->nodeHandle; } return OK;}/***************************************************************************** scanClassTypes - Scans nodes for matching class types** Scan <pNode> and all child nodes to see if they have exposed one or more* class types matching that described in <pNotify>. If we find match(es),* then invoke the corresponding notification callbacks.** RETURNS: N/A*/LOCAL VOID scanClassTypes (pUSBD_NODE pNode, pUSBD_CLIENT pClient, pUSBD_NOTIFY_REQ pNotify){ pUSBD_NODE_CLASS pClassType; UINT16 portNo; if (pNode != NULL) { /* Scan all class types exposed for this node. */ pClassType = usbListFirst (&pNode->classTypes); while (pClassType != NULL) { notifyIfMatch (pNode, pClassType, pClient, pNotify, USBD_DYNA_ATTACH); pClassType = usbListNext (&pClassType->classLink); } /* If this node is a hub, then recursively scan child nodes. */ if (pNode->nodeInfo.nodeType == USB_NODETYPE_HUB && pNode->pPorts != NULL) { for (portNo = 0; portNo < pNode->numPorts; portNo++) scanClassTypes (pNode->pPorts[portNo].pNode, pClient, pNotify); } }}/***************************************************************************** fncDynaAttachReg - Register a client for dynamic attach notification** RETURNS: S_usbdLib_xxxx*/LOCAL int fncDynaAttachReg (pURB_DYNA_ATTACH_REG_UNREG pUrb){ pUSBD_CLIENT pClient; pUSBD_NOTIFY_REQ pNotify; pUSBD_HCD pHcd; UINT16 busNo; int s; /* Validate parameters. */ if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -