⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbmouse.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.


  Module Name:

    UsbMouse.c

  Abstract:

--*/

#include "Efi.h"
#include "EfiDriverLib.h"
#include "EfiPrintLib.h"

#include "usb.h"

//
// Driver Consumed Protocol Prototypes
//
#include EFI_PROTOCOL_DEFINITION(DriverBinding)
#include EFI_PROTOCOL_DEFINITION(UsbIo)

//
// Driver Produced Protocol Prototypes
//
#include EFI_PROTOCOL_DEFINITION(SimplePointer)

#include "usblib.h"
#include "hid.h"
#include "usbmouse.h"
#include "mousehid.h"

//
// Prototypes
// Driver model protocol interface
//
EFI_STATUS
USBMouseDriverBindingEntryPoint(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  );

EFI_STATUS
USBMouseDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  );

EFI_STATUS
USBMouseDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  );

EFI_STATUS
USBMouseDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    Controller,
  IN  UINTN                         NumberOfChildren,
  IN  EFI_HANDLE                    *ChildHandleBuffer
  );

EFI_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding = {
  USBMouseDriverBindingSupported,
  USBMouseDriverBindingStart,
  USBMouseDriverBindingStop,
  0x10,
  NULL,
  NULL
};

//
// helper functions
//
static BOOLEAN
IsUsbMouse (
  IN  EFI_USB_IO_PROTOCOL     *UsbIo
  );

static EFI_STATUS
InitializeUsbMouseDevice (
  IN  USB_MOUSE_DEV           *UsbMouseDev
  );

static VOID
EFIAPI
UsbMouseWaitForInput (
  IN  EFI_EVENT               Event,
  IN  VOID                    *Context
  );

//
// Mouse interrupt handler
//
static EFI_STATUS
OnMouseInterruptComplete (
  IN  VOID        *Data,
  IN  UINTN       DataLength,
  IN  VOID        *Context,
  IN  UINT32      Result
  );

//
// Mouse Protocol
//
static EFI_STATUS
GetMouseState(
  IN   EFI_SIMPLE_POINTER_PROTOCOL  *This,
  OUT  EFI_SIMPLE_POINTER_STATE     *MouseState
);

static EFI_STATUS
UsbMouseReset(
  IN EFI_SIMPLE_POINTER_PROTOCOL    *This,
  IN BOOLEAN                        ExtendedVerification
  );

//
// Driver start here
//
EFI_DRIVER_ENTRY_POINT(USBMouseDriverBindingEntryPoint)

