-/** @file
+/** @file\r
This file implement UEFI driver for IDE Bus which includes device identification, \r
Child device(Disk, CDROM, etc) enumeration and child handler installation, and \r
- driver stop.
+ driver stop.\r
\r
- Copyright (c) 2006 - 2008, 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.
-
- @par Revision Reference:
- This module is modified from DXE\IDE module for Ide Contriller Init support
-
-**/
-
-#include "IdeBus.h"
-
-#define PCI_CLASS_MASS_STORAGE 0x01
-#define PCI_SUB_CLASS_IDE 0x01
-
-
-//
-// IDE Bus Driver Binding Protocol Instance
-//
-EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {
- IDEBusDriverBindingSupported,
- IDEBusDriverBindingStart,
- IDEBusDriverBindingStop,
- 0xa,
- NULL,
- NULL
-};
-/**
- Deregister an IDE device and free resources
-
- @param This Protocol instance pointer.
- @param Controller Ide device handle
- @param Handle Handle of device to deregister driver on
-
- @retval EFI_SUCCESS Deregiter a specific IDE device successfully
-
-
-**/
-EFI_STATUS
-DeRegisterIdeDevice (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_HANDLE Handle
- )
-{
- EFI_STATUS Status;
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- IDE_BLK_IO_DEV *IdeBlkIoDevice;
- EFI_PCI_IO_PROTOCOL *PciIo;
- UINTN Index;
-
- Status = gBS->OpenProtocol (
- Handle,
- &gEfiBlockIoProtocolGuid,
- (VOID **) &BlkIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);
-
- //
- // Report Status code: Device disabled
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),
- IdeBlkIoDevice->DevicePath
- );
-
- //
- // Close the child handle
- //
- Status = gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Handle
- );
-
- Status = gBS->UninstallMultipleProtocolInterfaces (
- Handle,
- &gEfiDevicePathProtocolGuid,
- IdeBlkIoDevice->DevicePath,
- &gEfiBlockIoProtocolGuid,
- &IdeBlkIoDevice->BlkIo,
- &gEfiDiskInfoProtocolGuid,
- &IdeBlkIoDevice->DiskInfo,
- NULL
- );
-
- if (EFI_ERROR (Status)) {
- gBS->OpenProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
- This->DriverBindingHandle,
- Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- return Status;
- }
-
- //
- // Release allocated resources
- //
- Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;
- if (Index < MAX_IDE_DEVICE) {
- IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;
- }
- ReleaseIdeResources (IdeBlkIoDevice);
-
- return EFI_SUCCESS;
-}
-/**
- Supported function of Driver Binding protocol for this driver.
-
- @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
- @param ControllerHandle The handle of the controller to test.
- @param RemainingDevicePath A pointer to the remaining portion of a device path.
-
- @retval EFI_SUCCESS Driver loaded.
- @retval other Driver not loaded.
-
-**/
-EFI_STATUS
-EFIAPI
-IDEBusDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
- EFI_DEV_PATH *Node;
- EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
-
- if (RemainingDevicePath != NULL) {
- Node = (EFI_DEV_PATH *) RemainingDevicePath;
- if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||
- Node->DevPath.SubType != MSG_ATAPI_DP ||
- DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {
- return EFI_UNSUPPORTED;
- }
- }
-
- //
- // Open the IO Abstraction(s) needed to perform the supported test
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **) &ParentDevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Close protocol, don't use device path protocol in the .Support() function
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- //
- // Verify the Ide Controller Init Protocol, which installed by the
- // IdeController module.
- // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't
- // open BY_DRIVER here) That's why we don't check pciio protocol
- // Note 2: ide_init driver check ide controller's pci config space, so we dont
- // check here any more to save code size
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiIdeControllerInitProtocolGuid,
- (VOID **) &IdeInit,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
-
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- }
-
- //
- // If protocols were opened normally, closed it
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiIdeControllerInitProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- return Status;
-}
-
-
-/**
- Start function of Driver binding protocol which start this driver on Controller
- by detecting all disks and installing BlockIo protocol on them.
-
- @param This Protocol instance pointer.
- @param Controller Handle of device to bind driver to.
- @param RemainingDevicePath produce all possible children.
-
- @retval EFI_SUCCESS This driver is added to ControllerHandle.
- @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
- @retval other This driver does not support this device.
-
-**/
-EFI_STATUS
-EFIAPI
-IDEBusDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-{
- EFI_STATUS Status;
- EFI_STATUS SavedStatus;
- EFI_PCI_IO_PROTOCOL *PciIo;
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
- EFI_DEV_PATH *Node;
- UINT8 IdeChannel;
- UINT8 BeginningIdeChannel;
- UINT8 EndIdeChannel;
- UINT8 IdeDevice;
- UINT8 BeginningIdeDevice;
- UINT8 EndIdeDevice;
- IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];
- IDE_BLK_IO_DEV *IdeBlkIoDevicePtr;
- IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];
- ATA_TRANSFER_MODE TransferMode;
- ATA_DRIVE_PARMS DriveParameters;
- EFI_DEV_PATH NewNode;
- UINT8 ConfigurationOptions;
- UINT16 CommandBlockBaseAddr;
- UINT16 ControlBlockBaseAddr;
- UINTN DataSize;
- IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
- UINT64 Supports;
-
- //
- // Local variables declaration for IdeControllerInit support
- //
- EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
- BOOLEAN EnumAll;
- BOOLEAN ChannelEnabled;
- UINT8 MaxDevices;
- EFI_IDENTIFY_DATA IdentifyData;
- EFI_ATA_COLLECTIVE_MODE *SupportedModes;
-
- IdeBusDriverPrivateData = NULL;
- SupportedModes = NULL;
-
- //
- // Perform IdeBus initialization
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **) &ParentDevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
- return Status;
- }
-
- //
- // Now open the IDE_CONTROLLER_INIT protocol. Step7.1
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiIdeControllerInitProtocolGuid,
- (VOID **) &IdeInit,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
-
- //
- // The following OpenProtocol function with _GET_PROTOCOL attribute and
- // will not return EFI_ALREADY_STARTED, so save it for now
- //
- SavedStatus = Status;
-
- if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
- DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));
- //
- // open protocol is not SUCCESS or not ALREADY_STARTED, error exit
- //
- goto ErrorExit;
- }
-
- //
- // Save Enumall. Step7.2
- //
- EnumAll = IdeInit->EnumAll;
-
- //
- // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL
- // attribute will not return EFI_ALREADY_STARTED
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));
- goto ErrorExit;
- }
-
- //
- // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable
- //
- if (SavedStatus != EFI_ALREADY_STARTED) {
- IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
- if (IdeBusDriverPrivateData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
-
- ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Controller,
- &gEfiCallerIdGuid,
- IdeBusDriverPrivateData,
- NULL
- );
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- }
-
- } else {
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiCallerIdGuid,
- (VOID **) &IdeBusDriverPrivateData,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- IdeBusDriverPrivateData = NULL;
- goto ErrorExit;
- }
- }
-
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationSupported,
- 0,
- &Supports
- );
- if (!EFI_ERROR (Status)) {
- Supports &= EFI_PCI_DEVICE_ENABLE;
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationEnable,
- Supports,
- NULL
- );
- }
-
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- }
-
- //
- // Read the environment variable that contains the IDEBus Driver's
- // Config options that were set by the Driver Configuration Protocol
- //
- DataSize = sizeof (ConfigurationOptions);
- Status = gRT->GetVariable (
- (CHAR16 *) L"Configuration",
- &gEfiCallerIdGuid,
- NULL,
- &DataSize,
- &ConfigurationOptions
- );
- if (EFI_ERROR (Status)) {
- ConfigurationOptions = 0x0f;
- }
-
- if (EnumAll) {
- //
- // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway
- //
- BeginningIdeChannel = IdePrimary;
- EndIdeChannel = IdeSecondary;
- BeginningIdeDevice = IdeMaster;
- EndIdeDevice = IdeSlave;
- } else if (RemainingDevicePath == NULL) {
- //
- // RemainingDevicePath is NULL, scan IDE bus for each device;
- //
- BeginningIdeChannel = IdePrimary;
- EndIdeChannel = IdeSecondary;
- BeginningIdeDevice = IdeMaster;
- //
- // default, may be redefined by IdeInit
- //
- EndIdeDevice = IdeSlave;
- } else {
- //
- // RemainingDevicePath is not NULL, only scan the specified device.
- //
- Node = (EFI_DEV_PATH *) RemainingDevicePath;
- BeginningIdeChannel = Node->Atapi.PrimarySecondary;
- EndIdeChannel = BeginningIdeChannel;
- BeginningIdeDevice = Node->Atapi.SlaveMaster;
- EndIdeDevice = BeginningIdeDevice;
- if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {
- Status = EFI_INVALID_PARAMETER;
- goto ErrorExit;
- }
- if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {
- Status = EFI_INVALID_PARAMETER;
- goto ErrorExit;
- }
- }
-
- //
- // Obtain IDE IO port registers' base addresses
- //
- Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- }
-
- //
- // Report status code: begin IdeBus initialization
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
- ParentDevicePath
- );
-
- //
- // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol
- //
- for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {
-
- IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);
-
- //
- // now obtain channel information fron IdeControllerInit protocol. Step9
- //
- Status = IdeInit->GetChannelInfo (
- IdeInit,
- IdeChannel,
- &ChannelEnabled,
- &MaxDevices
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));
- continue;
- }
-
- if (!ChannelEnabled) {
- continue;
- }
-
- EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);
- ASSERT (EndIdeDevice < IdeMaxDevice);
- //
- // Now inform the IDE Controller Init Module. Sept10
- //
- IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);
-
- //
- // No reset channel function implemented. Sept11
- //
- IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);
-
- //
- // Step13
- //
- IdeInit->NotifyPhase (
- IdeInit,
- EfiIdeBusBeforeDevicePresenceDetection,
- IdeChannel
- );
-
- //
- // Prepare to detect IDE device of this channel
- //
- InitializeIDEChannelData ();
-
- //
- // -- 1st inner loop --- Master/Slave ------------ Step14
- //
- for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
- //
- // Check whether the configuration options allow this device
- //
- if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {
- continue;
- }
-
- //
- // The device has been scanned in another Start(), No need to scan it again
- // for perf optimization.
- //
- if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {
- continue;
- }
-
- //
- // create child handle for the detected device.
- //
- IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));
- if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {
- continue;
- }
-
- IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];
-
- ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));
-
- IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;
- IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel;
- IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice;
-
- //
- // initialize Block IO interface's Media pointer
- //
- IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;
-
- //
- // Initialize IDE IO port addresses, including Command Block registers
- // and Control Block registers
- //
- IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));
- if (IdeBlkIoDevicePtr->IoPort == NULL) {
- continue;
- }
-
- ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));
- CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
- ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
-
- IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;
- (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
- IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
- IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
- IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
- IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
- IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
- (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);
-
- (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;
- IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);
-
- IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);
-
- IdeBlkIoDevicePtr->PciIo = PciIo;
- IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;
- IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;
-
- //
- // Report Status code: is about to detect IDE drive
- //
- REPORT_STATUS_CODE_EX (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),
- 0,
- &gEfiCallerIdGuid,
- NULL,
- NULL,
- 0
- );
-
- //
- // Discover device, now!
- //
- PERF_START (NULL, "DiscoverIdeDevice", "IDE", 0);
- Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);
- PERF_END (NULL, "DiscoverIdeDevice", "IDE", 0);
-
- IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;
- IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;
-
- if (!EFI_ERROR (Status)) {
- //
- // Set Device Path
- //
- ZeroMem (&NewNode, sizeof (NewNode));
- NewNode.DevPath.Type = MESSAGING_DEVICE_PATH;
- NewNode.DevPath.SubType = MSG_ATAPI_DP;
- SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));
-
- NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;
- NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;
- NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun;
- IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (
- ParentDevicePath,
- &NewNode.DevPath
- );
- if (IdeBlkIoDevicePtr->DevicePath == NULL) {
- ReleaseIdeResources (IdeBlkIoDevicePtr);
- continue;
- }
-
- //
- // Submit identify data to IDE controller init driver
- //
- CopyMem (&IdentifyData, IdeBlkIoDevicePtr->IdData, sizeof (IdentifyData));
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;
- IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);
- } else {
- //
- // Device detection failed
- //
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
- IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);
- ReleaseIdeResources (IdeBlkIoDevicePtr);
- IdeBlkIoDevicePtr = NULL;
- }
- //
- // end of 1st inner loop ---
- //
- }
- //
- // end of 1st outer loop =========
- //
- }
-
- //
- // = 2nd outer loop == Primary/Secondary =================
- //
- for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {
-
- //
- // -- 2nd inner loop --- Master/Slave --------
- //
- for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
-
- if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {
- continue;
- }
-
- if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {
- continue;
- }
-
- Status = IdeInit->CalculateMode (
- IdeInit,
- IdeChannel,
- IdeDevice,
- &SupportedModes
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));
- continue;
- }
-
- IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];
-
- //
- // Set best supported PIO mode on this IDE device
- //
- if (SupportedModes->PioMode.Mode <= AtaPioMode2) {
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;
- } else {
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;
- }
-
- TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
-
- if (SupportedModes->ExtModeCount == 0){
- Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
-
- if (EFI_ERROR (Status)) {
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
- ReleaseIdeResources (IdeBlkIoDevicePtr);
- IdeBlkIoDevicePtr = NULL;
- continue;
- }
- }
-
- //
- // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
- // be set together. Only one DMA mode can be set to a device. If setting
- // DMA mode operation fails, we can continue moving on because we only use
- // PIO mode at boot time. DMA modes are used by certain kind of OS booting
- //
- if (SupportedModes->UdmaMode.Valid) {
-
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;
- TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
- Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
-
- if (EFI_ERROR (Status)) {
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
- ReleaseIdeResources (IdeBlkIoDevicePtr);
- IdeBlkIoDevicePtr = NULL;
- continue;
- }
- //
- // Record Udma Mode
- //
- IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;
- IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;
- EnableInterrupt (IdeBlkIoDevicePtr);
- } else if (SupportedModes->MultiWordDmaMode.Valid) {
-
- TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;
- TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
- Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
-
- if (EFI_ERROR (Status)) {
- IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
- ReleaseIdeResources (IdeBlkIoDevicePtr);
- IdeBlkIoDevicePtr = NULL;
- continue;
- }
-
- EnableInterrupt (IdeBlkIoDevicePtr);
- }
- //
- // Init driver parameters
- //
- DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.sectors_per_track;
- DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->IdData->AtaData.heads - 1);
- DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;
- //
- // Set Parameters for the device:
- // 1) Init
- // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
- //
- if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {
- Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);
- }
-
- //
- // Record PIO mode used in private data
- //
- IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;
-
- //
- // Set IDE controller Timing Blocks in the PCI Configuration Space
- //
- IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
-
- //
- // Add Component Name for the IDE/ATAPI device that was discovered.
- //
- IdeBlkIoDevicePtr->ControllerNameTable = NULL;
- ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr);
-
- Status = gBS->InstallMultipleProtocolInterfaces (
- &IdeBlkIoDevicePtr->Handle,
- &gEfiDevicePathProtocolGuid,
- IdeBlkIoDevicePtr->DevicePath,
- &gEfiBlockIoProtocolGuid,
- &IdeBlkIoDevicePtr->BlkIo,
- &gEfiDiskInfoProtocolGuid,
- &IdeBlkIoDevicePtr->DiskInfo,
- NULL
- );
-
- if (EFI_ERROR (Status)) {
- ReleaseIdeResources (IdeBlkIoDevicePtr);
- }
-
- gBS->OpenProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
- This->DriverBindingHandle,
- IdeBlkIoDevicePtr->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
-
- IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;
-
- //
- // Report status code: device eanbled!
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),
- IdeBlkIoDevicePtr->DevicePath
- );
-
- //
- // Create event to clear pending IDE interrupt
- //
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- ClearInterrupt,
- IdeBlkIoDevicePtr,
- &gEfiEventExitBootServicesGuid,
- &IdeBlkIoDevicePtr->ExitBootServiceEvent
- );
-
- //
- // end of 2nd inner loop ----
- //
- }
- //
- // end of 2nd outer loop ==========
- //
- }
-
- //
- // All configurations done! Notify IdeController to do post initialization
- // work such as saving IDE controller PCI settings for S3 resume
- //
- IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
-
- if (SupportedModes != NULL) {
- gBS->FreePool (SupportedModes);
- }
-
- PERF_START (NULL, "Finish IDE detection", "IDE", 1);
- PERF_END (NULL, "Finish IDE detection", "IDE", 0);
-
- return EFI_SUCCESS;
-
-ErrorExit:
-
- //
- // Report error code: controller error
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),
- ParentDevicePath
- );
-
- gBS->CloseProtocol (
- Controller,
- &gEfiIdeControllerInitProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- gBS->UninstallMultipleProtocolInterfaces (
- Controller,
- &gEfiCallerIdGuid,
- IdeBusDriverPrivateData,
- NULL
- );
-
- if (IdeBusDriverPrivateData != NULL) {
- gBS->FreePool (IdeBusDriverPrivateData);
- }
-
- if (SupportedModes != NULL) {
- gBS->FreePool (SupportedModes);
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- return Status;
-
-}
-/**
- Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all
- child handle attached to the controller handle if there are.
-
- @param This Protocol instance pointer.
- @param Controller Handle of device to stop driver on
- @param NumberOfChildren Not used
- @param ChildHandleBuffer Not used
-
- @retval EFI_SUCCESS This driver is removed DeviceHandle
- @retval other This driver was not removed from this device
-
-**/
-EFI_STATUS
-EFIAPI
-IDEBusDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- )
-{
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *PciIo;
- BOOLEAN AllChildrenStopped;
- UINTN Index;
- IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
- UINT64 Supports;
-
- IdeBusDriverPrivateData = NULL;
-
- if (NumberOfChildren == 0) {
-
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationSupported,
- 0,
- &Supports
- );
- if (!EFI_ERROR (Status)) {
- Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;
- PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationDisable,
- Supports,
- NULL
- );
- }
- }
-
- gBS->OpenProtocol (
- Controller,
- &gEfiCallerIdGuid,
- (VOID **) &IdeBusDriverPrivateData,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
-
- gBS->UninstallMultipleProtocolInterfaces (
- Controller,
- &gEfiCallerIdGuid,
- IdeBusDriverPrivateData,
- NULL
- );
-
- if (IdeBusDriverPrivateData != NULL) {
- gBS->FreePool (IdeBusDriverPrivateData);
- }
- //
- // Close the bus driver
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiIdeControllerInitProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- return EFI_SUCCESS;
- }
-
- AllChildrenStopped = TRUE;
-
- for (Index = 0; Index < NumberOfChildren; Index++) {
-
- Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);
-
- if (EFI_ERROR (Status)) {
- AllChildrenStopped = FALSE;
- }
- }
-
- if (!AllChildrenStopped) {
- return EFI_DEVICE_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- issue ATA or ATAPI command to reset a block IO device.
- @param This Block IO protocol instance pointer.
- @param ExtendedVerification If FALSE,for ATAPI device, driver will only invoke ATAPI reset method
- If TRUE, for ATAPI device, driver need invoke ATA reset method after
- invoke ATAPI reset method
-
- @retval EFI_DEVICE_ERROR When the device is neighther ATA device or ATAPI device.
- @retval EFI_SUCCESS The device reset successfully
-
-**/
-EFI_STATUS
-EFIAPI
-IDEBlkIoReset (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
-{
- IDE_BLK_IO_DEV *IdeBlkIoDevice;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
- //
- // Requery IDE IO resources in case of the switch of native and legacy modes
- //
- ReassignIdeResources (IdeBlkIoDevice);
-
- //
- // for ATA device, using ATA reset method
- //
- if (IdeBlkIoDevice->Type == IdeHardDisk ||
- IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
- Status = AtaSoftReset (IdeBlkIoDevice);
- goto Done;
- }
-
- if (IdeBlkIoDevice->Type == IdeUnknown) {
- Status = EFI_DEVICE_ERROR;
- goto Done;
- }
-
- //
- // for ATAPI device, using ATAPI reset method
- //
- Status = AtapiSoftReset (IdeBlkIoDevice);
- if (ExtendedVerification) {
- Status = AtaSoftReset (IdeBlkIoDevice);
- }
-
-Done:
- gBS->RestoreTPL (OldTpl);
- return Status;
-}
-
-/**
- Read data from a block IO device
-
- @param This Block IO protocol instance pointer.
- @param MediaId The media ID of the device
+ Copyright (c) 2006 - 2008, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Revision Reference:\r
+ This module is modified from DXE\IDE module for Ide Contriller Init support\r
+\r
+**/\r
+\r
+#include "IdeBus.h"\r
+\r
+#define PCI_CLASS_MASS_STORAGE 0x01\r
+#define PCI_SUB_CLASS_IDE 0x01\r
+\r
+\r
+//\r
+// IDE Bus Driver Binding Protocol Instance\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {\r
+ IDEBusDriverBindingSupported,\r
+ IDEBusDriverBindingStart,\r
+ IDEBusDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+/**\r
+ Deregister an IDE device and free resources\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Controller Ide device handle\r
+ @param Handle Handle of device to deregister driver on\r
+\r
+ @retval EFI_SUCCESS Deregiter a specific IDE device successfully\r
+\r
+\r
+**/\r
+EFI_STATUS\r
+DeRegisterIdeDevice (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINTN Index;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Handle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ (VOID **) &BlkIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);\r
+\r
+ //\r
+ // Report Status code: Device disabled\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),\r
+ IdeBlkIoDevice->DevicePath\r
+ );\r
+\r
+ //\r
+ // Close the child handle\r
+ //\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Handle\r
+ );\r
+\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ IdeBlkIoDevice->DevicePath,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &IdeBlkIoDevice->BlkIo,\r
+ &gEfiDiskInfoProtocolGuid,\r
+ &IdeBlkIoDevice->DiskInfo,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Release allocated resources\r
+ //\r
+ Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;\r
+ if (Index < MAX_IDE_DEVICE) {\r
+ IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;\r
+ }\r
+ ReleaseIdeResources (IdeBlkIoDevice);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+/**\r
+ Supported function of Driver Binding protocol for this driver.\r
+\r
+ @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param ControllerHandle The handle of the controller to test.\r
+ @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
+\r
+ @retval EFI_SUCCESS Driver loaded.\r
+ @retval other Driver not loaded.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_DEV_PATH *Node;\r
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
+\r
+ if (RemainingDevicePath != NULL) {\r
+ Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+ if (Node->DevPath.Type != MESSAGING_DEVICE_PATH ||\r
+ Node->DevPath.SubType != MSG_ATAPI_DP ||\r
+ DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Close protocol, don't use device path protocol in the .Support() function\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ //\r
+ // Verify the Ide Controller Init Protocol, which installed by the\r
+ // IdeController module.\r
+ // Note 1: PciIo protocol has been opened BY_DRIVER by ide_init, so We can't\r
+ // open BY_DRIVER here) That's why we don't check pciio protocol\r
+ // Note 2: ide_init driver check ide controller's pci config space, so we dont\r
+ // check here any more to save code size\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ (VOID **) &IdeInit,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // If protocols were opened normally, closed it\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Start function of Driver binding protocol which start this driver on Controller\r
+ by detecting all disks and installing BlockIo protocol on them.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to bind driver to.\r
+ @param RemainingDevicePath produce all possible children.\r
+\r
+ @retval EFI_SUCCESS This driver is added to ControllerHandle.\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS SavedStatus;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_DEV_PATH *Node;\r
+ UINT8 IdeChannel;\r
+ UINT8 BeginningIdeChannel;\r
+ UINT8 EndIdeChannel;\r
+ UINT8 IdeDevice;\r
+ UINT8 BeginningIdeDevice;\r
+ UINT8 EndIdeDevice;\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevicePtr;\r
+ IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];\r
+ ATA_TRANSFER_MODE TransferMode;\r
+ ATA_DRIVE_PARMS DriveParameters;\r
+ EFI_DEV_PATH NewNode;\r
+ UINT8 ConfigurationOptions;\r
+ UINT16 CommandBlockBaseAddr;\r
+ UINT16 ControlBlockBaseAddr;\r
+ UINTN DataSize;\r
+ IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
+ UINT64 Supports;\r
+\r
+ //\r
+ // Local variables declaration for IdeControllerInit support\r
+ //\r
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;\r
+ BOOLEAN EnumAll;\r
+ BOOLEAN ChannelEnabled;\r
+ UINT8 MaxDevices;\r
+ EFI_IDENTIFY_DATA IdentifyData;\r
+ EFI_ATA_COLLECTIVE_MODE *SupportedModes;\r
+\r
+ IdeBusDriverPrivateData = NULL;\r
+ SupportedModes = NULL;\r
+\r
+ //\r
+ // Perform IdeBus initialization\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Now open the IDE_CONTROLLER_INIT protocol. Step7.1\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ (VOID **) &IdeInit,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ //\r
+ // The following OpenProtocol function with _GET_PROTOCOL attribute and\r
+ // will not return EFI_ALREADY_STARTED, so save it for now\r
+ //\r
+ SavedStatus = Status;\r
+\r
+ if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
+ DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));\r
+ //\r
+ // open protocol is not SUCCESS or not ALREADY_STARTED, error exit\r
+ //\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Save Enumall. Step7.2\r
+ //\r
+ EnumAll = IdeInit->EnumAll;\r
+\r
+ //\r
+ // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL\r
+ // attribute will not return EFI_ALREADY_STARTED\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable\r
+ //\r
+ if (SavedStatus != EFI_ALREADY_STARTED) {\r
+ IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
+ if (IdeBusDriverPrivateData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Controller,\r
+ &gEfiCallerIdGuid,\r
+ IdeBusDriverPrivateData,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ } else {\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &IdeBusDriverPrivateData,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData = NULL;\r
+ goto ErrorExit;\r
+ }\r
+ }\r
+\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationSupported,\r
+ 0,\r
+ &Supports\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Supports &= EFI_PCI_DEVICE_ENABLE;\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ Supports,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Read the environment variable that contains the IDEBus Driver's\r
+ // Config options that were set by the Driver Configuration Protocol\r
+ //\r
+ DataSize = sizeof (ConfigurationOptions);\r
+ Status = gRT->GetVariable (\r
+ (CHAR16 *) L"Configuration",\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &ConfigurationOptions\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ConfigurationOptions = 0x0f;\r
+ }\r
+\r
+ if (EnumAll) {\r
+ //\r
+ // If IdeInit->EnumAll is TRUE, must enumerate all IDE device anyway\r
+ //\r
+ BeginningIdeChannel = IdePrimary;\r
+ EndIdeChannel = IdeSecondary;\r
+ BeginningIdeDevice = IdeMaster;\r
+ EndIdeDevice = IdeSlave;\r
+ } else if (RemainingDevicePath == NULL) {\r
+ //\r
+ // RemainingDevicePath is NULL, scan IDE bus for each device;\r
+ //\r
+ BeginningIdeChannel = IdePrimary;\r
+ EndIdeChannel = IdeSecondary;\r
+ BeginningIdeDevice = IdeMaster;\r
+ //\r
+ // default, may be redefined by IdeInit\r
+ //\r
+ EndIdeDevice = IdeSlave;\r
+ } else {\r
+ //\r
+ // RemainingDevicePath is not NULL, only scan the specified device.\r
+ //\r
+ Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+ BeginningIdeChannel = Node->Atapi.PrimarySecondary;\r
+ EndIdeChannel = BeginningIdeChannel;\r
+ BeginningIdeDevice = Node->Atapi.SlaveMaster;\r
+ EndIdeDevice = BeginningIdeDevice;\r
+ if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto ErrorExit;\r
+ }\r
+ if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto ErrorExit;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Obtain IDE IO port registers' base addresses\r
+ //\r
+ Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Report status code: begin IdeBus initialization\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
+ ParentDevicePath\r
+ );\r
+\r
+ //\r
+ // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol\r
+ //\r
+ for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
+\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);\r
+\r
+ //\r
+ // now obtain channel information fron IdeControllerInit protocol. Step9\r
+ //\r
+ Status = IdeInit->GetChannelInfo (\r
+ IdeInit,\r
+ IdeChannel,\r
+ &ChannelEnabled,\r
+ &MaxDevices\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
+ continue;\r
+ }\r
+\r
+ if (!ChannelEnabled) {\r
+ continue;\r
+ }\r
+\r
+ EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);\r
+ ASSERT (EndIdeDevice < IdeMaxDevice);\r
+ //\r
+ // Now inform the IDE Controller Init Module. Sept10\r
+ //\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);\r
+\r
+ //\r
+ // No reset channel function implemented. Sept11\r
+ //\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);\r
+\r
+ //\r
+ // Step13\r
+ //\r
+ IdeInit->NotifyPhase (\r
+ IdeInit,\r
+ EfiIdeBusBeforeDevicePresenceDetection,\r
+ IdeChannel\r
+ );\r
+\r
+ //\r
+ // Prepare to detect IDE device of this channel\r
+ //\r
+ InitializeIDEChannelData ();\r
+\r
+ //\r
+ // -- 1st inner loop --- Master/Slave ------------ Step14\r
+ //\r
+ for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
+ //\r
+ // Check whether the configuration options allow this device\r
+ //\r
+ if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // The device has been scanned in another Start(), No need to scan it again\r
+ // for perf optimization.\r
+ //\r
+ if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // create child handle for the detected device.\r
+ //\r
+ IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));\r
+ if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {\r
+ continue;\r
+ }\r
+\r
+ IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
+\r
+ ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));\r
+\r
+ IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;\r
+ IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel;\r
+ IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice;\r
+\r
+ //\r
+ // initialize Block IO interface's Media pointer\r
+ //\r
+ IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;\r
+\r
+ //\r
+ // Initialize IDE IO port addresses, including Command Block registers\r
+ // and Control Block registers\r
+ //\r
+ IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));\r
+ if (IdeBlkIoDevicePtr->IoPort == NULL) {\r
+ continue;\r
+ }\r
+\r
+ ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));\r
+ CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;\r
+ ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;\r
+\r
+ IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;\r
+ (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);\r
+ IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);\r
+ IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);\r
+ IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);\r
+ IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);\r
+ IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);\r
+ (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);\r
+\r
+ (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;\r
+ IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);\r
+\r
+ IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);\r
+\r
+ IdeBlkIoDevicePtr->PciIo = PciIo;\r
+ IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;\r
+ IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;\r
+\r
+ //\r
+ // Report Status code: is about to detect IDE drive\r
+ //\r
+ REPORT_STATUS_CODE_EX (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),\r
+ 0,\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ NULL,\r
+ 0\r
+ );\r
+\r
+ //\r
+ // Discover device, now!\r
+ //\r
+ PERF_START (NULL, "DiscoverIdeDevice", "IDE", 0);\r
+ Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);\r
+ PERF_END (NULL, "DiscoverIdeDevice", "IDE", 0);\r
+\r
+ IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;\r
+ IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Set Device Path\r
+ //\r
+ ZeroMem (&NewNode, sizeof (NewNode));\r
+ NewNode.DevPath.Type = MESSAGING_DEVICE_PATH;\r
+ NewNode.DevPath.SubType = MSG_ATAPI_DP;\r
+ SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));\r
+\r
+ NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;\r
+ NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;\r
+ NewNode.Atapi.Lun = IdeBlkIoDevicePtr->Lun;\r
+ IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (\r
+ ParentDevicePath,\r
+ &NewNode.DevPath\r
+ );\r
+ if (IdeBlkIoDevicePtr->DevicePath == NULL) {\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Submit identify data to IDE controller init driver\r
+ //\r
+ CopyMem (&IdentifyData, IdeBlkIoDevicePtr->IdData, sizeof (IdentifyData));\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;\r
+ IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);\r
+ } else {\r
+ //\r
+ // Device detection failed\r
+ //\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ }\r
+ //\r
+ // end of 1st inner loop ---\r
+ //\r
+ }\r
+ //\r
+ // end of 1st outer loop =========\r
+ //\r
+ }\r
+\r
+ //\r
+ // = 2nd outer loop == Primary/Secondary =================\r
+ //\r
+ for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {\r
+\r
+ //\r
+ // -- 2nd inner loop --- Master/Slave --------\r
+ //\r
+ for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {\r
+\r
+ if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {\r
+ continue;\r
+ }\r
+\r
+ if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {\r
+ continue;\r
+ }\r
+\r
+ Status = IdeInit->CalculateMode (\r
+ IdeInit,\r
+ IdeChannel,\r
+ IdeDevice,\r
+ &SupportedModes\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));\r
+ continue;\r
+ }\r
+\r
+ IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];\r
+\r
+ //\r
+ // Set best supported PIO mode on this IDE device\r
+ //\r
+ if (SupportedModes->PioMode.Mode <= AtaPioMode2) {\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;\r
+ } else {\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;\r
+ }\r
+\r
+ TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
+\r
+ if (SupportedModes->ExtModeCount == 0){\r
+ Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
+ // be set together. Only one DMA mode can be set to a device. If setting\r
+ // DMA mode operation fails, we can continue moving on because we only use\r
+ // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
+ //\r
+ if (SupportedModes->UdmaMode.Valid) {\r
+\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;\r
+ TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);\r
+ Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ continue;\r
+ }\r
+ //\r
+ // Record Udma Mode\r
+ //\r
+ IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;\r
+ IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;\r
+ EnableInterrupt (IdeBlkIoDevicePtr);\r
+ } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
+\r
+ TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;\r
+ TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
+ Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ IdeBlkIoDevicePtr = NULL;\r
+ continue;\r
+ }\r
+\r
+ EnableInterrupt (IdeBlkIoDevicePtr);\r
+ }\r
+ //\r
+ // Init driver parameters\r
+ //\r
+ DriveParameters.Sector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.sectors_per_track;\r
+ DriveParameters.Heads = (UINT8) (IdeBlkIoDevicePtr->IdData->AtaData.heads - 1);\r
+ DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;\r
+ //\r
+ // Set Parameters for the device:\r
+ // 1) Init\r
+ // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command\r
+ //\r
+ if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {\r
+ Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);\r
+ }\r
+\r
+ //\r
+ // Record PIO mode used in private data\r
+ //\r
+ IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;\r
+\r
+ //\r
+ // Set IDE controller Timing Blocks in the PCI Configuration Space\r
+ //\r
+ IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);\r
+\r
+ //\r
+ // Add Component Name for the IDE/ATAPI device that was discovered.\r
+ //\r
+ IdeBlkIoDevicePtr->ControllerNameTable = NULL;\r
+ ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr);\r
+\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &IdeBlkIoDevicePtr->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ IdeBlkIoDevicePtr->DevicePath,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &IdeBlkIoDevicePtr->BlkIo,\r
+ &gEfiDiskInfoProtocolGuid,\r
+ &IdeBlkIoDevicePtr->DiskInfo,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ ReleaseIdeResources (IdeBlkIoDevicePtr);\r
+ }\r
+\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ IdeBlkIoDevicePtr->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+\r
+ IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;\r
+\r
+ //\r
+ // Report status code: device eanbled!\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),\r
+ IdeBlkIoDevicePtr->DevicePath\r
+ );\r
+\r
+ //\r
+ // Create event to clear pending IDE interrupt\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ ClearInterrupt,\r
+ IdeBlkIoDevicePtr,\r
+ &gEfiEventExitBootServicesGuid,\r
+ &IdeBlkIoDevicePtr->ExitBootServiceEvent\r
+ );\r
+\r
+ //\r
+ // end of 2nd inner loop ----\r
+ //\r
+ }\r
+ //\r
+ // end of 2nd outer loop ==========\r
+ //\r
+ }\r
+\r
+ //\r
+ // All configurations done! Notify IdeController to do post initialization\r
+ // work such as saving IDE controller PCI settings for S3 resume\r
+ //\r
+ IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);\r
+\r
+ if (SupportedModes != NULL) {\r
+ gBS->FreePool (SupportedModes);\r
+ }\r
+\r
+ PERF_START (NULL, "Finish IDE detection", "IDE", 1);\r
+ PERF_END (NULL, "Finish IDE detection", "IDE", 0);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+\r
+ //\r
+ // Report error code: controller error\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),\r
+ ParentDevicePath\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ IdeBusDriverPrivateData,\r
+ NULL\r
+ );\r
+\r
+ if (IdeBusDriverPrivateData != NULL) {\r
+ gBS->FreePool (IdeBusDriverPrivateData);\r
+ }\r
+\r
+ if (SupportedModes != NULL) {\r
+ gBS->FreePool (SupportedModes);\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return Status;\r
+\r
+}\r
+/**\r
+ Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all\r
+ child handle attached to the controller handle if there are.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Controller Handle of device to stop driver on\r
+ @param NumberOfChildren Not used\r
+ @param ChildHandleBuffer Not used\r
+\r
+ @retval EFI_SUCCESS This driver is removed DeviceHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBusDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ BOOLEAN AllChildrenStopped;\r
+ UINTN Index;\r
+ IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;\r
+ UINT64 Supports;\r
+\r
+ IdeBusDriverPrivateData = NULL;\r
+\r
+ if (NumberOfChildren == 0) {\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationSupported,\r
+ 0,\r
+ &Supports\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;\r
+ PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationDisable,\r
+ Supports,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &IdeBusDriverPrivateData,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiCallerIdGuid,\r
+ IdeBusDriverPrivateData,\r
+ NULL\r
+ );\r
+\r
+ if (IdeBusDriverPrivateData != NULL) {\r
+ gBS->FreePool (IdeBusDriverPrivateData);\r
+ }\r
+ //\r
+ // Close the bus driver\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiIdeControllerInitProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ AllChildrenStopped = TRUE;\r
+\r
+ for (Index = 0; Index < NumberOfChildren; Index++) {\r
+\r
+ Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ AllChildrenStopped = FALSE;\r
+ }\r
+ }\r
+\r
+ if (!AllChildrenStopped) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ issue ATA or ATAPI command to reset a block IO device.\r
+ @param This Block IO protocol instance pointer.\r
+ @param ExtendedVerification If FALSE,for ATAPI device, driver will only invoke ATAPI reset method\r
+ If TRUE, for ATAPI device, driver need invoke ATA reset method after\r
+ invoke ATAPI reset method\r
+\r
+ @retval EFI_DEVICE_ERROR When the device is neighther ATA device or ATAPI device.\r
+ @retval EFI_SUCCESS The device reset successfully\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReset (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+ //\r
+ // Requery IDE IO resources in case of the switch of native and legacy modes\r
+ //\r
+ ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+ //\r
+ // for ATA device, using ATA reset method\r
+ //\r
+ if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+ IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+ Status = AtaSoftReset (IdeBlkIoDevice);\r
+ goto Done;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // for ATAPI device, using ATAPI reset method\r
+ //\r
+ Status = AtapiSoftReset (IdeBlkIoDevice);\r
+ if (ExtendedVerification) {\r
+ Status = AtaSoftReset (IdeBlkIoDevice);\r
+ }\r
+\r
+Done:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Read data from a block IO device\r
+\r
+ @param This Block IO protocol instance pointer.\r
+ @param MediaId The media ID of the device\r
@param Lba Starting LBA address to read data\r
- @param BufferSize The size of data to be read
- @param Buffer Caller supplied buffer to save data
-
- @retval EFI_DEVICE_ERROR unknown device type
- @retval other read data status.
-
-**/
-EFI_STATUS
-EFIAPI
-IDEBlkIoReadBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
+ @param BufferSize The size of data to be read\r
+ @param Buffer Caller supplied buffer to save data\r
+\r
+ @retval EFI_DEVICE_ERROR unknown device type\r
+ @retval other read data status.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoReadBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
IN EFI_LBA Lba,\r
- IN UINTN BufferSize,
- OUT VOID *Buffer
- )
-{
- IDE_BLK_IO_DEV *IdeBlkIoDevice;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
-
- //
- // Requery IDE IO resources in case of the switch of native and legacy modes
- //
- ReassignIdeResources (IdeBlkIoDevice);
-
- //
- // For ATA compatible device, use ATA read block's mechanism
- //
- if (IdeBlkIoDevice->Type == IdeHardDisk ||
- IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
- Status = AtaBlkIoReadBlocks (
- IdeBlkIoDevice,
- MediaId,
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Requery IDE IO resources in case of the switch of native and legacy modes\r
+ //\r
+ ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+ //\r
+ // For ATA compatible device, use ATA read block's mechanism\r
+ //\r
+ if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+ IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+ Status = AtaBlkIoReadBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
Lba,\r
- BufferSize,
- Buffer
- );
- goto Done;
- }
-
- if (IdeBlkIoDevice->Type == IdeUnknown) {
- Status = EFI_DEVICE_ERROR;
- goto Done;
- }
-
- //
- // for ATAPI device, using ATAPI read block's mechanism
- //
- Status = AtapiBlkIoReadBlocks (
- IdeBlkIoDevice,
- MediaId,
+ BufferSize,\r
+ Buffer\r
+ );\r
+ goto Done;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // for ATAPI device, using ATAPI read block's mechanism\r
+ //\r
+ Status = AtapiBlkIoReadBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
Lba,\r
- BufferSize,
- Buffer
- );
-
-Done:
- gBS->RestoreTPL (OldTpl);
-
- return Status;
-}
-
-/**
+ BufferSize,\r
+ Buffer\r
+ );\r
+\r
+Done:\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
Write data to block io device.\r
-
- @param This Protocol instance pointer.
- @param MediaId The media ID of the device
+\r
+ @param This Protocol instance pointer.\r
+ @param MediaId The media ID of the device\r
@param Lba Starting LBA address to write data\r
- @param BufferSize The size of data to be written
- @param Buffer Caller supplied buffer to save data
-
- @retval EFI_DEVICE_ERROR unknown device type
- @retval other write data status
-
-**/
-EFI_STATUS
-EFIAPI
-IDEBlkIoWriteBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
+ @param BufferSize The size of data to be written\r
+ @param Buffer Caller supplied buffer to save data\r
+\r
+ @retval EFI_DEVICE_ERROR unknown device type\r
+ @retval other write data status\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoWriteBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
IN EFI_LBA Lba,\r
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
-{
- IDE_BLK_IO_DEV *IdeBlkIoDevice;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
- //
- // Requery IDE IO resources in case of the switch of native and legacy modes
- //
- ReassignIdeResources (IdeBlkIoDevice);
-
- //
- // for ATA device, using ATA write block's mechanism
- //
- if (IdeBlkIoDevice->Type == IdeHardDisk ||
- IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
-
- Status = AtaBlkIoWriteBlocks (
- IdeBlkIoDevice,
- MediaId,
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);\r
+ //\r
+ // Requery IDE IO resources in case of the switch of native and legacy modes\r
+ //\r
+ ReassignIdeResources (IdeBlkIoDevice);\r
+\r
+ //\r
+ // for ATA device, using ATA write block's mechanism\r
+ //\r
+ if (IdeBlkIoDevice->Type == IdeHardDisk ||\r
+ IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {\r
+\r
+ Status = AtaBlkIoWriteBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
Lba,\r
- BufferSize,
- Buffer
- );
- goto Done;
- }
-
- if (IdeBlkIoDevice->Type == IdeUnknown) {
- Status = EFI_DEVICE_ERROR;
- goto Done;
- }
-
- //
- // for ATAPI device, using ATAPI write block's mechanism
- //
- Status = AtapiBlkIoWriteBlocks (
- IdeBlkIoDevice,
- MediaId,
+ BufferSize,\r
+ Buffer\r
+ );\r
+ goto Done;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->Type == IdeUnknown) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // for ATAPI device, using ATAPI write block's mechanism\r
+ //\r
+ Status = AtapiBlkIoWriteBlocks (\r
+ IdeBlkIoDevice,\r
+ MediaId,\r
Lba,\r
- BufferSize,
- Buffer
- );
-
-Done:
- gBS->RestoreTPL (OldTpl);
- return Status;
-}
-/**
- Flushes all modified data to a physical block devices
-
- @param This Indicates a pointer to the calling context which to sepcify a
- sepcific block device
-
- @retval EFI_SUCCESS Always return success.
-**/
-EFI_STATUS
-EFIAPI
-IDEBlkIoFlushBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This
- )
-{
- //
- // return directly
- //
- return EFI_SUCCESS;
-}
-
-/**
+ BufferSize,\r
+ Buffer\r
+ );\r
+\r
+Done:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+/**\r
+ Flushes all modified data to a physical block devices\r
+\r
+ @param This Indicates a pointer to the calling context which to sepcify a\r
+ sepcific block device\r
+\r
+ @retval EFI_SUCCESS Always return success.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEBlkIoFlushBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This\r
+ )\r
+{\r
+ //\r
+ // return directly\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
This function is used by the IDE bus driver to get inquiry data. \r
Data format of Identify data is defined by the Interface GUID.\r
-
+\r
@param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
@param InquiryData Pointer to a buffer for the inquiry data.\r
@param InquiryDataSize Pointer to the value for the inquiry data size.\r
-
+\r
@retval EFI_SUCCESS The command was accepted without any errors.\r
@retval EFI_NOT_FOUND Device does not support this data class \r
@retval EFI_DEVICE_ERROR Error reading InquiryData from device \r
@retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough \r
-
-**/
-EFI_STATUS
-EFIAPI
-IDEDiskInfoInquiry (
- IN EFI_DISK_INFO_PROTOCOL *This,
- IN OUT VOID *InquiryData,
- IN OUT UINT32 *InquiryDataSize
- )
-{
- IDE_BLK_IO_DEV *IdeBlkIoDevice;
-
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
-
- if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {
- *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);
- return EFI_BUFFER_TOO_SMALL;
- }
-
- if (IdeBlkIoDevice->InquiryData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- gBS->CopyMem (InquiryData, IdeBlkIoDevice->InquiryData, sizeof (ATAPI_INQUIRY_DATA));
- *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);
-
- return EFI_SUCCESS;
-}
-
-/**
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoInquiry (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *InquiryData,\r
+ IN OUT UINT32 *InquiryDataSize\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+\r
+ if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {\r
+ *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->InquiryData == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ gBS->CopyMem (InquiryData, IdeBlkIoDevice->InquiryData, sizeof (ATAPI_INQUIRY_DATA));\r
+ *InquiryDataSize = sizeof (ATAPI_INQUIRY_DATA);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
This function is used by the IDE bus driver to get identify data. \r
- Data format of Identify data is defined by the Interface GUID.
-
+ Data format of Identify data is defined by the Interface GUID.\r
+\r
@param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
@param IdentifyData Pointer to a buffer for the identify data.\r
@param IdentifyDataSize Pointer to the value for the identify data size.\r
-
+\r
@retval EFI_SUCCESS The command was accepted without any errors.\r
@retval EFI_NOT_FOUND Device does not support this data class \r
@retval EFI_DEVICE_ERROR Error reading IdentifyData from device \r
@retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough \r
-
-**/
-EFI_STATUS
-EFIAPI
-IDEDiskInfoIdentify (
- IN EFI_DISK_INFO_PROTOCOL *This,
- IN OUT VOID *IdentifyData,
- IN OUT UINT32 *IdentifyDataSize
- )
-{
- IDE_BLK_IO_DEV *IdeBlkIoDevice;
-
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
-
- if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {
- *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);
- return EFI_BUFFER_TOO_SMALL;
- }
-
- if (IdeBlkIoDevice->IdData == NULL) {
- return EFI_NOT_FOUND;
- }
-
- gBS->CopyMem (IdentifyData, IdeBlkIoDevice->IdData, sizeof (EFI_IDENTIFY_DATA));
- *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);
-
- return EFI_SUCCESS;
-}
-
-/**
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoIdentify (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *IdentifyData,\r
+ IN OUT UINT32 *IdentifyDataSize\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+\r
+ if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {\r
+ *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ if (IdeBlkIoDevice->IdData == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ gBS->CopyMem (IdentifyData, IdeBlkIoDevice->IdData, sizeof (EFI_IDENTIFY_DATA));\r
+ *IdentifyDataSize = sizeof (EFI_IDENTIFY_DATA);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
This function is used by the IDE bus driver to get sense data. \r
- Data format of Sense data is defined by the Interface GUID.
-
+ Data format of Sense data is defined by the Interface GUID.\r
+\r
@param This Pointer to the EFI_DISK_INFO_PROTOCOL instance. \r
@param SenseData Pointer to the SenseData. \r
@param SenseDataSize Size of SenseData in bytes. \r
@param SenseDataNumber Pointer to the value for the identify data size.\r
-
+\r
@retval EFI_SUCCESS The command was accepted without any errors.\r
@retval EFI_NOT_FOUND Device does not support this data class \r
@retval EFI_DEVICE_ERROR Error reading InquiryData from device \r
@retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough \r
-
-**/
-EFI_STATUS
-EFIAPI
-IDEDiskInfoSenseData (
- IN EFI_DISK_INFO_PROTOCOL *This,
- IN OUT VOID *SenseData,
- IN OUT UINT32 *SenseDataSize,
- OUT UINT8 *SenseDataNumber
- )
-{
- return EFI_NOT_FOUND;
-}
-
-/**
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoSenseData (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ IN OUT VOID *SenseData,\r
+ IN OUT UINT32 *SenseDataSize,\r
+ OUT UINT8 *SenseDataNumber\r
+ )\r
+{\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
This function is used by the IDE bus driver to get controller information.\r
-
+\r
@param This Pointer to the EFI_DISK_INFO_PROTOCOL instance. \r
@param IdeChannel Pointer to the Ide Channel number. Primary or secondary.\r
@param IdeDevice Pointer to the Ide Device number. Master or slave.\r
-
+\r
@retval EFI_SUCCESS IdeChannel and IdeDevice are valid \r
@retval EFI_UNSUPPORTED This is not an IDE device \r
-
-**/
-EFI_STATUS
-EFIAPI
-IDEDiskInfoWhichIde (
- IN EFI_DISK_INFO_PROTOCOL *This,
- OUT UINT32 *IdeChannel,
- OUT UINT32 *IdeDevice
- )
-{
- IDE_BLK_IO_DEV *IdeBlkIoDevice;
-
- IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
- *IdeChannel = IdeBlkIoDevice->Channel;
- *IdeDevice = IdeBlkIoDevice->Device;
-
- return EFI_SUCCESS;
-}
-
-/**
- The is an event(generally the event is exitBootService event) call back function.
- Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.
-
- @param Event Pointer to this event
- @param Context Event hanlder private data
-
-**/
-VOID
-EFIAPI
-ClearInterrupt (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
- UINT64 IoPortForBmis;
- UINT8 RegisterValue;
- IDE_BLK_IO_DEV *IdeDev;
-
- //
- // Get our context
- //
- IdeDev = (IDE_BLK_IO_DEV *) Context;
-
- //
- // Obtain IDE IO port registers' base addresses
- //
- Status = ReassignIdeResources (IdeDev);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- //
- // Check whether interrupt is pending
- //
-
- //
- // Reset IDE device to force it de-assert interrupt pin
- // Note: this will reset all devices on this IDE channel
- //
- AtaSoftReset (IdeDev);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- //
- // Get base address of IDE Bus Master Status Regsiter
- //
- if (IdePrimary == IdeDev->Channel) {
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
- } else {
- if (IdeSecondary == IdeDev->Channel) {
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
- } else {
- return;
- }
- }
- //
- // Read BMIS register and clear ERROR and INTR bit
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- //
- // Select the other device on this channel to ensure this device to release the interrupt pin
- //
- if (IdeDev->Device == 0) {
- RegisterValue = (1 << 4) | 0xe0;
- } else {
- RegisterValue = (0 << 4) | 0xe0;
- }
- IDEWritePortB (
- IdeDev->PciIo,
- IdeDev->IoPort->Head,
- RegisterValue
- );
-
-}
-
-/**
- The user Entry Point for module IdeBus. The user code starts with this function.
-
- @param[in] ImageHandle The firmware allocated handle for the EFI image.
- @param[in] SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The entry point is executed successfully.
- @retval other Some error occurs when executing this entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-InitializeIdeBus(
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- //
- // Install driver model protocol(s).
- //
- Status = EfiLibInstallAllDriverProtocols2 (
- ImageHandle,
- SystemTable,
- &gIDEBusDriverBinding,
- ImageHandle,
- &gIDEBusComponentName,
- &gIDEBusComponentName2,
- NULL,
- NULL,
- &gIDEBusDriverDiagnostics,
- &gIDEBusDriverDiagnostics2
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IDEDiskInfoWhichIde (\r
+ IN EFI_DISK_INFO_PROTOCOL *This,\r
+ OUT UINT32 *IdeChannel,\r
+ OUT UINT32 *IdeDevice\r
+ )\r
+{\r
+ IDE_BLK_IO_DEV *IdeBlkIoDevice;\r
+\r
+ IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);\r
+ *IdeChannel = IdeBlkIoDevice->Channel;\r
+ *IdeDevice = IdeBlkIoDevice->Device;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ The is an event(generally the event is exitBootService event) call back function.\r
+ Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.\r
+\r
+ @param Event Pointer to this event\r
+ @param Context Event hanlder private data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ClearInterrupt (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 IoPortForBmis;\r
+ UINT8 RegisterValue;\r
+ IDE_BLK_IO_DEV *IdeDev;\r
+\r
+ //\r
+ // Get our context\r
+ //\r
+ IdeDev = (IDE_BLK_IO_DEV *) Context;\r
+\r
+ //\r
+ // Obtain IDE IO port registers' base addresses\r
+ //\r
+ Status = ReassignIdeResources (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Check whether interrupt is pending\r
+ //\r
+\r
+ //\r
+ // Reset IDE device to force it de-assert interrupt pin\r
+ // Note: this will reset all devices on this IDE channel\r
+ //\r
+ AtaSoftReset (IdeDev);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Get base address of IDE Bus Master Status Regsiter\r
+ //\r
+ if (IdePrimary == IdeDev->Channel) {\r
+ IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;\r
+ } else {\r
+ if (IdeSecondary == IdeDev->Channel) {\r
+ IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;\r
+ } else {\r
+ return;\r
+ }\r
+ }\r
+ //\r
+ // Read BMIS register and clear ERROR and INTR bit\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmis,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmis,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ //\r
+ // Select the other device on this channel to ensure this device to release the interrupt pin\r
+ //\r
+ if (IdeDev->Device == 0) {\r
+ RegisterValue = (1 << 4) | 0xe0;\r
+ } else {\r
+ RegisterValue = (0 << 4) | 0xe0;\r
+ }\r
+ IDEWritePortB (\r
+ IdeDev->PciIo,\r
+ IdeDev->IoPort->Head,\r
+ RegisterValue\r
+ );\r
+\r
+}\r
+\r
+/**\r
+ The user Entry Point for module IdeBus. The user code starts with this function.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeIdeBus(\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Install driver model protocol(s).\r
+ //\r
+ Status = EfiLibInstallAllDriverProtocols2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gIDEBusDriverBinding,\r
+ ImageHandle,\r
+ &gIDEBusComponentName,\r
+ &gIDEBusComponentName2,\r
+ NULL,\r
+ NULL,\r
+ &gIDEBusDriverDiagnostics,\r
+ &gIDEBusDriverDiagnostics2\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r