[Concept,06/20] efi: Convert a device-path to a uclass and name

Message ID 20250828020732.981415-7-sjg@u-boot.org
State New
Headers
Series efi: App and devicetree improvements |

Commit Message

Simon Glass Aug. 28, 2025, 2:07 a.m. UTC
  From: Simon Glass <sjg@chromium.org>

Add a function which looks through a device path and tries to figure out
the corresponding name (e.g. 'nvme' and uclass ID. This can be useful
for showing a short summary of the device path.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/efi_device_path.h | 11 +++++
 lib/efi/device_path.c     | 86 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)
  

Patch

diff --git a/include/efi_device_path.h b/include/efi_device_path.h
index 41b59367762..2e425a6d82b 100644
--- a/include/efi_device_path.h
+++ b/include/efi_device_path.h
@@ -10,6 +10,7 @@ 
 
 #include <efi.h>
 
+enum uclass_id;
 struct blk_desc;
 struct efi_load_option;
 struct udevice;
@@ -418,4 +419,14 @@  struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path);
 struct efi_device_path *efi_dp_from_http(const char *server,
 					 struct udevice *dev);
 
+/**
+ * efi_dp_guess_uclass() - get the guessed name and uclass from EFI device path
+ *
+ * @device_path:	EFI device path
+ * @guessp:		Returns the U-Boot uclass ID
+ * Return: name string
+ */
+const char *efi_dp_guess_uclass(struct efi_device_path *device_path,
+				enum uclass_id *guessp);
+
 #endif /* EFI_DEVICE_PATH_H */
diff --git a/lib/efi/device_path.c b/lib/efi/device_path.c
index 1dc28f81146..191d58bbd2d 100644
--- a/lib/efi/device_path.c
+++ b/lib/efi/device_path.c
@@ -1290,3 +1290,89 @@  struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path)
 
 	return NULL;
 }
+
+const char *efi_dp_guess_uclass(struct efi_device_path *device_path,
+				enum uclass_id *guessp)
+{
+	struct efi_device_path *dp = device_path;
+	enum uclass_id best_guess = UCLASS_BLK;
+	const char *best_name = "blk";
+
+	while (dp) {
+		if (dp->type == DEVICE_PATH_TYPE_MESSAGING_DEVICE) {
+			switch (dp->sub_type) {
+			case DEVICE_PATH_SUB_TYPE_MSG_ATAPI:
+				*guessp = UCLASS_IDE;
+				return "ide";
+			case DEVICE_PATH_SUB_TYPE_MSG_SCSI:
+			case DEVICE_PATH_SUB_TYPE_MSG_ISCSI:
+				*guessp = UCLASS_SCSI;
+				return "scsi";
+			case DEVICE_PATH_SUB_TYPE_MSG_FIREWIRE:
+			case DEVICE_PATH_SUB_TYPE_MSG_1394:
+				*guessp = UCLASS_BLK;
+				return "firewire";
+			case DEVICE_PATH_SUB_TYPE_MSG_USB:
+			case DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS:
+			case DEVICE_PATH_SUB_TYPE_MSG_USB_WWI:
+				*guessp = UCLASS_USB;
+				return "usb";
+			case DEVICE_PATH_SUB_TYPE_MSG_I2O:
+				*guessp = UCLASS_BLK;
+				return "i2o";
+			case DEVICE_PATH_SUB_TYPE_MSG_INFINIBAND:
+				*guessp = UCLASS_ETH;
+				return "infiniband";
+			case DEVICE_PATH_SUB_TYPE_MSG_VENDOR:
+				*guessp = UCLASS_MISC;
+				return "vendor";
+			case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR:
+			case DEVICE_PATH_SUB_TYPE_MSG_IPV4:
+			case DEVICE_PATH_SUB_TYPE_MSG_IPV6:
+			case DEVICE_PATH_SUB_TYPE_MSG_VLAN:
+				*guessp = UCLASS_ETH;
+				return "eth";
+			case DEVICE_PATH_SUB_TYPE_MSG_UART:
+				*guessp = UCLASS_SERIAL;
+				return "serial";
+			case DEVICE_PATH_SUB_TYPE_MSG_SATA:
+				*guessp = UCLASS_AHCI;
+				return "ahci";
+			case DEVICE_PATH_SUB_TYPE_MSG_FIBRECHAN:
+			case DEVICE_PATH_SUB_TYPE_MSG_FIBRECHAN_EX:
+				*guessp = UCLASS_SCSI;
+				return "fibrechan";
+			case DEVICE_PATH_SUB_TYPE_MSG_SAS:
+			case DEVICE_PATH_SUB_TYPE_MSG_SAS_EX:
+				*guessp = UCLASS_SCSI;
+				return "sas";
+			case DEVICE_PATH_SUB_TYPE_MSG_NVME:
+				*guessp = UCLASS_NVME;
+				return "nvme";
+			case DEVICE_PATH_SUB_TYPE_MSG_URI:
+				*guessp = UCLASS_ETH;
+				return "uri";
+			case DEVICE_PATH_SUB_TYPE_MSG_UFS:
+				*guessp = UCLASS_UFS;
+				return "ufs";
+			case DEVICE_PATH_SUB_TYPE_MSG_SD:
+			case DEVICE_PATH_SUB_TYPE_MSG_MMC:
+			case DEVICE_PATH_SUB_TYPE_MSG_EMMC:
+				*guessp = UCLASS_MMC;
+				return "mmc";
+			default:
+				break;
+			}
+		} else if (dp->type == DEVICE_PATH_TYPE_HARDWARE_DEVICE) {
+			/* PCI devices could be many things, keep as fallback */
+			best_guess = UCLASS_PCI;
+			best_name = "pci";
+		}
+		dp = efi_dp_next(dp);
+	}
+
+	*guessp = best_guess;
+
+	return best_name;
+}
+