svn commit: r313645 - head/sys/boot/efi/libefi

Toomas Soome tsoome at FreeBSD.org
Sat Feb 11 15:25:50 UTC 2017


Author: tsoome
Date: Sat Feb 11 15:25:49 2017
New Revision: 313645
URL: https://svnweb.freebsd.org/changeset/base/313645

Log:
  loader: implement MEDIA_FILEPATH_DP support in efipart
  
  The efipart rework did break the ARM systems as the new code is
  using more exact filters to sort the devices and we need to
  add support for MEDIA_FILEPATH_DP device paths.
  
  PR:		216940
  Reported by:	karl at denninger.net
  Reviewed by:	allanjude, manu
  Approved by:	allanjude (mentor)
  Differential Revision:	https://reviews.freebsd.org/D9520

Modified:
  head/sys/boot/efi/libefi/efipart.c

Modified: head/sys/boot/efi/libefi/efipart.c
==============================================================================
--- head/sys/boot/efi/libefi/efipart.c	Sat Feb 11 14:04:18 2017	(r313644)
+++ head/sys/boot/efi/libefi/efipart.c	Sat Feb 11 15:25:49 2017	(r313645)
@@ -417,6 +417,89 @@ efipart_hdinfo_add(EFI_HANDLE disk_handl
 	return (0);
 }
 
+/*
+ * The MEDIA_FILEPATH_DP has device name.
+ * From U-Boot sources it looks like names are in the form
+ * of typeN:M, where type is interface type, N is disk id
+ * and M is partition id.
+ */
+static int
+efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle)
+{
+	EFI_DEVICE_PATH *devpath;
+	FILEPATH_DEVICE_PATH *node;
+	char *pathname, *p;
+	int unit, len;
+	pdinfo_t *pd, *last;
+
+	/* First collect and verify all the data */
+	if ((devpath = efi_lookup_devpath(disk_handle)) == NULL)
+		return (ENOENT);
+	node = (FILEPATH_DEVICE_PATH *)efi_devpath_last_node(devpath);
+	if (node == NULL)
+		return (ENOENT);	/* This should not happen. */
+
+	pd = malloc(sizeof(pdinfo_t));
+	if (pd == NULL) {
+		printf("Failed to add disk, out of memory\n");
+		return (ENOMEM);
+	}
+	memset(pd, 0, sizeof(pdinfo_t));
+	STAILQ_INIT(&pd->pd_part);
+	last = STAILQ_LAST(&hdinfo, pdinfo, pd_link);
+	if (last != NULL)
+		unit = last->pd_unit + 1;
+	else
+		unit = 0;
+
+	/* FILEPATH_DEVICE_PATH has 0 terminated string */
+	for (len = 0; node->PathName[len] != 0; len++)
+		;
+	if ((pathname = malloc(len + 1)) == NULL) {
+		printf("Failed to add disk, out of memory\n");
+		free(pd);
+		return (ENOMEM);
+	}
+	cpy16to8(node->PathName, pathname, len + 1);
+	p = strchr(pathname, ':');
+
+	/*
+	 * Assume we are receiving handles in order, first disk handle,
+	 * then partitions for this disk. If this assumption proves
+	 * false, this code would need update.
+	 */
+	if (p == NULL) {	/* no colon, add the disk */
+		pd->pd_handle = disk_handle;
+		pd->pd_unit = unit;
+		pd->pd_devpath = devpath;
+		STAILQ_INSERT_TAIL(&hdinfo, pd, pd_link);
+		free(pathname);
+		return (0);
+	}
+	p++;	/* skip the colon */
+	unit = (int)strtol(p, NULL, 0);
+
+	/*
+	 * We should have disk registered, if not, we are receiving
+	 * handles out of order, and this code should be reworked
+	 * to create "blank" disk for partition, and to find the
+	 * disk based on PathName compares.
+	 */
+	if (last == NULL) {
+		printf("BUG: No disk for partition \"%s\"\n", pathname);
+		free(pathname);
+		free(pd);
+		return (EINVAL);
+	}
+	/* Add the partition. */
+	pd->pd_handle = disk_handle;
+	pd->pd_unit = unit;
+	pd->pd_devpath = devpath;
+	STAILQ_INSERT_TAIL(&last->pd_part, pd, pd_link);
+	free(pathname);
+	return (0);
+}
+
 static void
 efipart_updatehd(void)
 {
@@ -467,6 +550,12 @@ efipart_updatehd(void)
 			efipart_hdinfo_add(handle, efipart_handles[i]);
 			continue;
 		}
+
+		if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
+		    DevicePathSubType(node) == MEDIA_FILEPATH_DP) {
+			efipart_hdinfo_add_filepath(efipart_handles[i]);
+			continue;
+		}
 	}
 }
 


More information about the svn-src-all mailing list