| /*++ | |
| Copyright (c) 2006, Intel Corporation | |
| All rights reserved. This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| Module Name: | |
| UsbDxeLib.c | |
| Abstract: | |
| Common Dxe Libarary for USB | |
| Revision History | |
| --*/ | |
| // | |
| // Get Device Descriptor | |
| // | |
| EFI_STATUS | |
| UsbGetDescriptor ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN UINT16 Value, | |
| IN UINT16 Index, | |
| IN UINT16 DescriptorLength, | |
| OUT VOID *Descriptor, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Get Descriptor | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| Value - Device Request Value | |
| Index - Device Request Index | |
| DescriptorLength - Descriptor Length | |
| Descriptor - Descriptor buffer to contain result | |
| Status - Transfer Status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE; | |
| DevReq.Request = USB_DEV_GET_DESCRIPTOR; | |
| DevReq.Value = Value; | |
| DevReq.Index = Index; | |
| DevReq.Length = DescriptorLength; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbDataIn, | |
| TIMEOUT_VALUE, | |
| Descriptor, | |
| DescriptorLength, | |
| Status | |
| ); | |
| } | |
| // | |
| // Set Device Descriptor | |
| // | |
| EFI_STATUS | |
| UsbSetDescriptor ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN UINT16 Value, | |
| IN UINT16 Index, | |
| IN UINT16 DescriptorLength, | |
| IN VOID *Descriptor, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Set Descriptor | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| Value - Device Request Value | |
| Index - Device Request Index | |
| DescriptorLength - Descriptor Length | |
| Descriptor - Descriptor buffer to set | |
| Status - Transfer Status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| DevReq.RequestType = USB_DEV_SET_DESCRIPTOR_REQ_TYPE; | |
| DevReq.Request = USB_DEV_SET_DESCRIPTOR; | |
| DevReq.Value = Value; | |
| DevReq.Index = Index; | |
| DevReq.Length = DescriptorLength; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbDataOut, | |
| TIMEOUT_VALUE, | |
| Descriptor, | |
| DescriptorLength, | |
| Status | |
| ); | |
| } | |
| // | |
| // Get device Interface | |
| // | |
| EFI_STATUS | |
| UsbGetDeviceInterface ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN UINT16 Index, | |
| OUT UINT8 *AltSetting, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Get Device Interface | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| Index - Interface index value | |
| AltSetting - Alternate setting | |
| Status - Trasnsfer status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| DevReq.RequestType = USB_DEV_GET_INTERFACE_REQ_TYPE; | |
| DevReq.Request = USB_DEV_GET_INTERFACE; | |
| DevReq.Index = Index; | |
| DevReq.Length = 1; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbDataIn, | |
| TIMEOUT_VALUE, | |
| AltSetting, | |
| 1, | |
| Status | |
| ); | |
| } | |
| // | |
| // Set device interface | |
| // | |
| EFI_STATUS | |
| UsbSetDeviceInterface ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN UINT16 InterfaceNo, | |
| IN UINT16 AltSetting, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Set Device Interface | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| InterfaceNo - Interface Number | |
| AltSetting - Alternate setting | |
| Status - Trasnsfer status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| DevReq.RequestType = USB_DEV_SET_INTERFACE_REQ_TYPE; | |
| DevReq.Request = USB_DEV_SET_INTERFACE; | |
| DevReq.Value = AltSetting; | |
| DevReq.Index = InterfaceNo; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbNoData, | |
| TIMEOUT_VALUE, | |
| NULL, | |
| 0, | |
| Status | |
| ); | |
| } | |
| // | |
| // Get device configuration | |
| // | |
| EFI_STATUS | |
| UsbGetDeviceConfiguration ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| OUT UINT8 *ConfigValue, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Get Device Configuration | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| ConfigValue - Config Value | |
| Status - Transfer Status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| DevReq.RequestType = USB_DEV_GET_CONFIGURATION_REQ_TYPE; | |
| DevReq.Request = USB_DEV_GET_CONFIGURATION; | |
| DevReq.Length = 1; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbDataIn, | |
| TIMEOUT_VALUE, | |
| ConfigValue, | |
| 1, | |
| Status | |
| ); | |
| } | |
| // | |
| // Set device configuration | |
| // | |
| EFI_STATUS | |
| UsbSetDeviceConfiguration ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN UINT16 Value, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Set Device Configuration | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| Value - Configuration Value to set | |
| Status - Transfer status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE; | |
| DevReq.Request = USB_DEV_SET_CONFIGURATION; | |
| DevReq.Value = Value; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbNoData, | |
| TIMEOUT_VALUE, | |
| NULL, | |
| 0, | |
| Status | |
| ); | |
| } | |
| // | |
| // Set Device Feature | |
| // | |
| EFI_STATUS | |
| UsbSetDeviceFeature ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN EFI_USB_RECIPIENT Recipient, | |
| IN UINT16 Value, | |
| IN UINT16 Target, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Set Device Feature | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| Recipient - Interface/Device/Endpoint | |
| Value - Request value | |
| Target - Request Index | |
| Status - Transfer status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| switch (Recipient) { | |
| case EfiUsbDevice: | |
| DevReq.RequestType = 0x00; | |
| break; | |
| case EfiUsbInterface: | |
| DevReq.RequestType = 0x01; | |
| break; | |
| case EfiUsbEndpoint: | |
| DevReq.RequestType = 0x02; | |
| break; | |
| } | |
| // | |
| // Fill device request, see USB1.1 spec | |
| // | |
| DevReq.Request = USB_DEV_SET_FEATURE; | |
| DevReq.Value = Value; | |
| DevReq.Index = Target; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbNoData, | |
| TIMEOUT_VALUE, | |
| NULL, | |
| 0, | |
| Status | |
| ); | |
| } | |
| // | |
| // Clear Device Feature | |
| // | |
| EFI_STATUS | |
| UsbClearDeviceFeature ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN EFI_USB_RECIPIENT Recipient, | |
| IN UINT16 Value, | |
| IN UINT16 Target, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Clear Device Feature | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| Recipient - Interface/Device/Endpoint | |
| Value - Request value | |
| Target - Request Index | |
| Status - Transfer status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| switch (Recipient) { | |
| case EfiUsbDevice: | |
| DevReq.RequestType = 0x00; | |
| break; | |
| case EfiUsbInterface: | |
| DevReq.RequestType = 0x01; | |
| break; | |
| case EfiUsbEndpoint: | |
| DevReq.RequestType = 0x02; | |
| break; | |
| } | |
| // | |
| // Fill device request, see USB1.1 spec | |
| // | |
| DevReq.Request = USB_DEV_CLEAR_FEATURE; | |
| DevReq.Value = Value; | |
| DevReq.Index = Target; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbNoData, | |
| TIMEOUT_VALUE, | |
| NULL, | |
| 0, | |
| Status | |
| ); | |
| } | |
| // | |
| // Get Device Status | |
| // | |
| EFI_STATUS | |
| UsbGetDeviceStatus ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN EFI_USB_RECIPIENT Recipient, | |
| IN UINT16 Target, | |
| OUT UINT16 *DevStatus, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Get Device Status | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| Recipient - Interface/Device/Endpoint | |
| Target - Request index | |
| DevStatus - Device status | |
| Status - Transfer status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| EFI_USB_DEVICE_REQUEST DevReq; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); | |
| switch (Recipient) { | |
| case EfiUsbDevice: | |
| DevReq.RequestType = 0x80; | |
| break; | |
| case EfiUsbInterface: | |
| DevReq.RequestType = 0x81; | |
| break; | |
| case EfiUsbEndpoint: | |
| DevReq.RequestType = 0x82; | |
| break; | |
| } | |
| // | |
| // Fill device request, see USB1.1 spec | |
| // | |
| DevReq.Request = USB_DEV_GET_STATUS; | |
| DevReq.Value = 0; | |
| DevReq.Index = Target; | |
| DevReq.Length = 2; | |
| return UsbIo->UsbControlTransfer ( | |
| UsbIo, | |
| &DevReq, | |
| EfiUsbDataIn, | |
| TIMEOUT_VALUE, | |
| DevStatus, | |
| 2, | |
| Status | |
| ); | |
| } | |
| // | |
| // Usb Get String | |
| // | |
| EFI_STATUS | |
| UsbGetString ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN UINT16 LangID, | |
| IN UINT8 Index, | |
| IN VOID *Buf, | |
| IN UINTN BufSize, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Usb Get String | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| LangID - Language ID | |
| Index - Request index | |
| Buf - Buffer to store string | |
| BufSize - Buffer size | |
| Status - Transfer status | |
| Returns: | |
| EFI_INVALID_PARAMETER - Parameter is error | |
| EFI_SUCCESS - Success | |
| EFI_TIMEOUT - Device has no response | |
| --*/ | |
| { | |
| UINT16 Value; | |
| if (UsbIo == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| // | |
| // Fill value, see USB1.1 spec | |
| // | |
| Value = (UINT16) ((USB_DT_STRING << 8) | Index); | |
| return UsbGetDescriptor ( | |
| UsbIo, | |
| Value, | |
| LangID, | |
| (UINT16) BufSize, | |
| Buf, | |
| Status | |
| ); | |
| } | |
| EFI_STATUS | |
| UsbClearEndpointHalt ( | |
| IN EFI_USB_IO_PROTOCOL *UsbIo, | |
| IN UINT8 EndpointNo, | |
| OUT UINT32 *Status | |
| ) | |
| /*++ | |
| Routine Description: | |
| Clear endpoint stall | |
| Arguments: | |
| UsbIo - EFI_USB_IO_PROTOCOL | |
| EndpointNo - Endpoint Number | |
| Status - Transfer Status | |
| Returns: | |
| EFI_NOT_FOUND - Can't find the Endpoint | |
| EFI_DEVICE_ERROR - Hardware error | |
| EFI_SUCCESS - Success | |
| --*/ | |
| { | |
| EFI_STATUS Result; | |
| EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; | |
| EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; | |
| UINT8 Index; | |
| ZeroMem (&EndpointDescriptor, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)); | |
| // | |
| // First seach the endpoint descriptor for that endpoint addr | |
| // | |
| Result = UsbIo->UsbGetInterfaceDescriptor ( | |
| UsbIo, | |
| &InterfaceDescriptor | |
| ); | |
| if (EFI_ERROR (Result)) { | |
| return Result; | |
| } | |
| for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) { | |
| Result = UsbIo->UsbGetEndpointDescriptor ( | |
| UsbIo, | |
| Index, | |
| &EndpointDescriptor | |
| ); | |
| if (EFI_ERROR (Result)) { | |
| continue; | |
| } | |
| if (EndpointDescriptor.EndpointAddress == EndpointNo) { | |
| break; | |
| } | |
| } | |
| if (Index == InterfaceDescriptor.NumEndpoints) { | |
| // | |
| // No such endpoint | |
| // | |
| return EFI_NOT_FOUND; | |
| } | |
| Result = UsbClearDeviceFeature ( | |
| UsbIo, | |
| EfiUsbEndpoint, | |
| EfiUsbEndpointHalt, | |
| EndpointDescriptor.EndpointAddress, | |
| Status | |
| ); | |
| return Result; | |
| } |