Mercurial > unleashed > prev-conversion
changeset 18812:033958218f3c
loader.efi: chain loader should provide proper device handle
illumos issue #9073
author | Toomas Soome <tsoome@me.com> |
---|---|
date | Tue, 12 Dec 2017 18:01:57 +0200 |
parents | 4c609abb3bf5 |
children | 275f2ccf7d09 |
files | usr/src/boot/sys/boot/efi/include/efilib.h usr/src/boot/sys/boot/efi/libefi/efipart.c usr/src/boot/sys/boot/efi/loader/main.c |
diffstat | 3 files changed, 64 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/boot/sys/boot/efi/include/efilib.h Wed Feb 14 23:10:02 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/include/efilib.h Tue Dec 12 18:01:57 2017 +0200 @@ -60,6 +60,7 @@ } pdinfo_t; pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev); +pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev); void *efi_get_table(EFI_GUID *tbl);
--- a/usr/src/boot/sys/boot/efi/libefi/efipart.c Wed Feb 14 23:10:02 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/libefi/efipart.c Tue Dec 12 18:01:57 2017 +0200 @@ -106,16 +106,33 @@ static EFI_HANDLE *efipart_handles = NULL; static UINTN efipart_nhandles = 0; -static pdinfo_t * -efiblk_get_pdinfo(pdinfo_list_t *pdi, int unit) +pdinfo_list_t * +efiblk_get_pdinfo_list(struct devsw *dev) { - pdinfo_t *pd; + if (dev->dv_type == DEVT_DISK) + return (&hdinfo); + if (dev->dv_type == DEVT_CD) + return (&cdinfo); + if (dev->dv_type == DEVT_FD) + return (&fdinfo); + return (NULL); +} + +pdinfo_t * +efiblk_get_pdinfo(struct devdesc *dev) +{ + pdinfo_list_t *pdi; + pdinfo_t *pd = NULL; + + pdi = efiblk_get_pdinfo_list(dev->d_dev); + if (pdi == NULL) + return (pd); STAILQ_FOREACH(pd, pdi, pd_link) { - if (pd->pd_unit == unit) + if (pd->pd_unit == dev->d_unit) return (pd); } - return (NULL); + return (pd); } static int @@ -777,24 +794,11 @@ return (efipart_print_common(&efipart_hddev, &hdinfo, verbose)); } -pdinfo_list_t * -efiblk_get_pdinfo_list(struct devsw *dev) -{ - if (dev->dv_type == DEVT_DISK) - return (&hdinfo); - if (dev->dv_type == DEVT_CD) - return (&cdinfo); - if (dev->dv_type == DEVT_FD) - return (&fdinfo); - return (NULL); -} - static int efipart_open(struct open_file *f, ...) { va_list args; struct disk_devdesc *dev; - pdinfo_list_t *pdi; pdinfo_t *pd; EFI_BLOCK_IO *blkio; EFI_STATUS status; @@ -805,14 +809,10 @@ if (dev == NULL) return (EINVAL); - pdi = efiblk_get_pdinfo_list(dev->d_dev); - if (pdi == NULL) + pd = efiblk_get_pdinfo((struct devdesc *)dev); + if (pd == NULL) return (EINVAL); - pd = efiblk_get_pdinfo(pdi, dev->d_unit); - if (pd == NULL) - return (EIO); - if (pd->pd_blkio == NULL) { status = BS->HandleProtocol(pd->pd_handle, &blkio_guid, (void **)&pd->pd_blkio); @@ -851,17 +851,13 @@ efipart_close(struct open_file *f) { struct disk_devdesc *dev; - pdinfo_list_t *pdi; pdinfo_t *pd; dev = (struct disk_devdesc *)(f->f_devdata); if (dev == NULL) return (EINVAL); - pdi = efiblk_get_pdinfo_list(dev->d_dev); - if (pdi == NULL) - return (EINVAL); - pd = efiblk_get_pdinfo(pdi, dev->d_unit); + pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL); @@ -880,18 +876,14 @@ efipart_ioctl(struct open_file *f, u_long cmd, void *data) { struct disk_devdesc *dev; - pdinfo_list_t *pdi; pdinfo_t *pd; int rc; dev = (struct disk_devdesc *)(f->f_devdata); if (dev == NULL) return (EINVAL); - pdi = efiblk_get_pdinfo_list(dev->d_dev); - if (pdi == NULL) - return (EINVAL); - pd = efiblk_get_pdinfo(pdi, dev->d_unit); + pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL); @@ -964,17 +956,13 @@ { struct bcache_devdata bcd; struct disk_devdesc *dev; - pdinfo_list_t *pdi; pdinfo_t *pd; dev = (struct disk_devdesc *)devdata; if (dev == NULL) return (EINVAL); - pdi = efiblk_get_pdinfo_list(dev->d_dev); - if (pdi == NULL) - return (EINVAL); - pd = efiblk_get_pdinfo(pdi, dev->d_unit); + pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL); @@ -1002,7 +990,6 @@ char *buf, size_t *rsize) { struct disk_devdesc *dev = (struct disk_devdesc *)devdata; - pdinfo_list_t *pdi; pdinfo_t *pd; EFI_BLOCK_IO *blkio; uint64_t off, disk_blocks, d_offset = 0; @@ -1014,11 +1001,7 @@ if (dev == NULL || blk < 0) return (EINVAL); - pdi = efiblk_get_pdinfo_list(dev->d_dev); - if (pdi == NULL) - return (EINVAL); - - pd = efiblk_get_pdinfo(pdi, dev->d_unit); + pd = efiblk_get_pdinfo((struct devdesc *)dev); if (pd == NULL) return (EINVAL);
--- a/usr/src/boot/sys/boot/efi/loader/main.c Wed Feb 14 23:10:02 2018 +0200 +++ b/usr/src/boot/sys/boot/efi/loader/main.c Tue Dec 12 18:01:57 2017 +0200 @@ -884,9 +884,41 @@ *(--argv) = 0; } - if (efi_getdev((void **)&dev, name, (const char **)&path) == 0) - loaded_image->DeviceHandle = - efi_find_handle(dev->d_dev, dev->d_unit); + if (efi_getdev((void **)&dev, name, (const char **)&path) == 0) { + struct zfs_devdesc *z_dev; + struct disk_devdesc *d_dev; + pdinfo_t *hd, *pd; + + switch (dev->d_type) { + case DEVT_ZFS: + z_dev = (struct zfs_devdesc *)dev; + loaded_image->DeviceHandle = + efizfs_get_handle_by_guid(z_dev->pool_guid); + break; + case DEVT_NET: + loaded_image->DeviceHandle = + efi_find_handle(dev->d_dev, dev->d_unit); + break; + default: + hd = efiblk_get_pdinfo(dev); + if (STAILQ_EMPTY(&hd->pd_part)) { + loaded_image->DeviceHandle = hd->pd_handle; + break; + } + d_dev = (struct disk_devdesc *)dev; + STAILQ_FOREACH(pd, &hd->pd_part, pd_link) { + /* + * d_partition should be 255 + */ + if (pd->pd_unit == d_dev->d_slice) { + loaded_image->DeviceHandle = + pd->pd_handle; + break; + } + } + break; + } + } dev_cleanup(); status = BS->StartImage(loaderhandle, NULL, NULL);