From f6689bce799e23a6e2260c3f05823f63d63c8df0 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Wed, 6 Nov 2019 21:13:10 +0000 Subject: [PATCH] loader.efi: HARDDRIVE_DEVICE_PATH may have subpaths The macos does create Vendor Media devices on top of APFS container (like partition table inside the partition), so we need to collect such devices into respective device tree. MFC after: 1 week --- stand/efi/libefi/efipart.c | 51 ++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c index 2affab1c4274..c6aea2802d42 100644 --- a/stand/efi/libefi/efipart.c +++ b/stand/efi/libefi/efipart.c @@ -313,11 +313,14 @@ efipart_floppy(EFI_DEVICE_PATH *node) static pdinfo_t * efipart_find_parent(pdinfo_list_t *pdi, EFI_DEVICE_PATH *devpath) { - pdinfo_t *pd; + pdinfo_t *pd, *part; STAILQ_FOREACH(pd, pdi, pd_link) { if (efi_devpath_is_prefix(pd->pd_devpath, devpath)) return (pd); + part = efipart_find_parent(&pd->pd_part, devpath); + if (part != NULL) + return (part); } return (NULL); } @@ -500,21 +503,43 @@ efipart_initcd(void) return (0); } +static bool +efipart_hdinfo_add_node(pdinfo_t *hd, EFI_DEVICE_PATH *node) +{ + pdinfo_t *pd, *last; + VENDOR_DEVICE_PATH *ven_node; + + STAILQ_FOREACH(pd, &hdinfo, pd_link) { + if (efi_devpath_is_prefix(pd->pd_devpath, hd->pd_devpath)) + break; + } + if (pd == NULL) + return (false); + + /* Add the partition. */ + if (DevicePathSubType(node) == MEDIA_HARDDRIVE_DP) { + hd->pd_unit = ((HARDDRIVE_DEVICE_PATH *)node)->PartitionNumber; + } else { + last = STAILQ_LAST(&pd->pd_part, pdinfo, pd_link); + if (last != NULL) + hd->pd_unit = last->pd_unit + 1; + else + hd->pd_unit = 0; + } + hd->pd_parent = pd; + hd->pd_devsw = &efipart_hddev; + + STAILQ_INSERT_TAIL(&pd->pd_part, hd, pd_link); + return (true); +} + static void -efipart_hdinfo_add(pdinfo_t *hd, HARDDRIVE_DEVICE_PATH *node) +efipart_hdinfo_add(pdinfo_t *hd, EFI_DEVICE_PATH *node) { pdinfo_t *pd, *last; - STAILQ_FOREACH(pd, &hdinfo, pd_link) { - if (efi_devpath_is_prefix(pd->pd_devpath, hd->pd_devpath)) { - /* Add the partition. */ - hd->pd_unit = node->PartitionNumber; - hd->pd_parent = pd; - hd->pd_devsw = &efipart_hddev; - STAILQ_INSERT_TAIL(&pd->pd_part, hd, pd_link); - return; - } - } + if (efipart_hdinfo_add_node(hd, node)) + return; last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); if (last != NULL) @@ -677,7 +702,7 @@ efipart_updatehd(void) efipart_hdinfo_add(parent, NULL); } - efipart_hdinfo_add(hd, (HARDDRIVE_DEVICE_PATH *)node); + efipart_hdinfo_add(hd, node); goto restart; } }