4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This file implement UEFI driver for IDE Bus which includes device identification,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Child device(Disk, CDROM, etc) enumeration and child handler installation, and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync driver stop.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @par Revision Reference:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This module is modified from DXE\IDE module for Ide Contriller Init support
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// IDE Bus Driver Binding Protocol Instance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_DRIVER_BINDING_PROTOCOL gIDEBusDriverBinding = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Deregister an IDE device and free resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Controller Ide device handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Handle Handle of device to deregister driver on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Deregiter a specific IDE device successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Report Status code: Device disabled
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the child handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release allocated resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Supported function of Driver Binding protocol for this driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ControllerHandle The handle of the controller to test.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param RemainingDevicePath A pointer to the remaining portion of a device path.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Driver loaded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Driver not loaded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check if RemainingDevicePath is the End of Device Path Node,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if yes, go on checking other conditions
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If RemainingDevicePath isn't the End of Device Path Node,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // check its validation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DevicePathNodeLength(&Node->DevPath) != sizeof(ATAPI_DEVICE_PATH)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the Ide Controller Init Protocol, which installed by the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // IdeController module.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the I/O Abstraction(s) used to perform the supported test
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the EFI Device Path protocol needed to perform the supported test
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close protocol, don't use device path protocol in the Support() function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the EfiPciIoProtocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Now further check the PCI header: Base class (offset 0x0B) and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Sub Class (offset 0x0A). This controller should be an IDE controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Examine if it is IDE mode by class code
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || (PciData.Hdr.ClassCode[1] != PCI_SUB_CLASS_IDE)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start function of Driver binding protocol which start this driver on Controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by detecting all disks and installing BlockIo protocol on them.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Controller Handle of device to bind driver to.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param RemainingDevicePath produce all possible children.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS This driver is added to ControllerHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other This driver does not support this device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IDE_BLK_IO_DEV *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IDE_REGISTERS_BASE_ADDR IdeRegsBaseAddr[IdeMaxChannel];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Local variables declaration for IdeControllerInit support
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Perform IdeBus initialization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Now open the IDE_CONTROLLER_INIT protocol. Step7.1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The following OpenProtocol function with _GET_PROTOCOL attribute and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will not return EFI_ALREADY_STARTED, so save it for now
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // open protocol is not SUCCESS or not ALREADY_STARTED, error exit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save Enumall. Step7.2
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // attribute will not return EFI_ALREADY_STARTED
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read the environment variable that contains the IDEBus Driver's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Config options that were set by the Driver Configuration Protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // must enumerate all IDE devices anyway
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (!IsDevicePathEnd (RemainingDevicePath)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If RemainingDevicePath isn't the End of Device Path Node,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // only scan the specified device by RemainingDevicePath
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BeginningIdeChannel = Node->Atapi.PrimarySecondary;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If RemainingDevicePath is the End of Device Path Node,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // skip enumerate any device and return EFI_SUCESSS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Obtain IDE IO port registers' base addresses
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Report status code: begin IdeBus initialization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // now obtain channel information fron IdeControllerInit protocol. Step9
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Now inform the IDE Controller Init Module. Sept10
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No reset channel function implemented. Sept11
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Prepare to detect IDE device of this channel
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // -- 1st inner loop --- Master/Slave ------------ Step14
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the configuration options allow this device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The device has been scanned in another Start(), No need to scan it again
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for perf optimization.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // create child handle for the detected device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->Signature = IDE_BLK_IO_DEV_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->Channel = (EFI_IDE_CHANNEL) IdeChannel;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->Device = (EFI_IDE_DEVICE) IdeDevice;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // initialize Block IO interface's Media pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize IDE IO port addresses, including Command Block registers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and Control Block registers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Report Status code: is about to detect IDE drive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Discover device, now!
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice] = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set Device Path
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewNode.Atapi.PrimarySecondary = (UINT8) IdeBlkIoDevicePtr->Channel;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewNode.Atapi.SlaveMaster = (UINT8) IdeBlkIoDevicePtr->Device;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Submit identify data to IDE controller init driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&IdentifyData, IdeBlkIoDevicePtr->IdData, sizeof (IdentifyData));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Device detection failed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // end of 1st inner loop ---
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // end of 1st outer loop =========
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // = 2nd outer loop == Primary/Secondary =================
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // -- 2nd inner loop --- Master/Slave --------
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set best supported PIO mode on this IDE device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // be set together. Only one DMA mode can be set to a device. If setting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DMA mode operation fails, we can continue moving on because we only use
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // PIO mode at boot time. DMA modes are used by certain kind of OS booting
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Record Udma Mode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (SupportedModes->MultiWordDmaMode.Valid) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Init driver parameters
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DriveParameters.Sector = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DriveParameters.Heads = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DriveParameters.MultipleSector = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set Parameters for the device:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Record PIO mode used in private data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set IDE controller Timing Blocks in the PCI Configuration Space
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add Component Name for the IDE/ATAPI device that was discovered.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Report status code: device eanbled!
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create event to clear pending IDE interrupt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // end of 2nd inner loop ----
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // end of 2nd outer loop ==========
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // All configurations done! Notify IdeController to do post initialization
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // work such as saving IDE controller PCI settings for S3 resume
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PERF_START (NULL, "Finish IDE detection", "IDE", 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Report error code: controller error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stop function of Driver Binding Protocol which is to stop the driver on Controller Handle and all
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync child handle attached to the controller handle if there are.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Controller Handle of device to stop driver on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NumberOfChildren Not used
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ChildHandleBuffer Not used
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS This driver is removed DeviceHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other This driver was not removed from this device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IDE_BUS_DRIVER_PRIVATE_DATA *IdeBusDriverPrivateData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Supports &= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_DEVICE_ENABLE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the bus driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < NumberOfChildren; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = DeRegisterIdeDevice (This, Controller, ChildHandleBuffer[Index]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync issue ATA or ATAPI command to reset a block IO device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Block IO protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ExtendedVerification If FALSE,for ATAPI device, driver will only invoke ATAPI reset method
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If TRUE, for ATAPI device, driver need invoke ATA reset method after
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync invoke ATAPI reset method
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR When the device is neighther ATA device or ATAPI device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The device reset successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Requery IDE IO resources in case of the switch of native and legacy modes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for ATA device, using ATA reset method
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for ATAPI device, using ATAPI reset method
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Read data from a block IO device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Block IO protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MediaId The media ID of the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Lba Starting LBA address to read data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BufferSize The size of data to be read
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Buffer Caller supplied buffer to save data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR unknown device type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other read data status.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Requery IDE IO resources in case of the switch of native and legacy modes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For ATA compatible device, use ATA read block's mechanism
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for ATAPI device, using ATAPI read block's mechanism
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Write data to block io device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MediaId The media ID of the device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Lba Starting LBA address to write data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BufferSize The size of data to be written
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Buffer Caller supplied buffer to save data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR unknown device type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other write data status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Requery IDE IO resources in case of the switch of native and legacy modes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for ATA device, using ATA write block's mechanism
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for ATAPI device, using ATAPI write block's mechanism
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flushes all modified data to a physical block devices
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Indicates a pointer to the calling context which to sepcify a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sepcific block device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Always return success.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // return directly
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is used by the IDE bus driver to get inquiry data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data format of Identify data is defined by the Interface GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param InquiryData Pointer to a buffer for the inquiry data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param InquiryDataSize Pointer to the value for the inquiry data size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The command was accepted without any errors.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Device does not support this data class
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Error reading InquiryData from device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL IntquiryDataSize not big enough
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*InquiryDataSize < sizeof (ATAPI_INQUIRY_DATA)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CopyMem (InquiryData, IdeBlkIoDevice->InquiryData, sizeof (ATAPI_INQUIRY_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is used by the IDE bus driver to get identify data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data format of Identify data is defined by the Interface GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param IdentifyData Pointer to a buffer for the identify data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param IdentifyDataSize Pointer to the value for the identify data size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The command was accepted without any errors.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Device does not support this data class
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Error reading IdentifyData from device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*IdentifyDataSize < sizeof (EFI_IDENTIFY_DATA)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CopyMem (IdentifyData, IdeBlkIoDevice->IdData, sizeof (EFI_IDENTIFY_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is used by the IDE bus driver to get sense data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data format of Sense data is defined by the Interface GUID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SenseData Pointer to the SenseData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SenseDataSize Size of SenseData in bytes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SenseDataNumber Pointer to the value for the identify data size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The command was accepted without any errors.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Device does not support this data class
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Error reading InquiryData from device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is used by the IDE bus driver to get controller information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Pointer to the EFI_DISK_INFO_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param IdeChannel Pointer to the Ide Channel number. Primary or secondary.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param IdeDevice Pointer to the Ide Device number. Master or slave.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS IdeChannel and IdeDevice are valid
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED This is not an IDE device
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_DISK_INFO_THIS (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The is an event(generally the event is exitBootService event) call back function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Clear pending IDE interrupt before OS loader/kernel take control of the IDE device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Event Pointer to this event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Context Event hanlder private data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get our context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Obtain IDE IO port registers' base addresses
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether interrupt is pending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset IDE device to force it de-assert interrupt pin
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Note: this will reset all devices on this IDE channel
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get base address of IDE Bus Master Status Regsiter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read BMIS register and clear ERROR and INTR bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select the other device on this channel to ensure this device to release the interrupt pin
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The user Entry Point for module IdeBus. The user code starts with this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The firmware allocated handle for the EFI image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SystemTable A pointer to the EFI System Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The entry point is executed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Some error occurs when executing this entry point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install driver model protocol(s).