EFI: move x86 specific disk probing code

Move x86 specific disk (EDD) probing to arch specific file.  This code is x86
only and relates to legacy BIOS handling of disk drives.

Signed-off-by: Roy Franz <roy.franz@linaro.org>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Roy Franz authored and Jan Beulich committed 2014-09-25 14:29:29 +02:00
1 parent fbc3d9a220
commit b4bfea5532
2 files changed
+153 -143

No files matched your search

+152
View File
@@ -302,3 +302,155 @@ static void __init efi_arch_handle_cmdline(CHAR16 *image_name,
mbi.boot_loader_name = (long)"EFI";
mbi.mods_addr = (long)mb_modules;
}
static void __init efi_arch_edd(void)
{
static EFI_GUID __initdata bio_guid = BLOCK_IO_PROTOCOL;
static EFI_GUID __initdata devp_guid = DEVICE_PATH_PROTOCOL;
EFI_HANDLE *handles = NULL;
unsigned int i;
UINTN size;
EFI_STATUS status;
/* Collect EDD info. */
BUILD_BUG_ON(offsetof(struct edd_info, edd_device_params) != EDDEXTSIZE);
BUILD_BUG_ON(sizeof(struct edd_device_params) != EDDPARMSIZE);
size = 0;
status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size, NULL);
if ( status == EFI_BUFFER_TOO_SMALL )
status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
if ( !EFI_ERROR(status) )
status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size,
handles);
if ( EFI_ERROR(status) )
size = 0;
for ( i = 0; i < size / sizeof(*handles); ++i )
{
EFI_BLOCK_IO *bio;
EFI_DEV_PATH_PTR devp;
struct edd_info *info = boot_edd_info + boot_edd_info_nr;
struct edd_device_params *params = &info->edd_device_params;
enum { root, acpi, pci, ctrlr } state = root;
status = efi_bs->HandleProtocol(handles[i], &bio_guid, (void **)&bio);
if ( EFI_ERROR(status) ||
bio->Media->RemovableMedia ||
bio->Media->LogicalPartition )
continue;
if ( boot_edd_info_nr < EDD_INFO_MAX )
{
info->device = 0x80 + boot_edd_info_nr; /* fake */
info->version = 0x11;
params->length = offsetof(struct edd_device_params, dpte_ptr);
params->number_of_sectors = bio->Media->LastBlock + 1;
params->bytes_per_sector = bio->Media->BlockSize;
params->dpte_ptr = ~0;
}
++boot_edd_info_nr;
status = efi_bs->HandleProtocol(handles[i], &devp_guid,
(void **)&devp);
if ( EFI_ERROR(status) )
continue;
for ( ; !IsDevicePathEnd(devp.DevPath);
devp.DevPath = NextDevicePathNode(devp.DevPath) )
{
switch ( DevicePathType(devp.DevPath) )
{
const u8 *p;
case ACPI_DEVICE_PATH:
if ( state != root || boot_edd_info_nr > EDD_INFO_MAX )
break;
switch ( DevicePathSubType(devp.DevPath) )
{
case ACPI_DP:
if ( devp.Acpi->HID != EISA_PNP_ID(0xA03) &&
devp.Acpi->HID != EISA_PNP_ID(0xA08) )
break;
params->interface_path.pci.bus = devp.Acpi->UID;
state = acpi;
break;
case EXPANDED_ACPI_DP:
/* XXX */
break;
}
break;
case HARDWARE_DEVICE_PATH:
if ( state != acpi ||
DevicePathSubType(devp.DevPath) != HW_PCI_DP ||
boot_edd_info_nr > EDD_INFO_MAX )
break;
state = pci;
edd_put_string(params->host_bus_type, "PCI");
params->interface_path.pci.slot = devp.Pci->Device;
params->interface_path.pci.function = devp.Pci->Function;
break;
case MESSAGING_DEVICE_PATH:
if ( state != pci || boot_edd_info_nr > EDD_INFO_MAX )
break;
state = ctrlr;
switch ( DevicePathSubType(devp.DevPath) )
{
case MSG_ATAPI_DP:
edd_put_string(params->interface_type, "ATAPI");
params->interface_path.pci.channel =
devp.Atapi->PrimarySecondary;
params->device_path.atapi.device = devp.Atapi->SlaveMaster;
params->device_path.atapi.lun = devp.Atapi->Lun;
break;
case MSG_SCSI_DP:
edd_put_string(params->interface_type, "SCSI");
params->device_path.scsi.id = devp.Scsi->Pun;
params->device_path.scsi.lun = devp.Scsi->Lun;
break;
case MSG_FIBRECHANNEL_DP:
edd_put_string(params->interface_type, "FIBRE");
params->device_path.fibre.wwid = devp.FibreChannel->WWN;
params->device_path.fibre.lun = devp.FibreChannel->Lun;
break;
case MSG_1394_DP:
edd_put_string(params->interface_type, "1394");
params->device_path.i1394.eui = devp.F1394->Guid;
break;
case MSG_USB_DP:
case MSG_USB_CLASS_DP:
edd_put_string(params->interface_type, "USB");
break;
case MSG_I2O_DP:
edd_put_string(params->interface_type, "I2O");
params->device_path.i2o.identity_tag = devp.I2O->Tid;
break;
default:
continue;
}
info->version = 0x30;
params->length = sizeof(struct edd_device_params);
params->key = 0xbedd;
params->device_path_info_length =
sizeof(struct edd_device_params) -
offsetof(struct edd_device_params, key);
for ( p = (const u8 *)&params->key; p < &params->checksum; ++p )
params->checksum -= *p;
break;
case MEDIA_DEVICE_PATH:
if ( DevicePathSubType(devp.DevPath) == MEDIA_HARDDRIVE_DP &&
devp.HardDrive->MBRType == MBR_TYPE_PCAT &&
boot_mbr_signature_nr < EDD_MBR_SIG_MAX )
{
struct mbr_signature *sig = boot_mbr_signature +
boot_mbr_signature_nr;
sig->device = 0x80 + boot_edd_info_nr; /* fake */
memcpy(&sig->signature, devp.HardDrive->Signature,
sizeof(sig->signature));
++boot_mbr_signature_nr;
}
break;
}
}
}
if ( handles )
efi_bs->FreePool(handles);
if ( boot_edd_info_nr > EDD_INFO_MAX )
boot_edd_info_nr = EDD_INFO_MAX;
}
+1 -143
View File
@@ -660,8 +660,6 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
static EFI_GUID __initdata loaded_image_guid = LOADED_IMAGE_PROTOCOL;
static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
static EFI_GUID __initdata bio_guid = BLOCK_IO_PROTOCOL;
static EFI_GUID __initdata devp_guid = DEVICE_PATH_PROTOCOL;
static EFI_GUID __initdata shim_lock_guid = SHIM_LOCK_PROTOCOL_GUID;
EFI_LOADED_IMAGE *loaded_image;
EFI_STATUS status;
@@ -948,147 +946,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
}
}
/* Collect EDD info. */
BUILD_BUG_ON(offsetof(struct edd_info, edd_device_params) != EDDEXTSIZE);
BUILD_BUG_ON(sizeof(struct edd_device_params) != EDDPARMSIZE);
size = 0;
status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size, NULL);
if ( status == EFI_BUFFER_TOO_SMALL )
status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
if ( !EFI_ERROR(status) )
status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size,
handles);
if ( EFI_ERROR(status) )
size = 0;
for ( i = 0; i < size / sizeof(*handles); ++i )
{
EFI_BLOCK_IO *bio;
EFI_DEV_PATH_PTR devp;
struct edd_info *info = boot_edd_info + boot_edd_info_nr;
struct edd_device_params *params = &info->edd_device_params;
enum { root, acpi, pci, ctrlr } state = root;
status = efi_bs->HandleProtocol(handles[i], &bio_guid, (void **)&bio);
if ( EFI_ERROR(status) ||
bio->Media->RemovableMedia ||
bio->Media->LogicalPartition )
continue;
if ( boot_edd_info_nr < EDD_INFO_MAX )
{
info->device = 0x80 + boot_edd_info_nr; /* fake */
info->version = 0x11;
params->length = offsetof(struct edd_device_params, dpte_ptr);
params->number_of_sectors = bio->Media->LastBlock + 1;
params->bytes_per_sector = bio->Media->BlockSize;
params->dpte_ptr = ~0;
}
++boot_edd_info_nr;
status = efi_bs->HandleProtocol(handles[i], &devp_guid,
(void **)&devp);
if ( EFI_ERROR(status) )
continue;
for ( ; !IsDevicePathEnd(devp.DevPath);
devp.DevPath = NextDevicePathNode(devp.DevPath) )
{
switch ( DevicePathType(devp.DevPath) )
{
const u8 *p;
case ACPI_DEVICE_PATH:
if ( state != root || boot_edd_info_nr > EDD_INFO_MAX )
break;
switch ( DevicePathSubType(devp.DevPath) )
{
case ACPI_DP:
if ( devp.Acpi->HID != EISA_PNP_ID(0xA03) &&
devp.Acpi->HID != EISA_PNP_ID(0xA08) )
break;
params->interface_path.pci.bus = devp.Acpi->UID;
state = acpi;
break;
case EXPANDED_ACPI_DP:
/* XXX */
break;
}
break;
case HARDWARE_DEVICE_PATH:
if ( state != acpi ||
DevicePathSubType(devp.DevPath) != HW_PCI_DP ||
boot_edd_info_nr > EDD_INFO_MAX )
break;
state = pci;
edd_put_string(params->host_bus_type, "PCI");
params->interface_path.pci.slot = devp.Pci->Device;
params->interface_path.pci.function = devp.Pci->Function;
break;
case MESSAGING_DEVICE_PATH:
if ( state != pci || boot_edd_info_nr > EDD_INFO_MAX )
break;
state = ctrlr;
switch ( DevicePathSubType(devp.DevPath) )
{
case MSG_ATAPI_DP:
edd_put_string(params->interface_type, "ATAPI");
params->interface_path.pci.channel =
devp.Atapi->PrimarySecondary;
params->device_path.atapi.device = devp.Atapi->SlaveMaster;
params->device_path.atapi.lun = devp.Atapi->Lun;
break;
case MSG_SCSI_DP:
edd_put_string(params->interface_type, "SCSI");
params->device_path.scsi.id = devp.Scsi->Pun;
params->device_path.scsi.lun = devp.Scsi->Lun;
break;
case MSG_FIBRECHANNEL_DP:
edd_put_string(params->interface_type, "FIBRE");
params->device_path.fibre.wwid = devp.FibreChannel->WWN;
params->device_path.fibre.lun = devp.FibreChannel->Lun;
break;
case MSG_1394_DP:
edd_put_string(params->interface_type, "1394");
params->device_path.i1394.eui = devp.F1394->Guid;
break;
case MSG_USB_DP:
case MSG_USB_CLASS_DP:
edd_put_string(params->interface_type, "USB");
break;
case MSG_I2O_DP:
edd_put_string(params->interface_type, "I2O");
params->device_path.i2o.identity_tag = devp.I2O->Tid;
break;
default:
continue;
}
info->version = 0x30;
params->length = sizeof(struct edd_device_params);
params->key = 0xbedd;
params->device_path_info_length =
sizeof(struct edd_device_params) -
offsetof(struct edd_device_params, key);
for ( p = (const u8 *)&params->key; p < &params->checksum; ++p )
params->checksum -= *p;
break;
case MEDIA_DEVICE_PATH:
if ( DevicePathSubType(devp.DevPath) == MEDIA_HARDDRIVE_DP &&
devp.HardDrive->MBRType == MBR_TYPE_PCAT &&
boot_mbr_signature_nr < EDD_MBR_SIG_MAX )
{
struct mbr_signature *sig = boot_mbr_signature +
boot_mbr_signature_nr;
sig->device = 0x80 + boot_edd_info_nr; /* fake */
memcpy(&sig->signature, devp.HardDrive->Signature,
sizeof(sig->signature));
++boot_mbr_signature_nr;
}
break;
}
}
}
if ( handles )
efi_bs->FreePool(handles);
if ( boot_edd_info_nr > EDD_INFO_MAX )
boot_edd_info_nr = EDD_INFO_MAX;
efi_arch_edd();
/* XXX Collect EDID info. */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.