usb: Drop requirement for USB unbinding, add tests
Subsystems (19)
v2 cover usb: Drop requirement for USB unbinding, add tests
There was quite a bit of discussion about the change that required the unbinding of USB devices for the subsystem to function correctly. E.g.
https://patchwork.ozlabs.org/patch/485637/
The key issue is the usb_get_dev_index() function which is not a good API for driver model. We can drop use of this function once everything is converted to driver model. Then I believe the problems raised by Hans go away. For now we can add a deprecation warning on the function.
It is easy to convert USB keyboards to driver model. This series includes a patch for that.
This series also includes reverts for the three commits which as discussed I would like to drop. U-Boot should be able to run normally and exit without unbinding anything.
Also included are some tests for the 'usb tree' command. To make this work, console recording is implemented.
Finally, a USB keyboard driver is provided for sandbox, so that this part of the stack can be tested automatically.
Changes in v2:
- Add various patches to support USB keyboards and additional tests
Simon Glass (26):
sandbox: Add a way to skip time delays
dm: usb: Avoid time delays in sandbox tests
Move console definitions into a new console.h file
Drop config.h header from display_options.c
Add a circular memory buffer implementation
console: Add a console buffer
sandbox: Enable console recording and silent console
test: Record and silence console in tests
usb: Refactor USB tree output code for testing
dm: core: Add safe device iteration macros
sandbox: usb: Allow dynamic emulated USB device descriptors
sandbox: usb: Allow up to 4 emulated devices on a hub
sandbox: usb: Allow finding a USB emulator for a device Revert "dm: usb: Rename usb_find_child to usb_find_emul_child" Revert "dm: usb: Use device_unbind_children to clean up usb devs on
stop"
Revert "dm: Export device_remove_children / device_unbind_children"
dm: usb: Deprecate usb_get_dev_index()
dm: usb: Remove inactive children after a bus scan
dm: test: usb: Add tests for the 'usb tree' command
dm: test: usb: Add a test for device reordering
usb: Drop unused code in usb_kbd.c
usb: Avoid open-coded USB constants in usb_kbd.c
usb: sandbox: Add support for interrupt operations
usb: sandbox: Add a USB emulation driver
sandbox: Enable USB keyboard
dm: test: usb: sandbox: Add keyboard tests for sandbox
arch/blackfin/lib/cmd_cache_dump.c | 1 + arch/powerpc/cpu/mpc8260/ether_fcc.c | 1 + arch/powerpc/cpu/mpc8260/i2c.c | 1 + arch/powerpc/cpu/mpc8xx/i2c.c | 1 + arch/sandbox/cpu/cpu.c | 5 +- arch/sandbox/cpu/start.c | 8 + arch/sandbox/cpu/state.c | 14 ++ arch/sandbox/dts/test.dts | 19 +- arch/sandbox/include/asm/state.h | 20 ++ arch/sandbox/include/asm/test.h | 2 + arch/sh/lib/board.c | 1 + arch/sparc/lib/board.c | 1 + board/Arcturus/ucp1020/spl.c | 1 + board/astro/mcf5373l/fpga.c | 1 + board/cobra5272/flash.c | 1 + board/esd/common/cmd_loadpci.c | 1 + board/esd/cpci405/cpci405.c | 1 + board/esd/pmc405de/pmc405de.c | 1 + board/esd/pmc440/cmd_pmc440.c | 1 + board/esd/pmc440/pmc440.c | 1 + board/esd/vme8349/caddy.c | 1 + board/freescale/b4860qds/spl.c | 1 + board/freescale/c29xpcie/spl.c | 1 + board/freescale/mpc8569mds/mpc8569mds.c | 1 + board/freescale/p1010rdb/spl.c | 1 + board/freescale/p1022ds/spl.c | 1 + board/freescale/p1_p2_rdb_pc/spl.c | 1 + board/freescale/t102xqds/spl.c | 1 + board/freescale/t102xrdb/spl.c | 1 + board/freescale/t104xrdb/spl.c | 1 + board/freescale/t208xqds/spl.c | 1 + board/freescale/t208xrdb/spl.c | 1 + board/freescale/t4qds/spl.c | 1 + board/freescale/t4rdb/spl.c | 1 + board/gdsys/common/cmd_ioloop.c | 1 + board/inka4x0/inkadiag.c | 1 + board/lwmon5/kbd.c | 1 + board/mpl/common/kbd.c | 1 + board/mpl/pati/pati.c | 1 + board/renesas/sh7785lcr/selfcheck.c | 1 + board/tqc/tqm5200/cmd_stk52xx.c | 1 + board/tqc/tqm5200/tqm5200.c | 1 + board/xes/xpedite1000/xpedite1000.c | 1 + common/Kconfig | 28 +++ common/autoboot.c | 1 + common/board_f.c | 11 + common/board_r.c | 11 + common/cli.c | 1 + common/cli_hush.c | 1 + common/cli_simple.c | 1 + common/cmd_armflash.c | 1 + common/cmd_dcr.c | 1 + common/cmd_dfu.c | 1 + common/cmd_fastboot.c | 1 + common/cmd_fpgad.c | 1 + common/cmd_fuse.c | 1 + common/cmd_i2c.c | 1 + common/cmd_load.c | 1 + common/cmd_mem.c | 2 + common/cmd_misc.c | 1 + common/cmd_mmc.c | 1 + common/cmd_nand.c | 1 + common/cmd_nvedit.c | 1 + common/cmd_otp.c | 1 + common/cmd_pci.c | 1 + common/cmd_usb.c | 59 +++-- common/cmd_usb_mass_storage.c | 1 + common/command.c | 1 + common/console.c | 51 +++- common/iomux.c | 1 + common/main.c | 1 + common/usb_hub.c | 10 +- common/usb_kbd.c | 41 +-- configs/sandbox_defconfig | 5 + drivers/block/fsl_sata.c | 1 + drivers/core/device-remove.c | 22 +- drivers/fpga/ACEX1K.c | 1 + drivers/fpga/virtex2.c | 1 + drivers/fpga/zynqpl.c | 1 + drivers/i2c/adi_i2c.c | 1 + drivers/input/input.c | 1 + drivers/input/keyboard.c | 1 + drivers/misc/cbmem_console.c | 2 +- drivers/mtd/cfi_flash.c | 1 + drivers/mtd/nand/bfin_nand.c | 1 + drivers/net/e1000_spi.c | 1 + drivers/net/keystone_net.c | 1 + drivers/net/phy/phy.c | 1 + drivers/net/vsc7385.c | 1 + drivers/power/battery/bat_trats.c | 1 + drivers/spi/bfin_spi.c | 1 + drivers/spi/bfin_spi6xx.c | 1 + drivers/spi/sh_qspi.c | 1 + drivers/spi/sh_spi.c | 1 + drivers/usb/emul/Makefile | 1 + drivers/usb/emul/sandbox_flash.c | 48 ++-- drivers/usb/emul/sandbox_hub.c | 2 +- drivers/usb/emul/sandbox_keyb.c | 241 ++++++++++++++++++ drivers/usb/emul/usb-emul-uclass.c | 29 ++- drivers/usb/gadget/ether.c | 1 + drivers/usb/gadget/f_mass_storage.c | 1 + drivers/usb/gadget/f_thor.c | 1 + drivers/usb/host/r8a66597-hcd.c | 1 + drivers/usb/host/usb-sandbox.c | 19 ++ drivers/usb/host/usb-uclass.c | 54 +++- drivers/usb/musb-new/musb_uboot.c | 1 + examples/standalone/mem_to_mem_idma2intr.c | 1 + examples/standalone/smc911x_eeprom.c | 1 + include/asm-generic/global_data.h | 6 + include/common.h | 17 -- include/configs/sandbox.h | 3 +- include/console.h | 52 ++++ include/dm/device-internal.h | 26 -- include/dm/device.h | 12 + include/dm/uclass.h | 15 ++ include/linux/usb/ch9.h | 20 ++ include/membuff.h | 246 ++++++++++++++++++ include/usb.h | 29 +++ lib/Makefile | 1 + lib/display_options.c | 2 +- lib/gunzip.c | 1 + lib/membuff.c | 390 +++++++++++++++++++++++++++++ net/net.c | 1 + test/dm/test-main.c | 12 + test/dm/usb.c | 241 ++++++++++++++++++ test/ut.c | 4 + 126 files changed, 1717 insertions(+), 149 deletions(-) create mode 100644 drivers/usb/emul/sandbox_keyb.c create mode 100644 include/console.h create mode 100644 include/membuff.h create mode 100644 lib/membuff.c
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 1/26 sandbox: Add a way to skip time delays
Some tests are slow due to delays which are unnecessary on sandbox. The worst offender is USB where we lose two seconds. Add a way to disable time delays.
---
Changes in v2: None
arch/sandbox/cpu/cpu.c | 5 ++++- arch/sandbox/cpu/state.c | 14 ++++++++++++++ arch/sandbox/include/asm/state.h | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-)
arch/sandbox/cpu/cpu.c +4 -1
@@ -37,7 +37,10 @@ void sandbox_exit(void)/* delay x useconds */ void __udelay (unsigned long usec) { -os_usleep (usec); +struct sandbox_state *state =state_get_current (); + +if (!state->skip_delays) +os_usleep (usec); }int cleanup_before_linux (void )
arch/sandbox/cpu/state.c +14 -0
@@ -337,6 +337,20 @@ struct sandbox_state *state_get_current(void)return state; } +void state_set_skip_delays (bool skip_delays) +{ +struct sandbox_state *state =state_get_current (); + + state->skip_delays = skip_delays; +} + +bool state_get_skip_delays (void ) +{ +struct sandbox_state *state =state_get_current (); + +return state->skip_delays; +} +int state_init (void ) { state = &main_state;
arch/sandbox/include/asm/state.h +19 -0
@@ -63,6 +63,7 @@ struct sandbox_state {enum reset_t last_reset;/* Last reset type */ bool reset_allowed[RESET_COUNT ];/* Allowed reset types */ enum state_terminal_raw term_raw;/* Terminal raw/cooked */ +bool skip_delays;/* Ignore any time delays (for test) */ /* Pointer to information for each SPI bus/cs */ struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS ]
@@ -185,6 +186,24 @@ int sandbox_write_state(struct sandbox_state *state, const char *fname);int state_setprop (int node,const char *prop_name,const void *data,int size);/** +* Control skipping of time delays +* +* Some tests have unnecessay time delays (e.g. USB). Allow these to be +* skipped to speed up testing +* +* @param skip_delays true to skip delays from now on, false to honour delay +* requests +*/ +void state_set_skip_delays (bool skip_delays); + +/** +* See if delays should be skipped +* +* @return true if delays should be skipped, false if they should be honoured +*/ +bool state_get_skip_delays (void ); + +/** * Initialize the test system state */ int state_init (void );
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 1/26 sandbox: Add a way to skip time delays
Applied to u-boot-dm.
PATCH v2 2/26 dm: usb: Avoid time delays in sandbox tests
In reply to Simon GlassCurrently the USB tests take around two seconds to run. Remove these unnecessary time delays so that the tests run quickly.
---
Changes in v2: None
common/usb_hub.c | 10 +++++++++- test/dm/test-main.c | 2 ++ test/dm/usb.c | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-)
common/usb_hub.c +9 -1
@@ -31,6 +31,9 @@#include <asm/unaligned.h> #include <linux/ctype.h> #include <asm/byteorder.h> +#ifdef CONFIG_SANDBOX +#include <asm/state.h> +#endif #include <asm/unaligned.h> #include <dm/root.h>
@@ -466,7 +469,12 @@ static int usb_hub_configure(struct usb_device *dev)unsigned short portstatus, portchange;int ret;ulong start =get_timer (0 ); +uint delay =CONFIG_SYS_HZ ; +#ifdef CONFIG_SANDBOX +if (state_get_skip_delays ()) + delay =0 ; +#endif #ifdef CONFIG_DM_USB debug ("\n\nScanning '%s' port %d\n" , dev->dev->name, i +1 );#else
@@ -498,7 +506,7 @@ static int usb_hub_configure(struct usb_device *dev)if (portstatus &USB_PORT_STAT_CONNECTION )break ; - }while (get_timer (start) <CONFIG_SYS_HZ *1 ); + }while (get_timer (start) < delay);if (ret <0 )continue ;
test/dm/test-main.c +2 -0
@@ -9,6 +9,7 @@#include <dm.h> #include <errno.h> #include <malloc.h> +#include <asm/state.h> #include <dm/test.h> #include <dm/root.h> #include <dm/uclass-internal.h>
@@ -113,6 +114,7 @@ static int dm_test_main(const char *test_name)ut_assertok (dm_scan_fdt (gd->fdt_blob, false)); test->func (uts); +state_set_skip_delays (false);ut_assertok (dm_test_destroy (uts)); }
test/dm/usb.c +3 -0
@@ -8,6 +8,8 @@#include <dm.h> #include <usb.h> #include <asm/io.h> +#include <asm/state.h> +#include <dm/device-internal.h> #include <dm/test.h> #include <test/ut.h>
@@ -35,6 +37,7 @@ static int dm_test_usb_flash(struct unit_test_state *uts)block_dev_desc_t *dev_desc;char cmp[1024 ]; +state_set_skip_delays (true);ut_assertok (usb_init ());ut_assertok (uclass_get_device (UCLASS_MASS_STORAGE ,0 , &dev));ut_assertok (get_device ("usb" ,"0" , &dev_desc));
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 2/26 dm: usb: Avoid time delays in sandbox tests
Applied to u-boot-dm.
PATCH v2 3/26 Move console definitions into a new console.h file
In reply to Simon GlassThe console includes a global variable and several functions that are only used by a small subset of U-Boot files. Before adding more functions, move the definitions into their own header file.
---
Changes in v2: None
arch/blackfin/lib/cmd_cache_dump.c | 1 + arch/powerpc/cpu/mpc8260/ether_fcc.c | 1 + arch/powerpc/cpu/mpc8260/i2c.c | 1 + arch/powerpc/cpu/mpc8xx/i2c.c | 1 + arch/sh/lib/board.c | 1 + arch/sparc/lib/board.c | 1 + board/Arcturus/ucp1020/spl.c | 1 + board/astro/mcf5373l/fpga.c | 1 + board/cobra5272/flash.c | 1 + board/esd/common/cmd_loadpci.c | 1 + board/esd/cpci405/cpci405.c | 1 + board/esd/pmc405de/pmc405de.c | 1 + board/esd/pmc440/cmd_pmc440.c | 1 + board/esd/pmc440/pmc440.c | 1 + board/esd/vme8349/caddy.c | 1 + board/freescale/b4860qds/spl.c | 1 + board/freescale/c29xpcie/spl.c | 1 + board/freescale/mpc8569mds/mpc8569mds.c | 1 + board/freescale/p1010rdb/spl.c | 1 + board/freescale/p1022ds/spl.c | 1 + board/freescale/p1_p2_rdb_pc/spl.c | 1 + board/freescale/t102xqds/spl.c | 1 + board/freescale/t102xrdb/spl.c | 1 + board/freescale/t104xrdb/spl.c | 1 + board/freescale/t208xqds/spl.c | 1 + board/freescale/t208xrdb/spl.c | 1 + board/freescale/t4qds/spl.c | 1 + board/freescale/t4rdb/spl.c | 1 + board/gdsys/common/cmd_ioloop.c | 1 + board/inka4x0/inkadiag.c | 1 + board/lwmon5/kbd.c | 1 + board/mpl/common/kbd.c | 1 + board/mpl/pati/pati.c | 1 + board/renesas/sh7785lcr/selfcheck.c | 1 + board/tqc/tqm5200/cmd_stk52xx.c | 1 + board/tqc/tqm5200/tqm5200.c | 1 + board/xes/xpedite1000/xpedite1000.c | 1 + common/autoboot.c | 1 + common/board_f.c | 1 + common/board_r.c | 1 + common/cli.c | 1 + common/cli_hush.c | 1 + common/cli_simple.c | 1 + common/cmd_armflash.c | 1 + common/cmd_dcr.c | 1 + common/cmd_dfu.c | 1 + common/cmd_fastboot.c | 1 + common/cmd_fpgad.c | 1 + common/cmd_fuse.c | 1 + common/cmd_i2c.c | 1 + common/cmd_load.c | 1 + common/cmd_mem.c | 2 ++ common/cmd_misc.c | 1 + common/cmd_mmc.c | 1 + common/cmd_nand.c | 1 + common/cmd_nvedit.c | 1 + common/cmd_otp.c | 1 + common/cmd_pci.c | 1 + common/cmd_usb.c | 1 + common/cmd_usb_mass_storage.c | 1 + common/command.c | 1 + common/console.c | 1 + common/iomux.c | 1 + common/main.c | 1 + common/usb_kbd.c | 1 + drivers/block/fsl_sata.c | 1 + drivers/fpga/ACEX1K.c | 1 + drivers/fpga/virtex2.c | 1 + drivers/fpga/zynqpl.c | 1 + drivers/i2c/adi_i2c.c | 1 + drivers/input/input.c | 1 + drivers/input/keyboard.c | 1 + drivers/misc/cbmem_console.c | 2 +- drivers/mtd/cfi_flash.c | 1 + drivers/mtd/nand/bfin_nand.c | 1 + drivers/net/e1000_spi.c | 1 + drivers/net/keystone_net.c | 1 + drivers/net/phy/phy.c | 1 + drivers/net/vsc7385.c | 1 + drivers/power/battery/bat_trats.c | 1 + drivers/spi/bfin_spi.c | 1 + drivers/spi/bfin_spi6xx.c | 1 + drivers/spi/sh_qspi.c | 1 + drivers/spi/sh_spi.c | 1 + drivers/usb/gadget/ether.c | 1 + drivers/usb/gadget/f_mass_storage.c | 1 + drivers/usb/gadget/f_thor.c | 1 + drivers/usb/host/r8a66597-hcd.c | 1 + drivers/usb/musb-new/musb_uboot.c | 1 + examples/standalone/mem_to_mem_idma2intr.c | 1 + examples/standalone/smc911x_eeprom.c | 1 + include/common.h | 17 ----------------- include/console.h | 30 ++++++++++++++++++++++++++++++ lib/display_options.c | 1 + lib/gunzip.c | 1 + net/net.c | 1 + test/dm/test-main.c | 1 + test/dm/usb.c | 1 + 98 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 include/console.h
arch/blackfin/lib/cmd_cache_dump.c +1 -0
@@ -9,6 +9,7 @@#include <config.h> #include <common.h> #include <command.h> +#include <console.h> #include <asm/blackfin.h> #include <asm/mach-common/bits/mpu.h>
arch/powerpc/cpu/mpc8260/ether_fcc.c +1 -0
@@ -24,6 +24,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <asm/cpm_8260.h> #include <mpc8260.h>
arch/powerpc/cpu/mpc8260/i2c.c +1 -0
@@ -9,6 +9,7 @@*/ #include <common.h> +#include <console.h> #if defined(CONFIG_HARD_I2C )
arch/powerpc/cpu/mpc8xx/i2c.c +1 -0
@@ -12,6 +12,7 @@*/ #include <common.h> +#include <console.h> #ifdef CONFIG_HARD_I2C
arch/sh/lib/board.c +1 -0
@@ -7,6 +7,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <malloc.h> #include <stdio_dev.h> #include <version.h>
arch/sparc/lib/board.c +1 -0
@@ -11,6 +11,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <malloc.h> #include <stdio_dev.h> #include <config.h>
board/Arcturus/ucp1020/spl.c +1 -0
@@ -9,6 +9,7 @@*/ #include <common.h> +#include <console.h> #include <ns16550.h> #include <malloc.h> #include <mmc.h>
board/astro/mcf5373l/fpga.c +1 -0
@@ -15,6 +15,7 @@/* Altera/Xilinx FPGA configuration support for the ASTRO "URMEL" board */ #include <common.h> +#include <console.h> #include <watchdog.h> #include <altera.h> #include <ACEX1K.h>
board/cobra5272/flash.c +1 -0
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <console.h> #define PHYS_FLASH_1 CONFIG_SYS_FLASH_BASE#define FLASH_BANK_SIZE 0x200000
board/esd/common/cmd_loadpci.c +1 -0
@@ -7,6 +7,7 @@#include <common.h> #include <command.h> +#include <console.h> #if !defined(CONFIG_440 )#include <asm/4xx_pci.h> #endif
board/esd/cpci405/cpci405.c +1 -0
@@ -5,6 +5,7 @@* SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <console.h> #include <libfdt.h> #include <fdt_support.h> #include <asm/processor.h>
board/esd/pmc405de/pmc405de.c +1 -0
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <console.h> #include <libfdt.h> #include <fdt_support.h> #include <asm/processor.h>
board/esd/pmc440/cmd_pmc440.c +1 -0
@@ -6,6 +6,7 @@*/ #include <common.h> #include <command.h> +#include <console.h> #include <asm/io.h> #include <asm/cache.h> #include <asm/processor.h>
board/esd/pmc440/pmc440.c +1 -0
@@ -13,6 +13,7 @@* SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <console.h> #include <libfdt.h> #include <fdt_support.h> #include <asm/ppc440.h>
board/esd/vme8349/caddy.c +1 -0
@@ -8,6 +8,7 @@*/ #include <common.h> +#include <console.h> #include <ioports.h> #include <mpc83xx.h> #include <asm/mpc8349_pci.h>
board/freescale/b4860qds/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <asm/spl.h> #include <malloc.h> #include <ns16550.h>
board/freescale/c29xpcie/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <ns16550.h> #include <malloc.h> #include <mmc.h>
board/freescale/mpc8569mds/mpc8569mds.c +1 -0
@@ -7,6 +7,7 @@*/ #include <common.h> +#include <console.h> #include <hwconfig.h> #include <pci.h> #include <asm/processor.h>
board/freescale/p1010rdb/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <ns16550.h> #include <malloc.h> #include <mmc.h>
board/freescale/p1022ds/spl.c +1 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <console.h> #include <ns16550.h> #include <malloc.h> #include <mmc.h>
board/freescale/p1_p2_rdb_pc/spl.c +1 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <console.h> #include <ns16550.h> #include <malloc.h> #include <mmc.h>
board/freescale/t102xqds/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <ns16550.h> #include <nand.h>
board/freescale/t102xrdb/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <ns16550.h> #include <nand.h>
board/freescale/t104xrdb/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <ns16550.h> #include <nand.h>
board/freescale/t208xqds/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <ns16550.h> #include <nand.h>
board/freescale/t208xrdb/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <ns16550.h> #include <nand.h>
board/freescale/t4qds/spl.c +1 -0
@@ -4,6 +4,7 @@*/ #include <common.h> +#include <console.h> #include <asm/spl.h> #include <malloc.h> #include <ns16550.h>
board/freescale/t4rdb/spl.c +1 -0
@@ -7,6 +7,7 @@*/ #include <common.h> +#include <console.h> #include <asm/spl.h> #include <malloc.h> #include <ns16550.h>
board/gdsys/common/cmd_ioloop.c +1 -0
@@ -7,6 +7,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <gdsys_fpga.h>
board/inka4x0/inkadiag.c +1 -0
@@ -10,6 +10,7 @@#include <asm/io.h> #include <common.h> #include <config.h> +#include <console.h> #include <mpc5xxx.h> #include <pci.h>
board/lwmon5/kbd.c +1 -0
@@ -17,6 +17,7 @@#include <common.h> #include <i2c.h> #include <command.h> +#include <console.h> #include <post.h> #include <serial.h> #include <malloc.h>
board/mpl/common/kbd.c +1 -0
@@ -8,6 +8,7 @@* linux/drivers/char/pc_keyb.c */ #include <common.h> +#include <console.h> #include <asm/processor.h> #include <stdio_dev.h> #include "isa.h"
board/mpl/pati/pati.c +1 -0
@@ -29,6 +29,7 @@**********************************************************************************/ #include <common.h> +#include <console.h> #include <mpc5xx.h> #include <stdio_dev.h> #include <pci_ids.h>
board/renesas/sh7785lcr/selfcheck.c +1 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <console.h> #include <asm/io.h> #include <asm/processor.h> #include <asm/pci.h>
board/tqc/tqm5200/cmd_stk52xx.c +1 -0
@@ -12,6 +12,7 @@#include <common.h> #include <command.h> +#include <console.h> #if defined(CONFIG_CMD_BSP )
board/tqc/tqm5200/tqm5200.c +1 -0
@@ -12,6 +12,7 @@*/ #include <common.h> +#include <console.h> #include <mpc5xxx.h> #include <pci.h> #include <asm/processor.h>
board/xes/xpedite1000/xpedite1000.c +1 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <console.h> #include <asm/processor.h> #include <spd_sdram.h> #include <i2c.h>
common/autoboot.c +1 -0
@@ -9,6 +9,7 @@#include <autoboot.h> #include <bootretry.h> #include <cli.h> +#include <console.h> #include <fdtdec.h> #include <menu.h> #include <post.h>
common/board_f.c +1 -0
@@ -13,6 +13,7 @@#include <common.h> #include <linux/compiler.h> #include <version.h> +#include <console.h> #include <environment.h> #include <dm.h> #include <fdtdec.h>
common/board_r.c +1 -0
@@ -15,6 +15,7 @@#if defined(CONFIG_CMD_BEDBUG )#include <bedbug/type.h> #endif +#include <console.h> #ifdef CONFIG_HAS_DATAFLASH #include <dataflash.h> #endif
common/cli.c +1 -0
@@ -12,6 +12,7 @@#include <common.h> #include <cli.h> #include <cli_hush.h> +#include <console.h> #include <fdtdec.h> #include <malloc.h>
common/cli_hush.c +1 -0
@@ -79,6 +79,7 @@#include <malloc.h> /* malloc, free, realloc*/ #include <linux/ctype.h> /* isalpha, isdigit */ #include <common.h> /* readline */ +#include <console.h> #include <bootretry.h> #include <cli.h> #include <cli_hush.h>
common/cli_simple.c +1 -0
@@ -12,6 +12,7 @@#include <common.h> #include <bootretry.h> #include <cli.h> +#include <console.h> #include <linux/ctype.h> #define DEBUG_PARSER 0/* set to 1 to debug */
common/cmd_armflash.c +1 -0
@@ -8,6 +8,7 @@*/ #include <common.h> #include <command.h> +#include <console.h> #include <asm/io.h> #define MAX_REGIONS 4
common/cmd_dcr.c +1 -0
@@ -13,6 +13,7 @@#include <cli.h> #include <config.h> #include <command.h> +#include <console.h> unsigned long get_dcr (unsigned short );unsigned long set_dcr (unsigned short ,unsigned long );
common/cmd_dfu.c +1 -0
@@ -14,6 +14,7 @@#include <common.h> #include <watchdog.h> #include <dfu.h> +#include <console.h> #include <g_dnl.h> #include <usb.h> #include <net.h>
common/cmd_fastboot.c +1 -0
@@ -9,6 +9,7 @@*/ #include <common.h> #include <command.h> +#include <console.h> #include <g_dnl.h> #include <usb.h>
common/cmd_fpgad.c +1 -0
@@ -11,6 +11,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <gdsys_fpga.h>
common/cmd_fuse.c +1 -0
@@ -11,6 +11,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <fuse.h> #include <asm/errno.h>
common/cmd_i2c.c +1 -0
@@ -69,6 +69,7 @@#include <bootretry.h> #include <cli.h> #include <command.h> +#include <console.h> #include <dm.h> #include <edid.h> #include <environment.h>
common/cmd_load.c +1 -0
@@ -10,6 +10,7 @@*/ #include <common.h> #include <command.h> +#include <console.h> #include <s_record.h> #include <net.h> #include <exports.h>
common/cmd_mem.c +2 -0
@@ -12,9 +12,11 @@*/ #include <common.h> +#include <console.h> #include <bootretry.h> #include <cli.h> #include <command.h> +#include <console.h> #ifdef CONFIG_HAS_DATAFLASH #include <dataflash.h> #endif
common/cmd_misc.c +1 -0
@@ -10,6 +10,7 @@*/ #include <common.h> #include <command.h> +#include <console.h> static int do_sleep (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) {
common/cmd_mmc.c +1 -0
@@ -7,6 +7,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <mmc.h> static int curr_device =-1 ;
common/cmd_nand.c +1 -0
@@ -22,6 +22,7 @@#include <common.h> #include <linux/mtd/mtd.h> #include <command.h> +#include <console.h> #include <watchdog.h> #include <malloc.h> #include <asm/byteorder.h>
common/cmd_nvedit.c +1 -0
@@ -27,6 +27,7 @@#include <common.h> #include <cli.h> #include <command.h> +#include <console.h> #include <environment.h> #include <search.h> #include <errno.h>
common/cmd_otp.c +1 -0
@@ -16,6 +16,7 @@#include <config.h> #include <common.h> #include <command.h> +#include <console.h> #include <asm/blackfin.h> #include <asm/clock.h>
common/cmd_pci.c +1 -0
@@ -17,6 +17,7 @@#include <bootretry.h> #include <cli.h> #include <command.h> +#include <console.h> #include <asm/processor.h> #include <asm/io.h> #include <pci.h>
common/cmd_usb.c +1 -0
@@ -13,6 +13,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <dm.h> #include <memalign.h> #include <asm/byteorder.h>
common/cmd_usb_mass_storage.c +1 -0
@@ -8,6 +8,7 @@#include <errno.h> #include <common.h> #include <command.h> +#include <console.h> #include <g_dnl.h> #include <part.h> #include <usb.h>
common/command.c +1 -0
@@ -11,6 +11,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <linux/ctype.h> /*
common/console.c +1 -0
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <console.h> #include <debug_uart.h> #include <stdarg.h> #include <iomux.h>
common/iomux.c +1 -0
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <console.h> #include <serial.h> #include <malloc.h>
common/main.c +1 -0
@@ -10,6 +10,7 @@#include <common.h> #include <autoboot.h> #include <cli.h> +#include <console.h> #include <version.h> DECLARE_GLOBAL_DATA_PTR ;
common/usb_kbd.c +1 -0
@@ -8,6 +8,7 @@* SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <console.h> #include <dm.h> #include <errno.h> #include <malloc.h>
drivers/block/fsl_sata.c +1 -0
@@ -7,6 +7,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <asm/io.h> #include <asm/processor.h> #include <asm/fsl_serdes.h>
drivers/fpga/ACEX1K.c +1 -0
@@ -9,6 +9,7 @@*/ #include <common.h> /* core U-Boot definitions */ +#include <console.h> #include <ACEX1K.h> /* ACEX device family */ /* Define FPGA_DEBUG to get debug printf's */
drivers/fpga/virtex2.c +1 -0
@@ -12,6 +12,7 @@*/ #include <common.h> +#include <console.h> #include <virtex2.h> #if 0
drivers/fpga/zynqpl.c +1 -0
@@ -8,6 +8,7 @@*/ #include <common.h> +#include <console.h> #include <asm/io.h> #include <fs.h> #include <zynqpl.h>
drivers/i2c/adi_i2c.c +1 -0
@@ -7,6 +7,7 @@*/ #include <common.h> +#include <console.h> #include <i2c.h> #include <asm/clock.h>
drivers/input/input.c +1 -0
@@ -8,6 +8,7 @@*/ #include <common.h> +#include <console.h> #include <errno.h> #include <stdio_dev.h> #include <input.h>
drivers/input/keyboard.c +1 -0
@@ -9,6 +9,7 @@***********************************************************************/ #include <common.h> +#include <console.h> #include <stdio_dev.h> #include <keyboard.h>
drivers/misc/cbmem_console.c +1 -1
@@ -16,7 +16,7 @@*/ #include <common.h> - +#include <console.h> #ifndef CONFIG_SYS_COREBOOT #error This driver requires coreboot#endif
drivers/mtd/cfi_flash.c +1 -0
@@ -18,6 +18,7 @@/* #define DEBUG */ #include <common.h> +#include <console.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/byteorder.h>
drivers/mtd/nand/bfin_nand.c +1 -0
@@ -15,6 +15,7 @@*/ #include <common.h> +#include <console.h> #include <asm/io.h> #ifdef DEBUG
drivers/net/e1000_spi.c +1 -0
@@ -1,4 +1,5 @@#include <common.h> +#include <console.h> #include "e1000.h" #include <linux/compiler.h>
drivers/net/keystone_net.c +1 -0
@@ -8,6 +8,7 @@*/ #include <common.h> #include <command.h> +#include <console.h> #include <net.h> #include <phy.h>
drivers/net/phy/phy.c +1 -0
@@ -11,6 +11,7 @@#include <config.h> #include <common.h> +#include <console.h> #include <dm.h> #include <malloc.h> #include <net.h>
drivers/net/vsc7385.c +1 -0
@@ -14,6 +14,7 @@#include <config.h> #include <common.h> +#include <console.h> #include <asm/io.h> #include <asm/errno.h> #include "vsc7385.h"
drivers/power/battery/bat_trats.c +1 -0
@@ -6,6 +6,7 @@*/ #include <common.h> +#include <console.h> #include <power/pmic.h> #include <power/battery.h> #include <power/max8997_pmic.h>
drivers/spi/bfin_spi.c +1 -0
@@ -9,6 +9,7 @@/*#define DEBUG*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <spi.h>
drivers/spi/bfin_spi6xx.c +1 -0
@@ -18,6 +18,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <spi.h>
drivers/spi/sh_qspi.c +1 -0
@@ -8,6 +8,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <spi.h> #include <asm/arch/rmobile.h>
drivers/spi/sh_spi.c +1 -0
@@ -19,6 +19,7 @@*/ #include <common.h> +#include <console.h> #include <malloc.h> #include <spi.h> #include <asm/io.h>
drivers/usb/gadget/ether.c +1 -0
@@ -9,6 +9,7 @@*/ #include <common.h> +#include <console.h> #include <asm/errno.h> #include <linux/netdevice.h> #include <linux/usb/ch9.h>
drivers/usb/gadget/f_mass_storage.c +1 -0
@@ -243,6 +243,7 @@#include <config.h> #include <malloc.h> #include <common.h> +#include <console.h> #include <g_dnl.h> #include <linux/err.h>
drivers/usb/gadget/f_thor.c +1 -0
@@ -17,6 +17,7 @@#include <errno.h> #include <common.h> +#include <console.h> #include <malloc.h> #include <memalign.h> #include <version.h>
drivers/usb/host/r8a66597-hcd.c +1 -0
@@ -7,6 +7,7 @@*/ #include <common.h> +#include <console.h> #include <usb.h> #include <asm/io.h>
drivers/usb/musb-new/musb_uboot.c +1 -0
@@ -1,4 +1,5 @@#include <common.h> +#include <console.h> #include <watchdog.h> #ifdef CONFIG_ARCH_SUNXI #include <asm/arch/usb_phy.h>
examples/standalone/mem_to_mem_idma2intr.c +1 -0
@@ -28,6 +28,7 @@#include <common.h> +#include <console.h> #include <exports.h> DECLARE_GLOBAL_DATA_PTR ;
examples/standalone/smc911x_eeprom.c +1 -0
@@ -15,6 +15,7 @@*/ #include <common.h> +#include <console.h> #include <exports.h> #include <linux/ctype.h> #include "../drivers/net/smc911x.h"
include/common.h +0 -17
@@ -218,7 +218,6 @@ int run_command_repeatable(const char *cmd, int flag);* @return 0 on success, or != 0 on error. */ int run_command_list (const char *cmd,int len,int flag); -extern char console_buffer[];/* arch/$(ARCH)/lib/board.c */ void board_init_f (ulong );
@@ -862,15 +861,6 @@ void srand(unsigned int seed);unsigned int rand (void );unsigned int rand_r (unsigned int *seedp); -/* common/console.c */ -int console_init_f (void );/* Before relocation; uses the serial stuff */ -int console_init_r (void );/* After relocation; uses the console stuff */ -int console_assign (int file,const char *devname);/* Assign the console */ -int ctrlc (void ); -int had_ctrlc (void );/* have we had a Control-C since last clear? */ -void clear_ctrlc (void );/* clear the Control-C condition */ -int disable_ctrlc (int );/* 1 to disable, 0 to enable Control-C detect */ -int confirm_yesno (void );/* 1 if input is "y", "Y", "yes" or "YES" */ /* * STDIO based functions (can always be used) */
@@ -929,13 +919,6 @@ static inline struct in_addr getenv_ip(char *var)return string_to_ip (getenv (var)); } -/* -* CONSOLE multiplexing. -*/ -#ifdef CONFIG_CONSOLE_MUX -#include <iomux.h> -#endif -int pcmcia_init (void );#ifdef CONFIG_STATUS_LED
include/console.h new file +30 -0
@@ -0,0 +1,30 @@ +/* +* (C) Copyright 2000-2009 +* Wolfgang Denk, DENX Software Engineering, wd at denx.de. +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __CONSOLE_H +#define __CONSOLE_H + +extern char console_buffer[]; + +/* common/console.c */ +int console_init_f (void );/* Before relocation; uses the serial stuff */ +int console_init_r (void );/* After relocation; uses the console stuff */ +int console_assign (int file,const char *devname);/* Assign the console */ +int ctrlc (void ); +int had_ctrlc (void );/* have we had a Control-C since last clear? */ +void clear_ctrlc (void );/* clear the Control-C condition */ +int disable_ctrlc (int );/* 1 to disable, 0 to enable Control-C detect */ +int confirm_yesno (void );/* 1 if input is "y", "Y", "yes" or "YES" */ + +/* +* CONSOLE multiplexing. +*/ +#ifdef CONFIG_CONSOLE_MUX +#include <iomux.h> +#endif + +#endif
lib/display_options.c +1 -0
@@ -7,6 +7,7 @@#include <config.h> #include <common.h> +#include <console.h> #include <div64.h> #include <inttypes.h> #include <version.h>
lib/gunzip.c +1 -0
@@ -8,6 +8,7 @@#include <common.h> #include <watchdog.h> #include <command.h> +#include <console.h> #include <image.h> #include <malloc.h> #include <u-boot/zlib.h>
net/net.c +1 -0
@@ -83,6 +83,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <environment.h> #include <errno.h> #include <net.h>
test/dm/test-main.c +1 -0
@@ -6,6 +6,7 @@#include <common.h> #include <command.h> +#include <console.h> #include <dm.h> #include <errno.h> #include <malloc.h>
test/dm/usb.c +1 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <console.h> #include <dm.h> #include <usb.h> #include <asm/io.h>
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 3/26 Move console definitions into a new console.h file
Rebased to master and:
Applied to u-boot-dm.
PATCH v2 4/26 Drop config.h header from display_options.c
In reply to Simon GlassSince common.h will always include this automatically, it is not needed.
---
Changes in v2: None
lib/display_options.c | 1 - 1 file changed, 1 deletion(-)
lib/display_options.c +0 -1
@@ -5,7 +5,6 @@* SPDX-License-Identifier: GPL-2.0+ */ -#include <config.h> #include <common.h> #include <console.h> #include <div64.h>
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 4/26 Drop config.h header from display_options.c
Applied to u-boot-dm.
PATCH v2 5/26 Add a circular memory buffer implementation
In reply to Simon GlassThis will be used to support console recording. It provides for a circular buffer which can be written at the head and read from the tail. It supports avoiding data copying by providing raw access to the data.
---
Changes in v2: None
include/membuff.h | 246 ++++++++++++++++++++++++++++++++++ lib/Makefile | 1 + lib/membuff.c | 390 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 637 insertions(+) create mode 100644 include/membuff.h create mode 100644 lib/membuff.c
include/membuff.h new file +246 -0
@@ -0,0 +1,246 @@ +/* +* Copyright (c) 2015 Google, Inc +* Written by Simon Glass <[email protected]> +* +* Copyright (c) 1992 Simon Glass +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _MEMBUFF_H +#define _MEMBUFF_H + +/** +* @struct membuff: holds the state of a membuff - it is used for input and +* output buffers. The buffer extends from @start to (@start + @size - 1). +* Data in the buffer extends from @tail to @head: it is written in at +* @head and read out from @tail. The membuff is empty when @head == @tail +* and full when adding another character would make @head == @tail. We +* therefore waste one character in the membuff to avoid having an extra flag +* to determine whether (when @head == @tail) the membuff is empty or full. +* +* xxxxxx data +* ...... empty +* +* .............xxxxxxxxxxxxxxxx......................... +* ^ ^ +* tail head +* +* xxxxxxxxxxxxx................xxxxxxxxxxxxxxxxxxxxxxxxx +* ^ ^ +* head tail +*/ +struct membuff { +char *start;/** the start of the buffer */ +char *end;/** the end of the buffer (start + length) */ +char *head;/** current buffer head */ +char *tail;/** current buffer tail */ +}; + +/** +* membuff_purge() - reset a membuff to the empty state +* +* Initialise head and tail pointers so that the membuff becomes empty. +* +* @mb: membuff to purge +*/ +void membuff_purge (struct membuff *mb); + +/** +* membuff_putraw() - find out where bytes can be written +* +* Work out where in the membuff some data could be written. Return a pointer +* to the address and the number of bytes which can be written there. If +* @update is true, the caller must then write the data immediately, since +* the membuff is updated as if the write has been done, +* +* Note that because the spare space in a membuff may not be contiguous, this +* function may not return @maxlen even if there is enough space in the +* membuff. However, by calling this function twice (with @update == true), +* you will get access to all the spare space. +* +* @mb: membuff to adjust +* @maxlen: the number of bytes we want to write +* @update: true to update the membuff as if the write happened, false to not +* @data: the address data can be written to +* @return number of bytes which can be written +*/ +int membuff_putraw (struct membuff *mb,int maxlen,bool update,char **data); + +/** +* membuff_getraw() - find and return a pointer to available bytes +* +* Returns a pointer to any valid input data in the given membuff and +* optionally marks it as read. Note that not all input data may not be +* returned, since data is not necessarily contiguous in the membuff. However, +* if you call this function twice (with @update == true) you are guaranteed +* to get all available data, in at most two installments. +* +* @mb: membuff to adjust +* @maxlen: maximum number of bytes to get +* @update: true to update the membuff as if the bytes have been read (use +* false to check bytes without reading them) +* @data: returns address of data in input membuff +* @return the number of bytes available at *@data +*/ +int membuff_getraw (struct membuff *mb,int maxlen,bool update,char **data); + +/** +* membuff_putbyte() - Writes a byte to a membuff +* +* @mb: membuff to adjust +* @ch: byte to write +* @return true on success, false if membuff is full +*/ +bool membuff_putbyte (struct membuff *mb,int ch); + +/** +* @mb: membuff to adjust +* membuff_getbyte() - Read a byte from the membuff +* @return the byte read, or -1 if the membuff is empty +*/ +int membuff_getbyte (struct membuff *mb); + +/** +* membuff_peekbyte() - check the next available byte +* +* Return the next byte which membuff_getbyte() would return, without +* removing it from the membuff. +* +* @mb: membuff to adjust +* @return the byte peeked, or -1 if the membuff is empty +*/ +int membuff_peekbyte (struct membuff *mb); + +/** +* membuff_get() - get data from a membuff +* +* Copies any available data (up to @maxlen bytes) to @buff and removes it +* from the membuff. +* +* @mb: membuff to adjust +* @Buff: address of membuff to transfer bytes to +* @maxlen: maximum number of bytes to read +* @return the number of bytes read +*/ +int membuff_get (struct membuff *mb,char *buff,int maxlen); + +/** +* membuff_put() - write data to a membuff +* +* Writes some data to a membuff. Returns the number of bytes added. If this +* is less than @lnehgt, then the membuff got full +* +* @mb: membuff to adjust +* @data: the data to write +* @length: number of bytes to write from 'data' +* @return the number of bytes added +*/ +int membuff_put (struct membuff *mb,const char *buff,int length); + +/** +* membuff_isempty() - check if a membuff is empty +* +* @mb: membuff to check +* @return true if empty, else false +*/ +bool membuff_isempty (struct membuff *mb); + +/** +* membuff_avail() - check available data in a membuff +* +* @mb: membuff to check +* @return number of bytes of data available +*/ +int membuff_avail (struct membuff *mb); + +/** +* membuff_size() - get the size of a membuff +* +* Note that a membuff can only old data up to one byte less than its size. +* +* @mb: membuff to check +* @return total size +*/ +int membuff_size (struct membuff *mb); + +/** +* membuff_makecontig() - adjust all membuff data to be contiguous +* +* This places all data in a membuff into a single contiguous lump, if +* possible +* +* @mb: membuff to adjust +* @return true on success +*/ +bool membuff_makecontig (struct membuff *mb); + +/** +* membuff_free() - find the number of bytes that can be written to a membuff +* +* @mb: membuff to check +* @return returns the number of bytes free in a membuff +*/ +int membuff_free (struct membuff *mb); + +/** +* membuff_readline() - read a line of text from a membuff +* +* Reads a line of text of up to 'maxlen' characters from a membuff and puts +* it in @str. Any character less than @minch is assumed to be the end of +* line character +* +* @mb: membuff to adjust +* @str: Place to put the line +* @maxlen: Maximum line length (excluding terminator) +* @return number of bytes read (including terminator) if a line has been +* read, 0 if nothing was there +*/ +int membuff_readline (struct membuff *mb,char *str,int maxlen,int minch); + +/** +* membuff_extend_by() - expand a membuff +* +* Extends a membuff by the given number of bytes +* +* @mb: membuff to adjust +* @by: Number of bytes to increase the size by +* @max: Maximum size to allow +* @return 0 if the expand succeeded, -ENOMEM if not enough memory, -E2BIG +* if the the size would exceed @max +*/ +int membuff_extend_by (struct membuff *mb,int by,int max); + +/** +* membuff_init() - set up a new membuff using an existing membuff +* +* @mb: membuff to set up +* @buff: Address of buffer +* @size: Size of buffer +*/ +void membuff_init (struct membuff *mb,char *buff,int size); + +/** +* membuff_uninit() - clear a membuff so it can no longer be used +* +* @mb: membuff to uninit +*/ +void membuff_uninit (struct membuff *mb); + +/** +* membuff_new() - create a new membuff +* +* @mb: membuff to init +* @size: size of membuff to create +* @return 0 if OK, -ENOMEM if out of memory +*/ +int membuff_new (struct membuff *mb,int size); + +/** +* membuff_dispose() - free memory allocated to a membuff and uninit it +* +* @mb: membuff to dispose +*/ +void membuff_dispose (struct membuff *mb); + +#endif
lib/Makefile +1 -0
@@ -74,6 +74,7 @@ obj-y += div64.o obj-y += hang.o obj-y += linux_compat.o obj-y += linux_string.o +obj-y += membuff.o obj-$(CONFIG_REGEX) += slre.o obj-y += string.o obj-y += time.o
lib/membuff.c new file +390 -0
390 lines not on this page · raw message
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 5/26 Add a circular memory buffer implementation
Applied to u-boot-dm.
PATCH v2 6/26 console: Add a console buffer
In reply to Simon GlassIt is useful to be able to record console output and provide console input via a buffer. This provides sandbox with the ability to run a command and check its output. If the console is set to silent then no visible output is generated.
This also provides a means to fix the problem where tests produce unwanted output, such as errors or warnings. This can be confusing. We can instead set the console to silent and record this output. It can be checked later in the test if required.
It is possible that this may prove useful for non-test situations. For example the console output may be suppressed for normal operations, but recorded and stored for access by the OS. That feature is not implemented at present.
---
Changes in v2: None
common/Kconfig | 28 ++++++++++++++++++++++ common/board_f.c | 10 ++++++++ common/board_r.c | 10 ++++++++ common/console.c | 50 ++++++++++++++++++++++++++++++++++++++- include/asm-generic/global_data.h | 6 +++++ include/console.h | 22 +++++++++++++++++ 6 files changed, 125 insertions(+), 1 deletion(-)
common/Kconfig +28 -0
@@ -659,3 +659,31 @@ config CMD_TPM_TEST endmenu endmenu + +config CONSOLE_RECORD + bool "Console recording" + help + This provides a way to record console output (and provide console + input) through cirular buffers. This is mostly useful for testing. + Console output is recorded even when the console is silent. + To enable console recording, call console_record_reset_enable() + from your code. + +config CONSOLE_RECORD_OUT_SIZE + hex "Output buffer size" + depends on CONSOLE_RECORD + default 0x400 if CONSOLE_RECORD + help + Set the size of the console output buffer. When this fills up, no + more data will be recorded until some is removed. The buffer is + allocated immediately after the malloc() region is ready. + +config CONSOLE_RECORD_IN_SIZE + hex "Input buffer size" + depends on CONSOLE_RECORD + default 0x100 if CONSOLE_RECORD + help + Set the size of the console input buffer. When this contains data, + tstc() and getc() will use this in preference to real device input. + The buffer is allocated immediately after the malloc() region is + ready.
common/board_f.c +10 -0
@@ -737,6 +737,15 @@ static int mark_bootstage(void)return 0 ; } +static int initf_console_record (void ) +{ +#if defined(CONFIG_CONSOLE_RECORD ) && defined(CONFIG_SYS_MALLOC_F_LEN ) +return console_record_init (); +#else +return 0 ; +#endif +} +static int initf_dm (void ) {#if defined(CONFIG_DM ) && defined(CONFIG_SYS_MALLOC_F_LEN )
@@ -773,6 +782,7 @@ static init_fnc_t init_sequence_f[] = { trace_early_init, #endif initf_malloc, + initf_console_record, #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)/* TODO: can this go into arch_cpu_init()? */ probecpu,
common/board_r.c +10 -0
@@ -277,6 +277,15 @@ static int initr_malloc(void)return 0 ; } +static int initr_console_record (void ) +{ +#if defined(CONFIG_CONSOLE_RECORD ) +return console_record_init (); +#else +return 0 ; +#endif +} +#ifdef CONFIG_SYS_NONCACHED_MEMORY static int initr_noncached (void ) {
@@ -716,6 +725,7 @@ init_fnc_t init_sequence_r[] = {#endif initr_barrier, initr_malloc, + initr_console_record, #ifdef CONFIG_SYS_NONCACHED_MEMORY initr_noncached, #endif
common/console.c +49 -1
80 lines not on this page · raw message
include/asm-generic/global_data.h +6 -0
@@ -21,6 +21,7 @@*/ #ifndef __ASSEMBLY__ +#include <membuff.h> #include <linux/list.h> typedef struct global_data {
@@ -103,6 +104,10 @@ typedef struct global_data {#endif struct udevice *cur_serial_dev;/* current serial device */ struct arch_global_data arch;/* architecture-specific data */ +#ifdef CONFIG_CONSOLE_RECORD +struct membuff console_out;/* console output */ +struct membuff console_in;/* console input */ +#endif } gd_t;#endif
@@ -121,5 +126,6 @@ typedef struct global_data {#define GD_FLG_FULL_MALLOC_INIT 0x00200/* Full malloc() is ready */ #define GD_FLG_SPL_INIT 0x00400/* spl_init() has been called */ #define GD_FLG_SKIP_RELOC 0x00800/* Don't relocate */ +#define GD_FLG_RECORD 0x01000/* Record console */ #endif /* __ASM_GENERIC_GBL_DATA_H */
include/console.h +22 -0
@@ -20,6 +20,28 @@ void clear_ctrlc(void); /* clear the Control-C condition */int disable_ctrlc (int );/* 1 to disable, 0 to enable Control-C detect */ int confirm_yesno (void );/* 1 if input is "y", "Y", "yes" or "YES" */ +/** +* console_record_init() - set up the console recording buffers +* +* This should be called as soon as malloc() is available so that the maximum +* amount of console output can be recorded. +*/ +int console_record_init (void ); + +/** +* console_record_reset() - reset the console recording buffers +* +* Removes any data in the buffers +*/ +void console_record_reset (void ); + +/** +* console_record_reset_enable() - reset and enable the console buffers +* +* This should be called to enable the console buffer. +*/ +void console_record_reset_enable (void ); +/* * CONSOLE multiplexing. */
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 6/26 console: Add a console buffer
Applied to u-boot-dm.
PATCH v2 7/26 sandbox: Enable console recording and silent console
In reply to Simon GlassAllow console recording so that tests can use it. Also allow the console output to be suppressed, to reduce test output 'noise'.
---
Changes in v2: None
configs/sandbox_defconfig | 3 +++ include/configs/sandbox.h | 1 + 2 files changed, 4 insertions(+)
configs/sandbox_defconfig +3 -0
@@ -69,3 +69,6 @@ CONFIG_REMOTEPROC_SANDBOX=y CONFIG_CMD_REMOTEPROC=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y +CONFIG_CONSOLE_RECORD=y +CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000 +CONFIG_SYS_MALLOC_F_LEN=0x2000
include/configs/sandbox.h +1 -0
@@ -66,6 +66,7 @@#define CONFIG_SYS_HUSH_PARSER #define CONFIG_SYS_LONGHELP /* #undef to save memory */ #define CONFIG_SYS_CBSIZE 1024/* Console I/O Buffer Size */ +#define CONFIG_SILENT_CONSOLE /* Print Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 7/26 sandbox: Enable console recording and silent console
Applied to u-boot-dm.
PATCH v2 8/26 test: Record and silence console in tests
In reply to Simon GlassWhen running sandbox tests, silence the console to avoid unwanted output. Also, record the console in case tests want to check it.
The -v option can be used to enable stdout during tests.
---
Changes in v2: None
arch/sandbox/cpu/start.c | 8 ++++++++ arch/sandbox/include/asm/state.h | 1 + test/dm/test-main.c | 9 +++++++++ test/ut.c | 4 ++++ 4 files changed, 22 insertions(+)
arch/sandbox/cpu/start.c +8 -0
@@ -257,6 +257,14 @@ static int sandbox_cmdline_cb_terminal(struct sandbox_state *state,SANDBOX_CMDLINE_OPT_SHORT (terminal,'t' ,1 ,"Set terminal to raw/cooked mode" ); +static int sandbox_cmdline_cb_verbose (struct sandbox_state *state, +const char *arg) +{ + state->show_test_output = true; +return 0 ; +} +SANDBOX_CMDLINE_OPT_SHORT (verbose,'v' ,0 ,"Show test output" ); +int main (int argc,char *argv[]) {struct sandbox_state *state;
arch/sandbox/include/asm/state.h +1 -0
@@ -64,6 +64,7 @@ struct sandbox_state {bool reset_allowed[RESET_COUNT ];/* Allowed reset types */ enum state_terminal_raw term_raw;/* Terminal raw/cooked */ bool skip_delays;/* Ignore any time delays (for test) */ +bool show_test_output;/* Don't suppress stdout in tests */ /* Pointer to information for each SPI bus/cs */ struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS ]
test/dm/test-main.c +9 -0
@@ -76,6 +76,7 @@ static int dm_test_main(const char *test_name) struct unit_test *tests = ll_entry_start(struct unit_test, dm_test); const int n_ents = ll_entry_count(struct unit_test, dm_test);struct unit_test_state *uts = &global_dm_test_state; +struct sandbox_state *state =state_get_current (); uts->priv = &_global_priv_dm_test_state;struct unit_test *test;int run_count;
@@ -114,7 +115,15 @@ static int dm_test_main(const char *test_name)if (test->flags &DM_TESTF_SCAN_FDT )ut_assertok (dm_scan_fdt (gd->fdt_blob, false)); +/* +* Silence the console and rely on console reocrding to get +* our output. +*/ +console_record_reset (); +if (!state->show_test_output) + gd->flags |=GD_FLG_SILENT ; test->func (uts); + gd->flags &= ~GD_FLG_SILENT ;state_set_skip_delays (false);ut_assertok (dm_test_destroy (uts));
test/ut.c +4 -0
@@ -10,9 +10,12 @@#include <test/test.h> #include <test/ut.h> +DECLARE_GLOBAL_DATA_PTR ; +void ut_fail (struct unit_test_state *uts,const char *fname,int line,const char *func,const char *cond) { + gd->flags &= ~(GD_FLG_SILENT |GD_FLG_RECORD );printf ("%s:%d, %s(): %s\n" , fname, line, func, cond); uts->fail_count++; }
@@ -22,6 +25,7 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line, {va_list args; + gd->flags &= ~(GD_FLG_SILENT |GD_FLG_RECORD );printf ("%s:%d, %s(): %s: " , fname, line, func, cond);va_start (args, fmt);vprintf (fmt, args);
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 8/26 test: Record and silence console in tests
Applied to u-boot-dm.
PATCH v2 9/26 usb: Refactor USB tree output code for testing
In reply to Simon GlassAllow the 'usb tree' command to be used from test code, so that we can verify that it works correctly.
---
Changes in v2: None
common/cmd_usb.c | 58 ++++++++++++++++++++++++++++++++------------------------ include/usb.h | 8 ++++++++ 2 files changed, 41 insertions(+), 25 deletions(-)
common/cmd_usb.c +33 -25
@@ -429,7 +429,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) }/* main routine for the tree command */ -static void usb_show_tree (struct usb_device *dev) +static void usb_show_subtree (struct usb_device *dev) {char preamble[32 ];
@@ -437,6 +437,37 @@ static void usb_show_tree(struct usb_device *dev)usb_show_tree_graph (dev, &preamble[0 ]); } +void usb_show_tree (void ) +{ +#ifdef CONFIG_DM_USB +struct udevice *bus; + +for (uclass_first_device (UCLASS_USB , &bus); + bus; +uclass_next_device (&bus)) { +struct usb_device *udev; +struct udevice *dev; + +device_find_first_child (bus, &dev); +if (dev &&device_active (dev)) { + udev =dev_get_parent_priv (dev); +usb_show_subtree (udev); + } + } +#else +struct usb_device *udev; +int i; + +for (i =0 ; i <USB_MAX_DEVICE ; i++) { + udev =usb_get_dev_index (i); +if (udev ==NULL ) +break ; +if (udev->parent ==NULL ) +usb_show_subtree (udev); + } +#endif +} +static int usb_test (struct usb_device *dev,int port,char * arg) {int mode;
@@ -631,30 +662,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) }if (strncmp (argv[1 ],"tree" ,4 ) ==0 ) {puts ("USB device tree:\n" ); -#ifdef CONFIG_DM_USB -struct udevice *bus; - -for (uclass_first_device (UCLASS_USB , &bus); - bus; -uclass_next_device (&bus)) { -struct usb_device *udev; -struct udevice *dev; - -device_find_first_child (bus, &dev); -if (dev &&device_active (dev)) { - udev =dev_get_parent_priv (dev); -usb_show_tree (udev); - } - } -#else -for (i =0 ; i <USB_MAX_DEVICE ; i++) { - udev =usb_get_dev_index (i); -if (udev ==NULL ) -break ; -if (udev->parent ==NULL ) -usb_show_tree (udev); - } -#endif +usb_show_tree ();return 0 ; }if (strncmp (argv[1 ],"inf" ,3 ) ==0 ) {
include/usb.h +8 -0
@@ -957,4 +957,12 @@ int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp);*/ void usb_emul_reset (struct udevice *dev); +/** +* usb_show_tree() - show the USB device tree +* +* This shows a list of active USB devices along with basic information about +* each. +*/ +void usb_show_tree (void ); +#endif /*_USB_H_ */
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 9/26 usb: Refactor USB tree output code for testing
Applied to u-boot-dm.
PATCH v2 10/26 dm: core: Add safe device iteration macros
In reply to Simon GlassAdd iteration macros which support unbinding a device within the loop.
---
Changes in v2: None
include/dm/device.h | 12 ++++++++++++ include/dm/uclass.h | 15 +++++++++++++++ 2 files changed, 27 insertions(+)
include/dm/device.h +12 -0
@@ -509,6 +509,18 @@ static inline bool device_is_on_pci_bus(struct udevice *dev)return device_get_uclass_id (dev->parent) ==UCLASS_PCI ; } +/** +* device_foreach_child_safe() - iterate through child devices safely +* +* This allows the @pos child to be removed in the loop if required. +* +* @pos: struct udevice * for the current device +* @next: struct udevice * for the next device +* @parent: parent device to scan +*/ +#define device_foreach_child_safe (pos, next, parent) \ + list_for_each_entry_safe(pos, next, &parent->child_head, sibling_node) +/* device resource management */ typedef void (*dr_release_t )(struct udevice *dev,void *res);typedef int (*dr_match_t )(struct udevice *dev,void *res,void *match_data);
include/dm/uclass.h +15 -0
@@ -243,4 +243,19 @@ int uclass_resolve_seq(struct udevice *dev);#define uclass_foreach_dev (pos, uc) \ list_for_each_entry(pos, &uc->dev_head, uclass_node) +/** +* uclass_foreach_dev_safe() - Helper function to safely iteration through devs +* +* This creates a for() loop which works through the available devices in +* a uclass in order from start to end. Inside the loop, it is safe to remove +* @pos if required. +* +* @pos: struct udevice * to hold the current device. Set to NULL when there +* are no more devices. +* @next: struct udevice * to hold the next next +* @uc: uclass to scan +*/ +#define uclass_foreach_dev_safe (pos, next, uc) \ + list_for_each_entry_safe(pos, next, &uc->dev_head, uclass_node) +#endif
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 10/26 dm: core: Add safe device iteration macros
Applied to u-boot-dm.
PATCH v2 11/26 sandbox: usb: Allow dynamic emulated USB device descriptors
In reply to Simon GlassWe would like the serial number to come from the device tree node name of the emulated device. This avoids them all having the same name. Adjust the code to support this.
---
Changes in v2: None
drivers/usb/emul/sandbox_flash.c | 48 +++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 20 deletions(-)
drivers/usb/emul/sandbox_flash.c +28 -20
@@ -31,6 +31,14 @@ enum cmd_phase { PHASE_STATUS, }; +enum { +STRINGID_MANUFACTURER =1 , +STRINGID_PRODUCT , +STRINGID_SERIAL , + +STRINGID_COUNT , +}; +/** * struct sandbox_flash_priv - private state for this driver *
@@ -61,6 +69,7 @@ struct sandbox_flash_priv {struct sandbox_flash_plat {const char *pathname; +struct usb_string flash_strings[STRINGID_COUNT ]; };struct scsi_inquiry_resp {
@@ -89,21 +98,6 @@ struct __packed scsi_read10_req {u8 spare2[3 ]; }; -enum { -STRINGID_MANUFACTURER =1 , -STRINGID_PRODUCT , -STRINGID_SERIAL , - -STRINGID_COUNT , -}; - -static struct usb_string flash_strings[] = { - {STRINGID_MANUFACTURER ,"sandbox" }, - {STRINGID_PRODUCT ,"flash" }, - {STRINGID_SERIAL ,"2345" }, - {}, -}; -static struct usb_device_descriptor flash_device_desc = { .bLength =sizeof (flash_device_desc), .bDescriptorType =USB_DT_DEVICE ,
@@ -246,7 +240,8 @@ static void handle_read(struct sandbox_flash_priv *priv, ulong lba, } } -static int handle_ufi_command (struct sandbox_flash_priv *priv,const void *buff, +static int handle_ufi_command (struct sandbox_flash_plat *plat, +struct sandbox_flash_priv *priv,const void *buff,int len) {const struct SCSI_cmd_block *req = buff;
@@ -260,9 +255,10 @@ static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff, resp->data_format =1 ; resp->additional_len =0x1f ;strncpy (resp->vendor, - flash_strings[STRINGID_MANUFACTURER -1 ].s, + plat->flash_strings[STRINGID_MANUFACTURER -1 ].s,sizeof (resp->vendor)); -strncpy (resp->product, flash_strings[STRINGID_PRODUCT -1 ].s, +strncpy (resp->product, + plat->flash_strings[STRINGID_PRODUCT -1 ].s,sizeof (resp->product));strncpy (resp->revision,"1.0" ,sizeof (resp->revision));setup_response (priv, resp,sizeof (*resp));
@@ -303,6 +299,7 @@ static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff,static int sandbox_flash_bulk (struct udevice *dev,struct usb_device *udev,unsigned long pipe,void *buff,int len) { +struct sandbox_flash_plat *plat =dev_get_platdata (dev);struct sandbox_flash_priv *priv =dev_get_priv (dev);int ep =usb_pipeendpoint (pipe);struct umass_bbb_cbw *cbw = buff;
@@ -325,7 +322,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, goto err; priv->transfer_len = cbw->dCBWDataTransferLength; priv->tag = cbw->dCBWTag; -return handle_ufi_command (priv, cbw->CBWCDB, +return handle_ufi_command (plat, priv, cbw->CBWCDB, cbw->bCDBLength);case PHASE_DATA :debug ("data out\n" );
@@ -384,7 +381,18 @@ static int sandbox_flash_ofdata_to_platdata(struct udevice *dev)static int sandbox_flash_bind (struct udevice *dev) { -return usb_emul_setup_device (dev,PACKET_SIZE_64 , flash_strings, +struct sandbox_flash_plat *plat =dev_get_platdata (dev); +struct usb_string *fs; + + fs = plat->flash_strings; + fs[0 ].id =STRINGID_MANUFACTURER ; + fs[0 ].s ="sandbox" ; + fs[1 ].id =STRINGID_PRODUCT ; + fs[1 ].s ="flash" ; + fs[2 ].id =STRINGID_SERIAL ; + fs[2 ].s = dev->name; + +return usb_emul_setup_device (dev,PACKET_SIZE_64 , plat->flash_strings, flash_desc_list); }
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 11/26 sandbox: usb: Allow dynamic emulated USB device descriptors
Applied to u-boot-dm.
PATCH v2 12/26 sandbox: usb: Allow up to 4 emulated devices on a hub
In reply to Simon GlassTo support more advanced testing, support 4 devices instead of 2.
---
Changes in v2: None
drivers/usb/emul/sandbox_hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/emul/sandbox_hub.c +1 -1
@@ -13,7 +13,7 @@DECLARE_GLOBAL_DATA_PTR ;/* We only support up to 8 */ -#define SANDBOX_NUM_PORTS 2 +#define SANDBOX_NUM_PORTS 4struct sandbox_hub_platdata {struct usb_dev_platdata plat;
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 12/26 sandbox: usb: Allow up to 4 emulated devices on a hub
Applied to u-boot-dm.
PATCH v2 13/26 sandbox: usb: Allow finding a USB emulator for a device
In reply to Simon GlassEach USB device has an emulator. Currently this can only be found by supplying the 'pipe' value, which contains the device number. Add a way to find it directly from the emulated device.
---
Changes in v2: None
drivers/usb/emul/usb-emul-uclass.c | 17 +++++++++++++++-- include/usb.h | 10 ++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-)
drivers/usb/emul/usb-emul-uclass.c +15 -2
@@ -108,9 +108,8 @@ static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value,return upto ? upto : length ? -EIO :0 ; } -int usb_emul_find (struct udevice *bus,ulong pipe,struct udevice **emulp) +static int usb_emul_find_devnum (int devnum,struct udevice **emulp) { -int devnum =usb_pipedevice (pipe);struct udevice *dev;struct uclass *uc;int ret;
@@ -134,6 +133,20 @@ int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp)return -ENOENT ; } +int usb_emul_find (struct udevice *bus,ulong pipe,struct udevice **emulp) +{ +int devnum =usb_pipedevice (pipe); + +return usb_emul_find_devnum (devnum, emulp); +} + +int usb_emul_find_for_dev (struct udevice *dev,struct udevice **emulp) +{ +struct usb_dev_platdata *udev =dev_get_parent_platdata (dev); + +return usb_emul_find_devnum (udev->devnum, emulp); +} +int usb_emul_control (struct udevice *emul,struct usb_device *udev,unsigned long pipe,void *buffer,int length,struct devrequest *setup)
include/usb.h +10 -0
@@ -950,6 +950,16 @@ int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,int usb_emul_find (struct udevice *bus,ulong pipe,struct udevice **emulp);/** +* usb_emul_find_for_dev() - Find an emulator for a particular device +* +* @bus: USB bus (controller) +* @dev: USB device to check +* @emulp: Returns pointer to emulator, or NULL if not found +* @return 0 if found, -ve on error +*/ +int usb_emul_find_for_dev (struct udevice *dev,struct udevice **emulp); + +/** * usb_emul_reset() - Reset all emulators ready for use * * Clear out any address information in the emulators and make then ready for
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 13/26 sandbox: usb: Allow finding a USB emulator for a device
Applied to u-boot-dm.
PATCH v2 14/26 Revert "dm: usb: Rename usb_find_child to usb_find_emul_child"
In reply to Simon GlassThis reverts commit 9b510df703d282effba4f56ac567aa8011d56e6b.
We want to avoid having the USB stack rely on unbind.
---
Changes in v2: None
drivers/usb/host/usb-uclass.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
drivers/usb/host/usb-uclass.c +10 -9
@@ -494,14 +494,15 @@ error: }/** -* usb_find_emul_child() - Find an existing device for emulated devices +* usb_find_child() - Find an existing device which matches our needs +* +* */ -static int usb_find_emul_child (struct udevice *parent, -struct usb_device_descriptor *desc, -struct usb_interface_descriptor *iface, -struct udevice **devp) +static int usb_find_child (struct udevice *parent, +struct usb_device_descriptor *desc, +struct usb_interface_descriptor *iface, +struct udevice **devp) { -#ifdef CONFIG_SANDBOX struct udevice *dev; *devp =NULL ;
@@ -520,7 +521,7 @@ static int usb_find_emul_child(struct udevice *parent,return 0 ; } } -#endif +return -ENOENT ; }
@@ -580,8 +581,8 @@ int usb_scan_device(struct udevice *parent, int port,debug ("read_descriptor for '%s': ret=%d\n" , parent->name, ret);if (ret)return ret; - ret =usb_find_emul_child (parent, &udev->descriptor, iface, &dev); -debug ("** usb_find_emul_child returns %d\n" , ret); + ret =usb_find_child (parent, &udev->descriptor, iface, &dev); +debug ("** usb_find_child returns %d\n" , ret);if (ret) {if (ret != -ENOENT )return ret;
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 14/26 Revert "dm: usb: Rename usb_find_child to usb_find_emul_child"
Applied to u-boot-dm.
PATCH v2 15/26 Revert "dm: usb: Use device_unbind_children to clean up usb devs on stop"
In reply to Simon GlassThis reverts commit 6cda369509e0d3fa5f9e33c9d71589c4523799fa.
We want to avoid having the USB stack rely on unbind.
---
Changes in v2: None
drivers/usb/host/usb-uclass.c | 3 --- 1 file changed, 3 deletions(-)
drivers/usb/host/usb-uclass.c +0 -3
@@ -158,9 +158,6 @@ int usb_stop(void) ret =device_remove (bus);if (ret && !err) err = ret; - ret =device_unbind_children (bus); -if (ret && !err) - err = ret; }#ifdef CONFIG_SANDBOX
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 15/26 Revert "dm: usb: Use device_unbind_children to clean up usb devs on stop"
Applied to u-boot-dm.
PATCH v2 16/26 Revert "dm: Export device_remove_children / device_unbind_children"
In reply to Simon GlassThis reverts commit bb52b367f6ca4a3a918e77737f4ff6a1089912d9.
---
Changes in v2: None
drivers/core/device-remove.c | 22 ++++++++++++++++++---- include/dm/device-internal.h | 26 -------------------------- 2 files changed, 18 insertions(+), 30 deletions(-)
drivers/core/device-remove.c +18 -4
@@ -18,7 +18,16 @@#include <dm/uclass-internal.h> #include <dm/util.h> -int device_unbind_children (struct udevice *dev) +/** +* device_chld_unbind() - Unbind all device's children from the device +* +* On error, the function continues to unbind all children, and reports the +* first error. +* +* @dev: The device that is to be stripped of its children +* @return 0 on success, -ve on error +*/ +static int device_chld_unbind (struct udevice *dev) {struct udevice *pos, *n;int ret, saved_ret =0 ;
@@ -34,7 +43,12 @@ int device_unbind_children(struct udevice *dev)return saved_ret; } -int device_remove_children (struct udevice *dev) +/** +* device_chld_remove() - Stop all device's children +* @dev: The device whose children are to be removed +* @return 0 on success, -ve on error +*/ +static int device_chld_remove (struct udevice *dev) {struct udevice *pos, *n;int ret;
@@ -73,7 +87,7 @@ int device_unbind(struct udevice *dev)return ret; } - ret =device_unbind_children (dev); + ret =device_chld_unbind (dev);if (ret)return ret;
@@ -153,7 +167,7 @@ int device_remove(struct udevice *dev)if (ret)return ret; - ret =device_remove_children (dev); + ret =device_chld_remove (dev);if (ret) goto err;
include/dm/device-internal.h +0 -26
@@ -107,32 +107,6 @@ int device_unbind(struct udevice *dev);static inline int device_unbind (struct udevice *dev) {return 0 ; }#endif -/** -* device_remove_children() - Stop all device's children -* @dev: The device whose children are to be removed -* @return 0 on success, -ve on error -*/ -#if CONFIG_IS_ENABLED (DM_DEVICE_REMOVE ) -int device_remove_children (struct udevice *dev); -#else -static inline int device_remove_children (struct udevice *dev) {return 0 ; } -#endif - -/** -* device_unbind_children() - Unbind all device's children from the device -* -* On error, the function continues to unbind all children, and reports the -* first error. -* -* @dev: The device that is to be stripped of its children -* @return 0 on success, -ve on error -*/ -#if CONFIG_IS_ENABLED (DM_DEVICE_REMOVE ) -int device_unbind_children (struct udevice *dev); -#else -static inline int device_unbind_children (struct udevice *dev) {return 0 ; } -#endif -#if CONFIG_IS_ENABLED (DM_DEVICE_REMOVE )void device_free (struct udevice *dev);#else
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 16/26 Revert "dm: Export device_remove_children / device_unbind_children"
Applied to u-boot-dm.
PATCH v2 17/26 dm: usb: Deprecate usb_get_dev_index()
In reply to Simon GlassThis function should not be used with driver model. While there are users of USB Ethernet that use driver model for USB but not Ethernet, we have to keep it around. Add a comment to that effect.
---
Changes in v2: None
drivers/usb/host/usb-uclass.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/host/usb-uclass.c +9 -0
@@ -279,6 +279,14 @@ int usb_init(void)return usb_started ?0 :-1 ; } +/* +* TODO(sjg at chromium.org): Remove this legacy function. At present it is needed +* to support boards which use driver model for USB but not Ethernet, and want +* to use USB Ethernet. +* +* The #if clause is here to ensure that remains the only case. +*/ +#if !defined(CONFIG_DM_ETH ) && defined(CONFIG_USB_HOST_ETHER )static struct usb_device *find_child_devnum (struct udevice *parent,int devnum) {struct usb_device *udev;
@@ -312,6 +320,7 @@ struct usb_device *usb_get_dev_index(struct udevice *bus, int index) return find_child_devnum(dev, devnum); } +#endif int usb_post_bind (struct udevice *dev) {
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 17/26 dm: usb: Deprecate usb_get_dev_index()
Applied to u-boot-dm.
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
In reply to Simon GlassEach scan of the USB bus may return different results. Existing driver-model devices are reused when found, but if a device no longer exists it will stay around, de-activated, but bound.
Detect these devices and remove them after the scan completes.
---
Changes in v2: None
drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/usb/host/usb-uclass.c +23 -0
@@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse)printf ("%d USB Device(s) found\n" , priv->next_addr); } +static void remove_inactive_children (struct uclass *uc,struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { +struct udevice *dev, *next; + +if (!device_active (bus)) +continue ; + device_foreach_child_safe(dev, next, bus) { +if (!device_active (dev)) +device_unbind (dev); + } + } +} +int usb_init (void ) {int controllers_initialized =0 ;
@@ -270,6 +284,15 @@ int usb_init(void) }debug ("scan end\n" ); + +/* Remove any devices that were not found on this scan */ +remove_inactive_children (uc, bus); + + ret =uclass_get (UCLASS_USB_HUB , &uc); +if (ret) +return ret; +remove_inactive_children (uc, bus); +/* if we were not able to find at least one working bus, bail out */ if (!count)printf ("No controllers found\n" );
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi,
Quoted 7 lines · Simon Glass
Each scan of the USB bus may return different results. Existing driver-model devices are reused when found, but if a device no longer exists it will stay around, de-activated, but bound.
Detect these devices and remove them after the scan completes.
Signed-off-by Simon Glass <[email protected]>
I wonder how this is better then my original:
"dm: usb: Use device_unbind_children to clean up usb devs on stop"
Patch, the end result of both patches is the same and both are a NOP when DM_DEVICE_REMOVE is not set. Where as my code seems to be a much more KISS approach to the problem (my approach is just 3 lines vs 23 lines for yours).
I know we will need usb_find_child in the DM_DEVICE_REMOVE not set case, but why not only revert the:
"dm: usb: Rename usb_find_child to usb_find_emul_child"
commit, keep the other 2 you revert and drop this patch ?
This drops 3 patches from your patch-set and the end result is more clean IMHO.
Quoted 33 lines
Changes in v2: None
drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)drivers/usb/host/usb-uclass.c +14
-0@@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse)printf ("%d USB Device(s) found\n" , priv->next_addr); } +static void remove_inactive_children (struct uclass *uc,struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { +struct udevice *dev, *next; + +if (!device_active (bus)) +continue ; + device_foreach_child_safe(dev, next, bus) { +if (!device_active (dev)) +device_unbind (dev); + } + } +} +int usb_init (void ) {int controllers_initialized =0 ;@@ -270,6 +284,15 @@ int usb_init(void) }
drivers/usb/host/usb-uclass.c int usb_init(void) · line 295
Quoted 10 lines
drivers/usb/host/usb-uclass.c +9
-0debug ("scan end\n" ); + +/* Remove any devices that were not found on this scan */ +remove_inactive_children (uc, bus); + + ret =uclass_get (UCLASS_USB_HUB , &uc); +if (ret) +return ret; +remove_inactive_children (uc, bus); +
Why do you need to call remove_inactive_children twice here? This seems worthy of a comment explaining why this is necessary.
drivers/usb/host/usb-uclass.c int usb_init(void) · line 298
Quoted 4 lines
drivers/usb/host/usb-uclass.c +0
-0/* if we were not able to find at least one working bus, bail out */ if (!count)printf ("No controllers found\n" );
Regards,
Hans
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi Hans,
Quoted 26 lines · Hans de Goede
Hi,
Quoted 10 lines · Simon Glass
Each scan of the USB bus may return different results. Existing driver-model
devices are reused when found, but if a device no longer exists it will stay
around, de-activated, but bound.Detect these devices and remove them after the scan completes.
Signed-off-by Simon Glass <[email protected]>I wonder how this is better then my original:
"dm: usb: Usedevice_unbind_childrento clean up usb devs on stop"Patch, the end result of both patches is the same and both are a NOP when
DM_DEVICE_REMOVEis not set. Where as my code seems to be a much more KISS approach to the problem (my approach is just 3 lines vs 23 lines for yours).I know we will need
usb_find_childin theDM_DEVICE_REMOVEnot set case, but why not only revert the:
Quoted 6 lines
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, keep the other 2 you revert and drop this patch ?
This drops 3 patches from your patch-set and the end result is more clean IMHO.
I would like to avoid binding/unbinding things when nothing changes if possible. Also I'd like to support attaching device tree nodes/properties to USB devices as necessary, as we do with PCI, and removing things breaks that.
I still have to figure out one more test case, so I'll do that before commenting further.
Quoted 37 lines
Quoted 37 lines
Changes in v2: None
drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)drivers/usb/host/usb-uclass.c +14
-0@@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) printf("%d USB Device(s) found\n", priv->next_addr); } +static void remove_inactive_children (struct uclass *uc,struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { +struct udevice *dev, *next; + +if (!device_active (bus)) +continue ; + device_foreach_child_safe(dev, next, bus) { +if (!device_active (dev)) +device_unbind (dev); + } + } +} +int usb_init (void ){ int controllers_initialized = 0;drivers/usb/host/usb-uclass.c +0
-0@@ -270,6 +284,15 @@ int usb_init(void) }
Quoted 14 lines
drivers/usb/host/usb-uclass.c int usb_init(void) · line 295
Quoted 10 lines
drivers/usb/host/usb-uclass.c +9
-0debug ("scan end\n" ); + +/* Remove any devices that were not found on this scan */ +remove_inactive_children (uc, bus); + + ret =uclass_get (UCLASS_USB_HUB , &uc); +if (ret) +return ret; +remove_inactive_children (uc, bus); +Why do you need to call
remove_inactive_childrentwice here? This seems worthy of a comment explaining why this is necessary.
One is removing the children of USB controllers, one is removing the children of USB hubs. I'll add a comment.
Quoted 5 lines
Quoted 5 lines
drivers/usb/host/usb-uclass.c +0
-0/* if we were not able to find at least one working bus, bail out */ if (!count)printf("No controllers found\n");
Regards,
Simon
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi Hans,
Quoted 36 lines · Simon Glass
Hi Hans,
Quoted 26 lines · Hans de Goede
Hi,
Quoted 10 lines · Simon Glass
Each scan of the USB bus may return different results. Existing driver-model
devices are reused when found, but if a device no longer exists it will stay
around, de-activated, but bound.Detect these devices and remove them after the scan completes.
Signed-off-by Simon Glass <[email protected]>I wonder how this is better then my original:
"dm: usb: Usedevice_unbind_childrento clean up usb devs on stop"Patch, the end result of both patches is the same and both are a NOP when
DM_DEVICE_REMOVEis not set. Where as my code seems to be a much more KISS approach to the problem (my approach is just 3 lines vs 23 lines for yours).I know we will need
usb_find_childin theDM_DEVICE_REMOVEnot set case, but why not only revert the:Quoted 6 lines
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, keep the other 2 you revert and drop this patch ?
This drops 3 patches from your patch-set and the end result is more clean IMHO.
Quoted 7 lines
I would like to avoid binding/unbinding things when nothing changes if possible. Also I'd like to support attaching device tree nodes/properties to USB devices as necessary, as we do with PCI, and removing things breaks that.
I still have to figure out one more test case, so I'll do that before commenting further.
I've added the test case and pushed a new tree. However it turns out that this doesn't behave differently.
So please can you go ahead and run your original (manual) test case? I'd like to make sure that my automated tests are correct and catch the bug you reported and fixed.
Quoted 64 lines
Quoted 38 lines
Quoted 38 lines
Changes in v2: None
drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)drivers/usb/host/usb-uclass.c +14
-0@@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) printf("%d USB Device(s) found\n", priv->next_addr); } +static void remove_inactive_children (struct uclass *uc,struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { +struct udevice *dev, *next; + +if (!device_active (bus)) +continue ; + device_foreach_child_safe(dev, next, bus) { +if (!device_active (dev)) +device_unbind (dev); + } + } +} +int usb_init (void ){ int controllers_initialized = 0;drivers/usb/host/usb-uclass.c +0
-0@@ -270,6 +284,15 @@ int usb_init(void) }Quoted 14 lines
drivers/usb/host/usb-uclass.c int usb_init(void) · line 295
Quoted 10 lines
drivers/usb/host/usb-uclass.c +9
-0debug ("scan end\n" ); + +/* Remove any devices that were not found on this scan */ +remove_inactive_children (uc, bus); + + ret =uclass_get (UCLASS_USB_HUB , &uc); +if (ret) +return ret; +remove_inactive_children (uc, bus); +Why do you need to call
remove_inactive_childrentwice here? This seems worthy of a comment explaining why this is necessary.One is removing the children of USB controllers, one is removing the children of USB hubs. I'll add a comment.
Quoted 5 lines
Quoted 5 lines
drivers/usb/host/usb-uclass.c +0
-0/* if we were not able to find at least one working bus, bail out */ if (!count)printf("No controllers found\n");Regards,
Simon
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi,
Quoted 47 lines · Simon Glass
Hi Hans,
Quoted 36 lines · Simon Glass
Hi Hans,
Quoted 26 lines · Hans de Goede
Hi,
Quoted 10 lines · Simon Glass
Each scan of the USB bus may return different results. Existing driver-model
devices are reused when found, but if a device no longer exists it will stay
around, de-activated, but bound.Detect these devices and remove them after the scan completes.
Signed-off-by Simon Glass <[email protected]>I wonder how this is better then my original:
"dm: usb: Usedevice_unbind_childrento clean up usb devs on stop"Patch, the end result of both patches is the same and both are a NOP when
DM_DEVICE_REMOVEis not set. Where as my code seems to be a much more KISS approach to the problem (my approach is just 3 lines vs 23 lines for yours).I know we will need
usb_find_childin theDM_DEVICE_REMOVEnot set case, but why not only revert the:Quoted 6 lines
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, keep the other 2 you revert and drop this patch ?
This drops 3 patches from your patch-set and the end result is more clean IMHO.
Quoted 7 lines
I would like to avoid binding/unbinding things when nothing changes if possible. Also I'd like to support attaching device tree nodes/properties to USB devices as necessary, as we do with PCI, and removing things breaks that.
I still have to figure out one more test case, so I'll do that before commenting further.
Quoted 6 lines
I've added the test case and pushed a new tree. However it turns out that this doesn't behave differently.
So please can you go ahead and run your original (manual) test case? I'd like to make sure that my automated tests are correct and catch the bug you reported and fixed.
Ok, I've ran a whole battery of tests on your u-boot-dm/usb-working branch.
There are 2 issues:
1) You need to add these change to the commit introducing usb-keyb dm support (or one of the related commits), otherwise usb-keyb support breaks:
arch/arm/Kconfig +1 -0
@@ -513,6 +513,7 @@ config ARCH_SUNXI select DM select DM_GPIO select DM_ETH + select DM_KEYBOARD select DM_SERIAL select DM_USB select OF_CONTROL
The breakage is that without this usb_scan_device() returns -96 (EPFNOSUPPORT) for usb keyboards.
2) With that branch there still is the purely cosmetical issue, that if one plugs a usb-stick + keyb into the same hub, then swaps their place and do "usb reset" and then "usb tree" looks like this:
USB device tree:
1 Hub (480 Mb/s, 100mA)
| USB2.0 Hub
|
+-3 Human Interface (1.5 Mb/s, 100mA) | SINO WEALTH USB Composite Device | +-2 Mass Storage (480 Mb/s, 100mA)
USB Flash Disk 4C0E960F
Notice the order of devices listed: 1 - 3 - 2, which is a bit weird, as said this is purely cosmetical.
Note you can easily fix this by only reverting the:
"dm: usb: Rename usb_find_child to usb_find_emul_child"
commit, and keep the other 2 you revert and dropping this patch ?
As I already suggested before, this is both more KISS and as you can see it solves some actually (admittedly very minor) issues.
I'm not really buying your arguments for your more complex solution, as shown above re-using the devices actually causes issues.
Your other argument of wanting to attach device-tree properties I also do not find a strong argument, for one there has never been a need to do so sofar, and if we ever need this we need a way to specify which usb-device the properties belong to based on the topology under the host / root-hub anyway, and match things up when first scanning the bus. And if we can match things up on the first scan we can also match them up on subsequent scans and attach the same of-node again.
Anyways I'm fine with doing things your way, but I still have a preference for the more KISS and IMHO robust solution of simple unbinding all devices on usb-stop.
###
Talking about usb-stop, there is still one (BIG!) problem after this patch set when building usb-support with DM_DEVICE_REMOVE not set. This means that the controllers dma engines will not be stopped when booting the actual OS and they will still be accessing parts of the main memory while the actual OS is booting, which is BAD. So I suggest adding something like this to all host drivers which use dma in this way:
#if defined CONFIG_DM_USB && !defined CONFIG_DM_DEVICE_REMOVE
#error The EHCI driver cannot be used without CONFIG_DM_DEVICE_REMOVE otherwise DMA stays active while booting the OS #endif
Regards,
Hans
Quoted 65 lines
Quoted 65 lines
Quoted 39 lines
Quoted 39 lines
Changes in v2: None
drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)drivers/usb/host/usb-uclass.c +14
-0@@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) printf("%d USB Device(s) found\n", priv->next_addr); } +static void remove_inactive_children (struct uclass *uc,struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { +struct udevice *dev, *next; + +if (!device_active (bus)) +continue ; + device_foreach_child_safe(dev, next, bus) { +if (!device_active (dev)) +device_unbind (dev); + } + } +} +int usb_init (void ){ int controllers_initialized = 0;drivers/usb/host/usb-uclass.c +0
-0@@ -270,6 +284,15 @@ int usb_init(void) }Quoted 14 lines
drivers/usb/host/usb-uclass.c int usb_init(void) · line 295
Quoted 10 lines
drivers/usb/host/usb-uclass.c +9
-0debug ("scan end\n" ); + +/* Remove any devices that were not found on this scan */ +remove_inactive_children (uc, bus); + + ret =uclass_get (UCLASS_USB_HUB , &uc); +if (ret) +return ret; +remove_inactive_children (uc, bus); +Why do you need to call
remove_inactive_childrentwice here? This seems worthy of a comment explaining why this is necessary.One is removing the children of USB controllers, one is removing the children of USB hubs. I'll add a comment.
Quoted 5 lines
Quoted 5 lines
drivers/usb/host/usb-uclass.c +0
-0/* if we were not able to find at least one working bus, bail out */ if (!count)printf("No controllers found\n");Regards,
Simon
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi Hans,
Quoted 62 lines · Hans de Goede
Hi,
Quoted 57 lines · Simon Glass
Hi Hans,
Quoted 41 lines · Simon Glass
Hi Hans,
Quoted 29 lines · Hans de Goede
Hi,
Quoted 11 lines · Simon Glass
Each scan of the USB bus may return different results. Existing driver-model
devices are reused when found, but if a device no longer exists it will stay
around, de-activated, but bound.Detect these devices and remove them after the scan completes.
Signed-off-by Simon Glass <[email protected]>I wonder how this is better then my original:
"dm: usb: Usedevice_unbind_childrento clean up usb devs on stop"Patch, the end result of both patches is the same and both are a NOP when
DM_DEVICE_REMOVEis not set. Where as my code seems to be a much more KISS approach to the problem (my approach is just 3 lines vs 23 lines for yours).I know we will need
usb_find_childin theDM_DEVICE_REMOVEnot set case, but why not only revert the:Quoted 6 lines
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, keep the other 2 you revert and drop this patch ?
This drops 3 patches from your patch-set and the end result is more clean IMHO.
Quoted 7 lines
I would like to avoid binding/unbinding things when nothing changes if possible. Also I'd like to support attaching device tree nodes/properties to USB devices as necessary, as we do with PCI, and removing things breaks that.
I still have to figure out one more test case, so I'll do that before commenting further.
I've added the test case and pushed a new tree. However it turns out that this doesn't behave differently.
Quoted 6 lines
Quoted 3 lines
So please can you go ahead and run your original (manual) test case? I'd like to make sure that my automated tests are correct and catch the bug you reported and fixed.
Ok, I've ran a whole battery of tests on your u-boot-dm/usb-working branch.
Thanks!
Quoted 18 lines
There are 2 issues:
1) You need to add these change to the commit introducing usb-keyb dm support (or one of the related commits), otherwise usb-keyb support breaks:
arch/arm/Kconfig +1
-0@@ -513,6 +513,7 @@ config ARCH_SUNXI select DM select DM_GPIO select DM_ETH + select DM_KEYBOARD select DM_SERIAL select DM_USB select OF_CONTROL
Quoted 2 lines
The breakage is that without this
usb_scan_device()returns -96 (EPFNOSUPPORT) for usb keyboards.
OK. I am a bit concerned this might affect other boards too. Still, if we get this series applied soon there is plenty of time for testing. I'll look a bit closer.
Quoted 39 lines
2) With that branch there still is the purely cosmetical issue, that if one plugs a usb-stick + keyb into the same hub, then swaps their place and do "usb reset" and then "usb tree" looks like this:
USB device tree:
1 Hub (480 Mb/s, 100mA)
| USB2.0 Hub
|+-3 Human Interface (1.5 Mb/s, 100mA) | SINO WEALTH USB Composite Device | +-2 Mass Storage (480 Mb/s, 100mA)USB Flash Disk 4C0E960F
Notice the order of devices listed: 1 - 3 - 2, which is a bit weird, as said this is purely cosmetical.
Note you can easily fix this by only reverting the:
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, and keep the other 2 you revert and dropping this patch ?
As I already suggested before, this is both more KISS and as you can see it solves some actually (admittedly very minor) issues.
I'm not really buying your arguments for your more complex solution, as shown above re-using the devices actually causes issues.
Your other argument of wanting to attach device-tree properties I also do not find a strong argument, for one there has never been a need to do so sofar, and if we ever need this we need a way to specify which usb-device the properties belong to based on the topology under the host / root-hub anyway, and match things up when first scanning the bus. And if we can match things up on the first scan we can also match them up on subsequent scans and attach the same of-node again.
Quoted 3 lines
Anyways I'm fine with doing things your way, but I still have a preference for the more KISS and IMHO robust solution of simple unbinding all devices on usb-stop.
I wonder if it really is more complex. My preferred algorithm is to remove any devices that have not been probed after a scan. Yours is to remove and unbind any USB devices before a scan. What is the difference?
I much prefer not unbinding and rebinding devices. To my mind, devices should be bound once if possible, and most of the time it is possible. This is different from the Linux approach of combining 'bind' and 'probe'. At present sandbox cannot support 'usb reset'. I would like sandbox to provide full support so that we can use tests to verify functionality rather than manual testing.
Re the ordering above, I suppose I could fix that command easily enough. This is not a common problem though. Does it really matter?
Quoted 11 lines
###
Talking about usb-stop, there is still one (BIG!) problem after this patch set when building usb-support with
DM_DEVICE_REMOVEnot set. This means that the controllers dma engines will not be stopped when booting the actual OS and they will still be accessing parts of the main memory while the actual OS is booting, which is BAD. So I suggest adding something like this to all host drivers which use dma in this way:
Quoted 3 lines
#if defined
CONFIG_DM_USB&& !definedCONFIG_DM_DEVICE_REMOVE
#error The EHCI driver cannot be used withoutCONFIG_DM_DEVICE_REMOVEotherwise DMA stays active while booting the OS #endif
Sounds good. I am not suggesting that we encourage people to build USB with out DM_DEVICE_REMOVE. I just want to make sure that we don't create unnecessary dependencies such that DM_DEVICE_REMOVE becomes impossible to use.
We have a note in the Kconfig for that, but I agree we need to make it more explicit. With the #if approach it makes the pitfall much more obvious.
Quoted 77 lines
Regards,
Hans
Quoted 68 lines
Quoted 68 lines
Quoted 39 lines
Quoted 39 lines
Changes in v2: None
drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)drivers/usb/host/usb-uclass.c +14
-0@@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) printf("%d USB Device(s) found\n", priv->next_addr); } +static void remove_inactive_children (struct uclass *uc,struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { +struct udevice *dev, *next; + +if (!device_active (bus)) +continue ; + device_foreach_child_safe(dev, next, bus) { +if (!device_active (dev)) +device_unbind (dev); + } + } +} +int usb_init (void ){ int controllers_initialized = 0;drivers/usb/host/usb-uclass.c +0
-0@@ -270,6 +284,15 @@ int usb_init(void) }Quoted 15 lines
drivers/usb/host/usb-uclass.c int usb_init(void) · line 295
Quoted 10 lines
drivers/usb/host/usb-uclass.c +9
-0debug ("scan end\n" ); + +/* Remove any devices that were not found on this scan */ +remove_inactive_children (uc, bus); + + ret =uclass_get (UCLASS_USB_HUB , &uc); +if (ret) +return ret; +remove_inactive_children (uc, bus); +Why do you need to call
remove_inactive_childrentwice here? This seems worthy of a comment explaining why this is necessary.One is removing the children of USB controllers, one is removing the children of USB hubs. I'll add a comment.
Quoted 5 lines
Quoted 5 lines
drivers/usb/host/usb-uclass.c +0
-0/* if we were not able to find at least one working bus, bail out */ if (!count)printf("No controllers found\n");Regards,
Simon
Regards,
Simon
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi,
Quoted 3 lines · Simon Glass
Hi Hans,
On 11 November 2015 at 10:02, Hans de Goede <[email protected]> wrote:
<snip>
Quoted 22 lines
Quoted 1 line
Ok, I've ran a whole battery of tests on your u-boot-dm/usb-working branch.
Thanks!
Quoted 18 lines
There are 2 issues:
1) You need to add these change to the commit introducing usb-keyb dm support (or one of the related commits), otherwise usb-keyb support breaks:
arch/arm/Kconfig +1
-0@@ -513,6 +513,7 @@ config ARCH_SUNXI select DM select DM_GPIO select DM_ETH + select DM_KEYBOARD select DM_SERIAL select DM_USB select OF_CONTROL
Quoted 6 lines
Quoted 2 lines
The breakage is that without this
usb_scan_device()returns -96 (EPFNOSUPPORT) for usb keyboards.OK. I am a bit concerned this might affect other boards too. Still, if we get this series applied soon there is plenty of time for testing. I'll look a bit closer.
Ok.
Quoted 38 lines
Quoted 38 lines
2) With that branch there still is the purely cosmetical issue, that if one plugs a usb-stick + keyb into the same hub, then swaps their place and do "usb reset" and then "usb tree" looks like this:
USB device tree:
1 Hub (480 Mb/s, 100mA) | USB2.0 Hub | +-3 Human Interface (1.5 Mb/s, 100mA) | SINO WEALTH USB Composite Device | +-2 Mass Storage (480 Mb/s, 100mA) USB Flash Disk 4C0E960FNotice the order of devices listed: 1 - 3 - 2, which is a bit weird, as said this is purely cosmetical.
Note you can easily fix this by only reverting the:
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, and keep the other 2 you revert and dropping this patch ?
As I already suggested before, this is both more KISS and as you can see it solves some actually (admittedly very minor) issues.
I'm not really buying your arguments for your more complex solution, as shown above re-using the devices actually causes issues.
Your other argument of wanting to attach device-tree properties I also do not find a strong argument, for one there has never been a need to do so sofar, and if we ever need this we need a way to specify which usb-device the properties belong to based on the topology under the host / root-hub anyway, and match things up when first scanning the bus. And if we can match things up on the first scan we can also match them up on subsequent scans and attach the same of-node again.
Quoted 8 lines
Quoted 3 lines
Anyways I'm fine with doing things your way, but I still have a preference for the more KISS and IMHO robust solution of simple unbinding all devices on usb-stop.
I wonder if it really is more complex. My preferred algorithm is to remove any devices that have not been probed after a scan. Yours is to remove and unbind any USB devices before a scan. What is the difference?
If you unbind everything before (re)scanning you always start with a clean slate, making things more reproducible and simpler.
As for it being more complex, your approach needs a whole new helper function and needs to walk the list of devices twice, where as mine is just a single extra function call + error checking.
As an added bonus my approach allows adding an ifdef to usb_find_child turning it into a nop like this
#if defined CONFIG_SANDBOX || !defined CONFIG_DM_DEVICE_REMOVE
...
... complex code to find child
...
#else
return -ENODEV;#endif
So besides not needing the extra helper function your solution needs, my version also removes a bunch of extra code (from the resulting binary) in almost all cases.
So your solution is definitely more complex, needlessly so IMHO.
Quoted 2 lines
I much prefer not unbinding and rebinding devices. To my mind, devices should be bound once if possible, and most of the time it is possible.
Well in case of a re-scan we are discovering all devices from scratch, not just looking for changed devices, simply starting with a clean device list reflects this.
Quoted 7 lines
This is different from the Linux approach of combining 'bind' and 'probe'. At present sandbox cannot support 'usb reset'. I would like sandbox to provide full support so that we can use tests to verify functionality rather than manual testing.
Re the ordering above, I suppose I could fix that command easily enough. This is not a common problem though. Does it really matter?
Nope, as said this is a cosmetic issue, and for the record I'm fine with your approach of always re-using existing devices on a re-scan. I prefer the start with a clean slate approach but either is fine with me.
Quoted 14 lines
Quoted 10 lines
###
Talking about usb-stop, there is still one (BIG!) problem after this patch set when building usb-support with
DM_DEVICE_REMOVEnot set. This means that the controllers dma engines will not be stopped when booting the actual OS and they will still be accessing parts of the main memory while the actual OS is booting, which is BAD. So I suggest adding something like this to all host drivers which use dma in this way:Quoted 3 lines
#if defined
CONFIG_DM_USB&& !definedCONFIG_DM_DEVICE_REMOVE
#error The EHCI driver cannot be used withoutCONFIG_DM_DEVICE_REMOVEotherwise DMA stays active while booting the OS #endif
Quoted 8 lines
Sounds good. I am not suggesting that we encourage people to build USB with out
DM_DEVICE_REMOVE. I just want to make sure that we don't create unnecessary dependencies such thatDM_DEVICE_REMOVEbecomes impossible to use.We have a note in the
Kconfigfor that, but I agree we need to make it more explicit. With the #if approach it makes the pitfall much more obvious.
Ack, so we need to have patches for this for at least ohci, ehci, xhci and I guess also uhci ? Who is going to write these patches ?
Regards,
Hans
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi Hans,
Quoted 97 lines · Hans de Goede
Hi,
Quoted 5 lines · Simon Glass
Hi Hans,
On 11 November 2015 at 10:02, Hans de Goede <[email protected]> wrote:
<snip>
Quoted 24 lines
Quoted 2 lines
Ok, I've ran a whole battery of tests on your u-boot-dm/usb-working branch.
Thanks!
Quoted 18 lines
There are 2 issues:
1) You need to add these change to the commit introducing usb-keyb dm support (or one of the related commits), otherwise usb-keyb support breaks:
arch/arm/Kconfig +1
-0@@ -513,6 +513,7 @@ config ARCH_SUNXI select DM select DM_GPIO select DM_ETH + select DM_KEYBOARD select DM_SERIAL select DM_USB select OF_CONTROLQuoted 7 lines
Quoted 2 lines
The breakage is that without this
usb_scan_device()returns -96 (EPFNOSUPPORT) for usb keyboards.OK. I am a bit concerned this might affect other boards too. Still, if we get this series applied soon there is plenty of time for testing. I'll look a bit closer.
Ok.
Quoted 43 lines
Quoted 38 lines
2) With that branch there still is the purely cosmetical issue, that if one plugs a usb-stick + keyb into the same hub, then swaps their place and do "usb reset" and then "usb tree" looks like this:
USB device tree:
1 Hub (480 Mb/s, 100mA) | USB2.0 Hub | +-3 Human Interface (1.5 Mb/s, 100mA) | SINO WEALTH USB Composite Device | +-2 Mass Storage (480 Mb/s, 100mA) USB Flash Disk 4C0E960FNotice the order of devices listed: 1 - 3 - 2, which is a bit weird, as said this is purely cosmetical.
Note you can easily fix this by only reverting the:
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, and keep the other 2 you revert and dropping this patch ?
As I already suggested before, this is both more KISS and as you can see it solves some actually (admittedly very minor) issues.
I'm not really buying your arguments for your more complex solution, as shown above re-using the devices actually causes issues.
Your other argument of wanting to attach device-tree properties I also do not find a strong argument, for one there has never been a need to do so sofar, and if we ever need this we need a way to specify which usb-device the properties belong to based on the topology under the host / root-hub anyway, and match things up when first scanning the bus. And if we can match things up on the first scan we can also match them up on subsequent scans and attach the same of-node again.
Quoted 3 lines
Anyways I'm fine with doing things your way, but I still have a preference for the more KISS and IMHO robust solution of simple unbinding all devices on usb-stop.
Quoted 4 lines
I wonder if it really is more complex. My preferred algorithm is to remove any devices that have not been probed after a scan. Yours is to remove and unbind any USB devices before a scan. What is the difference?
Quoted 6 lines
If you unbind everything before (re)scanning you always start with a clean slate, making things more reproducible and simpler.
As for it being more complex, your approach needs a whole new helper function and needs to walk the list of devices twice, where as mine is just a single extra function call + error checking.
The helper function is basically the same as the one you have - it removes devices that are not activated, rather than all devices. I don't think the difference is large.
It doesn't actually walk the list of devices twice. It walks the list of USB controllers once, then the list of USB hubs once. We need to check both, as hubs may be need to be unbound.
Quoted 11 lines
As an added bonus my approach allows adding an ifdef to
usb_find_childturning it into a nop like this#if defined CONFIG_SANDBOX || !defined CONFIG_DM_DEVICE_REMOVE ... ... complex code to find child ... #else return -ENODEV;#endif
I'm not sure that is a bonus. It means that sandbox is no-longer using the same code path as other boards. That's actually one of the objectives of sandbox.
Quoted 6 lines
So besides not needing the extra helper function your solution needs, my version also removes a bunch of extra code (from the resulting binary) in almost all cases.
So your solution is definitely more complex, needlessly so IMHO.
It does have the virtue of allowing sandbox USB to work properly. At present 'usb reset' is broken, as I mentioned. Willy-nilly unbinding of devices is a bad idea IMO.
Yes I understand that the code to find the child is needed, but it's not large:
struct udevice *dev;
*devp = NULL;
for (device_find_first_child(parent, &dev);
dev;
device_find_next_child(&dev)) { struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
/* If this device is already in use, skip it */ if (device_active(dev))
continue;
debug(" %s: name='%s', plat=%d, desc=%d\n", __func__,
dev->name, plat->id.bDeviceClass, desc->bDeviceClass);
if (usb_match_one_id(desc, iface, &plat->id)) {
*devp = dev;
return 0; }
}
and usb_match_one_id() is needed anyway to support drivers. I suppose we could avoid this and always create a new device, which would degenerate to your solution of removing all the old devices. So if we want to provide that option, it would be easy to do.
Quoted 8 lines
Quoted 3 lines
I much prefer not unbinding and rebinding devices. To my mind, devices should be bound once if possible, and most of the time it is possible.
Well in case of a re-scan we are discovering all devices from scratch, not just looking for changed devices, simply starting with a clean device list reflects this.
Yes, although in most cases the list of devices will not change. We are really talking about an unusual case. Most of the time when U-Boot starts it runs 'usb start' once. The case where it runs multiple times is IMO not an important case to optimise, unless we are trying to use knowledge of previous devices to speed up detection of the new bus state.
Quoted 6 lines
Quoted 6 lines
This is different from the Linux approach of combining 'bind' and 'probe'. At present sandbox cannot support 'usb reset'. I would like sandbox to provide full support so that we can use tests to verify functionality rather than manual testing.
Quoted 8 lines
Quoted 2 lines
Re the ordering above, I suppose I could fix that command easily enough. This is not a common problem though. Does it really matter?
Nope, as said this is a cosmetic issue, and for the record I'm fine with your approach of always re-using existing devices on a re-scan. I prefer the start with a clean slate approach but either is fine with me.
OK
Quoted 22 lines
Quoted 22 lines
Quoted 11 lines
###
Talking about usb-stop, there is still one (BIG!) problem after this patch set when building usb-support with
DM_DEVICE_REMOVEnot set. This means that the controllers dma engines will not be stopped when booting the actual OS and they will still be accessing parts of the main memory while the actual OS is booting, which is BAD. So I suggest adding something like this to all host drivers which use dma in this way:Quoted 4 lines
#if defined
CONFIG_DM_USB&& !definedCONFIG_DM_DEVICE_REMOVE#error The EHCI driver cannot be used withoutCONFIG_DM_DEVICE_REMOVEotherwise DMA stays active while booting the OS
#endifSounds good. I am not suggesting that we encourage people to build USB with out
DM_DEVICE_REMOVE. I just want to make sure that we don't create unnecessary dependencies such thatDM_DEVICE_REMOVEbecomes impossible to use.
Quoted 7 lines
Quoted 3 lines
We have a note in the
Kconfigfor that, but I agree we need to make it more explicit. With the #if approach it makes the pitfall much more obvious.Ack, so we need to have patches for this for at least ohci, ehci, xhci and I guess also uhci ? Who is going to write these patches ?
I suppose I could do that. I would like to make sure that any USB fish hooks are removed, and that is part of the solution.
I'd really like to resolve this and move things forward. If you still have have strong objections please let me know. We did discuss this at the time and I was clear that I did not want to keep the solution as it was - I merged it because it fixed a bug, as you pointed out at the time.
Regards,
Simon
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi,
Quoted 1 line · Simon Glass
Hi Hans,
<snip>
Quoted 24 lines
Quoted 24 lines
Quoted 22 lines
Quoted 8 lines
Talking about usb-stop, there is still one (BIG!) problem after this patch set when building usb-support with
DM_DEVICE_REMOVEnot set. This means that the controllers dma engines will not be stopped when booting the actual OS and they will still be accessing parts of the main memory while the actual OS is booting, which is BAD. So I suggest adding something like this to all host drivers which use dma in this way:Quoted 4 lines
#if defined
CONFIG_DM_USB&& !definedCONFIG_DM_DEVICE_REMOVE#error The EHCI driver cannot be used withoutCONFIG_DM_DEVICE_REMOVEotherwise DMA stays active while booting the OS
#endifSounds good. I am not suggesting that we encourage people to build USB with out
DM_DEVICE_REMOVE. I just want to make sure that we don't create unnecessary dependencies such thatDM_DEVICE_REMOVEbecomes impossible to use.We have a note in the
Kconfigfor that, but I agree we need to make it more explicit. With the #if approach it makes the pitfall much more obvious.
Quoted 8 lines
Quoted 2 lines
Ack, so we need to have patches for this for at least ohci, ehci, xhci and I guess also uhci ? Who is going to write these patches ?
I suppose I could do that. I would like to make sure that any USB fish hooks are removed, and that is part of the solution.
I'd really like to resolve this and move things forward. If you still have have strong objections please let me know.
There are no objections from my side to move forward with your current solution.
Quoted 4 lines
We did discuss this at
the time and I was clear that I did not want to keep the solution as it was - I merged it because it fixed a bug, as you pointed out at the time.
Ack.
Regards,
Hans
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Hi Hans,
Quoted 50 lines · Hans de Goede
Hi,
Quoted 2 lines · Simon Glass
Hi Hans,
<snip>
Quoted 30 lines
Quoted 20 lines
Quoted 20 lines
Quoted 8 lines
Talking about usb-stop, there is still one (BIG!) problem after this patch set when building usb-support with
DM_DEVICE_REMOVEnot set. This means that the controllers dma engines will not be stopped when booting the actual OS and they will still be accessing parts of the main memory while the actual OS is booting, which is BAD. So I suggest adding something like this to all host drivers which use dma in this way:Quoted 4 lines
#if defined
CONFIG_DM_USB&& !definedCONFIG_DM_DEVICE_REMOVE#error The EHCI driver cannot be used withoutCONFIG_DM_DEVICE_REMOVEotherwise DMA stays active while booting the OS
#endifSounds good. I am not suggesting that we encourage people to build USB with out
DM_DEVICE_REMOVE. I just want to make sure that we don't create unnecessary dependencies such thatDM_DEVICE_REMOVEbecomes impossible to use.Quoted 8 lines
Quoted 3 lines
We have a note in the
Kconfigfor that, but I agree we need to make it more explicit. With the #if approach it makes the pitfall much more obvious.Ack, so we need to have patches for this for at least ohci, ehci, xhci and I guess also uhci ? Who is going to write these patches ?
Quoted 5 lines
I suppose I could do that. I would like to make sure that any USB fish hooks are removed, and that is part of the solution.
I'd really like to resolve this and move things forward. If you still have have strong objections please let me know.
There are no objections from my side to move forward with your current solution.
Quoted 7 lines
Quoted 4 lines
We did discuss this at
the time and I was clear that I did not want to keep the solution as it was - I merged it because it fixed a bug, as you pointed out at the time.Ack.
OK thanks. I'll see if I can get some more comments on the other patches.
Regards,
Simon
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
Applied to u-boot-dm.
PATCH v2 18/26 dm: usb: Remove inactive children after a bus scan
In reply to Simon GlassHi,
Quoted 47 lines · Simon Glass
Hi Hans,
Quoted 36 lines · Simon Glass
Hi Hans,
Quoted 26 lines · Hans de Goede
Hi,
Quoted 10 lines · Simon Glass
Each scan of the USB bus may return different results. Existing driver-model
devices are reused when found, but if a device no longer exists it will stay
around, de-activated, but bound.Detect these devices and remove them after the scan completes.
Signed-off-by Simon Glass <[email protected]>I wonder how this is better then my original:
"dm: usb: Usedevice_unbind_childrento clean up usb devs on stop"Patch, the end result of both patches is the same and both are a NOP when
DM_DEVICE_REMOVEis not set. Where as my code seems to be a much more KISS approach to the problem (my approach is just 3 lines vs 23 lines for yours).I know we will need
usb_find_childin theDM_DEVICE_REMOVEnot set case, but why not only revert the:Quoted 6 lines
"dm: usb: Rename
usb_find_childtousb_find_emul_child"commit, keep the other 2 you revert and drop this patch ?
This drops 3 patches from your patch-set and the end result is more clean IMHO.
Quoted 7 lines
I would like to avoid binding/unbinding things when nothing changes if possible. Also I'd like to support attaching device tree nodes/properties to USB devices as necessary, as we do with PCI, and removing things breaks that.
I still have to figure out one more test case, so I'll do that before commenting further.
Quoted 6 lines
I've added the test case and pushed a new tree. However it turns out that this doesn't behave differently.
So please can you go ahead and run your original (manual) test case? I'd like to make sure that my automated tests are correct and catch the bug you reported and fixed.
Ok, I've ran a whole battery of tests on your u-boot-dm/usb-working branch.
There are 2 issues:
1) You need to add these change to the commit introducing usb-keyb dm support (or one of the related commits), otherwise usb-keyb support breaks:
arch/arm/Kconfig +1 -0
@@ -513,6 +513,7 @@ config ARCH_SUNXI select DM select DM_GPIO select DM_ETH + select DM_KEYBOARD select DM_SERIAL select DM_USB select OF_CONTROL
The breakage is that without this usb_scan_device() returns -96 (EPFNOSUPPORT) for usb keyboards.
2) With that branch there still is the purely cosmetical issue, that if one plugs a usb-stick + keyb into the same hub, then swaps their place and do "usb reset" and then "usb tree" looks like this:
USB device tree:
1 Hub (480 Mb/s, 100mA)
| USB2.0 Hub
|
+-3 Human Interface (1.5 Mb/s, 100mA) | SINO WEALTH USB Composite Device | +-2 Mass Storage (480 Mb/s, 100mA)
USB Flash Disk 4C0E960F
Notice the order of devices listed: 1 - 3 - 2, which is a bit weird, as said this is purely cosmetical.
Note you can easily fix this by only reverting the:
"dm: usb: Rename usb_find_child to usb_find_emul_child"
commit, and keep the other 2 you revert and dropping this patch ?
As I already suggested before, this is both more KISS and as you can see it solves some actually (admittedly very minor) issues.
I'm not really buying your arguments for your more complex solution, as shown above re-using the devices actually causes issues.
Your other argument of wanting to attach device-tree properties I also do not find a strong argument, for one there has never been a need to do so sofar, and if we ever need this we need a way to specify which usb-device the properties belong to based on the topology under the host / root-hub anyway, and match things up when first scanning the bus. And if we can match things up on the first scan we can also match them up on subsequent scans and attach the same of-node again.
Anyways I'm fine with doing things your way, but I still have a preference for the more KISS and IMHO robust solution of simple unbinding all devices on usb-stop.
###
Talking about usb-stop, there is still one (BIG!) problem after this patch set when building usb-support with DM_DEVICE_REMOVE not set. This means that the controllers dma engines will not be stopped when booting the actual OS and they will still be accessing parts of the main memory while the actual OS is booting, which is BAD. So I suggest adding something like this to all host drivers which use dma in this way:
#if defined CONFIG_DM_USB && !defined CONFIG_DM_DEVICE_REMOVE
#error The EHCI driver cannot be used without CONFIG_DM_DEVICE_REMOVE otherwise DMA stays active while booting the OS #endif
Regards,
Hans
Quoted 65 lines
Quoted 65 lines
Quoted 39 lines
Quoted 39 lines
Changes in v2: None
drivers/usb/host/usb-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)drivers/usb/host/usb-uclass.c +14
-0@@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) printf("%d USB Device(s) found\n", priv->next_addr); } +static void remove_inactive_children (struct uclass *uc,struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { +struct udevice *dev, *next; + +if (!device_active (bus)) +continue ; + device_foreach_child_safe(dev, next, bus) { +if (!device_active (dev)) +device_unbind (dev); + } + } +} +int usb_init (void ){ int controllers_initialized = 0;drivers/usb/host/usb-uclass.c +0
-0@@ -270,6 +284,15 @@ int usb_init(void) }Quoted 14 lines
drivers/usb/host/usb-uclass.c int usb_init(void) · line 295
Quoted 10 lines
drivers/usb/host/usb-uclass.c +9
-0debug ("scan end\n" ); + +/* Remove any devices that were not found on this scan */ +remove_inactive_children (uc, bus); + + ret =uclass_get (UCLASS_USB_HUB , &uc); +if (ret) +return ret; +remove_inactive_children (uc, bus); +Why do you need to call
remove_inactive_childrentwice here? This seems worthy of a comment explaining why this is necessary.One is removing the children of USB controllers, one is removing the children of USB hubs. I'll add a comment.
Quoted 5 lines
Quoted 5 lines
drivers/usb/host/usb-uclass.c +0
-0/* if we were not able to find at least one working bus, bail out */ if (!count)printf("No controllers found\n");Regards,
Simon
PATCH v2 19/26 dm: test: usb: Add tests for the 'usb tree' command
In reply to Simon GlassAdd tests that this command produces the right output, even when a rescan results in a device disappearing from the bus.
---
Changes in v2: None
arch/sandbox/dts/test.dts | 14 ++++- test/dm/usb.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-)
arch/sandbox/dts/test.dts +13 -1
@@ -307,12 +307,24 @@ compatible = "sandbox,usb-hub"; #address-cells = <1>; #size-cells = <0>; - flash-stick { + flash-stick at 0 { reg = <0>; compatible = "sandbox,usb-flash"; sandbox,filepath = "testflash.bin"; }; + flash-stick at 1 { + reg = <1>; + compatible = "sandbox,usb-flash"; + sandbox,filepath = "testflash1.bin"; + }; + + flash-stick at 2 { + reg = <2>; + compatible = "sandbox,usb-flash"; + sandbox,filepath = "testflash2.bin"; + }; + }; }; };
test/dm/usb.c +156 -0
167 lines not on this page · raw message
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 19/26 dm: test: usb: Add tests for the 'usb tree' command
Applied to u-boot-dm.
PATCH v2 20/26 dm: test: usb: Add a test for device reordering
In reply to Simon GlassAdd tests that 'usb tree' produces the right output when a device changes order on the bus.
---
Changes in v2: None
test/dm/usb.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
test/dm/usb.c +50 -0
@@ -208,3 +208,53 @@ static int dm_test_usb_tree_remove(struct unit_test_state *uts)return 0 ; }DM_TEST (dm_test_usb_tree_remove,DM_TESTF_SCAN_PDATA |DM_TESTF_SCAN_FDT ); + +const char usb_tree_reorder[] = +" 1 Hub (12 Mb/s, 100mA)\n" +" | sandbox hub 2345\n" +" |\n" +" |\b+-2 Mass Storage (12 Mb/s, 100mA)\n" +" | sandbox flash flash-stick at 0\n" +" | \n" +" |\b+-3 Mass Storage (12 Mb/s, 100mA)\n" +" | sandbox flash flash-stick at 2\n" +" | \n" +" |\b+-4 Mass Storage (12 Mb/s, 100mA)\n" +" sandbox flash flash-stick at 1\n" +" \n" ; + +/* +* test that the 'usb tree' command output looks correct when we reorder two +* devices. +*/ +static int dm_test_usb_tree_reorder (struct unit_test_state *uts) +{ +struct udevice *dev, *parent; +char *data; +int len; + +/* Remove the second emulation device */ +ut_assertok (uclass_find_device_by_name (UCLASS_USB_EMUL ,"flash-stick at 1" , + &dev)); + parent = dev->parent; + +/* Reorder the devices in the parent list and uclass list */ +list_del (&dev->sibling_node); +list_add_tail (&dev->sibling_node, &parent->child_head); + +list_del (&dev->uclass_node); +list_add_tail (&dev->uclass_node, &dev->uclass->dev_head); + +state_set_skip_delays (true); +ut_assertok (usb_init ()); +console_record_reset_enable (); +usb_show_tree (); + len =membuff_getraw (&gd->console_out,-1 , true, &data); +if (len) + data[len] ='\0' ; +ut_asserteq_str (usb_tree_reorder, data); +ut_assertok (usb_stop ()); + +return 0 ; +} +DM_TEST (dm_test_usb_tree_reorder,DM_TESTF_SCAN_PDATA |DM_TESTF_SCAN_FDT );
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 20/26 dm: test: usb: Add a test for device reordering
Applied to u-boot-dm.
PATCH v2 21/26 usb: Drop unused code in usb_kbd.c
In reply to Simon GlassThis was missed in the conversion to driver model.
---
Changes in v2: None
common/usb_kbd.c | 30 ------------------------------ 1 file changed, 30 deletions(-)
common/usb_kbd.c +0 -30
@@ -541,35 +541,6 @@ int drv_usb_kbd_init(void)int error, i;debug ("%s: Probing for keyboard\n" , __func__); -#ifdef CONFIG_DM_USB -/* -* TODO: We should add U_BOOT_USB_DEVICE() declarations to each USB -* keyboard driver and then most of this file can be removed. -*/ -struct udevice *bus; -struct uclass *uc; -int ret; - - ret =uclass_get (UCLASS_USB , &uc); -if (ret) -return ret; - uclass_foreach_dev(bus, uc) { -for (i =0 ; i <USB_MAX_DEVICE ; i++) { -struct usb_device *dev; - - dev =usb_get_dev_index (bus, i);/* get device */ -debug ("i=%d, %p\n" , i, dev); -if (!dev) -break ;/* no more devices available */ - - error =probe_usb_keyboard (dev); -if (!error) -return 1 ; -if (error && error != -ENOENT ) -return error; - }/* for */ - } -#else /* Scan all USB Devices */ for (i =0 ; i <USB_MAX_DEVICE ; i++) {struct usb_device *dev;
@@ -588,7 +559,6 @@ int drv_usb_kbd_init(void)if (error && error != -ENOENT )return error; } -#endif /* No USB Keyboard found */ return -1 ;
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 21/26 usb: Drop unused code in usb_kbd.c
Applied to u-boot-dm.
PATCH v2 22/26 usb: Avoid open-coded USB constants in usb_kbd.c
In reply to Simon GlassReplace the open-coded values with constants to make it clearer what they mean.
---
Changes in v2: None
common/usb_kbd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
common/usb_kbd.c +5 -5
@@ -411,13 +411,13 @@ static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum) iface = &dev->config.if_desc[ifnum]; -if (iface->desc.bInterfaceClass !=3 ) +if (iface->desc.bInterfaceClass !=USB_CLASS_HID )return 0 ; -if (iface->desc.bInterfaceSubClass !=1 ) +if (iface->desc.bInterfaceSubClass !=USB_SUB_HID_BOOT )return 0 ; -if (iface->desc.bInterfaceProtocol !=1 ) +if (iface->desc.bInterfaceProtocol !=USB_PROT_HID_KEYBOARD )return 0 ;if (iface->desc.bNumEndpoints !=1 )
@@ -626,8 +626,8 @@ static const struct usb_device_id kbd_id_table[] = { USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL, .bInterfaceClass = USB_CLASS_HID, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 1, + .bInterfaceSubClass = USB_SUB_HID_BOOT, + .bInterfaceProtocol = USB_PROT_HID_KEYBOARD, }, { }/* Terminating entry */ };
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 22/26 usb: Avoid open-coded USB constants in usb_kbd.c
Applied to u-boot-dm.
PATCH v2 23/26 usb: sandbox: Add support for interrupt operations
In reply to Simon GlassAllow USB device emulation to support interrupt URBs so that we can use USB keyboards with sandbox.
---
Changes in v2: None
drivers/usb/emul/usb-emul-uclass.c | 12 ++++++++++++ drivers/usb/host/usb-sandbox.c | 19 +++++++++++++++++++ include/usb.h | 11 +++++++++++ 3 files changed, 42 insertions(+)
drivers/usb/emul/usb-emul-uclass.c +12 -0
@@ -218,6 +218,18 @@ int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,return ops->bulk (emul, udev, pipe, buffer, length); } +int usb_emul_int (struct udevice *emul,struct usb_device *udev, +unsigned long pipe,void *buffer,int length,int interval) +{ +struct dm_usb_ops *ops =usb_get_emul_ops (emul); + +if (!ops->interrupt) +return -ENOSYS ; +debug ("%s: dev=%s\n" , __func__, emul->name); + +return ops->interrupt (emul, udev, pipe, buffer, length, interval); +} +int usb_emul_setup_device (struct udevice *dev,int maxpacketsize,struct usb_string *strings,void **desc_list) {
drivers/usb/host/usb-sandbox.c +19 -0
@@ -87,6 +87,24 @@ static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev,return ret; } +static int sandbox_submit_int (struct udevice *bus,struct usb_device *udev, +unsigned long pipe,void *buffer,int length, +int interval) +{ +struct udevice *emul; +int ret; + +/* Just use child of dev as emulator? */ +debug ("%s: bus=%s\n" , __func__, bus->name); + ret =usb_emul_find (bus, pipe, &emul); +usbmon_trace (bus, pipe,NULL , emul); +if (ret) +return ret; + ret =usb_emul_int (emul, udev, pipe, buffer, length, interval); + +return ret; +} +static int sandbox_alloc_device (struct udevice *dev,struct usb_device *udev) {return 0 ;
@@ -100,6 +118,7 @@ static int sandbox_usb_probe(struct udevice *dev)static const struct dm_usb_ops sandbox_usb_ops = { .control = sandbox_submit_control, .bulk = sandbox_submit_bulk, + .interrupt = sandbox_submit_int, .alloc_device = sandbox_alloc_device, };
include/usb.h +11 -0
@@ -938,6 +938,17 @@ int usb_emul_bulk(struct udevice *emul, struct usb_device *udev, unsigned long pipe, void *buffer, int length);/** +* usb_emul_int() - Send an interrupt packet to an emulator +* +* @emul: Emulator device +* @udev: USB device (which the emulator is causing to appear) +* See struct dm_usb_ops for details on other parameters +* @return 0 if OK, -ve on error +*/ +int usb_emul_int (struct udevice *emul,struct usb_device *udev, +unsigned long pipe,void *buffer,int length,int interval); + +/** * usb_emul_find() - Find an emulator for a particular device * * Check @pipe to find a device number on bus @bus and return it.
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 23/26 usb: sandbox: Add support for interrupt operations
Applied to u-boot-dm.
PATCH v2 24/26 usb: sandbox: Add a USB emulation driver
In reply to Simon GlassAdd a simple USB keyboard driver for sandbox. It provides a function to 'load' it with input data, which it will then stream through to the normal U-Boot input subsystem. When the input data is exhausted, the keyboard stops providing data.
---
Changes in v2: None
arch/sandbox/include/asm/test.h | 2 + drivers/usb/emul/Makefile | 1 + drivers/usb/emul/sandbox_keyb.c | 241 ++++++++++++++++++++++++++++++++++++++++ include/linux/usb/ch9.h | 20 ++++ 4 files changed, 264 insertions(+) create mode 100644 drivers/usb/emul/sandbox_keyb.c
arch/sandbox/include/asm/test.h +2 -0
@@ -86,4 +86,6 @@ long sandbox_i2c_rtc_set_offset(struct udevice *dev, bool use_system_time,*/ long sandbox_i2c_rtc_get_set_base_time (struct udevice *dev,long base_time); +int sandbox_usb_keyb_add_string (struct udevice *dev,const char *str); +#endif
drivers/usb/emul/Makefile +1 -0
@@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EMUL) += sandbox_flash.o obj-$(CONFIG_USB_EMUL) += sandbox_hub.o +obj-$(CONFIG_USB_EMUL) += sandbox_keyb.o obj-$(CONFIG_USB_EMUL) += usb-emul-uclass.o
drivers/usb/emul/sandbox_keyb.c new file +241 -0
241 lines not on this page · raw message
include/linux/usb/ch9.h +20 -0
@@ -229,6 +229,8 @@ struct usb_ctrlrequest {#define USB_DT_PIPE_USAGE 0x24/* From the USB 3.0 spec */ #define USB_DT_SS_ENDPOINT_COMP 0x30 +/* From HID 1.11 spec */ +#define USB_DT_HID_REPORT 0x22/* Conventional codes for class-specific descriptors. The convention is * defined in the USB "Common Class" Spec (3.11). Individual class specs
@@ -385,6 +387,24 @@ struct usb_generic_descriptor {__u8 bDescriptorType; }; +struct __packed usb_class_hid_descriptor { +u8 bLength; +u8 bDescriptorType; +u16 bcdCDC; +u8 bCountryCode; +u8 bNumDescriptors;/* 0x01 */ +u8 bDescriptorType0; +u16 wDescriptorLength0; +/* optional descriptors are not supported. */ +}; + +struct __packed usb_class_report_descriptor { +u8 bLength;/* dummy */ +u8 bDescriptorType; +u16 wLength; +u8 bData[0 ]; +}; +/* * Endpoints */
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 24/26 usb: sandbox: Add a USB emulation driver
Applied to u-boot-dm.
PATCH v2 25/26 sandbox: Enable USB keyboard
In reply to Simon GlassEnable the USB keyboard on sandbox, now that we have a suitable emulation driver.
---
Changes in v2: None
configs/sandbox_defconfig | 2 ++ include/configs/sandbox.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
configs/sandbox_defconfig +2 -0
@@ -72,3 +72,5 @@ CONFIG_ADC_SANDBOX=y CONFIG_CONSOLE_RECORD=y CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000 CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_USB_KEYBOARD=y +CONFIG_SYS_USB_EVENT_POLL=y
include/configs/sandbox.h +1 -1
@@ -178,7 +178,7 @@#define CONFIG_KEYBOARD -#define SANDBOX_SERIAL_SETTINGS "stdin=serial,cros-ec-keyb\0" \ +#define SANDBOX_SERIAL_SETTINGS "stdin=serial,cros-ec-keyb,usbkbd\0" \ "stdout=serial,lcd\0" \ "stderr=serial,lcd\0"#else
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 25/26 sandbox: Enable USB keyboard
Applied to u-boot-dm.
PATCH v2 26/26 dm: test: usb: sandbox: Add keyboard tests for sandbox
In reply to Simon GlassAdd a test that verifies that USB keyboards work correctly on sandbox. This verifies some additional parts of the USB stack.
---
Changes in v2:
- Add various patches to support USB keyboards and additional tests
arch/sandbox/dts/test.dts | 5 +++++ test/dm/usb.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+)
arch/sandbox/dts/test.dts +5 -0
@@ -325,6 +325,11 @@ sandbox,filepath = "testflash2.bin"; }; + keyb at 3 { + reg = <3>; + compatible = "sandbox,usb-keyb"; + }; + }; }; };
test/dm/usb.c +31 -0
@@ -10,6 +10,7 @@#include <usb.h> #include <asm/io.h> #include <asm/state.h> +#include <asm/test.h> #include <dm/device-internal.h> #include <dm/test.h> #include <dm/uclass-internal.h>
@@ -258,3 +259,33 @@ static int dm_test_usb_tree_reorder(struct unit_test_state *uts)return 0 ; }DM_TEST (dm_test_usb_tree_reorder,DM_TESTF_SCAN_PDATA |DM_TESTF_SCAN_FDT ); + +static int dm_test_usb_keyb (struct unit_test_state *uts) +{ +struct udevice *dev; + +state_set_skip_delays (true); +ut_assertok (usb_init ()); + +/* Initially there should be no characters */ +ut_asserteq (0 ,tstc ()); + +ut_assertok (uclass_get_device_by_name (UCLASS_USB_EMUL ,"keyb" , + &dev)); + +/* +* Add a string to the USB keyboard buffer - it should appear in +* stdin +*/ +ut_assertok (sandbox_usb_keyb_add_string (dev,"ab" )); +ut_asserteq (1 ,tstc ()); +ut_asserteq ('a' ,getc ()); +ut_asserteq (1 ,tstc ()); +ut_asserteq ('b' ,getc ()); +ut_asserteq (0 ,tstc ()); + +ut_assertok (usb_stop ()); + +return 0 ; +} +DM_TEST (dm_test_usb_keyb,DM_TESTF_SCAN_PDATA |DM_TESTF_SCAN_FDT );
Signature · 1 line
2.6.0.rc2.230.g3dd15c0
PATCH v2 26/26 dm: test: usb: sandbox: Add keyboard tests for sandbox
Applied to u-boot-dm.
v2 cover usb: Drop requirement for USB unbinding, add tests
In reply to Simon GlassHi Simon,
Quoted 17 lines · Simon Glass
There was quite a bit of discussion about the change that required the unbinding of USB devices for the subsystem to function correctly. E.g.
https://patchwork.ozlabs.org/patch/485637/
The key issue is the
usb_get_dev_index()function which is not a good API for driver model. We can drop use of this function once everything is converted to driver model. Then I believe the problems raised by Hans go away. For now we can add a deprecation warning on the function.It is easy to convert USB keyboards to driver model. This series includes a patch for that.
This series also includes reverts for the three commits which as discussed I would like to drop. U-Boot should be able to run normally and exit without unbinding anything.
Quoted 8 lines
Also included are some tests for the 'usb tree' command. To make this work, console recording is implemented.
Finally, a USB keyboard driver is provided for sandbox, so that this part of the stack can be tested automatically.
Changes in v2:
- Add various patches to support USB keyboards and additional tests
Do you have a git branch with this patch-set somewhere for me to test ?
Regards,
Hans
v2 cover usb: Drop requirement for USB unbinding, add tests
Hi Hans,
Quoted 26 lines · Hans de Goede
Hi Simon,
Quoted 23 lines · Simon Glass
There was quite a bit of discussion about the change that required the unbinding of USB devices for the subsystem to function correctly. E.g.
https://patchwork.ozlabs.org/patch/485637/
The key issue is the
usb_get_dev_index()function which is not a good API for driver model. We can drop use of this function once everything is converted to driver model. Then I believe the problems raised by Hans go away. For now we can add a deprecation warning on the function.It is easy to convert USB keyboards to driver model. This series includes a patch for that.
This series also includes reverts for the three commits which as discussed I would like to drop. U-Boot should be able to run normally and exit without
unbinding anything.Also included are some tests for the 'usb tree' command. To make this work,
console recording is implemented.
Quoted 8 lines
Quoted 5 lines
Finally, a USB keyboard driver is provided for sandbox, so that this part of the stack can be tested automatically.
Changes in v2:
- Add various patches to support USB keyboards and additional testsDo you have a git branch with this patch-set somewhere for me to test ?
Yes I always upload branches before sending them. This one is u-boot-dm/usb-working. I should get better at including the branch name in the cover letter.
I still need to write a test for having two device types which switch order. Now that I have a USB keyboard emulation I should be able to do that. I'll then see the impact on 'usb tree'. So you may want to review the test code only for now.
Regards,
Simon
v2 cover usb: Drop requirement for USB unbinding, add tests
Hi,
Quoted 43 lines · Simon Glass
Hi Hans,
Quoted 26 lines · Hans de Goede
Hi Simon,
Quoted 23 lines · Simon Glass
There was quite a bit of discussion about the change that required the unbinding of USB devices for the subsystem to function correctly. E.g.
https://patchwork.ozlabs.org/patch/485637/
The key issue is the
usb_get_dev_index()function which is not a good API for driver model. We can drop use of this function once everything is converted to driver model. Then I believe the problems raised by Hans go away. For now we can add a deprecation warning on the function.It is easy to convert USB keyboards to driver model. This series includes a patch for that.
This series also includes reverts for the three commits which as discussed I would like to drop. U-Boot should be able to run normally and exit without
unbinding anything.Also included are some tests for the 'usb tree' command. To make this work,
console recording is implemented.Quoted 8 lines
Quoted 5 lines
Finally, a USB keyboard driver is provided for sandbox, so that this part of the stack can be tested automatically.
Changes in v2:
- Add various patches to support USB keyboards and additional testsDo you have a git branch with this patch-set somewhere for me to test ?
Yes I always upload branches before sending them. This one is u-boot-dm/usb-working. I should get better at including the branch name in the cover letter.
Quoted 7 lines
I still need to write a test for having two device types which switch order. Now that I have a USB keyboard emulation I should be able to do that. I'll then see the impact on 'usb tree'. So you may want to review the test code only for now.
Regards,
Simon
Are there any more comments on this series please? I plan to bring it in soon since we are already at RC1.
Regards,
Simon
v2 cover usb: Drop requirement for USB unbinding, add tests
In reply to Simon GlassQuoted 17 lines · Simon Glass
There was quite a bit of discussion about the change that required the unbinding of USB devices for the subsystem to function correctly. E.g.
https://patchwork.ozlabs.org/patch/485637/
The key issue is the
usb_get_dev_index()function which is not a good API for driver model. We can drop use of this function once everything is converted to driver model. Then I believe the problems raised by Hans go away. For now we can add a deprecation warning on the function.It is easy to convert USB keyboards to driver model. This series includes a patch for that.
This series also includes reverts for the three commits which as discussed I would like to drop. U-Boot should be able to run normally and exit without unbinding anything.
Quoted 8 lines
Also included are some tests for the 'usb tree' command. To make this work, console recording is implemented.
Finally, a USB keyboard driver is provided for sandbox, so that this part of the stack can be tested automatically.
Changes in v2:
- Add various patches to support USB keyboards and additional tests
Briefly
Best regards,
Marek Vasut