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
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.
25 // Driver model protocol interface
29 USBMouseDriverBindingEntryPoint (
30 IN EFI_HANDLE ImageHandle
,
31 IN EFI_SYSTEM_TABLE
*SystemTable
36 USBMouseDriverBindingSupported (
37 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
38 IN EFI_HANDLE Controller
,
39 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
44 USBMouseDriverBindingStart (
45 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
46 IN EFI_HANDLE Controller
,
47 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
52 USBMouseDriverBindingStop (
53 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
54 IN EFI_HANDLE Controller
,
55 IN UINTN NumberOfChildren
,
56 IN EFI_HANDLE
*ChildHandleBuffer
60 EFI_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding
= {
61 USBMouseDriverBindingSupported
,
62 USBMouseDriverBindingStart
,
63 USBMouseDriverBindingStop
,
75 IN EFI_USB_IO_PROTOCOL
*UsbIo
80 InitializeUsbMouseDevice (
81 IN USB_MOUSE_DEV
*UsbMouseDev
87 UsbMouseWaitForInput (
93 // Mouse interrupt handler
98 OnMouseInterruptComplete (
112 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
113 OUT EFI_SIMPLE_POINTER_STATE
*MouseState
120 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
121 IN BOOLEAN ExtendedVerification
126 USBMouseDriverBindingSupported (
127 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
128 IN EFI_HANDLE Controller
,
129 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
134 Test to see if this driver supports ControllerHandle. Any ControllerHandle
135 that has UsbHcProtocol installed will be supported.
138 This - Protocol instance pointer.
139 Controller - Handle of device to test
140 RemainingDevicePath - Not used
143 EFI_SUCCESS - This driver supports this device.
144 EFI_UNSUPPORTED - This driver does not support this device.
148 EFI_STATUS OpenStatus
;
149 EFI_USB_IO_PROTOCOL
*UsbIo
;
152 OpenStatus
= gBS
->OpenProtocol (
154 &gEfiUsbIoProtocolGuid
,
156 This
->DriverBindingHandle
,
158 EFI_OPEN_PROTOCOL_BY_DRIVER
160 if (EFI_ERROR (OpenStatus
) && (OpenStatus
!= EFI_ALREADY_STARTED
)) {
161 return EFI_UNSUPPORTED
;
164 if (OpenStatus
== EFI_ALREADY_STARTED
) {
165 return EFI_ALREADY_STARTED
;
169 // Use the USB I/O protocol interface to see the Controller is
170 // the Mouse controller that can be managed by this driver.
172 Status
= EFI_SUCCESS
;
173 if (!IsUsbMouse (UsbIo
)) {
174 Status
= EFI_UNSUPPORTED
;
179 &gEfiUsbIoProtocolGuid
,
180 This
->DriverBindingHandle
,
188 USBMouseDriverBindingStart (
189 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
190 IN EFI_HANDLE Controller
,
191 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
196 Starting the Usb Bus Driver
199 This - Protocol instance pointer.
200 Controller - Handle of device to test
201 RemainingDevicePath - Not used
204 EFI_SUCCESS - This driver supports this device.
205 EFI_UNSUPPORTED - This driver does not support this device.
206 EFI_DEVICE_ERROR - This driver cannot be started due to device
208 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
209 EFI_ALREADY_STARTED - Thios driver has been started
213 EFI_USB_IO_PROTOCOL
*UsbIo
;
214 EFI_USB_ENDPOINT_DESCRIPTOR
*EndpointDesc
;
215 USB_MOUSE_DEV
*UsbMouseDevice
;
216 UINT8 EndpointNumber
;
219 UINT8 PollingInterval
;
222 UsbMouseDevice
= NULL
;
223 Status
= EFI_SUCCESS
;
225 Status
= gBS
->OpenProtocol (
227 &gEfiUsbIoProtocolGuid
,
229 This
->DriverBindingHandle
,
231 EFI_OPEN_PROTOCOL_BY_DRIVER
233 if (EFI_ERROR (Status
)) {
237 UsbMouseDevice
= AllocateZeroPool (sizeof (USB_MOUSE_DEV
));
238 if (UsbMouseDevice
== NULL
) {
239 Status
= EFI_OUT_OF_RESOURCES
;
243 UsbMouseDevice
->UsbIo
= UsbIo
;
245 UsbMouseDevice
->Signature
= USB_MOUSE_DEV_SIGNATURE
;
247 UsbMouseDevice
->InterfaceDescriptor
= AllocatePool (sizeof (EFI_USB_INTERFACE_DESCRIPTOR
));
248 if (UsbMouseDevice
->InterfaceDescriptor
== NULL
) {
249 Status
= EFI_OUT_OF_RESOURCES
;
253 EndpointDesc
= AllocatePool (sizeof (EFI_USB_ENDPOINT_DESCRIPTOR
));
254 if (EndpointDesc
== NULL
) {
255 Status
= EFI_OUT_OF_RESOURCES
;
259 // Get the Device Path Protocol on Controller's handle
261 Status
= gBS
->OpenProtocol (
263 &gEfiDevicePathProtocolGuid
,
264 (VOID
**) &UsbMouseDevice
->DevicePath
,
265 This
->DriverBindingHandle
,
267 EFI_OPEN_PROTOCOL_GET_PROTOCOL
270 if (EFI_ERROR (Status
)) {
274 // Get interface & endpoint descriptor
276 UsbIo
->UsbGetInterfaceDescriptor (
278 UsbMouseDevice
->InterfaceDescriptor
281 EndpointNumber
= UsbMouseDevice
->InterfaceDescriptor
->NumEndpoints
;
283 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
284 UsbIo
->UsbGetEndpointDescriptor (
290 if ((EndpointDesc
->Attributes
& 0x03) == 0x03) {
293 // We only care interrupt endpoint here
295 UsbMouseDevice
->IntEndpointDescriptor
= EndpointDesc
;
299 if (UsbMouseDevice
->IntEndpointDescriptor
== NULL
) {
301 // No interrupt endpoint, then error
303 Status
= EFI_UNSUPPORTED
;
307 Status
= InitializeUsbMouseDevice (UsbMouseDevice
);
308 if (EFI_ERROR (Status
)) {
309 MouseReportStatusCode (
310 UsbMouseDevice
->DevicePath
,
311 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
312 (EFI_PERIPHERAL_MOUSE
| EFI_P_EC_INTERFACE_ERROR
)
318 UsbMouseDevice
->SimplePointerProtocol
.GetState
= GetMouseState
;
319 UsbMouseDevice
->SimplePointerProtocol
.Reset
= UsbMouseReset
;
320 UsbMouseDevice
->SimplePointerProtocol
.Mode
= &UsbMouseDevice
->Mode
;
322 Status
= gBS
->CreateEvent (
323 EFI_EVENT_NOTIFY_WAIT
,
325 UsbMouseWaitForInput
,
327 &((UsbMouseDevice
->SimplePointerProtocol
).WaitForInput
)
329 if (EFI_ERROR (Status
)) {
333 Status
= gBS
->InstallProtocolInterface (
335 &gEfiSimplePointerProtocolGuid
,
336 EFI_NATIVE_INTERFACE
,
337 &UsbMouseDevice
->SimplePointerProtocol
340 if (EFI_ERROR (Status
)) {
341 Status
= EFI_DEVICE_ERROR
;
346 // After Enabling Async Interrupt Transfer on this mouse Device
347 // we will be able to get key data from it. Thus this is deemed as
348 // the enable action of the mouse
351 MouseReportStatusCode (
352 UsbMouseDevice
->DevicePath
,
354 (EFI_PERIPHERAL_MOUSE
| EFI_P_PC_ENABLE
)
358 // submit async interrupt transfer
360 EndpointAddr
= UsbMouseDevice
->IntEndpointDescriptor
->EndpointAddress
;
361 PollingInterval
= UsbMouseDevice
->IntEndpointDescriptor
->Interval
;
362 PacketSize
= (UINT8
) (UsbMouseDevice
->IntEndpointDescriptor
->MaxPacketSize
);
364 Status
= UsbIo
->UsbAsyncInterruptTransfer (
370 OnMouseInterruptComplete
,
374 if (!EFI_ERROR (Status
)) {
376 UsbMouseDevice
->ControllerNameTable
= NULL
;
379 gUsbMouseComponentName
.SupportedLanguages
,
380 &UsbMouseDevice
->ControllerNameTable
,
381 (CHAR16
*) L
"Generic Usb Mouse"
388 // If submit error, uninstall that interface
390 Status
= EFI_DEVICE_ERROR
;
391 gBS
->UninstallProtocolInterface (
393 &gEfiSimplePointerProtocolGuid
,
394 &UsbMouseDevice
->SimplePointerProtocol
398 if (EFI_ERROR (Status
)) {
401 &gEfiUsbIoProtocolGuid
,
402 This
->DriverBindingHandle
,
406 if (UsbMouseDevice
!= NULL
) {
407 if (UsbMouseDevice
->InterfaceDescriptor
!= NULL
) {
408 gBS
->FreePool (UsbMouseDevice
->InterfaceDescriptor
);
411 if (UsbMouseDevice
->IntEndpointDescriptor
!= NULL
) {
412 gBS
->FreePool (UsbMouseDevice
->IntEndpointDescriptor
);
415 if ((UsbMouseDevice
->SimplePointerProtocol
).WaitForInput
!= NULL
) {
416 gBS
->CloseEvent ((UsbMouseDevice
->SimplePointerProtocol
).WaitForInput
);
419 gBS
->FreePool (UsbMouseDevice
);
420 UsbMouseDevice
= NULL
;
429 USBMouseDriverBindingStop (
430 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
431 IN EFI_HANDLE Controller
,
432 IN UINTN NumberOfChildren
,
433 IN EFI_HANDLE
*ChildHandleBuffer
438 Stop this driver on ControllerHandle. Support stoping any child handles
439 created by this driver.
442 This - Protocol instance pointer.
443 Controller - Handle of device to stop driver on
444 NumberOfChildren - Number of Children in the ChildHandleBuffer
445 ChildHandleBuffer - List of handles for the children we need to stop.
455 USB_MOUSE_DEV
*UsbMouseDevice
;
456 EFI_SIMPLE_POINTER_PROTOCOL
*SimplePointerProtocol
;
457 EFI_USB_IO_PROTOCOL
*UsbIo
;
460 // Get our context back.
462 Status
= gBS
->OpenProtocol (
464 &gEfiSimplePointerProtocolGuid
,
465 (VOID
**) &SimplePointerProtocol
,
466 This
->DriverBindingHandle
,
468 EFI_OPEN_PROTOCOL_GET_PROTOCOL
471 if (EFI_ERROR (Status
)) {
472 return EFI_UNSUPPORTED
;
475 UsbMouseDevice
= USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol
);
479 &gEfiSimplePointerProtocolGuid
,
480 This
->DriverBindingHandle
,
484 UsbIo
= UsbMouseDevice
->UsbIo
;
487 // Uninstall the Asyn Interrupt Transfer from this device
488 // will disable the mouse data input from this device
490 MouseReportStatusCode (
491 UsbMouseDevice
->DevicePath
,
493 (EFI_PERIPHERAL_MOUSE
| EFI_P_PC_DISABLE
)
497 // Delete Mouse Async Interrupt Transfer
499 UsbIo
->UsbAsyncInterruptTransfer (
501 UsbMouseDevice
->IntEndpointDescriptor
->EndpointAddress
,
503 UsbMouseDevice
->IntEndpointDescriptor
->Interval
,
509 gBS
->CloseEvent (UsbMouseDevice
->SimplePointerProtocol
.WaitForInput
);
511 if (UsbMouseDevice
->DelayedRecoveryEvent
) {
512 gBS
->CloseEvent (UsbMouseDevice
->DelayedRecoveryEvent
);
513 UsbMouseDevice
->DelayedRecoveryEvent
= 0;
516 Status
= gBS
->UninstallProtocolInterface (
518 &gEfiSimplePointerProtocolGuid
,
519 &UsbMouseDevice
->SimplePointerProtocol
521 if (EFI_ERROR (Status
)) {
527 &gEfiUsbIoProtocolGuid
,
528 This
->DriverBindingHandle
,
532 gBS
->FreePool (UsbMouseDevice
->InterfaceDescriptor
);
533 gBS
->FreePool (UsbMouseDevice
->IntEndpointDescriptor
);
535 if (UsbMouseDevice
->ControllerNameTable
) {
536 FreeUnicodeStringTable (UsbMouseDevice
->ControllerNameTable
);
539 gBS
->FreePool (UsbMouseDevice
);
547 IN EFI_USB_IO_PROTOCOL
*UsbIo
552 Tell if a Usb Controller is a mouse
555 UsbIo - Protocol instance pointer.
559 FALSE - It is not a mouse
563 EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
566 // Get the Default interface descriptor, now we only
567 // suppose it is interface 1
569 Status
= UsbIo
->UsbGetInterfaceDescriptor (
574 if (EFI_ERROR (Status
)) {
578 if ((InterfaceDescriptor
.InterfaceClass
== CLASS_HID
) &&
579 (InterfaceDescriptor
.InterfaceSubClass
== SUBCLASS_BOOT
) &&
580 (InterfaceDescriptor
.InterfaceProtocol
== PROTOCOL_MOUSE
)
590 InitializeUsbMouseDevice (
591 IN USB_MOUSE_DEV
*UsbMouseDev
596 Initialize the Usb Mouse Device.
599 UsbMouseDev - Device instance to be initialized
602 EFI_SUCCESS - Success
603 EFI_DEVICE_ERROR - Init error.
604 EFI_OUT_OF_RESOURCES- Can't allocate memory
607 EFI_USB_IO_PROTOCOL
*UsbIo
;
610 EFI_USB_HID_DESCRIPTOR MouseHidDesc
;
613 UsbIo
= UsbMouseDev
->UsbIo
;
616 // Get HID descriptor
618 Status
= UsbGetHidDescriptor (
620 UsbMouseDev
->InterfaceDescriptor
->InterfaceNumber
,
624 if (EFI_ERROR (Status
)) {
629 // Get Report descriptor
631 if (MouseHidDesc
.HidClassDesc
[0].DescriptorType
!= 0x22) {
632 return EFI_UNSUPPORTED
;
635 ReportDesc
= AllocateZeroPool (MouseHidDesc
.HidClassDesc
[0].DescriptorLength
);
636 if (ReportDesc
== NULL
) {
637 return EFI_OUT_OF_RESOURCES
;
640 Status
= UsbGetReportDescriptor (
642 UsbMouseDev
->InterfaceDescriptor
->InterfaceNumber
,
643 MouseHidDesc
.HidClassDesc
[0].DescriptorLength
,
647 if (EFI_ERROR (Status
)) {
648 gBS
->FreePool (ReportDesc
);
653 // Parse report descriptor
655 Status
= ParseMouseReportDescriptor (
658 MouseHidDesc
.HidClassDesc
[0].DescriptorLength
661 if (EFI_ERROR (Status
)) {
662 gBS
->FreePool (ReportDesc
);
666 if (UsbMouseDev
->NumberOfButtons
>= 1) {
667 UsbMouseDev
->Mode
.LeftButton
= TRUE
;
670 if (UsbMouseDev
->NumberOfButtons
> 1) {
671 UsbMouseDev
->Mode
.RightButton
= TRUE
;
674 UsbMouseDev
->Mode
.ResolutionX
= 8;
675 UsbMouseDev
->Mode
.ResolutionY
= 8;
676 UsbMouseDev
->Mode
.ResolutionZ
= 0;
678 // Here we just assume interface 0 is the mouse interface
680 UsbGetProtocolRequest (
686 if (Protocol
!= BOOT_PROTOCOL
) {
687 Status
= UsbSetProtocolRequest (
693 if (EFI_ERROR (Status
)) {
694 gBS
->FreePool (ReportDesc
);
695 return EFI_DEVICE_ERROR
;
700 // Set indefinite Idle rate for USB Mouse
709 gBS
->FreePool (ReportDesc
);
711 if (UsbMouseDev
->DelayedRecoveryEvent
) {
712 gBS
->CloseEvent (UsbMouseDev
->DelayedRecoveryEvent
);
713 UsbMouseDev
->DelayedRecoveryEvent
= 0;
716 Status
= gBS
->CreateEvent (
717 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
719 USBMouseRecoveryHandler
,
721 &UsbMouseDev
->DelayedRecoveryEvent
730 OnMouseInterruptComplete (
739 It is called whenever there is data received from async interrupt
743 Data - Data received.
744 DataLength - Length of Data
745 Context - Passed in context
746 Result - Async Interrupt Transfer result
754 USB_MOUSE_DEV
*UsbMouseDevice
;
755 EFI_USB_IO_PROTOCOL
*UsbIo
;
759 UsbMouseDevice
= (USB_MOUSE_DEV
*) Context
;
760 UsbIo
= UsbMouseDevice
->UsbIo
;
762 if (Result
!= EFI_USB_NOERROR
) {
764 // Some errors happen during the process
766 MouseReportStatusCode (
767 UsbMouseDevice
->DevicePath
,
768 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
769 (EFI_PERIPHERAL_MOUSE
| EFI_P_EC_INPUT_ERROR
)
772 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
773 EndpointAddr
= UsbMouseDevice
->IntEndpointDescriptor
->EndpointAddress
;
775 UsbClearEndpointHalt (
782 UsbIo
->UsbAsyncInterruptTransfer (
784 UsbMouseDevice
->IntEndpointDescriptor
->EndpointAddress
,
793 UsbMouseDevice
->DelayedRecoveryEvent
,
795 EFI_USB_INTERRUPT_DELAY
797 return EFI_DEVICE_ERROR
;
800 if (DataLength
== 0 || Data
== NULL
) {
804 UsbMouseDevice
->StateChanged
= TRUE
;
809 UsbMouseDevice
->State
.LeftButton
= (BOOLEAN
) (*(UINT8
*) Data
& 0x01);
810 UsbMouseDevice
->State
.RightButton
= (BOOLEAN
) (*(UINT8
*) Data
& 0x02);
811 UsbMouseDevice
->State
.RelativeMovementX
+= *((INT8
*) Data
+ 1);
812 UsbMouseDevice
->State
.RelativeMovementY
+= *((INT8
*) Data
+ 2);
814 if (DataLength
> 3) {
815 UsbMouseDevice
->State
.RelativeMovementZ
+= *((INT8
*) Data
+ 3);
824 IN EFI_MOUSE_STATE *MouseState
827 Aprint("(%x: %x, %x)\n",
828 MouseState->ButtonStates,
838 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
839 OUT EFI_SIMPLE_POINTER_STATE
*MouseState
844 Get the mouse state, see SIMPLE POINTER PROTOCOL.
847 This - Protocol instance pointer.
848 MouseState - Current mouse state
857 USB_MOUSE_DEV
*MouseDev
;
859 if (MouseState
== NULL
) {
860 return EFI_DEVICE_ERROR
;
863 MouseDev
= USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This
);
865 if (!MouseDev
->StateChanged
) {
866 return EFI_NOT_READY
;
872 sizeof (EFI_SIMPLE_POINTER_STATE
)
876 // Clear previous move state
878 MouseDev
->State
.RelativeMovementX
= 0;
879 MouseDev
->State
.RelativeMovementY
= 0;
880 MouseDev
->State
.RelativeMovementZ
= 0;
882 MouseDev
->StateChanged
= FALSE
;
891 IN EFI_SIMPLE_POINTER_PROTOCOL
*This
,
892 IN BOOLEAN ExtendedVerification
897 Reset the mouse device, see SIMPLE POINTER PROTOCOL.
900 This - Protocol instance pointer.
901 ExtendedVerification - Ignored here/
908 USB_MOUSE_DEV
*UsbMouseDevice
;
909 EFI_USB_IO_PROTOCOL
*UsbIo
;
911 UsbMouseDevice
= USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This
);
913 UsbIo
= UsbMouseDevice
->UsbIo
;
915 MouseReportStatusCode (
916 UsbMouseDevice
->DevicePath
,
918 (EFI_PERIPHERAL_MOUSE
| EFI_P_PC_RESET
)
922 &UsbMouseDevice
->State
,
923 sizeof (EFI_SIMPLE_POINTER_STATE
)
925 UsbMouseDevice
->StateChanged
= FALSE
;
933 UsbMouseWaitForInput (
941 Event notification function for SIMPLE_POINTER.WaitForInput event
942 Signal the event if there is input from mouse
946 Context - Passed parameter to event handler
951 USB_MOUSE_DEV
*UsbMouseDev
;
953 UsbMouseDev
= (USB_MOUSE_DEV
*) Context
;
956 // Someone is waiting on the mouse event, if there's
957 // input from mouse, signal the event
959 if (UsbMouseDev
->StateChanged
) {
960 gBS
->SignalEvent (Event
);
966 USBMouseRecoveryHandler (
973 Timer handler for Delayed Recovery timer.
976 Event - The Delayed Recovery event.
977 Context - Points to the USB_KB_DEV instance.
983 USB_MOUSE_DEV
*UsbMouseDev
;
984 EFI_USB_IO_PROTOCOL
*UsbIo
;
986 UsbMouseDev
= (USB_MOUSE_DEV
*) Context
;
988 UsbIo
= UsbMouseDev
->UsbIo
;
990 UsbIo
->UsbAsyncInterruptTransfer (
992 UsbMouseDev
->IntEndpointDescriptor
->EndpointAddress
,
994 UsbMouseDev
->IntEndpointDescriptor
->Interval
,
995 UsbMouseDev
->IntEndpointDescriptor
->MaxPacketSize
,
996 OnMouseInterruptComplete
,
1002 MouseReportStatusCode (
1003 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
1004 IN EFI_STATUS_CODE_TYPE CodeType
,
1005 IN EFI_STATUS_CODE_VALUE Value
1009 Routine Description:
1010 Report Status Code in Usb Bot Driver
1013 DevicePath - Use this to get Device Path
1014 CodeType - Status Code Type
1015 CodeValue - Status Code Value
1023 REPORT_STATUS_CODE_WITH_DEVICE_PATH (