118a73eb727e697f15891ccad55507ae3d8c37461eric_tian/** @file
218a73eb727e697f15891ccad55507ae3d8c37461eric_tian  A faked PS/2 Absolute Pointer driver. Routines that interacts with callers,
3afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  conforming to EFI driver model
4afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
5cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvinCopyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
6180a5a35cb49699bd249dee19e41cee34c856a58hhtianThis program and the accompanying materials
7afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianare licensed and made available under the terms and conditions of the BSD License
8afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianwhich accompanies this distribution.  The full text of the license may be found at
9afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianhttp://opensource.org/licenses/bsd-license.php
10afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
11afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
14afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian**/
15afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
16afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian#include "Ps2MouseAbsolutePointer.h"
17afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian#include "CommPs2.h"
18afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
19afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian//
20afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian// DriverBinding Protocol Instance
21afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian//
22afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFI_DRIVER_BINDING_PROTOCOL gPS2MouseAbsolutePointerDriver = {
23afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2MouseAbsolutePointerDriverSupported,
24afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2MouseAbsolutePointerDriverStart,
25afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2MouseAbsolutePointerDriverStop,
26afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  0x1,
27afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  NULL,
28afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  NULL
29afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian};
30afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
31bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
32bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  Test to see if this driver supports ControllerHandle. Any ControllerHandle
33bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  than contains a IsaIo protocol can be supported.
34bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
35bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  This                Protocol instance pointer.
36bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  ControllerHandle    Handle of device to test
37bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  RemainingDevicePath Optional parameter use to pick a specific child
38bcd70414877e56f3bffff0bf11b07a30ef51a68fklu                              device to start.
39bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
40bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_SUCCESS         This driver supports this device
41bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_ALREADY_STARTED This driver is already running on this device
42bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval other               This driver does not support this device
43bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
44bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
45afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFI_STATUS
46afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFIAPI
47afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianPS2MouseAbsolutePointerDriverSupported (
48afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
49afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_HANDLE                     Controller,
50afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
51afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  )
52afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
53afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS                          Status;
54afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_ISA_IO_PROTOCOL                 *IsaIo;
55afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
56afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = EFI_SUCCESS;
57afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
58afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
59afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Open the IO Abstraction(s) needed to perform the supported test
60afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
61afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->OpenProtocol (
62afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
63afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &gEfiIsaIoProtocolGuid,
64afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  (VOID **) &IsaIo,
65afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  This->DriverBindingHandle,
66afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
67afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  EFI_OPEN_PROTOCOL_BY_DRIVER
68afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
69afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
70afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return Status;
71afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
72afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
73afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Use the ISA I/O Protocol to see if Controller is the Mouse controller
74afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
75afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  switch (IsaIo->ResourceList->Device.HID) {
76afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  case EISA_PNP_ID (0xF03):
77afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
78afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Microsoft PS/2 style mouse
79afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
80afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  case EISA_PNP_ID (0xF13):
81afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
82afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    // PS/2 Port for PS/2-style Mice
83afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
84afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    break;
85afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
86afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  case EISA_PNP_ID (0x303):
87afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
88afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    // IBM Enhanced (101/102-key, PS/2 mouse support)
89afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
90afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    if (IsaIo->ResourceList->Device.UID == 1) {
91afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      break;
92afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    }
93afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
94afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  default:
95afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = EFI_UNSUPPORTED;
96afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    break;
97afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
98afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
99afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Close the I/O Abstraction(s) used to perform the supported test
100afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
101afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->CloseProtocol (
102afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller,
103afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         &gEfiIsaIoProtocolGuid,
104afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         This->DriverBindingHandle,
105afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller
106afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         );
107afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
108afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return Status;
109afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
110afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
111bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
112cab302fd4cb652cd05d2d0ff1629fda07d4e330ceric_tian  Start this driver on ControllerHandle by opening a IsaIo protocol, creating
113cab302fd4cb652cd05d2d0ff1629fda07d4e330ceric_tian  PS2_MOUSE_ABSOLUTE_POINTER_DEV device and install gEfiAbsolutePointerProtocolGuid
114cab302fd4cb652cd05d2d0ff1629fda07d4e330ceric_tian  finally.
115bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
116bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  This                 Protocol instance pointer.
117bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  ControllerHandle     Handle of device to bind driver to
118bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  RemainingDevicePath  Optional parameter use to pick a specific child
119bcd70414877e56f3bffff0bf11b07a30ef51a68fklu                               device to start.
120bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
121bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_SUCCESS          This driver is added to ControllerHandle
122bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
123bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval other                This driver does not support this device
124bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
125bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
126afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFI_STATUS
127afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFIAPI
128afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianPS2MouseAbsolutePointerDriverStart (
129afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
130afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_HANDLE                     Controller,
131afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
132afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  )
133afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
134afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS                          Status;
135afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS                          EmptyStatus;
136afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_ISA_IO_PROTOCOL                 *IsaIo;
137afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2_MOUSE_ABSOLUTE_POINTER_DEV     *MouseAbsolutePointerDev;
138afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  UINT8                               Data;
139afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_TPL                             OldTpl;
140afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS_CODE_VALUE               StatusCode;
141afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
142afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
143afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  StatusCode  = 0;
144afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev    = NULL;
145afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IsaIo       = NULL;
146afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
147afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
148afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Open the device path protocol
149afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
150afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->OpenProtocol (
151afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
152afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &gEfiDevicePathProtocolGuid,
153afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  (VOID **) &ParentDevicePath,
154afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  This->DriverBindingHandle,
155afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
156afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  EFI_OPEN_PROTOCOL_BY_DRIVER
157afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
158afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
159afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return Status;
160afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
161afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
162afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Report that the keyboard is being enabled
163afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
164afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
165afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PROGRESS_CODE,
166afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE,
167afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    ParentDevicePath
168afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    );
169afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
170afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
171afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Get the ISA I/O Protocol on Controller's handle
172afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
173afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->OpenProtocol (
174afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
175afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &gEfiIsaIoProtocolGuid,
176afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  (VOID **) &IsaIo,
177afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  This->DriverBindingHandle,
178afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
179afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  EFI_OPEN_PROTOCOL_BY_DRIVER
180afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
181afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
182afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    gBS->CloseProtocol (
183afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian           Controller,
184afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian           &gEfiDevicePathProtocolGuid,
185afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian           This->DriverBindingHandle,
186afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian           Controller
187afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian           );
188afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return EFI_INVALID_PARAMETER;
189afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
190afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
191afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Raise TPL to avoid keyboard operation impact
192afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
193afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
194afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
195afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
196afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Allocate private data
197afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
198afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev = AllocateZeroPool (sizeof (PS2_MOUSE_ABSOLUTE_POINTER_DEV));
199afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (MouseAbsolutePointerDev == NULL) {
200afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = EFI_OUT_OF_RESOURCES;
201afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    goto ErrorExit;
202afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
203afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
204afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Setup the device instance
205afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
206afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Signature       = PS2_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE;
207afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Handle          = Controller;
2083ae9910225f4bb39815dfb23f2fd9e712b9d75d2eric_tian  MouseAbsolutePointerDev->SampleRate      = SampleRate20;
2093ae9910225f4bb39815dfb23f2fd9e712b9d75d2eric_tian  MouseAbsolutePointerDev->Resolution      = MouseResolution4;
2103ae9910225f4bb39815dfb23f2fd9e712b9d75d2eric_tian  MouseAbsolutePointerDev->Scaling         = Scaling1;
211afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->DataPackageSize = 3;
212afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->IsaIo           = IsaIo;
213afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->DevicePath      = ParentDevicePath;
214afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
215afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
216afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Resolution = 4 counts/mm
217afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
218afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Mode.AbsoluteMaxX               = 1024;
219afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Mode.AbsoluteMinX               = 0;
220afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Mode.AbsoluteMaxY               = 798;
221afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Mode.AbsoluteMinY               = 0;
222afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Mode.AbsoluteMaxZ               = 0;
223afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Mode.AbsoluteMinZ               = 0;
224afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->Mode.Attributes                 = 0x03;
225afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
226afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset     = MouseAbsolutePointerReset;
227afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->AbsolutePointerProtocol.GetState  = MouseAbsolutePointerGetState;
228afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->AbsolutePointerProtocol.Mode      = &(MouseAbsolutePointerDev->Mode);
229afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
230afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
231afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Initialize keyboard controller if necessary
232afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
2334bb5fd6754ce131eb8129fc64287bc89a0f5e78fli-elvin  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2344bb5fd6754ce131eb8129fc64287bc89a0f5e78fli-elvin    EFI_PROGRESS_CODE,
2354bb5fd6754ce131eb8129fc64287bc89a0f5e78fli-elvin    EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST,
2364bb5fd6754ce131eb8129fc64287bc89a0f5e78fli-elvin    ParentDevicePath
2374bb5fd6754ce131eb8129fc64287bc89a0f5e78fli-elvin    );
2384bb5fd6754ce131eb8129fc64287bc89a0f5e78fli-elvin
239afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
240afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if ((Data & KBC_SYSF) != KBC_SYSF) {
241afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = KbcSelfTest (IsaIo);
242afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    if (EFI_ERROR (Status)) {
243afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;
244afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      goto ErrorExit;
245afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    }
246afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
247afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
248afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  KbcEnableAux (IsaIo);
249afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
250afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
251afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PROGRESS_CODE,
252afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,
253afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    ParentDevicePath
254afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    );
255afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
256afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
257afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Reset the mouse
258afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
259ace74c67ba8a9ec8a183945a2d4e2f8fa18b3da7li-elvin  Status = MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset (
260ace74c67ba8a9ec8a183945a2d4e2f8fa18b3da7li-elvin                     &MouseAbsolutePointerDev->AbsolutePointerProtocol,
261ace74c67ba8a9ec8a183945a2d4e2f8fa18b3da7li-elvin                     FeaturePcdGet (PcdPs2MouseExtendedVerification)
262ace74c67ba8a9ec8a183945a2d4e2f8fa18b3da7li-elvin                     );
263afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
264afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
265afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    // mouse not connected
266afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
267afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status      = EFI_SUCCESS;
268afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    StatusCode  = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;
269afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    goto ErrorExit;
270afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
271cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvin
272cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvin  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
273cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvin    EFI_PROGRESS_CODE,
274cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvin    EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED,
275cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvin    ParentDevicePath
276cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvin    );
277cb38c322f037a9a5d2751a4c7e351b0ee7302e96li-elvin
278afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
279afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Setup the WaitForKey event
280afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
281afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->CreateEvent (
282afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  EVT_NOTIFY_WAIT,
283afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  TPL_NOTIFY,
284afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  MouseAbsolutePointerWaitForInput,
285afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  MouseAbsolutePointerDev,
286afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &((MouseAbsolutePointerDev->AbsolutePointerProtocol).WaitForInput)
287afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
288afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
289afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = EFI_OUT_OF_RESOURCES;
290afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    goto ErrorExit;
291afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
292afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
293afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Setup a periodic timer, used to poll mouse state
294afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
295afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->CreateEvent (
296afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
297afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  TPL_NOTIFY,
298afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  PollMouseAbsolutePointer,
299afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  MouseAbsolutePointerDev,
300afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &MouseAbsolutePointerDev->TimerEvent
301afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
302afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
303afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = EFI_OUT_OF_RESOURCES;
304afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    goto ErrorExit;
305afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
306afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
307afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Start timer to poll mouse (100 samples per second)
308afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
309afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerPeriodic, 100000);
310afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
311afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = EFI_OUT_OF_RESOURCES;
312afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    goto ErrorExit;
313afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
314afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
315afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->ControllerNameTable = NULL;
316afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  AddUnicodeString2 (
317afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    "eng",
318afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    gPs2MouseAbsolutePointerComponentName.SupportedLanguages,
319afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    &MouseAbsolutePointerDev->ControllerNameTable,
320afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    L"Faked PS/2 Touchpad Device",
321afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    TRUE
322afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    );
323afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  AddUnicodeString2 (
324afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    "en",
325afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    gPs2MouseAbsolutePointerComponentName2.SupportedLanguages,
326afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    &MouseAbsolutePointerDev->ControllerNameTable,
327afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    L"Faked PS/2 Touchpad Device",
328afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    FALSE
329afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    );
330afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
331afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
332afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
333afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Install protocol interfaces for the mouse device.
334afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
335afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->InstallMultipleProtocolInterfaces (
336afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &Controller,
337afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &gEfiAbsolutePointerProtocolGuid,
338afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &MouseAbsolutePointerDev->AbsolutePointerProtocol,
339afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  NULL
340afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
341afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
342afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    goto ErrorExit;
343afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
344afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
345afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->RestoreTPL (OldTpl);
346afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
347afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return Status;
348afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
349afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianErrorExit:
350afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
351afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  KbcDisableAux (IsaIo);
352afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
353afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (StatusCode != 0) {
354afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
355afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      EFI_ERROR_CODE | EFI_ERROR_MINOR,
356afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      StatusCode,
357afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      ParentDevicePath
358afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      );
359afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
360afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
361afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput != NULL)) {
362afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);
363afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
364afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
365afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->TimerEvent != NULL)) {
366afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);
367afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
368afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
369afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->ControllerNameTable != NULL)) {
370afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);
371afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
372afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
373afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Since there will be no timer handler for mouse input any more,
374afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // exhaust input data just in case there is still mouse data left
375afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
376afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EmptyStatus = EFI_SUCCESS;
377afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  while (!EFI_ERROR (EmptyStatus)) {
378afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EmptyStatus = In8042Data (IsaIo, &Data);
379afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
380afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
381afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (MouseAbsolutePointerDev != NULL) {
382cab302fd4cb652cd05d2d0ff1629fda07d4e330ceric_tian    FreePool (MouseAbsolutePointerDev);
383afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
384afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
385afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->CloseProtocol (
386afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller,
387afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         &gEfiDevicePathProtocolGuid,
388afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         This->DriverBindingHandle,
389afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller
390afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         );
391afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
392afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->CloseProtocol (
393afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller,
394afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         &gEfiIsaIoProtocolGuid,
395afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         This->DriverBindingHandle,
396afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller
397afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         );
398afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
399afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->RestoreTPL (OldTpl);
400afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
401afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return Status;
402afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
403afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
404bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
405bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  Stop this driver on ControllerHandle. Support stoping any child handles
406bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  created by this driver.
407bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
408bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  This              Protocol instance pointer.
409bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  ControllerHandle  Handle of device to stop driver on
410bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
411bcd70414877e56f3bffff0bf11b07a30ef51a68fklu                            children is zero stop the entire bus driver.
412bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param  ChildHandleBuffer List of Child Handles to Stop.
413bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
414bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_SUCCESS       This driver is removed ControllerHandle
415bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval other             This driver was not removed from this device
416bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
417bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
418afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFI_STATUS
419afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFIAPI
420afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianPS2MouseAbsolutePointerDriverStop (
421afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
422afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_HANDLE                     Controller,
423afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN UINTN                          NumberOfChildren,
424afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_HANDLE                     *ChildHandleBuffer
425afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  )
426afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
427afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS                            Status;
428afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_ABSOLUTE_POINTER_PROTOCOL         *AbsolutePointerProtocol;
429afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2_MOUSE_ABSOLUTE_POINTER_DEV       *MouseAbsolutePointerDev;
430afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  UINT8                                 Data;
431afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
432afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->OpenProtocol (
433afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
434afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &gEfiAbsolutePointerProtocolGuid,
435afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  (VOID **) &AbsolutePointerProtocol,
436afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  This->DriverBindingHandle,
437afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
438afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
439afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
440afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
441afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return EFI_SUCCESS;
442afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
443afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
444afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (AbsolutePointerProtocol);
445afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
446afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
447afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Report that the keyboard is being disabled
448afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
449afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
450afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PROGRESS_CODE,
451afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,
452afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    MouseAbsolutePointerDev->DevicePath
453afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    );
454afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
455afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = gBS->UninstallProtocolInterface (
456afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  Controller,
457afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &gEfiAbsolutePointerProtocolGuid,
458afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  &MouseAbsolutePointerDev->AbsolutePointerProtocol
459afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian                  );
460afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (EFI_ERROR (Status)) {
461afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return Status;
462afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
463afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
464afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
465afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Cancel mouse data polling timer, close timer event
466afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
467afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerCancel, 0);
468afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);
469afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
470afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
471afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Since there will be no timer handler for mouse input any more,
472afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // exhaust input data just in case there is still mouse data left
473afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
474afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = EFI_SUCCESS;
475afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  while (!EFI_ERROR (Status)) {
476afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);
477afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
478afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
479afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);
480afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);
481cab302fd4cb652cd05d2d0ff1629fda07d4e330ceric_tian  FreePool (MouseAbsolutePointerDev);
482afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
483afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->CloseProtocol (
484afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller,
485afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         &gEfiDevicePathProtocolGuid,
486afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         This->DriverBindingHandle,
487afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller
488afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         );
489afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
490afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->CloseProtocol (
491afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller,
492afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         &gEfiIsaIoProtocolGuid,
493afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         This->DriverBindingHandle,
494afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         Controller
495afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian         );
496afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
497afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return EFI_SUCCESS;
498afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
499afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
500bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
50118a73eb727e697f15891ccad55507ae3d8c37461eric_tian  Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system.
502bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
503bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param This                 - Pointer of simple pointer Protocol.
504bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.
505bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
506bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
507bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_SUCCESS         - The command byte is written successfully.
508bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_DEVICE_ERROR    - Errors occurred during reseting keyboard.
509bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
510bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
511afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFI_STATUS
512afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFIAPI
513afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianMouseAbsolutePointerReset (
514afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_ABSOLUTE_POINTER_PROTOCOL    *This,
515afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN BOOLEAN                          ExtendedVerification
516afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  )
517afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
518afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS                       Status;
519afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2_MOUSE_ABSOLUTE_POINTER_DEV  *MouseAbsolutePointerDev;
520afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_TPL                          OldTpl;
521afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  BOOLEAN                          KeyboardEnable;
522afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  UINT8                            Data;
523afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
524afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);
525afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
526afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
527afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Report reset progress code
528afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
529afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
530afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PROGRESS_CODE,
531afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,
532afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    MouseAbsolutePointerDev->DevicePath
533afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    );
534afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
535afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  KeyboardEnable = FALSE;
536afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
537afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
538afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Raise TPL to avoid keyboard operation impact
539afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
540afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
541afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
542afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  ZeroMem (&MouseAbsolutePointerDev->State, sizeof (EFI_ABSOLUTE_POINTER_STATE));
543afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->StateChanged = FALSE;
544afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
545afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
546afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Exhaust input data
547afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
548afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = EFI_SUCCESS;
549afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  while (!EFI_ERROR (Status)) {
550afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);
551afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
552afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
553afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);
554afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
555afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  KbcDisableKb (MouseAbsolutePointerDev->IsaIo);
556afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
557afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
558afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
559afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
560afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // if there's data block on KBC data port, read it out
561afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
562afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if ((Data & KBC_OUTB) == KBC_OUTB) {
563afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data);
564afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
565afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
566afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = EFI_SUCCESS;
567afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
568afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.
569afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is
570afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling
571afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
572afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (ExtendedVerification && CheckMouseAbsolutePointerConnect (MouseAbsolutePointerDev)) {
573afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
574afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    // Send mouse reset command and set mouse default configure
575afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    //
576afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = PS2MouseReset (MouseAbsolutePointerDev->IsaIo);
577afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    if (EFI_ERROR (Status)) {
578afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      Status = EFI_DEVICE_ERROR;
579afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      goto Exit;
580afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    }
581afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
582afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = PS2MouseSetSampleRate (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->SampleRate);
583afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    if (EFI_ERROR (Status)) {
584afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      Status = EFI_DEVICE_ERROR;
585afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      goto Exit;
586afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    }
587afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
588afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = PS2MouseSetResolution (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Resolution);
589afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    if (EFI_ERROR (Status)) {
590afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      Status = EFI_DEVICE_ERROR;
591afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      goto Exit;
592afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    }
593afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
594afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = PS2MouseSetScaling (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Scaling);
595afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    if (EFI_ERROR (Status)) {
596afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      Status = EFI_DEVICE_ERROR;
597afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      goto Exit;
598afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    }
599afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
600afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);
601afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    if (EFI_ERROR (Status)) {
602afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      Status = EFI_DEVICE_ERROR;
603afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian      goto Exit;
604afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    }
605afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
606afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianExit:
607afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->RestoreTPL (OldTpl);
608afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
609afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (KeyboardEnable) {
610afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
611afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
612afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
613afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return Status;
614afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
615afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
616bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
617afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Check whether there is Ps/2 mouse device in system
618afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
61918a73eb727e697f15891ccad55507ae3d8c37461eric_tian  @param MouseAbsolutePointerDev - Absolute Pointer Device Private Data Structure
620afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
621bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval TRUE                - Keyboard in System.
622bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval FALSE               - Keyboard not in System.
623afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
624bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
625bcd70414877e56f3bffff0bf11b07a30ef51a68fkluBOOLEAN
626bcd70414877e56f3bffff0bf11b07a30ef51a68fkluCheckMouseAbsolutePointerConnect (
627bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  IN  PS2_MOUSE_ABSOLUTE_POINTER_DEV     *MouseAbsolutePointerDev
628bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  )
629afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
630afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
631afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS     Status;
632afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
633afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);
634afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (!EFI_ERROR (Status)) {
635afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return TRUE;
636afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
637afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
638afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return FALSE;
639afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
640afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
641bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
642bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  Get and Clear mouse status.
643bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
644bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param This                 - Pointer of simple pointer Protocol.
645bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param State                - Output buffer holding status.
646bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
647bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_INVALID_PARAMETER Output buffer is invalid.
648bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_NOT_READY         Mouse is not changed status yet.
649bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @retval EFI_SUCCESS           Mouse status is changed and get successful.
650bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
651afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFI_STATUS
652afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFIAPI
653afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianMouseAbsolutePointerGetState (
654afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_ABSOLUTE_POINTER_PROTOCOL     *This,
655afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN OUT EFI_ABSOLUTE_POINTER_STATE    *State
656afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  )
657afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
658afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;
659afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_TPL       OldTpl;
660afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
661afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);
662afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
663afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (State == NULL) {
664afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return EFI_INVALID_PARAMETER;
665afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
666afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
667afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (!MouseAbsolutePointerDev->StateChanged) {
668afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    return EFI_NOT_READY;
669afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
670afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
671afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
672afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  CopyMem (State, &(MouseAbsolutePointerDev->State), sizeof (EFI_ABSOLUTE_POINTER_STATE));
673afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
674afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
675afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // clear mouse state
676afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
677afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->State.CurrentX = 0;
678afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->State.CurrentY = 0;
679afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->State.CurrentZ = 0;
680afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->State.ActiveButtons = 0x0;
681afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev->StateChanged            = FALSE;
682afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  gBS->RestoreTPL (OldTpl);
683afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
684afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return EFI_SUCCESS;
685afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
686afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
687bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
688afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
68918a73eb727e697f15891ccad55507ae3d8c37461eric_tian  Event notification function for SIMPLE_POINTER.WaitForInput event.
69018a73eb727e697f15891ccad55507ae3d8c37461eric_tian  Signal the event if there is input from mouse.
691afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
692bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param Event    event object
693bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param Context  event context
694afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
695bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
696bcd70414877e56f3bffff0bf11b07a30ef51a68fkluVOID
697bcd70414877e56f3bffff0bf11b07a30ef51a68fkluEFIAPI
698bcd70414877e56f3bffff0bf11b07a30ef51a68fkluMouseAbsolutePointerWaitForInput (
699bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  IN  EFI_EVENT               Event,
700bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  IN  VOID                    *Context
701bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  )
702afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
703afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;
704afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
705afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;
706afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
707afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
708afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Someone is waiting on the mouse event, if there's
709afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // input from mouse, signal the event
710afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
711afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  if (MouseAbsolutePointerDev->StateChanged) {
712afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian    gBS->SignalEvent (Event);
713afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  }
714afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
715afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
716afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
717bcd70414877e56f3bffff0bf11b07a30ef51a68fklu/**
71818a73eb727e697f15891ccad55507ae3d8c37461eric_tian  Event notification function for TimerEvent event.
71918a73eb727e697f15891ccad55507ae3d8c37461eric_tian  If mouse device is connected to system, try to get the mouse packet data.
720bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
721bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param Event      -  TimerEvent in PS2_MOUSE_DEV
722bcd70414877e56f3bffff0bf11b07a30ef51a68fklu  @param Context    -  Pointer to PS2_MOUSE_DEV structure
723bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
724bcd70414877e56f3bffff0bf11b07a30ef51a68fklu**/
725afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianVOID
726afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFIAPI
727afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianPollMouseAbsolutePointer(
728afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_EVENT  Event,
729afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN VOID       *Context
730afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  )
731afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
732afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
733afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev;
734afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
735afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  MouseAbsolutePointerDev = (PS2_MOUSE_ABSOLUTE_POINTER_DEV *) Context;
736afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
737afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
738afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Polling mouse packet data
739afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
740afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  PS2MouseGetPacket (MouseAbsolutePointerDev);
741afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
742afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
743afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian/**
744afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  The user Entry Point for module Ps2MouseAbsolutePointer. The user code starts with this function.
745afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
746afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
747afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  @param[in] SystemTable    A pointer to the EFI System Table.
748afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
749afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  @retval EFI_SUCCESS       The entry point is executed successfully.
750afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  @retval other             Some error occurs when executing this entry point.
751afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
752afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian**/
753afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFI_STATUS
754afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianEFIAPI
755afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tianInitializePs2MouseAbsolutePointer(
756afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_HANDLE           ImageHandle,
757afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  IN EFI_SYSTEM_TABLE     *SystemTable
758afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  )
759afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian{
760afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  EFI_STATUS              Status;
761afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
762afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
763afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  // Install driver model protocol(s).
764afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  //
765afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  Status = EfiLibInstallDriverBindingComponentName2 (
766afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian             ImageHandle,
767afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian             SystemTable,
768afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian             &gPS2MouseAbsolutePointerDriver,
769afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian             ImageHandle,
770afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian             &gPs2MouseAbsolutePointerComponentName,
771afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian             &gPs2MouseAbsolutePointerComponentName2
772afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian             );
773afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  ASSERT_EFI_ERROR (Status);
774afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
775afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian
776afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian  return Status;
777afd0fe223066cfae5eac42bc5751eb3d0a758096eric_tian}
778bcd70414877e56f3bffff0bf11b07a30ef51a68fklu
779