summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig116
-rw-r--r--common/Makefile2
-rw-r--r--common/board_f.c7
-rw-r--r--common/board_r.c8
-rw-r--r--common/bootm.c1
-rw-r--r--common/cmd_bdinfo.c4
-rw-r--r--common/cmd_bootm.c1
-rw-r--r--common/cmd_bootstage.c7
-rw-r--r--common/cmd_demo.c1
-rw-r--r--common/cmd_elf.c2
-rw-r--r--common/cmd_fat.c1
-rw-r--r--common/cmd_fdt.c1
-rw-r--r--common/cmd_host.c175
-rw-r--r--common/cmd_lzmadec.c1
-rw-r--r--common/cmd_md5sum.c1
-rw-r--r--common/cmd_mem.c8
-rw-r--r--common/cmd_net.c178
-rw-r--r--common/cmd_nvedit.c1
-rw-r--r--common/cmd_pci.c14
-rw-r--r--common/cmd_pxe.c91
-rw-r--r--common/cmd_sandbox.c126
-rw-r--r--common/cmd_sf.c3
-rw-r--r--common/cmd_source.c1
-rw-r--r--common/cmd_trace.c1
-rw-r--r--common/cmd_usb.c198
-rw-r--r--common/cmd_ximg.c1
-rw-r--r--common/cros_ec.c35
-rw-r--r--common/hash.c1
-rw-r--r--common/image-fdt.c1
-rw-r--r--common/image-fit.c1
-rw-r--r--common/image.c1
-rw-r--r--common/iotrace.c1
-rw-r--r--common/lcd.c1
-rw-r--r--common/malloc_simple.c1
-rw-r--r--common/miiphyutil.c1
-rw-r--r--common/spl/spl_net.c4
-rw-r--r--common/update.c25
-rw-r--r--common/usb.c324
-rw-r--r--common/usb_hub.c194
-rw-r--r--common/usb_kbd.c119
-rw-r--r--common/usb_storage.c236
41 files changed, 1243 insertions, 652 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 4cde4b0..17930a4 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -339,6 +339,122 @@ config CMD_SETGETDCR
getidcr - Get a register value via indirect DCR addressing
setidcr - Set a register value via indirect DCR addressing
+config CMD_SOUND
+ bool "sound"
+ depends on SOUND
+ help
+ This provides basic access to the U-Boot's sound support. The main
+ feature is to play a beep.
+
+ sound init - set up sound system
+ sound play - play a sound
+
+endmenu
+
+menu "Boot timing"
+
+config BOOTSTAGE
+ bool "Boot timing and reporting"
+ help
+ Enable recording of boot time while booting. To use it, insert
+ calls to bootstage_mark() with a suitable BOOTSTAGE_ID from
+ bootstage.h. Only a single entry is recorded for each ID. You can
+ give the entry a name with bootstage_mark_name(). You can also
+ record elapsed time in a particular stage using bootstage_start()
+ before starting and bootstage_accum() when finished. Bootstage will
+ add up all the accumated time and report it.
+
+ Normally, IDs are defined in bootstage.h but a small number of
+ additional 'user' IDs can be used but passing BOOTSTAGE_ID_ALLOC
+ as the ID.
+
+ Calls to show_boot_progress() wil also result in log entries but
+ these will not have names.
+
+config BOOTSTAGE_REPORT
+ bool "Display a detailed boot timing report before booting the OS"
+ depends on BOOTSTAGE
+ help
+ Enable output of a boot time report just before the OS is booted.
+ This shows how long it took U-Boot to go through each stage of the
+ boot process. The report looks something like this:
+
+ Timer summary in microseconds:
+ Mark Elapsed Stage
+ 0 0 reset
+ 3,575,678 3,575,678 board_init_f start
+ 3,575,695 17 arch_cpu_init A9
+ 3,575,777 82 arch_cpu_init done
+ 3,659,598 83,821 board_init_r start
+ 3,910,375 250,777 main_loop
+ 29,916,167 26,005,792 bootm_start
+ 30,361,327 445,160 start_kernel
+
+config BOOTSTAGE_USER_COUNT
+ hex "Number of boot ID numbers available for user use"
+ default 20
+ help
+ This is the number of available user bootstage records.
+ Each time you call bootstage_mark(BOOTSTAGE_ID_ALLOC, ...)
+ a new ID will be allocated from this stash. If you exceed
+ the limit, recording will stop.
+
+config CMD_BOOTSTAGE
+ bool "Enable the 'bootstage' command"
+ depends on BOOTSTAGE
+ help
+ Add a 'bootstage' command which supports printing a report
+ and un/stashing of bootstage data.
+
+config BOOTSTAGE_FDT
+ bool "Store boot timing information in the OS device tree"
+ depends on BOOTSTAGE
+ help
+ Stash the bootstage information in the FDT. A root 'bootstage'
+ node is created with each bootstage id as a child. Each child
+ has a 'name' property and either 'mark' containing the
+ mark time in microsecond, or 'accum' containing the
+ accumulated time for that bootstage id in microseconds.
+ For example:
+
+ bootstage {
+ 154 {
+ name = "board_init_f";
+ mark = <3575678>;
+ };
+ 170 {
+ name = "lcd";
+ accum = <33482>;
+ };
+ };
+
+ Code in the Linux kernel can find this in /proc/devicetree.
+
+config BOOTSTAGE_STASH
+ bool "Stash the boot timing information in memory before booting OS"
+ depends on BOOTSTAGE
+ help
+ Some OSes do not support device tree. Bootstage can instead write
+ the boot timing information in a binary format at a given address.
+ This happens through a call to bootstage_stash(), typically in
+ the CPU's cleanup_before_linux() function. You can use the
+ 'bootstage stash' and 'bootstage unstash' commands to do this on
+ the command line.
+
+config BOOTSTAGE_STASH_ADDR
+ hex "Address to stash boot timing information"
+ default 0
+ help
+ Provide an address which will not be overwritten by the OS when it
+ starts, so that it can read this information when ready.
+
+config BOOTSTAGE_STASH_SIZE
+ hex "Size of boot timing stash region"
+ default 4096
+ help
+ This should be large enough to hold the bootstage stash. A value of
+ 4096 (4KiB) is normally plenty.
+
endmenu
endmenu
diff --git a/common/Makefile b/common/Makefile
index e545458..fba3830 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -152,7 +152,7 @@ obj-$(CONFIG_CMD_PXE) += cmd_pxe.o
obj-$(CONFIG_CMD_READ) += cmd_read.o
obj-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
obj-$(CONFIG_CMD_REISER) += cmd_reiser.o
-obj-$(CONFIG_SANDBOX) += cmd_sandbox.o
+obj-$(CONFIG_SANDBOX) += cmd_host.o
obj-$(CONFIG_CMD_SATA) += cmd_sata.o
obj-$(CONFIG_CMD_SF) += cmd_sf.o
obj-$(CONFIG_CMD_SCSI) += cmd_scsi.o
diff --git a/common/board_f.c b/common/board_f.c
index cb956b8..775df14 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -23,6 +23,7 @@
#include <i2c.h>
#include <initcall.h>
#include <logbuff.h>
+#include <mapmem.h>
/* TODO: Can we move these into arch/ headers? */
#ifdef CONFIG_8xx
@@ -815,6 +816,11 @@ __weak int reserve_arch(void)
return 0;
}
+__weak int arch_cpu_init_dm(void)
+{
+ return 0;
+}
+
static init_fnc_t init_sequence_f[] = {
#ifdef CONFIG_SANDBOX
setup_ram_buf,
@@ -835,6 +841,7 @@ static init_fnc_t init_sequence_f[] = {
fdtdec_check_fdt,
#endif
initf_dm,
+ arch_cpu_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 0335f6b..42ff18c 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -33,6 +33,7 @@
#endif
#include <logbuff.h>
#include <malloc.h>
+#include <mapmem.h>
#ifdef CONFIG_BITBANGMII
#include <miiphy.h>
#endif
@@ -230,7 +231,9 @@ static int initr_unlock_ram_in_cache(void)
#ifdef CONFIG_PCI
static int initr_pci(void)
{
+#ifndef CONFIG_DM_PCI
pci_init();
+#endif
return 0;
}
@@ -587,7 +590,7 @@ static int initr_bbmii(void)
static int initr_net(void)
{
puts("Net: ");
- eth_initialize(gd->bd);
+ eth_initialize();
#if defined(CONFIG_RESET_PHY_R)
debug("Reset Ethernet PHY\n");
reset_phy();
@@ -777,9 +780,6 @@ init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_PPC
initr_spi,
#endif
-#if defined(CONFIG_X86) && defined(CONFIG_SPI)
- init_func_spi,
-#endif
#ifdef CONFIG_CMD_NAND
initr_nand,
#endif
diff --git a/common/bootm.c b/common/bootm.c
index 34f60bb..6842029 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -13,6 +13,7 @@
#include <fdt_support.h>
#include <lmb.h>
#include <malloc.h>
+#include <mapmem.h>
#include <asm/io.h>
#include <linux/lzo.h>
#include <lzma/LzmaTypes.h>
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index aa81da2..f16d5c7 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -34,6 +34,7 @@ static void print_eth(int idx)
printf("%-12s= %s\n", name, val);
}
+#ifndef CONFIG_DM_ETH
__maybe_unused
static void print_eths(void)
{
@@ -52,6 +53,7 @@ static void print_eths(void)
printf("current eth = %s\n", eth_get_name());
printf("ip_addr = %s\n", getenv("ipaddr"));
}
+#endif
__maybe_unused
static void print_lnum(const char *name, unsigned long long value)
@@ -375,7 +377,7 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc,
print_num("-> size", bd->bi_dram[i].size);
}
-#if defined(CONFIG_CMD_NET)
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH)
print_eths();
#endif
printf("baudrate = %u bps\n", gd->baudrate);
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 4f77f22..6b6aca6 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -16,6 +16,7 @@
#include <image.h>
#include <lmb.h>
#include <malloc.h>
+#include <mapmem.h>
#include <nand.h>
#include <asm/byteorder.h>
#include <linux/compiler.h>
diff --git a/common/cmd_bootstage.c b/common/cmd_bootstage.c
index 106894a..788ab16 100644
--- a/common/cmd_bootstage.c
+++ b/common/cmd_bootstage.c
@@ -6,11 +6,6 @@
#include <common.h>
-#ifndef CONFIG_BOOTSTAGE_STASH
-#define CONFIG_BOOTSTAGE_STASH -1UL
-#define CONFIG_BOOTSTAGE_STASH_SIZE -1
-#endif
-
static int do_bootstage_report(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
@@ -24,7 +19,7 @@ static int get_base_size(int argc, char * const argv[], ulong *basep,
{
char *endp;
- *basep = CONFIG_BOOTSTAGE_STASH;
+ *basep = CONFIG_BOOTSTAGE_STASH_ADDR;
*sizep = CONFIG_BOOTSTAGE_STASH_SIZE;
if (argc < 2)
return 0;
diff --git a/common/cmd_demo.c b/common/cmd_demo.c
index 8a10bdf..209dc4a 100644
--- a/common/cmd_demo.c
+++ b/common/cmd_demo.c
@@ -9,6 +9,7 @@
#include <common.h>
#include <dm-demo.h>
+#include <mapmem.h>
#include <asm/io.h>
struct udevice *demo_dev;
diff --git a/common/cmd_elf.c b/common/cmd_elf.c
index c745371..22475dc 100644
--- a/common/cmd_elf.c
+++ b/common/cmd_elf.c
@@ -170,7 +170,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
* Check to see if we need to tftp the image ourselves before starting
*/
if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) {
- if (NetLoop(TFTPGET) <= 0)
+ if (net_loop(TFTPGET) <= 0)
return 1;
printf("Automatic boot of VxWorks image at address 0x%08lx ...\n",
addr);
diff --git a/common/cmd_fat.c b/common/cmd_fat.c
index c00fb28..aae993d 100644
--- a/common/cmd_fat.c
+++ b/common/cmd_fat.c
@@ -14,6 +14,7 @@
#include <net.h>
#include <ata.h>
#include <asm/io.h>
+#include <mapmem.h>
#include <part.h>
#include <fat.h>
#include <fs.h>
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
index 48b3e70..682b655 100644
--- a/common/cmd_fdt.c
+++ b/common/cmd_fdt.c
@@ -15,6 +15,7 @@
#include <asm/global_data.h>
#include <libfdt.h>
#include <fdt_support.h>
+#include <mapmem.h>
#include <asm/io.h>
#define MAX_LEVEL 32 /* how deeply nested we will go */
diff --git a/common/cmd_host.c b/common/cmd_host.c
new file mode 100644
index 0000000..ba1460e
--- /dev/null
+++ b/common/cmd_host.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2012, Google Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fs.h>
+#include <part.h>
+#include <sandboxblockdev.h>
+#include <asm/errno.h>
+
+static int host_curr_device = -1;
+
+static int do_host_load(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
+}
+
+static int do_host_ls(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
+}
+
+static int do_host_save(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
+}
+
+static int do_host_bind(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ if (argc < 2 || argc > 3)
+ return CMD_RET_USAGE;
+ char *ep;
+ char *dev_str = argv[1];
+ char *file = argc >= 3 ? argv[2] : NULL;
+ int dev = simple_strtoul(dev_str, &ep, 16);
+ if (*ep) {
+ printf("** Bad device specification %s **\n", dev_str);
+ return CMD_RET_USAGE;
+ }
+ return host_dev_bind(dev, file);
+}
+
+static int do_host_info(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ if (argc < 1 || argc > 2)
+ return CMD_RET_USAGE;
+ int min_dev = 0;
+ int max_dev = CONFIG_HOST_MAX_DEVICES - 1;
+ if (argc >= 2) {
+ char *ep;
+ char *dev_str = argv[1];
+ int dev = simple_strtoul(dev_str, &ep, 16);
+ if (*ep) {
+ printf("** Bad device specification %s **\n", dev_str);
+ return CMD_RET_USAGE;
+ }
+ min_dev = dev;
+ max_dev = dev;
+ }
+ int dev;
+ printf("%3s %12s %s\n", "dev", "blocks", "path");
+ for (dev = min_dev; dev <= max_dev; dev++) {
+ block_dev_desc_t *blk_dev;
+ int ret;
+
+ printf("%3d ", dev);
+ ret = host_get_dev_err(dev, &blk_dev);
+ if (ret) {
+ if (ret == -ENOENT)
+ puts("Not bound to a backing file\n");
+ else if (ret == -ENODEV)
+ puts("Invalid host device number\n");
+
+ continue;
+ }
+ struct host_block_dev *host_dev = blk_dev->priv;
+ printf("%12lu %s\n", (unsigned long)blk_dev->lba,
+ host_dev->filename);
+ }
+ return 0;
+}
+
+static int do_host_dev(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int dev;
+ char *ep;
+ block_dev_desc_t *blk_dev;
+ int ret;
+
+ if (argc < 1 || argc > 3)
+ return CMD_RET_USAGE;
+
+ if (argc == 1) {
+ if (host_curr_device < 0) {
+ printf("No current host device\n");
+ return 1;
+ }
+ printf("Current host device %d\n", host_curr_device);
+ return 0;
+ }
+
+ dev = simple_strtoul(argv[1], &ep, 16);
+ if (*ep) {
+ printf("** Bad device specification %s **\n", argv[2]);
+ return CMD_RET_USAGE;
+ }
+
+ ret = host_get_dev_err(dev, &blk_dev);
+ if (ret) {
+ if (ret == -ENOENT)
+ puts("Not bound to a backing file\n");
+ else if (ret == -ENODEV)
+ puts("Invalid host device number\n");
+
+ return 1;
+ }
+
+ host_curr_device = dev;
+ return 0;
+}
+
+static cmd_tbl_t cmd_host_sub[] = {
+ U_BOOT_CMD_MKENT(load, 7, 0, do_host_load, "", ""),
+ U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
+ U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
+ U_BOOT_CMD_MKENT(bind, 3, 0, do_host_bind, "", ""),
+ U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
+ U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
+};
+
+static int do_host(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ cmd_tbl_t *c;
+
+ /* Skip past 'host' */
+ argc--;
+ argv++;
+
+ c = find_cmd_tbl(argv[0], cmd_host_sub,
+ ARRAY_SIZE(cmd_host_sub));
+
+ if (c)
+ return c->cmd(cmdtp, flag, argc, argv);
+ else
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ sb, 8, 1, do_host,
+ "Deprecated: use 'host' command instead.", ""
+);
+
+U_BOOT_CMD(
+ host, 8, 1, do_host,
+ "Miscellaneous host commands",
+ "load hostfs - <addr> <filename> [<bytes> <offset>] - "
+ "load a file from host\n"
+ "host ls hostfs - <filename> - list files on host\n"
+ "host save hostfs - <addr> <filename> <bytes> [<offset>] - "
+ "save a file to host\n"
+ "host bind <dev> [<filename>] - bind \"host\" device to file\n"
+ "host info [<dev>] - show device binding & info\n"
+ "host dev [<dev>] - Set or retrieve the current host device\n"
+ "host commands use the \"hostfs\" device. The \"host\" device is used\n"
+ "with standard IO commands such as fatls or ext2load"
+);
diff --git a/common/cmd_lzmadec.c b/common/cmd_lzmadec.c
index 7b0b3fd..1ad9ed6 100644
--- a/common/cmd_lzmadec.c
+++ b/common/cmd_lzmadec.c
@@ -12,6 +12,7 @@
#include <common.h>
#include <command.h>
+#include <mapmem.h>
#include <asm/io.h>
#include <lzma/LzmaTools.h>
diff --git a/common/cmd_md5sum.c b/common/cmd_md5sum.c
index d22ace5..23bb81e 100644
--- a/common/cmd_md5sum.c
+++ b/common/cmd_md5sum.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <command.h>
+#include <mapmem.h>
#include <u-boot/md5.h>
#include <asm/io.h>
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 3f85c1a..45e471c 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -20,6 +20,7 @@
#endif
#include <hash.h>
#include <inttypes.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <asm/io.h>
#include <linux/compiler.h>
@@ -165,7 +166,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#endif
ulong addr, count;
int size;
- void *buf;
+ void *buf, *start;
ulong bytes;
if ((argc < 3) || (argc > 4))
@@ -197,7 +198,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
bytes = size * count;
- buf = map_sysmem(addr, bytes);
+ start = map_sysmem(addr, bytes);
+ buf = start;
while (count-- > 0) {
if (size == 4)
*((u32 *)buf) = (u32)writeval;
@@ -211,7 +213,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*((u8 *)buf) = (u8)writeval;
buf += size;
}
- unmap_sysmem(buf);
+ unmap_sysmem(start);
return 0;
}
diff --git a/common/cmd_net.c b/common/cmd_net.c
index 09489d4..b2f3c7b 100644
--- a/common/cmd_net.c
+++ b/common/cmd_net.c
@@ -44,10 +44,7 @@ U_BOOT_CMD(
#ifdef CONFIG_CMD_TFTPPUT
int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- int ret;
-
- ret = netboot_common(TFTPPUT, cmdtp, argc, argv);
- return ret;
+ return netboot_common(TFTPPUT, cmdtp, argc, argv);
}
U_BOOT_CMD(
@@ -117,24 +114,24 @@ static void netboot_update_env(void)
{
char tmp[22];
- if (NetOurGatewayIP) {
- ip_to_string(NetOurGatewayIP, tmp);
+ if (net_gateway.s_addr) {
+ ip_to_string(net_gateway, tmp);
setenv("gatewayip", tmp);
}
- if (NetOurSubnetMask) {
- ip_to_string(NetOurSubnetMask, tmp);
+ if (net_netmask.s_addr) {
+ ip_to_string(net_netmask, tmp);
setenv("netmask", tmp);
}
- if (NetOurHostName[0])
- setenv("hostname", NetOurHostName);
+ if (net_hostname[0])
+ setenv("hostname", net_hostname);
- if (NetOurRootPath[0])
- setenv("rootpath", NetOurRootPath);
+ if (net_root_path[0])
+ setenv("rootpath", net_root_path);
- if (NetOurIP) {
- ip_to_string(NetOurIP, tmp);
+ if (net_ip.s_addr) {
+ ip_to_string(net_ip, tmp);
setenv("ipaddr", tmp);
}
#if !defined(CONFIG_BOOTP_SERVERIP)
@@ -142,35 +139,33 @@ static void netboot_update_env(void)
* Only attempt to change serverip if net/bootp.c:BootpCopyNetParams()
* could have set it
*/
- if (NetServerIP) {
- ip_to_string(NetServerIP, tmp);
+ if (net_server_ip.s_addr) {
+ ip_to_string(net_server_ip, tmp);
setenv("serverip", tmp);
}
#endif
- if (NetOurDNSIP) {
- ip_to_string(NetOurDNSIP, tmp);
+ if (net_dns_server.s_addr) {
+ ip_to_string(net_dns_server, tmp);
setenv("dnsip", tmp);
}
#if defined(CONFIG_BOOTP_DNS2)
- if (NetOurDNS2IP) {
- ip_to_string(NetOurDNS2IP, tmp);
+ if (net_dns_server2.s_addr) {
+ ip_to_string(net_dns_server2, tmp);
setenv("dnsip2", tmp);
}
#endif
- if (NetOurNISDomain[0])
- setenv("domain", NetOurNISDomain);
+ if (net_nis_domain[0])
+ setenv("domain", net_nis_domain);
-#if defined(CONFIG_CMD_SNTP) \
- && defined(CONFIG_BOOTP_TIMEOFFSET)
- if (NetTimeOffset) {
- sprintf(tmp, "%d", NetTimeOffset);
+#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
+ if (net_ntp_time_offset) {
+ sprintf(tmp, "%d", net_ntp_time_offset);
setenv("timeoffset", tmp);
}
#endif
-#if defined(CONFIG_CMD_SNTP) \
- && defined(CONFIG_BOOTP_NTPSERVER)
- if (NetNtpServerIP) {
- ip_to_string(NetNtpServerIP, tmp);
+#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
+ if (net_ntp_server.s_addr) {
+ ip_to_string(net_ntp_server, tmp);
setenv("ntpserverip", tmp);
}
#endif
@@ -186,9 +181,9 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
ulong addr;
/* pre-set load_addr */
- if ((s = getenv("loadaddr")) != NULL) {
+ s = getenv("loadaddr");
+ if (s != NULL)
load_addr = simple_strtoul(s, NULL, 16);
- }
switch (argc) {
case 1:
@@ -204,22 +199,26 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
if (end == (argv[1] + strlen(argv[1])))
load_addr = addr;
else
- copy_filename(BootFile, argv[1], sizeof(BootFile));
+ copy_filename(net_boot_file_name, argv[1],
+ sizeof(net_boot_file_name));
break;
- case 3: load_addr = simple_strtoul(argv[1], NULL, 16);
- copy_filename(BootFile, argv[2], sizeof(BootFile));
+ case 3:
+ load_addr = simple_strtoul(argv[1], NULL, 16);
+ copy_filename(net_boot_file_name, argv[2],
+ sizeof(net_boot_file_name));
break;
#ifdef CONFIG_CMD_TFTPPUT
case 4:
if (strict_strtoul(argv[1], 16, &save_addr) < 0 ||
- strict_strtoul(argv[2], 16, &save_size) < 0) {
+ strict_strtoul(argv[2], 16, &save_size) < 0) {
printf("Invalid address/size\n");
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
- copy_filename(BootFile, argv[3], sizeof(BootFile));
+ copy_filename(net_boot_file_name, argv[3],
+ sizeof(net_boot_file_name));
break;
#endif
default:
@@ -228,19 +227,20 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
}
bootstage_mark(BOOTSTAGE_ID_NET_START);
- if ((size = NetLoop(proto)) < 0) {
+ size = net_loop(proto);
+ if (size < 0) {
bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
- return 1;
+ return CMD_RET_FAILURE;
}
bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
- /* NetLoop ok, update environment */
+ /* net_loop ok, update environment */
netboot_update_env();
/* done if no file was loaded (no errors though) */
if (size == 0) {
bootstage_error(BOOTSTAGE_ID_NET_LOADED);
- return 0;
+ return CMD_RET_SUCCESS;
}
/* flush cache */
@@ -250,10 +250,10 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
rcode = bootm_maybe_autostart(cmdtp, argv[0]);
- if (rcode < 0)
- bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
- else
+ if (rcode == CMD_RET_SUCCESS)
bootstage_mark(BOOTSTAGE_ID_NET_DONE);
+ else
+ bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
return rcode;
}
@@ -261,20 +261,20 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc < 2)
- return -1;
+ return CMD_RET_USAGE;
- NetPingIP = string_to_ip(argv[1]);
- if (NetPingIP == 0)
+ net_ping_ip = string_to_ip(argv[1]);
+ if (net_ping_ip.s_addr == 0)
return CMD_RET_USAGE;
- if (NetLoop(PING) < 0) {
+ if (net_loop(PING) < 0) {
printf("ping failed; host %s is not alive\n", argv[1]);
- return 1;
+ return CMD_RET_FAILURE;
}
printf("host %s is alive\n", argv[1]);
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -290,35 +290,35 @@ static void cdp_update_env(void)
{
char tmp[16];
- if (CDPApplianceVLAN != htons(-1)) {
- printf("CDP offered appliance VLAN %d\n", ntohs(CDPApplianceVLAN));
- VLAN_to_string(CDPApplianceVLAN, tmp);
+ if (cdp_appliance_vlan != htons(-1)) {
+ printf("CDP offered appliance VLAN %d\n",
+ ntohs(cdp_appliance_vlan));
+ vlan_to_string(cdp_appliance_vlan, tmp);
setenv("vlan", tmp);
- NetOurVLAN = CDPApplianceVLAN;
+ net_our_vlan = cdp_appliance_vlan;
}
- if (CDPNativeVLAN != htons(-1)) {
- printf("CDP offered native VLAN %d\n", ntohs(CDPNativeVLAN));
- VLAN_to_string(CDPNativeVLAN, tmp);
+ if (cdp_native_vlan != htons(-1)) {
+ printf("CDP offered native VLAN %d\n", ntohs(cdp_native_vlan));
+ vlan_to_string(cdp_native_vlan, tmp);
setenv("nvlan", tmp);
- NetOurNativeVLAN = CDPNativeVLAN;
+ net_native_vlan = cdp_native_vlan;
}
-
}
int do_cdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int r;
- r = NetLoop(CDP);
+ r = net_loop(CDP);
if (r < 0) {
printf("cdp failed; perhaps not a CISCO switch?\n");
- return 1;
+ return CMD_RET_FAILURE;
}
cdp_update_env();
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -334,32 +334,32 @@ int do_sntp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char *toff;
if (argc < 2) {
- NetNtpServerIP = getenv_IPaddr("ntpserverip");
- if (NetNtpServerIP == 0) {
+ net_ntp_server = getenv_ip("ntpserverip");
+ if (net_ntp_server.s_addr == 0) {
printf("ntpserverip not set\n");
- return (1);
+ return CMD_RET_FAILURE;
}
} else {
- NetNtpServerIP = string_to_ip(argv[1]);
- if (NetNtpServerIP == 0) {
+ net_ntp_server = string_to_ip(argv[1]);
+ if (net_ntp_server.s_addr == 0) {
printf("Bad NTP server IP address\n");
- return (1);
+ return CMD_RET_FAILURE;
}
}
toff = getenv("timeoffset");
if (toff == NULL)
- NetTimeOffset = 0;
+ net_ntp_time_offset = 0;
else
- NetTimeOffset = simple_strtol(toff, NULL, 10);
+ net_ntp_time_offset = simple_strtol(toff, NULL, 10);
- if (NetLoop(SNTP) < 0) {
+ if (net_loop(SNTP) < 0) {
printf("SNTP failed: host %pI4 not responding\n",
- &NetNtpServerIP);
- return 1;
+ &net_ntp_server);
+ return CMD_RET_FAILURE;
}
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -389,22 +389,22 @@ int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*/
if (strlen(argv[1]) >= 255) {
printf("dns error: hostname too long\n");
- return 1;
+ return CMD_RET_FAILURE;
}
- NetDNSResolve = argv[1];
+ net_dns_resolve = argv[1];
if (argc == 3)
- NetDNSenvvar = argv[2];
+ net_dns_env_var = argv[2];
else
- NetDNSenvvar = NULL;
+ net_dns_env_var = NULL;
- if (NetLoop(DNS) < 0) {
+ if (net_loop(DNS) < 0) {
printf("dns lookup of %s failed, check setup\n", argv[1]);
- return 1;
+ return CMD_RET_FAILURE;
}
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -421,21 +421,21 @@ static int do_link_local(cmd_tbl_t *cmdtp, int flag, int argc,
{
char tmp[22];
- if (NetLoop(LINKLOCAL) < 0)
- return 1;
+ if (net_loop(LINKLOCAL) < 0)
+ return CMD_RET_FAILURE;
- NetOurGatewayIP = 0;
- ip_to_string(NetOurGatewayIP, tmp);
+ net_gateway.s_addr = 0;
+ ip_to_string(net_gateway, tmp);
setenv("gatewayip", tmp);
- ip_to_string(NetOurSubnetMask, tmp);
+ ip_to_string(net_netmask, tmp);
setenv("netmask", tmp);
- ip_to_string(NetOurIP, tmp);
+ ip_to_string(net_ip, tmp);
setenv("ipaddr", tmp);
setenv("llipaddr", tmp); /* store this for next time */
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 855808c..be792ae 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -31,6 +31,7 @@
#include <search.h>
#include <errno.h>
#include <malloc.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <linux/stddef.h>
#include <asm/byteorder.h>
diff --git a/common/cmd_pci.c b/common/cmd_pci.c
index e3a77e3..dcecef8 100644
--- a/common/cmd_pci.c
+++ b/common/cmd_pci.c
@@ -48,6 +48,7 @@ void pciinfo(int BusNum, int ShortPCIListing)
unsigned char HeaderType;
unsigned short VendorID;
pci_dev_t dev;
+ int ret;
if (!hose)
return;
@@ -74,7 +75,10 @@ void pciinfo(int BusNum, int ShortPCIListing)
if (pci_skip_dev(hose, dev))
continue;
- pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID);
+ ret = pci_read_config_word(dev, PCI_VENDOR_ID,
+ &VendorID);
+ if (ret)
+ goto error;
if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
continue;
@@ -91,8 +95,12 @@ void pciinfo(int BusNum, int ShortPCIListing)
BusNum, Device, Function);
pci_header_show(dev);
}
- }
- }
+ }
+ }
+
+ return;
+error:
+ printf("Cannot read bus configuration: %d\n", ret);
}
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index 7e32c95..4cbb2b1 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -8,11 +8,13 @@
#include <common.h>
#include <command.h>
#include <malloc.h>
+#include <mapmem.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <errno.h>
#include <linux/list.h>
#include <fs.h>
+#include <asm/io.h>
#include "menu.h"
#include "cli.h"
@@ -188,11 +190,12 @@ static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
*
* Returns 1 for success, or < 0 on error.
*/
-static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
+static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
+ unsigned long file_addr)
{
size_t path_len;
char relfile[MAX_TFTP_PATH_LEN+1];
- char addr_buf[10];
+ char addr_buf[18];
int err;
err = get_bootfile_path(file_path, relfile, sizeof(relfile));
@@ -215,7 +218,7 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
printf("Retrieving file: %s\n", relfile);
- sprintf(addr_buf, "%p", file_addr);
+ sprintf(addr_buf, "%lx", file_addr);
return do_getfile(cmdtp, relfile, addr_buf);
}
@@ -227,11 +230,13 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
*
* Returns 1 on success, or < 0 for error.
*/
-static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
+static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
+ unsigned long file_addr)
{
unsigned long config_file_size;
char *tftp_filesize;
int err;
+ char *buf;
err = get_relfile(cmdtp, file_path, file_addr);
@@ -250,7 +255,9 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr
if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0)
return -EINVAL;
- *(char *)(file_addr + config_file_size) = '\0';
+ buf = map_sysmem(file_addr + config_file_size, 1);
+ *buf = '\0';
+ unmap_sysmem(buf);
return 1;
}
@@ -266,7 +273,8 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr
*
* Returns 1 on success or < 0 on error.
*/
-static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_addr_r)
+static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file,
+ unsigned long pxefile_addr_r)
{
size_t base_len = strlen(PXELINUX_DIR);
char path[MAX_TFTP_PATH_LEN+1];
@@ -287,7 +295,7 @@ static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_a
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
{
char *uuid_str;
@@ -305,7 +313,7 @@ static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
{
char mac_str[21];
int err;
@@ -325,12 +333,12 @@ static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
{
char ip_addr[9];
int mask_pos, err;
- sprintf(ip_addr, "%08X", ntohl(NetOurIP));
+ sprintf(ip_addr, "%08X", ntohl(net_ip.s_addr));
for (mask_pos = 7; mask_pos >= 0; mask_pos--) {
err = get_pxelinux_path(cmdtp, ip_addr, pxefile_addr_r);
@@ -384,9 +392,9 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
* Keep trying paths until we successfully get a file we're looking
* for.
*/
- if (pxe_uuid_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
- pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
- pxe_ipaddr_paths(cmdtp, (void *)pxefile_addr_r) > 0) {
+ if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 ||
+ pxe_mac_path(cmdtp, pxefile_addr_r) > 0 ||
+ pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) {
printf("Config file found\n");
return 0;
@@ -394,7 +402,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
while (pxe_default_paths[i]) {
if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
- (void *)pxefile_addr_r) > 0) {
+ pxefile_addr_r) > 0) {
printf("Config file found\n");
return 0;
}
@@ -427,7 +435,7 @@ static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const ch
if (strict_strtoul(envaddr, 16, &file_addr) < 0)
return -EINVAL;
- return get_relfile(cmdtp, file_path, (void *)file_addr);
+ return get_relfile(cmdtp, file_path, file_addr);
}
/*
@@ -790,6 +798,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
else
do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
#endif
+ unmap_sysmem(buf);
return 1;
}
@@ -1054,7 +1063,8 @@ static int parse_integer(char **c, int *dst)
return 1;
}
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level);
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
+ struct pxe_menu *cfg, int nest_level);
/*
* Parse an include statement, and retrieve and parse the file it mentions.
@@ -1064,12 +1074,14 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
* include, nest_level has already been incremented and doesn't need to be
* incremented here.
*/
-static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
+static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base,
struct pxe_menu *cfg, int nest_level)
{
char *include_path;
char *s = *c;
int err;
+ char *buf;
+ int ret;
err = parse_sliteral(c, &include_path);
@@ -1086,20 +1098,25 @@ static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
return err;
}
- return parse_pxefile_top(cmdtp, base, cfg, nest_level);
+ buf = map_sysmem(base, 0);
+ ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level);
+ unmap_sysmem(buf);
+
+ return ret;
}
/*
* Parse lines that begin with 'menu'.
*
- * b and nest are provided to handle the 'menu include' case.
+ * base and nest are provided to handle the 'menu include' case.
*
- * b should be the address where the file currently being parsed is stored.
+ * base should point to a location where it's safe to store the included file.
*
* nest_level should be 1 when parsing the top level pxe file, 2 when parsing
* a file it includes, 3 when parsing a file included by that file, and so on.
*/
-static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, int nest_level)
+static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
+ unsigned long base, int nest_level)
{
struct token t;
char *s = *c;
@@ -1114,7 +1131,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b,
break;
case T_INCLUDE:
- err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg,
+ err = handle_include(cmdtp, c, base, cfg,
nest_level + 1);
break;
@@ -1281,7 +1298,8 @@ static int parse_label(char **c, struct pxe_menu *cfg)
*
* Returns 1 on success, < 0 on error.
*/
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level)
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
+ struct pxe_menu *cfg, int nest_level)
{
struct token t;
char *s, *b, *label_name;
@@ -1303,7 +1321,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
switch (t.type) {
case T_MENU:
cfg->prompt = 1;
- err = parse_menu(cmdtp, &p, cfg, b, nest_level);
+ err = parse_menu(cmdtp, &p, cfg,
+ base + ALIGN(strlen(b) + 1, 4),
+ nest_level);
break;
case T_TIMEOUT:
@@ -1328,8 +1348,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
break;
case T_INCLUDE:
- err = handle_include(cmdtp, &p, b + ALIGN(strlen(b), 4), cfg,
- nest_level + 1);
+ err = handle_include(cmdtp, &p,
+ base + ALIGN(strlen(b), 4), cfg,
+ nest_level + 1);
break;
case T_PROMPT:
@@ -1385,9 +1406,11 @@ static void destroy_pxe_menu(struct pxe_menu *cfg)
* files it includes). The resulting pxe_menu struct can be free()'d by using
* the destroy_pxe_menu() function.
*/
-static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
+static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg)
{
struct pxe_menu *cfg;
+ char *buf;
+ int r;
cfg = malloc(sizeof(struct pxe_menu));
@@ -1398,7 +1421,11 @@ static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
INIT_LIST_HEAD(&cfg->labels);
- if (parse_pxefile_top(cmdtp, menucfg, cfg, 1) < 0) {
+ buf = map_sysmem(menucfg, 0);
+ r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1);
+ unmap_sysmem(buf);
+
+ if (r < 0) {
destroy_pxe_menu(cfg);
return NULL;
}
@@ -1556,7 +1583,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
+ cfg = parse_pxefile(cmdtp, pxefile_addr_r);
if (cfg == NULL) {
printf("Error parsing config file\n");
@@ -1567,7 +1594,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
destroy_pxe_menu(cfg);
- copy_filename(BootFile, "", sizeof(BootFile));
+ copy_filename(net_boot_file_name, "", sizeof(net_boot_file_name));
return 0;
}
@@ -1663,12 +1690,12 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- if (get_pxe_file(cmdtp, filename, (void *)pxefile_addr_r) < 0) {
+ if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
printf("Error reading config file\n");
return 1;
}
- cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
+ cfg = parse_pxefile(cmdtp, pxefile_addr_r);
if (cfg == NULL) {
printf("Error parsing config file\n");
diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c
deleted file mode 100644
index 4286969..0000000
--- a/common/cmd_sandbox.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2012, Google Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <fs.h>
-#include <part.h>
-#include <sandboxblockdev.h>
-#include <asm/errno.h>
-
-static int do_sandbox_load(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
-}
-
-static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
-}
-
-static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
-}
-
-static int do_sandbox_bind(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- if (argc < 2 || argc > 3)
- return CMD_RET_USAGE;
- char *ep;
- char *dev_str = argv[1];
- char *file = argc >= 3 ? argv[2] : NULL;
- int dev = simple_strtoul(dev_str, &ep, 16);
- if (*ep) {
- printf("** Bad device specification %s **\n", dev_str);
- return CMD_RET_USAGE;
- }
- return host_dev_bind(dev, file);
-}
-
-static int do_sandbox_info(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- if (argc < 1 || argc > 2)
- return CMD_RET_USAGE;
- int min_dev = 0;
- int max_dev = CONFIG_HOST_MAX_DEVICES - 1;
- if (argc >= 2) {
- char *ep;
- char *dev_str = argv[1];
- int dev = simple_strtoul(dev_str, &ep, 16);
- if (*ep) {
- printf("** Bad device specification %s **\n", dev_str);
- return CMD_RET_USAGE;
- }
- min_dev = dev;
- max_dev = dev;
- }
- int dev;
- printf("%3s %12s %s\n", "dev", "blocks", "path");
- for (dev = min_dev; dev <= max_dev; dev++) {
- block_dev_desc_t *blk_dev;
- int ret;
-
- printf("%3d ", dev);
- ret = host_get_dev_err(dev, &blk_dev);
- if (ret) {
- if (ret == -ENOENT)
- puts("Not bound to a backing file\n");
- else if (ret == -ENODEV)
- puts("Invalid host device number\n");
-
- continue;
- }
- struct host_block_dev *host_dev = blk_dev->priv;
- printf("%12lu %s\n", (unsigned long)blk_dev->lba,
- host_dev->filename);
- }
- return 0;
-}
-
-static cmd_tbl_t cmd_sandbox_sub[] = {
- U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""),
- U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""),
- U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""),
- U_BOOT_CMD_MKENT(bind, 3, 0, do_sandbox_bind, "", ""),
- U_BOOT_CMD_MKENT(info, 3, 0, do_sandbox_info, "", ""),
-};
-
-static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- cmd_tbl_t *c;
-
- /* Skip past 'sandbox' */
- argc--;
- argv++;
-
- c = find_cmd_tbl(argv[0], cmd_sandbox_sub,
- ARRAY_SIZE(cmd_sandbox_sub));
-
- if (c)
- return c->cmd(cmdtp, flag, argc, argv);
- else
- return CMD_RET_USAGE;
-}
-
-U_BOOT_CMD(
- sb, 8, 1, do_sandbox,
- "Miscellaneous sandbox commands",
- "load hostfs - <addr> <filename> [<bytes> <offset>] - "
- "load a file from host\n"
- "sb ls hostfs - <filename> - list files on host\n"
- "sb save hostfs - <addr> <filename> <bytes> [<offset>] - "
- "save a file to host\n"
- "sb bind <dev> [<filename>] - bind \"host\" device to file\n"
- "sb info [<dev>] - show device binding & info\n"
- "sb commands use the \"hostfs\" device. The \"host\" device is used\n"
- "with standard IO commands such as fatls or ext2load"
-);
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 5c788e9..6aabf39 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -10,6 +10,7 @@
#include <div64.h>
#include <dm.h>
#include <malloc.h>
+#include <mapmem.h>
#include <spi.h>
#include <spi_flash.h>
@@ -130,7 +131,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])
return 1;
}
- flash = new->uclass_priv;
+ flash = dev_get_uclass_priv(new);
#else
new = spi_flash_probe(bus, cs, speed, mode);
if (!new) {
diff --git a/common/cmd_source.c b/common/cmd_source.c
index 6881bc9..d2a881d 100644
--- a/common/cmd_source.c
+++ b/common/cmd_source.c
@@ -19,6 +19,7 @@
#include <command.h>
#include <image.h>
#include <malloc.h>
+#include <mapmem.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#if defined(CONFIG_8xx)
diff --git a/common/cmd_trace.c b/common/cmd_trace.c
index 8c630e6..1e62a1a 100644
--- a/common/cmd_trace.c
+++ b/common/cmd_trace.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <command.h>
+#include <mapmem.h>
#include <trace.h>
#include <asm/io.h>
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 27813f0..eab55cd 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -2,6 +2,9 @@
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
+ * Adapted for U-Boot driver model
+ * (C) Copyright 2015 Google, Inc
+ *
* Most of this source has been derived from the Linux USB
* project.
*
@@ -10,6 +13,7 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <part.h>
@@ -252,18 +256,57 @@ static void usb_display_config(struct usb_device *dev)
printf("\n");
}
+/*
+ * With driver model this isn't right since we can have multiple controllers
+ * and the device numbering starts at 1 on each bus.
+ * TODO(sjg@chromium.org): Add a way to specify the controller/bus.
+ */
static struct usb_device *usb_find_device(int devnum)
{
- struct usb_device *dev;
+#ifdef CONFIG_DM_USB
+ struct usb_device *udev;
+ struct udevice *hub;
+ struct uclass *uc;
+ int ret;
+
+ /* Device addresses start at 1 */
+ devnum++;
+ ret = uclass_get(UCLASS_USB_HUB, &uc);
+ if (ret)
+ return NULL;
+
+ uclass_foreach_dev(hub, uc) {
+ struct udevice *dev;
+
+ if (!device_active(hub))
+ continue;
+ udev = dev_get_parentdata(hub);
+ if (udev->devnum == devnum)
+ return udev;
+
+ for (device_find_first_child(hub, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ if (!device_active(hub))
+ continue;
+
+ udev = dev_get_parentdata(dev);
+ if (udev->devnum == devnum)
+ return udev;
+ }
+ }
+#else
+ struct usb_device *udev;
int d;
for (d = 0; d < USB_MAX_DEVICE; d++) {
- dev = usb_get_dev_index(d);
- if (dev == NULL)
+ udev = usb_get_dev_index(d);
+ if (udev == NULL)
return NULL;
- if (dev->devnum == devnum)
- return dev;
+ if (udev->devnum == devnum)
+ return udev;
}
+#endif
return NULL;
}
@@ -293,20 +336,31 @@ static inline char *portspeed(int speed)
/* shows the device tree recursively */
static void usb_show_tree_graph(struct usb_device *dev, char *pre)
{
- int i, index;
+ int index;
int has_child, last_child;
index = strlen(pre);
printf(" %s", pre);
+#ifdef CONFIG_DM_USB
+ has_child = device_has_active_children(dev->dev);
+#else
/* check if the device has connected children */
+ int i;
+
has_child = 0;
for (i = 0; i < dev->maxchild; i++) {
if (dev->children[i] != NULL)
has_child = 1;
}
+#endif
/* check if we are the last one */
- last_child = 1;
- if (dev->parent != NULL) {
+#ifdef CONFIG_DM_USB
+ last_child = device_is_last_sibling(dev->dev);
+#else
+ last_child = (dev->parent != NULL);
+#endif
+ if (last_child) {
+#ifndef CONFIG_DM_USB
for (i = 0; i < dev->parent->maxchild; i++) {
/* search for children */
if (dev->parent->children[i] == dev) {
@@ -322,9 +376,10 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
} /* while */
} /* device found */
} /* for all children of the parent */
+#endif
printf("\b+-");
/* correct last child */
- if (last_child)
+ if (last_child && index)
pre[index-1] = ' ';
} /* if not root hub */
else
@@ -340,6 +395,26 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
printf(" %s %s %s %s\n", pre, dev->mf, dev->prod, dev->serial);
printf(" %s\n", pre);
+#ifdef CONFIG_DM_USB
+ struct udevice *child;
+
+ for (device_find_first_child(dev->dev, &child);
+ child;
+ device_find_next_child(&child)) {
+ struct usb_device *udev;
+
+ if (!device_active(child))
+ continue;
+
+ udev = dev_get_parentdata(child);
+
+ /* Ignore emulators, we only want real devices */
+ if (device_get_uclass_id(child) != UCLASS_USB_EMUL) {
+ usb_show_tree_graph(udev, pre);
+ pre[index] = 0;
+ }
+ }
+#else
if (dev->maxchild > 0) {
for (i = 0; i < dev->maxchild; i++) {
if (dev->children[i] != NULL) {
@@ -348,6 +423,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
}
}
}
+#endif
}
/* main routine for the tree command */
@@ -355,7 +431,7 @@ static void usb_show_tree(struct usb_device *dev)
{
char preamble[32];
- memset(preamble, 0, 32);
+ memset(preamble, '\0', sizeof(preamble));
usb_show_tree_graph(dev, &preamble[0]);
}
@@ -448,10 +524,13 @@ static void do_usb_start(void)
if (usb_init() < 0)
return;
+ /* Driver model will probe the devices as they are found */
+#ifndef CONFIG_DM_USB
#ifdef CONFIG_USB_STORAGE
/* try to recognize storage devices immediately */
usb_stor_curr_dev = usb_stor_scan(1);
#endif
+#endif
#ifdef CONFIG_USB_HOST_ETHER
/* try to recognize ethernet devices immediately */
usb_ether_curr_dev = usb_host_eth_scan(1);
@@ -461,14 +540,50 @@ static void do_usb_start(void)
#endif
}
+#ifdef CONFIG_DM_USB
+static void show_info(struct udevice *dev)
+{
+ struct udevice *child;
+ struct usb_device *udev;
+
+ udev = dev_get_parentdata(dev);
+ usb_display_desc(udev);
+ usb_display_config(udev);
+ for (device_find_first_child(dev, &child);
+ child;
+ device_find_next_child(&child)) {
+ if (device_active(child))
+ show_info(child);
+ }
+}
+
+static int usb_device_info(void)
+{
+ struct udevice *bus;
+
+ for (uclass_first_device(UCLASS_USB, &bus);
+ bus;
+ uclass_next_device(&bus)) {
+ struct udevice *hub;
+
+ device_find_first_child(bus, &hub);
+ if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
+ device_active(hub)) {
+ show_info(hub);
+ }
+ }
+
+ return 0;
+}
+#endif
+
/******************************************************************************
* usb command intepreter
*/
static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
-
+ struct usb_device *udev = NULL;
int i;
- struct usb_device *dev = NULL;
extern char usb_started;
#ifdef CONFIG_USB_STORAGE
block_dev_desc_t *stor_dev;
@@ -508,36 +623,63 @@ 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 *hub;
+
+ device_find_first_child(bus, &hub);
+ if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
+ device_active(hub)) {
+ udev = dev_get_parentdata(hub);
+ usb_show_tree(udev);
+ }
+ }
+#else
for (i = 0; i < USB_MAX_DEVICE; i++) {
- dev = usb_get_dev_index(i);
- if (dev == NULL)
+ udev = usb_get_dev_index(i);
+ if (udev == NULL)
break;
- if (dev->parent == NULL)
- usb_show_tree(dev);
+ if (udev->parent == NULL)
+ usb_show_tree(udev);
}
+#endif
return 0;
}
if (strncmp(argv[1], "inf", 3) == 0) {
- int d;
if (argc == 2) {
+#ifdef CONFIG_DM_USB
+ usb_device_info();
+#else
+ int d;
for (d = 0; d < USB_MAX_DEVICE; d++) {
- dev = usb_get_dev_index(d);
- if (dev == NULL)
+ udev = usb_get_dev_index(d);
+ if (udev == NULL)
break;
- usb_display_desc(dev);
- usb_display_config(dev);
+ usb_display_desc(udev);
+ usb_display_config(udev);
}
+#endif
return 0;
} else {
+ /*
+ * With driver model this isn't right since we can
+ * have multiple controllers and the device numbering
+ * starts at 1 on each bus.
+ */
i = simple_strtoul(argv[2], NULL, 10);
printf("config for device %d\n", i);
- dev = usb_find_device(i);
- if (dev == NULL) {
+ udev = usb_find_device(i);
+ if (udev == NULL) {
printf("*** No device available ***\n");
return 0;
} else {
- usb_display_desc(dev);
- usb_display_config(dev);
+ usb_display_desc(udev);
+ usb_display_config(udev);
}
}
return 0;
@@ -546,13 +688,13 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc < 5)
return CMD_RET_USAGE;
i = simple_strtoul(argv[2], NULL, 10);
- dev = usb_find_device(i);
- if (dev == NULL) {
+ udev = usb_find_device(i);
+ if (udev == NULL) {
printf("Device %d does not exist.\n", i);
return 1;
}
i = simple_strtoul(argv[3], NULL, 10);
- return usb_test(dev, i, argv[4]);
+ return usb_test(udev, i, argv[4]);
}
#ifdef CONFIG_USB_STORAGE
if (strncmp(argv[1], "stor", 4) == 0)
diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c
index 64b9186..8b8645c 100644
--- a/common/cmd_ximg.c
+++ b/common/cmd_ximg.c
@@ -15,6 +15,7 @@
#include <common.h>
#include <command.h>
#include <image.h>
+#include <mapmem.h>
#include <watchdog.h>
#if defined(CONFIG_BZIP2)
#include <bzlib.h>
diff --git a/common/cros_ec.c b/common/cros_ec.c
index bb299bc..7a4f785 100644
--- a/common/cros_ec.c
+++ b/common/cros_ec.c
@@ -15,18 +15,8 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifndef CONFIG_DM_CROS_EC
-struct local_info {
- struct cros_ec_dev *cros_ec_dev; /* Pointer to cros_ec device */
- int cros_ec_err; /* Error for cros_ec, 0 if ok */
-};
-
-static struct local_info local;
-#endif
-
struct cros_ec_dev *board_get_cros_ec_dev(void)
{
-#ifdef CONFIG_DM_CROS_EC
struct udevice *dev;
int ret;
@@ -35,31 +25,11 @@ struct cros_ec_dev *board_get_cros_ec_dev(void)
debug("%s: Error %d\n", __func__, ret);
return NULL;
}
- return dev->uclass_priv;
-#else
- return local.cros_ec_dev;
-#endif
-}
-
-static int board_init_cros_ec_devices(const void *blob)
-{
-#ifndef CONFIG_DM_CROS_EC
- local.cros_ec_err = cros_ec_init(blob, &local.cros_ec_dev);
- if (local.cros_ec_err)
- return -1; /* Will report in board_late_init() */
-#endif
-
- return 0;
-}
-
-int cros_ec_board_init(void)
-{
- return board_init_cros_ec_devices(gd->fdt_blob);
+ return dev_get_uclass_priv(dev);
}
int cros_ec_get_error(void)
{
-#ifdef CONFIG_DM_CROS_EC
struct udevice *dev;
int ret;
@@ -68,7 +38,4 @@ int cros_ec_get_error(void)
return ret;
return 0;
-#else
- return local.cros_ec_err;
-#endif
}
diff --git a/common/hash.c b/common/hash.c
index 9e9f84b..c94c98b 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -14,6 +14,7 @@
#include <common.h>
#include <command.h>
#include <malloc.h>
+#include <mapmem.h>
#include <hw_sha.h>
#include <asm/io.h>
#include <asm/errno.h>
diff --git a/common/image-fdt.c b/common/image-fdt.c
index d9e4728..7e2da7b 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -14,6 +14,7 @@
#include <errno.h>
#include <image.h>
#include <libfdt.h>
+#include <mapmem.h>
#include <asm/io.h>
#ifndef CONFIG_SYS_FDT_PAD
diff --git a/common/image-fit.c b/common/image-fit.c
index 778d2a1..4eb4d42 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -16,6 +16,7 @@
#else
#include <common.h>
#include <errno.h>
+#include <mapmem.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
#endif /* !USE_HOSTCC*/
diff --git a/common/image.c b/common/image.c
index 162b682..abc0d89 100644
--- a/common/image.c
+++ b/common/image.c
@@ -27,6 +27,7 @@
#include <environment.h>
#include <image.h>
+#include <mapmem.h>
#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
diff --git a/common/iotrace.c b/common/iotrace.c
index ced426e..2725563 100644
--- a/common/iotrace.c
+++ b/common/iotrace.c
@@ -7,6 +7,7 @@
#define IOTRACE_IMPL
#include <common.h>
+#include <mapmem.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/common/lcd.c b/common/lcd.c
index aab73d8..055c366 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <stdio_dev.h>
#include <lcd.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <asm/unaligned.h>
#include <splash.h>
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
index 64ae036..d445199 100644
--- a/common/malloc_simple.c
+++ b/common/malloc_simple.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <malloc.h>
+#include <mapmem.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/common/miiphyutil.c b/common/miiphyutil.c
index 74812e6..c88c28a 100644
--- a/common/miiphyutil.c
+++ b/common/miiphyutil.c
@@ -11,6 +11,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <miiphy.h>
#include <phy.h>
diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c
index ff53705..217a435 100644
--- a/common/spl/spl_net.c
+++ b/common/spl/spl_net.c
@@ -21,14 +21,14 @@ void spl_net_load_image(const char *device)
env_relocate();
setenv("autoload", "yes");
load_addr = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header);
- rv = eth_initialize(gd->bd);
+ rv = eth_initialize();
if (rv == 0) {
printf("No Ethernet devices found\n");
hang();
}
if (device)
setenv("ethact", device);
- rv = NetLoop(BOOTP);
+ rv = net_loop(BOOTP);
if (rv < 0) {
printf("Problem booting with BOOTP\n");
hang();
diff --git a/common/update.c b/common/update.c
index cc830a7..1c6aa18 100644
--- a/common/update.c
+++ b/common/update.c
@@ -39,8 +39,8 @@
#define CONFIG_UPDATE_TFTP_CNT_MAX 0
#endif
-extern ulong TftpRRQTimeoutMSecs;
-extern int TftpRRQTimeoutCountMax;
+extern ulong tftp_timeout_ms;
+extern int tftp_timeout_count_max;
extern flash_info_t flash_info[];
extern ulong load_addr;
@@ -55,22 +55,22 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
rv = 0;
/* save used globals and env variable */
- saved_timeout_msecs = TftpRRQTimeoutMSecs;
- saved_timeout_count = TftpRRQTimeoutCountMax;
+ saved_timeout_msecs = tftp_timeout_ms;
+ saved_timeout_count = tftp_timeout_count_max;
saved_netretry = strdup(getenv("netretry"));
- saved_bootfile = strdup(BootFile);
+ saved_bootfile = strdup(net_boot_file_name);
/* set timeouts for auto-update */
- TftpRRQTimeoutMSecs = msec_max;
- TftpRRQTimeoutCountMax = cnt_max;
+ tftp_timeout_ms = msec_max;
+ tftp_timeout_count_max = cnt_max;
/* we don't want to retry the connection if errors occur */
setenv("netretry", "no");
/* download the update file */
load_addr = addr;
- copy_filename(BootFile, filename, sizeof(BootFile));
- size = NetLoop(TFTPGET);
+ copy_filename(net_boot_file_name, filename, sizeof(net_boot_file_name));
+ size = net_loop(TFTPGET);
if (size < 0)
rv = 1;
@@ -78,15 +78,16 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
flush_cache(addr, size);
/* restore changed globals and env variable */
- TftpRRQTimeoutMSecs = saved_timeout_msecs;
- TftpRRQTimeoutCountMax = saved_timeout_count;
+ tftp_timeout_ms = saved_timeout_msecs;
+ tftp_timeout_count_max = saved_timeout_count;
setenv("netretry", saved_netretry);
if (saved_netretry != NULL)
free(saved_netretry);
if (saved_bootfile != NULL) {
- copy_filename(BootFile, saved_bootfile, sizeof(BootFile));
+ copy_filename(net_boot_file_name, saved_bootfile,
+ sizeof(net_boot_file_name));
free(saved_bootfile);
}
diff --git a/common/usb.c b/common/usb.c
index d94640a..a4820d3 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -28,6 +28,7 @@
*/
#include <common.h>
#include <command.h>
+#include <dm.h>
#include <asm/processor.h>
#include <linux/compiler.h>
#include <linux/ctype.h>
@@ -41,12 +42,13 @@
#define USB_BUFSIZ 512
-static struct usb_device usb_dev[USB_MAX_DEVICE];
-static int dev_index;
static int asynch_allowed;
-
char usb_started; /* flag for the started/stopped USB status */
+#ifndef CONFIG_DM_USB
+static struct usb_device usb_dev[USB_MAX_DEVICE];
+static int dev_index;
+
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#endif
@@ -94,8 +96,8 @@ int usb_init(void)
controllers_initialized++;
start_index = dev_index;
printf("scanning bus %d for devices... ", i);
- dev = usb_alloc_new_device(ctrl);
- if (!dev)
+ ret = usb_alloc_new_device(ctrl, &dev);
+ if (ret)
break;
/*
@@ -104,7 +106,7 @@ int usb_init(void)
*/
ret = usb_new_device(dev);
if (ret)
- usb_free_device();
+ usb_free_device(dev->controller);
if (start_index == dev_index) {
puts("No USB Device found\n");
@@ -158,6 +160,7 @@ int usb_disable_asynch(int disable)
asynch_allowed = !disable;
return old_value;
}
+#endif /* !CONFIG_DM_USB */
/*-------------------------------------------------------------------
@@ -821,6 +824,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
* the USB device are static allocated [USB_MAX_DEVICE].
*/
+#ifndef CONFIG_DM_USB
/* returns a pointer to the device with the index [index].
* if the device is not assigned (dev->devnum==-1) returns NULL
@@ -833,16 +837,13 @@ struct usb_device *usb_get_dev_index(int index)
return &usb_dev[index];
}
-/* returns a pointer of a new device structure or NULL, if
- * no device struct is available
- */
-struct usb_device *usb_alloc_new_device(void *controller)
+int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp)
{
int i;
debug("New Device %d\n", dev_index);
if (dev_index == USB_MAX_DEVICE) {
printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);
- return NULL;
+ return -ENOSPC;
}
/* default Address is 0, real addresses start with 1 */
usb_dev[dev_index].devnum = dev_index + 1;
@@ -852,7 +853,9 @@ struct usb_device *usb_alloc_new_device(void *controller)
usb_dev[dev_index].parent = NULL;
usb_dev[dev_index].controller = controller;
dev_index++;
- return &usb_dev[dev_index - 1];
+ *devp = &usb_dev[dev_index - 1];
+
+ return 0;
}
/*
@@ -860,7 +863,7 @@ struct usb_device *usb_alloc_new_device(void *controller)
* Called in error cases where configuring a newly attached
* device fails for some reason.
*/
-void usb_free_device(void)
+void usb_free_device(struct udevice *controller)
{
dev_index--;
debug("Freeing device node: %d\n", dev_index);
@@ -878,123 +881,101 @@ __weak int usb_alloc_device(struct usb_device *udev)
{
return 0;
}
-/*
- * By the time we get here, the device has gotten a new device ID
- * and is in the default state. We need to identify the thing and
- * get the ball rolling..
- *
- * Returns 0 for success, != 0 for error.
- */
-int usb_new_device(struct usb_device *dev)
+#endif /* !CONFIG_DM_USB */
+
+#ifndef CONFIG_DM_USB
+int usb_legacy_port_reset(struct usb_device *hub, int portnr)
{
- int addr, err;
- int tmp;
- ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+ if (hub) {
+ unsigned short portstatus;
+ int err;
- /*
- * Allocate usb 3.0 device context.
- * USB 3.0 (xHCI) protocol tries to allocate device slot
- * and related data structures first. This call does that.
- * Refer to sec 4.3.2 in xHCI spec rev1.0
- */
- if (usb_alloc_device(dev)) {
- printf("Cannot allocate device context to get SLOT_ID\n");
- return -EINVAL;
+ /* reset the port for the second time */
+ err = legacy_hub_port_reset(hub, portnr - 1, &portstatus);
+ if (err < 0) {
+ printf("\n Couldn't reset port %i\n", portnr);
+ return err;
+ }
+ } else {
+ usb_reset_root_port();
}
- /* We still haven't set the Address yet */
- addr = dev->devnum;
- dev->devnum = 0;
+ return 0;
+}
+#endif
-#ifdef CONFIG_LEGACY_USB_INIT_SEQ
- /* this is the old and known way of initializing devices, it is
- * different than what Windows and Linux are doing. Windows and Linux
- * both retrieve 64 bytes while reading the device descriptor
- * Several USB stick devices report ERR: CTL_TIMEOUT, caused by an
- * invalid header while reading 8 bytes as device descriptor. */
- dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
- dev->maxpacketsize = PACKET_SIZE_8;
- dev->epmaxpacketin[0] = 8;
- dev->epmaxpacketout[0] = 8;
-
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, tmpbuf, 8);
- if (err < 8) {
- printf("\n USB device not responding, " \
- "giving up (status=%lX)\n", dev->status);
- return -EIO;
+static int get_descriptor_len(struct usb_device *dev, int len, int expect_len)
+{
+ __maybe_unused struct usb_device_descriptor *desc;
+ ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+ int err;
+
+ desc = (struct usb_device_descriptor *)tmpbuf;
+
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, len);
+ if (err < expect_len) {
+ if (err < 0) {
+ printf("unable to get device descriptor (error=%d)\n",
+ err);
+ return err;
+ } else {
+ printf("USB device descriptor short read (expected %i, got %i)\n",
+ expect_len, err);
+ return -EIO;
+ }
}
- memcpy(&dev->descriptor, tmpbuf, 8);
-#else
- /* This is a Windows scheme of initialization sequence, with double
+ memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
+
+ return 0;
+}
+
+static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
+{
+ __maybe_unused struct usb_device_descriptor *desc;
+
+ /*
+ * This is a Windows scheme of initialization sequence, with double
* reset of the device (Linux uses the same sequence)
* Some equipment is said to work only with such init sequence; this
* patch is based on the work by Alan Stern:
* http://sourceforge.net/mailarchive/forum.php?
* thread_id=5729457&forum_id=5398
*/
- __maybe_unused struct usb_device_descriptor *desc;
- struct usb_device *parent = dev->parent;
- unsigned short portstatus;
- /* send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is
+ /*
+ * send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is
* only 18 bytes long, this will terminate with a short packet. But if
* the maxpacket size is 8 or 16 the device may be waiting to transmit
* some more, or keeps on retransmitting the 8 byte header. */
- desc = (struct usb_device_descriptor *)tmpbuf;
dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
/* Default to 64 byte max packet size */
dev->maxpacketsize = PACKET_SIZE_64;
dev->epmaxpacketin[0] = 64;
dev->epmaxpacketout[0] = 64;
- /*
- * XHCI needs to issue a Address device command to setup
- * proper device context structures, before it can interact
- * with the device. So a get_descriptor will fail before any
- * of that is done for XHCI unlike EHCI.
- */
-#ifndef CONFIG_USB_XHCI
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
- /*
- * Validate we've received only at least 8 bytes, not that we've
- * received the entire descriptor. The reasoning is:
- * - The code only uses fields in the first 8 bytes, so that's all we
- * need to have fetched at this stage.
- * - The smallest maxpacket size is 8 bytes. Before we know the actual
- * maxpacket the device uses, the USB controller may only accept a
- * single packet. Consequently we are only guaranteed to receive 1
- * packet (at least 8 bytes) even in a non-error case.
- *
- * At least the DWC2 controller needs to be programmed with the number
- * of packets in addition to the number of bytes. A request for 64
- * bytes of data with the maxpacket guessed as 64 (above) yields a
- * request for 1 packet.
- */
- if (err < 8) {
- debug("usb_new_device: usb_get_descriptor() failed\n");
- return -EIO;
- }
-
- dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
- /*
- * Fetch the device class, driver can use this info
- * to differentiate between HUB and DEVICE.
- */
- dev->descriptor.bDeviceClass = desc->bDeviceClass;
-#endif
+ if (do_read) {
+ int err;
- if (parent) {
- /* reset the port for the second time */
- err = hub_port_reset(dev->parent, dev->portnr - 1, &portstatus);
- if (err < 0) {
- printf("\n Couldn't reset port %i\n", dev->portnr);
- return -EIO;
- }
- } else {
- usb_reset_root_port();
+ /*
+ * Validate we've received only at least 8 bytes, not that we've
+ * received the entire descriptor. The reasoning is:
+ * - The code only uses fields in the first 8 bytes, so that's all we
+ * need to have fetched at this stage.
+ * - The smallest maxpacket size is 8 bytes. Before we know the actual
+ * maxpacket the device uses, the USB controller may only accept a
+ * single packet. Consequently we are only guaranteed to receive 1
+ * packet (at least 8 bytes) even in a non-error case.
+ *
+ * At least the DWC2 controller needs to be programmed with the number
+ * of packets in addition to the number of bytes. A request for 64
+ * bytes of data with the maxpacket guessed as 64 (above) yields a
+ * request for 1 packet.
+ */
+ err = get_descriptor_len(dev, 64, 8);
+ if (err)
+ return err;
}
-#endif
dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
@@ -1015,6 +996,33 @@ int usb_new_device(struct usb_device *dev)
printf("usb_new_device: invalid max packet size\n");
return -EIO;
}
+
+ return 0;
+}
+
+static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
+ struct usb_device *parent, int portnr)
+{
+ int err;
+
+ /*
+ * Allocate usb 3.0 device context.
+ * USB 3.0 (xHCI) protocol tries to allocate device slot
+ * and related data structures first. This call does that.
+ * Refer to sec 4.3.2 in xHCI spec rev1.0
+ */
+ err = usb_alloc_device(dev);
+ if (err) {
+ printf("Cannot allocate device context to get SLOT_ID\n");
+ return err;
+ }
+ err = usb_setup_descriptor(dev, do_read);
+ if (err)
+ return err;
+ err = usb_legacy_port_reset(parent, portnr);
+ if (err)
+ return err;
+
dev->devnum = addr;
err = usb_set_address(dev); /* set address */
@@ -1022,45 +1030,49 @@ int usb_new_device(struct usb_device *dev)
if (err < 0) {
printf("\n USB device not accepting new address " \
"(error=%lX)\n", dev->status);
- return -EIO;
+ return err;
}
mdelay(10); /* Let the SET_ADDRESS settle */
- tmp = sizeof(dev->descriptor);
+ return 0;
+}
+
+int usb_select_config(struct usb_device *dev)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+ int err;
+
+ err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
+ if (err)
+ return err;
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
- tmpbuf, sizeof(dev->descriptor));
- if (err < tmp) {
- if (err < 0)
- printf("unable to get device descriptor (error=%d)\n",
- err);
- else
- printf("USB device descriptor short read " \
- "(expected %i, got %i)\n", tmp, err);
- return -EIO;
- }
- memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
/* correct le values */
le16_to_cpus(&dev->descriptor.bcdUSB);
le16_to_cpus(&dev->descriptor.idVendor);
le16_to_cpus(&dev->descriptor.idProduct);
le16_to_cpus(&dev->descriptor.bcdDevice);
+
/* only support for one config for now */
err = usb_get_configuration_no(dev, tmpbuf, 0);
if (err < 0) {
printf("usb_new_device: Cannot read configuration, " \
"skipping device %04x:%04x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct);
- return -EIO;
+ return err;
}
usb_parse_config(dev, tmpbuf, 0);
usb_set_maxpacket(dev);
- /* we set the default configuration here */
- if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
+ /*
+ * we set the default configuration here
+ * This seems premature. If the driver wants a different configuration
+ * it will need to select itself.
+ */
+ err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue);
+ if (err < 0) {
printf("failed to set default configuration " \
"len %d, status %lX\n", dev->act_len, dev->status);
- return -EIO;
+ return err;
}
debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
dev->descriptor.iManufacturer, dev->descriptor.iProduct,
@@ -1080,11 +1092,63 @@ int usb_new_device(struct usb_device *dev)
debug("Manufacturer %s\n", dev->mf);
debug("Product %s\n", dev->prod);
debug("SerialNumber %s\n", dev->serial);
- /* now prode if the device is a hub */
- usb_hub_probe(dev, 0);
+
return 0;
}
+int usb_setup_device(struct usb_device *dev, bool do_read,
+ struct usb_device *parent, int portnr)
+{
+ int addr;
+ int ret;
+
+ /* We still haven't set the Address yet */
+ addr = dev->devnum;
+ dev->devnum = 0;
+
+ ret = usb_prepare_device(dev, addr, do_read, parent, portnr);
+ if (ret)
+ return ret;
+ ret = usb_select_config(dev);
+
+ return ret;
+}
+
+#ifndef CONFIG_DM_USB
+/*
+ * By the time we get here, the device has gotten a new device ID
+ * and is in the default state. We need to identify the thing and
+ * get the ball rolling..
+ *
+ * Returns 0 for success, != 0 for error.
+ */
+int usb_new_device(struct usb_device *dev)
+{
+ bool do_read = true;
+ int err;
+
+ /*
+ * XHCI needs to issue a Address device command to setup
+ * proper device context structures, before it can interact
+ * with the device. So a get_descriptor will fail before any
+ * of that is done for XHCI unlike EHCI.
+ */
+#ifdef CONFIG_USB_XHCI
+ do_read = false;
+#endif
+ err = usb_setup_device(dev, do_read, dev->parent, dev->portnr);
+ if (err)
+ return err;
+
+ /* Now probe if the device is a hub */
+ err = usb_hub_probe(dev, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+#endif
+
__weak
int board_usb_init(int index, enum usb_init_type init)
{
@@ -1096,4 +1160,14 @@ int board_usb_cleanup(int index, enum usb_init_type init)
{
return 0;
}
+
+bool usb_device_has_child_on_port(struct usb_device *parent, int port)
+{
+#ifdef CONFIG_DM_USB
+ return false;
+#else
+ return parent->children[port] != NULL;
+#endif
+}
+
/* EOF */
diff --git a/common/usb_hub.c b/common/usb_hub.c
index f54a404..c9be530 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -24,11 +24,16 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
+#include <errno.h>
#include <asm/processor.h>
#include <asm/unaligned.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
#include <usb.h>
#ifdef CONFIG_4xx
@@ -37,6 +42,7 @@
#define USB_BUFSIZ 512
+/* TODO(sjg@chromium.org): Remove this when CONFIG_DM_USB is defined */
static struct usb_hub_device hub_dev[USB_MAX_HUB];
static int usb_hub_index;
@@ -148,14 +154,19 @@ static inline char *portspeed(int portstatus)
return speed_str;
}
-int hub_port_reset(struct usb_device *dev, int port,
+int legacy_hub_port_reset(struct usb_device *dev, int port,
unsigned short *portstat)
{
int tries;
ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
unsigned short portstatus, portchange;
- debug("hub_port_reset: resetting port %d...\n", port);
+#ifdef CONFIG_DM_USB
+ debug("%s: resetting '%s' port %d...\n", __func__, dev->dev->name,
+ port + 1);
+#else
+ debug("%s: resetting port %d...\n", __func__, port + 1);
+#endif
for (tries = 0; tries < MAX_TRIES; tries++) {
usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
@@ -213,17 +224,26 @@ int hub_port_reset(struct usb_device *dev, int port,
return 0;
}
+#ifdef CONFIG_DM_USB
+int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat)
+{
+ struct usb_device *udev = dev_get_parentdata(dev);
-void usb_hub_port_connect_change(struct usb_device *dev, int port)
+ return legacy_hub_port_reset(udev, port, portstat);
+}
+#endif
+
+int usb_hub_port_connect_change(struct usb_device *dev, int port)
{
- struct usb_device *usb;
ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
unsigned short portstatus;
+ int ret, speed;
/* Check status */
- if (usb_get_port_status(dev, port + 1, portsts) < 0) {
+ ret = usb_get_port_status(dev, port + 1, portsts);
+ if (ret < 0) {
debug("get_port_status failed\n");
- return;
+ return ret;
}
portstatus = le16_to_cpu(portsts->wPortStatus);
@@ -237,51 +257,70 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
/* Disconnect any existing devices under this port */
if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
- (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) {
+ (!(portstatus & USB_PORT_STAT_ENABLE))) ||
+ usb_device_has_child_on_port(dev, port)) {
debug("usb_disconnect(&hub->children[port]);\n");
/* Return now if nothing is connected */
if (!(portstatus & USB_PORT_STAT_CONNECTION))
- return;
+ return -ENOTCONN;
}
mdelay(200);
/* Reset the port */
- if (hub_port_reset(dev, port, &portstatus) < 0) {
+ ret = legacy_hub_port_reset(dev, port, &portstatus);
+ if (ret < 0) {
printf("cannot reset port %i!?\n", port + 1);
- return;
+ return ret;
}
mdelay(200);
- /* Allocate a new device struct for it */
- usb = usb_alloc_new_device(dev->controller);
-
switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
case USB_PORT_STAT_SUPER_SPEED:
- usb->speed = USB_SPEED_SUPER;
+ speed = USB_SPEED_SUPER;
break;
case USB_PORT_STAT_HIGH_SPEED:
- usb->speed = USB_SPEED_HIGH;
+ speed = USB_SPEED_HIGH;
break;
case USB_PORT_STAT_LOW_SPEED:
- usb->speed = USB_SPEED_LOW;
+ speed = USB_SPEED_LOW;
break;
default:
- usb->speed = USB_SPEED_FULL;
+ speed = USB_SPEED_FULL;
break;
}
+#ifdef CONFIG_DM_USB
+ struct udevice *child;
+
+ ret = usb_scan_device(dev->dev, port + 1, speed, &child);
+#else
+ struct usb_device *usb;
+
+ ret = usb_alloc_new_device(dev->controller, &usb);
+ if (ret) {
+ printf("cannot create new device: ret=%d", ret);
+ return ret;
+ }
+
dev->children[port] = usb;
+ usb->speed = speed;
usb->parent = dev;
usb->portnr = port + 1;
/* Run it through the hoops (find a driver, etc) */
- if (usb_new_device(usb)) {
+ ret = usb_new_device(usb);
+ if (ret < 0) {
/* Woops, disable the port */
- usb_free_device();
+ usb_free_device(dev->controller);
dev->children[port] = NULL;
+ }
+#endif
+ if (ret < 0) {
debug("hub: disabling port %d\n", port + 1);
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
}
+
+ return ret;
}
@@ -294,27 +333,30 @@ static int usb_hub_configure(struct usb_device *dev)
struct usb_hub_descriptor *descriptor;
struct usb_hub_device *hub;
__maybe_unused struct usb_hub_status *hubsts;
+ int ret;
/* "allocate" Hub device */
hub = usb_hub_allocate();
if (hub == NULL)
- return -1;
+ return -ENOMEM;
hub->pusb_dev = dev;
/* Get the the hub descriptor */
- if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
+ ret = usb_get_hub_descriptor(dev, buffer, 4);
+ if (ret < 0) {
debug("usb_hub_configure: failed to get hub " \
"descriptor, giving up %lX\n", dev->status);
- return -1;
+ return ret;
}
descriptor = (struct usb_hub_descriptor *)buffer;
length = min_t(int, descriptor->bLength,
sizeof(struct usb_hub_descriptor));
- if (usb_get_hub_descriptor(dev, buffer, length) < 0) {
+ ret = usb_get_hub_descriptor(dev, buffer, length);
+ if (ret < 0) {
debug("usb_hub_configure: failed to get hub " \
"descriptor 2nd giving up %lX\n", dev->status);
- return -1;
+ return ret;
}
memcpy((unsigned char *)&hub->desc, buffer, length);
/* adjust 16bit values */
@@ -382,13 +424,14 @@ static int usb_hub_configure(struct usb_device *dev)
if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
debug("usb_hub_configure: failed to get Status - " \
"too long: %d\n", descriptor->bLength);
- return -1;
+ return -EFBIG;
}
- if (usb_get_hub_status(dev, buffer) < 0) {
+ ret = usb_get_hub_status(dev, buffer);
+ if (ret < 0) {
debug("usb_hub_configure: failed to get Status %lX\n",
dev->status);
- return -1;
+ return ret;
}
#ifdef DEBUG
@@ -420,6 +463,11 @@ static int usb_hub_configure(struct usb_device *dev)
int ret;
ulong start = get_timer(0);
+#ifdef CONFIG_DM_USB
+ debug("\n\nScanning '%s' port %d\n", dev->dev->name, i + 1);
+#else
+ debug("\n\nScanning port %d\n", i + 1);
+#endif
/*
* Wait for (whichever finishes first)
* - A maximum of 10 seconds
@@ -469,7 +517,7 @@ static int usb_hub_configure(struct usb_device *dev)
* them again. Works at least with mouse driver */
if (!(portstatus & USB_PORT_STAT_ENABLE) &&
(portstatus & USB_PORT_STAT_CONNECTION) &&
- ((dev->children[i]))) {
+ usb_device_has_child_on_port(dev, i)) {
debug("already running port %i " \
"disabled by hub (EMI?), " \
"re-enabling...\n", i + 1);
@@ -500,33 +548,107 @@ static int usb_hub_configure(struct usb_device *dev)
return 0;
}
-int usb_hub_probe(struct usb_device *dev, int ifnum)
+static int usb_hub_check(struct usb_device *dev, int ifnum)
{
struct usb_interface *iface;
- struct usb_endpoint_descriptor *ep;
- int ret;
+ struct usb_endpoint_descriptor *ep = NULL;
iface = &dev->config.if_desc[ifnum];
/* Is it a hub? */
if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
- return 0;
+ goto err;
/* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
if ((iface->desc.bInterfaceSubClass != 0) &&
(iface->desc.bInterfaceSubClass != 1))
- return 0;
+ goto err;
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
if (iface->desc.bNumEndpoints != 1)
- return 0;
+ goto err;
ep = &iface->ep_desc[0];
/* Output endpoint? Curiousier and curiousier.. */
if (!(ep->bEndpointAddress & USB_DIR_IN))
- return 0;
+ goto err;
/* If it's not an interrupt endpoint, we'd better punt! */
if ((ep->bmAttributes & 3) != 3)
- return 0;
+ goto err;
/* We found a hub */
debug("USB hub found\n");
+ return 0;
+
+err:
+ debug("USB hub not found: bInterfaceClass=%d, bInterfaceSubClass=%d, bNumEndpoints=%d\n",
+ iface->desc.bInterfaceClass, iface->desc.bInterfaceSubClass,
+ iface->desc.bNumEndpoints);
+ if (ep) {
+ debug(" bEndpointAddress=%#x, bmAttributes=%d",
+ ep->bEndpointAddress, ep->bmAttributes);
+ }
+
+ return -ENOENT;
+}
+
+int usb_hub_probe(struct usb_device *dev, int ifnum)
+{
+ int ret;
+
+ ret = usb_hub_check(dev, ifnum);
+ if (ret)
+ return 0;
ret = usb_hub_configure(dev);
return ret;
}
+
+#ifdef CONFIG_DM_USB
+int usb_hub_scan(struct udevice *hub)
+{
+ struct usb_device *udev = dev_get_parentdata(hub);
+
+ return usb_hub_configure(udev);
+}
+
+static int usb_hub_post_bind(struct udevice *dev)
+{
+ /* Scan the bus for devices */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+static int usb_hub_post_probe(struct udevice *dev)
+{
+ debug("%s\n", __func__);
+ return usb_hub_scan(dev);
+}
+
+static const struct udevice_id usb_hub_ids[] = {
+ { .compatible = "usb-hub" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_generic_hub) = {
+ .name = "usb_hub",
+ .id = UCLASS_USB_HUB,
+ .of_match = usb_hub_ids,
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+UCLASS_DRIVER(usb_hub) = {
+ .id = UCLASS_USB_HUB,
+ .name = "usb_hub",
+ .post_bind = usb_hub_post_bind,
+ .post_probe = usb_hub_post_probe,
+ .child_pre_probe = usb_child_pre_probe,
+ .per_child_auto_alloc_size = sizeof(struct usb_device),
+ .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+};
+
+static const struct usb_device_id hub_id_table[] = {
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
+ .bDeviceClass = USB_CLASS_HUB
+ },
+ { } /* Terminating entry */
+};
+
+USB_DEVICE(usb_generic_hub, hub_id_table);
+
+#endif
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index ecc3085..24a1a56 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 <dm.h>
#include <errno.h>
#include <malloc.h>
#include <stdio_dev.h>
@@ -471,60 +472,104 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
return 1;
}
+static int probe_usb_keyboard(struct usb_device *dev)
+{
+ char *stdinname;
+ struct stdio_dev usb_kbd_dev;
+ int error;
+
+ /* Try probing the keyboard */
+ if (usb_kbd_probe(dev, 0) != 1)
+ return -ENOENT;
+
+ /* Register the keyboard */
+ debug("USB KBD: register.\n");
+ memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
+ strcpy(usb_kbd_dev.name, DEVNAME);
+ usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+ usb_kbd_dev.getc = usb_kbd_getc;
+ usb_kbd_dev.tstc = usb_kbd_testc;
+ usb_kbd_dev.priv = (void *)dev;
+ error = stdio_register(&usb_kbd_dev);
+ if (error)
+ return error;
+
+ stdinname = getenv("stdin");
+#ifdef CONFIG_CONSOLE_MUX
+ error = iomux_doenv(stdin, stdinname);
+ if (error)
+ return error;
+#else
+ /* Check if this is the standard input device. */
+ if (strcmp(stdinname, DEVNAME))
+ return 1;
+
+ /* Reassign the console */
+ if (overwrite_console())
+ return 1;
+
+ error = console_assign(stdin, DEVNAME);
+ if (error)
+ return error;
+#endif
+
+ return 0;
+}
+
/* Search for keyboard and register it if found. */
int drv_usb_kbd_init(void)
{
- struct stdio_dev usb_kbd_dev;
- struct usb_device *dev;
- char *stdinname = getenv("stdin");
int error, i;
+ debug("%s: Probing for keyboard\n", __func__);
+#ifdef CONFIG_DM_USB
+ /*
+ * TODO: We should add USB_DEVICE() declarations to each USB ethernet
+ * 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;
+
/* Get USB device. */
dev = usb_get_dev_index(i);
if (!dev)
- return -1;
+ break;
if (dev->devnum == -1)
continue;
- /* Try probing the keyboard */
- if (usb_kbd_probe(dev, 0) != 1)
- continue;
-
- /* Register the keyboard */
- debug("USB KBD: register.\n");
- memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
- strcpy(usb_kbd_dev.name, DEVNAME);
- usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
- usb_kbd_dev.getc = usb_kbd_getc;
- usb_kbd_dev.tstc = usb_kbd_testc;
- usb_kbd_dev.priv = (void *)dev;
- error = stdio_register(&usb_kbd_dev);
- if (error)
- return error;
-
-#ifdef CONFIG_CONSOLE_MUX
- error = iomux_doenv(stdin, stdinname);
- if (error)
- return error;
-#else
- /* Check if this is the standard input device. */
- if (strcmp(stdinname, DEVNAME))
- return 1;
-
- /* Reassign the console */
- if (overwrite_console())
+ error = probe_usb_keyboard(dev);
+ if (!error)
return 1;
-
- error = console_assign(stdin, DEVNAME);
- if (error)
+ if (error && error != -ENOENT)
return error;
-#endif
-
- return 1;
}
+#endif
/* No USB Keyboard found */
return -1;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index a4ca7a5..cc9b3e3 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -9,6 +9,8 @@
*
* Adapted for U-Boot:
* (C) Copyright 2001 Denis Peter, MPL AG Switzerland
+ * Driver model conversion:
+ * (C) Copyright 2015 Google, Inc
*
* For BBB support (C) Copyright 2003
* Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
@@ -33,9 +35,13 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
+#include <errno.h>
#include <inttypes.h>
+#include <mapmem.h>
#include <asm/byteorder.h>
#include <asm/processor.h>
+#include <dm/device-internal.h>
#include <part.h>
#include <usb.h>
@@ -56,49 +62,8 @@ static const unsigned char us_direction[256/8] = {
#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
-
-/*
- * CBI style
- */
-
-#define US_CBI_ADSC 0
-
-/*
- * BULK only
- */
-#define US_BBB_RESET 0xff
-#define US_BBB_GET_MAX_LUN 0xfe
-
-/* Command Block Wrapper */
-typedef struct {
- __u32 dCBWSignature;
-# define CBWSIGNATURE 0x43425355
- __u32 dCBWTag;
- __u32 dCBWDataTransferLength;
- __u8 bCBWFlags;
-# define CBWFLAGS_OUT 0x00
-# define CBWFLAGS_IN 0x80
- __u8 bCBWLUN;
- __u8 bCDBLength;
-# define CBWCDBLENGTH 16
- __u8 CBWCDB[CBWCDBLENGTH];
-} umass_bbb_cbw_t;
-#define UMASS_BBB_CBW_SIZE 31
static __u32 CBWTag;
-/* Command Status Wrapper */
-typedef struct {
- __u32 dCSWSignature;
-# define CSWSIGNATURE 0x53425355
- __u32 dCSWTag;
- __u32 dCSWDataResidue;
- __u8 bCSWStatus;
-# define CSWSTATUS_GOOD 0x0
-# define CSWSTATUS_FAILED 0x1
-# define CSWSTATUS_PHASE 0x2
-} umass_bbb_csw_t;
-#define UMASS_BBB_CSW_SIZE 13
-
#define USB_MAX_STOR_DEV 5
static int usb_max_devs; /* number of highest available usb device */
@@ -145,7 +110,6 @@ struct us_data {
static struct us_data usb_stor[USB_MAX_STOR_DEV];
-
#define USB_STOR_TRANSPORT_GOOD 0
#define USB_STOR_TRANSPORT_FAILED -1
#define USB_STOR_TRANSPORT_ERROR -2
@@ -158,7 +122,6 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
lbaint_t blkcnt, void *buffer);
unsigned long usb_stor_write(int device, lbaint_t blknr,
lbaint_t blkcnt, const void *buffer);
-struct usb_device * usb_get_dev_index(int index);
void uhci_show_temp_int_td(void);
#ifdef CONFIG_PARTITIONS
@@ -208,30 +171,61 @@ static unsigned int usb_get_max_lun(struct us_data *us)
return (len > 0) ? *result : 0;
}
-static int usb_storage_register(struct usb_device *dev, unsigned char iface)
+static int usb_stor_probe_device(struct usb_device *dev)
{
- int lun, max_lun, start = usb_max_devs;
- int nb_dev = 0;
-
- if (!usb_storage_probe(dev, iface, &usb_stor[usb_max_devs]))
- return nb_dev;
-
- /*
- * OK, it's a storage device. Iterate over its LUNs
- * and populate `usb_dev_desc'.
- */
- max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
- for (lun = 0; lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV; lun++) {
- usb_dev_desc[usb_max_devs].lun = lun;
- if (usb_stor_get_info(dev, &usb_stor[start],
- &usb_dev_desc[usb_max_devs]) == 1) {
- nb_dev++;
+ if (dev == NULL)
+ return -ENOENT; /* no more devices available */
+
+ debug("\n\nProbing for storage\n");
+ if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
+ /* OK, it's a storage device. Iterate over its LUNs
+ * and populate `usb_dev_desc'.
+ */
+ int lun, max_lun, start = usb_max_devs;
+
+ max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
+ for (lun = 0;
+ lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
+ lun++) {
+ struct block_dev_desc *blkdev;
+
+ blkdev = &usb_dev_desc[usb_max_devs];
+ memset(blkdev, '\0', sizeof(block_dev_desc_t));
+ blkdev->if_type = IF_TYPE_USB;
+ blkdev->dev = usb_max_devs;
+ blkdev->part_type = PART_TYPE_UNKNOWN;
+ blkdev->target = 0xff;
+ blkdev->type = DEV_TYPE_UNKNOWN;
+ blkdev->block_read = usb_stor_read;
+ blkdev->block_write = usb_stor_write;
+ blkdev->lun = lun;
+ blkdev->priv = dev;
+
+ if (usb_stor_get_info(dev, &usb_stor[start],
+ &usb_dev_desc[usb_max_devs]) ==
+ 1) {
+ usb_max_devs++;
+ debug("%s: Found device %p\n", __func__, dev);
+ }
}
}
- return nb_dev;
+ /* if storage device */
+ if (usb_max_devs == USB_MAX_STOR_DEV) {
+ printf("max USB Storage Device reached: %d stopping\n",
+ usb_max_devs);
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+void usb_stor_reset(void)
+{
+ usb_max_devs = 0;
}
+#ifndef CONFIG_DM_USB
/*******************************************************************************
* scan the usb and reports device info
* to the user if mode = 1
@@ -239,42 +233,21 @@ static int usb_storage_register(struct usb_device *dev, unsigned char iface)
*/
int usb_stor_scan(int mode)
{
- unsigned char i, iface;
- struct usb_device *dev;
+ unsigned char i;
if (mode == 1)
printf(" scanning usb for storage devices... ");
usb_disable_asynch(1); /* asynch transfer not allowed */
- for (i = 0; i < USB_MAX_STOR_DEV; i++) {
- memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t));
- usb_dev_desc[i].if_type = IF_TYPE_USB;
- usb_dev_desc[i].dev = i;
- usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
- usb_dev_desc[i].target = 0xff;
- usb_dev_desc[i].type = DEV_TYPE_UNKNOWN;
- usb_dev_desc[i].block_read = usb_stor_read;
- usb_dev_desc[i].block_write = usb_stor_write;
- }
-
- usb_max_devs = 0;
+ usb_stor_reset();
for (i = 0; i < USB_MAX_DEVICE; i++) {
+ struct usb_device *dev;
+
dev = usb_get_dev_index(i); /* get device */
debug("i=%d\n", i);
- if (dev == NULL)
- break; /* no more devices available */
-
- for (iface = 0; iface < dev->config.no_of_if; iface++) {
- usb_max_devs += usb_storage_register(dev, iface);
- }
-
- /* if storage device */
- if (usb_max_devs == USB_MAX_STOR_DEV) {
- printf("max USB Storage Device reached: %d stopping\n",
- usb_max_devs);
+ if (usb_stor_probe_device(dev))
break;
- }
} /* for */
usb_disable_asynch(0); /* asynch transfer allowed */
@@ -283,6 +256,7 @@ int usb_stor_scan(int mode)
return 0;
return -1;
}
+#endif
static int usb_stor_irq(struct usb_device *dev)
{
@@ -347,8 +321,9 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
/* set up the transfer loop */
do {
/* transfer the data */
- debug("Bulk xfer %p(%d) try #%d\n",
- buf, this_xfer, 11 - maxtry);
+ debug("Bulk xfer 0x%lx(%d) try #%d\n",
+ (ulong)map_to_sysmem(buf), this_xfer,
+ 11 - maxtry);
result = usb_bulk_msg(us->pusb_dev, pipe, buf,
this_xfer, &partial,
USB_CNTL_TIMEOUT * 5);
@@ -494,7 +469,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
int actlen;
int dir_in;
unsigned int pipe;
- ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
+ ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_cbw, cbw, 1);
dir_in = US_DIRECTION(srb->cmd[0]);
@@ -670,7 +645,7 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
int dir_in;
int actlen, data_actlen;
unsigned int pipe, pipein, pipeout;
- ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
+ ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_csw, csw, 1);
#ifdef BBB_XPORT_TRACE
unsigned char *ptr;
int index;
@@ -1059,7 +1034,7 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
unsigned short smallblks;
struct usb_device *dev;
struct us_data *ss;
- int retry, i;
+ int retry;
ccb *srb = &usb_ccb;
if (blkcnt == 0)
@@ -1067,14 +1042,11 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
device &= 0xff;
/* Setup device */
- debug("\nusb_read: dev %d \n", device);
- dev = NULL;
- for (i = 0; i < USB_MAX_DEVICE; i++) {
- dev = usb_get_dev_index(i);
- if (dev == NULL)
- return 0;
- if (dev->devnum == usb_dev_desc[device].target)
- break;
+ debug("\nusb_read: dev %d\n", device);
+ dev = usb_dev_desc[device].priv;
+ if (!dev) {
+ debug("%s: No device\n", __func__);
+ return 0;
}
ss = (struct us_data *)dev->privptr;
@@ -1132,7 +1104,7 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
unsigned short smallblks;
struct usb_device *dev;
struct us_data *ss;
- int retry, i;
+ int retry;
ccb *srb = &usb_ccb;
if (blkcnt == 0)
@@ -1140,15 +1112,10 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
device &= 0xff;
/* Setup device */
- debug("\nusb_write: dev %d \n", device);
- dev = NULL;
- for (i = 0; i < USB_MAX_DEVICE; i++) {
- dev = usb_get_dev_index(i);
- if (dev == NULL)
- return 0;
- if (dev->devnum == usb_dev_desc[device].target)
- break;
- }
+ debug("\nusb_write: dev %d\n", device);
+ dev = usb_dev_desc[device].priv;
+ if (!dev)
+ return 0;
ss = (struct us_data *)dev->privptr;
usb_disable_asynch(1); /* asynch transfer not allowed */
@@ -1232,6 +1199,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
iface->desc.bInterfaceSubClass < US_SC_MIN ||
iface->desc.bInterfaceSubClass > US_SC_MAX) {
+ debug("Not mass storage\n");
/* if it's not a mass storage, we go no further */
return 0;
}
@@ -1358,8 +1326,10 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
pccb->lun = dev_desc->lun;
debug(" address %d\n", dev_desc->target);
- if (usb_inquiry(pccb, ss))
+ if (usb_inquiry(pccb, ss)) {
+ debug("%s: usb_inquiry() failed\n", __func__);
return -1;
+ }
perq = usb_stor_buf[0];
modi = usb_stor_buf[1];
@@ -1369,6 +1339,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
* they would not respond to test_unit_ready .
*/
if (((perq & 0x1f) == 0x1f) || ((perq & 0x1f) == 0x0d)) {
+ debug("%s: unknown/unsupported device\n", __func__);
return 0;
}
if ((modi&0x80) == 0x80) {
@@ -1431,3 +1402,46 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
debug("partype: %d\n", dev_desc->part_type);
return 1;
}
+
+#ifdef CONFIG_DM_USB
+
+static int usb_mass_storage_probe(struct udevice *dev)
+{
+ struct usb_device *udev = dev_get_parentdata(dev);
+ int ret;
+
+ usb_disable_asynch(1); /* asynch transfer not allowed */
+ ret = usb_stor_probe_device(udev);
+ usb_disable_asynch(0); /* asynch transfer allowed */
+
+ return ret;
+}
+
+static const struct udevice_id usb_mass_storage_ids[] = {
+ { .compatible = "usb-mass-storage" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_mass_storage) = {
+ .name = "usb_mass_storage",
+ .id = UCLASS_MASS_STORAGE,
+ .of_match = usb_mass_storage_ids,
+ .probe = usb_mass_storage_probe,
+};
+
+UCLASS_DRIVER(usb_mass_storage) = {
+ .id = UCLASS_MASS_STORAGE,
+ .name = "usb_mass_storage",
+};
+
+static const struct usb_device_id mass_storage_id_table[] = {
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+ .bInterfaceClass = USB_CLASS_MASS_STORAGE
+ },
+ { } /* Terminating entry */
+};
+
+USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+
+#endif