/** @file
  EFI glue for BIOS INT 13h block devices.

  This file is coded to EDD 3.0 as defined by T13 D1386 Revision 4
  Availible on http://www.t13.org/#Project drafts
  Currently at ftp://fission.dt.wdc.com/pub/standards/x3t13/project/d1386r4.pdf

Copyright (c) 1999 - 2011, Intel Corporation. All rights reserved.<BR>

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.

**/

#include "BiosBlkIo.h"

//
// Global data declaration
//
//
// EFI Driver Binding Protocol Instance
//
EFI_DRIVER_BINDING_PROTOCOL gBiosBlockIoDriverBinding = {
  BiosBlockIoDriverBindingSupported,
  BiosBlockIoDriverBindingStart,
  BiosBlockIoDriverBindingStop,
  0x3,
  NULL,
  NULL
};

//
// Semaphore to control access to global variables mActiveInstances and mBufferUnder1Mb
//
EFI_LOCK                    mGlobalDataLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_APPLICATION);

//
// Number of active instances of this protocol.  This is used to allocate/free
// the shared buffer.  You must acquire the semaphore to modify.
//
UINTN                       mActiveInstances = 0;

//
// Pointer to the beginning of the buffer used for real mode thunk
// You must acquire the semaphore to modify.
//
EFI_PHYSICAL_ADDRESS        mBufferUnder1Mb = 0;

//
// Address packet is a buffer under 1 MB for all version EDD calls
//
EDD_DEVICE_ADDRESS_PACKET   *mEddBufferUnder1Mb;

//
// This is a buffer for INT 13h func 48 information
//
BIOS_LEGACY_DRIVE           *mLegacyDriverUnder1Mb;

//
// Buffer of 0xFE00 bytes for EDD 1.1 transfer must be under 1 MB
//  0xFE00 bytes is the max transfer size supported.
//
VOID                        *mEdd11Buffer;

/**
  Driver entry point.

  @param  ImageHandle  Handle of driver image.
  @param  SystemTable  Pointer to system table.

  @retval EFI_SUCCESS  Entrypoint successfully executed.
  @retval Others       Fail to execute entrypoint.

**/
EFI_STATUS
EFIAPI
BiosBlockIoDriverEntryPoint (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Install protocols
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gBiosBlockIoDriverBinding,
             ImageHandle,
             &gBiosBlockIoComponentName,
             &gBiosBlockIoComponentName2
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Install Legacy BIOS GUID to mark this driver as a BIOS Thunk Driver
  //
  return gBS->InstallMultipleProtocolInterfaces (
                &ImageHandle,
                &gEfiLegacyBiosGuid,
                NULL,
                NULL
                );
}

