/** @file\r
-\r
- Parse mouse hid descriptor.\r
+ Helper functions to parse HID report descriptor and items.\r
\r
Copyright (c) 2004 - 2008, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
\r
**/\r
\r
-#include "MouseHid.h"\r
+#include "UsbMouse.h"\r
\r
\r
/**\r
- Get next item from report descriptor.\r
+ Get next HID item from report descriptor.\r
+\r
+ This function retrieves next HID item from report descriptor, according to\r
+ the start position.\r
+ According to USB HID Specification, An item is piece of information\r
+ about the device. All items have a one-byte prefix that contains\r
+ the item tag, item type, and item size.\r
+ There are two basic types of items: short items and long items.\r
+ If the item is a short item, its optional data size may be 0, 1, 2, or 4 bytes.\r
+ Only short item is supported here.\r
\r
- @param StartPos Start Position.\r
- @param EndPos End Position.\r
- @param HidItem HidItem to return.\r
+ @param StartPos Start position of the HID item to get.\r
+ @param EndPos End position of the range to get the the next HID item.\r
+ @param HidItem Buffer for the HID Item to return.\r
\r
- @return Position.\r
+ @return Pointer to end of the HID item returned.\r
+ NULL if no HID item retrieved.\r
\r
**/\r
UINT8 *\r
-GetNextItem (\r
+GetNextHidItem (\r
IN UINT8 *StartPos,\r
IN UINT8 *EndPos,\r
OUT HID_ITEM *HidItem\r
{\r
UINT8 Temp;\r
\r
- if ((EndPos - StartPos) <= 0) {\r
+ if (EndPos <= StartPos) {\r
return NULL;\r
}\r
\r
Temp = *StartPos;\r
StartPos++;\r
+\r
//\r
- // bit 2,3\r
- //\r
- HidItem->Type = (UINT8) ((Temp >> 2) & 0x03);\r
- //\r
- // bit 4-7\r
+ // Bit format of prefix byte:\r
+ // Bits 0-1: Size\r
+ // Bits 2-3: Type\r
+ // Bits 4-7: Tag\r
//\r
- HidItem->Tag = (UINT8) ((Temp >> 4) & 0x0F);\r
+ HidItem->Type = BitFieldRead8 (Temp, 2, 3);\r
+ HidItem->Tag = BitFieldRead8 (Temp, 4, 7);\r
\r
if (HidItem->Tag == HID_ITEM_TAG_LONG) {\r
//\r
- // Long Items are not supported by HID rev1.0,\r
- // although we try to parse it.\r
+ // Long Items are not supported, although we try to parse it.\r
//\r
HidItem->Format = HID_ITEM_FORMAT_LONG;\r
\r
}\r
} else {\r
HidItem->Format = HID_ITEM_FORMAT_SHORT;\r
- //\r
- // bit 0, 1\r
- //\r
- HidItem->Size = (UINT8) (Temp & 0x03);\r
- switch (HidItem->Size) {\r
+ HidItem->Size = BitFieldRead8 (Temp, 0, 1);\r
\r
+ switch (HidItem->Size) {\r
case 0:\r
//\r
// No data\r
\r
case 1:\r
//\r
- // One byte data\r
+ // 1-byte data\r
//\r
if ((EndPos - StartPos) >= 1) {\r
HidItem->Data.U8 = *StartPos++;\r
\r
case 2:\r
//\r
- // Two byte data\r
+ // 2-byte data\r
//\r
if ((EndPos - StartPos) >= 2) {\r
CopyMem (&HidItem->Data.U16, StartPos, sizeof (UINT16));\r
\r
case 3:\r
//\r
- // 4 byte data, adjust size\r
+ // 4-byte data, adjust size\r
//\r
- HidItem->Size++;\r
+ HidItem->Size = 4;\r
if ((EndPos - StartPos) >= 4) {\r
CopyMem (&HidItem->Data.U32, StartPos, sizeof (UINT32));\r
StartPos += 4;\r
\r
\r
/**\r
- Get item data from report descriptor.\r
+ Get data from HID item.\r
\r
- @param HidItem The pointer to HID_ITEM.\r
+ This function retrieves data from HID item.\r
+ It only supports short items, which has 4 types of data:\r
+ 0, 1, 2, or 4 bytes.\r
\r
- @return The Data of HidItem.\r
+ @param HidItem Pointer to the HID item.\r
+\r
+ @return The data of HID item.\r
\r
**/\r
UINT32\r
)\r
{\r
//\r
- // Get Data from HID_ITEM structure\r
+ // Get data from HID item.\r
//\r
switch (HidItem->Size) {\r
-\r
case 1:\r
return HidItem->Data.U8;\r
-\r
case 2:\r
return HidItem->Data.U16;\r
-\r
case 4:\r
return HidItem->Data.U32;\r
}\r
-\r
return 0;\r
}\r
\r
-\r
/**\r
- Parse local item from report descriptor.\r
+ Parse HID item from report descriptor.\r
\r
+ There are three item types: Main, Global, and Local.\r
+ This function parses these types of HID items according\r
+ to tag info.\r
+ \r
@param UsbMouse The instance of USB_MOUSE_DEV\r
- @param LocalItem The pointer to local hid item\r
+ @param HidItem The HID item to parse\r
\r
**/\r
VOID\r
-ParseLocalItem (\r
+ParseHidItem (\r
IN USB_MOUSE_DEV *UsbMouse,\r
- IN HID_ITEM *LocalItem\r
+ IN HID_ITEM *HidItem\r
)\r
{\r
- UINT32 Data;\r
+ UINT8 Data;\r
\r
- if (LocalItem->Size == 0) {\r
+ switch (HidItem->Type) {\r
+\r
+ case HID_ITEM_TYPE_MAIN:\r
//\r
- // No expected data for local item\r
+ // we don't care any main items, just skip\r
//\r
- return ;\r
- }\r
+ return;\r
\r
- Data = GetItemData (LocalItem);\r
-\r
- switch (LocalItem->Tag) {\r
-\r
- case HID_LOCAL_ITEM_TAG_DELIMITER:\r
+ case HID_ITEM_TYPE_GLOBAL:\r
//\r
- // we don't support delimiter here\r
+ // For global items, we only care Usage Page tag for Button Page here\r
//\r
- return ;\r
-\r
- case HID_LOCAL_ITEM_TAG_USAGE:\r
- return ;\r
+ if (HidItem->Tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE) {\r
+ Data = (UINT8) GetItemData (HidItem);\r
+ if (Data == 0x09) {\r
+ //\r
+ // Button Page\r
+ //\r
+ UsbMouse->PrivateData.ButtonDetected = TRUE;\r
+ }\r
+ }\r
+ return;\r
\r
- case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:\r
- if (UsbMouse->PrivateData.ButtonDetected) {\r
- UsbMouse->PrivateData.ButtonMinIndex = (UINT8) Data;\r
+ case HID_ITEM_TYPE_LOCAL:\r
+ if (HidItem->Size == 0) {\r
+ //\r
+ // No expected data for local item\r
+ //\r
+ return ;\r
}\r
\r
- return ;\r
+ Data = (UINT8) GetItemData (HidItem);\r
\r
- case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:\r
- {\r
+ switch (HidItem->Tag) {\r
+ case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:\r
if (UsbMouse->PrivateData.ButtonDetected) {\r
- UsbMouse->PrivateData.ButtonMaxIndex = (UINT8) Data;\r
+ UsbMouse->PrivateData.ButtonMinIndex = Data;\r
}\r
-\r
return ;\r
- }\r
- }\r
-}\r
\r
-\r
-/**\r
- Parse global item from report descriptor.\r
-\r
- @param UsbMouse The instance of USB_MOUSE_DEV\r
- @param GlobalItem The pointer to global hid item\r
-\r
-**/\r
-VOID\r
-ParseGlobalItem (\r
- IN USB_MOUSE_DEV *UsbMouse,\r
- IN HID_ITEM *GlobalItem\r
- )\r
-{\r
- UINT8 UsagePage;\r
-\r
- switch (GlobalItem->Tag) {\r
- case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:\r
+ case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:\r
{\r
- UsagePage = (UINT8) GetItemData (GlobalItem);\r
-\r
- //\r
- // We only care Button Page here\r
- //\r
- if (UsagePage == 0x09) {\r
- //\r
- // Button Page\r
- //\r
- UsbMouse->PrivateData.ButtonDetected = TRUE;\r
- return ;\r
+ if (UsbMouse->PrivateData.ButtonDetected) {\r
+ UsbMouse->PrivateData.ButtonMaxIndex = Data;\r
}\r
- break;\r
+ return ;\r
}\r
\r
- }\r
-}\r
-\r
-\r
-/**\r
- Parse main item from report descriptor.\r
-\r
- @param UsbMouse The instance of USB_MOUSE_DEV\r
- @param MainItem Main hid item to parse\r
-\r
-**/\r
-VOID\r
-ParseMainItem (\r
- IN USB_MOUSE_DEV *UsbMouse,\r
- IN HID_ITEM *MainItem\r
- )\r
-{\r
- //\r
- // we don't care any main items, just skip\r
- //\r
- return ;\r
-}\r
-\r
-\r
-/**\r
- Parse hid item from report descriptor.\r
-\r
- @param UsbMouse The instance of USB_MOUSE_DEV\r
- @param HidItem The hid item to parse\r
-\r
-**/\r
-VOID\r
-ParseHidItem (\r
- IN USB_MOUSE_DEV *UsbMouse,\r
- IN HID_ITEM *HidItem\r
- )\r
-{\r
- switch (HidItem->Type) {\r
-\r
- case HID_ITEM_TYPE_MAIN:\r
- //\r
- // For Main Item, parse main item\r
- //\r
- ParseMainItem (UsbMouse, HidItem);\r
- break;\r
-\r
- case HID_ITEM_TYPE_GLOBAL:\r
- //\r
- // For global Item, parse global item\r
- //\r
- ParseGlobalItem (UsbMouse, HidItem);\r
- break;\r
-\r
- case HID_ITEM_TYPE_LOCAL:\r
- //\r
- // For Local Item, parse local item\r
- //\r
- ParseLocalItem (UsbMouse, HidItem);\r
- break;\r
+ default:\r
+ return;\r
+ }\r
}\r
}\r
\r
/**\r
Parse Mouse Report Descriptor.\r
\r
+ According to USB HID Specification, report descriptors are\r
+ composed of pieces of information. Each piece of information\r
+ is called an Item. This function retrieves each item from\r
+ the report descriptor and updates USB_MOUSE_DEV.\r
+\r
@param UsbMouse The instance of USB_MOUSE_DEV\r
@param ReportDescriptor Report descriptor to parse\r
@param ReportSize Report descriptor size\r
\r
- @retval EFI_DEVICE_ERROR Report descriptor error\r
- @retval EFI_SUCCESS Parse descriptor success\r
+ @retval EFI_SUCCESS Report descriptor successfully parsed.\r
+ @retval EFI_UNSUPPORTED Report descriptor contains long item.\r
\r
**/\r
EFI_STATUS\r
ParseMouseReportDescriptor (\r
- IN USB_MOUSE_DEV *UsbMouse,\r
+ OUT USB_MOUSE_DEV *UsbMouse,\r
IN UINT8 *ReportDescriptor,\r
IN UINTN ReportSize\r
)\r
\r
DescriptorEnd = ReportDescriptor + ReportSize;\r
\r
- Ptr = GetNextItem (ReportDescriptor, DescriptorEnd, &HidItem);\r
-\r
+ Ptr = GetNextHidItem (ReportDescriptor, DescriptorEnd, &HidItem);\r
while (Ptr != NULL) {\r
if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {\r
//\r
- // Long Format Item is not supported at current HID revision\r
+ // Long Item is not supported at current HID revision\r
//\r
- return EFI_DEVICE_ERROR;\r
+ return EFI_UNSUPPORTED;\r
}\r
\r
ParseHidItem (UsbMouse, &HidItem);\r
\r
- Ptr = GetNextItem (Ptr, DescriptorEnd, &HidItem);\r
+ Ptr = GetNextHidItem (Ptr, DescriptorEnd, &HidItem);\r
}\r
\r
- UsbMouse->NumberOfButtons = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1);\r
- UsbMouse->XLogicMax = UsbMouse->YLogicMax = 127;\r
- UsbMouse->XLogicMin = UsbMouse->YLogicMin = -127;\r
+ UsbMouse->NumberOfButtons = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1);\r
+ UsbMouse->XLogicMax = 127;\r
+ UsbMouse->YLogicMax = 127;\r
+ UsbMouse->XLogicMin = -127;\r
+ UsbMouse->YLogicMin = -127;\r
\r
return EFI_SUCCESS;\r
}\r