loader.efi: efipart does not recognize partitionless disks
Rework the block device handle check to allow more robust device classification. This is mostly usability issue - it can be quite confusing for user when no disks are listed with lsdev. Add more comments about what and why is done. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D13026
This commit is contained in:
parent
7143bb7626
commit
cdadbf0971
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326089
@ -195,6 +195,72 @@ efipart_floppy(EFI_DEVICE_PATH *node)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine if the provided device path is hdd.
|
||||||
|
*
|
||||||
|
* There really is no simple fool proof way to classify the devices.
|
||||||
|
* Since we do build three lists of devices - floppy, cd and hdd, we
|
||||||
|
* will try to see if the device is floppy or cd, and list anything else
|
||||||
|
* as hdd.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
efipart_hdd(EFI_DEVICE_PATH *dp)
|
||||||
|
{
|
||||||
|
unsigned i, nin;
|
||||||
|
EFI_DEVICE_PATH *devpath, *node;
|
||||||
|
EFI_BLOCK_IO *blkio;
|
||||||
|
EFI_STATUS status;
|
||||||
|
|
||||||
|
if (dp == NULL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if ((node = efi_devpath_last_node(dp)) == NULL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if (efipart_floppy(node) != NULL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test every EFI BLOCK IO handle to make sure dp is not device path
|
||||||
|
* for CD/DVD.
|
||||||
|
*/
|
||||||
|
nin = efipart_nhandles / sizeof (*efipart_handles);
|
||||||
|
for (i = 0; i < nin; i++) {
|
||||||
|
devpath = efi_lookup_devpath(efipart_handles[i]);
|
||||||
|
if (devpath == NULL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
/* Only continue testing when dp is prefix in devpath. */
|
||||||
|
if (!efi_devpath_is_prefix(dp, devpath))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device path has to have last node describing the
|
||||||
|
* device, or we can not test the type.
|
||||||
|
*/
|
||||||
|
if ((node = efi_devpath_last_node(devpath)) == NULL)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
|
||||||
|
DevicePathSubType(node) == MEDIA_CDROM_DP) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we do have the media. */
|
||||||
|
status = BS->HandleProtocol(efipart_handles[i],
|
||||||
|
&blkio_guid, (void **)&blkio);
|
||||||
|
if (EFI_ERROR(status))
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
/* USB or SATA cd without the media. */
|
||||||
|
if (blkio->Media->RemovableMedia &&
|
||||||
|
!blkio->Media->MediaPresent) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add or update entries with new handle data.
|
* Add or update entries with new handle data.
|
||||||
*/
|
*/
|
||||||
@ -308,9 +374,13 @@ efipart_updatecd(void)
|
|||||||
|
|
||||||
if ((node = efi_devpath_last_node(devpath)) == NULL)
|
if ((node = efi_devpath_last_node(devpath)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (efipart_floppy(node) != NULL)
|
if (efipart_floppy(node) != NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (efipart_hdd(devpath))
|
||||||
|
continue;
|
||||||
|
|
||||||
status = BS->HandleProtocol(efipart_handles[i],
|
status = BS->HandleProtocol(efipart_handles[i],
|
||||||
&blkio_guid, (void **)&blkio);
|
&blkio_guid, (void **)&blkio);
|
||||||
if (EFI_ERROR(status))
|
if (EFI_ERROR(status))
|
||||||
@ -380,13 +450,21 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle)
|
|||||||
pdinfo_t *hd, *pd, *last;
|
pdinfo_t *hd, *pd, *last;
|
||||||
|
|
||||||
disk_devpath = efi_lookup_devpath(disk_handle);
|
disk_devpath = efi_lookup_devpath(disk_handle);
|
||||||
part_devpath = efi_lookup_devpath(part_handle);
|
if (disk_devpath == NULL)
|
||||||
if (disk_devpath == NULL || part_devpath == NULL) {
|
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
|
|
||||||
|
if (part_handle != NULL) {
|
||||||
|
part_devpath = efi_lookup_devpath(part_handle);
|
||||||
|
if (part_devpath == NULL)
|
||||||
|
return (ENOENT);
|
||||||
|
node = (HARDDRIVE_DEVICE_PATH *)
|
||||||
|
efi_devpath_last_node(part_devpath);
|
||||||
|
if (node == NULL)
|
||||||
|
return (ENOENT); /* This should not happen. */
|
||||||
|
} else {
|
||||||
|
part_devpath = NULL;
|
||||||
|
node = NULL;
|
||||||
}
|
}
|
||||||
node = (HARDDRIVE_DEVICE_PATH *)efi_devpath_last_node(part_devpath);
|
|
||||||
if (node == NULL)
|
|
||||||
return (ENOENT); /* This should not happen. */
|
|
||||||
|
|
||||||
pd = calloc(1, sizeof(pdinfo_t));
|
pd = calloc(1, sizeof(pdinfo_t));
|
||||||
if (pd == NULL) {
|
if (pd == NULL) {
|
||||||
@ -397,6 +475,9 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle)
|
|||||||
|
|
||||||
STAILQ_FOREACH(hd, &hdinfo, pd_link) {
|
STAILQ_FOREACH(hd, &hdinfo, pd_link) {
|
||||||
if (efi_devpath_match(hd->pd_devpath, disk_devpath) == true) {
|
if (efi_devpath_match(hd->pd_devpath, disk_devpath) == true) {
|
||||||
|
if (part_devpath == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
/* Add the partition. */
|
/* Add the partition. */
|
||||||
pd->pd_handle = part_handle;
|
pd->pd_handle = part_handle;
|
||||||
pd->pd_unit = node->PartitionNumber;
|
pd->pd_unit = node->PartitionNumber;
|
||||||
@ -419,6 +500,9 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle)
|
|||||||
hd->pd_devpath = disk_devpath;
|
hd->pd_devpath = disk_devpath;
|
||||||
STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link);
|
STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link);
|
||||||
|
|
||||||
|
if (part_devpath == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
pd = calloc(1, sizeof(pdinfo_t));
|
pd = calloc(1, sizeof(pdinfo_t));
|
||||||
if (pd == NULL) {
|
if (pd == NULL) {
|
||||||
printf("Failed to add partition, out of memory\n");
|
printf("Failed to add partition, out of memory\n");
|
||||||
@ -541,7 +625,8 @@ efipart_updatehd(void)
|
|||||||
|
|
||||||
if ((node = efi_devpath_last_node(devpath)) == NULL)
|
if ((node = efi_devpath_last_node(devpath)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (efipart_floppy(node) != NULL)
|
|
||||||
|
if (!efipart_hdd(devpath))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
status = BS->HandleProtocol(efipart_handles[i],
|
status = BS->HandleProtocol(efipart_handles[i],
|
||||||
@ -549,6 +634,12 @@ efipart_updatehd(void)
|
|||||||
if (EFI_ERROR(status))
|
if (EFI_ERROR(status))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
|
||||||
|
DevicePathSubType(node) == MEDIA_FILEPATH_DP) {
|
||||||
|
efipart_hdinfo_add_filepath(efipart_handles[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
|
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
|
||||||
DevicePathSubType(node) == MEDIA_HARDDRIVE_DP) {
|
DevicePathSubType(node) == MEDIA_HARDDRIVE_DP) {
|
||||||
devpathcpy = efi_devpath_trim(devpath);
|
devpathcpy = efi_devpath_trim(devpath);
|
||||||
@ -568,18 +659,16 @@ efipart_updatehd(void)
|
|||||||
continue;
|
continue;
|
||||||
if ((node = efi_devpath_last_node(devpathcpy)) == NULL)
|
if ((node = efi_devpath_last_node(devpathcpy)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
|
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
|
||||||
DevicePathSubType(node) == MEDIA_HARDDRIVE_DP)
|
DevicePathSubType(node) == MEDIA_HARDDRIVE_DP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
efipart_hdinfo_add(handle, efipart_handles[i]);
|
efipart_hdinfo_add(handle, efipart_handles[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
|
efipart_hdinfo_add(efipart_handles[i], NULL);
|
||||||
DevicePathSubType(node) == MEDIA_FILEPATH_DP) {
|
|
||||||
efipart_hdinfo_add_filepath(efipart_handles[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user