/**
  Check whether the driver supports this device.

  @param  This                   The Udriver binding protocol.
  @param  Controller             The controller handle to check.
  @param  RemainingDevicePath    The remaining device path.

  @retval EFI_SUCCESS            The driver supports this controller.
  @retval other                  This device isn't supported.

**/
EFI_STATUS
EFIAPI
BiosBlockIoDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  PCI_TYPE00                Pci;

  //
  // See if the Legacy BIOS Protocol is available
  //
  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  gBS->CloseProtocol (
        Controller,
        &gEfiDevicePathProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );      
  
  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // See if this is a PCI VGA Controller by looking at the Command register and
  // Class Code Register
  //
  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci);
  if (EFI_ERROR (Status)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  Status = EFI_UNSUPPORTED;
  if (Pci.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE ||
      (Pci.Hdr.ClassCode[2] == PCI_BASE_CLASS_INTELLIGENT && Pci.Hdr.ClassCode[1] == PCI_SUB_CLASS_INTELLIGENT)
      ) {
    Status = EFI_SUCCESS;
  }

Done:
  gBS->CloseProtocol (
        Controller,
        &gEfiPciIoProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

  return Status;
}

/**
  Starts the device with this driver.

  @param  This                   The driver binding instance.
  @param  Controller             Handle of device to bind driver to.
  @param  RemainingDevicePath    Optional parameter use to pick a specific child
                                 device to start.

  @retval EFI_SUCCESS            The controller is controlled by the driver.
  @retval Other                  This controller cannot be started.

**/
EFI_STATUS
EFIAPI
BiosBlockIoDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINT8                     DiskStart;
  UINT8                     DiskEnd;
  BIOS_BLOCK_IO_DEV         *BiosBlockIoPrivate;
  EFI_DEVICE_PATH_PROTOCOL  *PciDevPath;
  UINTN                     Index;
  UINTN                     Flags;
  UINTN                     TmpAddress;
  BOOLEAN                   DeviceEnable;

  //
  // Initialize variables
  //
  PciIo      = NULL;
  PciDevPath = NULL;
  
  DeviceEnable = FALSE; 

  //
  // See if the Legacy BIOS Protocol is available
  //
  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  //
  // Open the IO Abstraction(s) needed
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &PciDevPath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    goto Error;
  }
  //
  // Enable the device and make sure VGA cycles are being forwarded to this VGA device
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationEnable,
                    EFI_PCI_DEVICE_ENABLE,
                    NULL
                    );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  
  DeviceEnable = TRUE;
  
  //
  // Check to see if there is a legacy option ROM image associated with this PCI device
  //
  Status = LegacyBios->CheckPciRom (
                        LegacyBios,
                        Controller,
                        NULL,
                        NULL,
                        &Flags
                        );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  //
  // Post the legacy option ROM if it is available.
  //
  Status = LegacyBios->InstallPciRom (
                        LegacyBios,
                        Controller,
                        NULL,
                        &Flags,
                        &DiskStart,
                        &DiskEnd,
                        NULL,
                        NULL
                        );
  if (EFI_ERROR (Status)) {
    goto Error;
  }
  //
  // All instances share a buffer under 1MB to put real mode thunk code in
  // If it has not been allocated, then we allocate it.
  //
  if (mBufferUnder1Mb == 0) {
    //
    // Should only be here if there are no active instances
    //
    ASSERT (mActiveInstances == 0);

    //
    // Acquire the lock
    //
    EfiAcquireLock (&mGlobalDataLock);

    //
    // Allocate below 1MB
    //
    mBufferUnder1Mb = 0x00000000000FFFFF;
    Status          = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, BLOCK_IO_BUFFER_PAGE_SIZE, &mBufferUnder1Mb);

    //
    // Release the lock
    //
    EfiReleaseLock (&mGlobalDataLock);

    //
    // Check memory allocation success
    //
    if (EFI_ERROR (Status)) {
      //
      // In checked builds we want to assert if the allocate failed.
      //
      ASSERT_EFI_ERROR (Status);
      Status          = EFI_OUT_OF_RESOURCES;
      mBufferUnder1Mb = 0;
      goto Error;
    }

    TmpAddress = (UINTN) mBufferUnder1Mb;
    //
    // Adjusting the value to be on proper boundary
    //
    mEdd11Buffer = (VOID *) ALIGN_VARIABLE (TmpAddress);

    TmpAddress   = (UINTN) mEdd11Buffer + MAX_EDD11_XFER;
    //
    // Adjusting the value to be on proper boundary
    //
    mLegacyDriverUnder1Mb = (BIOS_LEGACY_DRIVE *) ALIGN_VARIABLE (TmpAddress);

    TmpAddress = (UINTN) mLegacyDriverUnder1Mb + sizeof (BIOS_LEGACY_DRIVE);
    //
    // Adjusting the value to be on proper boundary
    //
    mEddBufferUnder1Mb = (EDD_DEVICE_ADDRESS_PACKET *) ALIGN_VARIABLE (TmpAddress);
  }
  //
  // Allocate the private device structure for each disk
  //
  for (Index = DiskStart; Index < DiskEnd; Index++) {

    Status = gBS->AllocatePool (
                    EfiBootServicesData,
                    sizeof (BIOS_BLOCK_IO_DEV),
                    (VOID **) &BiosBlockIoPrivate
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
    //
    // Zero the private device structure
    //
    ZeroMem (BiosBlockIoPrivate, sizeof (BIOS_BLOCK_IO_DEV));

    //
    // Initialize the private device structure
    //
    BiosBlockIoPrivate->Signature                 = BIOS_CONSOLE_BLOCK_IO_DEV_SIGNATURE;
    BiosBlockIoPrivate->ControllerHandle          = Controller;
    BiosBlockIoPrivate->LegacyBios                = LegacyBios;
    BiosBlockIoPrivate->PciIo                     = PciIo;

    BiosBlockIoPrivate->Bios.Floppy               = FALSE;
    BiosBlockIoPrivate->Bios.Number               = (UINT8) Index;
    BiosBlockIoPrivate->Bios.Letter               = (UINT8) (Index - 0x80 + 'C');
    BiosBlockIoPrivate->BlockMedia.RemovableMedia = FALSE;

    if (BiosInitBlockIo (BiosBlockIoPrivate)) {
      SetBiosInitBlockIoDevicePath (PciDevPath, &BiosBlockIoPrivate->Bios, &BiosBlockIoPrivate->DevicePath);

      //
      // Install the Block Io Protocol onto a new child handle
      //
      Status = gBS->InstallMultipleProtocolInterfaces (
                      &BiosBlockIoPrivate->Handle,
                      &gEfiBlockIoProtocolGuid,
                      &BiosBlockIoPrivate->BlockIo,
                      &gEfiDevicePathProtocolGuid,
                      BiosBlockIoPrivate->DevicePath,
                      NULL
                      );
      if (EFI_ERROR (Status)) {
        gBS->FreePool (BiosBlockIoPrivate);
      }
      //
      // Open For Child Device
      //
      Status = gBS->OpenProtocol (
                      Controller,
                      &gEfiPciIoProtocolGuid,
                      (VOID **) &BiosBlockIoPrivate->PciIo,
                      This->DriverBindingHandle,
                      BiosBlockIoPrivate->Handle,
                      EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                      );

    } else {
      gBS->FreePool (BiosBlockIoPrivate);
    }
  }

Error:
  if (EFI_ERROR (Status)) {
    if (PciIo != NULL) {
      if (DeviceEnable) {
        PciIo->Attributes (
                PciIo,
                EfiPciIoAttributeOperationDisable,
                EFI_PCI_DEVICE_ENABLE,
                NULL
                );
      }
      gBS->CloseProtocol (
            Controller,
            &gEfiPciIoProtocolGuid,
            This->DriverBindingHandle,
            Controller
            );
      if (PciDevPath != NULL) {
        gBS->CloseProtocol (
              Controller,
              &gEfiDevicePathProtocolGuid,
              This->DriverBindingHandle,
              Controller
              );
      }
      if (mBufferUnder1Mb != 0 && mActiveInstances == 0) {
        gBS->FreePages (mBufferUnder1Mb, BLOCK_IO_BUFFER_PAGE_SIZE);

        //
        // Clear the buffer back to 0
        //
        EfiAcquireLock (&mGlobalDataLock);
        mBufferUnder1Mb = 0;
        EfiReleaseLock (&mGlobalDataLock);
      }
    }
  } else {
    //
    // Successfully installed, so increment the number of active instances
    //
    EfiAcquireLock (&mGlobalDataLock);
    mActiveInstances++;
    EfiReleaseLock (&mGlobalDataLock);
  }

  return Status;
}

