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

📄 usbdcorelib.c

📁 MPC5200 BSP 支持ATA,USB, I2C,扩展网口
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* 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,		    /* wIndex */    UINT16 length,		    /* wLength */    pVOID pBfr, 		    /* data */    pUINT16 pActLen		    /* actual len for IN data */    )    {    pUSBD_CLIENT pClient;    pUSBD_NODE pNode;    pUSB_SETUP pSetup;    pUSB_IRP pIrp;    /* validate the client handle for this request */    if (!validateClient (pUrb->handle, &pClient))	return S_usbdLib_BAD_HANDLE;    /* validate the node to which this request is directed */    if (!validateNode (nodeId, &pNode))	return S_usbdLib_BAD_HANDLE;    /* Only one control request can be outstanding at a time. */    if (OSS_SEM_TAKE (pNode->controlSem, EXCLUSION_TIMEOUT) != OK)	return S_usbdLib_TIMEOUT;    /* we now own the control mutex for this node.  format and issue the     * control request to this node.     */    pSetup = &pNode->setup;    pIrp = &pNode->irp;        /* format the setup packet */    pSetup->requestType = requestType;    pSetup->request = request;    pSetup->value = TO_LITTLEW (value);    pSetup->index = TO_LITTLEW (index);    pSetup->length = TO_LITTLEW (length);    /* format an IRP to execute this control transfer */    memset (pIrp, 0, sizeof (USB_IRP) + sizeof (USB_BFR_LIST));    pIrp->userPtr = pNode;    pIrp->irpLen = sizeof (USB_IRP) + sizeof (USB_BFR_LIST);    pIrp->userCallback = controlIrpCallback;    pIrp->flags = USB_FLAG_SHORT_OK;    pIrp->timeout = USB_TIMEOUT_DEFAULT;    pIrp->transferLen = sizeof (USB_SETUP) + length;    /* format bfrList [] entry for Setup packet */    pIrp->bfrCount = 0;    pIrp->bfrList [pIrp->bfrCount].pid = USB_PID_SETUP;    pIrp->bfrList [pIrp->bfrCount].pBfr = (pUINT8) pSetup;    pIrp->bfrList [pIrp->bfrCount].bfrLen = sizeof (USB_SETUP);    pIrp->bfrCount++;	    /* format bfrList [] entry for data stage, if any. */    if (length > 0)	{	pIrp->bfrList [pIrp->bfrCount].pid = 	    ((requestType & USB_RT_DEV_TO_HOST) != 0) ? USB_PID_IN : USB_PID_OUT;	pIrp->bfrList [pIrp->bfrCount].pBfr = pBfr;	pIrp->bfrList [pIrp->bfrCount].bfrLen = length;	pIrp->bfrCount++;	}    /* All control transfers are followed by a "status" packet for which     * the direction is the opposite of that for the data stage and the     * length of the transfer is 0. */    pIrp->bfrList [pIrp->bfrCount].pid = 	((requestType & USB_RT_DEV_TO_HOST) != 0) ? USB_PID_OUT : USB_PID_IN;    pIrp->bfrList [pIrp->bfrCount].pBfr = NULL;    pIrp->bfrList [pIrp->bfrCount].bfrLen = 0;    pIrp->bfrCount++;    /* Store info about pending control IRP in node struct */    pNode->pClient = pClient;    pNode->pUrb = pUrb;    pNode->pActLen = pActLen;    /* submit the control transfer IRP.     *     * NOTE: If usbHcdIrpSubmit fails, it will still invoke the IRP callback     * which will in turn release the controlSem taken above.  The     * callback will also set the URB completion status.     */    if (usbdTransfer (internalClient, pNode->controlPipe, pIrp) != OK)	return S_usbdLib_GENERAL_FAULT;    return PENDING;    }/***************************************************************************** resetDataToggle - reset data toggle on affected pipes** This function is called when a "configuration event" is detected* for a given node.  This function searches all pipes associated with* the node for any that might be affected by the configuration event* and resets their data toggles to DATA0.** RETURNS: N/A*/LOCAL VOID resetDataToggle    (    USBD_NODE_ID nodeId,    UINT16 configuration,    UINT16 interface,    UINT16 endpoint    )    {    pUSBD_NODE pNode;    pUSBD_PIPE pPipe;    if (!validateNode (nodeId, &pNode))	return;    pPipe = usbListFirst (&pNode->pipes);    while (pPipe != NULL)	{	if (configuration == ANY_CONFIGURATION ||	    configuration == pPipe->configuration)	    {	    if (interface == ANY_INTERFACE ||		interface == pPipe->interface)		{		if (endpoint == ANY_ENDPOINT ||		    endpoint == pPipe->endpoint)		    {		    pPipe->dataToggle = USB_DATA0;		    }		}	    }	pPipe = usbListNext (&pPipe->nodePipeLink);	}    }/***************************************************************************** fncFeatureClear - Clear a USB feature** RETURNS: S_usbdLib_xxxx*/LOCAL int fncFeatureClear    (    pURB_FEATURE_CLEAR_SET pUrb    )    {    /* Check if this constitutes a configuration event.  So, reset the      * data toggle for any affected pipes.     */    if (pUrb->requestType == (USB_RT_STANDARD | USB_RT_ENDPOINT) &&	pUrb->feature == USB_FSEL_DEV_ENDPOINT_HALT)	{	resetDataToggle (pUrb->nodeId, ANY_CONFIGURATION, ANY_INTERFACE, 	    pUrb->index);	}    return controlRequest (&pUrb->header, pUrb->nodeId, 	USB_RT_HOST_TO_DEV | pUrb->requestType, USB_REQ_CLEAR_FEATURE, 	pUrb->feature, pUrb->index, 0, NULL, NULL);    }/***************************************************************************** fncFeatureSet - Set a USB feature** RETURNS: S_usbdLib_xxxx*/LOCAL int fncFeatureSet    (    pURB_FEATURE_CLEAR_SET pUrb    )    {    return controlRequest (&pUrb->header, pUrb->nodeId, 	USB_RT_HOST_TO_DEV | pUrb->requestType, USB_REQ_SET_FEATURE, 	pUrb->feature, pUrb->index, 0, NULL, NULL);    }/***************************************************************************** fncConfigGet - Get a device's configuration** RETURNS: S_usbdLib_xxxx*/LOCAL int fncConfigGet    (    pURB_CONFIG_GET_SET pUrb    )    {    pUrb->configuration = 0;    return controlRequest (&pUrb->header, pUrb->nodeId, 	USB_RT_DEV_TO_HOST | USB_RT_STANDARD | USB_RT_DEVICE,	USB_REQ_GET_CONFIGURATION, 0, 0, 1, &pUrb->configuration, NULL);    }/***************************************************************************** fncConfigSet - Set a device's configuration** RETURNS: S_usbdLib_xxxx*/LOCAL int fncConfigSet    (    pURB_CONFIG_GET_SET pUrb    )    {    pUSBD_NODE pNode;    pUSBD_NODE pParentNode;    /* Validate parameters */    if (!validateNode (pUrb->nodeId, &pNode))	return S_usbdLib_BAD_HANDLE;    /* Verify that the port to which this device is connected is capable of     * providing the current needed by this device.     */    if (pNode != pNode->pBus->pRoot && pNode->pBus->pRoot != NULL)	{	/* Retrieve the pointer to the parent hub for this node */	validateNode (pNode->nodeInfo.parentHubId, &pParentNode);	/* Check the power required against the parent's capability */	if (pUrb->maxPower > pParentNode->maxPowerPerPort)	    return S_usbdLib_POWER_FAULT;	}    /* This constitutes a configuration event.	So, reset the data toggle     * for any affected pipes.     */    resetDataToggle (pUrb->nodeId, pUrb->configuration, ANY_INTERFACE, 	ANY_ENDPOINT);    /* Set the device's configuration */    return controlRequest (&pUrb->header, pUrb->nodeId, 	USB_RT_HOST_TO_DEV | USB_RT_STANDARD | USB_RT_DEVICE,	USB_REQ_SET_CONFIGURATION, pUrb->configuration, 0, 0, NULL, NULL);    }/***************************************************************************** fncDescriptorGet - Retrieve a USB descriptor** RETURNS: S_usbdLib_xxxx*/LOCAL int fncDescriptorGet    (    pURB_DESCRIPTOR_GET_SET pUrb    )    {    return controlRequest (&pUrb->header, pUrb->nodeId,	USB_RT_DEV_TO_HOST | pUrb->requestType, USB_REQ_GET_DESCRIPTOR,	pUrb->descriptorType << 8 | pUrb->descriptorIndex,	pUrb->languageId, pUrb->bfrLen, pUrb->pBfr, &pUrb->actLen);    }/***************************************************************************** fncDescriptorSet - Sets a USB descriptor** RETURNS: S_usbdLib_xxxx*/LOCAL int fncDescriptorSet    (    pURB_DESCRIPTOR_GET_SET pUrb    )    {    return controlRequest (&pUrb->header, pUrb->nodeId,	USB_RT_HOST_TO_DEV | pUrb->requestType, USB_REQ_SET_DESCRIPTOR,	pUrb->descriptorType << 8 | pUrb->descriptorIndex,	pUrb->languageId, pUrb->bfrLen, pUrb->pBfr, NULL);    }/***************************************************************************** fncInterfaceGet - Returns a device's interface setting** RETURNS: S_usbdLib_xxxx*/LOCAL int fncInterfaceGet    (    pURB_INTERFACE_GET_SET pUrb    )    {    pUrb->alternateSetting = 0;    return controlRequest (&pUrb->header, pUrb->nodeId,	USB_RT_DEV_TO_HOST | USB_RT_STANDARD | USB_RT_INTERFACE,	USB_REQ_GET_INTERFACE, 0, pUrb->interfaceIndex, 1, 	&pUrb->alternateSetting, NULL);    }/***************************************************************************** fncInterfaceSet - Sets a device's interface setting** RETURNS: S_usbdLib_xxxx*/LOCAL int fncInterfaceSet    (    pURB_INTERFACE_GET_SET pUrb    )    {    /* This constitutes a configuration event.	So, reset the data toggle     * for any affected pipes.     */    resetDataToggle (pUrb->nodeId, ANY_CONFIGURATION, pUrb->interfaceIndex,	ANY_ENDPOINT);    return controlRequest (&pUrb->header, pUrb->nodeId,	USB_RT_HOST_TO_DEV | USB_RT_STANDARD | USB_RT_INTERFACE,	USB_REQ_SET_INTERFACE, pUrb->alternateSetting, pUrb->interfaceIndex,	0, NULL, NULL);    }/***************************************************************************** fncStatusGet - Returns a device/interface/endpoint status word** RETURNS: S_usbdLib_xxxx*/LOCAL int fncStatusGet    (    pURB_STATUS_GET pUrb    )    {    return controlRequest (&pUrb->header, pUrb->nodeId,	USB_RT_DEV_TO_HOST | pUrb->requestType, USB_REQ_GET_STATUS, 	0, pUrb->index, pUrb->bfrLen, pUrb->pBfr, &pUrb->actLen);    }/***************************************************************************** fncAddressGet - Returns a node's USB address** RETURNS: S_usbdLib_xxxx*/LOCAL int fncAddressGet    (    pURB_ADDRESS_GET_SET pUrb    )    {    pUSBD_NODE pNode;    /* validate node handle */    if (!validateNode (pUrb->nodeId, &pNode))	return S_usbdLib_BAD_HANDLE;    /* return current USB address for node */    pUrb->deviceAddress = pNode->busAddress;    return OK;    }/***************************************************************************** fncAddressSet - Sets a node's USB address** RETURNS: S_usbdLib_xxxx*/LOCAL int fncAddressSet    (    pURB_ADDRESS_GET_SET pUrb    )    {    int s;    s = controlRequest (&pUrb->header, pUrb->nodeId, 	USB_RT_HOST_TO_DEV | USB_RT_STANDARD | USB_RT_DEVICE,	USB_REQ_SET_ADDRESS, pUrb->deviceAddress, 0, 0, NULL, NULL);    OSS_THREAD_SLEEP (USB_TIME_SET_ADDRESS);    return s;    }/***************************************************************************** fncNodeInfoGet - Returns information about a node** RETURNS: S_usbdLib_xxxx*/LOCAL int fncNodeInfoGet    (    pURB_NODE_INFO_GET pUrb    )    {    pUSBD_NODE pNode;    /* Validate root */    if (!validateNode (pUrb->nodeId, &pNode))	return S_usbdLib_BAD_HANDLE;    /* Validate other parameters */    if (pUrb->pNodeInfo == NULL)	return S_usbdLib_BAD_PARAM;    /* Copy node info to caller's buffer */    memcpy (pUrb->pNodeInfo, &pNode->nodeInfo,	min (pUrb->infoLen, sizeof (pNode->nodeInfo)));    return OK;    }/***************************************************************************** fncVendorSpecific - Executes a vendor-specific USB request** RETURNS: S_usbdLib_xxxx*/LOCAL int fncVendorSpecific    (    pURB_VENDOR_SPECIFIC pUrb    )    {    return controlRequest (&pUrb->header, pUrb->nodeId,	pUrb->requestType, pUrb->request, pUrb->value, pUrb->index,	pUrb->length, pUrb->pBfr, &pUrb->actLen);    }/***************************************************************************** fncPipeCreate - Create a new transfer pipe** RETURNS: S_usbdLib_xxxx*/LOCAL int fncPipeCreate    (    pURB_PIPE_CREATE pUrb    )    {    pUSBD_CLIENT pClient;    pUSBD_NODE pNode;    pUSBD_PIPE pPipe;    pUSBD_BUS pBus;    UINT32 nanoseconds = 0;    HCD_PIPE_HANDLE hcdPipeHandle;    /* validate the client handle for this request */    if (!validateClient (pUrb->header.handle, &pClient))	return S_usbdLib_BAD_HANDLE;    /* validate the node to which this request is directed */    if (!validateNode (pUrb->nodeId, &pNode))	return S_usbdLib_BAD_HANDLE;    /* Validate other parameters */    if ((pUrb->transferType == USB_XFRTYPE_ISOCH ||	pUrb->transferType == USB_XFRTYPE_INTERRUPT) &&	pUrb->bandwidth == 0)	return S_usbdLib_BAD_PARAM;    if (pUrb->transferType == USB_XFRTYPE_INTERRUPT &&	pUrb->serviceInterval == 0)	return S_usbdLib_BAD_PARAM;    /* Make sure a default packet size is specified */    if (pUrb->maxPayload == 0)	pUrb->maxPayload = USB_MIN_CTRL_PACKET_SIZE;    /* Notify HCD of new pipe and make sure enough bandwidth is available to      * create the pipe.      */    pBus = pNode->pBus;    if (usbHcdPipeCreate (&pBus->pHcd->ne

⌨️ 快捷键说明

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