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