]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointer.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbMouseAbsolutePointerDxe / UsbMouseAbsolutePointer.c
CommitLineData
09f72ae8 1/** @file\r
67b8a9ce 2 USB Mouse Driver that manages USB mouse and produces Absolute Pointer Protocol.\r
09f72ae8 3\r
d1102dba 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
09f72ae8 6\r
09f72ae8 7**/\r
8\r
9#include "UsbMouseAbsolutePointer.h"\r
10\r
1436aea4 11EFI_DRIVER_BINDING_PROTOCOL gUsbMouseAbsolutePointerDriverBinding = {\r
09f72ae8 12 USBMouseAbsolutePointerDriverBindingSupported,\r
13 USBMouseAbsolutePointerDriverBindingStart,\r
14 USBMouseAbsolutePointerDriverBindingStop,\r
15 0x1,\r
16 NULL,\r
17 NULL\r
18};\r
19\r
67b8a9ce 20/**\r
21 Entrypoint of USB Mouse Absolute Pointer Driver.\r
09f72ae8 22\r
67b8a9ce 23 This function is the entrypoint of USB Mouse Driver. It installs Driver Binding\r
24 Protocols together with Component Name Protocols.\r
09f72ae8 25\r
67b8a9ce 26 @param ImageHandle The firmware allocated handle for the EFI image.\r
27 @param SystemTable A pointer to the EFI System Table.\r
09f72ae8 28\r
67b8a9ce 29 @retval EFI_SUCCESS The entry point is executed successfully.\r
09f72ae8 30\r
67b8a9ce 31**/\r
09f72ae8 32EFI_STATUS\r
33EFIAPI\r
34USBMouseAbsolutePointerDriverBindingEntryPoint (\r
1436aea4
MK
35 IN EFI_HANDLE ImageHandle,\r
36 IN EFI_SYSTEM_TABLE *SystemTable\r
09f72ae8 37 )\r
67b8a9ce 38{\r
1436aea4 39 EFI_STATUS Status;\r
09f72ae8 40\r
67b8a9ce 41 Status = EfiLibInstallDriverBindingComponentName2 (\r
42 ImageHandle,\r
43 SystemTable,\r
44 &gUsbMouseAbsolutePointerDriverBinding,\r
45 ImageHandle,\r
46 &gUsbMouseAbsolutePointerComponentName,\r
47 &gUsbMouseAbsolutePointerComponentName2\r
48 );\r
49 ASSERT_EFI_ERROR (Status);\r
09f72ae8 50\r
67b8a9ce 51 return EFI_SUCCESS;\r
09f72ae8 52}\r
53\r
09f72ae8 54/**\r
67b8a9ce 55 Check whether USB Mouse Absolute Pointer Driver supports this device.\r
09f72ae8 56\r
67b8a9ce 57 @param This The driver binding protocol.\r
58 @param Controller The controller handle to check.\r
59 @param RemainingDevicePath The remaining device path.\r
09f72ae8 60\r
67b8a9ce 61 @retval EFI_SUCCESS The driver supports this controller.\r
62 @retval other This device isn't supported.\r
09f72ae8 63\r
64**/\r
65EFI_STATUS\r
66EFIAPI\r
67USBMouseAbsolutePointerDriverBindingSupported (\r
1436aea4
MK
68 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
69 IN EFI_HANDLE Controller,\r
70 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
09f72ae8 71 )\r
72{\r
1436aea4
MK
73 EFI_STATUS Status;\r
74 EFI_USB_IO_PROTOCOL *UsbIo;\r
09f72ae8 75\r
67b8a9ce 76 Status = gBS->OpenProtocol (\r
77 Controller,\r
78 &gEfiUsbIoProtocolGuid,\r
1436aea4 79 (VOID **)&UsbIo,\r
67b8a9ce 80 This->DriverBindingHandle,\r
81 Controller,\r
82 EFI_OPEN_PROTOCOL_BY_DRIVER\r
83 );\r
84 if (EFI_ERROR (Status)) {\r
85 return Status;\r
09f72ae8 86 }\r
d1102dba 87\r
09f72ae8 88 //\r
67b8a9ce 89 // Use the USB I/O Protocol interface to check whether Controller is\r
90 // a mouse device that can be managed by this driver.\r
09f72ae8 91 //\r
92 Status = EFI_SUCCESS;\r
67b8a9ce 93 if (!IsUsbMouse (UsbIo)) {\r
09f72ae8 94 Status = EFI_UNSUPPORTED;\r
95 }\r
d1102dba 96\r
09f72ae8 97 gBS->CloseProtocol (\r
1436aea4
MK
98 Controller,\r
99 &gEfiUsbIoProtocolGuid,\r
100 This->DriverBindingHandle,\r
101 Controller\r
102 );\r
d1102dba 103\r
09f72ae8 104 return Status;\r
105}\r
106\r
09f72ae8 107/**\r
67b8a9ce 108 Starts the mouse device with this driver.\r
09f72ae8 109\r
d2286747 110 This function consumes USB I/O Protocol, initializes USB mouse device,\r
67b8a9ce 111 installs Absolute Pointer Protocol, and submits Asynchronous Interrupt\r
112 Transfer to manage the USB mouse device.\r
113\r
114 @param This The driver binding instance.\r
115 @param Controller Handle of device to bind driver to.\r
116 @param RemainingDevicePath Optional parameter use to pick a specific child\r
117 device to start.\r
09f72ae8 118\r
119 @retval EFI_SUCCESS This driver supports this device.\r
120 @retval EFI_UNSUPPORTED This driver does not support this device.\r
67b8a9ce 121 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.\r
122 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
123 @retval EFI_ALREADY_STARTED This driver has been started.\r
09f72ae8 124\r
125**/\r
126EFI_STATUS\r
127EFIAPI\r
128USBMouseAbsolutePointerDriverBindingStart (\r
1436aea4
MK
129 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
130 IN EFI_HANDLE Controller,\r
131 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
09f72ae8 132 )\r
133{\r
1436aea4
MK
134 EFI_STATUS Status;\r
135 EFI_USB_IO_PROTOCOL *UsbIo;\r
136 USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice;\r
137 UINT8 EndpointNumber;\r
138 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;\r
139 UINT8 Index;\r
140 UINT8 EndpointAddr;\r
141 UINT8 PollingInterval;\r
142 UINT8 PacketSize;\r
143 BOOLEAN Found;\r
144 EFI_TPL OldTpl;\r
09f72ae8 145\r
15cc67e6 146 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
67b8a9ce 147 //\r
148 // Open USB I/O Protocol\r
149 //\r
09f72ae8 150 Status = gBS->OpenProtocol (\r
151 Controller,\r
152 &gEfiUsbIoProtocolGuid,\r
1436aea4 153 (VOID **)&UsbIo,\r
09f72ae8 154 This->DriverBindingHandle,\r
155 Controller,\r
d1102dba 156 EFI_OPEN_PROTOCOL_BY_DRIVER\r
09f72ae8 157 );\r
158 if (EFI_ERROR (Status)) {\r
15cc67e6 159 goto ErrorExit1;\r
09f72ae8 160 }\r
d1102dba 161\r
09f72ae8 162 UsbMouseAbsolutePointerDevice = AllocateZeroPool (sizeof (USB_MOUSE_ABSOLUTE_POINTER_DEV));\r
67b8a9ce 163 ASSERT (UsbMouseAbsolutePointerDevice != NULL);\r
09f72ae8 164\r
67b8a9ce 165 UsbMouseAbsolutePointerDevice->UsbIo = UsbIo;\r
166 UsbMouseAbsolutePointerDevice->Signature = USB_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE;\r
09f72ae8 167\r
09f72ae8 168 //\r
169 // Get the Device Path Protocol on Controller's handle\r
170 //\r
171 Status = gBS->OpenProtocol (\r
172 Controller,\r
173 &gEfiDevicePathProtocolGuid,\r
1436aea4 174 (VOID **)&UsbMouseAbsolutePointerDevice->DevicePath,\r
09f72ae8 175 This->DriverBindingHandle,\r
176 Controller,\r
177 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
178 );\r
179\r
180 if (EFI_ERROR (Status)) {\r
181 goto ErrorExit;\r
182 }\r
37623a5c 183\r
184 //\r
185 // Report Status Code here since USB mouse will be detected next.\r
186 //\r
187 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
188 EFI_PROGRESS_CODE,\r
189 (EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT),\r
b9de2d78 190 UsbMouseAbsolutePointerDevice->DevicePath\r
37623a5c 191 );\r
192\r
09f72ae8 193 //\r
194 // Get interface & endpoint descriptor\r
195 //\r
196 UsbIo->UsbGetInterfaceDescriptor (\r
67b8a9ce 197 UsbIo,\r
198 &UsbMouseAbsolutePointerDevice->InterfaceDescriptor\r
199 );\r
09f72ae8 200\r
67b8a9ce 201 EndpointNumber = UsbMouseAbsolutePointerDevice->InterfaceDescriptor.NumEndpoints;\r
09f72ae8 202\r
67b8a9ce 203 //\r
6cfb6da9 204 // Traverse endpoints to find interrupt endpoint IN\r
67b8a9ce 205 //\r
206 Found = FALSE;\r
09f72ae8 207 for (Index = 0; Index < EndpointNumber; Index++) {\r
208 UsbIo->UsbGetEndpointDescriptor (\r
67b8a9ce 209 UsbIo,\r
210 Index,\r
211 &EndpointDescriptor\r
212 );\r
09f72ae8 213\r
6cfb6da9 214 if (((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) &&\r
1436aea4
MK
215 ((EndpointDescriptor.EndpointAddress & USB_ENDPOINT_DIR_IN) != 0))\r
216 {\r
09f72ae8 217 //\r
218 // We only care interrupt endpoint here\r
219 //\r
1436aea4 220 CopyMem (&UsbMouseAbsolutePointerDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof (EndpointDescriptor));\r
67b8a9ce 221 Found = TRUE;\r
222 break;\r
09f72ae8 223 }\r
224 }\r
225\r
67b8a9ce 226 if (!Found) {\r
09f72ae8 227 //\r
37623a5c 228 // Report Status Code to indicate that there is no USB mouse\r
229 //\r
230 REPORT_STATUS_CODE (\r
b9de2d78 231 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
37623a5c 232 (EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED)\r
233 );\r
234 //\r
67b8a9ce 235 // No interrupt endpoint found, then return unsupported.\r
09f72ae8 236 //\r
237 Status = EFI_UNSUPPORTED;\r
238 goto ErrorExit;\r
239 }\r
240\r
37623a5c 241 //\r
242 // Report Status Code here since USB mouse has be detected.\r
243 //\r
244 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
245 EFI_PROGRESS_CODE,\r
246 (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED),\r
b9de2d78 247 UsbMouseAbsolutePointerDevice->DevicePath\r
37623a5c 248 );\r
249\r
67b8a9ce 250 Status = InitializeUsbMouseDevice (UsbMouseAbsolutePointerDevice);\r
09f72ae8 251 if (EFI_ERROR (Status)) {\r
67b8a9ce 252 //\r
253 // Fail to initialize USB mouse device.\r
254 //\r
255 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
09f72ae8 256 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
f9876ecf 257 (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INTERFACE_ERROR),\r
67b8a9ce 258 UsbMouseAbsolutePointerDevice->DevicePath\r
09f72ae8 259 );\r
260\r
261 goto ErrorExit;\r
262 }\r
263\r
67b8a9ce 264 //\r
265 // Initialize and install EFI Absolute Pointer Protocol.\r
266 //\r
09f72ae8 267 UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.GetState = GetMouseAbsolutePointerState;\r
d1102dba 268 UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.Reset = UsbMouseAbsolutePointerReset;\r
1436aea4 269 UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.Mode = &UsbMouseAbsolutePointerDevice->Mode;\r
09f72ae8 270\r
271 Status = gBS->CreateEvent (\r
67b8a9ce 272 EVT_NOTIFY_WAIT,\r
273 TPL_NOTIFY,\r
274 UsbMouseAbsolutePointerWaitForInput,\r
275 UsbMouseAbsolutePointerDevice,\r
276 &((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput)\r
277 );\r
09f72ae8 278 if (EFI_ERROR (Status)) {\r
279 goto ErrorExit;\r
280 }\r
281\r
282 Status = gBS->InstallProtocolInterface (\r
67b8a9ce 283 &Controller,\r
284 &gEfiAbsolutePointerProtocolGuid,\r
285 EFI_NATIVE_INTERFACE,\r
286 &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol\r
287 );\r
09f72ae8 288\r
289 if (EFI_ERROR (Status)) {\r
09f72ae8 290 goto ErrorExit;\r
291 }\r
292\r
293 //\r
67b8a9ce 294 // The next step would be submitting Asynchronous Interrupt Transfer on this mouse device.\r
295 // After that we will be able to get key data from it. Thus this is deemed as\r
296 // the enable action of the mouse, so report status code accordingly.\r
09f72ae8 297 //\r
67b8a9ce 298 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
09f72ae8 299 EFI_PROGRESS_CODE,\r
f9876ecf 300 (EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE),\r
67b8a9ce 301 UsbMouseAbsolutePointerDevice->DevicePath\r
09f72ae8 302 );\r
303\r
304 //\r
67b8a9ce 305 // Submit Asynchronous Interrupt Transfer to manage this device.\r
09f72ae8 306 //\r
67b8a9ce 307 EndpointAddr = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress;\r
308 PollingInterval = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.Interval;\r
1436aea4 309 PacketSize = (UINT8)(UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.MaxPacketSize);\r
09f72ae8 310\r
311 Status = UsbIo->UsbAsyncInterruptTransfer (\r
312 UsbIo,\r
313 EndpointAddr,\r
314 TRUE,\r
315 PollingInterval,\r
316 PacketSize,\r
67b8a9ce 317 OnMouseInterruptComplete,\r
09f72ae8 318 UsbMouseAbsolutePointerDevice\r
319 );\r
320\r
67b8a9ce 321 if (EFI_ERROR (Status)) {\r
322 //\r
323 // If submit error, uninstall that interface\r
324 //\r
325 gBS->UninstallProtocolInterface (\r
326 Controller,\r
327 &gEfiAbsolutePointerProtocolGuid,\r
328 &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol\r
329 );\r
330 goto ErrorExit;\r
331 }\r
09f72ae8 332\r
67b8a9ce 333 UsbMouseAbsolutePointerDevice->ControllerNameTable = NULL;\r
334 AddUnicodeString2 (\r
335 "eng",\r
336 gUsbMouseAbsolutePointerComponentName.SupportedLanguages,\r
337 &UsbMouseAbsolutePointerDevice->ControllerNameTable,\r
338 L"Generic Usb Mouse Absolute Pointer",\r
1436aea4
MK
339 TRUE\r
340 );\r
67b8a9ce 341 AddUnicodeString2 (\r
342 "en",\r
343 gUsbMouseAbsolutePointerComponentName2.SupportedLanguages,\r
344 &UsbMouseAbsolutePointerDevice->ControllerNameTable,\r
345 L"Generic Usb Mouse Absolute Pointer",\r
346 FALSE\r
347 );\r
09f72ae8 348\r
15cc67e6 349 gBS->RestoreTPL (OldTpl);\r
67b8a9ce 350 return EFI_SUCCESS;\r
09f72ae8 351\r
1436aea4
MK
352 //\r
353 // Error handler\r
354 //\r
09f72ae8 355ErrorExit:\r
356 if (EFI_ERROR (Status)) {\r
357 gBS->CloseProtocol (\r
1436aea4
MK
358 Controller,\r
359 &gEfiUsbIoProtocolGuid,\r
360 This->DriverBindingHandle,\r
361 Controller\r
362 );\r
09f72ae8 363\r
364 if (UsbMouseAbsolutePointerDevice != NULL) {\r
09f72ae8 365 if ((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput != NULL) {\r
366 gBS->CloseEvent ((UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol).WaitForInput);\r
367 }\r
368\r
67b8a9ce 369 FreePool (UsbMouseAbsolutePointerDevice);\r
09f72ae8 370 UsbMouseAbsolutePointerDevice = NULL;\r
371 }\r
372 }\r
373\r
15cc67e6 374ErrorExit1:\r
375 gBS->RestoreTPL (OldTpl);\r
376\r
09f72ae8 377 return Status;\r
378}\r
379\r
09f72ae8 380/**\r
67b8a9ce 381 Stop the USB mouse device handled by this driver.\r
09f72ae8 382\r
67b8a9ce 383 @param This The driver binding protocol.\r
384 @param Controller The controller to release.\r
385 @param NumberOfChildren The number of handles in ChildHandleBuffer.\r
386 @param ChildHandleBuffer The array of child handle.\r
09f72ae8 387\r
67b8a9ce 388 @retval EFI_SUCCESS The device was stopped.\r
389 @retval EFI_UNSUPPORTED Absolute Pointer Protocol is not installed on Controller.\r
390 @retval Others Fail to uninstall protocols attached on the device.\r
09f72ae8 391\r
392**/\r
393EFI_STATUS\r
394EFIAPI\r
395USBMouseAbsolutePointerDriverBindingStop (\r
1436aea4
MK
396 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
397 IN EFI_HANDLE Controller,\r
398 IN UINTN NumberOfChildren,\r
399 IN EFI_HANDLE *ChildHandleBuffer\r
09f72ae8 400 )\r
401{\r
67b8a9ce 402 EFI_STATUS Status;\r
403 USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice;\r
404 EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol;\r
405 EFI_USB_IO_PROTOCOL *UsbIo;\r
09f72ae8 406\r
09f72ae8 407 Status = gBS->OpenProtocol (\r
67b8a9ce 408 Controller,\r
409 &gEfiAbsolutePointerProtocolGuid,\r
1436aea4 410 (VOID **)&AbsolutePointerProtocol,\r
67b8a9ce 411 This->DriverBindingHandle,\r
412 Controller,\r
413 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
414 );\r
09f72ae8 415\r
416 if (EFI_ERROR (Status)) {\r
67b8a9ce 417 return EFI_UNSUPPORTED;\r
09f72ae8 418 }\r
09f72ae8 419\r
67b8a9ce 420 UsbMouseAbsolutePointerDevice = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (AbsolutePointerProtocol);\r
09f72ae8 421\r
422 UsbIo = UsbMouseAbsolutePointerDevice->UsbIo;\r
423\r
424 //\r
67b8a9ce 425 // The key data input from this device will be disabled.\r
09f72ae8 426 //\r
67b8a9ce 427 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
09f72ae8 428 EFI_PROGRESS_CODE,\r
f9876ecf 429 (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE),\r
67b8a9ce 430 UsbMouseAbsolutePointerDevice->DevicePath\r
09f72ae8 431 );\r
432\r
433 //\r
67b8a9ce 434 // Delete the Asynchronous Interrupt Transfer from this device\r
09f72ae8 435 //\r
436 UsbIo->UsbAsyncInterruptTransfer (\r
67b8a9ce 437 UsbIo,\r
438 UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress,\r
439 FALSE,\r
440 UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.Interval,\r
441 0,\r
442 NULL,\r
443 NULL\r
444 );\r
09f72ae8 445\r
446 Status = gBS->UninstallProtocolInterface (\r
447 Controller,\r
448 &gEfiAbsolutePointerProtocolGuid,\r
449 &UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol\r
450 );\r
451 if (EFI_ERROR (Status)) {\r
452 return Status;\r
453 }\r
454\r
455 gBS->CloseProtocol (\r
67b8a9ce 456 Controller,\r
457 &gEfiUsbIoProtocolGuid,\r
458 This->DriverBindingHandle,\r
459 Controller\r
460 );\r
09f72ae8 461\r
67b8a9ce 462 //\r
463 // Free all resources.\r
464 //\r
465 gBS->CloseEvent (UsbMouseAbsolutePointerDevice->AbsolutePointerProtocol.WaitForInput);\r
d1102dba 466\r
67b8a9ce 467 if (UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent != NULL) {\r
468 gBS->CloseEvent (UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent);\r
469 UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent = NULL;\r
470 }\r
09f72ae8 471\r
67b8a9ce 472 if (UsbMouseAbsolutePointerDevice->ControllerNameTable != NULL) {\r
09f72ae8 473 FreeUnicodeStringTable (UsbMouseAbsolutePointerDevice->ControllerNameTable);\r
474 }\r
475\r
67b8a9ce 476 FreePool (UsbMouseAbsolutePointerDevice);\r
09f72ae8 477\r
478 return EFI_SUCCESS;\r
09f72ae8 479}\r
480\r
09f72ae8 481/**\r
67b8a9ce 482 Uses USB I/O to check whether the device is a USB mouse device.\r
09f72ae8 483\r
67b8a9ce 484 @param UsbIo Pointer to a USB I/O protocol instance.\r
09f72ae8 485\r
67b8a9ce 486 @retval TRUE Device is a USB mouse device.\r
487 @retval FALSE Device is a not USB mouse device.\r
09f72ae8 488\r
489**/\r
490BOOLEAN\r
67b8a9ce 491IsUsbMouse (\r
1436aea4 492 IN EFI_USB_IO_PROTOCOL *UsbIo\r
09f72ae8 493 )\r
494{\r
495 EFI_STATUS Status;\r
496 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;\r
497\r
498 //\r
67b8a9ce 499 // Get the default interface descriptor\r
09f72ae8 500 //\r
501 Status = UsbIo->UsbGetInterfaceDescriptor (\r
502 UsbIo,\r
503 &InterfaceDescriptor\r
504 );\r
505\r
506 if (EFI_ERROR (Status)) {\r
507 return FALSE;\r
508 }\r
509\r
510 if ((InterfaceDescriptor.InterfaceClass == CLASS_HID) &&\r
511 (InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT) &&\r
512 (InterfaceDescriptor.InterfaceProtocol == PROTOCOL_MOUSE)\r
1436aea4
MK
513 )\r
514 {\r
09f72ae8 515 return TRUE;\r
516 }\r
517\r
518 return FALSE;\r
519}\r
520\r
09f72ae8 521/**\r
67b8a9ce 522 Initialize the USB mouse device.\r
09f72ae8 523\r
67b8a9ce 524 This function retrieves and parses HID report descriptor, and\r
525 initializes state of USB_MOUSE_ABSOLUTE_POINTER_DEV. Then it sets indefinite idle\r
526 rate for the device. Finally it creates event for delayed recovery,\r
527 which deals with device error.\r
09f72ae8 528\r
67b8a9ce 529 @param UsbMouseAbsolutePointerDev Device instance to be initialized.\r
530\r
531 @retval EFI_SUCCESS USB mouse device successfully initialized.\r
532 @retval EFI_UNSUPPORTED HID descriptor type is not report descriptor.\r
533 @retval Other USB mouse device was not initialized successfully.\r
09f72ae8 534\r
535**/\r
09f72ae8 536EFI_STATUS\r
67b8a9ce 537InitializeUsbMouseDevice (\r
1436aea4 538 IN USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev\r
09f72ae8 539 )\r
540{\r
1436aea4
MK
541 EFI_USB_IO_PROTOCOL *UsbIo;\r
542 UINT8 Protocol;\r
543 EFI_STATUS Status;\r
544 EFI_USB_HID_DESCRIPTOR *MouseHidDesc;\r
545 UINT8 *ReportDesc;\r
546 EFI_USB_CONFIG_DESCRIPTOR ConfigDesc;\r
547 VOID *Buf;\r
548 UINT32 TransferResult;\r
549 UINT16 Total;\r
550 USB_DESC_HEAD *Head;\r
551 BOOLEAN Start;\r
09f72ae8 552\r
553 UsbIo = UsbMouseAbsolutePointerDev->UsbIo;\r
554\r
555 //\r
0309b719 556 // Get the current configuration descriptor. Note that it doesn't include other descriptors.\r
09f72ae8 557 //\r
0309b719 558 Status = UsbIo->UsbGetConfigDescriptor (\r
559 UsbIo,\r
560 &ConfigDesc\r
561 );\r
562 if (EFI_ERROR (Status)) {\r
563 return Status;\r
564 }\r
565\r
566 //\r
567 // By issuing Get_Descriptor(Configuration) request with total length, we get the Configuration descriptor,\r
568 // all Interface descriptors, all Endpoint descriptors, and the HID descriptor for each interface.\r
569 //\r
570 Buf = AllocateZeroPool (ConfigDesc.TotalLength);\r
571 if (Buf == NULL) {\r
572 return EFI_OUT_OF_RESOURCES;\r
573 }\r
574\r
575 Status = UsbGetDescriptor (\r
67b8a9ce 576 UsbIo,\r
0309b719 577 (UINT16)((USB_DESC_TYPE_CONFIG << 8) | (ConfigDesc.ConfigurationValue - 1)),\r
578 0,\r
579 ConfigDesc.TotalLength,\r
580 Buf,\r
581 &TransferResult\r
67b8a9ce 582 );\r
09f72ae8 583 if (EFI_ERROR (Status)) {\r
0309b719 584 FreePool (Buf);\r
09f72ae8 585 return Status;\r
586 }\r
587\r
1436aea4
MK
588 Total = 0;\r
589 Start = FALSE;\r
590 Head = (USB_DESC_HEAD *)Buf;\r
0309b719 591 MouseHidDesc = NULL;\r
592\r
593 //\r
594 // Get HID descriptor from the receipt of Get_Descriptor(Configuration) request.\r
595 // This algorithm is based on the fact that the HID descriptor shall be interleaved\r
596 // between the interface and endpoint descriptors for HID interfaces.\r
597 //\r
598 while (Total < ConfigDesc.TotalLength) {\r
599 if (Head->Type == USB_DESC_TYPE_INTERFACE) {\r
600 if ((((USB_INTERFACE_DESCRIPTOR *)Head)->InterfaceNumber == UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber) &&\r
1436aea4
MK
601 (((USB_INTERFACE_DESCRIPTOR *)Head)->AlternateSetting == UsbMouseAbsolutePointerDev->InterfaceDescriptor.AlternateSetting))\r
602 {\r
0309b719 603 Start = TRUE;\r
604 }\r
605 }\r
1436aea4 606\r
af3a71b8 607 if (Start && (Head->Type == USB_DESC_TYPE_ENDPOINT)) {\r
0309b719 608 break;\r
609 }\r
1436aea4 610\r
af3a71b8 611 if (Start && (Head->Type == USB_DESC_TYPE_HID)) {\r
0309b719 612 MouseHidDesc = (EFI_USB_HID_DESCRIPTOR *)Head;\r
613 break;\r
614 }\r
1436aea4 615\r
ab742719 616 Total = Total + (UINT16)Head->Len;\r
1436aea4 617 Head = (USB_DESC_HEAD *)((UINT8 *)Buf + Total);\r
0309b719 618 }\r
619\r
620 if (MouseHidDesc == NULL) {\r
621 FreePool (Buf);\r
622 return EFI_UNSUPPORTED;\r
623 }\r
624\r
09f72ae8 625 //\r
67b8a9ce 626 // Get report descriptor\r
09f72ae8 627 //\r
0309b719 628 if (MouseHidDesc->HidClassDesc[0].DescriptorType != USB_DESC_TYPE_REPORT) {\r
629 FreePool (Buf);\r
09f72ae8 630 return EFI_UNSUPPORTED;\r
631 }\r
632\r
0309b719 633 ReportDesc = AllocateZeroPool (MouseHidDesc->HidClassDesc[0].DescriptorLength);\r
67b8a9ce 634 ASSERT (ReportDesc != NULL);\r
09f72ae8 635\r
636 Status = UsbGetReportDescriptor (\r
67b8a9ce 637 UsbIo,\r
638 UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,\r
0309b719 639 MouseHidDesc->HidClassDesc[0].DescriptorLength,\r
67b8a9ce 640 ReportDesc\r
641 );\r
09f72ae8 642\r
643 if (EFI_ERROR (Status)) {\r
0309b719 644 FreePool (Buf);\r
67b8a9ce 645 FreePool (ReportDesc);\r
09f72ae8 646 return Status;\r
647 }\r
648\r
649 //\r
650 // Parse report descriptor\r
651 //\r
652 Status = ParseMouseReportDescriptor (\r
67b8a9ce 653 UsbMouseAbsolutePointerDev,\r
654 ReportDesc,\r
0309b719 655 MouseHidDesc->HidClassDesc[0].DescriptorLength\r
67b8a9ce 656 );\r
09f72ae8 657\r
658 if (EFI_ERROR (Status)) {\r
0309b719 659 FreePool (Buf);\r
67b8a9ce 660 FreePool (ReportDesc);\r
09f72ae8 661 return Status;\r
662 }\r
663\r
67b8a9ce 664 UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxX = 1024;\r
665 UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxY = 1024;\r
666 UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxZ = 0;\r
667 UsbMouseAbsolutePointerDev->Mode.AbsoluteMinX = 0;\r
668 UsbMouseAbsolutePointerDev->Mode.AbsoluteMinY = 0;\r
669 UsbMouseAbsolutePointerDev->Mode.AbsoluteMinZ = 0;\r
670 UsbMouseAbsolutePointerDev->Mode.Attributes = 0x3;\r
09c777c6
RN
671\r
672 //\r
673 // Let the cursor's starting position is in the center of the screen.\r
674 //\r
675 UsbMouseAbsolutePointerDev->State.CurrentX =\r
5ea43771 676 DivU64x32 (UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxX + UsbMouseAbsolutePointerDev->Mode.AbsoluteMinX, 2);\r
09c777c6 677 UsbMouseAbsolutePointerDev->State.CurrentY =\r
5ea43771 678 DivU64x32 (UsbMouseAbsolutePointerDev->Mode.AbsoluteMaxY + UsbMouseAbsolutePointerDev->Mode.AbsoluteMinY, 2);\r
09c777c6 679\r
09f72ae8 680 //\r
67b8a9ce 681 // Set boot protocol for the USB mouse.\r
682 // This driver only supports boot protocol.\r
09f72ae8 683 //\r
684 UsbGetProtocolRequest (\r
685 UsbIo,\r
67b8a9ce 686 UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,\r
09f72ae8 687 &Protocol\r
688 );\r
09f72ae8 689 if (Protocol != BOOT_PROTOCOL) {\r
690 Status = UsbSetProtocolRequest (\r
67b8a9ce 691 UsbIo,\r
83040701 692 UsbMouseAbsolutePointerDev->InterfaceDescriptor.InterfaceNumber,\r
67b8a9ce 693 BOOT_PROTOCOL\r
694 );\r
09f72ae8 695\r
696 if (EFI_ERROR (Status)) {\r
0309b719 697 FreePool (Buf);\r
67b8a9ce 698 FreePool (ReportDesc);\r
699 return Status;\r
09f72ae8 700 }\r
701 }\r
702\r
0309b719 703 FreePool (Buf);\r
67b8a9ce 704 FreePool (ReportDesc);\r
09f72ae8 705\r
67b8a9ce 706 //\r
707 // Create event for delayed recovery, which deals with device error.\r
708 //\r
709 if (UsbMouseAbsolutePointerDev->DelayedRecoveryEvent != NULL) {\r
09f72ae8 710 gBS->CloseEvent (UsbMouseAbsolutePointerDev->DelayedRecoveryEvent);\r
711 UsbMouseAbsolutePointerDev->DelayedRecoveryEvent = 0;\r
712 }\r
713\r
67b8a9ce 714 gBS->CreateEvent (\r
715 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
716 TPL_NOTIFY,\r
717 USBMouseRecoveryHandler,\r
718 UsbMouseAbsolutePointerDev,\r
719 &UsbMouseAbsolutePointerDev->DelayedRecoveryEvent\r
720 );\r
09f72ae8 721\r
722 return EFI_SUCCESS;\r
723}\r
724\r
09f72ae8 725/**\r
67b8a9ce 726 Handler function for USB mouse's asynchronous interrupt transfer.\r
727\r
728 This function is the handler function for USB mouse's asynchronous interrupt transfer\r
729 to manage the mouse. It parses data returned from asynchronous interrupt transfer, and\r
730 get button and movement state.\r
09f72ae8 731\r
67b8a9ce 732 @param Data A pointer to a buffer that is filled with key data which is\r
733 retrieved via asynchronous interrupt transfer.\r
734 @param DataLength Indicates the size of the data buffer.\r
735 @param Context Pointing to USB_KB_DEV instance.\r
736 @param Result Indicates the result of the asynchronous interrupt transfer.\r
09f72ae8 737\r
67b8a9ce 738 @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.\r
739 @retval EFI_DEVICE_ERROR Hardware error occurs.\r
09f72ae8 740\r
741**/\r
09f72ae8 742EFI_STATUS\r
743EFIAPI\r
67b8a9ce 744OnMouseInterruptComplete (\r
1436aea4
MK
745 IN VOID *Data,\r
746 IN UINTN DataLength,\r
747 IN VOID *Context,\r
748 IN UINT32 Result\r
09f72ae8 749 )\r
750{\r
1436aea4
MK
751 USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice;\r
752 EFI_USB_IO_PROTOCOL *UsbIo;\r
753 UINT8 EndpointAddr;\r
754 UINT32 UsbResult;\r
09f72ae8 755\r
1436aea4
MK
756 UsbMouseAbsolutePointerDevice = (USB_MOUSE_ABSOLUTE_POINTER_DEV *)Context;\r
757 UsbIo = UsbMouseAbsolutePointerDevice->UsbIo;\r
09f72ae8 758\r
759 if (Result != EFI_USB_NOERROR) {\r
760 //\r
761 // Some errors happen during the process\r
762 //\r
67b8a9ce 763 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
09f72ae8 764 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
f9876ecf 765 (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INPUT_ERROR),\r
67b8a9ce 766 UsbMouseAbsolutePointerDevice->DevicePath\r
09f72ae8 767 );\r
768\r
769 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
67b8a9ce 770 EndpointAddr = UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress;\r
09f72ae8 771\r
772 UsbClearEndpointHalt (\r
773 UsbIo,\r
774 EndpointAddr,\r
775 &UsbResult\r
776 );\r
777 }\r
778\r
67b8a9ce 779 //\r
780 // Delete & Submit this interrupt again\r
d1102dba 781 // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.\r
67b8a9ce 782 //\r
09f72ae8 783 UsbIo->UsbAsyncInterruptTransfer (\r
67b8a9ce 784 UsbIo,\r
785 UsbMouseAbsolutePointerDevice->IntEndpointDescriptor.EndpointAddress,\r
786 FALSE,\r
787 0,\r
788 0,\r
789 NULL,\r
790 NULL\r
791 );\r
792 //\r
793 // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.\r
794 //\r
09f72ae8 795 gBS->SetTimer (\r
67b8a9ce 796 UsbMouseAbsolutePointerDevice->DelayedRecoveryEvent,\r
797 TimerRelative,\r
798 EFI_USB_INTERRUPT_DELAY\r
799 );\r
09f72ae8 800 return EFI_DEVICE_ERROR;\r
801 }\r
802\r
67b8a9ce 803 //\r
804 // If no error and no data, just return EFI_SUCCESS.\r
805 //\r
1436aea4 806 if ((DataLength == 0) || (Data == NULL)) {\r
09f72ae8 807 return EFI_SUCCESS;\r
808 }\r
809\r
810 //\r
67b8a9ce 811 // Check mouse Data\r
812 // USB HID Specification specifies following data format:\r
813 // Byte Bits Description\r
814 // 0 0 Button 1\r
815 // 1 Button 2\r
816 // 2 Button 3\r
817 // 4 to 7 Device-specific\r
818 // 1 0 to 7 X displacement\r
819 // 2 0 to 7 Y displacement\r
820 // 3 to n 0 to 7 Device specific (optional)\r
09f72ae8 821 //\r
0dd60655
RN
822 if (DataLength < 3) {\r
823 return EFI_DEVICE_ERROR;\r
824 }\r
825\r
826 UsbMouseAbsolutePointerDevice->StateChanged = TRUE;\r
827\r
1436aea4 828 UsbMouseAbsolutePointerDevice->State.ActiveButtons = *(UINT8 *)Data & (BIT0 | BIT1 | BIT2);\r
09c777c6
RN
829\r
830 UsbMouseAbsolutePointerDevice->State.CurrentX =\r
831 MIN (\r
1436aea4
MK
832 MAX (\r
833 (INT64)UsbMouseAbsolutePointerDevice->State.CurrentX + *((INT8 *)Data + 1),\r
834 (INT64)UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinX\r
835 ),\r
836 (INT64)UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxX\r
09c777c6
RN
837 );\r
838 UsbMouseAbsolutePointerDevice->State.CurrentY =\r
839 MIN (\r
1436aea4
MK
840 MAX (\r
841 (INT64)UsbMouseAbsolutePointerDevice->State.CurrentY + *((INT8 *)Data + 2),\r
842 (INT64)UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinY\r
843 ),\r
844 (INT64)UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxY\r
09c777c6 845 );\r
09f72ae8 846 if (DataLength > 3) {\r
09c777c6
RN
847 UsbMouseAbsolutePointerDevice->State.CurrentZ =\r
848 MIN (\r
1436aea4
MK
849 MAX (\r
850 (INT64)UsbMouseAbsolutePointerDevice->State.CurrentZ + *((INT8 *)Data + 1),\r
851 (INT64)UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinZ\r
852 ),\r
853 (INT64)UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxZ\r
09c777c6 854 );\r
09f72ae8 855 }\r
09f72ae8 856\r
857 return EFI_SUCCESS;\r
858}\r
859\r
860/**\r
67b8a9ce 861 Retrieves the current state of a pointer device.\r
09f72ae8 862\r
d1102dba 863 @param This A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.\r
67b8a9ce 864 @param MouseState A pointer to the state information on the pointer device.\r
09f72ae8 865\r
67b8a9ce 866 @retval EFI_SUCCESS The state of the pointer device was returned in State.\r
867 @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to\r
d1102dba 868 GetState().\r
67b8a9ce 869 @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's\r
d1102dba
LG
870 current state.\r
871 @retval EFI_INVALID_PARAMETER State is NULL.\r
09f72ae8 872\r
873**/\r
09f72ae8 874EFI_STATUS\r
875EFIAPI\r
876GetMouseAbsolutePointerState (\r
877 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
67b8a9ce 878 OUT EFI_ABSOLUTE_POINTER_STATE *State\r
09f72ae8 879 )\r
880{\r
1436aea4 881 USB_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;\r
09f72ae8 882\r
67b8a9ce 883 if (State == NULL) {\r
884 return EFI_INVALID_PARAMETER;\r
09f72ae8 885 }\r
886\r
887 MouseAbsolutePointerDev = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (This);\r
888\r
67b8a9ce 889 if (!MouseAbsolutePointerDev->StateChanged) {\r
09f72ae8 890 return EFI_NOT_READY;\r
891 }\r
892\r
67b8a9ce 893 //\r
894 // Retrieve mouse state from USB_MOUSE_ABSOLUTE_POINTER_DEV,\r
895 // which was filled by OnMouseInterruptComplete()\r
896 //\r
09f72ae8 897 CopyMem (\r
67b8a9ce 898 State,\r
899 &MouseAbsolutePointerDev->State,\r
09f72ae8 900 sizeof (EFI_ABSOLUTE_POINTER_STATE)\r
901 );\r
902\r
67b8a9ce 903 MouseAbsolutePointerDev->StateChanged = FALSE;\r
09f72ae8 904\r
905 return EFI_SUCCESS;\r
906}\r
907\r
09f72ae8 908/**\r
67b8a9ce 909 Resets the pointer device hardware.\r
09f72ae8 910\r
67b8a9ce 911 @param This A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.\r
912 @param ExtendedVerification Indicates that the driver may perform a more exhaustive\r
913 verification operation of the device during reset.\r
09f72ae8 914\r
67b8a9ce 915 @retval EFI_SUCCESS The device was reset.\r
916 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.\r
09f72ae8 917\r
918**/\r
09f72ae8 919EFI_STATUS\r
920EFIAPI\r
921UsbMouseAbsolutePointerReset (\r
67b8a9ce 922 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
09f72ae8 923 IN BOOLEAN ExtendedVerification\r
924 )\r
925{\r
1436aea4 926 USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDevice;\r
09f72ae8 927\r
1436aea4 928 UsbMouseAbsolutePointerDevice = USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL (This);\r
09f72ae8 929\r
67b8a9ce 930 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
09f72ae8 931 EFI_PROGRESS_CODE,\r
f9876ecf 932 (EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET),\r
67b8a9ce 933 UsbMouseAbsolutePointerDevice->DevicePath\r
09f72ae8 934 );\r
935\r
67b8a9ce 936 //\r
937 // Clear mouse state.\r
938 //\r
09f72ae8 939 ZeroMem (\r
67b8a9ce 940 &UsbMouseAbsolutePointerDevice->State,\r
09f72ae8 941 sizeof (EFI_ABSOLUTE_POINTER_STATE)\r
942 );\r
09c777c6
RN
943\r
944 //\r
945 // Let the cursor's starting position is in the center of the screen.\r
946 //\r
947 UsbMouseAbsolutePointerDevice->State.CurrentX =\r
5ea43771 948 DivU64x32 (UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxX + UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinX, 2);\r
09c777c6 949 UsbMouseAbsolutePointerDevice->State.CurrentY =\r
5ea43771 950 DivU64x32 (UsbMouseAbsolutePointerDevice->Mode.AbsoluteMaxY + UsbMouseAbsolutePointerDevice->Mode.AbsoluteMinY, 2);\r
09c777c6 951\r
67b8a9ce 952 UsbMouseAbsolutePointerDevice->StateChanged = FALSE;\r
09f72ae8 953\r
954 return EFI_SUCCESS;\r
955}\r
956\r
957/**\r
67b8a9ce 958 Event notification function for EFI_ABSOLUTE_POINTER_PROTOCOL.WaitForInput event.\r
09f72ae8 959\r
67b8a9ce 960 @param Event Event to be signaled when there's input from mouse.\r
961 @param Context Points to USB_MOUSE_ABSOLUTE_POINTER_DEV instance.\r
09f72ae8 962\r
963**/\r
09f72ae8 964VOID\r
965EFIAPI\r
966UsbMouseAbsolutePointerWaitForInput (\r
1436aea4
MK
967 IN EFI_EVENT Event,\r
968 IN VOID *Context\r
09f72ae8 969 )\r
970{\r
1436aea4 971 USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev;\r
09f72ae8 972\r
1436aea4 973 UsbMouseAbsolutePointerDev = (USB_MOUSE_ABSOLUTE_POINTER_DEV *)Context;\r
09f72ae8 974\r
975 //\r
67b8a9ce 976 // If there's input from mouse, signal the event.\r
09f72ae8 977 //\r
67b8a9ce 978 if (UsbMouseAbsolutePointerDev->StateChanged) {\r
09f72ae8 979 gBS->SignalEvent (Event);\r
980 }\r
981}\r
982\r
983/**\r
67b8a9ce 984 Handler for Delayed Recovery event.\r
09f72ae8 985\r
67b8a9ce 986 This function is the handler for Delayed Recovery event triggered\r
987 by timer.\r
988 After a device error occurs, the event would be triggered\r
989 with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY\r
990 is defined in USB standard for error handling.\r
09f72ae8 991\r
67b8a9ce 992 @param Event The Delayed Recovery event.\r
993 @param Context Points to the USB_MOUSE_ABSOLUTE_POINTER_DEV instance.\r
09f72ae8 994\r
995**/\r
996VOID\r
997EFIAPI\r
67b8a9ce 998USBMouseRecoveryHandler (\r
1436aea4
MK
999 IN EFI_EVENT Event,\r
1000 IN VOID *Context\r
09f72ae8 1001 )\r
1002{\r
1436aea4
MK
1003 USB_MOUSE_ABSOLUTE_POINTER_DEV *UsbMouseAbsolutePointerDev;\r
1004 EFI_USB_IO_PROTOCOL *UsbIo;\r
09f72ae8 1005\r
1436aea4 1006 UsbMouseAbsolutePointerDev = (USB_MOUSE_ABSOLUTE_POINTER_DEV *)Context;\r
09f72ae8 1007\r
1436aea4 1008 UsbIo = UsbMouseAbsolutePointerDev->UsbIo;\r
09f72ae8 1009\r
67b8a9ce 1010 //\r
1011 // Re-submit Asynchronous Interrupt Transfer for recovery.\r
1012 //\r
09f72ae8 1013 UsbIo->UsbAsyncInterruptTransfer (\r
67b8a9ce 1014 UsbIo,\r
1015 UsbMouseAbsolutePointerDev->IntEndpointDescriptor.EndpointAddress,\r
1016 TRUE,\r
1017 UsbMouseAbsolutePointerDev->IntEndpointDescriptor.Interval,\r
1018 UsbMouseAbsolutePointerDev->IntEndpointDescriptor.MaxPacketSize,\r
1019 OnMouseInterruptComplete,\r
1020 UsbMouseAbsolutePointerDev\r
1021 );\r
09f72ae8 1022}\r