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