aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-03-25 09:40:19 -0400
committerTom Rini <trini@konsulko.com>2023-03-25 09:40:19 -0400
commit8be7b4629e87ff8db08dd087c81d58129d029bad (patch)
treefa7317c65ed1e93b9799cdba31ea1ac42906d073
parent78f67f11a9920ef988cbff5341616695c3e87ebd (diff)
parent180b7118bed8433f9cfe4b5ad62c6b0d901924f5 (diff)
downloadu-boot-8be7b4629e87ff8db08dd087c81d58129d029bad.zip
u-boot-8be7b4629e87ff8db08dd087c81d58129d029bad.tar.gz
u-boot-8be7b4629e87ff8db08dd087c81d58129d029bad.tar.bz2
Merge tag 'efi-2023.04-rc5' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/25Mar2023
Pull request for efi-2023.04-rc5 UEFI: * Create unique device paths for USB devices with the same vendor and product id.
-rw-r--r--include/efi_api.h6
-rw-r--r--lib/efi_loader/efi_device_path.c45
-rw-r--r--lib/efi_loader/efi_device_path_to_text.c7
3 files changed, 46 insertions, 12 deletions
diff --git a/include/efi_api.h b/include/efi_api.h
index 2d18d25..c57868a 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -570,6 +570,7 @@ struct efi_mac_addr {
#define DEVICE_PATH_TYPE_HARDWARE_DEVICE 0x01
# define DEVICE_PATH_SUB_TYPE_MEMORY 0x03
# define DEVICE_PATH_SUB_TYPE_VENDOR 0x04
+# define DEVICE_PATH_SUB_TYPE_CONTROLLER 0x05
struct efi_device_path_memory {
struct efi_device_path dp;
@@ -584,6 +585,11 @@ struct efi_device_path_vendor {
u8 vendor_data[];
} __packed;
+struct efi_device_path_controller {
+ struct efi_device_path dp;
+ u32 controller_number;
+} __packed;
+
#define DEVICE_PATH_TYPE_ACPI_DEVICE 0x02
# define DEVICE_PATH_SUB_TYPE_ACPI_DEVICE 0x01
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 3b267b7..b6dd575 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -147,7 +147,7 @@ struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
* in practice fallback.efi just uses MEDIA:HARD_DRIVE
* so not sure when we would see these other cases.
*/
- if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_CLASS) ||
+ if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB) ||
EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) ||
EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH))
return dp;
@@ -564,6 +564,11 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
return dp_size(dev->parent)
+ sizeof(struct efi_device_path_vendor) + 1;
#endif
+#ifdef CONFIG_USB
+ case UCLASS_MASS_STORAGE:
+ return dp_size(dev->parent)
+ + sizeof(struct efi_device_path_controller);
+#endif
#ifdef CONFIG_VIRTIO_BLK
case UCLASS_VIRTIO:
/*
@@ -585,7 +590,7 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
case UCLASS_MASS_STORAGE:
case UCLASS_USB_HUB:
return dp_size(dev->parent) +
- sizeof(struct efi_device_path_usb_class);
+ sizeof(struct efi_device_path_usb);
default:
/* just skip over unknown classes: */
return dp_size(dev->parent);
@@ -742,6 +747,19 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
return &dp[1];
}
#endif
+#if defined(CONFIG_USB)
+ case UCLASS_MASS_STORAGE: {
+ struct blk_desc *desc = desc = dev_get_uclass_plat(dev);
+ struct efi_device_path_controller *dp =
+ dp_fill(buf, dev->parent);
+
+ dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+ dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CONTROLLER;
+ dp->dp.length = sizeof(*dp);
+ dp->controller_number = desc->lun;
+ return &dp[1];
+ }
+#endif
default:
debug("%s(%u) %s: unhandled parent class: %s (%u)\n",
__FILE__, __LINE__, __func__,
@@ -767,19 +785,22 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
#endif
case UCLASS_MASS_STORAGE:
case UCLASS_USB_HUB: {
- struct efi_device_path_usb_class *udp =
- dp_fill(buf, dev->parent);
- struct usb_device *udev = dev_get_parent_priv(dev);
- struct usb_device_descriptor *desc = &udev->descriptor;
+ struct efi_device_path_usb *udp = dp_fill(buf, dev->parent);
+
+ switch (device_get_uclass_id(dev->parent)) {
+ case UCLASS_USB_HUB: {
+ struct usb_device *udev = dev_get_parent_priv(dev);
+ udp->parent_port_number = udev->portnr;
+ break;
+ }
+ default:
+ udp->parent_port_number = 0;
+ }
udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
- udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS;
+ udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
udp->dp.length = sizeof(*udp);
- udp->vendor_id = desc->idVendor;
- udp->product_id = desc->idProduct;
- udp->device_class = desc->bDeviceClass;
- udp->device_subclass = desc->bDeviceSubClass;
- udp->device_protocol = desc->bDeviceProtocol;
+ udp->usb_interface = 0;
return &udp[1];
}
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 9062058..4b2ade3 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -77,6 +77,13 @@ static char *dp_hardware(char *s, struct efi_device_path *dp)
s += sprintf(s, ")");
break;
}
+ case DEVICE_PATH_SUB_TYPE_CONTROLLER: {
+ struct efi_device_path_controller *cdp =
+ (struct efi_device_path_controller *)dp;
+
+ s += sprintf(s, "Ctrl(0x%0x)", cdp->controller_number);
+ break;
+ }
default:
s = dp_unknown(s, dp);
break;