ps2mouse.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 769 行 · 第 1/2 页
C
769 行
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Ps2Mouse.c
Abstract:
PS/2 Mouse driver. Routines that interacts with callers,
conforming to EFI driver model
--*/
#include "Ps2Mouse.h"
#include "CommPs2.h"
//
// DriverBinding Protocol Instance
//
EFI_DRIVER_BINDING_PROTOCOL gPS2MouseDriver = {
PS2MouseDriverSupported,
PS2MouseDriverStart,
PS2MouseDriverStop,
0x10,
NULL,
NULL
};
EFI_STATUS
EFIAPI
PS2MouseDriverSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
ControllerDriver Protocol Method
Arguments:
Returns:
--*/
// GC_TODO: This - add argument and description to function comment
// GC_TODO: Controller - add argument and description to function comment
// GC_TODO: RemainingDevicePath - add argument and description to function comment
{
EFI_STATUS Status;
EFI_INTERFACE_DEFINITION_FOR_ISA_IO *IsaIo;
Status = EFI_SUCCESS;
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
Controller,
EFI_ISA_IO_PROTOCOL_VERSION,
(VOID **) &IsaIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Use the ISA I/O Protocol to see if Controller is the Keyboard controller
//
switch (IsaIo->ResourceList->Device.HID) {
case EISA_PNP_ID (0xF03):
//
// Microsoft PS/2 style mouse
//
case EISA_PNP_ID (0xF13):
//
// PS/2 Port for PS/2-style Mice
//
break;
case EISA_PNP_ID (0x303):
//
// IBM Enhanced (101/102-key, PS/2 mouse support)
//
if (IsaIo->ResourceList->Device.UID == 1) {
break;
}
default:
Status = EFI_UNSUPPORTED;
break;
}
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
Controller,
EFI_ISA_IO_PROTOCOL_VERSION,
This->DriverBindingHandle,
Controller
);
return Status;
}
EFI_STATUS
EFIAPI
PS2MouseDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Start protocol interfaces for the mouse device handles.
Arguments:
This - Protocol instance pointer.
Controller - Handle of device to bind driver to.
RemainingDevicePath - Not used.
Returns:
EFI_SUCCESS - This driver is added to DeviceHandle.
other - Errors occurred.
--*/
{
EFI_STATUS Status;
EFI_STATUS EmptyStatus;
EFI_INTERFACE_DEFINITION_FOR_ISA_IO *IsaIo;
PS2_MOUSE_DEV *MouseDev;
UINT8 Data;
EFI_TPL OldTpl;
EFI_STATUS_CODE_VALUE StatusCode;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
StatusCode = 0;
MouseDev = NULL;
IsaIo = NULL;
//
// Open the device path protocol
//
Status = gBS->OpenProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **) &ParentDevicePath,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Report that the keyboard is being enabled
//
ReportStatusCodeWithDevicePath (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE,
0,
&gEfiCallerIdGuid,
ParentDevicePath
);
//
// Get the ISA I/O Protocol on Controller's handle
//
Status = gBS->OpenProtocol (
Controller,
EFI_ISA_IO_PROTOCOL_VERSION,
(VOID **) &IsaIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_INVALID_PARAMETER;
}
//
// Raise TPL to avoid keyboard operation impact
//
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
//
// Allocate private data
//
MouseDev = EfiLibAllocateZeroPool (sizeof (PS2_MOUSE_DEV));
if (MouseDev == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Setup the device instance
//
MouseDev->Signature = PS2_MOUSE_DEV_SIGNATURE;
MouseDev->Handle = Controller;
MouseDev->SampleRate = SSR_20;
MouseDev->Resolution = CMR4;
MouseDev->Scaling = SF1;
MouseDev->DataPackageSize = 3;
MouseDev->IsaIo = IsaIo;
MouseDev->DevicePath = ParentDevicePath;
//
// Resolution = 4 counts/mm
//
MouseDev->Mode.ResolutionX = 4;
MouseDev->Mode.ResolutionY = 4;
MouseDev->Mode.LeftButton = TRUE;
MouseDev->Mode.RightButton = TRUE;
MouseDev->SimplePointerProtocol.Reset = MouseReset;
MouseDev->SimplePointerProtocol.GetState = MouseGetState;
MouseDev->SimplePointerProtocol.Mode = &(MouseDev->Mode);
//
// Initialize keyboard controller if necessary
//
IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
if ((Data & KBC_SYSF) != KBC_SYSF) {
Status = KbcSelfTest (IsaIo);
if (EFI_ERROR (Status)) {
StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;
goto ErrorExit;
}
}
KbcEnableAux (IsaIo);
ReportStatusCodeWithDevicePath (
EFI_PROGRESS_CODE,
EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,
0,
&gEfiCallerIdGuid,
ParentDevicePath
);
//
// Reset the mouse
//
Status = MouseDev->SimplePointerProtocol.Reset (&MouseDev->SimplePointerProtocol, TRUE);
if (EFI_ERROR (Status)) {
//
// mouse not connected
//
Status = EFI_SUCCESS;
StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;
goto ErrorExit;
}
//
// Setup the WaitForKey event
//
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_WAIT,
EFI_TPL_NOTIFY,
MouseWaitForInput,
MouseDev,
&((MouseDev->SimplePointerProtocol).WaitForInput)
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Setup a periodic timer, used to poll mouse state
//
Status = gBS->CreateEvent (
EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_NOTIFY,
PollMouse,
MouseDev,
&MouseDev->TimerEvent
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Start timer to poll mouse (100 samples per second)
//
Status = gBS->SetTimer (MouseDev->TimerEvent, TimerPeriodic, 100000);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
MouseDev->ControllerNameTable = NULL;
EfiLibAddUnicodeString (
"eng",
gPs2MouseComponentName.SupportedLanguages,
&MouseDev->ControllerNameTable,
L"PS/2 Mouse Device"
);
//
// Install protocol interfaces for the keyboard device.
//
Status = gBS->InstallMultipleProtocolInterfaces (
&Controller,
&gEfiSimplePointerProtocolGuid,
&MouseDev->SimplePointerProtocol,
NULL
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
gBS->RestoreTPL (OldTpl);
return Status;
ErrorExit:
KbcDisableAux (IsaIo);
if (StatusCode != 0) {
ReportStatusCodeWithDevicePath (
EFI_ERROR_CODE | EFI_ERROR_MINOR,
StatusCode,
0,
&gEfiCallerIdGuid,
ParentDevicePath
);
}
if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) {
gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);
}
if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) {
gBS->CloseEvent (MouseDev->TimerEvent);
}
if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) {
EfiLibFreeUnicodeStringTable (MouseDev->ControllerNameTable);
}
//
// Since there will be no timer handler for mouse input any more,
// exhaust input data just in case there is still mouse data left
//
EmptyStatus = EFI_SUCCESS;
while (!EFI_ERROR (EmptyStatus)) {
EmptyStatus = In8042Data (IsaIo, &Data);
}
if (MouseDev != NULL) {
gBS->FreePool (MouseDev);
}
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->CloseProtocol (
Controller,
EFI_ISA_IO_PROTOCOL_VERSION,
This->DriverBindingHandle,
Controller
);
gBS->RestoreTPL (OldTpl);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?