Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Sep 2017 13:53:43 +0000 (UTC)
From:      Toomas Soome <tsoome@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r323389 - in head/sys/boot/efi: include libefi loader
Message-ID:  <201709101353.v8ADrhUO036350@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tsoome
Date: Sun Sep 10 13:53:42 2017
New Revision: 323389
URL: https://svnweb.freebsd.org/changeset/base/323389

Log:
  loader.efi: chain loader should provide proper device handle
  
  Since the efipart rewrite, the chain command was looking for device
  handle using interface applicable only for net devices. Disk
  partitions and zfs pools need their own approach to find the proper handle.
  
  Reviewed by:	imp
  Differential Revision:	https://reviews.freebsd.org/D12287

Modified:
  head/sys/boot/efi/include/efilib.h
  head/sys/boot/efi/include/efizfs.h
  head/sys/boot/efi/libefi/efipart.c
  head/sys/boot/efi/libefi/efizfs.c
  head/sys/boot/efi/loader/main.c

Modified: head/sys/boot/efi/include/efilib.h
==============================================================================
--- head/sys/boot/efi/include/efilib.h	Sun Sep 10 13:21:54 2017	(r323388)
+++ head/sys/boot/efi/include/efilib.h	Sun Sep 10 13:53:42 2017	(r323389)
@@ -61,6 +61,7 @@ typedef struct pdinfo
 } 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);
 

Modified: head/sys/boot/efi/include/efizfs.h
==============================================================================
--- head/sys/boot/efi/include/efizfs.h	Sun Sep 10 13:21:54 2017	(r323388)
+++ head/sys/boot/efi/include/efizfs.h	Sun Sep 10 13:53:42 2017	(r323389)
@@ -45,6 +45,7 @@ extern uint64_t pool_guid;
 
 extern void efi_zfs_probe(void);
 extern zfsinfo_list_t *efizfs_get_zfsinfo_list(void);
+extern EFI_HANDLE efizfs_get_handle_by_guid(uint64_t);
 
 #endif
 

Modified: head/sys/boot/efi/libefi/efipart.c
==============================================================================
--- head/sys/boot/efi/libefi/efipart.c	Sun Sep 10 13:21:54 2017	(r323388)
+++ head/sys/boot/efi/libefi/efipart.c	Sun Sep 10 13:53:42 2017	(r323389)
@@ -101,16 +101,33 @@ static pdinfo_list_t hdinfo;
 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
@@ -671,24 +688,11 @@ efipart_printhd(int verbose)
 	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;
@@ -699,11 +703,7 @@ efipart_open(struct open_file *f, ...)
 	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 (EIO);
 
@@ -734,17 +734,13 @@ static int
 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);
 
@@ -763,18 +759,14 @@ static int
 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);
 
@@ -847,17 +839,13 @@ efipart_strategy(void *devdata, int rw, daddr_t blk, s
 {
 	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);
 
@@ -881,7 +869,6 @@ efipart_realstrategy(void *devdata, int rw, daddr_t bl
     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;
@@ -893,11 +880,7 @@ efipart_realstrategy(void *devdata, int rw, daddr_t bl
 	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);
 

Modified: head/sys/boot/efi/libefi/efizfs.c
==============================================================================
--- head/sys/boot/efi/libefi/efizfs.c	Sun Sep 10 13:21:54 2017	(r323388)
+++ head/sys/boot/efi/libefi/efizfs.c	Sun Sep 10 13:53:42 2017	(r323389)
@@ -52,6 +52,19 @@ efizfs_get_zfsinfo_list(void)
 	return (&zfsinfo);
 }
 
+EFI_HANDLE
+efizfs_get_handle_by_guid(uint64_t guid)
+{
+	zfsinfo_t *zi;
+
+	STAILQ_FOREACH(zi, &zfsinfo, zi_link) {
+		if (zi->zi_pool_guid == guid) {
+			return (zi->zi_handle);
+		}
+	}
+	return (NULL);
+}
+
 static void
 insert_zfs(EFI_HANDLE handle, uint64_t guid)
 {

Modified: head/sys/boot/efi/loader/main.c
==============================================================================
--- head/sys/boot/efi/loader/main.c	Sun Sep 10 13:21:54 2017	(r323388)
+++ head/sys/boot/efi/loader/main.c	Sun Sep 10 13:53:42 2017	(r323389)
@@ -871,9 +871,41 @@ command_chain(int argc, char *argv[])
 		*(--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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709101353.v8ADrhUO036350>