diff options
Diffstat (limited to 'common')
38 files changed, 532 insertions, 466 deletions
diff --git a/common/Kconfig b/common/Kconfig index 620d41f..ccf5475 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -679,3 +679,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. diff --git a/common/autoboot.c b/common/autoboot.c index c367076..c11fb31 100644 --- a/common/autoboot.c +++ b/common/autoboot.c @@ -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> diff --git a/common/board_f.c b/common/board_f.c index 04c273e..b035c90 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -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> @@ -736,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) @@ -772,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, @@ -780,9 +791,9 @@ static init_fnc_t init_sequence_f[] = { x86_fsp_init, #endif arch_cpu_init, /* basic arch cpu dependent setup */ - mark_bootstage, initf_dm, arch_cpu_init_dm, + mark_bootstage, /* need timer, go after init dm */ #if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f, #endif diff --git a/common/board_r.c b/common/board_r.c index c6aa7e5..f7118e8 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -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 @@ -279,6 +280,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) { @@ -730,6 +740,7 @@ init_fnc_t init_sequence_r[] = { #endif initr_barrier, initr_malloc, + initr_console_record, #ifdef CONFIG_SYS_NONCACHED_MEMORY initr_noncached, #endif diff --git a/common/cli.c b/common/cli.c index b6ae80a..fbcd339 100644 --- a/common/cli.c +++ b/common/cli.c @@ -12,6 +12,7 @@ #include <common.h> #include <cli.h> #include <cli_hush.h> +#include <console.h> #include <fdtdec.h> #include <malloc.h> diff --git a/common/cli_hush.c b/common/cli_hush.c index 296542f..a7cac4f 100644 --- a/common/cli_hush.c +++ b/common/cli_hush.c @@ -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> diff --git a/common/cli_simple.c b/common/cli_simple.c index d8b40c9..9c3d073 100644 --- a/common/cli_simple.c +++ b/common/cli_simple.c @@ -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 */ diff --git a/common/cmd_armflash.c b/common/cmd_armflash.c index af453f7..b94d128 100644 --- a/common/cmd_armflash.c +++ b/common/cmd_armflash.c @@ -8,6 +8,7 @@ */ #include <common.h> #include <command.h> +#include <console.h> #include <asm/io.h> #define MAX_REGIONS 4 diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c index 57a8a3f..69afeaf 100644 --- a/common/cmd_bedbug.c +++ b/common/cmd_bedbug.c @@ -5,6 +5,7 @@ #include <common.h> #include <cli.h> #include <command.h> +#include <console.h> #include <linux/ctype.h> #include <net.h> #include <bedbug/type.h> diff --git a/common/cmd_dcr.c b/common/cmd_dcr.c index 4fddd80..cc77250 100644 --- a/common/cmd_dcr.c +++ b/common/cmd_dcr.c @@ -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); diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c index f060db7..6d95ce9 100644 --- a/common/cmd_dfu.c +++ b/common/cmd_dfu.c @@ -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> diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index e9904cd..6eab1ea 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -25,404 +25,241 @@ #include <command.h> #include <i2c.h> -extern void eeprom_init (void); -extern int eeprom_read (unsigned dev_addr, unsigned offset, - uchar *buffer, unsigned cnt); -extern int eeprom_write (unsigned dev_addr, unsigned offset, - uchar *buffer, unsigned cnt); -#if defined(CONFIG_SYS_EEPROM_WREN) -extern int eeprom_write_enable (unsigned dev_addr, int state); +#ifndef CONFIG_SYS_I2C_SPEED +#define CONFIG_SYS_I2C_SPEED 50000 #endif - -#if defined(CONFIG_SYS_EEPROM_X40430) - /* Maximum number of times to poll for acknowledge after write */ -#define MAX_ACKNOWLEDGE_POLLS 10 +#ifndef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 0 #endif -/* ------------------------------------------------------------------------- */ - -#if defined(CONFIG_CMD_EEPROM) -static int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - const char *const fmt = - "\nEEPROM @0x%lX %s: addr %08lx off %04lx count %ld ... "; - -#if defined(CONFIG_SYS_I2C_MULTI_EEPROMS) - if (argc == 6) { - ulong dev_addr = simple_strtoul (argv[2], NULL, 16); - ulong addr = simple_strtoul (argv[3], NULL, 16); - ulong off = simple_strtoul (argv[4], NULL, 16); - ulong cnt = simple_strtoul (argv[5], NULL, 16); -#else - if (argc == 5) { - ulong dev_addr = CONFIG_SYS_DEF_EEPROM_ADDR; - ulong addr = simple_strtoul (argv[2], NULL, 16); - ulong off = simple_strtoul (argv[3], NULL, 16); - ulong cnt = simple_strtoul (argv[4], NULL, 16); -#endif /* CONFIG_SYS_I2C_MULTI_EEPROMS */ - -# if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C) - eeprom_init (); -# endif /* !CONFIG_SPI */ - - if (strcmp (argv[1], "read") == 0) { - int rcode; - - printf (fmt, dev_addr, argv[1], addr, off, cnt); - - rcode = eeprom_read (dev_addr, off, (uchar *) addr, cnt); - - puts ("done\n"); - return rcode; - } else if (strcmp (argv[1], "write") == 0) { - int rcode; - - printf (fmt, dev_addr, argv[1], addr, off, cnt); - - rcode = eeprom_write (dev_addr, off, (uchar *) addr, cnt); - - puts ("done\n"); - return rcode; - } - } - - return CMD_RET_USAGE; -} +#ifndef CONFIG_SYS_EEPROM_PAGE_WRITE_BITS +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 8 #endif -/*----------------------------------------------------------------------- - * +#define EEPROM_PAGE_SIZE (1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS) +#define EEPROM_PAGE_OFFSET(x) ((x) & (EEPROM_PAGE_SIZE - 1)) + +/* * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM. * * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is * 0x00000nxx for EEPROM address selectors and page number at n. */ - #if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C) -#if !defined(CONFIG_SYS_I2C_EEPROM_ADDR_LEN) || CONFIG_SYS_I2C_EEPROM_ADDR_LEN < 1 || CONFIG_SYS_I2C_EEPROM_ADDR_LEN > 2 +#if !defined(CONFIG_SYS_I2C_EEPROM_ADDR_LEN) || \ + (CONFIG_SYS_I2C_EEPROM_ADDR_LEN < 1) || \ + (CONFIG_SYS_I2C_EEPROM_ADDR_LEN > 2) #error CONFIG_SYS_I2C_EEPROM_ADDR_LEN must be 1 or 2 #endif #endif -int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt) +__weak int eeprom_write_enable(unsigned dev_addr, int state) { - unsigned end = offset + cnt; - unsigned blk_off; - int rcode = 0; + return 0; +} - /* Read data until done or would cross a page boundary. - * We must write the address again when changing pages - * because the next page may be in a different device. - */ - while (offset < end) { - unsigned alen, len; -#if !defined(CONFIG_SYS_I2C_FRAM) - unsigned maxlen; +void eeprom_init(int bus) +{ + /* SPI EEPROM */ +#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C) + spi_init_f(); #endif -#if CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) - uchar addr[2]; + /* I2C EEPROM */ +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT) +#if defined(CONFIG_SYS_I2C) + if (bus >= 0) + i2c_set_bus_num(bus); +#endif + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif +} - blk_off = offset & 0xFF; /* block offset */ +static int eeprom_addr(unsigned dev_addr, unsigned offset, uchar *addr) +{ + unsigned blk_off; + int alen; - addr[0] = offset >> 8; /* block number */ - addr[1] = blk_off; /* block offset */ - alen = 2; + blk_off = offset & 0xff; /* block offset */ +#if CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 + addr[0] = offset >> 8; /* block number */ + addr[1] = blk_off; /* block offset */ + alen = 2; #else - uchar addr[3]; - - blk_off = offset & 0xFF; /* block offset */ - - addr[0] = offset >> 16; /* block number */ - addr[1] = offset >> 8; /* upper address octet */ - addr[2] = blk_off; /* lower address octet */ - alen = 3; -#endif /* CONFIG_SYS_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */ - - addr[0] |= dev_addr; /* insert device address */ + addr[0] = offset >> 16; /* block number */ + addr[1] = offset >> 8; /* upper address octet */ + addr[2] = blk_off; /* lower address octet */ + alen = 3; +#endif /* CONFIG_SYS_I2C_EEPROM_ADDR_LEN */ - len = end - offset; + addr[0] |= dev_addr; /* insert device address */ - /* - * For a FRAM device there is no limit on the number of the - * bytes that can be ccessed with the single read or write - * operation. - */ -#if !defined(CONFIG_SYS_I2C_FRAM) - maxlen = 0x100 - blk_off; - if (maxlen > I2C_RXTX_LEN) - maxlen = I2C_RXTX_LEN; - if (len > maxlen) - len = maxlen; -#endif - -#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C) - spi_read (addr, alen, buffer, len); -#else -#if defined(CONFIG_SYS_I2C_EEPROM_BUS) - i2c_set_bus_num(CONFIG_SYS_I2C_EEPROM_BUS); -#endif - if (i2c_read(addr[0], offset, alen - 1, buffer, len)) - rcode = 1; -#endif - buffer += len; - offset += len; - } - - return rcode; + return alen; } -/*----------------------------------------------------------------------- - * - * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is - * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM. - * - * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is - * 0x00000nxx for EEPROM address selectors and page number at n. - */ - -int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt) +static int eeprom_len(unsigned offset, unsigned end) { - unsigned end = offset + cnt; - unsigned blk_off; - int rcode = 0; - -#if defined(CONFIG_SYS_EEPROM_X40430) - uchar contr_r_addr[2]; - uchar addr_void[2]; - uchar contr_reg[2]; - uchar ctrl_reg_v; - int i; -#endif + unsigned len = end - offset; -#if defined(CONFIG_SYS_EEPROM_WREN) - eeprom_write_enable (dev_addr,1); -#endif - /* Write data until done or would cross a write page boundary. - * We must write the address again when changing pages - * because the address counter only increments within a page. + /* + * For a FRAM device there is no limit on the number of the + * bytes that can be ccessed with the single read or write + * operation. */ - - while (offset < end) { - unsigned alen, len; #if !defined(CONFIG_SYS_I2C_FRAM) - unsigned maxlen; -#endif + unsigned blk_off = offset & 0xff; + unsigned maxlen = EEPROM_PAGE_SIZE - EEPROM_PAGE_OFFSET(blk_off); -#if CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) - uchar addr[2]; + if (maxlen > I2C_RXTX_LEN) + maxlen = I2C_RXTX_LEN; - blk_off = offset & 0xFF; /* block offset */ - - addr[0] = offset >> 8; /* block number */ - addr[1] = blk_off; /* block offset */ - alen = 2; -#else - uchar addr[3]; + if (len > maxlen) + len = maxlen; +#endif - blk_off = offset & 0xFF; /* block offset */ + return len; +} - addr[0] = offset >> 16; /* block number */ - addr[1] = offset >> 8; /* upper address octet */ - addr[2] = blk_off; /* lower address octet */ - alen = 3; -#endif /* CONFIG_SYS_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */ +static int eeprom_rw_block(unsigned offset, uchar *addr, unsigned alen, + uchar *buffer, unsigned len, bool read) +{ + int ret = 0; - addr[0] |= dev_addr; /* insert device address */ + /* SPI */ +#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C) + if (read) + spi_read(addr, alen, buffer, len); + else + spi_write(addr, alen, buffer, len); +#else /* I2C */ - len = end - offset; +#if defined(CONFIG_SYS_I2C_EEPROM_BUS) + i2c_set_bus_num(CONFIG_SYS_I2C_EEPROM_BUS); +#endif - /* - * For a FRAM device there is no limit on the number of the - * bytes that can be accessed with the single read or write - * operation. - */ -#if !defined(CONFIG_SYS_I2C_FRAM) + if (read) + ret = i2c_read(addr[0], offset, alen - 1, buffer, len); + else + ret = i2c_write(addr[0], offset, alen - 1, buffer, len); -#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_BITS) + if (ret) + ret = 1; +#endif + return ret; +} -#define EEPROM_PAGE_SIZE (1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS) -#define EEPROM_PAGE_OFFSET(x) ((x) & (EEPROM_PAGE_SIZE - 1)) +static int eeprom_rw(unsigned dev_addr, unsigned offset, uchar *buffer, + unsigned cnt, bool read) +{ + unsigned end = offset + cnt; + unsigned alen, len; + int rcode = 0; + uchar addr[3]; - maxlen = EEPROM_PAGE_SIZE - EEPROM_PAGE_OFFSET(blk_off); -#else - maxlen = 0x100 - blk_off; -#endif - if (maxlen > I2C_RXTX_LEN) - maxlen = I2C_RXTX_LEN; + while (offset < end) { + alen = eeprom_addr(dev_addr, offset, addr); - if (len > maxlen) - len = maxlen; -#endif + len = eeprom_len(offset, end); -#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C) - spi_write (addr, alen, buffer, len); -#else -#if defined(CONFIG_SYS_EEPROM_X40430) - /* Get the value of the control register. - * Set current address (internal pointer in the x40430) - * to 0x1ff. - */ - contr_r_addr[0] = 9; - contr_r_addr[1] = 0xff; - addr_void[0] = 0; - addr_void[1] = addr[1]; -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR - contr_r_addr[0] |= CONFIG_SYS_I2C_EEPROM_ADDR; - addr_void[0] |= CONFIG_SYS_I2C_EEPROM_ADDR; -#endif - contr_reg[0] = 0xff; - if (i2c_read (contr_r_addr[0], contr_r_addr[1], 1, contr_reg, 1) != 0) { - rcode = 1; - } - ctrl_reg_v = contr_reg[0]; - - /* Are any of the eeprom blocks write protected? - */ - if (ctrl_reg_v & 0x18) { - ctrl_reg_v &= ~0x18; /* reset block protect bits */ - ctrl_reg_v |= 0x02; /* set write enable latch */ - ctrl_reg_v &= ~0x04; /* clear RWEL */ - - /* Set write enable latch. - */ - contr_reg[0] = 0x02; - if (i2c_write (contr_r_addr[0], 0xff, 1, contr_reg, 1) != 0) { - rcode = 1; - } - - /* Set register write enable latch. - */ - contr_reg[0] = 0x06; - if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { - rcode = 1; - } - - /* Modify ctrl register. - */ - contr_reg[0] = ctrl_reg_v; - if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { - rcode = 1; - } - - /* The write (above) is an operation on NV memory. - * These can take some time (~5ms), and the device - * will not respond to further I2C messages till - * it's completed the write. - * So poll device for an I2C acknowledge. - * When we get one we know we can continue with other - * operations. - */ - contr_reg[0] = 0; - for (i = 0; i < MAX_ACKNOWLEDGE_POLLS; i++) { - if (i2c_read (addr_void[0], addr_void[1], 1, contr_reg, 1) == 0) - break; /* got ack */ -#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS) - udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); -#endif - } - if (i == MAX_ACKNOWLEDGE_POLLS) { - puts ("EEPROM poll acknowledge failed\n"); - rcode = 1; - } - } - - /* Is the write enable latch on?. - */ - else if (!(ctrl_reg_v & 0x02)) { - /* Set write enable latch. - */ - contr_reg[0] = 0x02; - if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) { - rcode = 1; - } - } - /* Write is enabled ... now write eeprom value. - */ -#endif -#if defined(CONFIG_SYS_I2C_EEPROM_BUS) - i2c_set_bus_num(CONFIG_SYS_I2C_EEPROM_BUS); -#endif - if (i2c_write(addr[0], offset, alen - 1, buffer, len)) - rcode = 1; + rcode = eeprom_rw_block(offset, addr, alen, buffer, len, read); -#endif buffer += len; offset += len; -#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS) - udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); -#endif + if (!read) + udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); } -#if defined(CONFIG_SYS_EEPROM_WREN) - eeprom_write_enable (dev_addr,0); -#endif + return rcode; } -#if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C) -int -eeprom_probe (unsigned dev_addr, unsigned offset) +int eeprom_read(unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt) { - unsigned char chip; - - /* Probe the chip address + /* + * Read data until done or would cross a page boundary. + * We must write the address again when changing pages + * because the next page may be in a different device. */ -#if CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) - chip = offset >> 8; /* block number */ -#else - chip = offset >> 16; /* block number */ -#endif /* CONFIG_SYS_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */ + return eeprom_rw(dev_addr, offset, buffer, cnt, 1); +} + +int eeprom_write(unsigned dev_addr, unsigned offset, + uchar *buffer, unsigned cnt) +{ + int ret; + + eeprom_write_enable(dev_addr, 1); - chip |= dev_addr; /* insert device address */ + /* + * Write data until done or would cross a write page boundary. + * We must write the address again when changing pages + * because the address counter only increments within a page. + */ + ret = eeprom_rw(dev_addr, offset, buffer, cnt, 1); - return (i2c_probe (chip)); + eeprom_write_enable(dev_addr, 0); + return ret; } -#endif -/*----------------------------------------------------------------------- - * Set default values - */ -#ifndef CONFIG_SYS_I2C_SPEED -#define CONFIG_SYS_I2C_SPEED 50000 +static int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const char *const fmt = + "\nEEPROM @0x%lX %s: addr %08lx off %04lx count %ld ... "; + char * const *args = &argv[2]; + int rcode; + ulong dev_addr, addr, off, cnt; + int bus_addr; + + switch (argc) { +#ifdef CONFIG_SYS_DEF_EEPROM_ADDR + case 5: + bus_addr = -1; + dev_addr = CONFIG_SYS_DEF_EEPROM_ADDR; + break; #endif + case 6: + bus_addr = -1; + dev_addr = simple_strtoul(*args++, NULL, 16); + break; + case 7: + bus_addr = simple_strtoul(*args++, NULL, 16); + dev_addr = simple_strtoul(*args++, NULL, 16); + break; + default: + return CMD_RET_USAGE; + } -void eeprom_init (void) -{ + addr = simple_strtoul(*args++, NULL, 16); + off = simple_strtoul(*args++, NULL, 16); + cnt = simple_strtoul(*args++, NULL, 16); -#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C) - spi_init_f (); -#endif -#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT) - i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -#endif -} + eeprom_init(bus_addr); -/*----------------------------------------------------------------------- - */ + if (strcmp(argv[1], "read") == 0) { + printf(fmt, dev_addr, argv[1], addr, off, cnt); + + rcode = eeprom_read(dev_addr, off, (uchar *)addr, cnt); + + puts("done\n"); + return rcode; + } else if (strcmp(argv[1], "write") == 0) { + printf(fmt, dev_addr, argv[1], addr, off, cnt); -/***************************************************/ + rcode = eeprom_write(dev_addr, off, (uchar *)addr, cnt); -#if defined(CONFIG_CMD_EEPROM) + puts("done\n"); + return rcode; + } + + return CMD_RET_USAGE; +} -#ifdef CONFIG_SYS_I2C_MULTI_EEPROMS U_BOOT_CMD( - eeprom, 6, 1, do_eeprom, + eeprom, 7, 1, do_eeprom, "EEPROM sub-system", - "read devaddr addr off cnt\n" - "eeprom write devaddr addr off cnt\n" + "read <bus> <devaddr> addr off cnt\n" + "eeprom write <bus> <devaddr> addr off cnt\n" " - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'" ) -#else /* One EEPROM */ -U_BOOT_CMD( - eeprom, 5, 1, do_eeprom, - "EEPROM sub-system", - "read addr off cnt\n" - "eeprom write addr off cnt\n" - " - read/write `cnt' bytes at EEPROM offset `off'" -) -#endif /* CONFIG_SYS_I2C_MULTI_EEPROMS */ - -#endif diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c index b9d1c8c..488822a 100644 --- a/common/cmd_fastboot.c +++ b/common/cmd_fastboot.c @@ -9,6 +9,7 @@ */ #include <common.h> #include <command.h> +#include <console.h> #include <g_dnl.h> #include <usb.h> diff --git a/common/cmd_fpgad.c b/common/cmd_fpgad.c index 1f1d00f..5370c3e 100644 --- a/common/cmd_fpgad.c +++ b/common/cmd_fpgad.c @@ -11,6 +11,7 @@ #include <common.h> #include <command.h> +#include <console.h> #include <gdsys_fpga.h> diff --git a/common/cmd_fuse.c b/common/cmd_fuse.c index d4bc0f6..5998f9b 100644 --- a/common/cmd_fuse.c +++ b/common/cmd_fuse.c @@ -11,6 +11,7 @@ #include <common.h> #include <command.h> +#include <console.h> #include <fuse.h> #include <asm/errno.h> diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c index e3c0297..d94d553 100644 --- a/common/cmd_gpt.c +++ b/common/cmd_gpt.c @@ -1,6 +1,9 @@ /* * cmd_gpt.c -- GPT (GUID Partition Table) handling command * + * Copyright (C) 2015 + * Lukasz Majewski <l.majewski@majess.pl> + * * Copyright (C) 2012 Samsung Electronics * author: Lukasz Majewski <l.majewski@samsung.com> * author: Piotr Wilczek <p.wilczek@samsung.com> @@ -15,6 +18,7 @@ #include <exports.h> #include <linux/ctype.h> #include <div64.h> +#include <memalign.h> #ifndef CONFIG_PARTITION_UUIDS #error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_GPT to be enabled @@ -118,6 +122,40 @@ static char *extract_val(const char *str, const char *key) } /** + * found_key(): Found key without value in parameter list (comma separated). + * + * @param str - pointer to string with key + * @param key - pointer to the key to search for + * + * @return - true on found key + */ +static bool found_key(const char *str, const char *key) +{ + char *k; + char *s, *strcopy; + bool result = false; + + strcopy = strdup(str); + if (!strcopy) + return NULL; + + s = strcopy; + while (s) { + k = strsep(&s, ","); + if (!k) + break; + if (strcmp(k, key) == 0) { + result = true; + break; + } + } + + free(strcopy); + + return result; +} + +/** * set_gpt_info(): Fill partition information from string * function allocates memory, remember to free! * @@ -271,6 +309,10 @@ static int set_gpt_info(block_dev_desc_t *dev_desc, parts[i].start = lldiv(start_ll, dev_desc->blksz); free(val); } + + /* bootable */ + if (found_key(tok, "bootable")) + parts[i].bootable = 1; } *parts_count = p_count; @@ -293,9 +335,6 @@ static int gpt_default(block_dev_desc_t *blk_dev_desc, const char *str_part) u8 part_count = 0; disk_partition_t *partitions = NULL; - if (!str_part) - return -1; - /* fill partitions */ ret = set_gpt_info(blk_dev_desc, str_part, &str_disk_guid, &partitions, &part_count); @@ -317,6 +356,43 @@ static int gpt_default(block_dev_desc_t *blk_dev_desc, const char *str_part) return ret; } +static int gpt_verify(block_dev_desc_t *blk_dev_desc, const char *str_part) +{ + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, + blk_dev_desc->blksz); + disk_partition_t *partitions = NULL; + gpt_entry *gpt_pte = NULL; + char *str_disk_guid; + u8 part_count = 0; + int ret = 0; + + /* fill partitions */ + ret = set_gpt_info(blk_dev_desc, str_part, + &str_disk_guid, &partitions, &part_count); + if (ret) { + if (ret == -1) { + printf("No partition list provided - only basic check\n"); + ret = gpt_verify_headers(blk_dev_desc, gpt_head, + &gpt_pte); + goto out; + } + if (ret == -2) + printf("Missing disk guid\n"); + if ((ret == -3) || (ret == -4)) + printf("Partition list incomplete\n"); + return -1; + } + + /* Check partition layout with provided pattern */ + ret = gpt_verify_partitions(blk_dev_desc, partitions, part_count, + gpt_head, &gpt_pte); + free(str_disk_guid); + free(partitions); + out: + free(gpt_pte); + return ret; +} + /** * do_gpt(): Perform GPT operations * @@ -332,45 +408,49 @@ static int do_gpt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int ret = CMD_RET_SUCCESS; int dev = 0; char *ep; - block_dev_desc_t *blk_dev_desc; + block_dev_desc_t *blk_dev_desc = NULL; - if (argc < 5) + if (argc < 4 || argc > 5) return CMD_RET_USAGE; - /* command: 'write' */ - if ((strcmp(argv[1], "write") == 0) && (argc == 5)) { - dev = (int)simple_strtoul(argv[3], &ep, 10); - if (!ep || ep[0] != '\0') { - printf("'%s' is not a number\n", argv[3]); - return CMD_RET_USAGE; - } - blk_dev_desc = get_dev(argv[2], dev); - if (!blk_dev_desc) { - printf("%s: %s dev %d NOT available\n", - __func__, argv[2], dev); - return CMD_RET_FAILURE; - } - - puts("Writing GPT: "); + dev = (int)simple_strtoul(argv[3], &ep, 10); + if (!ep || ep[0] != '\0') { + printf("'%s' is not a number\n", argv[3]); + return CMD_RET_USAGE; + } + blk_dev_desc = get_dev(argv[2], dev); + if (!blk_dev_desc) { + printf("%s: %s dev %d NOT available\n", + __func__, argv[2], dev); + return CMD_RET_FAILURE; + } + if ((strcmp(argv[1], "write") == 0) && (argc == 5)) { + printf("Writing GPT: "); ret = gpt_default(blk_dev_desc, argv[4]); - if (!ret) { - puts("success!\n"); - return CMD_RET_SUCCESS; - } else { - puts("error!\n"); - return CMD_RET_FAILURE; - } + } else if ((strcmp(argv[1], "verify") == 0)) { + ret = gpt_verify(blk_dev_desc, argv[4]); + printf("Verify GPT: "); } else { return CMD_RET_USAGE; } - return ret; + + if (ret) { + printf("error!\n"); + return CMD_RET_FAILURE; + } + + printf("success!\n"); + return CMD_RET_SUCCESS; } U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt, "GUID Partition Table", "<command> <interface> <dev> <partitions_list>\n" - " - GUID partition table restoration\n" - " Restore GPT information on a device connected\n" + " - GUID partition table restoration and validity check\n" + " Restore or verify GPT information on a device connected\n" " to interface\n" + " Example usage:\n" + " gpt write mmc 0 $partitions\n" + " gpt verify mmc 0 $partitions\n" ); diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 864b259..3d0de81 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -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> diff --git a/common/cmd_load.c b/common/cmd_load.c index d043e6d..0aa7937 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -10,6 +10,7 @@ */ #include <common.h> #include <command.h> +#include <console.h> #include <s_record.h> #include <net.h> #include <exports.h> diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 43c3fb6..9fb2584 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -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 diff --git a/common/cmd_mii.c b/common/cmd_mii.c index 5e9079d..7ef7532 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -314,6 +314,11 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) mask = simple_strtoul(argv[5], NULL, 16); } + if (addrhi > 31) { + printf("Incorrect PHY address. Range should be 0-31\n"); + return CMD_RET_USAGE; + } + /* use current device */ devname = miiphy_get_current_dev(); diff --git a/common/cmd_misc.c b/common/cmd_misc.c index 93f9eab..39d8683 100644 --- a/common/cmd_misc.c +++ b/common/cmd_misc.c @@ -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[]) { diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 1335e3d..dfc1ec8 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -7,6 +7,7 @@ #include <common.h> #include <command.h> +#include <console.h> #include <mmc.h> static int curr_device = -1; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 1482462..a6b67e2 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -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> diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index f4c2523..2f9cdd0 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -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> diff --git a/common/cmd_otp.c b/common/cmd_otp.c index 593bb8c..10c1475 100644 --- a/common/cmd_otp.c +++ b/common/cmd_otp.c @@ -16,6 +16,7 @@ #include <config.h> #include <common.h> #include <command.h> +#include <console.h> #include <asm/blackfin.h> #include <asm/clock.h> diff --git a/common/cmd_pci.c b/common/cmd_pci.c index dcecef8..802e433 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -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> diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 1ef55dc..a540b42 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -13,6 +13,7 @@ #include <common.h> #include <command.h> +#include <console.h> #include <dm.h> #include <memalign.h> #include <asm/byteorder.h> @@ -428,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]; @@ -436,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; @@ -527,11 +559,14 @@ static void do_usb_start(void) /* Driver model will probe the devices as they are found */ #ifndef CONFIG_DM_USB -#ifdef CONFIG_USB_STORAGE +# ifdef CONFIG_USB_STORAGE /* try to recognize storage devices immediately */ usb_stor_curr_dev = usb_stor_scan(1); -#endif -#endif +# endif +# ifdef CONFIG_USB_KEYBOARD + drv_usb_kbd_init(); +# endif +#endif /* !CONFIG_DM_USB */ #ifdef CONFIG_USB_HOST_ETHER # ifdef CONFIG_DM_ETH # ifndef CONFIG_DM_USB @@ -542,9 +577,6 @@ static void do_usb_start(void) usb_ether_curr_dev = usb_host_eth_scan(1); # endif #endif -#ifdef CONFIG_USB_KEYBOARD - drv_usb_kbd_init(); -#endif } #ifdef CONFIG_DM_USB @@ -630,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) { diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index 198dab1..0407389 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -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> diff --git a/common/command.c b/common/command.c index 972ae28..858e288 100644 --- a/common/command.c +++ b/common/command.c @@ -11,6 +11,7 @@ #include <common.h> #include <command.h> +#include <console.h> #include <linux/ctype.h> /* diff --git a/common/console.c b/common/console.c index ace206c..bc37b6d 100644 --- a/common/console.c +++ b/common/console.c @@ -6,6 +6,7 @@ */ #include <common.h> +#include <console.h> #include <debug_uart.h> #include <stdarg.h> #include <iomux.h> @@ -377,6 +378,15 @@ int getc(void) if (!gd->have_console) return 0; +#ifdef CONFIG_CONSOLE_RECORD + if (gd->console_in.start) { + int ch; + + ch = membuff_getbyte(&gd->console_in); + if (ch != -1) + return 1; + } +#endif if (gd->flags & GD_FLG_DEVINIT) { /* Get from the standard input */ return fgetc(stdin); @@ -395,7 +405,12 @@ int tstc(void) if (!gd->have_console) return 0; - +#ifdef CONFIG_CONSOLE_RECORD + if (gd->console_in.start) { + if (membuff_peekbyte(&gd->console_in) != -1) + return 1; + } +#endif if (gd->flags & GD_FLG_DEVINIT) { /* Test the standard input */ return ftstc(stdin); @@ -469,6 +484,10 @@ void putc(const char c) return; } #endif +#ifdef CONFIG_CONSOLE_RECORD + if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start) + membuff_putbyte(&gd->console_out, c); +#endif #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -512,6 +531,10 @@ void puts(const char *s) return; } #endif +#ifdef CONFIG_CONSOLE_RECORD + if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start) + membuff_put(&gd->console_out, s, strlen(s)); +#endif #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) return; @@ -535,44 +558,31 @@ void puts(const char *s) } } -int printf(const char *fmt, ...) +#ifdef CONFIG_CONSOLE_RECORD +int console_record_init(void) { - va_list args; - uint i; - char printbuffer[CONFIG_SYS_PBSIZE]; + int ret; - va_start(args, fmt); + ret = membuff_new(&gd->console_out, CONFIG_CONSOLE_RECORD_OUT_SIZE); + if (ret) + return ret; + ret = membuff_new(&gd->console_in, CONFIG_CONSOLE_RECORD_IN_SIZE); - /* For this to work, printbuffer must be larger than - * anything we ever want to print. - */ - i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); - va_end(args); - - /* Print the string */ - puts(printbuffer); - return i; + return ret; } -int vprintf(const char *fmt, va_list args) +void console_record_reset(void) { - uint i; - char printbuffer[CONFIG_SYS_PBSIZE]; - -#if defined(CONFIG_PRE_CONSOLE_BUFFER) && !defined(CONFIG_SANDBOX) - if (!gd->have_console) - return 0; -#endif - - /* For this to work, printbuffer must be larger than - * anything we ever want to print. - */ - i = vscnprintf(printbuffer, sizeof(printbuffer), fmt, args); + membuff_purge(&gd->console_out); + membuff_purge(&gd->console_in); +} - /* Print the string */ - puts(printbuffer); - return i; +void console_record_reset_enable(void) +{ + console_record_reset(); + gd->flags |= GD_FLG_RECORD; } +#endif /* test if ctrl-c was pressed */ static int ctrlc_disabled = 0; /* see disable_ctrl() */ diff --git a/common/env_eeprom.c b/common/env_eeprom.c index eea169d..72b1373 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -91,7 +91,7 @@ void env_relocate_spec(void) uchar rdbuf[64], flags[2]; int i, crc_ok[2] = {0, 0}; - eeprom_init(); /* prepare for EEPROM read/write */ + eeprom_init(-1); /* prepare for EEPROM read/write */ off_env[0] = CONFIG_ENV_OFFSET; off_env[1] = CONFIG_ENV_OFFSET_REDUND; @@ -154,7 +154,7 @@ void env_relocate_spec(void) ulong crc, len, new; uchar rdbuf[64]; - eeprom_init(); /* prepare for EEPROM read/write */ + eeprom_init(-1); /* prepare for EEPROM read/write */ /* read old CRC */ eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, diff --git a/common/env_ubi.c b/common/env_ubi.c index e0dc5af..e611199 100644 --- a/common/env_ubi.c +++ b/common/env_ubi.c @@ -181,8 +181,7 @@ void env_relocate_spec(void) return; } - if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf, - CONFIG_ENV_SIZE)) { + if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) { printf("\n** Unable to read env from %s:%s **\n", CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); set_default_env(NULL); diff --git a/common/image.c b/common/image.c index 85c4f39..c36927f 100644 --- a/common/image.c +++ b/common/image.c @@ -158,6 +158,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_RKIMAGE, "rkimage", "Rockchip Boot Image" }, { IH_TYPE_RKSD, "rksd", "Rockchip SD Boot Image" }, { IH_TYPE_RKSPI, "rkspi", "Rockchip SPI Boot Image" }, + { IH_TYPE_ZYNQIMAGE, "zynqimage", "Xilinx Zynq Boot Image" }, { -1, "", "", }, }; diff --git a/common/iomux.c b/common/iomux.c index 62bdec6..3d8d00b 100644 --- a/common/iomux.c +++ b/common/iomux.c @@ -6,6 +6,7 @@ */ #include <common.h> +#include <console.h> #include <serial.h> #include <malloc.h> diff --git a/common/main.c b/common/main.c index ead0cd1..5a03181 100644 --- a/common/main.c +++ b/common/main.c @@ -10,6 +10,7 @@ #include <common.h> #include <autoboot.h> #include <cli.h> +#include <console.h> #include <version.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/common/stdio.c b/common/stdio.c index ab4df20..8311ac7 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -11,6 +11,7 @@ #include <config.h> #include <common.h> +#include <dm.h> #include <errno.h> #include <stdarg.h> #include <malloc.h> @@ -24,6 +25,8 @@ #include <i2c.h> #endif +#include <dm/device-internal.h> + DECLARE_GLOBAL_DATA_PTR; static struct stdio_dev devs; @@ -245,6 +248,32 @@ int stdio_init_tables(void) int stdio_add_devices(void) { +#ifdef CONFIG_DM_KEYBOARD + struct udevice *dev; + struct uclass *uc; + int ret; + + /* + * For now we probe all the devices here. At some point this should be + * done only when the devices are required - e.g. we have a list of + * input devices to start up in the stdin environment variable. That + * work probably makes more sense when stdio itself is converted to + * driver model. + * + * TODO(sjg@chromium.org): Convert changing uclass_first_device() etc. + * to return the device even on error. Then we could use that here. + */ + ret = uclass_get(UCLASS_KEYBOARD, &uc); + if (ret) + return ret; + + /* Don't report errors to the caller - assume that they are non-fatal */ + uclass_foreach_dev(dev, uc) { + ret = device_probe(dev); + if (ret) + printf("Failed to probe keyboard '%s'\n", dev->name); + } +#endif #ifdef CONFIG_SYS_I2C i2c_init_all(); #else @@ -258,7 +287,7 @@ int stdio_add_devices(void) #if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) drv_video_init (); #endif -#ifdef CONFIG_KEYBOARD +#if defined(CONFIG_KEYBOARD) && !defined(CONFIG_DM_KEYBOARD) drv_keyboard_init (); #endif #ifdef CONFIG_LOGBUFFER diff --git a/common/usb_hub.c b/common/usb_hub.c index a92c9fb..e1de813 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -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; diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 0302e5b..069fbd2 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -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> @@ -399,7 +400,7 @@ static int usb_kbd_getc(struct stdio_dev *sdev) } /* probes the USB device dev for keyboard type. */ -static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) +static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum) { struct usb_interface *iface; struct usb_endpoint_descriptor *ep; @@ -410,13 +411,13 @@ static int usb_kbd_probe(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) @@ -496,7 +497,7 @@ static int probe_usb_keyboard(struct usb_device *dev) int error; /* Try probing the keyboard */ - if (usb_kbd_probe(dev, 0) != 1) + if (usb_kbd_probe_dev(dev, 0) != 1) return -ENOENT; /* Register the keyboard */ @@ -533,41 +534,13 @@ static int probe_usb_keyboard(struct usb_device *dev) return 0; } +#ifndef CONFIG_DM_USB /* Search for keyboard and register it if found. */ 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; @@ -586,11 +559,11 @@ int drv_usb_kbd_init(void) if (error && error != -ENOENT) return error; } -#endif /* No USB Keyboard found */ return -1; } +#endif /* Deregister the keyboard. */ int usb_kbd_deregister(int force) @@ -622,3 +595,43 @@ int usb_kbd_deregister(int force) return 1; #endif } + +#ifdef CONFIG_DM_USB + +static int usb_kbd_probe(struct udevice *dev) +{ + struct usb_device *udev = dev_get_parent_priv(dev); + int ret; + + ret = probe_usb_keyboard(udev); + + return ret; +} + +static const struct udevice_id usb_kbd_ids[] = { + { .compatible = "usb-keyboard" }, + { } +}; + +U_BOOT_DRIVER(usb_kbd) = { + .name = "usb_kbd", + .id = UCLASS_KEYBOARD, + .of_match = usb_kbd_ids, + .probe = usb_kbd_probe, +}; + +static const struct usb_device_id kbd_id_table[] = { + { + .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS | + USB_DEVICE_ID_MATCH_INT_PROTOCOL, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = USB_SUB_HID_BOOT, + .bInterfaceProtocol = USB_PROT_HID_KEYBOARD, + }, + { } /* Terminating entry */ +}; + +U_BOOT_USB_DEVICE(usb_kbd, kbd_id_table); + +#endif |