From 732b0825475c1a2466a6abf6e223b2a77af011f2 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Mon, 6 Mar 2023 14:27:21 +0100 Subject: nvedit: simplify do_env_indirect() Instead of calling env_get(from) up to three times, just do it once, computing the value we will put into 'to' and error out if that is NULL (i.e. no 'from' variable and no default provided). No functional change. Signed-off-by: Rasmus Villemoes Reviewed-by: Simon Glass --- cmd/nvedit.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 7cbc3fd573a..12eae0627bb 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -1025,6 +1025,7 @@ static int do_env_indirect(struct cmd_tbl *cmdtp, int flag, char *from = argv[2]; char *default_value = NULL; int ret = 0; + char *val; if (argc < 3 || argc > 4) { return CMD_RET_USAGE; @@ -1034,18 +1035,14 @@ static int do_env_indirect(struct cmd_tbl *cmdtp, int flag, default_value = argv[3]; } - if (env_get(from) == NULL && default_value == NULL) { + val = env_get(from) ?: default_value; + if (!val) { printf("## env indirect: Environment variable for (%s) does not exist.\n", from); return CMD_RET_FAILURE; } - if (env_get(from) == NULL) { - ret = env_set(to, default_value); - } - else { - ret = env_set(to, env_get(from)); - } + ret = env_set(to, val); if (ret == 0) { return CMD_RET_SUCCESS; -- cgit v1.2.3 From 59b1c9be01934222cf773b35de7c8d086dabaef6 Mon Sep 17 00:00:00 2001 From: Stephen Carlson Date: Fri, 10 Mar 2023 11:07:13 -0800 Subject: cmd: pci: Add command to set MPS of all PCIe devices Enable tuning of the PCI Express MPS (Maximum Payload Size) of each device. The Maximum Read Request Size is not altered. The SAFE method uses the largest MPS value supported by all devices in the system for each device. This method is the same algorithm as used by Linux pci=pcie_bus_safe. The PEER2PEER method sets all devices to the minimal (128 byte) MPS, which allows hot plug of devices later that might only support the minimum size, and ensures compatibility of DMA between two devices on the bus. Signed-off-by: Stephen Carlson --- cmd/Kconfig | 10 ++++ cmd/Makefile | 1 + cmd/pci_mps.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 cmd/pci_mps.c (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index ba5ec69293f..8138ab98eab 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1396,6 +1396,16 @@ config CMD_PCI peripherals. Sub-commands allow bus enumeration, displaying and changing configuration space and a few other features. +config CMD_PCI_MPS + bool "pci_mps - Configure PCI device MPS" + depends on PCI + help + Enables PCI Express Maximum Packet Size (MPS) tuning. This + command configures the PCI Express MPS of each endpoint to the + largest value supported by all devices below the root complex. + The Maximum Read Request Size will not be altered. This method is + the same algorithm as used by Linux pci=pcie_bus_safe. + config CMD_PINMUX bool "pinmux - show pins muxing" depends on PINCTRL diff --git a/cmd/Makefile b/cmd/Makefile index d95833b2de0..e032091621d 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -131,6 +131,7 @@ obj-$(CONFIG_CMD_PART) += part.o obj-$(CONFIG_CMD_PCAP) += pcap.o ifdef CONFIG_PCI obj-$(CONFIG_CMD_PCI) += pci.o +obj-$(CONFIG_CMD_PCI_MPS) += pci_mps.o endif obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PMC) += pmc.o diff --git a/cmd/pci_mps.c b/cmd/pci_mps.c new file mode 100644 index 00000000000..555a5fdd8e6 --- /dev/null +++ b/cmd/pci_mps.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2022 Microsoft Corporation + * Stephen Carlson + * + * PCI Express Maximum Packet Size (MPS) configuration + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PCI_MPS_SAFE 0 +#define PCI_MPS_PEER2PEER 1 + +static int pci_mps_find_safe(struct udevice *bus, unsigned int *min_mps, + unsigned int *n) +{ + struct udevice *dev; + int res = 0, addr; + unsigned int mpss; + u32 regval; + + if (!min_mps || !n) + return -EINVAL; + + for (device_find_first_child(bus, &dev); + dev; + device_find_next_child(&dev)) { + addr = dm_pci_find_capability(dev, PCI_CAP_ID_EXP); + if (addr <= 0) + continue; + + res = dm_pci_read_config32(dev, addr + PCI_EXP_DEVCAP, + ®val); + if (res != 0) + return res; + mpss = (unsigned int)(regval & PCI_EXP_DEVCAP_PAYLOAD); + *n += 1; + if (mpss < *min_mps) + *min_mps = mpss; + } + + return res; +} + +static int pci_mps_set_bus(struct udevice *bus, unsigned int target) +{ + struct udevice *dev; + u32 mpss, target_mps = (u32)(target << 5); + u16 mps; + int res = 0, addr; + + for (device_find_first_child(bus, &dev); + dev && res == 0; + device_find_next_child(&dev)) { + addr = dm_pci_find_capability(dev, PCI_CAP_ID_EXP); + if (addr <= 0) + continue; + + res = dm_pci_read_config32(dev, addr + PCI_EXP_DEVCAP, + &mpss); + if (res != 0) + return res; + + /* Do not set device above its maximum MPSS */ + mpss = (mpss & PCI_EXP_DEVCAP_PAYLOAD) << 5; + if (target_mps < mpss) + mps = (u16)target_mps; + else + mps = (u16)mpss; + res = dm_pci_clrset_config16(dev, addr + PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_PAYLOAD, mps); + } + + return res; +} + +/* + * Sets the MPS of each PCI Express device to the specified policy. + */ +static int pci_mps_set(int policy) +{ + struct udevice *bus; + int i, res = 0; + /* 0 = 128B, min value for hotplug */ + unsigned int mps = 0; + + if (policy == PCI_MPS_SAFE) { + unsigned int min_mps = PCI_EXP_DEVCAP_PAYLOAD_4096B, n = 0; + + /* Find maximum MPS supported by all devices */ + for (i = 0; + uclass_get_device_by_seq(UCLASS_PCI, i, &bus) == 0 && + res == 0; + i++) + res = pci_mps_find_safe(bus, &min_mps, &n); + + /* If no devices were found, do not reconfigure */ + if (n == 0) + return res; + mps = min_mps; + } + + /* This message is checked by the sandbox test */ + printf("Setting MPS of all devices to %uB\n", 128U << mps); + for (i = 0; + uclass_get_device_by_seq(UCLASS_PCI, i, &bus) == 0 && res == 0; + i++) + res = pci_mps_set_bus(bus, mps); + + return res; +} + +/* + * PCI MPS tuning commands + * + * Syntax: + * pci_mps safe + * pci_mps peer2peer + */ +static int do_pci_mps(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char cmd = 'u'; + int ret = 0; + + if (argc > 1) + cmd = argv[1][0]; + + switch (cmd) { + case 's': /* safe */ + ret = pci_mps_set(PCI_MPS_SAFE); + break; + case 'p': /* peer2peer/hotplug */ + ret = pci_mps_set(PCI_MPS_PEER2PEER); + break; + default: /* usage, help */ + goto usage; + } + + return ret; +usage: + return CMD_RET_USAGE; +} + +/***************************************************/ + +#ifdef CONFIG_SYS_LONGHELP +static char pci_mps_help_text[] = + "safe\n" + " - Set PCI Express MPS of all devices to safe values\n" + "pci_mps peer2peer\n" + " - Set PCI Express MPS of all devices to support hotplug and peer-to-peer DMA\n"; +#endif + +U_BOOT_CMD(pci_mps, 2, 0, do_pci_mps, + "configure PCI Express MPS", pci_mps_help_text); -- cgit v1.2.3 From a57adacf50d1bc0b5efd85b484a5c52a4c1ebcf1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Mon, 20 Mar 2023 21:01:43 +0200 Subject: cmd: ums: abort mounting by pressing any key This patch introduses config which allows interrupt run of usb mass storage with any key. This is especially useful on devices with limited input capabilities like tablets and smatphones which have only gpio keys in direct access. Signed-off-by: Svyatoslav Ryhel Reviewed-by: Simon Glass --- cmd/Kconfig | 6 ++++++ cmd/usb_mass_storage.c | 10 ++++++++++ 2 files changed, 16 insertions(+) (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index 8138ab98eab..8c9b430f99f 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1552,6 +1552,12 @@ config CMD_USB_MASS_STORAGE export a block device: U-Boot, the USB device, acts as a simple external hard drive plugged on the host USB port. +config CMD_UMS_ABORT_KEYED + bool "UMS abort with any key" + depends on CMD_USB_MASS_STORAGE + help + Allow interruption of usb mass storage run with any key pressed. + config CMD_PVBLOCK bool "Xen para-virtualized block device" depends on XEN diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index b7daaa6e8e8..c3cc1975f9d 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -231,6 +231,16 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, goto cleanup_register; } + if (IS_ENABLED(CONFIG_CMD_UMS_ABORT_KEYED)) { + /* Abort by pressing any key */ + if (tstc()) { + getchar(); + printf("\rOperation aborted.\n"); + rc = CMD_RET_SUCCESS; + goto cleanup_register; + } + } + schedule(); } -- cgit v1.2.3