ps2mouse.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 769 行 · 第 1/2 页
C
769 行
return Status;
}
EFI_STATUS
EFIAPI
PS2MouseDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
Returns:
--*/
// GC_TODO: This - add argument and description to function comment
// GC_TODO: Controller - add argument and description to function comment
// GC_TODO: NumberOfChildren - add argument and description to function comment
// GC_TODO: ChildHandleBuffer - add argument and description to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
EFI_STATUS Status;
EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;
PS2_MOUSE_DEV *MouseDev;
UINT8 Data;
Status = gBS->OpenProtocol (
Controller,
&gEfiSimplePointerProtocolGuid,
(VOID **) &SimplePointerProtocol,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
MouseDev = PS2_MOUSE_DEV_FROM_THIS (SimplePointerProtocol);
//
// Report that the keyboard is being disabled
//
ReportStatusCodeWithDevicePath (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,
0,
&gEfiCallerIdGuid,
MouseDev->DevicePath
);
Status = gBS->UninstallProtocolInterface (
Controller,
&gEfiSimplePointerProtocolGuid,
&MouseDev->SimplePointerProtocol
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Disable mouse on keyboard controller
//
KbcDisableAux (MouseDev->IsaIo);
//
// Cancel mouse data polling timer, close timer event
//
gBS->SetTimer (MouseDev->TimerEvent, TimerCancel, 0);
gBS->CloseEvent (MouseDev->TimerEvent);
//
// Since there will be no timer handler for mouse input any more,
// exhaust input data just in case there is still mouse data left
//
Status = EFI_SUCCESS;
while (!EFI_ERROR (Status)) {
Status = In8042Data (MouseDev->IsaIo, &Data);
}
gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);
EfiLibFreeUnicodeStringTable (MouseDev->ControllerNameTable);
gBS->FreePool (MouseDev);
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->CloseProtocol (
Controller,
EFI_ISA_IO_PROTOCOL_VERSION,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
MouseReset (
IN EFI_SIMPLE_POINTER_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system
Arguments:
This - Pointer of simple pointer Protocol.
ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.
Returns:
EFI_SUCCESS - The command byte is written successfully.
EFI_DEVICE_ERROR - Errors occurred during reseting keyboard.
--*/
{
EFI_STATUS Status;
PS2_MOUSE_DEV *MouseDev;
EFI_TPL OldTpl;
BOOLEAN KeyboardEnable;
UINT8 Data;
MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);
//
// Report reset progress code
//
ReportStatusCodeWithDevicePath (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,
0,
&gEfiCallerIdGuid,
MouseDev->DevicePath
);
KeyboardEnable = FALSE;
//
// Raise TPL to avoid keyboard operation impact
//
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
EfiZeroMem (&MouseDev->State, sizeof (EFI_SIMPLE_POINTER_STATE));
MouseDev->StateChanged = FALSE;
//
// Exhaust input data
//
Status = EFI_SUCCESS;
while (!EFI_ERROR (Status)) {
Status = In8042Data (MouseDev->IsaIo, &Data);
}
CheckKbStatus (MouseDev->IsaIo, &KeyboardEnable);
KbcDisableKb (MouseDev->IsaIo);
MouseDev->IsaIo->Io.Read (MouseDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
//
// if there's data block on KBC data port, read it out
//
if ((Data & KBC_OUTB) == KBC_OUTB) {
MouseDev->IsaIo->Io.Read (MouseDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data);
}
Status = EFI_SUCCESS;
//
// The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.
// This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is
// connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling
//
if (ExtendedVerification && CheckMouseConnect (MouseDev)) {
//
// Send mouse reset command and set mouse default configure
//
Status = PS2MouseReset (MouseDev->IsaIo);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto Exit;
}
Status = PS2MouseSetSampleRate (MouseDev->IsaIo, MouseDev->SampleRate);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto Exit;
}
Status = PS2MouseSetResolution (MouseDev->IsaIo, MouseDev->Resolution);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto Exit;
}
Status = PS2MouseSetScaling (MouseDev->IsaIo, MouseDev->Scaling);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto Exit;
}
Status = PS2MouseEnable (MouseDev->IsaIo);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto Exit;
}
}
Exit:
gBS->RestoreTPL (OldTpl);
if (KeyboardEnable) {
KbcEnableKb (MouseDev->IsaIo);
}
return Status;
}
BOOLEAN
CheckMouseConnect (
IN PS2_MOUSE_DEV *MouseDev
)
/*++
Routine Description:
Check whether there is Ps/2 mouse device in system
Arguments:
PS2_MOUSE_DEV - Mouse Private Data Structure
Returns:
TRUE - Keyboard in System.
FALSE - Keyboard not in System.
--*/
{
EFI_STATUS Status;
Status = PS2MouseEnable (MouseDev->IsaIo);
if (!EFI_ERROR (Status)) {
return TRUE;
}
return FALSE;
}
EFI_STATUS
EFIAPI
MouseGetState (
IN EFI_SIMPLE_POINTER_PROTOCOL *This,
IN OUT EFI_SIMPLE_POINTER_STATE *State
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
This - GC_TODO: add argument description
State - GC_TODO: add argument description
Returns:
EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
EFI_NOT_READY - GC_TODO: Add description for return value
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
PS2_MOUSE_DEV *MouseDev;
EFI_TPL OldTpl;
MouseDev = PS2_MOUSE_DEV_FROM_THIS (This);
if (State == NULL) {
return EFI_INVALID_PARAMETER;
}
if (!MouseDev->StateChanged) {
return EFI_NOT_READY;
}
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
EfiCopyMem (State, &(MouseDev->State), sizeof (EFI_SIMPLE_POINTER_STATE));
//
// clear mouse state
//
MouseDev->State.RelativeMovementX = 0;
MouseDev->State.RelativeMovementY = 0;
MouseDev->State.RelativeMovementZ = 0;
MouseDev->StateChanged = FALSE;
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
}
VOID
EFIAPI
MouseWaitForInput (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Event notification function for SIMPLE_POINTER.WaitForInput event
Signal the event if there is input from mouse
Arguments:
Returns:
--*/
// GC_TODO: Event - add argument and description to function comment
// GC_TODO: Context - add argument and description to function comment
{
PS2_MOUSE_DEV *MouseDev;
MouseDev = (PS2_MOUSE_DEV *) Context;
//
// Someone is waiting on the mouse event, if there's
// input from mouse, signal the event
//
if (MouseDev->StateChanged) {
gBS->SignalEvent (Event);
}
}
VOID
EFIAPI
PollMouse (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Event notification function for TimerEvent event
If mouse device is connected to system, try to get the mouse packet data
Arguments:
Event - TimerEvent in PS2_MOUSE_DEV
Context - Pointer to PS2_MOUSE_DEV structure
Returns:
None
--*/
{
PS2_MOUSE_DEV *MouseDev;
MouseDev = (PS2_MOUSE_DEV *) Context;
//
// Polling mouse packet data
//
PS2MouseGetPacket (MouseDev);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?