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