diff options
author | Toomas Soome <tsoome@FreeBSD.org> | 2019-11-06 21:13:10 +0000 |
---|---|---|
committer | Toomas Soome <tsoome@FreeBSD.org> | 2019-11-06 21:13:10 +0000 |
commit | f6689bce799e23a6e2260c3f05823f63d63c8df0 (patch) | |
tree | 32ec7940410dea97a1890dbc32a748983c253d5f /stand/efi/libefi | |
parent | 044ab55e41712a07fcec3e803eda03cf9cb36c60 (diff) | |
download | src-f6689bce799e23a6e2260c3f05823f63d63c8df0.tar.gz src-f6689bce799e23a6e2260c3f05823f63d63c8df0.zip |
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
Notes
Notes:
svn path=/head/; revision=354415
Diffstat (limited to 'stand/efi/libefi')
-rw-r--r-- | stand/efi/libefi/efipart.c | 49 |
1 files changed, 37 insertions, 12 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 void -efipart_hdinfo_add(pdinfo_t *hd, HARDDRIVE_DEVICE_PATH *node) +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)) { - /* 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 (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, EFI_DEVICE_PATH *node) +{ + pdinfo_t *pd, *last; + + if (efipart_hdinfo_add_node(hd, node)) + return; last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); if (last != NULL) @@ -677,7 +702,7 @@ restart: efipart_hdinfo_add(parent, NULL); } - efipart_hdinfo_add(hd, (HARDDRIVE_DEVICE_PATH *)node); + efipart_hdinfo_add(hd, node); goto restart; } } |