/**
  Stop the device handled by this driver.

  @param  This                   The driver binding protocol.
  @param  Controller             The controller to release.
  @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
  @param  ChildHandleBuffer      The array of child handle.

  @retval EFI_SUCCESS            The device was stopped.
  @retval EFI_DEVICE_ERROR       The device could not be stopped due to a device error.
  @retval Others                 Fail to uninstall protocols attached on the device.

**/
EFI_STATUS
EFIAPI
BiosBlockIoDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      Controller,
  IN  UINTN                           NumberOfChildren,
  IN  EFI_HANDLE                      *ChildHandleBuffer
  )
{
  EFI_STATUS            Status;
  BOOLEAN               AllChildrenStopped;
  EFI_BLOCK_IO_PROTOCOL *BlockIo;
  BIOS_BLOCK_IO_DEV     *BiosBlockIoPrivate;
  UINTN                 Index;

  //
  // Decrement the number of active instances
  //
  if (mActiveInstances != 0) {
    //
    // Add a check since the stop function will be called 2 times for each handle
    //
    EfiAcquireLock (&mGlobalDataLock);
    mActiveInstances--;
    EfiReleaseLock (&mGlobalDataLock);
  }

  if ((mActiveInstances == 0) && (mBufferUnder1Mb != 0)) {
    //
    // Free our global buffer
    //
    Status = gBS->FreePages (mBufferUnder1Mb, BLOCK_IO_BUFFER_PAGE_SIZE);
    ASSERT_EFI_ERROR (Status);

    EfiAcquireLock (&mGlobalDataLock);
    mBufferUnder1Mb = 0;
    EfiReleaseLock (&mGlobalDataLock);
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {
    Status = gBS->OpenProtocol (
                    ChildHandleBuffer[Index],
                    &gEfiBlockIoProtocolGuid,
                    (VOID **) &BlockIo,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    BiosBlockIoPrivate = BIOS_BLOCK_IO_FROM_THIS (BlockIo);

    //
    // Release PCI I/O and Block IO Protocols on the clild handle.
    //
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    ChildHandleBuffer[Index],
                    &gEfiBlockIoProtocolGuid,
                    &BiosBlockIoPrivate->BlockIo,
                    &gEfiDevicePathProtocolGuid,
                    BiosBlockIoPrivate->DevicePath,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
    //
    // Shutdown the hardware
    //
    BiosBlockIoPrivate->PciIo->Attributes (
                                BiosBlockIoPrivate->PciIo,
                                EfiPciIoAttributeOperationDisable,
                                EFI_PCI_DEVICE_ENABLE,
                                NULL
                                );

    gBS->CloseProtocol (
          Controller,
          &gEfiPciIoProtocolGuid,
          This->DriverBindingHandle,
          ChildHandleBuffer[Index]
          );

    gBS->FreePool (BiosBlockIoPrivate);
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  }

  Status = gBS->CloseProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  This->DriverBindingHandle,
                  Controller
                  );

  Status = gBS->CloseProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  This->DriverBindingHandle,
                  Controller
                  );

  return EFI_SUCCESS;
}

