diff options
Diffstat (limited to 'Core/EM/usb/efiusbhid.c')
-rw-r--r-- | Core/EM/usb/efiusbhid.c | 534 |
1 files changed, 534 insertions, 0 deletions
diff --git a/Core/EM/usb/efiusbhid.c b/Core/EM/usb/efiusbhid.c new file mode 100644 index 0000000..aa859ae --- /dev/null +++ b/Core/EM/usb/efiusbhid.c @@ -0,0 +1,534 @@ +//**************************************************************************** +//**************************************************************************** +//** ** +//** (C)Copyright 1985-2015, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone (770)-246-8600 ** +//** ** +//**************************************************************************** +//**************************************************************************** + +//**************************************************************************** +// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbhid.c 17 5/28/15 5:01a Wilsonlee $ +// +// $Revision: 17 $ +// +// $Date: 5/28/15 5:01a $ +// +//**************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbhid.c $ +// +// 17 5/28/15 5:01a Wilsonlee +// [TAG] EIP218997 +// [Category] Improvement +// [Description] Break the GetQueue loop if UninstallDevice is failed. +// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c, +// efiusbpoint.c, efiusbhid.c +// +// 16 8/12/14 3:04a Wilsonlee +// [TAG] EIP180970 +// [Category] Improvement +// [Description] Update X and Y data to usbmousedata and install +// SimplePointerProtocol interface if the mouses are using boot protocol +// interface. +// [Files] efiusbhid.c, usbms.c +// +// 15 5/06/14 5:17a Ryanchou +// [TAG] EIP166835 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Arrow keys cannot work with specific USB keyboard +// [RootCause] HID driver cannot parse a input report that includes both +// usage minimum/maximum and single usage. +// [Solution] Store the usage in the same array to determine the input +// data format. +// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c, +// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c +// +// 14 10/19/13 7:08a Ryanchou +// [TAG] EIP138257 +// [Category] Improvement +// [Description] Correct USB HID device type. +// [Files] amiusb.c, usbdef.h, usbhid.c, efiusbhid.c, uhcd.c +// +// 13 7/24/13 2:31a Roberthsu +// [TAG] EIP121333 +// [Category] Improvement +// [Description] Multiple USB mouse support for UEFI USB mouse driver +// [Files] efiusbhid.c,efiusbkb.h,efiusbms.c +// +// 12 3/19/13 4:00a Ryanchou +// [TAG] EIP118177 +// [Category] Improvement +// [Description] Dynamically allocate HCStrucTable at runtime. +// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c, +// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c, +// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c, +// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak, +// usbmisc.c, usbsrc.sdl +// +// 11 11/29/12 7:48a Ryanchou +// [TAG] EIP107586 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Unplug USB keyboard does not uninstall EFI USB keyboard +// driver properly +// [RootCause] The EIP99431 changes clear DEV_INFO.bSubDeviceType in +// runtime keyboard driver, that cause EFI keyboard driver does not know +// what type of the device is. +// [Solution] Do not clear DEV_INFO.bSubDeviceType in runtime keyboard +// driver. +// [Files] usb.c, usbhid.c, efiusbhid.c +// +// 10 11/10/12 6:41a Ryanchou +// [TAG] EIP99431 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for +// keyboard input +// [RootCause] Stopping EFI USB keyboard driver does not stop the +// endpoint polling, then application calls UsbAsyncInterruptTransfer, +// error will be returned. +// [Solution] Stops endpoint polling and release resource when +// disconnecting the device driver. And improve the +// UsbSyncInterruptTransfer. +// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c, +// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c, +// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h +// +// 9 8/29/12 8:35a Ryanchou +// [TAG] EIP77262 +// [Category] New Feature +// [Description] Remove SMM dependency of USB. +// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c, +// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c, +// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs, +// uhcd.h, usbmisc.c, AmiUsbController.h +// +// 8 5/04/12 5:19a Roberthsu +// +// 7 5/03/12 5:55a Roberthsu +// [TAG] EIP84455 +// [Category] Improvement +// [Description] Implement usb hid device gencric. +// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc +// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c +// ,usbsrc.sdl +// +// 6 12/29/11 1:54a Deepthins +// [TAG] EIP77537 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Multiple USB keyboard are not synchronized properly +// [RootCause] In USB driver for the new Simpletextin ( USB keyboard) +// device, the memory allocated for the device is saved in gUsbKbd +// pointer. The same pointer is used when multiple simple text in device +// installed. +// [Solution] USB_KB_DEV structure is divided into 2 structure, one is +// common for all the Simpletextin and another structure is for specific +// to the SimpleTextin Device.Based on it, allocate the memory for +// structure and use it. When the stop function is called, we should free +// only the structure that is specific for device. +// +// [Files] Efiusbkb.c, Efiusbhid.c, efiusbkb.c +// +// 5 12/14/11 2:10a Ryanchou +// [TAG] EIP76397 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] ASSERT occurred when executing "reconnect -r" under shell +// [RootCause] The EIP63188 changes locate all USB controllers at one +// time, the "reconnect -r" will connect ConIn and ConOut first, so USB +// driver only locate a controller. +// [Solution] Rollback the EIP63188 changes to avoid this issue. +// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h, +// usbbus.c usbhid.c +// +// 4 10/24/11 8:31a Wilsonlee +// [TAG] EIP69250 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] USB driver doesn't pass SCT 2.3 ComponentName2 protocol. +// [RootCause] There is no checking if passed controller handle is NULL +// in AMIUSBComponentNameGetControllerName function. +// [Solution] Check controller handle is NULL in +// AMIUSBComponentNameGetControllerName function. +// [Files] componentname.c efiusbccid.c efiusbhid.c +// +// 3 9/23/11 12:31a Rameshr +// [TAG] EIP63054 +// [Category] New Feature +// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key +// press +// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c, +// Efiusbkb.c, efiusbkb.h, efiusbhid.c +// +// 2 8/05/11 7:28a Ryanchou +// [TAG] EIP66231 +// [Category] Improvement +// [Description] Remove token POINT_SUPPORT.Add token USB_DEV_POINT.Add +// check core version in point driver.Add check device descriptor to send +// get lang id command.Modify check button usage page. +// [Files] efiusbhid.c, efiusbpoint.c, usbbus.c, usbhid.c, usbpoint.c, +// usbsrc.sdl +// +// 1 7/15/11 6:26a Ryanchou +// [TAG] EIP38434 +// [Category] New Feature +// [Description] Added USB HID report protocol support. +// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c, +// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, +// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c, +// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c +// +//**************************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: EfiUsbHid.C +// +// Description: EFI USB HID device Driver +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +#include "amidef.h" +#include "usbdef.h" +#include "uhcd.h" +#include "efiusbkb.h" +#include "usbkbd.h" + +#include "componentname.h" +#include "usbbus.h" + +extern DLIST mUsbKeyboardData; +extern USB_GLOBAL_DATA *gUsbData; +EFI_EVENT UsbKeyEvent; +extern USB_KEYBOARD_DATA* gUsbKeyboardData; + +#define AMI_HID_DEVICE_GUID \ + {0x1fede521, 0x31c, 0x4bc5, 0x80, 0x50, 0xf3, 0xd6, 0x16, 0x1e, 0x2e, 0x92} + +EFI_GUID gAmiHidDeviceGuid = AMI_HID_DEVICE_GUID; + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: UsbHidGetControllerName +// +// Description: USB EFI keyboard driver driver protocol function that +// returns the keyboard controller name. +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +CHAR16* +UsbHidGetControllerName( + EFI_HANDLE Controller, + EFI_HANDLE Child +) +{ + return NULL; +} + + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: UsbHidInit +// +// Description: HID EFI driver entry point +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +UsbHidInit( + EFI_HANDLE ImageHandle, + EFI_HANDLE ServiceHandle +) +{ + EFI_STATUS Status; + static NAME_SERVICE_T Names; + static EFI_DRIVER_BINDING_PROTOCOL Binding = { + SupportedUSBHid, + InstallUSBHid, + UninstallUSBHid, + USBKB_DRIVER_VERSION, + NULL, + NULL }; + + Binding.DriverBindingHandle = ServiceHandle; + Binding.ImageHandle = ImageHandle; + + DListInit(&mUsbKeyboardData); + + // + // Create a event to Poll a key when there is RegisterKeyNotify + // + pBS->CreateEvent( + EVT_TIMER | EFI_EVENT_NOTIFY_SIGNAL, + TPL_NOTIFY, + StartPollingKey, + NULL, + &UsbKeyEvent + ); + + InitUSBMouse(); + // + // Allocate the memory for gUsbKeyboardData and calling InitUSBKeyboard + // to initialize the USB keyboard. + // + Status = gBS->AllocatePool( EfiBootServicesData,sizeof(USB_KEYBOARD_DATA), &gUsbKeyboardData ); + ASSERT_EFI_ERROR(Status); + EfiZeroMem(gUsbKeyboardData, sizeof(USB_KEYBOARD_DATA)); + Status = InitUSBKeyboard(); + + return gBS->InstallMultipleProtocolInterfaces( + &Binding.DriverBindingHandle, + &gEfiDriverBindingProtocolGuid, &Binding, + &gEfiComponentName2ProtocolGuid, InitNamesProtocol(&Names, //(EIP69250) + L"USB Hid driver", UsbHidGetControllerName), + NULL); +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: SupportedUSBHid +// +// Description: Verifies if usb hid support can be installed on a device +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +SupportedUSBHid( + EFI_DRIVER_BINDING_PROTOCOL *This, + EFI_HANDLE Controller, + EFI_DEVICE_PATH_PROTOCOL *DevicePath) +{ + EFI_USB_INTERFACE_DESCRIPTOR Desc; + EFI_STATUS Status; + EFI_USB_IO_PROTOCOL *UsbIo; + + Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid, + &UsbIo, This->DriverBindingHandle, + Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR(Status)) { + return Status; + } + + gBS->CloseProtocol ( Controller, &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, Controller); + + Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &Desc ); + if(EFI_ERROR(Status)) + return EFI_UNSUPPORTED; + + if ( Desc.InterfaceClass == BASE_CLASS_HID) + { + return EFI_SUCCESS; + } else { + return EFI_UNSUPPORTED; + } +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: InstallUSBHid +// +// Description: Installs SimpleTxtIn protocol on a given handle +// +// Input: Controller - controller handle to install protocol on. +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +InstallUSBHid( + EFI_DRIVER_BINDING_PROTOCOL *This, + EFI_HANDLE Controller, + EFI_DEVICE_PATH_PROTOCOL *DevicePath +) +{ + EFI_STATUS Status; + EFI_USB_IO_PROTOCOL *UsbIo; + USBDEV_T* HidDev; + HC_STRUC* HcData; + UINT8 UsbStatus; + + USB_DEBUG(DEBUG_USBHC_LEVEL, + "USB: InstallUSBHid: starting...\n"); + // + // Open Protocols + // + Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid, + &UsbIo, This->DriverBindingHandle, + Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR(Status)) + return Status; + + HidDev = UsbIo2Dev(UsbIo); +//Find DEV_INFO + ASSERT(HidDev); + HcData = gUsbData->HcTable[HidDev->dev_info->bHCNumber - 1]; + UsbStatus = UsbSmiReConfigDevice(HcData, HidDev->dev_info); + if(UsbStatus != USB_SUCCESS) { + USB_DEBUG(DEBUG_USBHC_LEVEL, + "InstallUSBHid: failed to Reconfigure Hid: %d\n", UsbStatus ); + gBS->CloseProtocol ( + Controller, &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, Controller); + return EFI_DEVICE_ERROR; + } + + Status = gBS->InstallMultipleProtocolInterfaces (&Controller, + &gAmiHidDeviceGuid, NULL, + NULL + ); + + if(HidDev->dev_info->HidDevType & HID_DEV_TYPE_KEYBOARD) { + InstallUSBKeyboard(This,Controller,DevicePath,HidDev->dev_info,UsbIo); + } + + if (HidDev->dev_info->HidDevType & (HID_DEV_TYPE_MOUSE | HID_DEV_TYPE_POINT)) { + if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) { + if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_RELATIVE_DATA) { + InstallUSBMouse(Controller, UsbIo, HidDev->dev_info); + } +#if USB_DEV_POINT + if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_ABSOLUTE_DATA) { + InstallUSBAbsMouse(Controller, HidDev->dev_info); + } +#endif + } else { + InstallUSBMouse(Controller, UsbIo, HidDev->dev_info); + } + } + return Status; + +} + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Name: UninstallHid +// +// Description: Uninstalls protocol on a given handle +// +// Input: Controller - controller handle. +// +// Output: None +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS +UninstallUSBHid( + EFI_DRIVER_BINDING_PROTOCOL *This, + EFI_HANDLE Controller, + UINTN NumberOfChildren, + EFI_HANDLE *Children +) +{ + EFI_STATUS Status; + EFI_USB_IO_PROTOCOL *UsbIo; + VOID *Ptr; + UINT8 UsbSatus; + USBDEV_T* HidDev; + HC_STRUC* HcData; + + USB_DEBUG(DEBUG_USBHC_LEVEL, + "\n USB: UnInstallUSBHid: stoping...\n"); + + Status = gBS->OpenProtocol(Controller, &gAmiHidDeviceGuid, + &Ptr, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); + + if (EFI_ERROR(Status)) { + return Status; + } + // + // Open Protocols + // + Status = gBS->OpenProtocol(Controller, &gEfiUsbIoProtocolGuid, + &UsbIo, This->DriverBindingHandle, + Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); + if (EFI_ERROR(Status)) { + return Status; + } + + HidDev = UsbIo2Dev(UsbIo); + HcData = gUsbData->HcTable[HidDev->dev_info->bHCNumber - 1]; + + UsbSatus = UsbDevDriverDisconnect(HcData, HidDev->dev_info); + ASSERT(UsbSatus == USB_SUCCESS); + + if (HidDev->dev_info->HidDevType & HID_DEV_TYPE_KEYBOARD) { + Status = UninstallUSBKeyboard(This,Controller,NumberOfChildren,Children); + if (EFI_ERROR(Status)) { + return Status; + } + } + + if (HidDev->dev_info->HidDevType & (HID_DEV_TYPE_MOUSE | HID_DEV_TYPE_POINT)) { + if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) { + if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_RELATIVE_DATA) { + Status = UninstallUSBMouse(This, Controller, NumberOfChildren, Children); + if (EFI_ERROR(Status)) { + return Status; + } + } +#if USB_DEV_POINT + if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_ABSOLUTE_DATA) { + Status = UninstallUSBAbsMouse(Controller); + if (EFI_ERROR(Status)) { + return Status; + } + } +#endif + } else { + Status = UninstallUSBMouse(This, Controller, NumberOfChildren, Children); + if (EFI_ERROR(Status)) { + return Status; + } + } + } + + Status = gBS->UninstallMultipleProtocolInterfaces (Controller, + &gAmiHidDeviceGuid, NULL, + NULL); + + if (EFI_ERROR(Status)) { + return Status; + } + //Close usbio protocol + Status = gBS->CloseProtocol(Controller, &gEfiUsbIoProtocolGuid, + This->DriverBindingHandle, Controller); + + return Status; +} + +//**************************************************************************** +//**************************************************************************** +//** ** +//** (C)Copyright 1985-2015, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Norcross, GA 30093 ** +//** ** +//** Phone (770)-246-8600 ** +//** ** +//**************************************************************************** +//**************************************************************************** |