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