/**
  Build device path for device.

  @param  BaseDevicePath         Base device path.
  @param  Drive                  Legacy drive.
  @param  DevicePath             Device path for output.

**/
VOID
SetBiosInitBlockIoDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *BaseDevicePath,
  IN  BIOS_LEGACY_DRIVE         *Drive,
  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath
  )
{
  EFI_STATUS                  Status;
  BLOCKIO_VENDOR_DEVICE_PATH  VendorNode;
  
  Status = EFI_UNSUPPORTED;
  
  //
  // BugBug: Check for memory leaks!
  //
  if (Drive->EddVersion == EDD_VERSION_30) {
    //
    // EDD 3.0 case.
    //
    Status = BuildEdd30DevicePath (BaseDevicePath, Drive, DevicePath);
  }
  
  if (EFI_ERROR (Status)) {
    //
    // EDD 1.1 device case or it is unrecognized EDD 3.0 device
    //
    ZeroMem (&VendorNode, sizeof (VendorNode));
    VendorNode.DevicePath.Header.Type     = HARDWARE_DEVICE_PATH;
    VendorNode.DevicePath.Header.SubType  = HW_VENDOR_DP;
    SetDevicePathNodeLength (&VendorNode.DevicePath.Header, sizeof (VendorNode));
    CopyMem (&VendorNode.DevicePath.Guid, &gBlockIoVendorGuid, sizeof (EFI_GUID));
    VendorNode.LegacyDriveLetter  = Drive->Number;
    *DevicePath                   = AppendDevicePathNode (BaseDevicePath, &VendorNode.DevicePath.Header);
  }
}