EFI_STATUS
USBMouseDriverBindingEntryPoint(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
/*++

Routine Description:
  Register Driver Binding protocol for this driver.

Arguments:
  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

Returns:
  EFI_SUCCESS - Driver loaded
  other       - Driver not loaded

--*/
{
  return EfiLibInstallAllDriverProtocols (
           ImageHandle, 
           SystemTable, 
           &gUsbMouseDriverBinding, 
           ImageHandle,
           &gUsbMouseComponentName,
           NULL,
           NULL
         );
}


EFI_STATUS
USBMouseDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
/*++

  Routine Description:
    Test to see if this driver supports ControllerHandle. Any ControllerHandle
    than contains a BlockIo and DiskIo protocol can be supported.

  Arguments:
    This                - Protocol instance pointer.
    ControllerHandle    - Handle of device to test
    RemainingDevicePath - Not used

  Returns:
    EFI_SUCCES          - This driver supports this device
    EFI_ALREADY_STARTED - This driver is already running on this device
    other               - This driver does not support this device

--*/
{
  EFI_STATUS                OpenStatus;
  EFI_USB_IO_PROTOCOL       *UsbIo;
  EFI_STATUS              Status;

  OpenStatus = gBS->OpenProtocol(
                    Controller,
                    &gEfiUsbIoProtocolGuid,
                    &UsbIo,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                 );
  if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {
      return EFI_UNSUPPORTED;
  }

  if (OpenStatus == EFI_ALREADY_STARTED) {
    return EFI_ALREADY_STARTED;
  }
  
  //
  // Use the USB I/O protocol interface to see the Controller is
  // the Mouse controller that can be managed by this driver.
  //
  Status = EFI_SUCCESS;
  if(!IsUsbMouse(UsbIo)) {
      Status = EFI_UNSUPPORTED;
  }

  gBS->CloseProtocol (
          Controller,
          &gEfiUsbIoProtocolGuid,
          This->DriverBindingHandle,
          Controller
       );
  return Status;
}


EFI_STATUS
USBMouseDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
/*++

  Routine Description:
    Start this driver on ControllerHandle by opening a Block IO and Disk IO
    protocol, reading Device Path, and creating a child handle with a
    Disk IO and device path protocol.

  Arguments:
    This                - Protocol instance pointer.
    ControllerHandle    - Handle of device to bind driver to
    RemainingDevicePath - Not used

  Returns:
    EFI_SUCCES          - This driver is added to DeviceHandle
    EFI_ALREADY_STARTED - This driver is already running on DeviceHandle
    other               - This driver does not support this device

--*/
{
  EFI_STATUS                  Status;
  EFI_USB_IO_PROTOCOL         *UsbIo;
  EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc;
  USB_MOUSE_DEV               *UsbMouseDevice;
  UINT8                       EndpointNumber;
  UINT8                       i;
  UINT8                       EndpointAddr;
  UINT8                       PollingInterval;
  UINT8                       PacketSize;

  UsbMouseDevice = NULL;
  Status = EFI_SUCCESS;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsbIoProtocolGuid,
                  &UsbIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
      goto ErrorExit;
  }

  Status = gBS->AllocatePool(
                  EfiBootServicesData,
                  sizeof(USB_MOUSE_DEV),
                  &UsbMouseDevice
                );

  if (EFI_ERROR(Status)) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ErrorExit;
  }

  EfiZeroMem(UsbMouseDevice,sizeof(USB_MOUSE_DEV));

  UsbMouseDevice->UsbIo = UsbIo;

  UsbMouseDevice->Signature = USB_MOUSE_DEV_SIGNATURE;

  Status = gBS->AllocatePool(
                  EfiBootServicesData,
                  sizeof (EFI_USB_INTERFACE_DESCRIPTOR),
                  &UsbMouseDevice->InterfaceDescriptor
                );
                
  if (EFI_ERROR(Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
                    
  Status = gBS->AllocatePool(
                  EfiBootServicesData,
                  sizeof (EFI_USB_ENDPOINT_DESCRIPTOR),
                  &EndpointDesc
                );
                
  if (EFI_ERROR(Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  //
  // Get interface & endpoint descriptor
  //
  UsbIo->UsbGetInterfaceDescriptor(
           UsbIo,
           UsbMouseDevice->InterfaceDescriptor
         );

  EndpointNumber = UsbMouseDevice->InterfaceDescriptor->NumEndpoints;

  for(i = 0; i < EndpointNumber; i++) {
    UsbIo->UsbGetEndpointDescriptor(
             UsbIo,
             i,
             EndpointDesc
           );

    if((EndpointDesc->Attributes & 0x03) == 0x03) {

        //
        // We only care interrupt endpoint here
        //
        UsbMouseDevice->IntEndpointDescriptor = EndpointDesc;
    }
  }

  if(UsbMouseDevice->IntEndpointDescriptor == NULL) {
    //
    // No interrupt endpoint, then error
    //
    Status = EFI_UNSUPPORTED;
    goto ErrorExit;
  }

  Status = InitializeUsbMouseDevice (UsbMouseDevice);
  if (EFI_ERROR(Status)) {
    goto ErrorExit;
  }

  UsbMouseDevice->SimplePointerProtocol.GetState = GetMouseState;
  UsbMouseDevice->SimplePointerProtocol.Reset = UsbMouseReset;
  UsbMouseDevice->SimplePointerProtocol.Mode = &UsbMouseDevice->Mode;

  Status = gBS->CreateEvent (
                    EFI_EVENT_NOTIFY_WAIT,
                    EFI_TPL_NOTIFY,
                    UsbMouseWaitForInput,
                    UsbMouseDevice,
                    &((UsbMouseDevice->SimplePointerProtocol).WaitForInput)
                    );
  if (EFI_ERROR(Status)) {
    goto ErrorExit;
  }

  Status = gBS->InstallProtocolInterface(
                  &Controller,
                  &gEfiSimplePointerProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &UsbMouseDevice->SimplePointerProtocol
                );

  if (EFI_ERROR(Status)) {
    Status = EFI_DEVICE_ERROR;
    goto ErrorExit;
  }
  
  //
  // submit async interrupt transfer
  //
  EndpointAddr = UsbMouseDevice->IntEndpointDescriptor->EndpointAddress;
  PollingInterval = UsbMouseDevice->IntEndpointDescriptor->Interval;
  PacketSize = (UINT8)(UsbMouseDevice->IntEndpointDescriptor->MaxPacketSize);

  Status = UsbIo->UsbAsyncInterruptTransfer(
                      UsbIo,
                      EndpointAddr,
                      TRUE,
                      PollingInterval,
                      PacketSize,
                      OnMouseInterruptComplete,
                      UsbMouseDevice
                   );

  if (!EFI_ERROR(Status)) {
    
    UsbMouseDevice->ControllerNameTable = NULL;
    EfiLibAddUnicodeString (
      "eng", 
      gUsbMouseComponentName.SupportedLanguages, 
      &UsbMouseDevice->ControllerNameTable, 
      L"Generic Usb Mouse"
    );

    return EFI_SUCCESS;
  }

  //
  // If submit error, uninstall that interface
  //
  Status = EFI_DEVICE_ERROR; 
  gBS->UninstallProtocolInterface (
        Controller,
        &gEfiSimplePointerProtocolGuid,
        &UsbMouseDevice->SimplePointerProtocol
      );
           
ErrorExit:
  if(EFI_ERROR(Status)) {
    gBS->CloseProtocol (
           Controller,
           &gEfiUsbIoProtocolGuid,
           This->DriverBindingHandle,
           Controller
         );

    if (UsbMouseDevice != NULL) {
      if (UsbMouseDevice->InterfaceDescriptor != NULL) {
        gBS->FreePool (UsbMouseDevice->InterfaceDescriptor);
      }
      if (UsbMouseDevice->IntEndpointDescriptor != NULL) {
        gBS->FreePool (UsbMouseDevice->IntEndpointDescriptor);
      }
      
      if ((UsbMouseDevice->SimplePointerProtocol).WaitForInput != NULL) {
        gBS->CloseEvent ((UsbMouseDevice->SimplePointerProtocol).WaitForInput);
      }
      gBS->FreePool(UsbMouseDevice);
      UsbMouseDevice = NULL;
    }
  }

  return Status;
}


EFI_STATUS
USBMouseDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    Controller,
  IN  UINTN                         NumberOfChildren,
  IN  EFI_HANDLE                    *ChildHandleBuffer
  )
/*++

  Routine Description:
    Stop this driver on ControllerHandle. Support stoping any child handles
    created by this driver.

  Arguments:
    This              - Protocol instance pointer.
    DeviceHandle      - Handle of device to stop driver on
    NumberOfChildren  - Number of Children in the ChildHandleBuffer
    ChildHandleBuffer - List of handles for the children we need to stop.

  Returns:
    EFI_SUCCES          - This driver is removed DeviceHandle
    other               - This driver was not removed from this device

--*/
{
  EFI_STATUS                      Status;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -