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