/**
  Build device path for EDD 3.0.

  @param  BaseDevicePath         Base device path.
  @param  Drive                  Legacy drive.
  @param  DevicePath             Device path for output.

  @retval EFI_SUCCESS            The device path is built successfully.
  @retval EFI_UNSUPPORTED        It is failed to built device path.

**/
EFI_STATUS
BuildEdd30DevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *BaseDevicePath,
  IN  BIOS_LEGACY_DRIVE         *Drive,
  IN  EFI_DEVICE_PATH_PROTOCOL  **DevicePath
  )
{
  //
  // AVL    UINT64                  Address;
  // AVL    EFI_HANDLE              Handle;
  //
  EFI_DEV_PATH  Node;
  UINT32        Controller;

  Controller = (UINT32) Drive->Parameters.InterfacePath.Pci.Controller;

  ZeroMem (&Node, sizeof (Node));
  if ((AsciiStrnCmp ("ATAPI", Drive->Parameters.InterfaceType, 5) == 0) ||
      (AsciiStrnCmp ("ATA", Drive->Parameters.InterfaceType, 3) == 0)
      ) {
    //
    // ATA or ATAPI drive found
    //
    Node.Atapi.Header.Type    = MESSAGING_DEVICE_PATH;
    Node.Atapi.Header.SubType = MSG_ATAPI_DP;
    SetDevicePathNodeLength (&Node.Atapi.Header, sizeof (ATAPI_DEVICE_PATH));
    Node.Atapi.SlaveMaster      = Drive->Parameters.DevicePath.Atapi.Master;
    Node.Atapi.Lun              = Drive->Parameters.DevicePath.Atapi.Lun;
    Node.Atapi.PrimarySecondary = (UINT8) Controller;
  } else {
    //
    // Not an ATA/ATAPI drive
    //
    if (Controller != 0) {
      ZeroMem (&Node, sizeof (Node));
      Node.Controller.Header.Type      = HARDWARE_DEVICE_PATH;
      Node.Controller.Header.SubType   = HW_CONTROLLER_DP;
      SetDevicePathNodeLength (&Node.Controller.Header, sizeof (CONTROLLER_DEVICE_PATH));
      Node.Controller.ControllerNumber = Controller;
      *DevicePath                      = AppendDevicePathNode (*DevicePath, &Node.DevPath);
    }

    ZeroMem (&Node, sizeof (Node));

    if (AsciiStrnCmp ("SCSI", Drive->Parameters.InterfaceType, 4) == 0) {
      //
      // SCSI drive
      //
      Node.Scsi.Header.Type     = MESSAGING_DEVICE_PATH;
      Node.Scsi.Header.SubType  = MSG_SCSI_DP;
      SetDevicePathNodeLength (&Node.Scsi.Header, sizeof (SCSI_DEVICE_PATH));

      //
      // Lun is miss aligned in both EDD and Device Path data structures.
      //  thus we do a byte copy, to prevent alignment traps on IA-64.
      //
      CopyMem (&Node.Scsi.Lun, &Drive->Parameters.DevicePath.Scsi.Lun, sizeof (UINT16));
      Node.Scsi.Pun = Drive->Parameters.DevicePath.Scsi.Pun;

    } else if (AsciiStrnCmp ("USB", Drive->Parameters.InterfaceType, 3) == 0) {
      //
      // USB drive
      //
      Node.Usb.Header.Type    = MESSAGING_DEVICE_PATH;
      Node.Usb.Header.SubType = MSG_USB_DP;
      SetDevicePathNodeLength (&Node.Usb.Header, sizeof (USB_DEVICE_PATH));
      Node.Usb.ParentPortNumber = (UINT8) Drive->Parameters.DevicePath.Usb.Reserved;

    } else if (AsciiStrnCmp ("1394", Drive->Parameters.InterfaceType, 4) == 0) {
      //
      // 1394 drive
      //
      Node.F1394.Header.Type    = MESSAGING_DEVICE_PATH;
      Node.F1394.Header.SubType = MSG_1394_DP;
      SetDevicePathNodeLength (&Node.F1394.Header, sizeof (F1394_DEVICE_PATH));
      Node.F1394.Guid = Drive->Parameters.DevicePath.FireWire.Guid;

    } else if (AsciiStrnCmp ("FIBRE", Drive->Parameters.InterfaceType, 5) == 0) {
      //
      // Fibre drive
      //
      Node.FibreChannel.Header.Type     = MESSAGING_DEVICE_PATH;
      Node.FibreChannel.Header.SubType  = MSG_FIBRECHANNEL_DP;
      SetDevicePathNodeLength (&Node.FibreChannel.Header, sizeof (FIBRECHANNEL_DEVICE_PATH));
      Node.FibreChannel.WWN = Drive->Parameters.DevicePath.FibreChannel.Wwn;
      Node.FibreChannel.Lun = Drive->Parameters.DevicePath.FibreChannel.Lun;

    } else {
      DEBUG (
        (
        DEBUG_BLKIO, "It is unrecognized EDD 3.0 device, Drive Number = %x, InterfaceType = %s\n",
        Drive->Number,
        Drive->Parameters.InterfaceType
        )
        );      
    }
  }

  if (Node.DevPath.Type == 0) {
    return EFI_UNSUPPORTED;
  }
  
  *DevicePath = AppendDevicePathNode (BaseDevicePath, &Node.DevPath);
  return EFI_SUCCESS;
}
