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