1 /** @file
2   Helper routine and corresponding data struct used by USB Mouse Absolute Pointer Driver.
3 
4 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #ifndef _USB_MOUSE_ABSOLUTE_POINTER_H_
16 #define _USB_MOUSE_ABSOLUTE_POINTER_H_
17 
18 
19 #include <Uefi.h>
20 
21 #include <Protocol/AbsolutePointer.h>
22 #include <Protocol/UsbIo.h>
23 #include <Protocol/DevicePath.h>
24 
25 #include <Library/ReportStatusCodeLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/UefiDriverEntryPoint.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/UefiLib.h>
30 #include <Library/MemoryAllocationLib.h>
31 #include <Library/UefiUsbLib.h>
32 #include <Library/DebugLib.h>
33 
34 #include <IndustryStandard/Usb.h>
35 
36 #define CLASS_HID               3
37 #define SUBCLASS_BOOT           1
38 #define PROTOCOL_MOUSE          2
39 
40 #define BOOT_PROTOCOL           0
41 #define REPORT_PROTOCOL         1
42 
43 #define USB_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE SIGNATURE_32 ('u', 'm', 's', 't')
44 
45 //
46 // A common header for usb standard descriptor.
47 // Each stand descriptor has a length and type.
48 //
49 #pragma pack(1)
50 typedef struct {
51   UINT8                   Len;
52   UINT8                   Type;
53 } USB_DESC_HEAD;
54 #pragma pack()
55 
56 ///
57 /// Button range and status
58 ///
59 typedef struct {
60   BOOLEAN ButtonDetected;
61   UINT8   ButtonMinIndex;
62   UINT8   ButtonMaxIndex;
63   UINT8   Reserved;
64 } USB_MOUSE_BUTTON_DATA;
65 
66 ///
67 /// Device instance of USB mouse.
68 ///
69 typedef struct {
70   UINTN                         Signature;
71   EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
72   EFI_EVENT                     DelayedRecoveryEvent;
73   EFI_USB_IO_PROTOCOL           *UsbIo;
74   EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;
75   EFI_USB_ENDPOINT_DESCRIPTOR   IntEndpointDescriptor;
76   UINT8                         NumberOfButtons;
77   INT32                         XLogicMax;
78   INT32                         XLogicMin;
79   INT32                         YLogicMax;
80   INT32                         YLogicMin;
81   EFI_ABSOLUTE_POINTER_PROTOCOL AbsolutePointerProtocol;
82   EFI_ABSOLUTE_POINTER_STATE    State;
83   EFI_ABSOLUTE_POINTER_MODE     Mode;
84   BOOLEAN                       StateChanged;
85   USB_MOUSE_BUTTON_DATA         PrivateData;
86   EFI_UNICODE_STRING_TABLE      *ControllerNameTable;
87 } USB_MOUSE_ABSOLUTE_POINTER_DEV;
88 
89 ///
90 /// General HID Item structure
91 ///
92 
93 typedef union {
94   UINT8   Uint8;
95   UINT16  Uint16;
96   UINT32  Uint32;
97   INT8    Int8;
98   INT16   Int16;
99   INT32   Int32;
100   UINT8   *LongData;
101 } HID_DATA;
102 
103 typedef struct {
104   UINT16    Format;
105   UINT8     Size;
106   UINT8     Type;
107   UINT8     Tag;
108   HID_DATA  Data;
109 } HID_ITEM;
110 
111 #define USB_MOUSE_ABSOLUTE_POINTER_DEV_FROM_MOUSE_PROTOCOL(a) \
112     CR(a, USB_MOUSE_ABSOLUTE_POINTER_DEV, AbsolutePointerProtocol, USB_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE)
113 
114 //
115 // Global Variables
116 //
117 extern EFI_DRIVER_BINDING_PROTOCOL   gUsbMouseAbsolutePointerDriverBinding;
118 extern EFI_COMPONENT_NAME_PROTOCOL   gUsbMouseAbsolutePointerComponentName;
119 extern EFI_COMPONENT_NAME2_PROTOCOL  gUsbMouseAbsolutePointerComponentName2;
120 
121 //
122 // Functions of Driver Binding Protocol
123 //
124 
125 /**
126   Check whether USB Mouse Absolute Pointer Driver supports this device.
127 
128   @param  This                   The driver binding protocol.
129   @param  Controller             The controller handle to check.
130   @param  RemainingDevicePath    The remaining device path.
131 
132   @retval EFI_SUCCESS            The driver supports this controller.
133   @retval other                  This device isn't supported.
134 
135 **/
136 EFI_STATUS
137 EFIAPI
138 USBMouseAbsolutePointerDriverBindingSupported (
139   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
140   IN EFI_HANDLE                     Controller,
141   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
142   );
143 
144 /**
145   Starts the mouse device with this driver.
146 
147   This function consumes USB I/O Portocol, intializes USB mouse device,
148   installs Absolute Pointer Protocol, and submits Asynchronous Interrupt
149   Transfer to manage the USB mouse device.
150 
151   @param  This                  The driver binding instance.
152   @param  Controller            Handle of device to bind driver to.
153   @param  RemainingDevicePath   Optional parameter use to pick a specific child
154                                 device to start.
155 
156   @retval EFI_SUCCESS           This driver supports this device.
157   @retval EFI_UNSUPPORTED       This driver does not support this device.
158   @retval EFI_DEVICE_ERROR      This driver cannot be started due to device Error.
159   @retval EFI_OUT_OF_RESOURCES  Can't allocate memory resources.
160   @retval EFI_ALREADY_STARTED   This driver has been started.
161 
162 **/
163 EFI_STATUS
164 EFIAPI
165 USBMouseAbsolutePointerDriverBindingStart (
166   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
167   IN EFI_HANDLE                     Controller,
168   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
169   );
170 
171 /**
172   Stop the USB mouse device handled by this driver.
173 
174   @param  This                   The driver binding protocol.
175   @param  Controller             The controller to release.
176   @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
177   @param  ChildHandleBuffer      The array of child handle.
178 
179   @retval EFI_SUCCESS            The device was stopped.
180   @retval EFI_UNSUPPORTED        Absolute Pointer Protocol is not installed on Controller.
181   @retval Others                 Fail to uninstall protocols attached on the device.
182 
183 **/
184 EFI_STATUS
185 EFIAPI
186 USBMouseAbsolutePointerDriverBindingStop (
187   IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
188   IN  EFI_HANDLE                    Controller,
189   IN  UINTN                         NumberOfChildren,
190   IN  EFI_HANDLE                    *ChildHandleBuffer
191   );
192 
193 //
194 // EFI Component Name Functions
195 //
196 
197 /**
198   Retrieves a Unicode string that is the user readable name of the driver.
199 
200   This function retrieves the user readable name of a driver in the form of a
201   Unicode string. If the driver specified by This has a user readable name in
202   the language specified by Language, then a pointer to the driver name is
203   returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
204   by This does not support the language specified by Language,
205   then EFI_UNSUPPORTED is returned.
206 
207   @param  This                  A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
208                                 EFI_COMPONENT_NAME_PROTOCOL instance.
209   @param  Language              A pointer to a Null-terminated ASCII string
210                                 array indicating the language. This is the
211                                 language of the driver name that the caller is
212                                 requesting, and it must match one of the
213                                 languages specified in SupportedLanguages. The
214                                 number of languages supported by a driver is up
215                                 to the driver writer. Language is specified
216                                 in RFC 4646 or ISO 639-2 language code format.
217   @param  DriverName            A pointer to the Unicode string to return.
218                                 This Unicode string is the name of the
219                                 driver specified by This in the language
220                                 specified by Language.
221 
222   @retval EFI_SUCCESS           The Unicode string for the Driver specified by
223                                 This and the language specified by Language was
224                                 returned in DriverName.
225   @retval EFI_INVALID_PARAMETER Language is NULL.
226   @retval EFI_INVALID_PARAMETER DriverName is NULL.
227   @retval EFI_UNSUPPORTED       The driver specified by This does not support
228                                 the language specified by Language.
229 
230 **/
231 EFI_STATUS
232 EFIAPI
233 UsbMouseAbsolutePointerComponentNameGetDriverName (
234   IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
235   IN  CHAR8                        *Language,
236   OUT CHAR16                       **DriverName
237   );
238 
239 /**
240   Retrieves a Unicode string that is the user readable name of the controller
241   that is being managed by a driver.
242 
243   This function retrieves the user readable name of the controller specified by
244   ControllerHandle and ChildHandle in the form of a Unicode string. If the
245   driver specified by This has a user readable name in the language specified by
246   Language, then a pointer to the controller name is returned in ControllerName,
247   and EFI_SUCCESS is returned.  If the driver specified by This is not currently
248   managing the controller specified by ControllerHandle and ChildHandle,
249   then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
250   support the language specified by Language, then EFI_UNSUPPORTED is returned.
251 
252   @param  This                  A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
253                                 EFI_COMPONENT_NAME_PROTOCOL instance.
254   @param  ControllerHandle      The handle of a controller that the driver
255                                 specified by This is managing.  This handle
256                                 specifies the controller whose name is to be
257                                 returned.
258   @param  ChildHandle           The handle of the child controller to retrieve
259                                 the name of.  This is an optional parameter that
260                                 may be NULL.  It will be NULL for device
261                                 drivers.  It will also be NULL for a bus drivers
262                                 that wish to retrieve the name of the bus
263                                 controller.  It will not be NULL for a bus
264                                 driver that wishes to retrieve the name of a
265                                 child controller.
266   @param  Language              A pointer to a Null-terminated ASCII string
267                                 array indicating the language.  This is the
268                                 language of the driver name that the caller is
269                                 requesting, and it must match one of the
270                                 languages specified in SupportedLanguages. The
271                                 number of languages supported by a driver is up
272                                 to the driver writer. Language is specified in
273                                 RFC 4646 or ISO 639-2 language code format.
274   @param  ControllerName        A pointer to the Unicode string to return.
275                                 This Unicode string is the name of the
276                                 controller specified by ControllerHandle and
277                                 ChildHandle in the language specified by
278                                 Language from the point of view of the driver
279                                 specified by This.
280 
281   @retval EFI_SUCCESS           The Unicode string for the user readable name in
282                                 the language specified by Language for the
283                                 driver specified by This was returned in
284                                 DriverName.
285   @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
286   @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
287                                 EFI_HANDLE.
288   @retval EFI_INVALID_PARAMETER Language is NULL.
289   @retval EFI_INVALID_PARAMETER ControllerName is NULL.
290   @retval EFI_UNSUPPORTED       The driver specified by This is not currently
291                                 managing the controller specified by
292                                 ControllerHandle and ChildHandle.
293   @retval EFI_UNSUPPORTED       The driver specified by This does not support
294                                 the language specified by Language.
295 
296 **/
297 EFI_STATUS
298 EFIAPI
299 UsbMouseAbsolutePointerComponentNameGetControllerName (
300   IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
301   IN  EFI_HANDLE                                      ControllerHandle,
302   IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
303   IN  CHAR8                                           *Language,
304   OUT CHAR16                                          **ControllerName
305   );
306 
307 //
308 // Functions of EFI_ABSOLUTE_POINTER_PROTOCOL
309 //
310 
311 /**
312   Retrieves the current state of a pointer device.
313 
314   @param  This                  A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.
315   @param  MouseState            A pointer to the state information on the pointer device.
316 
317   @retval EFI_SUCCESS           The state of the pointer device was returned in State.
318   @retval EFI_NOT_READY         The state of the pointer device has not changed since the last call to
319                                 GetState().
320   @retval EFI_DEVICE_ERROR      A device error occurred while attempting to retrieve the pointer device's
321                                 current state.
322   @retval EFI_INVALID_PARAMETER State is NULL.
323 
324 **/
325 EFI_STATUS
326 EFIAPI
327 GetMouseAbsolutePointerState (
328   IN   EFI_ABSOLUTE_POINTER_PROTOCOL  *This,
329   OUT  EFI_ABSOLUTE_POINTER_STATE     *State
330   );
331 
332 /**
333   Resets the pointer device hardware.
334 
335   @param  This                  A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.
336   @param  ExtendedVerification  Indicates that the driver may perform a more exhaustive
337                                 verification operation of the device during reset.
338 
339   @retval EFI_SUCCESS           The device was reset.
340   @retval EFI_DEVICE_ERROR      The device is not functioning correctly and could not be reset.
341 
342 **/
343 EFI_STATUS
344 EFIAPI
345 UsbMouseAbsolutePointerReset (
346   IN EFI_ABSOLUTE_POINTER_PROTOCOL  *This,
347   IN BOOLEAN                        ExtendedVerification
348   );
349 
350 /**
351   Event notification function for EFI_ABSOLUTE_POINTER_PROTOCOL.WaitForInput event.
352 
353   @param  Event        Event to be signaled when there's input from mouse.
354   @param  Context      Points to USB_MOUSE_ABSOLUTE_POINTER_DEV instance.
355 
356 **/
357 VOID
358 EFIAPI
359 UsbMouseAbsolutePointerWaitForInput (
360   IN  EFI_EVENT               Event,
361   IN  VOID                    *Context
362   );
363 
364 //
365 // Internal worker functions
366 //
367 
368 /**
369   Uses USB I/O to check whether the device is a USB mouse device.
370 
371   @param  UsbIo    Pointer to a USB I/O protocol instance.
372 
373   @retval TRUE     Device is a USB mouse device.
374   @retval FALSE    Device is a not USB mouse device.
375 
376 **/
377 BOOLEAN
378 IsUsbMouse (
379   IN  EFI_USB_IO_PROTOCOL     *UsbIo
380   );
381 
382 /**
383   Initialize the USB mouse device.
384 
385   This function retrieves and parses HID report descriptor, and
386   initializes state of USB_MOUSE_ABSOLUTE_POINTER_DEV. Then it sets indefinite idle
387   rate for the device. Finally it creates event for delayed recovery,
388   which deals with device error.
389 
390   @param  UsbMouseAbsolutePointerDev   Device instance to be initialized.
391 
392   @retval EFI_SUCCESS                  USB mouse device successfully initialized.
393   @retval EFI_UNSUPPORTED              HID descriptor type is not report descriptor.
394   @retval Other                        USB mouse device was not initialized successfully.
395 
396 **/
397 EFI_STATUS
398 InitializeUsbMouseDevice (
399   IN  USB_MOUSE_ABSOLUTE_POINTER_DEV           *UsbMouseAbsolutePointerDev
400   );
401 
402 /**
403   Handler function for USB mouse's asynchronous interrupt transfer.
404 
405   This function is the handler function for USB mouse's asynchronous interrupt transfer
406   to manage the mouse. It parses data returned from asynchronous interrupt transfer, and
407   get button and movement state.
408 
409   @param  Data             A pointer to a buffer that is filled with key data which is
410                            retrieved via asynchronous interrupt transfer.
411   @param  DataLength       Indicates the size of the data buffer.
412   @param  Context          Pointing to USB_KB_DEV instance.
413   @param  Result           Indicates the result of the asynchronous interrupt transfer.
414 
415   @retval EFI_SUCCESS      Asynchronous interrupt transfer is handled successfully.
416   @retval EFI_DEVICE_ERROR Hardware error occurs.
417 
418 **/
419 EFI_STATUS
420 EFIAPI
421 OnMouseInterruptComplete (
422   IN  VOID        *Data,
423   IN  UINTN       DataLength,
424   IN  VOID        *Context,
425   IN  UINT32      Result
426   );
427 
428 /**
429   Handler for Delayed Recovery event.
430 
431   This function is the handler for Delayed Recovery event triggered
432   by timer.
433   After a device error occurs, the event would be triggered
434   with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
435   is defined in USB standard for error handling.
436 
437   @param  Event                 The Delayed Recovery event.
438   @param  Context               Points to the USB_MOUSE_ABSOLUTE_POINTER_DEV instance.
439 
440 **/
441 VOID
442 EFIAPI
443 USBMouseRecoveryHandler (
444   IN    EFI_EVENT    Event,
445   IN    VOID         *Context
446   );
447 
448 /**
449   Parse Mouse Report Descriptor.
450 
451   According to USB HID Specification, report descriptors are
452   composed of pieces of information. Each piece of information
453   is called an Item. This function retrieves each item from
454   the report descriptor and updates USB_MOUSE_ABSOLUTE_POINTER_DEV.
455 
456   @param  UsbMouseAbsolutePointer  The instance of USB_MOUSE_ABSOLUTE_POINTER_DEV
457   @param  ReportDescriptor         Report descriptor to parse
458   @param  ReportSize               Report descriptor size
459 
460   @retval EFI_SUCCESS              Report descriptor successfully parsed.
461   @retval EFI_UNSUPPORTED          Report descriptor contains long item.
462 
463 **/
464 EFI_STATUS
465 ParseMouseReportDescriptor (
466   OUT USB_MOUSE_ABSOLUTE_POINTER_DEV   *UsbMouseAbsolutePointer,
467   IN  UINT8                            *ReportDescriptor,
468   IN  UINTN                            ReportSize
469   );
470 
471 #endif
472