diff options
author | erictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-06-13 08:05:03 +0000 |
---|---|---|
committer | erictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-06-13 08:05:03 +0000 |
commit | 0309b719dd01b25845f1518865e150acfeffa70f (patch) | |
tree | 4e2d0ad39256c1f1b25a1a1c29c33fa67f9349f3 | |
parent | 60448d9b8dc5bc2f2d3038bc07daad1346cf3438 (diff) | |
download | edk2-platforms-0309b719dd01b25845f1518865e150acfeffa70f.tar.xz |
MdeModulePkg/UsbMouse: Get HID descriptor from the return of Get_Desc(Configuration) request with total length rather than from Get_Hid_Desc request.
Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Elvin Li <elvin.li@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13449 6f19259b-4bc3-4df7-8a09-765794883524
4 files changed, 186 insertions, 34 deletions
diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c index 8c2edb4f99..3540cd4a0f 100644 --- a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c @@ -1,7 +1,7 @@ /** @file
USB Mouse Driver that manages USB mouse and produces Absolute Pointer Protocol.
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
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
@@ -521,46 +521,108 @@ InitializeUsbMouseDevice ( IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev
)
{
- EFI_USB_IO_PROTOCOL *UsbIo;
- UINT8 Protocol;
- EFI_STATUS Status;
- EFI_USB_HID_DESCRIPTOR MouseHidDesc;
- UINT8 *ReportDesc;
- UINT8 ReportId;
- UINT8 Duration;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ UINT8 Protocol;
+ EFI_STATUS Status;
+ EFI_USB_HID_DESCRIPTOR *MouseHidDesc;
+ UINT8 *ReportDesc;
+ UINT8 ReportId;
+ UINT8 Duration;
+ EFI_USB_CONFIG_DESCRIPTOR ConfigDesc;
+ VOID *Buf;
+ UINT32 TransferResult;
+ UINT16 Total;
+ USB_DESC_HEAD *Head;
+ BOOLEAN Start;
UsbIo = UsbMouseAbsolutePointerDev->UsbIo;
//
- // Get HID descriptor
+ // Get the current configuration descriptor. Note that it doesn't include other descriptors.
+ //
+ Status = UsbIo->UsbGetConfigDescriptor (
+ UsbIo,
+ &ConfigDesc
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // By issuing Get_Descriptor(Configuration) request with total length, we get the Configuration descriptor,
+ // all Interface descriptors, all Endpoint descriptors, and the HID descriptor for each interface.
//
- Status = UsbGetHidDescriptor (
+ Buf = AllocateZeroPool (ConfigDesc.TotalLength);
+ if (Buf == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = UsbGetDescriptor (
UsbIo,
- UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,
- &MouseHidDesc
+ (UINT16)((USB_DESC_TYPE_CONFIG << 8) | (ConfigDesc.ConfigurationValue - 1)),
+ 0,
+ ConfigDesc.TotalLength,
+ Buf,
+ &TransferResult
);
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
return Status;
}
+ Total = 0;
+ Start = FALSE;
+ Head = (USB_DESC_HEAD *)Buf;
+ MouseHidDesc = NULL;
+
+ //
+ // Get HID descriptor from the receipt of Get_Descriptor(Configuration) request.
+ // This algorithm is based on the fact that the HID descriptor shall be interleaved
+ // between the interface and endpoint descriptors for HID interfaces.
+ //
+ while (Total < ConfigDesc.TotalLength) {
+ if (Head->Type == USB_DESC_TYPE_INTERFACE) {
+ if ((((USB_INTERFACE_DESCRIPTOR *)Head)->InterfaceNumber == UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber) &&
+ (((USB_INTERFACE_DESCRIPTOR *)Head)->AlternateSetting == UsbMouseAbsolutePointerDev->InterfaceDescriptor.AlternateSetting)) {
+ Start = TRUE;
+ }
+ }
+ if ((Start == TRUE) && (Head->Type == USB_DESC_TYPE_ENDPOINT)) {
+ break;
+ }
+ if ((Start == TRUE) && (Head->Type == USB_DESC_TYPE_HID)) {
+ MouseHidDesc = (EFI_USB_HID_DESCRIPTOR *)Head;
+ break;
+ }
+ Total += (UINT16)Head->Len;
+ Head = (USB_DESC_HEAD*)((UINT8 *)Buf + Total);
+ }
+
+ if (MouseHidDesc == NULL) {
+ FreePool (Buf);
+ return EFI_UNSUPPORTED;
+ }
+
//
// Get report descriptor
//
- if (MouseHidDesc.HidClassDesc[0].DescriptorType != USB_DESC_TYPE_REPORT) {
+ if (MouseHidDesc->HidClassDesc[0].DescriptorType != USB_DESC_TYPE_REPORT) {
+ FreePool (Buf);
return EFI_UNSUPPORTED;
}
- ReportDesc = AllocateZeroPool (MouseHidDesc.HidClassDesc[0].DescriptorLength);
+ ReportDesc = AllocateZeroPool (MouseHidDesc->HidClassDesc[0].DescriptorLength);
ASSERT (ReportDesc != NULL);
Status = UsbGetReportDescriptor (
UsbIo,
UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,
- MouseHidDesc.HidClassDesc[0].DescriptorLength,
+ MouseHidDesc->HidClassDesc[0].DescriptorLength,
ReportDesc
);
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
FreePool (ReportDesc);
return Status;
}
@@ -571,10 +633,11 @@ InitializeUsbMouseDevice ( Status = ParseMouseReportDescriptor (
UsbMouseAbsolutePointerDev,
ReportDesc,
- MouseHidDesc.HidClassDesc[0].DescriptorLength
+ MouseHidDesc->HidClassDesc[0].DescriptorLength
);
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
FreePool (ReportDesc);
return Status;
}
@@ -604,6 +667,7 @@ InitializeUsbMouseDevice ( );
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
FreePool (ReportDesc);
return Status;
}
@@ -626,6 +690,7 @@ InitializeUsbMouseDevice ( Duration
);
+ FreePool (Buf);
FreePool (ReportDesc);
//
diff --git a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.h b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.h index 169f0be4f7..08b8d56dd8 100644 --- a/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.h +++ b/MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.h @@ -1,7 +1,7 @@ /** @file
Helper routine and corresponding data struct used by USB Mouse Absolute Pointer Driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
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
@@ -42,6 +42,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define USB_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE SIGNATURE_32 ('u', 'm', 's', 't')
+//
+// A common header for usb standard descriptor.
+// Each stand descriptor has a length and type.
+//
+#pragma pack(1)
+typedef struct {
+ UINT8 Len;
+ UINT8 Type;
+} USB_DESC_HEAD;
+#pragma pack()
+
///
/// Button range and status
///
diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c index d81eaf7eae..d4e5a03475 100644 --- a/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c @@ -1,7 +1,7 @@ /** @file
USB Mouse Driver that manages USB mouse and produces Simple Pointer Protocol.
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
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
@@ -521,46 +521,108 @@ InitializeUsbMouseDevice ( IN OUT USB_MOUSE_DEV *UsbMouseDev
)
{
- EFI_USB_IO_PROTOCOL *UsbIo;
- UINT8 Protocol;
- EFI_STATUS Status;
- EFI_USB_HID_DESCRIPTOR MouseHidDesc;
- UINT8 *ReportDesc;
- UINT8 ReportId;
- UINT8 Duration;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ UINT8 Protocol;
+ EFI_STATUS Status;
+ EFI_USB_HID_DESCRIPTOR *MouseHidDesc;
+ UINT8 *ReportDesc;
+ UINT8 ReportId;
+ UINT8 Duration;
+ EFI_USB_CONFIG_DESCRIPTOR ConfigDesc;
+ VOID *Buf;
+ UINT32 TransferResult;
+ UINT16 Total;
+ USB_DESC_HEAD *Head;
+ BOOLEAN Start;
UsbIo = UsbMouseDev->UsbIo;
//
- // Get HID descriptor
+ // Get the current configuration descriptor. Note that it doesn't include other descriptors.
+ //
+ Status = UsbIo->UsbGetConfigDescriptor (
+ UsbIo,
+ &ConfigDesc
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // By issuing Get_Descriptor(Configuration) request with total length, we get the Configuration descriptor,
+ // all Interface descriptors, all Endpoint descriptors, and the HID descriptor for each interface.
//
- Status = UsbGetHidDescriptor (
+ Buf = AllocateZeroPool (ConfigDesc.TotalLength);
+ if (Buf == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = UsbGetDescriptor (
UsbIo,
- UsbMouseDev->InterfaceDescriptor.InterfaceNumber,
- &MouseHidDesc
+ (UINT16)((USB_DESC_TYPE_CONFIG << 8) | (ConfigDesc.ConfigurationValue - 1)),
+ 0,
+ ConfigDesc.TotalLength,
+ Buf,
+ &TransferResult
);
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
return Status;
}
+ Total = 0;
+ Start = FALSE;
+ Head = (USB_DESC_HEAD *)Buf;
+ MouseHidDesc = NULL;
+
+ //
+ // Get HID descriptor from the receipt of Get_Descriptor(Configuration) request.
+ // This algorithm is based on the fact that the HID descriptor shall be interleaved
+ // between the interface and endpoint descriptors for HID interfaces.
+ //
+ while (Total < ConfigDesc.TotalLength) {
+ if (Head->Type == USB_DESC_TYPE_INTERFACE) {
+ if ((((USB_INTERFACE_DESCRIPTOR *)Head)->InterfaceNumber == UsbMouseDev->InterfaceDescriptor.InterfaceNumber) &&
+ (((USB_INTERFACE_DESCRIPTOR *)Head)->AlternateSetting == UsbMouseDev->InterfaceDescriptor.AlternateSetting)) {
+ Start = TRUE;
+ }
+ }
+ if ((Start == TRUE) && (Head->Type == USB_DESC_TYPE_ENDPOINT)) {
+ break;
+ }
+ if ((Start == TRUE) && (Head->Type == USB_DESC_TYPE_HID)) {
+ MouseHidDesc = (EFI_USB_HID_DESCRIPTOR *)Head;
+ break;
+ }
+ Total += (UINT16)Head->Len;
+ Head = (USB_DESC_HEAD*)((UINT8 *)Buf + Total);
+ }
+
+ if (MouseHidDesc == NULL) {
+ FreePool (Buf);
+ return EFI_UNSUPPORTED;
+ }
+
//
// Get report descriptor
//
- if (MouseHidDesc.HidClassDesc[0].DescriptorType != USB_DESC_TYPE_REPORT) {
+ if (MouseHidDesc->HidClassDesc[0].DescriptorType != USB_DESC_TYPE_REPORT) {
+ FreePool (Buf);
return EFI_UNSUPPORTED;
}
- ReportDesc = AllocateZeroPool (MouseHidDesc.HidClassDesc[0].DescriptorLength);
+ ReportDesc = AllocateZeroPool (MouseHidDesc->HidClassDesc[0].DescriptorLength);
ASSERT (ReportDesc != NULL);
Status = UsbGetReportDescriptor (
UsbIo,
UsbMouseDev->InterfaceDescriptor.InterfaceNumber,
- MouseHidDesc.HidClassDesc[0].DescriptorLength,
+ MouseHidDesc->HidClassDesc[0].DescriptorLength,
ReportDesc
);
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
FreePool (ReportDesc);
return Status;
}
@@ -571,10 +633,11 @@ InitializeUsbMouseDevice ( Status = ParseMouseReportDescriptor (
UsbMouseDev,
ReportDesc,
- MouseHidDesc.HidClassDesc[0].DescriptorLength
+ MouseHidDesc->HidClassDesc[0].DescriptorLength
);
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
FreePool (ReportDesc);
return Status;
}
@@ -610,6 +673,7 @@ InitializeUsbMouseDevice ( );
if (EFI_ERROR (Status)) {
+ FreePool (Buf);
FreePool (ReportDesc);
return Status;
}
@@ -632,6 +696,7 @@ InitializeUsbMouseDevice ( Duration
);
+ FreePool (Buf);
FreePool (ReportDesc);
//
diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h index 6d677f7709..0dab9de11d 100644 --- a/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h @@ -1,7 +1,7 @@ /** @file
Helper routine and corresponding data struct used by USB Mouse Driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
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
@@ -42,6 +42,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define USB_MOUSE_DEV_SIGNATURE SIGNATURE_32 ('u', 'm', 'o', 'u')
+//
+// A common header for usb standard descriptor.
+// Each stand descriptor has a length and type.
+//
+#pragma pack(1)
+typedef struct {
+ UINT8 Len;
+ UINT8 Type;
+} USB_DESC_HEAD;
+#pragma pack()
+
///
/// Button range and status
///
|