+++ /dev/null
-/** @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.\r
-\r
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\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
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- PCI_TYPE00 PciData;\r
-\r
- if (RemainingDevicePath != NULL) {\r
- Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
- //\r
- // Check if RemainingDevicePath is the End of Device Path Node,\r
- // if yes, go on checking other conditions\r
- //\r
- if (!IsDevicePathEnd (Node)) {\r
- //\r
- // If RemainingDevicePath isn't the End of Device Path Node,\r
- // check its validation\r
- //\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
- //\r
- // Verify the Ide Controller Init Protocol, which installed by the\r
- // IdeController module.\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
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Close the I/O Abstraction(s) used to perform the supported test\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiIdeControllerInitProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- //\r
- // Open the EFI Device Path protocol 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
- //\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
- // Get the EfiPciIoProtocol\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
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Now further check the PCI header: Base class (offset 0x0B) and\r
- // Sub Class (offset 0x0A). This controller should be an IDE controller\r
- //\r
- Status = PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- 0,\r
- sizeof (PciData),\r
- &PciData\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Examine if it is IDE mode by class code\r
- //\r
- if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || (PciData.Hdr.ClassCode[1] != PCI_SUB_CLASS_IDE)) {\r
- Status = EFI_UNSUPPORTED;\r
- } else {\r
- Status = EFI_SUCCESS;\r
- }\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 &= (UINT64)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 || RemainingDevicePath == NULL) {\r
- //\r
- // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL,\r
- // must enumerate all IDE devices anyway\r
- //\r
- BeginningIdeChannel = IdePrimary;\r
- EndIdeChannel = IdeSecondary;\r
- BeginningIdeDevice = IdeMaster;\r
- EndIdeDevice = IdeSlave;\r
-\r
- } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
- //\r
- // If RemainingDevicePath isn't the End of Device Path Node,\r
- // only scan the specified device by RemainingDevicePath\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
- } else {\r
- //\r
- // If RemainingDevicePath is the End of Device Path Node,\r
- // skip enumerate any device and return EFI_SUCESSS\r
- //\r
- BeginningIdeChannel = IdeMaxChannel;\r
- EndIdeChannel = IdeMaxChannel - 1;\r
- BeginningIdeDevice = IdeMaxDevice;\r
- EndIdeDevice = IdeMaxDevice - 1;\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
- ASSERT (IdeChannel * 2 + IdeDevice < MAX_IDE_DEVICE);\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
- ASSERT (IdeChannel < IdeMaxChannel && IdeDevice < IdeMaxDevice);\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) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;\r
- DriveParameters.Heads = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->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
- 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 &= (UINT64)(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\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,\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,\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,\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
-\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\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,\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,\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,\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
-\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.\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
-\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.\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
-\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
-\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 handler 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
- Status = 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