]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbMouseSimulateTouchPadDxe/UsbMouseSimulateTouchPad.c
delete a debug output to pass through EBC build and align some line to conform with...
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbMouseSimulateTouchPadDxe / UsbMouseSimulateTouchPad.c
CommitLineData
8ae0b360 1/** @file\r
2\r
3Copyright (c) 2004 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12 Module Name:\r
13\r
14 UsbMouseSimulateTouchPad.c\r
15\r
16 Abstract:\r
17\r
18\r
19**/\r
20\r
21#include "UsbMouseSimulateTouchPad.h"\r
22\r
23#include <Library/DebugLib.h>\r
24#include <IndustryStandard/Usb.h>\r
25\r
26#include "mousehid.h"\r
27\r
28//\r
29// Prototypes\r
30// Driver model protocol interface\r
31//\r
32EFI_STATUS\r
33EFIAPI\r
34USBMouseSimulateTouchPadDriverBindingEntryPoint (\r
35 IN EFI_HANDLE ImageHandle,\r
36 IN EFI_SYSTEM_TABLE *SystemTable\r
37 );\r
38\r
39EFI_STATUS\r
40EFIAPI\r
41USBMouseSimulateTouchPadDriverBindingSupported (\r
42 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
43 IN EFI_HANDLE Controller,\r
44 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
45 );\r
46\r
47EFI_STATUS\r
48EFIAPI\r
49USBMouseSimulateTouchPadDriverBindingStart (\r
50 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
51 IN EFI_HANDLE Controller,\r
52 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
53 );\r
54\r
55EFI_STATUS\r
56EFIAPI\r
57USBMouseSimulateTouchPadDriverBindingStop (\r
58 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
59 IN EFI_HANDLE Controller,\r
60 IN UINTN NumberOfChildren,\r
61 IN EFI_HANDLE *ChildHandleBuffer\r
62 );\r
63\r
64EFI_GUID gEfiUsbMouseSimulateTouchPadDriverGuid = {\r
65 0xa579f729, 0xa71d, 0x4b45, { 0xbe, 0xd7, 0xd, 0xb0, 0xa8, 0x7c, 0x3e, 0x8d }\r
66};\r
67\r
68EFI_DRIVER_BINDING_PROTOCOL gUsbMouseSimulateTouchPadDriverBinding = {\r
69 USBMouseSimulateTouchPadDriverBindingSupported,\r
70 USBMouseSimulateTouchPadDriverBindingStart,\r
71 USBMouseSimulateTouchPadDriverBindingStop,\r
72 0x1,\r
73 NULL,\r
74 NULL\r
75};\r
76\r
77//\r
78// helper functions\r
79//\r
80STATIC\r
81BOOLEAN\r
82IsUsbMouseSimulateTouchPad (\r
83 IN EFI_USB_IO_PROTOCOL *UsbIo\r
84 );\r
85\r
86STATIC\r
87EFI_STATUS\r
88InitializeUsbMouseSimulateTouchPadDevice (\r
89 IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev\r
90 );\r
91\r
92STATIC\r
93VOID\r
94EFIAPI\r
95UsbMouseSimulateTouchPadWaitForInput (\r
96 IN EFI_EVENT Event,\r
97 IN VOID *Context\r
98 );\r
99\r
100//\r
101// Mouse interrupt handler\r
102//\r
103STATIC\r
104EFI_STATUS\r
105EFIAPI\r
106OnMouseSimulateTouchPadInterruptComplete (\r
107 IN VOID *Data,\r
108 IN UINTN DataLength,\r
109 IN VOID *Context,\r
110 IN UINT32 Result\r
111 );\r
112\r
113//\r
114// Mouse simulate TouchPad, Using AbsolutePointer Protocol\r
115//\r
116STATIC\r
117EFI_STATUS\r
118EFIAPI\r
119GetMouseSimulateTouchPadState (\r
120 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
121 OUT EFI_ABSOLUTE_POINTER_STATE *MouseSimulateTouchPadState\r
122 );\r
123\r
124STATIC\r
125EFI_STATUS\r
126EFIAPI\r
127UsbMouseSimulateTouchPadReset (\r
128 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
129 IN BOOLEAN ExtendedVerification\r
130 );\r
131\r
132//\r
133// Driver start here\r
134//\r
135EFI_STATUS\r
136EFIAPI\r
137USBMouseSimulateTouchPadDriverBindingEntryPoint (\r
138 IN EFI_HANDLE ImageHandle,\r
139 IN EFI_SYSTEM_TABLE *SystemTable\r
140 )\r
141/*++\r
142\r
143 Routine Description:\r
144 Entry point for EFI drivers.\r
145\r
146 Arguments:\r
147 ImageHandle - EFI_HANDLE\r
148 SystemTable - EFI_SYSTEM_TABLE\r
149 Returns:\r
150 EFI_SUCCESS\r
151 others\r
152\r
153--*/\r
154{\r
155 return EfiLibInstallDriverBindingComponentName2 (\r
156 ImageHandle,\r
157 SystemTable,\r
158 &gUsbMouseSimulateTouchPadDriverBinding,\r
159 ImageHandle,\r
160 &gUsbMouseSimulateTouchPadComponentName,\r
161 &gUsbMouseSimulateTouchPadComponentName2\r
162 );\r
163}\r
164\r
165\r
166/**\r
167 Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
168 that has UsbHcProtocol installed will be supported.\r
169\r
170 @param This Protocol instance pointer.\r
171 @param Controller Handle of device to test\r
172 @param RemainingDevicePath Not used\r
173\r
174 @retval EFI_SUCCESS This driver supports this device.\r
175 @retval EFI_UNSUPPORTED This driver does not support this device.\r
176\r
177**/\r
178EFI_STATUS\r
179EFIAPI\r
180USBMouseSimulateTouchPadDriverBindingSupported (\r
181 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
182 IN EFI_HANDLE Controller,\r
183 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
184 )\r
185{\r
186 EFI_STATUS OpenStatus;\r
187 EFI_USB_IO_PROTOCOL *UsbIo;\r
188 EFI_STATUS Status;\r
189\r
190 OpenStatus = gBS->OpenProtocol (\r
191 Controller,\r
192 &gEfiUsbIoProtocolGuid,\r
193 (VOID **) &UsbIo,\r
194 This->DriverBindingHandle,\r
195 Controller,\r
196 EFI_OPEN_PROTOCOL_BY_DRIVER\r
197 );\r
198 if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {\r
199 return EFI_UNSUPPORTED;\r
200 }\r
201\r
202 if (OpenStatus == EFI_ALREADY_STARTED) {\r
203 return EFI_ALREADY_STARTED;\r
204 }\r
205 \r
206 //\r
207 // Use the USB I/O protocol interface to see the Controller is\r
208 // the Mouse controller that can be managed by this driver.\r
209 //\r
210 Status = EFI_SUCCESS;\r
211 if (!IsUsbMouseSimulateTouchPad (UsbIo)) {\r
212 Status = EFI_UNSUPPORTED;\r
213 }\r
214 \r
215 gBS->CloseProtocol (\r
216 Controller,\r
217 &gEfiUsbIoProtocolGuid,\r
218 This->DriverBindingHandle,\r
219 Controller\r
220 );\r
221 \r
222 return Status;\r
223}\r
224\r
225\r
226/**\r
227 Starting the Usb Bus Driver\r
228\r
229 @param This Protocol instance pointer.\r
230 @param Controller Handle of device to test\r
231 @param RemainingDevicePath Not used\r
232\r
233 @retval EFI_SUCCESS This driver supports this device.\r
234 @retval EFI_UNSUPPORTED This driver does not support this device.\r
235 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error\r
236 EFI_OUT_OF_RESOURCES- Can't allocate memory\r
237 resources\r
238 @retval EFI_ALREADY_STARTED Thios driver has been started\r
239\r
240**/\r
241EFI_STATUS\r
242EFIAPI\r
243USBMouseSimulateTouchPadDriverBindingStart (\r
244 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
245 IN EFI_HANDLE Controller,\r
246 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
247 )\r
248{\r
249 EFI_STATUS Status;\r
250 EFI_USB_IO_PROTOCOL *UsbIo;\r
251 EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc;\r
252 USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice;\r
253 UINT8 EndpointNumber;\r
254 UINT8 Index;\r
255 UINT8 EndpointAddr;\r
256 UINT8 PollingInterval;\r
257 UINT8 PacketSize;\r
258\r
259 UsbMouseSimulateTouchPadDevice = NULL;\r
260 Status = EFI_SUCCESS;\r
261\r
262 Status = gBS->OpenProtocol (\r
263 Controller,\r
264 &gEfiUsbIoProtocolGuid,\r
265 (VOID **) &UsbIo,\r
266 This->DriverBindingHandle,\r
267 Controller,\r
268 EFI_OPEN_PROTOCOL_BY_DRIVER \r
269 );\r
270 if (EFI_ERROR (Status)) {\r
271 goto ErrorExit;\r
272 }\r
273 \r
274 UsbMouseSimulateTouchPadDevice = AllocateZeroPool (sizeof (USB_MOUSE_SIMULATE_TOUCHPAD_DEV));\r
275 if (UsbMouseSimulateTouchPadDevice == NULL) {\r
276 Status = EFI_OUT_OF_RESOURCES;\r
277 goto ErrorExit;\r
278 }\r
279\r
280 UsbMouseSimulateTouchPadDevice->UsbIo = UsbIo;\r
281\r
282 UsbMouseSimulateTouchPadDevice->Signature = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_SIGNATURE;\r
283\r
284 UsbMouseSimulateTouchPadDevice->InterfaceDescriptor = AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR));\r
f74cc026 285\r
8ae0b360 286 if (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor == NULL) {\r
287 Status = EFI_OUT_OF_RESOURCES;\r
288 goto ErrorExit;\r
289 }\r
290\r
291 EndpointDesc = AllocatePool (sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));\r
292 if (EndpointDesc == NULL) {\r
293 Status = EFI_OUT_OF_RESOURCES;\r
294 goto ErrorExit;\r
295 }\r
296 //\r
297 // Get the Device Path Protocol on Controller's handle\r
298 //\r
299 Status = gBS->OpenProtocol (\r
300 Controller,\r
301 &gEfiDevicePathProtocolGuid,\r
302 (VOID **) &UsbMouseSimulateTouchPadDevice->DevicePath,\r
303 This->DriverBindingHandle,\r
304 Controller,\r
305 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
306 );\r
307\r
308 if (EFI_ERROR (Status)) {\r
309 goto ErrorExit;\r
310 }\r
311 //\r
312 // Get interface & endpoint descriptor\r
313 //\r
314 UsbIo->UsbGetInterfaceDescriptor (\r
315 UsbIo,\r
316 UsbMouseSimulateTouchPadDevice->InterfaceDescriptor\r
317 );\r
318\r
319 EndpointNumber = UsbMouseSimulateTouchPadDevice->InterfaceDescriptor->NumEndpoints;\r
320\r
321 for (Index = 0; Index < EndpointNumber; Index++) {\r
322 UsbIo->UsbGetEndpointDescriptor (\r
323 UsbIo,\r
324 Index,\r
325 EndpointDesc\r
326 );\r
327\r
328 if ((EndpointDesc->Attributes & 0x03) == 0x03) {\r
329\r
330 //\r
331 // We only care interrupt endpoint here\r
332 //\r
333 UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor = EndpointDesc;\r
334 }\r
335 }\r
336\r
337 if (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor == NULL) {\r
338 //\r
339 // No interrupt endpoint, then error\r
340 //\r
341 Status = EFI_UNSUPPORTED;\r
342 goto ErrorExit;\r
343 }\r
344\r
345 Status = InitializeUsbMouseSimulateTouchPadDevice (UsbMouseSimulateTouchPadDevice);\r
346 if (EFI_ERROR (Status)) {\r
347 MouseSimulateTouchPadReportStatusCode (\r
348 UsbMouseSimulateTouchPadDevice->DevicePath,\r
349 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
350 PcdGet32 (PcdStatusCodeValueMouseInterfaceError)\r
351 );\r
352\r
353 goto ErrorExit;\r
354 }\r
355\r
f74cc026 356 UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.GetState = GetMouseSimulateTouchPadState;\r
357 UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.Reset = UsbMouseSimulateTouchPadReset;\r
358 UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.Mode = &UsbMouseSimulateTouchPadDevice->AbsolutePointerMode;\r
359\r
360 Status = gBS->CreateEvent (\r
361 EVT_NOTIFY_WAIT,\r
362 TPL_NOTIFY,\r
363 UsbMouseSimulateTouchPadWaitForInput,\r
364 UsbMouseSimulateTouchPadDevice,\r
365 &((UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol).WaitForInput)\r
366 );\r
367 if (EFI_ERROR (Status)) {\r
368 goto ErrorExit;\r
369 }\r
370\r
371 Status = gBS->InstallProtocolInterface (\r
372 &Controller,\r
373 &gEfiAbsolutePointerProtocolGuid,\r
374 EFI_NATIVE_INTERFACE,\r
375 &UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol\r
376 );\r
377\r
378 if (EFI_ERROR (Status)) {\r
379 Status = EFI_DEVICE_ERROR;\r
380 goto ErrorExit;\r
381 }\r
8ae0b360 382\r
383 //\r
384 // After Enabling Async Interrupt Transfer on this mouse Device\r
385 // we will be able to get key data from it. Thus this is deemed as\r
386 // the enable action of the mouse\r
387 //\r
388\r
389 MouseSimulateTouchPadReportStatusCode (\r
390 UsbMouseSimulateTouchPadDevice->DevicePath,\r
391 EFI_PROGRESS_CODE,\r
392 PcdGet32 (PcdStatusCodeValueMouseEnable)\r
393 );\r
394\r
395 //\r
396 // submit async interrupt transfer\r
397 //\r
398 EndpointAddr = UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress;\r
399 PollingInterval = UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->Interval;\r
400 PacketSize = (UINT8) (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->MaxPacketSize);\r
401\r
402 Status = UsbIo->UsbAsyncInterruptTransfer (\r
403 UsbIo,\r
404 EndpointAddr,\r
405 TRUE,\r
406 PollingInterval,\r
407 PacketSize,\r
408 OnMouseSimulateTouchPadInterruptComplete,\r
409 UsbMouseSimulateTouchPadDevice\r
410 );\r
411\r
412 if (!EFI_ERROR (Status)) {\r
413\r
414 UsbMouseSimulateTouchPadDevice->ControllerNameTable = NULL;\r
415 AddUnicodeString2 (\r
416 "eng",\r
417 gUsbMouseSimulateTouchPadComponentName.SupportedLanguages,\r
418 &UsbMouseSimulateTouchPadDevice->ControllerNameTable,\r
419 L"Generic Usb Mouse Simulate TouchPad",\r
420 TRUE\r
421 );\r
422 AddUnicodeString2 (\r
423 "en",\r
424 gUsbMouseSimulateTouchPadComponentName2.SupportedLanguages,\r
425 &UsbMouseSimulateTouchPadDevice->ControllerNameTable,\r
426 L"Generic Usb Mouse Simulate TouchPad2",\r
427 FALSE\r
428 );\r
429\r
430 return EFI_SUCCESS;\r
431 }\r
432\r
433 //\r
434 // If submit error, uninstall that interface\r
435 //\r
436 Status = EFI_DEVICE_ERROR;\r
437\r
438 gBS->UninstallProtocolInterface (\r
f74cc026 439 Controller,\r
440 &gEfiAbsolutePointerProtocolGuid,\r
441 &UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol\r
8ae0b360 442 );\r
443\r
444ErrorExit:\r
8ae0b360 445 if (EFI_ERROR (Status)) {\r
446 gBS->CloseProtocol (\r
447 Controller,\r
448 &gEfiUsbIoProtocolGuid,\r
449 This->DriverBindingHandle,\r
450 Controller\r
451 );\r
452\r
453 if (UsbMouseSimulateTouchPadDevice != NULL) {\r
454 if (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor != NULL) {\r
455 gBS->FreePool (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor);\r
456 }\r
457\r
458 if (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor != NULL) {\r
459 gBS->FreePool (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor);\r
460 }\r
461 \r
f74cc026 462 if ((UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol).WaitForInput != NULL) {\r
463 gBS->CloseEvent ((UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol).WaitForInput);\r
464 }\r
8ae0b360 465\r
466 gBS->FreePool (UsbMouseSimulateTouchPadDevice);\r
467 UsbMouseSimulateTouchPadDevice = NULL;\r
468 }\r
469 }\r
470\r
471 return Status;\r
472}\r
473\r
474\r
475/**\r
476 Stop this driver on ControllerHandle. Support stoping any child handles\r
477 created by this driver.\r
478\r
479 @param This Protocol instance pointer.\r
480 @param Controller Handle of device to stop driver on\r
481 @param NumberOfChildren Number of Children in the ChildHandleBuffer\r
482 @param ChildHandleBuffer List of handles for the children we need to stop.\r
483\r
484 @return EFI_SUCCESS\r
485 @return EFI_DEVICE_ERROR\r
486 @return others\r
487\r
488**/\r
489EFI_STATUS\r
490EFIAPI\r
491USBMouseSimulateTouchPadDriverBindingStop (\r
492 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
493 IN EFI_HANDLE Controller,\r
494 IN UINTN NumberOfChildren,\r
495 IN EFI_HANDLE *ChildHandleBuffer\r
496 )\r
497{\r
498 EFI_STATUS Status;\r
499 USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice;\r
500 EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointerProtocol;\r
501 EFI_USB_IO_PROTOCOL *UsbIo;\r
502\r
503 //\r
504 // Get our context back.\r
505 //\r
f74cc026 506 Status = gBS->OpenProtocol (\r
507 Controller,\r
508 &gEfiAbsolutePointerProtocolGuid,\r
509 (VOID **) &AbsolutePointerProtocol,\r
510 This->DriverBindingHandle,\r
511 Controller,\r
512 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
513 );\r
514\r
515 if (EFI_ERROR (Status)) {\r
516 return EFI_UNSUPPORTED;\r
517 }\r
8ae0b360 518 UsbMouseSimulateTouchPadDevice = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL (AbsolutePointerProtocol);\r
519\r
520 gBS->CloseProtocol (\r
521 Controller,\r
522 &gEfiAbsolutePointerProtocolGuid,\r
523 This->DriverBindingHandle,\r
524 Controller\r
525 );\r
526\r
527 UsbIo = UsbMouseSimulateTouchPadDevice->UsbIo;\r
528\r
529 //\r
530 // Uninstall the Asyn Interrupt Transfer from this device\r
531 // will disable the mouse data input from this device\r
532 //\r
533 MouseSimulateTouchPadReportStatusCode (\r
534 UsbMouseSimulateTouchPadDevice->DevicePath,\r
535 EFI_PROGRESS_CODE,\r
536 PcdGet32 (PcdStatusCodeValueMouseDisable)\r
537 );\r
538\r
539 //\r
540 // Delete Mouse Async Interrupt Transfer\r
541 //\r
542 UsbIo->UsbAsyncInterruptTransfer (\r
543 UsbIo,\r
544 UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress,\r
545 FALSE,\r
546 UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->Interval,\r
547 0,\r
548 NULL,\r
549 NULL\r
550 );\r
551\r
552 gBS->CloseEvent (UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol.WaitForInput);\r
553 \r
554 if (UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent) {\r
555 gBS->CloseEvent (UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent);\r
556 UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent = 0;\r
557 }\r
558\r
559 Status = gBS->UninstallProtocolInterface (\r
560 Controller,\r
561 &gEfiAbsolutePointerProtocolGuid,\r
562 &UsbMouseSimulateTouchPadDevice->AbsolutePointerProtocol\r
563 );\r
564 if (EFI_ERROR (Status)) {\r
565 return Status;\r
566 }\r
567\r
568 gBS->CloseProtocol (\r
569 Controller,\r
570 &gEfiUsbIoProtocolGuid,\r
571 This->DriverBindingHandle,\r
572 Controller\r
573 );\r
574\r
575 gBS->FreePool (UsbMouseSimulateTouchPadDevice->InterfaceDescriptor);\r
576 gBS->FreePool (UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor);\r
577\r
578 if (UsbMouseSimulateTouchPadDevice->ControllerNameTable) {\r
579 FreeUnicodeStringTable (UsbMouseSimulateTouchPadDevice->ControllerNameTable);\r
580 }\r
581\r
582 gBS->FreePool (UsbMouseSimulateTouchPadDevice);\r
583\r
584 return EFI_SUCCESS;\r
585\r
586}\r
587\r
588\r
589/**\r
590 Tell if a Usb Controller is a mouse\r
591\r
592 @param UsbIo Protocol instance pointer.\r
593\r
594 @retval TRUE It is a mouse\r
595 @retval FALSE It is not a mouse\r
596\r
597**/\r
598BOOLEAN\r
599IsUsbMouseSimulateTouchPad (\r
600 IN EFI_USB_IO_PROTOCOL *UsbIo\r
601 )\r
602{\r
603 EFI_STATUS Status;\r
604 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;\r
605\r
606 //\r
607 // Get the Default interface descriptor, now we only\r
608 // suppose it is interface 1\r
609 //\r
610 Status = UsbIo->UsbGetInterfaceDescriptor (\r
611 UsbIo,\r
612 &InterfaceDescriptor\r
613 );\r
614\r
615 if (EFI_ERROR (Status)) {\r
616 return FALSE;\r
617 }\r
618\r
619 if ((InterfaceDescriptor.InterfaceClass == CLASS_HID) &&\r
620 (InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT) &&\r
621 (InterfaceDescriptor.InterfaceProtocol == PROTOCOL_MOUSE)\r
622 ) {\r
623 \r
624 return TRUE;\r
625 }\r
626\r
627 return FALSE;\r
628}\r
629\r
630\r
631/**\r
632 Initialize the Usb Mouse Simulate TouchPad Device.\r
633\r
634 @param UsbMouseSimulateTouchPadDev Device instance to be initialized\r
635\r
636 @retval EFI_SUCCESS Success\r
637 @retval EFI_DEVICE_ERROR Init error. EFI_OUT_OF_RESOURCES- Can't allocate\r
638 memory\r
639\r
640**/\r
641STATIC\r
642EFI_STATUS\r
643InitializeUsbMouseSimulateTouchPadDevice (\r
644 IN USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev\r
645 )\r
646{\r
647 EFI_USB_IO_PROTOCOL *UsbIo;\r
648 UINT8 Protocol;\r
649 EFI_STATUS Status;\r
650 EFI_USB_HID_DESCRIPTOR MouseHidDesc;\r
651 UINT8 *ReportDesc;\r
652\r
653 UsbIo = UsbMouseSimulateTouchPadDev->UsbIo;\r
654\r
655 //\r
656 // Get HID descriptor\r
657 //\r
658 Status = UsbGetHidDescriptor (\r
659 UsbIo,\r
660 UsbMouseSimulateTouchPadDev->InterfaceDescriptor->InterfaceNumber,\r
661 &MouseHidDesc\r
662 );\r
663\r
664 if (EFI_ERROR (Status)) {\r
665 return Status;\r
666 }\r
667\r
668 //\r
669 // Get Report descriptor\r
670 //\r
671 if (MouseHidDesc.HidClassDesc[0].DescriptorType != 0x22) {\r
672 return EFI_UNSUPPORTED;\r
673 }\r
674\r
675 ReportDesc = AllocateZeroPool (MouseHidDesc.HidClassDesc[0].DescriptorLength);\r
676 if (ReportDesc == NULL) {\r
677 return EFI_OUT_OF_RESOURCES;\r
678 }\r
679\r
680 Status = UsbGetReportDescriptor (\r
681 UsbIo,\r
682 UsbMouseSimulateTouchPadDev->InterfaceDescriptor->InterfaceNumber,\r
683 MouseHidDesc.HidClassDesc[0].DescriptorLength,\r
684 ReportDesc\r
685 );\r
686\r
687 if (EFI_ERROR (Status)) {\r
688 gBS->FreePool (ReportDesc);\r
689 return Status;\r
690 }\r
691\r
692 //\r
693 // Parse report descriptor\r
694 //\r
695 Status = ParseMouseReportDescriptor (\r
696 UsbMouseSimulateTouchPadDev,\r
697 ReportDesc,\r
698 MouseHidDesc.HidClassDesc[0].DescriptorLength\r
699 );\r
700\r
701 if (EFI_ERROR (Status)) {\r
702 gBS->FreePool (ReportDesc);\r
703 return Status;\r
704 }\r
705\r
f74cc026 706 UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMaxX = 1024;\r
707 UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMaxY = 1024;\r
708 UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMaxZ = 0;\r
709 UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMinX = 0;\r
710 UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMinY = 0;\r
711 UsbMouseSimulateTouchPadDev->AbsolutePointerMode.AbsoluteMinZ = 0;\r
712 UsbMouseSimulateTouchPadDev->AbsolutePointerMode.Attributes = 0x3;\r
8ae0b360 713 \r
714 //\r
715 // Here we just assume interface 0 is the mouse interface\r
716 //\r
717 UsbGetProtocolRequest (\r
718 UsbIo,\r
719 0,\r
720 &Protocol\r
721 );\r
722\r
723 if (Protocol != BOOT_PROTOCOL) {\r
724 Status = UsbSetProtocolRequest (\r
725 UsbIo,\r
726 0,\r
727 BOOT_PROTOCOL\r
728 );\r
729\r
730 if (EFI_ERROR (Status)) {\r
731 gBS->FreePool (ReportDesc);\r
732 return EFI_DEVICE_ERROR;\r
733 }\r
734 }\r
735\r
736 //\r
737 // Set indefinite Idle rate for USB Mouse\r
738 //\r
739 UsbSetIdleRequest (\r
740 UsbIo,\r
741 0,\r
742 0,\r
743 0\r
744 );\r
745\r
746 gBS->FreePool (ReportDesc);\r
747\r
748 if (UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent) {\r
749 gBS->CloseEvent (UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent);\r
750 UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent = 0;\r
751 }\r
752\r
753 Status = gBS->CreateEvent (\r
754 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
755 TPL_NOTIFY,\r
756 USBMouseSimulateTouchPadRecoveryHandler,\r
757 UsbMouseSimulateTouchPadDev,\r
758 &UsbMouseSimulateTouchPadDev->DelayedRecoveryEvent\r
759 );\r
760\r
761 return EFI_SUCCESS;\r
762}\r
763\r
764\r
765/**\r
766 It is called whenever there is data received from async interrupt\r
767 transfer.\r
768\r
769 @param Data Data received.\r
770 @param DataLength Length of Data\r
771 @param Context Passed in context\r
772 @param Result Async Interrupt Transfer result\r
773\r
774 @return EFI_SUCCESS\r
775 @return EFI_DEVICE_ERROR\r
776\r
777**/\r
778STATIC\r
779EFI_STATUS\r
780EFIAPI\r
781OnMouseSimulateTouchPadInterruptComplete (\r
782 IN VOID *Data,\r
783 IN UINTN DataLength,\r
784 IN VOID *Context,\r
785 IN UINT32 Result\r
786 )\r
787{\r
788 USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice;\r
789 EFI_USB_IO_PROTOCOL *UsbIo;\r
790 UINT8 EndpointAddr;\r
791 UINT32 UsbResult;\r
792\r
793 UsbMouseSimulateTouchPadDevice = (USB_MOUSE_SIMULATE_TOUCHPAD_DEV *) Context;\r
794 UsbIo = UsbMouseSimulateTouchPadDevice->UsbIo;\r
795\r
796 if (Result != EFI_USB_NOERROR) {\r
797 //\r
798 // Some errors happen during the process\r
799 //\r
800 MouseSimulateTouchPadReportStatusCode (\r
801 UsbMouseSimulateTouchPadDevice->DevicePath,\r
802 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
803 PcdGet32 (PcdStatusCodeValueMouseInputError)\r
804 );\r
805\r
806 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
807 EndpointAddr = UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress;\r
808\r
809 UsbClearEndpointHalt (\r
810 UsbIo,\r
811 EndpointAddr,\r
812 &UsbResult\r
813 );\r
814 }\r
815\r
816 UsbIo->UsbAsyncInterruptTransfer (\r
817 UsbIo,\r
818 UsbMouseSimulateTouchPadDevice->IntEndpointDescriptor->EndpointAddress,\r
819 FALSE,\r
820 0,\r
821 0,\r
822 NULL,\r
823 NULL\r
824 );\r
825\r
826 gBS->SetTimer (\r
827 UsbMouseSimulateTouchPadDevice->DelayedRecoveryEvent,\r
828 TimerRelative,\r
829 EFI_USB_INTERRUPT_DELAY\r
830 );\r
831 return EFI_DEVICE_ERROR;\r
832 }\r
833\r
834 if (DataLength == 0 || Data == NULL) {\r
835 return EFI_SUCCESS;\r
836 }\r
837\r
f74cc026 838 //\r
839 //Check mouse Data\r
840 //\r
841 UsbMouseSimulateTouchPadDevice->AbsolutePointerStateChanged = TRUE;\r
842 UsbMouseSimulateTouchPadDevice->AbsolutePointerState.CurrentX += *((INT8 *) Data + 1);\r
843 UsbMouseSimulateTouchPadDevice->AbsolutePointerState.CurrentY += *((INT8 *) Data + 2);\r
844 if (DataLength > 3) {\r
845 UsbMouseSimulateTouchPadDevice->AbsolutePointerState.CurrentZ += *((INT8 *) Data + 3);\r
846 }\r
847 UsbMouseSimulateTouchPadDevice->AbsolutePointerState.ActiveButtons = *(UINT8 *)Data & 0x3;\r
8ae0b360 848\r
849 return EFI_SUCCESS;\r
850}\r
851\r
852/**\r
853 Get the mouse state, see ABSOLUTE POINTER PROTOCOL.\r
854\r
855 @param This Protocol instance pointer.\r
856 @param MouseState Current mouse state\r
857\r
858 @return EFI_SUCCESS\r
859 @return EFI_DEVICE_ERROR\r
860 @return EFI_NOT_READY\r
861\r
862**/\r
863STATIC\r
864EFI_STATUS\r
865EFIAPI\r
866GetMouseSimulateTouchPadState (\r
867 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
868 OUT EFI_ABSOLUTE_POINTER_STATE *MouseSimulateTouchPadState\r
869 )\r
870{\r
871 USB_MOUSE_SIMULATE_TOUCHPAD_DEV *MouseSimulateTouchPadDev;\r
872\r
873 if (MouseSimulateTouchPadState == NULL) {\r
874 return EFI_DEVICE_ERROR;\r
875 }\r
876\r
877 MouseSimulateTouchPadDev = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL (This);\r
878\r
879 if (!MouseSimulateTouchPadDev->AbsolutePointerStateChanged) {\r
880 return EFI_NOT_READY;\r
881 }\r
882\r
883 CopyMem (\r
884 MouseSimulateTouchPadState,\r
885 &MouseSimulateTouchPadDev->AbsolutePointerState,\r
886 sizeof (EFI_ABSOLUTE_POINTER_STATE)\r
887 );\r
888\r
889 //\r
890 // Clear previous move state\r
891 //\r
892 MouseSimulateTouchPadDev->AbsolutePointerState.CurrentX = 0;\r
893 MouseSimulateTouchPadDev->AbsolutePointerState.CurrentY = 0;\r
894 MouseSimulateTouchPadDev->AbsolutePointerState.CurrentZ = 0;\r
895 MouseSimulateTouchPadDev->AbsolutePointerState.ActiveButtons = 0;\r
896\r
897 MouseSimulateTouchPadDev->AbsolutePointerStateChanged = FALSE;\r
898\r
899 return EFI_SUCCESS;\r
900}\r
901\r
902\r
903/**\r
904 Reset the mouse device, see ABSOLUTE POINTER PROTOCOL.\r
905\r
906 @param This Protocol instance pointer.\r
907 @param ExtendedVerification Ignored here/\r
908\r
909 @return EFI_SUCCESS\r
910\r
911**/\r
912STATIC\r
913EFI_STATUS\r
914EFIAPI\r
915UsbMouseSimulateTouchPadReset (\r
916 IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
917 IN BOOLEAN ExtendedVerification\r
918 )\r
919{\r
920 USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDevice;\r
921\r
922 UsbMouseSimulateTouchPadDevice = USB_MOUSE_SIMULATE_TOUCHPAD_DEV_FROM_MOUSE_PROTOCOL (This);\r
923\r
924 MouseSimulateTouchPadReportStatusCode (\r
925 UsbMouseSimulateTouchPadDevice->DevicePath,\r
926 EFI_PROGRESS_CODE,\r
927 PcdGet32 (PcdStatusCodeValueMouseReset)\r
928 );\r
929\r
930 ZeroMem (\r
931 &UsbMouseSimulateTouchPadDevice->AbsolutePointerState,\r
932 sizeof (EFI_ABSOLUTE_POINTER_STATE)\r
933 );\r
934 UsbMouseSimulateTouchPadDevice->AbsolutePointerStateChanged = FALSE;\r
935\r
936 return EFI_SUCCESS;\r
937}\r
938\r
939/**\r
940 Event notification function for ABSOLUTE_POINTER.WaitForInput event\r
941 Signal the event if there is input from mouse\r
942\r
943 @param Event Wait Event\r
944 @param Context Passed parameter to event handler\r
945 VOID\r
946\r
947**/\r
948STATIC\r
949VOID\r
950EFIAPI\r
951UsbMouseSimulateTouchPadWaitForInput (\r
952 IN EFI_EVENT Event,\r
953 IN VOID *Context\r
954 )\r
955{\r
956 USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev;\r
957\r
958 UsbMouseSimulateTouchPadDev = (USB_MOUSE_SIMULATE_TOUCHPAD_DEV *) Context;\r
959\r
960 //\r
961 // Someone is waiting on the mouse event, if there's\r
962 // input from mouse, signal the event\r
963 //\r
964 if (UsbMouseSimulateTouchPadDev->AbsolutePointerStateChanged) {\r
965 gBS->SignalEvent (Event);\r
966 }\r
967}\r
968\r
969/**\r
970 Timer handler for Delayed Recovery timer.\r
971\r
972 @param Event The Delayed Recovery event.\r
973 @param Context Points to the USB_KB_DEV instance.\r
974\r
975\r
976**/\r
977VOID\r
978EFIAPI\r
979USBMouseSimulateTouchPadRecoveryHandler (\r
980 IN EFI_EVENT Event,\r
981 IN VOID *Context\r
982 )\r
983{\r
984 USB_MOUSE_SIMULATE_TOUCHPAD_DEV *UsbMouseSimulateTouchPadDev;\r
985 EFI_USB_IO_PROTOCOL *UsbIo;\r
986\r
987 UsbMouseSimulateTouchPadDev = (USB_MOUSE_SIMULATE_TOUCHPAD_DEV *) Context;\r
988\r
989 UsbIo = UsbMouseSimulateTouchPadDev->UsbIo;\r
990\r
991 UsbIo->UsbAsyncInterruptTransfer (\r
992 UsbIo,\r
993 UsbMouseSimulateTouchPadDev->IntEndpointDescriptor->EndpointAddress,\r
994 TRUE,\r
995 UsbMouseSimulateTouchPadDev->IntEndpointDescriptor->Interval,\r
996 UsbMouseSimulateTouchPadDev->IntEndpointDescriptor->MaxPacketSize,\r
997 OnMouseSimulateTouchPadInterruptComplete,\r
998 UsbMouseSimulateTouchPadDev\r
999 );\r
1000}\r
1001\r
1002\r
1003/**\r
1004 Report Status Code in Usb Bot Driver\r
1005\r
1006 @param DevicePath Use this to get Device Path\r
1007 @param CodeType Status Code Type\r
1008 @param CodeValue Status Code Value\r
1009\r
1010 @return None\r
1011\r
1012**/\r
1013VOID\r
1014MouseSimulateTouchPadReportStatusCode (\r
1015 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1016 IN EFI_STATUS_CODE_TYPE CodeType,\r
1017 IN EFI_STATUS_CODE_VALUE Value\r
1018 )\r
1019{\r
1020 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
1021 CodeType,\r
1022 Value,\r
1023 DevicePath\r
1024 );\r
1025}\r