📄 usbdcorelib.c
字号:
/* 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 ((s = validateUrb (pUrb, sizeof (*pUrb), &pClient)) != OK) return s; if (pUrb->attachCallback == NULL) return S_usbdLib_BAD_PARAM; /* Create a new dynamic notification request structure */ if ((pNotify = OSS_CALLOC (sizeof (*pNotify))) == NULL) return S_usbdLib_OUT_OF_MEMORY; pNotify->deviceClass = pUrb->deviceClass; pNotify->deviceSubClass = pUrb->deviceSubClass; pNotify->deviceProtocol = pUrb->deviceProtocol; pNotify->callback = pUrb->attachCallback; /* Link this to the list of notification requests for the client */ usbListLink (&pClient->notifyReqs, pNotify, &pNotify->reqLink, LINK_TAIL); /* At the time of the initial notification registration (now), it is * necessary to scan the list of devices already attached to the USB(s) * in order to see if any match the request. Devices attached/removed * later will be handled by the busThread. */ pHcd = usbListFirst (&hcdList); while (pHcd != NULL) { for (busNo = 0; busNo < pHcd->busCount; busNo++) scanClassTypes (pHcd->pBuses [busNo].pRoot, pClient, pNotify); pHcd = usbListNext (&pHcd->hcdLink); } return OK; }/***************************************************************************** fncDynaAttachUnreg - Unregister a client for dynamic attach notification** RETURNS: S_usbdLib_xxxx*/LOCAL int fncDynaAttachUnreg ( pURB_DYNA_ATTACH_REG_UNREG pUrb ) { pUSBD_CLIENT pClient; pUSBD_NOTIFY_REQ pNotify; int s; /* Validate parameters. */ if ((s = validateUrb (pUrb, sizeof (*pUrb), &pClient)) != OK) return s; /* Search the client's list of notification requests for one which * matches exactly the parameters in the URB. */ pNotify = usbListFirst (&pClient->notifyReqs); while (pNotify != NULL) { if (pNotify->deviceClass == pUrb->deviceClass && pNotify->deviceSubClass == pUrb->deviceSubClass && pNotify->deviceProtocol == pUrb->deviceProtocol && pNotify->callback == pUrb->attachCallback) { /* We found a matching notification request. Destroy it. */ destroyNotify (pNotify); return OK; } pNotify = usbListNext (&pNotify->reqLink); } /* If we get this far, no matching request was found. Declare an error */ return S_usbdLib_GENERAL_FAULT; }/***************************************************************************** controlIrpCallback - called when control pipe Irp completes** By convention, the USB_IRP.userPtr field is a pointer to the USBD_NODE* for this transfer.** RETURNS: N/A*/LOCAL VOID controlIrpCallback ( pVOID p /* completed IRP */ ) { pUSB_IRP pIrp = (pUSB_IRP) p; pUSBD_NODE pNode = pIrp->userPtr; pURB_HEADER pUrb = pNode->pUrb; /* Store the actual length transferred */ if (pNode->pActLen != NULL) *pNode->pActLen = pIrp->bfrList [1].actLen; /* Store the completion result in the URB */ setUrbResult (pUrb, (pIrp->result == OK) ? OK : S_usbdLib_IO_FAULT); /* We're done with the control pipe structures for this node. */ OSS_SEM_GIVE (pNode->controlSem); }/***************************************************************************** controlRequest - Formats and submits a control transfer request** This is an internal utility function which formats a USB Setup packet* and sends it to the control pipe of a node.** RETURNS: S_usbdLib_xxxx*/LOCAL int controlRequest ( pURB_HEADER pUrb, /* URB header */ USBD_NODE_ID nodeId, /* node id */ UINT8 requestType, /* bmRequestType */ UINT8 request, /* bRequest */ UINT16 value, /* wValue */ UINT16 index, /* wI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -