Merge git://git.denx.de/u-boot-dm
authorTom Rini <trini@konsulko.com>
Wed, 12 Jul 2017 00:28:46 +0000 (20:28 -0400)
committerTom Rini <trini@konsulko.com>
Wed, 12 Jul 2017 00:28:46 +0000 (20:28 -0400)
282 files changed:
README
api/api_storage.c
arch/Kconfig
arch/arm/Kconfig
arch/arm/cpu/armv7/ls102xa/Kconfig
arch/arm/cpu/armv7/ls102xa/ls102xa_sata.c
arch/arm/cpu/armv7/mx6/Kconfig
arch/arm/cpu/armv7/mx6/clock.c
arch/arm/cpu/armv8/fsl-layerscape/Kconfig
arch/arm/cpu/armv8/fsl-layerscape/soc.c
arch/arm/dts/rk3328.dtsi
arch/arm/dts/tegra114-dalmore.dts
arch/arm/dts/tegra124-cei-tk1-som.dts
arch/arm/dts/tegra124-jetson-tk1.dts
arch/arm/dts/tegra124-venice2.dts
arch/arm/dts/tegra186-p2771-0000.dtsi
arch/arm/dts/tegra20-colibri.dts
arch/arm/dts/tegra20-harmony.dts
arch/arm/dts/tegra20-trimslice.dts
arch/arm/dts/tegra210-e2220-1170.dts
arch/arm/dts/tegra210-p2371-0000.dts
arch/arm/dts/tegra210-p2371-2180.dts
arch/arm/dts/tegra210-p2571.dts
arch/arm/dts/tegra30-apalis.dts
arch/arm/dts/tegra30-beaver.dts
arch/arm/dts/tegra30-cardhu.dts
arch/arm/dts/tegra30-colibri.dts
arch/arm/dts/tegra30-tec-ng.dts
arch/arm/imx-common/Makefile
arch/arm/imx-common/cpu.c
arch/arm/include/asm/arch-ls102xa/config.h
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-omap2/omap5/Kconfig
arch/arm/mach-omap2/sata.c
arch/arm/mach-tegra/board2.c
arch/arm/mach-tegra/clock.c
arch/powerpc/cpu/mpc83xx/Kconfig
arch/powerpc/cpu/mpc85xx/Kconfig
arch/powerpc/cpu/mpc85xx/cpu_init.c
arch/powerpc/cpu/mpc86xx/Kconfig
arch/sandbox/cpu/spl.c
arch/sandbox/dts/sandbox.dts
arch/sandbox/dts/test.dts
arch/x86/cpu/ivybridge/sata.c
board/advantech/dms-ba16/dms-ba16.c
board/bachmann/ot1200/ot1200.c
board/boundary/nitrogen6x/nitrogen6x.c
board/congatec/Kconfig
board/congatec/cgtqmx6eval/cgtqmx6eval.c
board/dfi/Kconfig
board/gateworks/gw_ventana/gw_ventana.c
board/highbank/ahci.c
board/highbank/highbank.c
board/kosagi/novena/novena.c
board/sandbox/README.sandbox
board/toradex/apalis_imx6/apalis_imx6.c
board/toradex/colibri_imx6/colibri_imx6.c
board/udoo/udoo.c
board/wandboard/wandboard.c
cmd/Kconfig
cmd/fdt.c
cmd/scsi.c
cmd/version.c
common/Kconfig
common/Makefile
common/board_r.c
common/console.c
common/spl/spl_sata.c
common/splash_source.c
common/usb_storage.c
configs/A10-OLinuXino-Lime_defconfig
configs/A20-OLinuXino-Lime2_defconfig
configs/A20-OLinuXino-Lime_defconfig
configs/A20-OLinuXino_MICRO_defconfig
configs/A20-Olimex-SOM-EVB_defconfig
configs/Bananapi_M2_Ultra_defconfig
configs/Bananapi_defconfig
configs/Bananapro_defconfig
configs/Cubieboard2_defconfig
configs/Cubieboard_defconfig
configs/Cubietruck_defconfig
configs/Itead_Ibox_A20_defconfig
configs/Lamobo_R1_defconfig
configs/Linksprite_pcDuino3_Nano_defconfig
configs/Linksprite_pcDuino3_defconfig
configs/MPC8315ERDB_defconfig
configs/MPC8349ITX_LOWBOOT_defconfig
configs/MPC8349ITX_defconfig
configs/MPC837XERDB_defconfig
configs/MPC8544DS_defconfig
configs/MPC8610HPCD_defconfig
configs/Marsboard_A10_defconfig
configs/Mele_A1000_defconfig
configs/Mele_M5_defconfig
configs/Orangepi_defconfig
configs/Orangepi_mini_defconfig
configs/Wits_Pro_A20_DKT_defconfig
configs/bayleybay_defconfig
configs/cgtqmx6eval_defconfig
configs/chromebook_link64_defconfig
configs/chromebook_link_defconfig
configs/chromebook_samus_defconfig
configs/chromebox_panther_defconfig
configs/cm_fx6_defconfig
configs/cm_t54_defconfig
configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig
configs/controlcenterd_36BIT_SDCARD_defconfig
configs/controlcenterdc_defconfig
configs/cougarcanyon2_defconfig
configs/crownbay_defconfig
configs/db-88f6820-gp_defconfig
configs/db-mv784mp-gp_defconfig
configs/highbank_defconfig
configs/ls1012aqds_qspi_defconfig
configs/ls2081ardb_defconfig
configs/m53evk_defconfig
configs/minnowmax_defconfig
configs/mx53loco_defconfig
configs/mx6qsabrelite_defconfig
configs/nitrogen6q2g_defconfig
configs/nitrogen6q_defconfig
configs/novena_defconfig
configs/nyan-big_defconfig
configs/omap5_uevm_defconfig
configs/sandbox_defconfig
configs/som-db5800-som-6867_defconfig
configs/tbs2910_defconfig
configs/udoo_defconfig
configs/wandboard_defconfig
configs/xilinx_zynqmp_ep_defconfig
configs/xilinx_zynqmp_zcu102_defconfig
configs/xilinx_zynqmp_zcu102_revB_defconfig
doc/README.gpt
doc/driver-model/of-plat.txt
drivers/Kconfig
drivers/Makefile
drivers/ata/Kconfig [new file with mode: 0644]
drivers/ata/Makefile [new file with mode: 0644]
drivers/ata/ahci-uclass.c [moved from drivers/block/ahci-uclass.c with 100% similarity]
drivers/ata/ahci.c [moved from drivers/block/ahci.c with 74% similarity]
drivers/ata/dwc_ahci.c [moved from drivers/block/dwc_ahci.c with 92% similarity]
drivers/ata/dwc_ahsata.c [moved from drivers/block/dwc_ahsata.c with 92% similarity]
drivers/ata/dwc_ahsata.h [moved from drivers/block/dwc_ahsata.h with 100% similarity]
drivers/ata/fsl_sata.c [moved from drivers/block/fsl_sata.c with 100% similarity]
drivers/ata/fsl_sata.h [moved from drivers/block/fsl_sata.h with 100% similarity]
drivers/ata/libata.c [moved from drivers/block/libata.c with 100% similarity]
drivers/ata/mvsata_ide.c [moved from drivers/block/mvsata_ide.c with 100% similarity]
drivers/ata/mxc_ata.c [moved from drivers/block/mxc_ata.c with 100% similarity]
drivers/ata/sata.c [moved from common/sata.c with 100% similarity]
drivers/ata/sata_ceva.c [moved from drivers/block/sata_ceva.c with 95% similarity]
drivers/ata/sata_dwc.c [moved from drivers/block/sata_dwc.c with 100% similarity]
drivers/ata/sata_dwc.h [moved from drivers/block/sata_dwc.h with 100% similarity]
drivers/ata/sata_mv.c [moved from drivers/block/sata_mv.c with 100% similarity]
drivers/ata/sata_sandbox.c [moved from drivers/block/sata_sandbox.c with 100% similarity]
drivers/ata/sata_sil.c [moved from drivers/block/sata_sil.c with 100% similarity]
drivers/ata/sata_sil.h [moved from drivers/block/sata_sil.h with 100% similarity]
drivers/ata/sata_sil3114.c [moved from drivers/block/sata_sil3114.c with 100% similarity]
drivers/ata/sata_sil3114.h [moved from drivers/block/sata_sil3114.h with 100% similarity]
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/scsi-uclass.c [deleted file]
drivers/block/sym53c8xx.c [deleted file]
drivers/core/Makefile
drivers/core/dump.c
drivers/core/lists.c
drivers/core/of_access.c
drivers/core/ofnode.c
drivers/core/read.c
drivers/core/read_extra.c [new file with mode: 0644]
drivers/core/regmap.c
drivers/core/uclass.c
drivers/core/util.c
drivers/misc/cros_ec_sandbox.c
drivers/pci/pci-uclass.c
drivers/pinctrl/pinctrl-uclass.c
drivers/scsi/Kconfig [new file with mode: 0644]
drivers/scsi/Makefile [new file with mode: 0644]
drivers/scsi/sandbox_scsi.c [moved from drivers/block/sandbox_scsi.c with 75% similarity]
drivers/scsi/scsi-uclass.c [new file with mode: 0644]
drivers/scsi/scsi.c [moved from common/scsi.c with 86% similarity]
drivers/serial/ns16550.c
drivers/serial/serial-uclass.c
drivers/usb/emul/sandbox_flash.c
drivers/video/pwm_backlight.c
drivers/video/simple_panel.c
drivers/video/tegra124/display.c
drivers/video/vidconsole-uclass.c
fs/fat/fat.c
include/ahci.h
include/config_cmd_all.h
include/config_distro_bootcmd.h
include/config_fallbacks.h
include/configs/MPC8315ERDB.h
include/configs/MPC8349ITX.h
include/configs/MPC837XEMDS.h
include/configs/MPC837XERDB.h
include/configs/MPC8536DS.h
include/configs/MPC8544DS.h
include/configs/MPC8572DS.h
include/configs/MPC8610HPCD.h
include/configs/MPC8641HPCN.h
include/configs/P1010RDB.h
include/configs/P1022DS.h
include/configs/P2041RDB.h
include/configs/P4080DS.h
include/configs/T102xQDS.h
include/configs/T1040QDS.h
include/configs/T104xRDB.h
include/configs/T208xQDS.h
include/configs/T208xRDB.h
include/configs/T4240QDS.h
include/configs/T4240RDB.h
include/configs/UCP1020.h
include/configs/advantech_dms-ba16.h
include/configs/am57xx_evm.h
include/configs/apalis_imx6.h
include/configs/cgtqmx6eval.h
include/configs/cm_fx6.h
include/configs/cm_t54.h
include/configs/controlcenterd.h
include/configs/controlcenterdc.h
include/configs/corenet_ds.h
include/configs/cyrus.h
include/configs/db-88f6820-gp.h
include/configs/db-mv784mp-gp.h
include/configs/dra7xx_evm.h
include/configs/efi-x86.h
include/configs/galileo.h
include/configs/gw_ventana.h
include/configs/highbank.h
include/configs/ls1012aqds.h
include/configs/ls1012ardb.h
include/configs/ls1043aqds.h
include/configs/ls1046aqds.h
include/configs/ls1046ardb.h
include/configs/ls2080aqds.h
include/configs/ls2080ardb.h
include/configs/m53evk.h
include/configs/mvebu_armada-37xx.h
include/configs/mvebu_armada-8k.h
include/configs/mx53loco.h
include/configs/nitrogen6x.h
include/configs/novena.h
include/configs/omap5_uevm.h
include/configs/ot1200.h
include/configs/p1_p2_rdb_pc.h
include/configs/p1_twr.h
include/configs/qemu-x86.h
include/configs/sandbox.h
include/configs/sunxi-common.h
include/configs/t4qds.h
include/configs/tbs2910.h
include/configs/theadorable.h
include/configs/udoo.h
include/configs/wandboard.h
include/configs/x86-common.h
include/configs/xilinx_zynqmp.h
include/console.h
include/display_options.h
include/dm/of_access.h
include/dm/ofnode.h
include/dm/read.h
include/dm/uclass-id.h
include/dm/uclass.h
include/scsi.h
lib/display_options.c
lib/of_live.c
scripts/config_whitelist.txt
test/Makefile
test/dm/test-fdt.c
test/print_ut.c [new file with mode: 0644]
test/py/tests/test_ofplatdata.py
tools/binman/binman.py
tools/dtoc/dtb_platdata.py [new file with mode: 0644]
tools/dtoc/dtoc.py
tools/dtoc/dtoc_test.dts [new file with mode: 0644]
tools/dtoc/dtoc_test_aliases.dts [new file with mode: 0644]
tools/dtoc/dtoc_test_empty.dts [new file with mode: 0644]
tools/dtoc/dtoc_test_phandle.dts [new file with mode: 0644]
tools/dtoc/dtoc_test_simple.dts [new file with mode: 0644]
tools/dtoc/test_dtoc.py [new file with mode: 0644]
tools/moveconfig.py

diff --git a/README b/README
index ee35dec..c73f6dd 100644 (file)
--- a/README
+++ b/README
@@ -826,7 +826,6 @@ The following options need to be configured:
                CONFIG_CMD_RUN            run command in env variable
                CONFIG_CMD_SANDBOX      * sb command to access sandbox features
                CONFIG_CMD_SAVES        * save S record dump
-               CONFIG_SCSI             * SCSI Support
                CONFIG_CMD_SDRAM        * print SDRAM configuration information
                                          (requires CONFIG_CMD_I2C)
                CONFIG_CMD_SF           * Read/write/erase SPI NOR flash
@@ -1043,16 +1042,11 @@ The following options need to be configured:
                        Default is 32bit.
 
 - SCSI Support:
-               At the moment only there is only support for the
-               SYM53C8XX SCSI controller; define
-               CONFIG_SCSI_SYM53C8XX to enable it.
-
                CONFIG_SYS_SCSI_MAX_LUN [8], CONFIG_SYS_SCSI_MAX_SCSI_ID [7] and
                CONFIG_SYS_SCSI_MAX_DEVICE [CONFIG_SYS_SCSI_MAX_SCSI_ID *
                CONFIG_SYS_SCSI_MAX_LUN] can be adjusted to define the
                maximum numbers of LUNs, SCSI ID's and target
                devices.
-               CONFIG_SYS_SCSI_SYM53C8XX_CCF to fix clock timing (80Mhz)
 
                The environment variable 'scsidevs' is set to the number of
                SCSI devices found during the last scan.
index 8bed2f3..6fc6f44 100644 (file)
@@ -63,7 +63,7 @@ void dev_stor_init(void)
        specs[ENUM_MMC].type = DEV_TYP_STOR | DT_STOR_MMC;
        specs[ENUM_MMC].name = "mmc";
 #endif
-#if defined(CONFIG_CMD_SATA)
+#if defined(CONFIG_SATA)
        specs[ENUM_SATA].max_dev = CONFIG_SYS_SATA_MAX_DEVICE;
        specs[ENUM_SATA].enum_started = 0;
        specs[ENUM_SATA].enum_ended = 0;
index fe1b991..7e76abd 100644 (file)
@@ -75,6 +75,8 @@ config SANDBOX
        imply FAT_WRITE
        imply HASH_VERIFY
        imply LZMA
+       imply SCSI
+       imply CMD_SATA
 
 config SH
        bool "SuperH architecture"
index 5f2048b..d43aaac 100644 (file)
@@ -792,6 +792,7 @@ config TARGET_LS2080AQDS
        select BOARD_LATE_INIT
        select SUPPORT_SPL
        select ARCH_MISC_INIT
+       imply SCSI
        help
          Support for Freescale LS2080AQDS platform
          The LS2080A Development System (QDS) is a high-performance
@@ -806,6 +807,7 @@ config TARGET_LS2080ARDB
        select BOARD_LATE_INIT
        select SUPPORT_SPL
        select ARCH_MISC_INIT
+       imply SCSI
        help
          Support for Freescale LS2080ARDB platform.
          The LS2080A Reference design board (RDB) is a high-performance
@@ -866,6 +868,7 @@ config TARGET_LS1012ARDB
        select ARCH_LS1012A
        select ARM64
        select BOARD_LATE_INIT
+       imply SCSI
        help
          Support for Freescale LS1012ARDB platform.
          The LS1012A Reference design board (RDB) is a high-performance
@@ -894,6 +897,7 @@ config TARGET_LS1021AQDS
        select LS1_DEEP_SLEEP
        select SYS_FSL_DDR
        select BOARD_EARLY_INIT_F
+       imply SCSI
 
 config TARGET_LS1021ATWR
        bool "Support ls1021atwr"
@@ -906,6 +910,7 @@ config TARGET_LS1021ATWR
        select ARCH_SUPPORT_PSCI
        select LS1_DEEP_SLEEP
        select BOARD_EARLY_INIT_F
+       imply SCSI
 
 config TARGET_LS1021AIOT
        bool "Support ls1021aiot"
@@ -916,6 +921,7 @@ config TARGET_LS1021AIOT
        select SUPPORT_SPL
        select ARCH_LS1021A
        select ARCH_SUPPORT_PSCI
+       imply SCSI
        help
          Support for Freescale LS1021AIOT platform.
          The LS1021A Freescale board (IOT) is a high-performance
@@ -930,6 +936,7 @@ config TARGET_LS1043AQDS
        select BOARD_LATE_INIT
        select SUPPORT_SPL
        select BOARD_EARLY_INIT_F
+       imply SCSI
        help
          Support for Freescale LS1043AQDS platform.
 
@@ -941,6 +948,7 @@ config TARGET_LS1043ARDB
        select BOARD_LATE_INIT
        select SUPPORT_SPL
        select BOARD_EARLY_INIT_F
+       imply SCSI
        help
          Support for Freescale LS1043ARDB platform.
 
@@ -953,6 +961,7 @@ config TARGET_LS1046AQDS
        select SUPPORT_SPL
        select DM_SPI_FLASH if DM_SPI
        select BOARD_EARLY_INIT_F
+       imply SCSI
        help
          Support for Freescale LS1046AQDS platform.
          The LS1046A Development System (QDS) is a high-performance
@@ -969,6 +978,7 @@ config TARGET_LS1046ARDB
        select DM_SPI_FLASH if DM_SPI
        select POWER_MC34VR500
        select BOARD_EARLY_INIT_F
+       imply SCSI
        help
          Support for Freescale LS1046ARDB platform.
          The LS1046A Reference Design Board (RDB) is a high-performance
index b61f3cd..6a013b2 100644 (file)
@@ -14,6 +14,7 @@ config ARCH_LS1021A
        select SYS_FSL_HAS_SEC
        select SYS_FSL_SEC_COMPAT_5
        select SYS_FSL_SEC_LE
+       imply SCSI
 
 menu "LS102xA architecture"
        depends on ARCH_LS1021A
index 144f2c3..e11d3a1 100644 (file)
@@ -36,7 +36,7 @@ int ls1021a_sata_init(void)
        out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
 
        ahci_init((void __iomem *)AHCI_BASE_ADDR);
-       scsi_scan(0);
+       scsi_scan(false);
 
        return 0;
 }
index 4fd60d4..1e5dc9a 100644 (file)
@@ -77,6 +77,7 @@ config TARGET_ADVANTECH_DMS_BA16
        bool "Advantech dms-ba16"
        select BOARD_LATE_INIT
        select MX6Q
+       imply CMD_SATA
 
 config TARGET_APALIS_IMX6
        bool "Toradex Apalis iMX6 board"
@@ -85,6 +86,7 @@ config TARGET_APALIS_IMX6
        select DM
        select DM_SERIAL
        select DM_THERMAL
+       imply CMD_SATA
 
 config TARGET_ARISTAINETOS
        bool "aristainetos"
@@ -141,6 +143,7 @@ config TARGET_GE_B850V3
 config TARGET_GW_VENTANA
        bool "gw_ventana"
        select SUPPORT_SPL
+       imply CMD_SATA
 
 config TARGET_KOSAGI_NOVENA
        bool "Kosagi Novena"
@@ -302,6 +305,7 @@ config TARGET_OPOS6ULDEV
 config TARGET_OT1200
        bool "Bachmann OT1200"
        select SUPPORT_SPL
+       imply CMD_SATA
 
 config TARGET_PICO_IMX6UL
        bool "PICO-IMX6UL-EMMC"
index 84bc213..1f2739e 100644 (file)
@@ -1042,7 +1042,7 @@ u32 imx_get_fecclk(void)
        return mxc_get_clock(MXC_IPG_CLK);
 }
 
-#if defined(CONFIG_CMD_SATA) || defined(CONFIG_PCIE_IMX)
+#if defined(CONFIG_SATA) || defined(CONFIG_PCIE_IMX)
 static int enable_enet_pll(uint32_t en)
 {
        struct mxc_ccm_reg *const imx_ccm
@@ -1069,7 +1069,7 @@ static int enable_enet_pll(uint32_t en)
 }
 #endif
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
 static void ungate_sata_clock(void)
 {
        struct mxc_ccm_reg *const imx_ccm =
@@ -1143,7 +1143,7 @@ int enable_pcie_clock(void)
        clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
 
        /* Party time! Ungate the clock to the PCIe. */
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        ungate_sata_clock();
 #endif
        ungate_pcie_clock();
index d8b285d..5825f9b 100644 (file)
@@ -26,6 +26,7 @@ config ARCH_LS1043A
        select SYS_FSL_HAS_DDR4
        select ARCH_EARLY_INIT_R
        select BOARD_EARLY_INIT_F
+       imply SCSI
 
 config ARCH_LS1046A
        bool
@@ -46,6 +47,7 @@ config ARCH_LS1046A
        select SYS_FSL_SRDS_2
        select ARCH_EARLY_INIT_R
        select BOARD_EARLY_INIT_F
+       imply SCSI
 
 config ARCH_LS2080A
        bool
index 0943e83..aee1ffa 100644 (file)
@@ -225,7 +225,7 @@ int sata_init(void)
        out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
 
        ahci_init((void __iomem *)CONFIG_SYS_SATA1);
-       scsi_scan(0);
+       scsi_scan(false);
 
        return 0;
 }
@@ -244,7 +244,7 @@ int sata_init(void)
        out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
 
        ahci_init((void __iomem *)CONFIG_SYS_SATA);
-       scsi_scan(0);
+       scsi_scan(false);
 
        return 0;
 }
index 35e02f5..0bab1e3 100644 (file)
@@ -25,6 +25,9 @@
                i2c1 = &i2c1;
                i2c2 = &i2c2;
                i2c3 = &i2c3;
+               mmc0 = &emmc;
+               mmc1 = &sdmmc;
+               mmc2 = &sdmmc_ext;
        };
 
        cpus {
index 5f4df88..18bcb75 100644 (file)
@@ -93,3 +93,7 @@
                };
        };
 };
+
+&uartd {
+       status = "okay";
+};
index c4d4f9d..b1dd418 100644 (file)
                };
        };
 };
+
+&uartd {
+       status = "okay";
+};
index f1db952..d642043 100644 (file)
                };
        };
 };
+
+&uartd {
+       status = "okay";
+};
index add9244..7e9c6aa 100644 (file)
        };
 
 };
+
+&uarta {
+       status = "okay";
+};
index 54b2539..a1319dc 100644 (file)
@@ -76,3 +76,7 @@
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index 3c10dd6..9171319 100644 (file)
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index dcbde7c..0c90705 100644 (file)
                clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
+
+&uartd {
+       status = "okay";
+};
index 7fb7dd0..31f509a 100644 (file)
        };
 
 };
+
+&uarta {
+       status = "okay";
+};
index 70cd72b..e6b0686 100644 (file)
@@ -57,3 +57,7 @@
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index d961296..539e7ce 100644 (file)
@@ -58,3 +58,7 @@
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index 0dc06a4..da4349b 100644 (file)
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index 2afcde5..16370c5 100644 (file)
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index 9e4ab8c..e739c59 100644 (file)
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index 4a32fcf..c1a15bb 100644 (file)
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index 70fd916..5b9798c 100644 (file)
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index 3cff2f6..49ebe91 100644 (file)
                };
        };
 };
+
+&uarta {
+       status = "okay";
+};
index e924acc..f2a49b8 100644 (file)
@@ -20,3 +20,7 @@
                status = "okay";
        };
 };
+
+&uartd {
+       status = "okay";
+};
index b7cb434..fc69172 100644 (file)
@@ -25,7 +25,7 @@ obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6 mx7))
 obj-y  += cache.o init.o
-obj-$(CONFIG_CMD_SATA) += sata.o
+obj-$(CONFIG_SATA) += sata.o
 obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
 obj-$(CONFIG_IMX_RDC) += rdc-sema.o
 obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o
index 74bdd24..9e83b42 100644 (file)
@@ -278,7 +278,7 @@ void arch_preboot_os(void)
 #if defined(CONFIG_PCIE_IMX)
        imx_pcie_remove();
 #endif
-#if defined(CONFIG_CMD_SATA)
+#if defined(CONFIG_SATA)
        sata_stop();
 #if defined(CONFIG_MX6)
        disable_sata_clock();
index 5c4da0f..fc954c5 100644 (file)
@@ -81,7 +81,6 @@
 
 /* SATA */
 #define AHCI_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x02200000)
-#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 6ae54ef..3e48d58 100644 (file)
@@ -57,6 +57,7 @@ config MV78230
 config MV78260
        bool
        select ARMADA_XP
+       imply CMD_SATA
 
 config MV78460
        bool
@@ -77,6 +78,7 @@ config TARGET_CLEARFOG
 config TARGET_MVEBU_ARMADA_37XX
        bool "Support Armada 37xx platforms"
        select ARMADA_3700
+       imply SCSI
 
 config TARGET_DB_88F6720
        bool "Support DB-88F6720 Armada 375"
@@ -94,6 +96,7 @@ config TARGET_MVEBU_ARMADA_8K
        bool "Support Armada 7k/8k platforms"
        select ARMADA_8K
        select BOARD_LATE_INIT
+       imply SCSI
 
 config TARGET_DB_MV784MP_GP
        bool "Support db-mv784mp-gp"
@@ -111,6 +114,7 @@ config TARGET_THEADORABLE
        bool "Support theadorable Armada XP"
        select BOARD_LATE_INIT if USB
        select MV78260
+       imply CMD_SATA
 
 config TARGET_CONTROLCENTERDC
        bool "Support CONTROLCENTERDC"
index 1a66abd..08f45bc 100644 (file)
@@ -25,12 +25,14 @@ config TARGET_DRA7XX_EVM
        select DRA7XX
        select TI_I2C_BOARD_DETECT
        select PHYS_64BIT
+       imply SCSI
 
 config TARGET_AM57XX_EVM
        bool "AM57XX"
        select BOARD_LATE_INIT
        select DRA7XX
        select TI_I2C_BOARD_DETECT
+       imply SCSI
 
 endchoice
 
index 0c82689..dc68896 100644 (file)
@@ -63,8 +63,10 @@ void scsi_init(void)
        scsi_scan(1);
 }
 
-void scsi_bus_reset(void)
+int scsi_bus_reset(struct udevice *dev)
 {
        ahci_reset((void __iomem *)DWC_AHSATA_BASE);
        ahci_init((void __iomem *)DWC_AHSATA_BASE);
+
+       return 0;
 }
index 1e627ba..6b5fa7d 100644 (file)
@@ -9,14 +9,8 @@
 #include <dm.h>
 #include <errno.h>
 #include <ns16550.h>
-#include <linux/compiler.h>
-#include <linux/sizes.h>
+#include <usb.h>
 #include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/funcmux.h>
-#include <asm/arch/pinmux.h>
-#include <asm/arch/pmu.h>
-#include <asm/arch/tegra.h>
 #include <asm/arch-tegra/ap.h>
 #include <asm/arch-tegra/board.h>
 #include <asm/arch-tegra/clk_rst.h>
 #include <asm/arch-tegra/uart.h>
 #include <asm/arch-tegra/warmboot.h>
 #include <asm/arch-tegra/gpu.h>
+#include <asm/arch-tegra/usb.h>
+#include <asm/arch-tegra/xusb-padctl.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/funcmux.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/pmu.h>
+#include <asm/arch/tegra.h>
 #ifdef CONFIG_TEGRA_CLOCK_SCALING
 #include <asm/arch/emc.h>
 #endif
-#include <asm/arch-tegra/usb.h>
-#ifdef CONFIG_USB_EHCI_TEGRA
-#include <usb.h>
-#endif
-#include <asm/arch-tegra/xusb-padctl.h>
 #include <power/as3722.h>
-#include <i2c.h>
-#include <spi.h>
 #include "emc.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -162,8 +156,10 @@ int board_init(void)
 #if defined(CONFIG_DM_VIDEO)
        board_id = tegra_board_id();
        err = tegra_lcd_pmic_init(board_id);
-       if (err)
+       if (err) {
+               debug("Failed to set up LCD PMIC\n");
                return err;
+       }
 #endif
 
 #ifdef CONFIG_TEGRA_NAND
index bac4211..668bbd2 100644 (file)
@@ -7,6 +7,8 @@
 /* Tegra SoC common clock control functions */
 
 #include <common.h>
+#include <div64.h>
+#include <dm.h>
 #include <errno.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
@@ -15,8 +17,6 @@
 #include <asm/arch-tegra/clk_rst.h>
 #include <asm/arch-tegra/pmc.h>
 #include <asm/arch-tegra/timer.h>
-#include <div64.h>
-#include <fdtdec.h>
 
 /*
  * This is our record of the current clock rate of each clock. We don't
index 0772b7c..cdd21a2 100644 (file)
@@ -54,6 +54,7 @@ config TARGET_MPC8349ITX
 config TARGET_MPC837XEMDS
        bool "Support MPC837XEMDS"
        select BOARD_EARLY_INIT_F
+       imply CMD_SATA
 
 config TARGET_MPC837XERDB
        bool "Support MPC837XERDB"
index 4db687c..0bff79a 100644 (file)
@@ -63,30 +63,35 @@ config TARGET_P3041DS
        select PHYS_64BIT
        select ARCH_P3041
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
+       imply CMD_SATA
 
 config TARGET_P4080DS
        bool "Support P4080DS"
        select PHYS_64BIT
        select ARCH_P4080
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
+       imply CMD_SATA
 
 config TARGET_P5020DS
        bool "Support P5020DS"
        select PHYS_64BIT
        select ARCH_P5020
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
+       imply CMD_SATA
 
 config TARGET_P5040DS
        bool "Support P5040DS"
        select PHYS_64BIT
        select ARCH_P5040
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
+       imply CMD_SATA
 
 config TARGET_MPC8536DS
        bool "Support MPC8536DS"
        select ARCH_MPC8536
 # Use DDR3 controller with DDR2 DIMMs on this board
        select SYS_FSL_DDRC_GEN3
+       imply CMD_SATA
 
 config TARGET_MPC8541CDS
        bool "Support MPC8541CDS"
@@ -117,6 +122,7 @@ config TARGET_MPC8572DS
        select ARCH_MPC8572
 # Use DDR3 controller with DDR2 DIMMs on this board
        select SYS_FSL_DDRC_GEN3
+       imply SCSI
 
 config TARGET_P1010RDB_PA
        bool "Support P1010RDB_PA"
@@ -125,6 +131,7 @@ config TARGET_P1010RDB_PA
        select SUPPORT_SPL
        select SUPPORT_TPL
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1010RDB_PB
        bool "Support P1010RDB_PB"
@@ -133,12 +140,14 @@ config TARGET_P1010RDB_PB
        select SUPPORT_SPL
        select SUPPORT_TPL
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1022DS
        bool "Support P1022DS"
        select ARCH_P1022
        select SUPPORT_SPL
        select SUPPORT_TPL
+       imply CMD_SATA
 
 config TARGET_P1023RDB
        bool "Support P1023RDB"
@@ -151,6 +160,7 @@ config TARGET_P1020MBG
        select SUPPORT_TPL
        select ARCH_P1020
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1020RDB_PC
        bool "Support P1020RDB-PC"
@@ -158,6 +168,7 @@ config TARGET_P1020RDB_PC
        select SUPPORT_TPL
        select ARCH_P1020
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1020RDB_PD
        bool "Support P1020RDB-PD"
@@ -165,6 +176,7 @@ config TARGET_P1020RDB_PD
        select SUPPORT_TPL
        select ARCH_P1020
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1020UTM
        bool "Support P1020UTM"
@@ -172,6 +184,7 @@ config TARGET_P1020UTM
        select SUPPORT_TPL
        select ARCH_P1020
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1021RDB
        bool "Support P1021RDB"
@@ -179,6 +192,7 @@ config TARGET_P1021RDB
        select SUPPORT_TPL
        select ARCH_P1021
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1024RDB
        bool "Support P1024RDB"
@@ -186,6 +200,7 @@ config TARGET_P1024RDB
        select SUPPORT_TPL
        select ARCH_P1024
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1025RDB
        bool "Support P1025RDB"
@@ -193,6 +208,7 @@ config TARGET_P1025RDB
        select SUPPORT_TPL
        select ARCH_P1025
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P2020RDB
        bool "Support P2020RDB-PC"
@@ -200,6 +216,7 @@ config TARGET_P2020RDB
        select SUPPORT_TPL
        select ARCH_P2020
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_P1_TWR
        bool "Support p1_twr"
@@ -210,6 +227,7 @@ config TARGET_P2041RDB
        select ARCH_P2041
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_QEMU_PPCE500
        bool "Support qemu-ppce500"
@@ -223,6 +241,7 @@ config TARGET_T1024QDS
        select SUPPORT_SPL
        select PHYS_64BIT
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_T1023RDB
        bool "Support T1023RDB"
@@ -246,6 +265,7 @@ config TARGET_T1040QDS
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select PHYS_64BIT
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config TARGET_T1040RDB
        bool "Support T1040RDB"
@@ -253,6 +273,7 @@ config TARGET_T1040RDB
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T1040D4RDB
        bool "Support T1040D4RDB"
@@ -260,6 +281,7 @@ config TARGET_T1040D4RDB
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T1042RDB
        bool "Support T1042RDB"
@@ -267,6 +289,7 @@ config TARGET_T1042RDB
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T1042D4RDB
        bool "Support T1042D4RDB"
@@ -274,6 +297,7 @@ config TARGET_T1042D4RDB
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T1042RDB_PI
        bool "Support T1042RDB_PI"
@@ -281,6 +305,7 @@ config TARGET_T1042RDB_PI
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T2080QDS
        bool "Support T2080QDS"
@@ -288,6 +313,7 @@ config TARGET_T2080QDS
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T2080RDB
        bool "Support T2080RDB"
@@ -295,6 +321,7 @@ config TARGET_T2080RDB
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T2081QDS
        bool "Support T2081QDS"
@@ -308,6 +335,7 @@ config TARGET_T4160QDS
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T4160RDB
        bool "Support T4160RDB"
@@ -321,12 +349,14 @@ config TARGET_T4240QDS
        select BOARD_LATE_INIT if CHAIN_OF_TRUST
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_T4240RDB
        bool "Support T4240RDB"
        select ARCH_T4240
        select SUPPORT_SPL
        select PHYS_64BIT
+       imply CMD_SATA
 
 config TARGET_CONTROLCENTERD
        bool "Support controlcenterd"
@@ -356,6 +386,7 @@ config TARGET_XPEDITE550X
 config TARGET_UCP1020
        bool "Support uCP1020"
        select ARCH_P1020
+       imply CMD_SATA
 
 config TARGET_CYRUS_P5020
        bool "Support Varisys Cyrus P5020"
@@ -477,6 +508,7 @@ config ARCH_MPC8536
        select SYS_FSL_SEC_COMPAT_2
        select SYS_PPC_E500_USE_DEBUG_TLB
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_MPC8540
        bool
@@ -585,6 +617,7 @@ config ARCH_P1010
        select SYS_PPC_E500_USE_DEBUG_TLB
        select FSL_IFC
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config ARCH_P1011
        bool
@@ -613,6 +646,7 @@ config ARCH_P1020
        select SYS_FSL_SEC_COMPAT_2
        select SYS_PPC_E500_USE_DEBUG_TLB
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_P1021
        bool
@@ -627,6 +661,7 @@ config ARCH_P1021
        select SYS_FSL_SEC_COMPAT_2
        select SYS_PPC_E500_USE_DEBUG_TLB
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_P1022
        bool
@@ -670,6 +705,7 @@ config ARCH_P1024
        select SYS_PPC_E500_USE_DEBUG_TLB
        select FSL_ELBC
        imply CMD_EEPROM
+       imply CMD_SATA
 
 config ARCH_P1025
        bool
@@ -684,6 +720,7 @@ config ARCH_P1025
        select SYS_FSL_SEC_COMPAT_2
        select SYS_PPC_E500_USE_DEBUG_TLB
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_P2020
        bool
@@ -746,6 +783,7 @@ config ARCH_P3041
        select SYS_FSL_SEC_BE
        select SYS_FSL_SEC_COMPAT_4
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_P4080
        bool
@@ -781,6 +819,7 @@ config ARCH_P4080
        select SYS_FSL_SEC_BE
        select SYS_FSL_SEC_COMPAT_4
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_P5020
        bool
@@ -802,6 +841,7 @@ config ARCH_P5020
        select SYS_FSL_SEC_COMPAT_4
        select SYS_PPC64
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_P5040
        bool
@@ -823,6 +863,7 @@ config ARCH_P5040
        select SYS_FSL_SEC_COMPAT_4
        select SYS_PPC64
        select FSL_ELBC
+       imply CMD_SATA
 
 config ARCH_QEMU_E500
        bool
@@ -880,6 +921,7 @@ config ARCH_T1040
        select SYS_FSL_SEC_BE
        select SYS_FSL_SEC_COMPAT_5
        select FSL_IFC
+       imply CMD_SATA
 
 config ARCH_T1042
        bool
@@ -898,6 +940,7 @@ config ARCH_T1042
        select SYS_FSL_SEC_BE
        select SYS_FSL_SEC_COMPAT_5
        select FSL_IFC
+       imply CMD_SATA
 
 config ARCH_T2080
        bool
@@ -920,6 +963,7 @@ config ARCH_T2080
        select SYS_FSL_SEC_COMPAT_4
        select SYS_PPC64
        select FSL_IFC
+       imply CMD_SATA
 
 config ARCH_T2081
        bool
@@ -961,6 +1005,7 @@ config ARCH_T4160
        select SYS_FSL_SEC_COMPAT_4
        select SYS_PPC64
        select FSL_IFC
+       imply CMD_SATA
 
 config ARCH_T4240
        bool
@@ -985,6 +1030,7 @@ config ARCH_T4240
        select SYS_FSL_SEC_COMPAT_4
        select SYS_PPC64
        select FSL_IFC
+       imply CMD_SATA
 
 config BOOKE
        bool
index f5bf67c..a3076d8 100644 (file)
@@ -48,7 +48,7 @@
 #ifndef CONFIG_ARCH_QEMU_E500
 #include <fsl_ddr.h>
 #endif
-#include "../../../../drivers/block/fsl_sata.h"
+#include "../../../../drivers/ata/fsl_sata.h"
 #ifdef CONFIG_U_QE
 #include <fsl_qe.h>
 #endif
@@ -1024,7 +1024,7 @@ void arch_preboot_os(void)
        mtmsr(msr);
 }
 
-#if defined(CONFIG_CMD_SATA) && defined(CONFIG_FSL_SATA)
+#if defined(CONFIG_SATA) && defined(CONFIG_FSL_SATA)
 int sata_initialize(void)
 {
        if (is_serdes_configured(SATA1) || is_serdes_configured(SATA2))
index fcac658..2cc180d 100644 (file)
@@ -21,6 +21,7 @@ config TARGET_MPC8610HPCD
 config TARGET_MPC8641HPCN
        bool "Support MPC8641HPCN"
        select ARCH_MPC8641
+       imply SCSI
 
 config TARGET_XPEDITE517X
        bool "Support xpedite517x"
index 7cc76d4..2495fa9 100644 (file)
@@ -44,16 +44,5 @@ SPL_LOAD_IMAGE_METHOD("sandbox", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
 
 void spl_board_init(void)
 {
-       struct udevice *dev;
-
        preloader_console_init();
-
-       /*
-       * Scan all the devices so that we can output their platform data. See
-       * sandbox_spl_probe().
-       */
-       for (uclass_first_device(UCLASS_MISC, &dev);
-       dev;
-       uclass_next_device(&dev))
-               ;
 }
index 40f423d..0aba6c9 100644 (file)
@@ -5,6 +5,7 @@
 / {
        #address-cells = <1>;
        #size-cells = <1>;
+       model = "sandbox";
 
        aliases {
                eth5 = "/eth@90000000";
index 7dde95d..65b2f8e 100644 (file)
                };
        };
 
+       probing {
+               compatible = "simple-bus";
+               test1 {
+                       compatible = "denx,u-boot-probe-test";
+               };
+
+               test2 {
+                       compatible = "denx,u-boot-probe-test";
+               };
+
+               test3 {
+                       compatible = "denx,u-boot-probe-test";
+               };
+
+               test4 {
+                       compatible = "denx,u-boot-probe-test";
+               };
+       };
+
        pwrdom: power-domain {
                compatible = "sandbox,power-domain";
                #power-domain-cells = <1>;
index 0f5e190..462b7c0 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <ahci.h>
 #include <dm.h>
 #include <fdtdec.h>
 #include <asm/io.h>
@@ -208,6 +209,20 @@ static void bd82x6x_sata_enable(struct udevice *dev)
        dm_pci_write_config16(dev, 0x90, map);
 }
 
+static int bd82x6x_sata_bind(struct udevice *dev)
+{
+       struct udevice *scsi_dev;
+       int ret;
+
+       if (gd->flags & GD_FLG_RELOC) {
+               ret = ahci_bind_scsi(dev, &scsi_dev);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static int bd82x6x_sata_probe(struct udevice *dev)
 {
        struct udevice *pch;
@@ -219,8 +234,12 @@ static int bd82x6x_sata_probe(struct udevice *dev)
 
        if (!(gd->flags & GD_FLG_RELOC))
                bd82x6x_sata_enable(dev);
-       else
+       else {
                bd82x6x_sata_init(dev, pch);
+               ret = ahci_probe_scsi(dev);
+               if (ret)
+                       return ret;
+       }
 
        return 0;
 }
@@ -234,5 +253,6 @@ U_BOOT_DRIVER(ahci_ivybridge_drv) = {
        .name           = "ahci_ivybridge",
        .id             = UCLASS_AHCI,
        .of_match       = bd82x6x_ahci_ids,
+       .bind           = bd82x6x_sata_bind,
        .probe          = bd82x6x_sata_probe,
 };
index 91e96ab..2dab906 100644 (file)
@@ -609,7 +609,7 @@ int board_late_init(void)
        pwm_enable(0);
 #endif
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_ba16_sata();
 #endif
 
index c0a8b64..74f652e 100644 (file)
@@ -338,7 +338,7 @@ int board_init(void)
 
        leds_on();
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_sata();
 #endif
 
index ab8b2be..1145af5 100644 (file)
@@ -903,7 +903,7 @@ int board_init(void)
        setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
        setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_sata();
 #endif
 
index 875d1ae..ff5a1d8 100644 (file)
@@ -13,6 +13,7 @@ choice
 config TARGET_CONGA_QEVAL20_QA3_E3845
        bool "congatec QEVAL 2.0 & conga-QA3/E3845"
        select BOARD_LATE_INIT
+       imply SCSI
        help
          This is the congatec Qseven 2.0 evaluation carrier board
          (conga-QEVAL) equipped with the conga-QA3/E3845-4G SoM.
index 24956a8..fe7db91 100644 (file)
@@ -702,7 +702,7 @@ int board_init(void)
        else
                setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_sata();
 #endif
 
index 25d0a11..d2a1d78 100644 (file)
@@ -12,6 +12,7 @@ choice
 
 config TARGET_DFI_BT700
        bool "DFI BT700 BayTrail"
+       imply SCSI
        help
          This is the DFI Q7X-151 baseboard equipped with the
          DFI BayTrail Bt700 SoM. It contains an Atom E3845 with
index 6b950ee..40ee1b6 100644 (file)
@@ -633,7 +633,7 @@ int board_init(void)
 #endif
        setup_ventana_i2c();
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_sata();
 #endif
        /* read Gateworks EEPROM into global struct (used later) */
index 1578a33..dadfbdd 100644 (file)
@@ -172,7 +172,7 @@ static void cphy_override_lane(u8 port)
 
 #define WAIT_MS_LINKUP 4
 
-int ahci_link_up(struct ahci_probe_ent *probe_ent, int port)
+int ahci_link_up(struct ahci_uc_priv *probe_ent, int port)
 {
        u32 tmp;
        int j = 0;
index 55999ed..1af2207 100644 (file)
@@ -67,7 +67,7 @@ void scsi_init(void)
        cphy_disable_overrides();
        if (reg & PWRDOM_STAT_SATA) {
                ahci_init((void __iomem *)HB_AHCI_BASE);
-               scsi_scan(1);
+               scsi_scan(true);
        }
 }
 #endif
index f6972c2..17c2b13 100644 (file)
@@ -167,7 +167,7 @@ int board_init(void)
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_sata();
 #endif
 
index 02d8ab3..9dc2eb0 100644 (file)
@@ -333,7 +333,7 @@ the contents of the root directory on the second partion of the image
 A disk image can be created using the following commands:
 
 $> truncate -s 1200M ./disk.raw
-$> echo -e "label: gpt\n,64M,U\n,,L" | /usr/sbin/sfdisk  ./disk.raw
+$> echo -e "label: gpt\n,64M,U\n,,L" | /usr/sbin/sgdisk  ./disk.raw
 $> lodev=`sudo losetup -P -f --show ./disk.raw`
 $> sudo mkfs.vfat -n EFI -v ${lodev}p1
 $> sudo mkfs.ext4 -L ROOT -v ${lodev}p2
index 7c49ddf..166b93f 100644 (file)
@@ -784,7 +784,7 @@ int board_init(void)
        (void) pmic_init();
 #endif
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_sata();
 #endif
 
index 69467ca..87e2447 100644 (file)
@@ -657,7 +657,7 @@ int board_init(void)
        (void) pmic_init();
 #endif
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        setup_sata();
 #endif
 
index eb7ab65..d2cbbaa 100644 (file)
@@ -244,7 +244,7 @@ int board_init(void)
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        if (is_cpu_type(MXC_CPU_MX6Q))
                setup_sata();
 #endif
index 2c9dc8b..438bc0e 100644 (file)
@@ -379,7 +379,7 @@ int board_early_init_f(void)
 #if defined(CONFIG_VIDEO_IPUV3)
        setup_display();
 #endif
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
        /* Only mx6q wandboard has SATA */
        if (is_cpu_type(MXC_CPU_MX6Q))
                setup_sata();
index 6758db1..c80ac36 100644 (file)
@@ -734,6 +734,19 @@ config CMD_FDC
        help
          The 'fdtboot' command allows booting an image from a floppy disk.
 
+config CMD_SATA
+       bool "sata - Access SATA subsystem"
+       select SATA
+       help
+         SATA (Serial Advanced Technology Attachment) is a serial bus
+         standard for connecting to hard drives and other storage devices.
+         This command provides information about attached devices and allows
+         reading, writing and other operations.
+
+         SATA replaces PATA (originally just ATA), which stands for Parallel AT
+         Attachment, where AT refers to an IBM AT (Advanced Technology)
+         computer released in 1984.
+
 endmenu
 
 
index 31a5361..05e19f8 100644 (file)
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -284,6 +284,10 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        len = 0;
                } else {
                        ptmp = fdt_getprop(working_fdt, nodeoffset, prop, &len);
+                       if (!ptmp) {
+                               printf("prop (%s) not found!\n", prop);
+                               return 1;
+                       }
                        if (len > SCRATCHPAD) {
                                printf("prop (%d) doesn't fit in scratchpad!\n",
                                       len);
index 4213ec8..5709718 100644 (file)
@@ -36,8 +36,8 @@ static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        case 2:
                if (strncmp(argv[1], "res", 3) == 0) {
                        printf("\nReset SCSI\n");
-                       scsi_bus_reset();
-                       ret = scsi_scan(1);
+                       scsi_bus_reset(NULL);
+                       ret = scsi_scan(true);
                        if (ret)
                                return CMD_RET_FAILURE;
                        return ret;
@@ -55,7 +55,7 @@ static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                        return 0;
                }
                if (strncmp(argv[1], "scan", 4) == 0) {
-                       ret = scsi_scan(1);
+                       ret = scsi_scan(true);
                        if (ret)
                                return CMD_RET_FAILURE;
                        return ret;
index 1be0667..15aab5d 100644 (file)
@@ -17,7 +17,9 @@ const char __weak version_string[] = U_BOOT_VERSION_STRING;
 
 static int do_version(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       printf("\n%s\n", version_string);
+       char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
+
+       printf(display_options_get_banner(false, buf, sizeof(buf)));
 #ifdef CC_VERSION_STRING
        puts(CC_VERSION_STRING "\n");
 #endif
index 086b676..361346b 100644 (file)
@@ -488,7 +488,7 @@ config DISPLAY_CPUINFO
 
 config DISPLAY_BOARDINFO
        bool "Display information about the board during start up"
-       default y if ARM || M68K || MIPS || PPC || XTENSA
+       default y if ARM || M68K || MIPS || PPC || SANDBOX || XTENSA
        help
          Display information about the board that U-Boot is running on
          when U-Boot starts up. The board function checkboard() is called
index 8540fbc..17a92ea 100644 (file)
@@ -79,8 +79,6 @@ obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o
 obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
 obj-$(CONFIG_LYNXKDI) += lynxkdi.o
 obj-$(CONFIG_MENU) += menu.o
-obj-$(CONFIG_CMD_SATA) += sata.o
-obj-$(CONFIG_SCSI) += scsi.o
 obj-$(CONFIG_UPDATE_TFTP) += update.o
 obj-$(CONFIG_DFU_TFTP) += update.o
 obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
@@ -122,9 +120,6 @@ obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
 obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 endif
-ifdef CONFIG_SPL_SATA_SUPPORT
-obj-$(CONFIG_SCSI) += scsi.o
-endif
 endif
 #environment
 obj-y += env_common.o
index 3341a52..ecca1ed 100644 (file)
@@ -829,6 +829,7 @@ static init_fnc_t init_sequence_r[] = {
 #endif
        console_init_r,         /* fully init console as a device */
 #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
+       console_announce_r,
        show_board_info,
 #endif
 #ifdef CONFIG_ARCH_MISC_INIT
index 1232808..c6156f3 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdarg.h>
 #include <iomux.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <os.h>
 #include <serial.h>
 #include <stdio_dev.h>
@@ -202,7 +203,6 @@ static void console_putc(int file, const char c)
        }
 }
 
-#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
 static void console_puts_noserial(int file, const char *s)
 {
        int i;
@@ -214,7 +214,6 @@ static void console_puts_noserial(int file, const char *s)
                        dev->puts(dev, s);
        }
 }
-#endif
 
 static void console_puts(int file, const char *s)
 {
@@ -248,13 +247,11 @@ static inline void console_putc(int file, const char c)
        stdio_devices[file]->putc(stdio_devices[file], c);
 }
 
-#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
 static inline void console_puts_noserial(int file, const char *s)
 {
        if (strcmp(stdio_devices[file]->name, "serial") != 0)
                stdio_devices[file]->puts(stdio_devices[file], s);
 }
-#endif
 
 static inline void console_puts(int file, const char *s)
 {
@@ -420,9 +417,13 @@ int tstc(void)
 
 static void pre_console_putc(const char c)
 {
-       char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
+       char *buffer;
+
+       buffer = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
 
        buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
+
+       unmap_sysmem(buffer);
 }
 
 static void pre_console_puts(const char *s)
@@ -434,14 +435,16 @@ static void pre_console_puts(const char *s)
 static void print_pre_console_buffer(int flushpoint)
 {
        unsigned long in = 0, out = 0;
-       char *buf_in = (char *)CONFIG_PRE_CON_BUF_ADDR;
        char buf_out[CONFIG_PRE_CON_BUF_SZ + 1];
+       char *buf_in;
 
+       buf_in = map_sysmem(CONFIG_PRE_CON_BUF_ADDR, CONFIG_PRE_CON_BUF_SZ);
        if (gd->precon_buf_idx > CONFIG_PRE_CON_BUF_SZ)
                in = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
 
        while (in < gd->precon_buf_idx)
                buf_out[out++] = buf_in[CIRC_BUF_IDX(in++)];
+       unmap_sysmem(buf_in);
 
        buf_out[out] = 0;
 
@@ -462,13 +465,6 @@ static inline void print_pre_console_buffer(int flushpoint) {}
 
 void putc(const char c)
 {
-#ifdef CONFIG_SANDBOX
-       /* sandbox can send characters to stdout before it has a console */
-       if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
-               os_putc(c);
-               return;
-       }
-#endif
 #ifdef CONFIG_DEBUG_UART
        /* if we don't have a console yet, use the debug UART */
        if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
@@ -505,12 +501,6 @@ void putc(const char c)
 
 void puts(const char *s)
 {
-#ifdef CONFIG_SANDBOX
-       if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
-               os_puts(s);
-               return;
-       }
-#endif
 #ifdef CONFIG_DEBUG_UART
        if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
                while (*s) {
@@ -699,6 +689,19 @@ static void console_update_silent(void)
 #endif
 }
 
+int console_announce_r(void)
+{
+#if !CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
+       char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
+
+       display_options_get_banner(false, buf, sizeof(buf));
+
+       console_puts_noserial(stdout, buf);
+#endif
+
+       return 0;
+}
+
 /* Called before relocation - use serial functions */
 int console_init_f(void)
 {
index 5476206..bac11f6 100644 (file)
@@ -34,7 +34,7 @@ static int spl_sata_load_image(struct spl_image_info *spl_image,
                return err;
        } else {
                /* try to recognize storage devices immediately */
-               scsi_scan(0);
+               scsi_scan(false);
                stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0);
                if (!stor_dev)
                        return -ENODEV;
index d1647c8..ee055dd 100644 (file)
@@ -162,7 +162,7 @@ static inline int splash_init_usb(void)
 }
 #endif
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
 static int splash_init_sata(void)
 {
        return sata_initialize();
index 03171f7..df0b057 100644 (file)
@@ -63,7 +63,7 @@ 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)));
+static struct scsi_cmd usb_ccb __aligned(ARCH_DMA_MINALIGN);
 static __u32 CBWTag;
 
 static int usb_max_devs; /* number of highest available usb device */
@@ -73,7 +73,7 @@ static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
 #endif
 
 struct us_data;
-typedef int (*trans_cmnd)(ccb *cb, struct us_data *data);
+typedef int (*trans_cmnd)(struct scsi_cmd *cb, struct us_data *data);
 typedef int (*trans_reset)(struct us_data *data);
 
 struct us_data {
@@ -95,7 +95,7 @@ struct us_data {
        unsigned int    irqpipe;                /* pipe for release_irq */
        unsigned char   irqmaxp;                /* max packed for irq Pipe */
        unsigned char   irqinterval;            /* Intervall for IRQ Pipe */
-       ccb             *srb;                   /* current srb */
+       struct scsi_cmd *srb;                   /* current srb */
        trans_reset     transport_reset;        /* reset routine */
        trans_cmnd      transport;              /* transport routine */
 };
@@ -349,7 +349,7 @@ static int usb_stor_irq(struct usb_device *dev)
 
 #ifdef DEBUG
 
-static void usb_show_srb(ccb *pccb)
+static void usb_show_srb(struct scsi_cmd *pccb)
 {
        int i;
        printf("SRB: len %d datalen 0x%lX\n ", pccb->cmdlen, pccb->datalen);
@@ -541,7 +541,7 @@ static int usb_stor_CB_reset(struct us_data *us)
  * Set up the command for a BBB device. Note that the actual SCSI
  * command is copied into cbw.CBWCDB.
  */
-static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
+static int usb_stor_BBB_comdat(struct scsi_cmd *srb, struct us_data *us)
 {
        int result;
        int actlen;
@@ -590,7 +590,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 /* FIXME: we also need a CBI_command which sets up the completion
  * interrupt, and waits for it
  */
-static int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
+static int usb_stor_CB_comdat(struct scsi_cmd *srb, struct us_data *us)
 {
        int result = 0;
        int dir_in, retry;
@@ -659,7 +659,7 @@ static int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
 }
 
 
-static int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
+static int usb_stor_CBI_get_status(struct scsi_cmd *srb, struct us_data *us)
 {
        int timeout;
 
@@ -714,7 +714,7 @@ static int usb_stor_BBB_clear_endpt_stall(struct us_data *us, __u8 endpt)
                               endpt, NULL, 0, USB_CNTL_TIMEOUT * 5);
 }
 
-static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
+static int usb_stor_BBB_transport(struct scsi_cmd *srb, struct us_data *us)
 {
        int result, retry;
        int dir_in;
@@ -837,11 +837,11 @@ again:
        return result;
 }
 
-static int usb_stor_CB_transport(ccb *srb, struct us_data *us)
+static int usb_stor_CB_transport(struct scsi_cmd *srb, struct us_data *us)
 {
        int result, status;
-       ccb *psrb;
-       ccb reqsrb;
+       struct scsi_cmd *psrb;
+       struct scsi_cmd reqsrb;
        int retry, notready;
 
        psrb = &reqsrb;
@@ -950,7 +950,7 @@ do_retry:
 }
 
 
-static int usb_inquiry(ccb *srb, struct us_data *ss)
+static int usb_inquiry(struct scsi_cmd *srb, struct us_data *ss)
 {
        int retry, i;
        retry = 5;
@@ -974,7 +974,7 @@ static int usb_inquiry(ccb *srb, struct us_data *ss)
        return 0;
 }
 
-static int usb_request_sense(ccb *srb, struct us_data *ss)
+static int usb_request_sense(struct scsi_cmd *srb, struct us_data *ss)
 {
        char *ptr;
 
@@ -994,7 +994,7 @@ static int usb_request_sense(ccb *srb, struct us_data *ss)
        return 0;
 }
 
-static int usb_test_unit_ready(ccb *srb, struct us_data *ss)
+static int usb_test_unit_ready(struct scsi_cmd *srb, struct us_data *ss)
 {
        int retries = 10;
 
@@ -1025,7 +1025,7 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss)
        return -1;
 }
 
-static int usb_read_capacity(ccb *srb, struct us_data *ss)
+static int usb_read_capacity(struct scsi_cmd *srb, struct us_data *ss)
 {
        int retry;
        /* XXX retries */
@@ -1043,8 +1043,8 @@ static int usb_read_capacity(ccb *srb, struct us_data *ss)
        return -1;
 }
 
-static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start,
-                      unsigned short blocks)
+static int usb_read_10(struct scsi_cmd *srb, struct us_data *ss,
+                      unsigned long start, unsigned short blocks)
 {
        memset(&srb->cmd[0], 0, 12);
        srb->cmd[0] = SCSI_READ10;
@@ -1060,8 +1060,8 @@ static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start,
        return ss->transport(srb, ss);
 }
 
-static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start,
-                       unsigned short blocks)
+static int usb_write_10(struct scsi_cmd *srb, struct us_data *ss,
+                       unsigned long start, unsigned short blocks)
 {
        memset(&srb->cmd[0], 0, 12);
        srb->cmd[0] = SCSI_WRITE10;
@@ -1115,7 +1115,7 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
        struct usb_device *udev;
        struct us_data *ss;
        int retry;
-       ccb *srb = &usb_ccb;
+       struct scsi_cmd *srb = &usb_ccb;
 #ifdef CONFIG_BLK
        struct blk_desc *block_dev;
 #endif
@@ -1197,7 +1197,7 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
        struct usb_device *udev;
        struct us_data *ss;
        int retry;
-       ccb *srb = &usb_ccb;
+       struct scsi_cmd *srb = &usb_ccb;
 #ifdef CONFIG_BLK
        struct blk_desc *block_dev;
 #endif
@@ -1395,7 +1395,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
        ALLOC_CACHE_ALIGN_BUFFER(u32, cap, 2);
        ALLOC_CACHE_ALIGN_BUFFER(u8, usb_stor_buf, 36);
        u32 capacity, blksz;
-       ccb *pccb = &usb_ccb;
+       struct scsi_cmd *pccb = &usb_ccb;
 
        pccb->pdata = usb_stor_buf;
 
index ec16a44..9143022 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_AXP_ALDO3_VOLT=2800
 CONFIG_AXP_ALDO4_VOLT=2800
index 1f2daa6..f7b600b 100644 (file)
@@ -20,6 +20,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_SCSI=y
 CONFIG_DFU_RAM=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
index 7f63d4a..182a8f5 100644 (file)
@@ -16,6 +16,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_ALDO3_VOLT=2800
index 89e87e7..ae98e41 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_AXP_ALDO3_VOLT=2800
index 6c87648..61fe5e6 100644 (file)
@@ -20,6 +20,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index 4332eca..8c409fa 100644 (file)
@@ -14,5 +14,6 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_FPGA is not set
+CONFIG_SCSI=y
 CONFIG_AXP_DLDO4_VOLT=2500
 CONFIG_AXP_ELDO3_VOLT=1200
index fe75eef..352a18e 100644 (file)
@@ -17,6 +17,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_NETCONSOLE=y
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index df65922..4218d5a 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_NETCONSOLE=y
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index 02c503f..dc2722a 100644 (file)
@@ -15,6 +15,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_USB_EHCI_HCD=y
index a8e9c98..f83a691 100644 (file)
@@ -15,5 +15,6 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_USB_EHCI_HCD=y
index f9d56c8..cbd535c 100644 (file)
@@ -22,6 +22,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_SCSI=y
 CONFIG_DFU_RAM=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
index 4bae19f..bab25b4 100644 (file)
@@ -15,6 +15,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_USB_EHCI_HCD=y
index cc29d60..2ec0847 100644 (file)
@@ -17,6 +17,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index 80416cb..1e61cd2 100644 (file)
@@ -17,6 +17,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index b9f89a0..6f4a02f 100644 (file)
@@ -15,6 +15,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_USB_EHCI_HCD=y
index 38417e7..32b88fc 100644 (file)
@@ -7,6 +7,7 @@ CONFIG_BOOTDELAY=6
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index 9cec452..c7f093e 100644 (file)
@@ -10,6 +10,7 @@ CONFIG_SYS_PROMPT="MPC8349E-mITX> "
 CONFIG_CMD_IDE=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_PING=y
index 9145ada..e508b3d 100644 (file)
@@ -10,6 +10,7 @@ CONFIG_SYS_PROMPT="MPC8349E-mITX> "
 CONFIG_CMD_IDE=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_PING=y
index 2f3e7b0..fc21671 100644 (file)
@@ -8,6 +8,7 @@ CONFIG_HUSH_PARSER=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index aef9bac..cb15afa 100644 (file)
@@ -15,6 +15,7 @@ CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 # CONFIG_CMD_HASH is not set
 CONFIG_CMD_EXT2=y
+CONFIG_SCSI=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_NETDEVICES=y
index d949990..6aef6d8 100644 (file)
@@ -15,6 +15,7 @@ CONFIG_CMD_PING=y
 CONFIG_CMD_BMP=y
 CONFIG_CMD_EXT2=y
 CONFIG_DOS_PARTITION=y
+CONFIG_SCSI=y
 # CONFIG_MMC is not set
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_SYS_NS16550=y
index 6b8bd1a..516a16f 100644 (file)
@@ -11,6 +11,7 @@ CONFIG_SPL=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_SUNXI_NO_PMIC=y
 CONFIG_USB_EHCI_HCD=y
index 0442360..0c9e8d1 100644 (file)
@@ -15,5 +15,6 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_SUN4I_EMAC=y
 CONFIG_USB_EHCI_HCD=y
index 4c377e3..400a165 100644 (file)
@@ -16,6 +16,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_SUN7I_GMAC=y
 CONFIG_USB_EHCI_HCD=y
index b8c1ea4..ed3e678 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index 19c35ef..56f405c 100644 (file)
@@ -21,6 +21,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index 8658ef6..2a2f26d 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_SPL_I2C_SUPPORT=y
 # CONFIG_SPL_DOS_PARTITION is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_SCSI=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_RGMII=y
 CONFIG_SUN7I_GMAC=y
index d2f9f24..14b74c4 100644 (file)
@@ -46,6 +46,7 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
 CONFIG_CPU=y
 CONFIG_MMC=y
 CONFIG_MMC_PCI=y
index 77dd227..94d7e76 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_CMD_USB=y
 CONFIG_CMD_DFU=y
 CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
index febbeb5..557919c 100644 (file)
@@ -57,6 +57,9 @@ CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_SPL_SYSCON=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_BLK=y
 CONFIG_CPU=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_INTEL=y
index e2f5782..3105fed 100644 (file)
@@ -40,6 +40,9 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_BLK=y
 CONFIG_CPU=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_INTEL=y
index 3e12bea..ab2d27e 100644 (file)
@@ -40,6 +40,7 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
 CONFIG_CPU=y
 CONFIG_INTEL_BROADWELL_GPIO=y
 CONFIG_CROS_EC=y
index 0d65a90..30d4019 100644 (file)
@@ -36,6 +36,9 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_BLK=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_LPC=y
 CONFIG_SPI_FLASH=y
index dc587a6..a548d8f 100644 (file)
@@ -35,6 +35,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_FPGA is not set
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_PING=y
index ec26f99..6d18eac 100644 (file)
@@ -38,6 +38,7 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
+CONFIG_SCSI=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
index cff3f45..d05f35d 100644 (file)
@@ -22,6 +22,7 @@ CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_BMP=y
index f155089..d2af507 100644 (file)
@@ -22,6 +22,7 @@ CONFIG_CMD_MMC=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_BMP=y
index 31ad014..a46c468 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_CMD_EXT4=y
 CONFIG_EFI_PARTITION=y
 CONFIG_OF_BOARD_FIXUP=y
 CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_SCSI=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_PCA953X=y
 CONFIG_DM_I2C=y
index f589dec..1008ef7 100644 (file)
@@ -29,6 +29,7 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_PCI=y
index 4a88f5f..ac50681 100644 (file)
@@ -35,6 +35,7 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
 CONFIG_CPU=y
 CONFIG_MMC=y
 CONFIG_MMC_PCI=y
index d6068aa..f0b0d69 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_SCSI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_MV=y
index 9e7e89e..99533b9 100644 (file)
@@ -21,6 +21,7 @@ CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_DHCP=y
index 041d048..6f19492 100644 (file)
@@ -23,5 +23,6 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
 CONFIG_EFI_PARTITION=y
 # CONFIG_PARTITION_UUIDS is not set
+CONFIG_SCSI=y
 # CONFIG_MMC is not set
 CONFIG_OF_LIBFDT=y
index 2124273..695d7d1 100644 (file)
@@ -31,6 +31,7 @@ CONFIG_OF_CONTROL=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
+CONFIG_SCSI=y
 CONFIG_DM_MMC=y
 # CONFIG_DM_MMC_OPS is not set
 CONFIG_DM_SPI_FLASH=y
index d8420ba..bc2792e 100644 (file)
@@ -21,6 +21,7 @@ CONFIG_CMD_CACHE=y
 CONFIG_OF_CONTROL=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
+CONFIG_SCSI=y
 CONFIG_FSL_CAAM=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_NETDEVICES=y
index cc4a74c..afcaf58 100644 (file)
@@ -24,6 +24,7 @@ CONFIG_CMD_GREPENV=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index 96a45aa..a64a0a3 100644 (file)
@@ -47,6 +47,7 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
 CONFIG_CPU=y
 CONFIG_MMC=y
 CONFIG_MMC_PCI=y
index 5727356..6e2f585 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_SATA=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
index a542799..32bd271 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index a19d093..baa509d 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index edf4b63..ebfa843 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index afacea7..3f8b98e 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_CMD_MMC=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
index fb2e479..cb3b0a8 100644 (file)
@@ -6,6 +6,10 @@ CONFIG_DEFAULT_DEVICE_TREE="tegra124-nyan-big"
 CONFIG_FIT=y
 CONFIG_FIT_BEST_MATCH=y
 CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_BOOTSTAGE=y
+CONFIG_SPL_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x83000000
 CONFIG_SYS_STDIO_DEREGISTER=y
 CONFIG_SYS_PROMPT="Tegra124 (Nyan-big) # "
 # CONFIG_CMD_IMI is not set
@@ -23,6 +27,7 @@ CONFIG_CMD_GPIO=y
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_BMP=y
+CONFIG_CMD_BOOTSTAGE=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
@@ -46,6 +51,10 @@ CONFIG_PMIC_AS3722=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_PWM_TEGRA=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x70006000
+CONFIG_DEBUG_UART_CLOCK=408000000
+CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_SYS_NS16550=y
 CONFIG_TEGRA114_SPI=y
 CONFIG_TPM_TIS_INFINEON=y
index f5ac38b..0af00b1 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ISO_PARTITION=y
+CONFIG_SCSI=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_MMC_OMAP_HS=y
index 6a6e774..7a1b9ef 100644 (file)
@@ -14,6 +14,8 @@ CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
 CONFIG_CONSOLE_RECORD=y
 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_SILENT_CONSOLE=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
index ea3d175..56a7e4b 100644 (file)
@@ -43,6 +43,7 @@ CONFIG_EFI_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SCSI=y
 CONFIG_CPU=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
index ac8f9c6..90a238c 100644 (file)
@@ -21,6 +21,7 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index 3bf5505..7e52bdc 100644 (file)
@@ -19,6 +19,7 @@ CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MMC=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
index b4b3283..95a14ca 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_CMD_MMC=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_SATA=y
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_DM=y
index a4b4059..578db22 100644 (file)
@@ -46,6 +46,7 @@ CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SCSI=y
 CONFIG_DM_SCSI=y
 CONFIG_SATA_CEVA=y
 CONFIG_DFU_RAM=y
index 3616065..4f1524b 100644 (file)
@@ -39,6 +39,7 @@ CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SCSI=y
 CONFIG_DM_SCSI=y
 CONFIG_SATA_CEVA=y
 CONFIG_DFU_RAM=y
index f3ba5a0..4b944cb 100644 (file)
@@ -39,6 +39,7 @@ CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SCSI=y
 CONFIG_DM_SCSI=y
 CONFIG_SATA_CEVA=y
 CONFIG_DFU_RAM=y
index 3fcd835..c0acc8a 100644 (file)
@@ -210,6 +210,16 @@ U-BOOT> gpt verify mmc 0 $partitions
 U-BOOT> if test $? = 0; then echo "GPT OK"; else echo "GPT ERR"; fi
 
 
+The GPT functionality may be tested with the 'sandbox' board by
+creating a disk image as described under 'Block Device Emulation' in
+board/sandbox/README.sandbox:
+
+=>host bind 0 ./disk.raw
+=> gpt read host 0
+[ . . . ]
+=> gpt flip host 0
+[ . . . ]
+
 Partition type GUID:
 ====================
 
index 0063bfe..3ed8c75 100644 (file)
@@ -156,6 +156,11 @@ This avoids the code overhead of converting the device tree data to
 platform data in the driver. The ofdata_to_platdata() method should
 therefore do nothing in such a driver.
 
+Where a node has multiple compatible strings, a #define is used to make them
+equivalent, e.g.:
+
+#define dtd_rockchip_rk3299_dw_mshc dtd_rockchip_rk3288_dw_mshc
+
 
 Converting of-platdata to a useful form
 ---------------------------------------
index a736386..2e03133 100644 (file)
@@ -6,6 +6,8 @@ source "drivers/core/Kconfig"
 
 source "drivers/adc/Kconfig"
 
+source "drivers/ata/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/clk/Kconfig"
@@ -70,6 +72,8 @@ source "drivers/reset/Kconfig"
 
 source "drivers/rtc/Kconfig"
 
+source "drivers/scsi/Kconfig"
+
 source "drivers/serial/Kconfig"
 
 source "drivers/sound/Kconfig"
index 058bccb..8624bd8 100644 (file)
@@ -45,7 +45,7 @@ obj-$(CONFIG_SPL_DFU_SUPPORT) += dfu/
 obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/
 obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += usb/host/
 obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/
-obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
+obj-$(CONFIG_SPL_SATA_SUPPORT) += ata/ scsi/
 obj-$(CONFIG_SPL_USB_HOST_SUPPORT) += block/
 obj-$(CONFIG_SPL_MMC_SUPPORT) += block/
 endif
@@ -66,6 +66,7 @@ endif
 ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
 
 obj-y += adc/
+obj-y += ata/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
@@ -81,6 +82,7 @@ obj-y += dfu/
 obj-$(CONFIG_X86) += pch/
 obj-y += phy/marvell/
 obj-y += rtc/
+obj-y += scsi/
 obj-y += sound/
 obj-y += spmi/
 obj-y += sysreset/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
new file mode 100644 (file)
index 0000000..6427f1b
--- /dev/null
@@ -0,0 +1,62 @@
+config AHCI
+       bool "Support SATA controllers with driver model"
+       depends on DM
+       help
+         This enables a uclass for disk controllers in U-Boot. Various driver
+         types can use this, such as AHCI/SATA. It does not provide any standard
+         operations at present. The block device interface has not been converted
+         to driver model.
+
+config SATA
+       bool "Support SATA controllers"
+       help
+         This enables support for SATA (Serial Advanced Technology
+         Attachment), a serial bus standard for connecting to hard drives and
+         other storage devices.
+
+         SATA replaces PATA (originally just ATA), which stands for Parallel AT
+         Attachment, where AT refers to an IBM AT (Advanced Technology)
+         computer released in 1984.
+
+         See also CMD_SATA which provides command-line support.
+
+config SCSI
+       bool "Support SCSI controllers"
+       help
+         This enables support for SCSI (Small Computer System Interface),
+         a parallel interface widely used with storage peripherals such as
+         hard drives and optical drives. The SCSI standards define physical
+         interfaces as well as protocols for controlling devices and
+         tranferring data.
+
+config DM_SCSI
+       bool "Support SCSI controllers with driver model"
+       depends on BLK
+       help
+         This option enables the SCSI (Small Computer System Interface) uclass
+         which supports SCSI and SATA HDDs. For every device configuration
+         (IDs/LUNs) a block device is created with RAW read/write and
+         filesystem support.
+
+menu "SATA/SCSI device support"
+
+config SATA_CEVA
+       bool "Ceva Sata controller"
+       depends on AHCI
+       depends on DM_SCSI
+       help
+         This option enables Ceva Sata controller hard IP available on Xilinx
+         ZynqMP. Support up to 2 external devices. Complient with SATA 3.1 and
+         AHCI 1.3 specifications with hot-plug detect feature.
+
+
+config DWC_AHCI
+       bool "Enable Synopsys DWC AHCI driver support"
+       select SCSI_AHCI
+       select PHY
+       depends on DM_SCSI
+       help
+         Enable this driver to support Sata devices through
+         Synopsys DWC AHCI module.
+
+endmenu
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
new file mode 100644 (file)
index 0000000..c48184c
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_DWC_AHCI) += dwc_ahci.o
+obj-$(CONFIG_AHCI) += ahci-uclass.o
+obj-$(CONFIG_SCSI_AHCI) += ahci.o
+obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
+obj-$(CONFIG_FSL_SATA) += fsl_sata.o
+obj-$(CONFIG_LIBATA) += libata.o
+obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
+obj-$(CONFIG_MX51_PATA) += mxc_ata.o
+obj-$(CONFIG_SATA) += sata.o
+obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
+obj-$(CONFIG_SATA_DWC) += sata_dwc.o
+obj-$(CONFIG_SATA_MV) += sata_mv.o
+obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
+obj-$(CONFIG_SATA_SIL) += sata_sil.o
+obj-$(CONFIG_SANDBOX) += sata_sandbox.o
similarity index 74%
rename from drivers/block/ahci.c
rename to drivers/ata/ahci.c
index 3fa14a7..6da412d 100644 (file)
@@ -6,6 +6,8 @@
  * SPDX-License-Identifier:    GPL-2.0+
  *
  * with the reference on libata and ahci drvier in kernel
+ *
+ * This driver provides a SCSI interface to SATA.
  */
 #include <common.h>
 
 #include <asm/io.h>
 #include <malloc.h>
 #include <memalign.h>
+#include <pci.h>
 #include <scsi.h>
 #include <libata.h>
 #include <linux/ctype.h>
 #include <ahci.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
 
-static int ata_io_flush(u8 port);
+static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port);
 
-struct ahci_probe_ent *probe_ent = NULL;
-u16 *ataid[AHCI_MAX_PORTS];
+#ifndef CONFIG_DM_SCSI
+struct ahci_uc_priv *probe_ent = NULL;
+#endif
 
 #define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
 
@@ -109,11 +115,11 @@ static int waiting_for_cmd_completed(void __iomem *offset,
        return (i < timeout_msec) ? 0 : -1;
 }
 
-int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port)
+int __weak ahci_link_up(struct ahci_uc_priv *uc_priv, u8 port)
 {
        u32 tmp;
        int j = 0;
-       void __iomem *port_mmio = probe_ent->port[port].port_mmio;
+       void __iomem *port_mmio = uc_priv->port[port].port_mmio;
 
        /*
         * Bring up SATA link.
@@ -166,19 +172,19 @@ int ahci_reset(void __iomem *base)
        return 0;
 }
 
-static int ahci_host_init(struct ahci_probe_ent *probe_ent)
+static int ahci_host_init(struct ahci_uc_priv *uc_priv)
 {
 #if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
 # ifdef CONFIG_DM_PCI
-       struct udevice *dev = probe_ent->dev;
+       struct udevice *dev = uc_priv->dev;
        struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
 # else
-       pci_dev_t pdev = probe_ent->dev;
+       pci_dev_t pdev = uc_priv->dev;
        unsigned short vendor;
 # endif
        u16 tmp16;
 #endif
-       void __iomem *mmio = probe_ent->mmio_base;
+       void __iomem *mmio = uc_priv->mmio_base;
        u32 tmp, cap_save, cmd;
        int i, j, ret;
        void __iomem *port_mmio;
@@ -190,7 +196,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
        cap_save &= ((1 << 28) | (1 << 17));
        cap_save |= (1 << 27);  /* Staggered Spin-up. Not needed. */
 
-       ret = ahci_reset(probe_ent->mmio_base);
+       ret = ahci_reset(uc_priv->mmio_base);
        if (ret)
                return ret;
 
@@ -217,23 +223,23 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
        }
 # endif
 #endif
-       probe_ent->cap = readl(mmio + HOST_CAP);
-       probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
-       port_map = probe_ent->port_map;
-       probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
+       uc_priv->cap = readl(mmio + HOST_CAP);
+       uc_priv->port_map = readl(mmio + HOST_PORTS_IMPL);
+       port_map = uc_priv->port_map;
+       uc_priv->n_ports = (uc_priv->cap & 0x1f) + 1;
 
        debug("cap 0x%x  port_map 0x%x  n_ports %d\n",
-             probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
+             uc_priv->cap, uc_priv->port_map, uc_priv->n_ports);
 
-       if (probe_ent->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID)
-               probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;
+       if (uc_priv->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID)
+               uc_priv->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;
 
-       for (i = 0; i < probe_ent->n_ports; i++) {
+       for (i = 0; i < uc_priv->n_ports; i++) {
                if (!(port_map & (1 << i)))
                        continue;
-               probe_ent->port[i].port_mmio = ahci_port_base(mmio, i);
-               port_mmio = (u8 *) probe_ent->port[i].port_mmio;
-               ahci_setup_port(&probe_ent->port[i], mmio, i);
+               uc_priv->port[i].port_mmio = ahci_port_base(mmio, i);
+               port_mmio = (u8 *)uc_priv->port[i].port_mmio;
+               ahci_setup_port(&uc_priv->port[i], mmio, i);
 
                /* make sure port is not active */
                tmp = readl(port_mmio + PORT_CMD);
@@ -262,7 +268,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
                writel_with_flush(cmd, port_mmio + PORT_CMD);
 
                /* Bring up SATA link. */
-               ret = ahci_link_up(probe_ent, i);
+               ret = ahci_link_up(uc_priv, i);
                if (ret) {
                        printf("SATA link %d timeout.\n", i);
                        continue;
@@ -319,7 +325,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
                tmp = readl(port_mmio + PORT_SCR_STAT);
                debug("SATA port %d status: 0x%x\n", i, tmp);
                if ((tmp & PORT_SCR_STAT_DET_MASK) == PORT_SCR_STAT_DET_PHYRDY)
-                       probe_ent->link_port_map |= (0x01 << i);
+                       uc_priv->link_port_map |= (0x01 << i);
        }
 
        tmp = readl(mmio + HOST_CTL);
@@ -344,25 +350,25 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
 }
 
 
-static void ahci_print_info(struct ahci_probe_ent *probe_ent)
+static void ahci_print_info(struct ahci_uc_priv *uc_priv)
 {
 #if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI)
 # if defined(CONFIG_DM_PCI)
-       struct udevice *dev = probe_ent->dev;
+       struct udevice *dev = uc_priv->dev;
 # else
-       pci_dev_t pdev = probe_ent->dev;
+       pci_dev_t pdev = uc_priv->dev;
 # endif
        u16 cc;
 #endif
-       void __iomem *mmio = probe_ent->mmio_base;
+       void __iomem *mmio = uc_priv->mmio_base;
        u32 vers, cap, cap2, impl, speed;
        const char *speed_s;
        const char *scc_s;
 
        vers = readl(mmio + HOST_VERSION);
-       cap = probe_ent->cap;
+       cap = uc_priv->cap;
        cap2 = readl(mmio + HOST_CAP2);
-       impl = probe_ent->port_map;
+       impl = uc_priv->port_map;
 
        speed = (cap >> 20) & 0xf;
        if (speed == 1)
@@ -427,9 +433,9 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
 
 #ifndef CONFIG_SCSI_AHCI_PLAT
 # if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
-static int ahci_init_one(struct udevice *dev)
+static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev)
 # else
-static int ahci_init_one(pci_dev_t dev)
+static int ahci_init_one(struct ahci_uc_priv *uc_priv, pci_dev_t dev)
 # endif
 {
 #if !defined(CONFIG_DM_SCSI)
@@ -437,26 +443,19 @@ static int ahci_init_one(pci_dev_t dev)
 #endif
        int rc;
 
-       probe_ent = malloc(sizeof(struct ahci_probe_ent));
-       if (!probe_ent) {
-               printf("%s: No memory for probe_ent\n", __func__);
-               return -ENOMEM;
-       }
-
-       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
-       probe_ent->dev = dev;
+       uc_priv->dev = dev;
 
-       probe_ent->host_flags = ATA_FLAG_SATA
+       uc_priv->host_flags = ATA_FLAG_SATA
                                | ATA_FLAG_NO_LEGACY
                                | ATA_FLAG_MMIO
                                | ATA_FLAG_PIO_DMA
                                | ATA_FLAG_NO_ATAPI;
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
+       uc_priv->pio_mask = 0x1f;
+       uc_priv->udma_mask = 0x7f;      /*Fixme,assume to support UDMA6 */
 
 #if !defined(CONFIG_DM_SCSI)
 #ifdef CONFIG_DM_PCI
-       probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
+       uc_priv->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
                                              PCI_REGION_MEM);
 
        /* Take from kernel:
@@ -467,7 +466,7 @@ static int ahci_init_one(pci_dev_t dev)
        if (vendor == 0x197b)
                dm_pci_write_config8(dev, 0x41, 0xa1);
 #else
-       probe_ent->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5,
+       uc_priv->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5,
                                           PCI_REGION_MEM);
 
        /* Take from kernel:
@@ -479,17 +478,17 @@ static int ahci_init_one(pci_dev_t dev)
                pci_write_config_byte(dev, 0x41, 0xa1);
 #endif
 #else
-       struct scsi_platdata *plat = dev_get_platdata(dev);
-       probe_ent->mmio_base = (void *)plat->base;
+       struct scsi_platdata *plat = dev_get_uclass_platdata(dev);
+       uc_priv->mmio_base = (void *)plat->base;
 #endif
 
-       debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
+       debug("ahci mmio_base=0x%p\n", uc_priv->mmio_base);
        /* initialize adapter */
-       rc = ahci_host_init(probe_ent);
+       rc = ahci_host_init(uc_priv);
        if (rc)
                goto err_out;
 
-       ahci_print_info(probe_ent);
+       ahci_print_info(uc_priv);
 
        return 0;
 
@@ -500,9 +499,10 @@ static int ahci_init_one(pci_dev_t dev)
 
 #define MAX_DATA_BYTE_COUNT  (4*1024*1024)
 
-static int ahci_fill_sg(u8 port, unsigned char *buf, int buf_len)
+static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port,
+                       unsigned char *buf, int buf_len)
 {
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct ahci_ioports *pp = &(uc_priv->port[port]);
        struct ahci_sg *ahci_sg = pp->cmd_tbl_sg;
        u32 sg_count;
        int i;
@@ -555,9 +555,9 @@ static int wait_spinup(void __iomem *port_mmio)
        return -ETIMEDOUT;
 }
 
-static int ahci_port_start(u8 port)
+static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port)
 {
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct ahci_ioports *pp = &(uc_priv->port[port]);
        void __iomem *port_mmio = pp->port_mmio;
        u32 port_status;
        void __iomem *mem;
@@ -630,11 +630,11 @@ static int ahci_port_start(u8 port)
 }
 
 
-static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
-                               int buf_len, u8 is_write)
+static int ahci_device_data_io(struct ahci_uc_priv *uc_priv, u8 port, u8 *fis,
+                              int fis_len, u8 *buf, int buf_len, u8 is_write)
 {
 
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct ahci_ioports *pp = &(uc_priv->port[port]);
        void __iomem *port_mmio = pp->port_mmio;
        u32 opts;
        u32 port_status;
@@ -642,7 +642,7 @@ static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
 
        debug("Enter %s: for port %d\n", __func__, port);
 
-       if (port > probe_ent->n_ports) {
+       if (port > uc_priv->n_ports) {
                printf("Invalid port number %d\n", port);
                return -1;
        }
@@ -655,7 +655,7 @@ static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
 
        memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
 
-       sg_count = ahci_fill_sg(port, buf, buf_len);
+       sg_count = ahci_fill_sg(uc_priv, port, buf, buf_len);
        opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6);
        ahci_fill_cmd_slot(pp, opts);
 
@@ -689,7 +689,8 @@ static char *ata_id_strcpy(u16 *target, u16 *src, int len)
 /*
  * SCSI INQUIRY command operation.
  */
-static int ata_scsiop_inquiry(ccb *pccb)
+static int ata_scsiop_inquiry(struct ahci_uc_priv *uc_priv,
+                             struct scsi_cmd *pccb)
 {
        static const u8 hdr[] = {
                0,
@@ -720,21 +721,21 @@ static int ata_scsiop_inquiry(ccb *pccb)
        /* Read id from sata */
        port = pccb->target;
 
-       if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), (u8 *)tmpid,
-                               ATA_ID_WORDS * 2, 0)) {
+       if (ahci_device_data_io(uc_priv, port, (u8 *)&fis, sizeof(fis),
+                               (u8 *)tmpid, ATA_ID_WORDS * 2, 0)) {
                debug("scsi_ahci: SCSI inquiry command failure.\n");
                return -EIO;
        }
 
-       if (!ataid[port]) {
-               ataid[port] = malloc(ATA_ID_WORDS * 2);
-               if (!ataid[port]) {
+       if (!uc_priv->ataid[port]) {
+               uc_priv->ataid[port] = malloc(ATA_ID_WORDS * 2);
+               if (!uc_priv->ataid[port]) {
                        printf("%s: No memory for ataid[port]\n", __func__);
                        return -ENOMEM;
                }
        }
 
-       idbuf = ataid[port];
+       idbuf = uc_priv->ataid[port];
 
        memcpy(idbuf, tmpid, ATA_ID_WORDS * 2);
        ata_swap_buf_le16(idbuf, ATA_ID_WORDS);
@@ -753,7 +754,8 @@ static int ata_scsiop_inquiry(ccb *pccb)
 /*
  * SCSI READ10/WRITE10 command operation.
  */
-static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
+static int ata_scsiop_read_write(struct ahci_uc_priv *uc_priv,
+                                struct scsi_cmd *pccb, u8 is_write)
 {
        lbaint_t lba = 0;
        u16 blocks = 0;
@@ -833,8 +835,8 @@ static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
                fis[13] = (now_blocks >> 8) & 0xff;
 
                /* Read/Write from ahci */
-               if (ahci_device_data_io(pccb->target, (u8 *) &fis, sizeof(fis),
-                                       user_buffer, transfer_size,
+               if (ahci_device_data_io(uc_priv, pccb->target, (u8 *)&fis,
+                                       sizeof(fis), user_buffer, transfer_size,
                                        is_write)) {
                        debug("scsi_ahci: SCSI %s10 command failure.\n",
                              is_write ? "WRITE" : "READ");
@@ -848,7 +850,7 @@ static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
                 * usually, one extra flush when the rare writes do happen.
                 */
                if (is_write) {
-                       if (-EIO == ata_io_flush(pccb->target))
+                       if (-EIO == ata_io_flush(uc_priv, pccb->target))
                                return -EIO;
                }
                user_buffer += transfer_size;
@@ -864,20 +866,21 @@ static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
 /*
  * SCSI READ CAPACITY10 command operation.
  */
-static int ata_scsiop_read_capacity10(ccb *pccb)
+static int ata_scsiop_read_capacity10(struct ahci_uc_priv *uc_priv,
+                                     struct scsi_cmd *pccb)
 {
        u32 cap;
        u64 cap64;
        u32 block_size;
 
-       if (!ataid[pccb->target]) {
+       if (!uc_priv->ataid[pccb->target]) {
                printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
                       "\tNo ATA info!\n"
                       "\tPlease run SCSI command INQUIRY first!\n");
                return -EPERM;
        }
 
-       cap64 = ata_id_n_sectors(ataid[pccb->target]);
+       cap64 = ata_id_n_sectors(uc_priv->ataid[pccb->target]);
        if (cap64 > 0x100000000ULL)
                cap64 = 0xffffffff;
 
@@ -894,19 +897,20 @@ static int ata_scsiop_read_capacity10(ccb *pccb)
 /*
  * SCSI READ CAPACITY16 command operation.
  */
-static int ata_scsiop_read_capacity16(ccb *pccb)
+static int ata_scsiop_read_capacity16(struct ahci_uc_priv *uc_priv,
+                                     struct scsi_cmd *pccb)
 {
        u64 cap;
        u64 block_size;
 
-       if (!ataid[pccb->target]) {
+       if (!uc_priv->ataid[pccb->target]) {
                printf("scsi_ahci: SCSI READ CAPACITY16 command failure. "
                       "\tNo ATA info!\n"
                       "\tPlease run SCSI command INQUIRY first!\n");
                return -EPERM;
        }
 
-       cap = ata_id_n_sectors(ataid[pccb->target]);
+       cap = ata_id_n_sectors(uc_priv->ataid[pccb->target]);
        cap = cpu_to_be64(cap);
        memcpy(pccb->pdata, &cap, sizeof(cap));
 
@@ -920,59 +924,87 @@ static int ata_scsiop_read_capacity16(ccb *pccb)
 /*
  * SCSI TEST UNIT READY command operation.
  */
-static int ata_scsiop_test_unit_ready(ccb *pccb)
+static int ata_scsiop_test_unit_ready(struct ahci_uc_priv *uc_priv,
+                                     struct scsi_cmd *pccb)
 {
-       return (ataid[pccb->target]) ? 0 : -EPERM;
+       return (uc_priv->ataid[pccb->target]) ? 0 : -EPERM;
 }
 
 
-int scsi_exec(ccb *pccb)
+static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
 {
+       struct ahci_uc_priv *uc_priv;
+#ifdef CONFIG_DM_SCSI
+       uc_priv = dev_get_uclass_priv(dev);
+#else
+       uc_priv = probe_ent;
+#endif
        int ret;
 
        switch (pccb->cmd[0]) {
        case SCSI_READ16:
        case SCSI_READ10:
-               ret = ata_scsiop_read_write(pccb, 0);
+               ret = ata_scsiop_read_write(uc_priv, pccb, 0);
                break;
        case SCSI_WRITE10:
-               ret = ata_scsiop_read_write(pccb, 1);
+               ret = ata_scsiop_read_write(uc_priv, pccb, 1);
                break;
        case SCSI_RD_CAPAC10:
-               ret = ata_scsiop_read_capacity10(pccb);
+               ret = ata_scsiop_read_capacity10(uc_priv, pccb);
                break;
        case SCSI_RD_CAPAC16:
-               ret = ata_scsiop_read_capacity16(pccb);
+               ret = ata_scsiop_read_capacity16(uc_priv, pccb);
                break;
        case SCSI_TST_U_RDY:
-               ret = ata_scsiop_test_unit_ready(pccb);
+               ret = ata_scsiop_test_unit_ready(uc_priv, pccb);
                break;
        case SCSI_INQUIRY:
-               ret = ata_scsiop_inquiry(pccb);
+               ret = ata_scsiop_inquiry(uc_priv, pccb);
                break;
        default:
                printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
-               return false;
+               return -ENOTSUPP;
        }
 
        if (ret) {
                debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
-               return false;
+               return ret;
        }
-       return true;
+       return 0;
 
 }
 
-#if defined(CONFIG_DM_SCSI)
-void scsi_low_level_init(int busdevfunc, struct udevice *dev)
-#else
-void scsi_low_level_init(int busdevfunc)
-#endif
+static int ahci_start_ports(struct ahci_uc_priv *uc_priv)
 {
-       int i;
        u32 linkmap;
+       int i;
+
+       linkmap = uc_priv->link_port_map;
+
+       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
+               if (((linkmap >> i) & 0x01)) {
+                       if (ahci_port_start(uc_priv, (u8) i)) {
+                               printf("Can not start port %d\n", i);
+                               continue;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+#ifndef CONFIG_DM_SCSI
+void scsi_low_level_init(int busdevfunc)
+{
+       struct ahci_uc_priv *uc_priv;
 
 #ifndef CONFIG_SCSI_AHCI_PLAT
+       probe_ent = calloc(1, sizeof(struct ahci_uc_priv));
+       if (!probe_ent) {
+               printf("%s: No memory for uc_priv\n", __func__);
+               return;
+       }
+       uc_priv = probe_ent;
 # if defined(CONFIG_DM_PCI)
        struct udevice *dev;
        int ret;
@@ -980,76 +1012,94 @@ void scsi_low_level_init(int busdevfunc)
        ret = dm_pci_bus_find_bdf(busdevfunc, &dev);
        if (ret)
                return;
-       ahci_init_one(dev);
-# elif defined(CONFIG_DM_SCSI)
-       ahci_init_one(dev);
+       ahci_init_one(uc_priv, dev);
 # else
-       ahci_init_one(busdevfunc);
+       ahci_init_one(uc_priv, busdevfunc);
 # endif
+#else
+       uc_priv = probe_ent;
 #endif
 
-       linkmap = probe_ent->link_port_map;
+       ahci_start_ports(uc_priv);
+}
+#endif
 
-       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
-               if (((linkmap >> i) & 0x01)) {
-                       if (ahci_port_start((u8) i)) {
-                               printf("Can not start port %d\n", i);
-                               continue;
-                       }
-               }
-       }
+#ifndef CONFIG_SCSI_AHCI_PLAT
+# if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
+int achi_init_one_dm(struct udevice *dev)
+{
+       struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);
+
+       return ahci_init_one(uc_priv, dev);
 }
+#endif
+#endif
 
-#ifdef CONFIG_SCSI_AHCI_PLAT
-int ahci_init(void __iomem *base)
+int achi_start_ports_dm(struct udevice *dev)
 {
-       int i, rc = 0;
-       u32 linkmap;
+       struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);
 
-       probe_ent = malloc(sizeof(struct ahci_probe_ent));
-       if (!probe_ent) {
-               printf("%s: No memory for probe_ent\n", __func__);
-               return -ENOMEM;
-       }
+       return ahci_start_ports(uc_priv);
+}
 
-       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
+#ifdef CONFIG_SCSI_AHCI_PLAT
+static int ahci_init_common(struct ahci_uc_priv *uc_priv, void __iomem *base)
+{
+       int rc;
 
-       probe_ent->host_flags = ATA_FLAG_SATA
+       uc_priv->host_flags = ATA_FLAG_SATA
                                | ATA_FLAG_NO_LEGACY
                                | ATA_FLAG_MMIO
                                | ATA_FLAG_PIO_DMA
                                | ATA_FLAG_NO_ATAPI;
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->udma_mask = 0x7f;    /*Fixme,assume to support UDMA6 */
+       uc_priv->pio_mask = 0x1f;
+       uc_priv->udma_mask = 0x7f;      /*Fixme,assume to support UDMA6 */
 
-       probe_ent->mmio_base = base;
+       uc_priv->mmio_base = base;
 
        /* initialize adapter */
-       rc = ahci_host_init(probe_ent);
+       rc = ahci_host_init(uc_priv);
        if (rc)
                goto err_out;
 
-       ahci_print_info(probe_ent);
+       ahci_print_info(uc_priv);
 
-       linkmap = probe_ent->link_port_map;
+       rc = ahci_start_ports(uc_priv);
 
-       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
-               if (((linkmap >> i) & 0x01)) {
-                       if (ahci_port_start((u8) i)) {
-                               printf("Can not start port %d\n", i);
-                               continue;
-                       }
-               }
-       }
 err_out:
        return rc;
 }
 
+#ifndef CONFIG_DM_SCSI
+int ahci_init(void __iomem *base)
+{
+       struct ahci_uc_priv *uc_priv;
+
+       probe_ent = malloc(sizeof(struct ahci_uc_priv));
+       if (!probe_ent) {
+               printf("%s: No memory for uc_priv\n", __func__);
+               return -ENOMEM;
+       }
+
+       uc_priv = probe_ent;
+       memset(uc_priv, 0, sizeof(struct ahci_uc_priv));
+
+       return ahci_init_common(uc_priv, base);
+}
+#endif
+
+int ahci_init_dm(struct udevice *dev, void __iomem *base)
+{
+       struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev);
+
+       return ahci_init_common(uc_priv, base);
+}
+
 void __weak scsi_init(void)
 {
 }
 
-#endif
+#endif /* CONFIG_SCSI_AHCI_PLAT */
 
 /*
  * In the general case of generic rotating media it makes sense to have a
@@ -1060,10 +1110,10 @@ void __weak scsi_init(void)
  * is the last write is difficult. Because writing to the disk in u-boot is
  * very rare, this flush command will be invoked after every block write.
  */
-static int ata_io_flush(u8 port)
+static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port)
 {
        u8 fis[20];
-       struct ahci_ioports *pp = &(probe_ent->port[port]);
+       struct ahci_ioports *pp = &(uc_priv->port[port]);
        void __iomem *port_mmio = pp->port_mmio;
        u32 cmd_fis_len = 5;    /* five dwords */
 
@@ -1087,13 +1137,82 @@ static int ata_io_flush(u8 port)
        return 0;
 }
 
+static int ahci_scsi_bus_reset(struct udevice *dev)
+{
+       /* Not implemented */
+
+       return 0;
+}
+
+#ifdef CONFIG_DM_SCSI
+int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = device_bind_driver(ahci_dev, "ahci_scsi", "ahci_scsi", &dev);
+       if (ret)
+               return ret;
+       *devp = dev;
+
+       return 0;
+}
+
+int ahci_probe_scsi(struct udevice *ahci_dev)
+{
+#ifdef CONFIG_SCSI_AHCI_PLAT
+       return -ENOSYS;  /* TODO(sjg@chromium.org): Support non-PCI AHCI */
+#else
+       struct ahci_uc_priv *uc_priv;
+       struct scsi_platdata *uc_plat;
+       struct udevice *dev;
+       int ret;
+
+       device_find_first_child(ahci_dev, &dev);
+       if (!dev)
+               return -ENODEV;
+       uc_plat = dev_get_uclass_platdata(dev);
+       uc_plat->base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5,
+                                             PCI_REGION_MEM);
+       uc_plat->max_lun = 1;
+       uc_plat->max_id = 2;
+       uc_priv = dev_get_uclass_priv(dev);
+       ret = ahci_init_one(uc_priv, dev);
+       if (ret)
+               return ret;
+       ret = ahci_start_ports(uc_priv);
+       if (ret)
+               return ret;
+
+       debug("Scanning %s\n", dev->name);
+       ret = scsi_scan_dev(dev, true);
+       if (ret)
+               return ret;
+#endif
+
+       return 0;
+}
+
+struct scsi_ops scsi_ops = {
+       .exec           = ahci_scsi_exec,
+       .bus_reset      = ahci_scsi_bus_reset,
+};
 
-__weak void scsi_bus_reset(void)
+U_BOOT_DRIVER(ahci_scsi) = {
+       .name           = "ahci_scsi",
+       .id             = UCLASS_SCSI,
+       .ops            = &scsi_ops,
+};
+#else
+int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
 {
-       /*Not implement*/
+       return ahci_scsi_exec(dev, pccb);
 }
 
-void scsi_print_error(ccb * pccb)
+__weak int scsi_bus_reset(struct udevice *dev)
 {
-       /*The ahci error info can be read in the ahci driver*/
+       return ahci_scsi_bus_reset(dev);
+
+       return 0;
 }
+#endif
similarity index 92%
rename from drivers/block/dwc_ahci.c
rename to drivers/ata/dwc_ahci.c
index 3f839bf..f614798 100644 (file)
@@ -28,7 +28,7 @@ struct dwc_ahci_priv {
 static int dwc_ahci_ofdata_to_platdata(struct udevice *dev)
 {
        struct dwc_ahci_priv *priv = dev_get_priv(dev);
-       struct scsi_platdata *plat = dev_get_platdata(dev);
+       struct scsi_platdata *plat = dev_get_uclass_platdata(dev);
        fdt_addr_t addr;
 
        plat->max_id = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
@@ -81,7 +81,11 @@ static int dwc_ahci_probe(struct udevice *dev)
                writel(val, priv->wrapper_base + TI_SATA_SYSCONFIG);
        }
 
-       return ahci_init(priv->base);
+       ret = ahci_init_dm(dev, priv->base);
+       if (ret)
+               return ret;
+
+       return achi_start_ports_dm(dev);
 }
 
 static const struct udevice_id dwc_ahci_ids[] = {
@@ -94,8 +98,8 @@ U_BOOT_DRIVER(dwc_ahci) = {
        .id     = UCLASS_SCSI,
        .of_match = dwc_ahci_ids,
        .ofdata_to_platdata = dwc_ahci_ofdata_to_platdata,
+       .ops    = &scsi_ops,
        .probe  = dwc_ahci_probe,
        .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv),
-       .platdata_auto_alloc_size = sizeof(struct scsi_platdata),
        .flags = DM_FLAG_ALLOC_PRIV_DMA,
 };
similarity index 92%
rename from drivers/block/dwc_ahsata.c
rename to drivers/ata/dwc_ahsata.c
index c306e92..78572a5 100644 (file)
@@ -100,7 +100,7 @@ static int waiting_for_cmd_completed(u8 *offset,
        return (i < timeout_msec) ? 0 : -1;
 }
 
-static int ahci_setup_oobr(struct ahci_probe_ent *probe_ent,
+static int ahci_setup_oobr(struct ahci_uc_priv *probe_ent,
                                                int clk)
 {
        struct sata_host_regs *host_mmio =
@@ -112,7 +112,7 @@ static int ahci_setup_oobr(struct ahci_probe_ent *probe_ent,
        return 0;
 }
 
-static int ahci_host_init(struct ahci_probe_ent *probe_ent)
+static int ahci_host_init(struct ahci_uc_priv *probe_ent)
 {
        u32 tmp, cap_save, num_ports;
        int i, j, timeout = 1000;
@@ -275,7 +275,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
        return 0;
 }
 
-static void ahci_print_info(struct ahci_probe_ent *probe_ent)
+static void ahci_print_info(struct ahci_uc_priv *probe_ent)
 {
        struct sata_host_regs *host_mmio =
                (struct sata_host_regs *)probe_ent->mmio_base;
@@ -331,10 +331,10 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
 static int ahci_init_one(int pdev)
 {
        int rc;
-       struct ahci_probe_ent *probe_ent = NULL;
+       struct ahci_uc_priv *probe_ent = NULL;
 
-       probe_ent = malloc(sizeof(struct ahci_probe_ent));
-       memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
+       probe_ent = malloc(sizeof(struct ahci_uc_priv));
+       memset(probe_ent, 0, sizeof(struct ahci_uc_priv));
        probe_ent->dev = pdev;
 
        probe_ent->host_flags = ATA_FLAG_SATA
@@ -361,7 +361,7 @@ err_out:
        return rc;
 }
 
-static int ahci_fill_sg(struct ahci_probe_ent *probe_ent,
+static int ahci_fill_sg(struct ahci_uc_priv *probe_ent,
                        u8 port, unsigned char *buf, int buf_len)
 {
        struct ahci_ioports *pp = &(probe_ent->port[port]);
@@ -408,7 +408,7 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts)
 
 #define AHCI_GET_CMD_SLOT(c) ((c) ? ffs(c) : 0)
 
-static int ahci_exec_ata_cmd(struct ahci_probe_ent *probe_ent,
+static int ahci_exec_ata_cmd(struct ahci_uc_priv *probe_ent,
                u8 port, struct sata_fis_h2d *cfis,
                u8 *buf, u32 buf_len, s32 is_write)
 {
@@ -461,8 +461,8 @@ static int ahci_exec_ata_cmd(struct ahci_probe_ent *probe_ent,
 
 static void ahci_set_feature(u8 dev, u8 port)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
        struct sata_fis_h2d *cfis = &h2d;
 
@@ -476,7 +476,7 @@ static void ahci_set_feature(u8 dev, u8 port)
        ahci_exec_ata_cmd(probe_ent, port, cfis, NULL, 0, READ_CMD);
 }
 
-static int ahci_port_start(struct ahci_probe_ent *probe_ent,
+static int ahci_port_start(struct ahci_uc_priv *probe_ent,
                                        u8 port)
 {
        struct ahci_ioports *pp = &(probe_ent->port[port]);
@@ -560,7 +560,7 @@ int init_sata(int dev)
 {
        int i;
        u32 linkmap;
-       struct ahci_probe_ent *probe_ent = NULL;
+       struct ahci_uc_priv *probe_ent = NULL;
 
 #if defined(CONFIG_MX6)
        if (!is_mx6dq() && !is_mx6dqp())
@@ -573,7 +573,7 @@ int init_sata(int dev)
 
        ahci_init_one(dev);
 
-       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        linkmap = probe_ent->link_port_map;
 
        if (0 == linkmap) {
@@ -597,7 +597,7 @@ int init_sata(int dev)
 
 int reset_sata(int dev)
 {
-       struct ahci_probe_ent *probe_ent;
+       struct ahci_uc_priv *probe_ent;
        struct sata_host_regs *host_mmio;
 
        if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
@@ -605,7 +605,7 @@ int reset_sata(int dev)
                return -1;
        }
 
-       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        if (NULL == probe_ent)
                /* not initialized, so nothing to reset */
                return 0;
@@ -636,8 +636,8 @@ static void dwc_ahsata_print_info(int dev)
 
 static void dwc_ahsata_identify(int dev, u16 *id)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
        struct sata_fis_h2d *cfis = &h2d;
        u8 port = probe_ent->hard_port_no;
@@ -655,8 +655,8 @@ static void dwc_ahsata_identify(int dev, u16 *id)
 
 static void dwc_ahsata_xfer_mode(int dev, u16 *id)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
 
        probe_ent->pio_mask = id[ATA_ID_PIO_MODES];
        probe_ent->udma_mask = id[ATA_ID_UDMA_MODES];
@@ -667,8 +667,8 @@ static void dwc_ahsata_xfer_mode(int dev, u16 *id)
 static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt,
                                u8 *buffer, int is_write)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
        struct sata_fis_h2d *cfis = &h2d;
        u8 port = probe_ent->hard_port_no;
@@ -698,8 +698,8 @@ static u32 dwc_ahsata_rw_cmd(int dev, u32 start, u32 blkcnt,
 
 void dwc_ahsata_flush_cache(int dev)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
        struct sata_fis_h2d *cfis = &h2d;
        u8 port = probe_ent->hard_port_no;
@@ -716,8 +716,8 @@ void dwc_ahsata_flush_cache(int dev)
 static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt,
                                u8 *buffer, int is_write)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
        struct sata_fis_h2d *cfis = &h2d;
        u8 port = probe_ent->hard_port_no;
@@ -753,8 +753,8 @@ static u32 dwc_ahsata_rw_cmd_ext(int dev, u32 start, lbaint_t blkcnt,
 u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt,
                                u8 *buffer, int is_write)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
        struct sata_fis_h2d *cfis = &h2d;
        u8 port = probe_ent->hard_port_no;
@@ -795,8 +795,8 @@ u32 dwc_ahsata_rw_ncq_cmd(int dev, u32 start, lbaint_t blkcnt,
 
 void dwc_ahsata_flush_cache_ext(int dev)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        struct sata_fis_h2d h2d __aligned(ARCH_DMA_MINALIGN);
        struct sata_fis_h2d *cfis = &h2d;
        u8 port = probe_ent->hard_port_no;
@@ -812,8 +812,8 @@ void dwc_ahsata_flush_cache_ext(int dev)
 
 static void dwc_ahsata_init_wcache(int dev, u16 *id)
 {
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
 
        if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
                probe_ent->flags |= SATA_FLAG_WCACHE;
@@ -893,7 +893,7 @@ u32 ata_low_level_rw_lba28(int dev, u32 blknr, lbaint_t blkcnt,
 int sata_port_status(int dev, int port)
 {
        struct sata_port_regs *port_mmio;
-       struct ahci_probe_ent *probe_ent = NULL;
+       struct ahci_uc_priv *probe_ent = NULL;
 
        if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1))
                return -EINVAL;
@@ -901,7 +901,7 @@ int sata_port_status(int dev, int port)
        if (sata_dev_desc[dev].priv == NULL)
                return -ENODEV;
 
-       probe_ent = (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       probe_ent = (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        port_mmio = (struct sata_port_regs *)probe_ent->port[port].port_mmio;
 
        return readl(&(port_mmio->ssts)) & SATA_PORT_SSTS_DET_MASK;
@@ -926,8 +926,8 @@ ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
 ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
 {
        u32 rc;
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        u32 flags = probe_ent->flags;
 
        if (sata_dev_desc[dev].lba48) {
@@ -953,8 +953,8 @@ int scan_sata(int dev)
        u8 product[ATA_ID_PROD_LEN + 1] = { 0 };
        u16 *id;
        u64 n_sectors;
-       struct ahci_probe_ent *probe_ent =
-               (struct ahci_probe_ent *)sata_dev_desc[dev].priv;
+       struct ahci_uc_priv *probe_ent =
+               (struct ahci_uc_priv *)sata_dev_desc[dev].priv;
        u8 port = probe_ent->hard_port_no;
        struct blk_desc *pdev = &(sata_dev_desc[dev]);
 
similarity index 100%
rename from drivers/block/libata.c
rename to drivers/ata/libata.c
similarity index 100%
rename from common/sata.c
rename to drivers/ata/sata.c
similarity index 95%
rename from drivers/block/sata_ceva.c
rename to drivers/ata/sata_ceva.c
index 0c24fce..d582e5b 100644 (file)
@@ -113,10 +113,11 @@ static int ceva_init_sata(ulong mmio)
 
 static int sata_ceva_probe(struct udevice *dev)
 {
-       struct scsi_platdata *plat = dev_get_platdata(dev);
+       struct scsi_platdata *plat = dev_get_uclass_platdata(dev);
 
        ceva_init_sata(plat->base);
-       return 0;
+
+       return achi_init_one_dm(dev);
 }
 
 static const struct udevice_id sata_ceva_ids[] = {
@@ -126,7 +127,7 @@ static const struct udevice_id sata_ceva_ids[] = {
 
 static int sata_ceva_ofdata_to_platdata(struct udevice *dev)
 {
-       struct scsi_platdata *plat = dev_get_platdata(dev);
+       struct scsi_platdata *plat = dev_get_uclass_platdata(dev);
 
        plat->base = devfdt_get_addr(dev);
        if (plat->base == FDT_ADDR_T_NONE)
@@ -143,7 +144,7 @@ U_BOOT_DRIVER(ceva_host_blk) = {
        .name = "ceva_sata",
        .id = UCLASS_SCSI,
        .of_match = sata_ceva_ids,
+       .ops = &scsi_ops,
        .probe = sata_ceva_probe,
        .ofdata_to_platdata = sata_ceva_ofdata_to_platdata,
-       .platdata_auto_alloc_size = sizeof(struct scsi_platdata),
 };
index 931defd..ca7692d 100644 (file)
@@ -10,24 +10,6 @@ config BLK
          be partitioned into several areas, called 'partitions' in U-Boot.
          A filesystem can be placed in each partition.
 
-config AHCI
-       bool "Support SATA controllers with driver model"
-       depends on DM
-       help
-         This enables a uclass for disk controllers in U-Boot. Various driver
-         types can use this, such as AHCI/SATA. It does not provide any standard
-         operations at present. The block device interface has not been converted
-         to driver model.
-
-config DM_SCSI
-       bool "Support SCSI controllers with driver model"
-       depends on BLK
-       help
-         This option enables the SCSI (Small Computer System Interface) uclass
-         which supports SCSI and SATA HDDs. For every device configuration
-         (IDs/LUNs) a block device is created with RAW read/write and
-         filesystem support.
-
 config BLOCK_CACHE
        bool "Use block device cache"
        default n
@@ -37,29 +19,6 @@ config BLOCK_CACHE
          it will prevent repeated reads from directory structures and other
          filesystem data structures.
 
-menu "SATA/SCSI device support"
-
-config SATA_CEVA
-       bool "Ceva Sata controller"
-       depends on AHCI
-       depends on DM_SCSI
-       help
-         This option enables Ceva Sata controller hard IP available on Xilinx
-         ZynqMP. Support up to 2 external devices. Complient with SATA 3.1 and
-         AHCI 1.3 specifications with hot-plug detect feature.
-
-
-config DWC_AHCI
-       bool "Enable Synopsys DWC AHCI driver support"
-       select SCSI_AHCI
-       select PHY
-       depends on DM_SCSI
-       help
-         Enable this driver to support Sata devices through
-         Synopsys DWC AHCI module.
-
-endmenu
-
 config IDE
        bool "Support IDE controllers"
        help
index adea6c6..a5e7307 100644 (file)
@@ -11,23 +11,8 @@ ifndef CONFIG_BLK
 obj-y += blk_legacy.o
 endif
 
-obj-$(CONFIG_DWC_AHCI) += dwc_ahci.o
-obj-$(CONFIG_AHCI) += ahci-uclass.o
-obj-$(CONFIG_DM_SCSI) += scsi-uclass.o
-obj-$(CONFIG_SCSI_AHCI) += ahci.o
-obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
-obj-$(CONFIG_FSL_SATA) += fsl_sata.o
 obj-$(CONFIG_IDE) += ide.o
 obj-$(CONFIG_IDE_FTIDE020) += ftide020.o
-obj-$(CONFIG_LIBATA) += libata.o
-obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
-obj-$(CONFIG_MX51_PATA) += mxc_ata.o
-obj-$(CONFIG_SATA_CEVA) += sata_ceva.o
-obj-$(CONFIG_SATA_DWC) += sata_dwc.o
-obj-$(CONFIG_SATA_MV) += sata_mv.o
-obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
-obj-$(CONFIG_SATA_SIL) += sata_sil.o
-obj-$(CONFIG_SANDBOX) += sandbox.o sandbox_scsi.o sata_sandbox.o
-obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
+obj-$(CONFIG_SANDBOX) += sandbox.o
 obj-$(CONFIG_SYSTEMACE) += systemace.o
 obj-$(CONFIG_BLOCK_CACHE) += blkcache.o
diff --git a/drivers/block/scsi-uclass.c b/drivers/block/scsi-uclass.c
deleted file mode 100644 (file)
index 05da6cd..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- * Copyright (c) 2016 Xilinx, Inc
- * Written by Michal Simek
- *
- * Based on ahci-uclass.c
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <scsi.h>
-
-static int scsi_post_probe(struct udevice *dev)
-{
-       debug("%s: device %p\n", __func__, dev);
-       scsi_low_level_init(0, dev);
-       return 0;
-}
-
-UCLASS_DRIVER(scsi) = {
-       .id             = UCLASS_SCSI,
-       .name           = "scsi",
-       .post_probe      = scsi_post_probe,
-};
diff --git a/drivers/block/sym53c8xx.c b/drivers/block/sym53c8xx.c
deleted file mode 100644 (file)
index 50043e6..0000000
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * (C) Copyright 2001
- * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- * partly derived from
- * linux/drivers/scsi/sym53c8xx.c
- *
- */
-
-/*
- * SCSI support based on the chip sym53C810.
- *
- * 09-19-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
- *             The local version of this driver for the BAB750 board does not
- *             use interrupts but polls the chip instead (see the call of
- *             'handle_scsi_int()' in 'scsi_issue()'.
- */
-
-#include <common.h>
-
-#include <command.h>
-#include <pci.h>
-#include <asm/processor.h>
-#include <sym53c8xx.h>
-#include <scsi.h>
-
-#undef SYM53C8XX_DEBUG
-
-#ifdef SYM53C8XX_DEBUG
-#define        PRINTF(fmt,args...)     printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-#if defined(CONFIG_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
-
-#undef SCSI_SINGLE_STEP
-/*
- * Single Step is only used for debug purposes
- */
-#ifdef SCSI_SINGLE_STEP
-static unsigned long start_script_select;
-static unsigned long start_script_msgout;
-static unsigned long start_script_msgin;
-static unsigned long start_script_msg_ext;
-static unsigned long start_script_cmd;
-static unsigned long start_script_data_in;
-static unsigned long start_script_data_out;
-static unsigned long start_script_status;
-static unsigned long start_script_complete;
-static unsigned long start_script_error;
-static unsigned long start_script_reselection;
-static unsigned int len_script_select;
-static unsigned int len_script_msgout;
-static unsigned int len_script_msgin;
-static unsigned int len_script_msg_ext;
-static unsigned int len_script_cmd;
-static unsigned int len_script_data_in;
-static unsigned int len_script_data_out;
-static unsigned int len_script_status;
-static unsigned int len_script_complete;
-static unsigned int len_script_error;
-static unsigned int len_script_reselection;
-#endif
-
-
-static unsigned short scsi_int_mask;   /* shadow register for SCSI related interrupts */
-static unsigned char  script_int_mask; /* shadow register for SCRIPT related interrupts */
-static unsigned long script_select[8]; /* script for selection */
-static unsigned long script_msgout[8]; /* script for message out phase (NOT USED) */
-static unsigned long script_msgin[14]; /* script for message in phase */
-static unsigned long script_msg_ext[32]; /* script for message in phase when more than 1 byte message */
-static unsigned long script_cmd[18];    /* script for command phase */
-static unsigned long script_data_in[8]; /* script for data in phase */
-static unsigned long script_data_out[8]; /* script for data out phase */
-static unsigned long script_status[6]; /* script for status phase */
-static unsigned long script_complete[10]; /* script for complete */
-static unsigned long script_reselection[4]; /* script for reselection (NOT USED) */
-static unsigned long script_error[2]; /* script for error handling */
-
-static unsigned long int_stat[3]; /* interrupt status */
-static unsigned long scsi_mem_addr; /* base memory address =SCSI_MEM_ADDRESS; */
-
-#define bus_to_phys(a) pci_mem_to_phys(busdevfunc, (unsigned long) (a))
-#define phys_to_bus(a) pci_phys_to_mem(busdevfunc, (unsigned long) (a))
-
-#define SCSI_MAX_RETRY 3 /* number of retries in scsi_issue() */
-
-#define SCSI_MAX_RETRY_NOT_READY 10 /* number of retries when device is not ready */
-#define SCSI_NOT_READY_TIME_OUT 500 /* timeout per retry when not ready */
-
-/*********************************************************************************
- * forward declerations
- */
-
-void scsi_chip_init(void);
-void handle_scsi_int(void);
-
-
-/********************************************************************************
- * reports SCSI errors to the user
- */
-void scsi_print_error (ccb * pccb)
-{
-       int i;
-
-       printf ("SCSI Error: Target %d LUN %d Command %02X\n", pccb->target,
-               pccb->lun, pccb->cmd[0]);
-       printf ("       CCB: ");
-       for (i = 0; i < pccb->cmdlen; i++)
-               printf ("%02X ", pccb->cmd[i]);
-       printf ("(len=%d)\n", pccb->cmdlen);
-       printf ("     Cntrl: ");
-       switch (pccb->contr_stat) {
-       case SIR_COMPLETE:
-               printf ("Complete (no Error)\n");
-               break;
-       case SIR_SEL_ATN_NO_MSG_OUT:
-               printf ("Selected with ATN no MSG out phase\n");
-               break;
-       case SIR_CMD_OUT_ILL_PH:
-               printf ("Command out illegal phase\n");
-               break;
-       case SIR_MSG_RECEIVED:
-               printf ("MSG received Error\n");
-               break;
-       case SIR_DATA_IN_ERR:
-               printf ("Data in Error\n");
-               break;
-       case SIR_DATA_OUT_ERR:
-               printf ("Data out Error\n");
-               break;
-       case SIR_SCRIPT_ERROR:
-               printf ("Script Error\n");
-               break;
-       case SIR_MSG_OUT_NO_CMD:
-               printf ("MSG out no Command phase\n");
-               break;
-       case SIR_MSG_OVER7:
-               printf ("MSG in over 7 bytes\n");
-               break;
-       case INT_ON_FY:
-               printf ("Interrupt on fly\n");
-               break;
-       case SCSI_SEL_TIME_OUT:
-               printf ("SCSI Selection Timeout\n");
-               break;
-       case SCSI_HNS_TIME_OUT:
-               printf ("SCSI Handshake Timeout\n");
-               break;
-       case SCSI_MA_TIME_OUT:
-               printf ("SCSI Phase Error\n");
-               break;
-       case SCSI_UNEXP_DIS:
-               printf ("SCSI unexpected disconnect\n");
-               break;
-       default:
-               printf ("unknown status %lx\n", pccb->contr_stat);
-               break;
-       }
-       printf ("     Sense: SK %x (", pccb->sense_buf[2] & 0x0f);
-       switch (pccb->sense_buf[2] & 0xf) {
-       case SENSE_NO_SENSE:
-               printf ("No Sense)");
-               break;
-       case SENSE_RECOVERED_ERROR:
-               printf ("Recovered Error)");
-               break;
-       case SENSE_NOT_READY:
-               printf ("Not Ready)");
-               break;
-       case SENSE_MEDIUM_ERROR:
-               printf ("Medium Error)");
-               break;
-       case SENSE_HARDWARE_ERROR:
-               printf ("Hardware Error)");
-               break;
-       case SENSE_ILLEGAL_REQUEST:
-               printf ("Illegal request)");
-               break;
-       case SENSE_UNIT_ATTENTION:
-               printf ("Unit Attention)");
-               break;
-       case SENSE_DATA_PROTECT:
-               printf ("Data Protect)");
-               break;
-       case SENSE_BLANK_CHECK:
-               printf ("Blank check)");
-               break;
-       case SENSE_VENDOR_SPECIFIC:
-               printf ("Vendor specific)");
-               break;
-       case SENSE_COPY_ABORTED:
-               printf ("Copy aborted)");
-               break;
-       case SENSE_ABORTED_COMMAND:
-               printf ("Aborted Command)");
-               break;
-       case SENSE_VOLUME_OVERFLOW:
-               printf ("Volume overflow)");
-               break;
-       case SENSE_MISCOMPARE:
-               printf ("Misscompare\n");
-               break;
-       default:
-               printf ("Illegal Sensecode\n");
-               break;
-       }
-       printf (" ASC %x ASCQ %x\n", pccb->sense_buf[12],
-               pccb->sense_buf[13]);
-       printf ("    Status: ");
-       switch (pccb->status) {
-       case S_GOOD:
-               printf ("Good\n");
-               break;
-       case S_CHECK_COND:
-               printf ("Check condition\n");
-               break;
-       case S_COND_MET:
-               printf ("Condition Met\n");
-               break;
-       case S_BUSY:
-               printf ("Busy\n");
-               break;
-       case S_INT:
-               printf ("Intermediate\n");
-               break;
-       case S_INT_COND_MET:
-               printf ("Intermediate condition met\n");
-               break;
-       case S_CONFLICT:
-               printf ("Reservation conflict\n");
-               break;
-       case S_TERMINATED:
-               printf ("Command terminated\n");
-               break;
-       case S_QUEUE_FULL:
-               printf ("Task set full\n");
-               break;
-       default:
-               printf ("unknown: %02X\n", pccb->status);
-               break;
-       }
-
-}
-
-
-/******************************************************************************
- * sets-up the SCSI controller
- * the base memory address is retrieved via the pci_read_config_dword
- */
-void scsi_low_level_init(int busdevfunc)
-{
-       unsigned int cmd;
-       unsigned int addr;
-       unsigned char vec;
-
-       pci_read_config_byte(busdevfunc, PCI_INTERRUPT_LINE, &vec);
-       pci_read_config_dword(busdevfunc, PCI_BASE_ADDRESS_1, &addr);
-
-       addr = bus_to_phys(addr & ~0xf);
-
-       /*
-        * Enable bus mastering in case this has not been done, yet.
-        */
-       pci_read_config_dword(busdevfunc, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER;
-       pci_write_config_dword(busdevfunc, PCI_COMMAND, cmd);
-
-       scsi_mem_addr = addr;
-
-       scsi_chip_init();
-       scsi_bus_reset();
-}
-
-
-/************************************************************************************
- * Low level Part of SCSI Driver
- */
-
-/*
- * big-endian -> little endian conversion for the script
- */
-unsigned long swap_script(unsigned long val)
-{
-       return ((val >> 24) & 0xff) | ((val >> 8) & 0xff00) |
-               ((val << 8) & 0xff0000) | ((val << 24) & 0xff000000);
-}
-
-
-void scsi_write_byte(ulong offset,unsigned char val)
-{
-       out8(scsi_mem_addr+offset,val);
-}
-
-
-unsigned char scsi_read_byte(ulong offset)
-{
-       return(in8(scsi_mem_addr+offset));
-}
-
-
-/********************************************************************************
- * interrupt handler
- */
-void handle_scsi_int(void)
-{
-       unsigned char stat,stat1,stat2;
-       unsigned short sstat;
-       int i;
-#ifdef SCSI_SINGLE_STEP
-       unsigned long tt;
-#endif
-       stat=scsi_read_byte(ISTAT);
-       if((stat & DIP)==DIP) { /* DMA Interrupt pending */
-               stat1=scsi_read_byte(DSTAT);
-#ifdef SCSI_SINGLE_STEP
-               if((stat1 & SSI)==SSI) {
-                       tt=in32r(scsi_mem_addr+DSP);
-                       if(((tt)>=start_script_select) && ((tt)<start_script_select+len_script_select)) {
-                               printf("select %d\n",(tt-start_script_select)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_msgout) && ((tt)<start_script_msgout+len_script_msgout)) {
-                               printf("msgout %d\n",(tt-start_script_msgout)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_msgin) && ((tt)<start_script_msgin+len_script_msgin)) {
-                               printf("msgin %d\n",(tt-start_script_msgin)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_msg_ext) && ((tt)<start_script_msg_ext+len_script_msg_ext)) {
-                               printf("msgin_ext %d\n",(tt-start_script_msg_ext)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_cmd) && ((tt)<start_script_cmd+len_script_cmd)) {
-                               printf("cmd %d\n",(tt-start_script_cmd)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_data_in) && ((tt)<start_script_data_in+len_script_data_in)) {
-                               printf("data_in %d\n",(tt-start_script_data_in)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_data_out) && ((tt)<start_script_data_out+len_script_data_out)) {
-                               printf("data_out %d\n",(tt-start_script_data_out)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_status) && ((tt)<start_script_status+len_script_status)) {
-                               printf("status %d\n",(tt-start_script_status)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_complete) && ((tt)<start_script_complete+len_script_complete)) {
-                               printf("complete %d\n",(tt-start_script_complete)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_error) && ((tt)<start_script_error+len_script_error)) {
-                               printf("error %d\n",(tt-start_script_error)>>2);
-                               goto end_single;
-                       }
-                       if(((tt)>=start_script_reselection) && ((tt)<start_script_reselection+len_script_reselection)) {
-                               printf("reselection %d\n",(tt-start_script_reselection)>>2);
-                               goto end_single;
-                       }
-                       printf("sc: %lx\n",tt);
-end_single:
-                       stat2=scsi_read_byte(DCNTL);
-                       stat2|=STD;
-                       scsi_write_byte(DCNTL,stat2);
-               }
-#endif
-               if((stat1 & SIR)==SIR) /* script interrupt */
-               {
-                       int_stat[0]=in32(scsi_mem_addr+DSPS);
-               }
-               if((stat1 & DFE)==0) { /* fifo not epmty */
-                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
-                       stat2=scsi_read_byte(STEST3);
-                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
-               }
-       }
-       if((stat & SIP)==SIP) {  /* scsi interrupt */
-               sstat = (unsigned short)scsi_read_byte(SIST+1);
-               sstat <<=8;
-               sstat |= (unsigned short)scsi_read_byte(SIST);
-               for(i=0;i<3;i++) {
-                       if(int_stat[i]==0)
-                               break; /* found an empty int status */
-               }
-               int_stat[i]=SCSI_INT_STATE | sstat;
-               stat1=scsi_read_byte(DSTAT);
-               if((stat1 & DFE)==0) { /* fifo not epmty */
-                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
-                       stat2=scsi_read_byte(STEST3);
-                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
-               }
-       }
-       if((stat & INTF)==INTF) { /* interrupt on Fly */
-               scsi_write_byte(ISTAT,stat); /* clear it */
-               for(i=0;i<3;i++) {
-                       if(int_stat[i]==0)
-                               break; /* found an empty int status */
-               }
-               int_stat[i]=INT_ON_FY;
-       }
-}
-
-void scsi_bus_reset(void)
-{
-       unsigned char t;
-       int i;
-       int end = CONFIG_SYS_SCSI_SPIN_UP_TIME*1000;
-
-       t=scsi_read_byte(SCNTL1);
-       scsi_write_byte(SCNTL1,(t | CRST));
-       udelay(50);
-       scsi_write_byte(SCNTL1,t);
-
-       puts("waiting for devices to spin up");
-       for(i=0;i<end;i++) {
-               udelay(1000); /* give the devices time to spin up */
-               if (i % 1000 == 0)
-                       putc('.');
-       }
-       putc('\n');
-       scsi_chip_init(); /* reinit the chip ...*/
-
-}
-
-void scsi_int_enable(void)
-{
-       scsi_write_byte(SIEN,(unsigned char)scsi_int_mask);
-       scsi_write_byte(SIEN+1,(unsigned char)(scsi_int_mask>>8));
-       scsi_write_byte(DIEN,script_int_mask);
-}
-
-void scsi_write_dsp(unsigned long start)
-{
-#ifdef SCSI_SINGLE_STEP
-       unsigned char t;
-#endif
-       out32r(scsi_mem_addr + DSP,start);
-#ifdef SCSI_SINGLE_STEP
-       t=scsi_read_byte(DCNTL);
-  t|=STD;
-       scsi_write_byte(DCNTL,t);
-#endif
-}
-
-/* only used for debug purposes */
-void scsi_print_script(void)
-{
-       printf("script_select @         0x%08lX\n",(unsigned long)&script_select[0]);
-       printf("script_msgout @         0x%08lX\n",(unsigned long)&script_msgout[0]);
-       printf("script_msgin @          0x%08lX\n",(unsigned long)&script_msgin[0]);
-       printf("script_msgext @         0x%08lX\n",(unsigned long)&script_msg_ext[0]);
-       printf("script_cmd @            0x%08lX\n",(unsigned long)&script_cmd[0]);
-       printf("script_data_in @        0x%08lX\n",(unsigned long)&script_data_in[0]);
-       printf("script_data_out @       0x%08lX\n",(unsigned long)&script_data_out[0]);
-       printf("script_status @         0x%08lX\n",(unsigned long)&script_status[0]);
-       printf("script_complete @       0x%08lX\n",(unsigned long)&script_complete[0]);
-       printf("script_error @          0x%08lX\n",(unsigned long)&script_error[0]);
-}
-
-
-void scsi_set_script(ccb *pccb)
-{
-       int busdevfunc = pccb->priv;
-       int i;
-       i=0;
-       script_select[i++]=swap_script(SCR_REG_REG(GPREG, SCR_AND, 0xfe));
-       script_select[i++]=0; /* LED ON */
-       script_select[i++]=swap_script(SCR_CLR(SCR_TRG)); /* select initiator mode */
-       script_select[i++]=0;
-       /* script_select[i++]=swap_script(SCR_SEL_ABS_ATN | pccb->target << 16); */
-       script_select[i++]=swap_script(SCR_SEL_ABS | pccb->target << 16);
-       script_select[i++]=swap_script(phys_to_bus(&script_cmd[4])); /* error handling */
-       script_select[i++]=swap_script(SCR_JUMP); /* next section */
-       /*      script_select[i++]=swap_script((unsigned long)&script_msgout[0]); */ /* message out */
-       script_select[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* command out */
-
-#ifdef SCSI_SINGLE_STEP
-       start_script_select=(unsigned long)&script_select[0];
-       len_script_select=i*4;
-#endif
-
-       i=0;
-       script_msgout[i++]=swap_script(SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)));
-       script_msgout[i++]=SIR_SEL_ATN_NO_MSG_OUT;
-       script_msgout[i++]=swap_script( SCR_MOVE_ABS(1) ^ SCR_MSG_OUT);
-       script_msgout[i++]=swap_script(phys_to_bus(&pccb->msgout[0]));
-       script_msgout[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_COMMAND))); /* if Command phase */
-       script_msgout[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* switch to command */
-       script_msgout[i++]=swap_script(SCR_INT); /* interrupt if not */
-       script_msgout[i++]=SIR_MSG_OUT_NO_CMD;
-
-#ifdef SCSI_SINGLE_STEP
-       start_script_msgout=(unsigned long)&script_msgout[0];
-       len_script_msgout=i*4;
-#endif
-       i=0;
-       script_cmd[i++]=swap_script(SCR_MOVE_ABS(pccb->cmdlen) ^ SCR_COMMAND);
-       script_cmd[i++]=swap_script(phys_to_bus(&pccb->cmd[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN))); /* message in ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT))); /* data out ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_data_out[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN))); /* data in ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_data_in[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)));  /* status ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_status[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)));  /* command ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_cmd[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)));  /* message out ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_msgout[0]));
-       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN))); /* just for error handling message in ? */
-       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
-       script_cmd[i++]=swap_script(SCR_INT); /* interrupt if not */
-       script_cmd[i++]=SIR_CMD_OUT_ILL_PH;
-#ifdef SCSI_SINGLE_STEP
-       start_script_cmd=(unsigned long)&script_cmd[0];
-       len_script_cmd=i*4;
-#endif
-       i=0;
-       script_data_out[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_OUT); /* move */
-       script_data_out[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
-       script_data_out[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
-       script_data_out[i++]=swap_script(phys_to_bus(&script_status[0]));
-       script_data_out[i++]=swap_script(SCR_INT);
-       script_data_out[i++]=SIR_DATA_OUT_ERR;
-
-#ifdef SCSI_SINGLE_STEP
-       start_script_data_out=(unsigned long)&script_data_out[0];
-       len_script_data_out=i*4;
-#endif
-       i=0;
-       script_data_in[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_IN); /* move  */
-       script_data_in[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
-       script_data_in[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
-       script_data_in[i++]=swap_script(phys_to_bus(&script_status[0]));
-       script_data_in[i++]=swap_script(SCR_INT);
-       script_data_in[i++]=SIR_DATA_IN_ERR;
-#ifdef SCSI_SINGLE_STEP
-       start_script_data_in=(unsigned long)&script_data_in[0];
-       len_script_data_in=i*4;
-#endif
-       i=0;
-       script_msgin[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN);
-       script_msgin[i++]=swap_script(phys_to_bus(&pccb->msgin[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
-       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)));
-       script_msgin[i++]=swap_script(phys_to_bus(&script_msg_ext[0]));
-       script_msgin[i++]=swap_script(SCR_INT);
-       script_msgin[i++]=SIR_MSG_RECEIVED;
-#ifdef SCSI_SINGLE_STEP
-       start_script_msgin=(unsigned long)&script_msgin[0];
-       len_script_msgin=i*4;
-#endif
-       i=0;
-       script_msg_ext[i++]=swap_script(SCR_CLR (SCR_ACK)); /* clear ACK */
-       script_msg_ext[i++]=0;
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* assuming this is the msg length */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[1]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[2]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[3]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[4]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[5]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[6]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
-       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[7]));
-       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN)));
-       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
-       script_msg_ext[i++]=swap_script(SCR_INT);
-       script_msg_ext[i++]=SIR_MSG_OVER7;
-#ifdef SCSI_SINGLE_STEP
-       start_script_msg_ext=(unsigned long)&script_msg_ext[0];
-       len_script_msg_ext=i*4;
-#endif
-       i=0;
-       script_status[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_STATUS);
-       script_status[i++]=swap_script(phys_to_bus(&pccb->status));
-       script_status[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)));
-       script_status[i++]=swap_script(phys_to_bus(&script_msgin[0]));
-       script_status[i++]=swap_script(SCR_INT);
-       script_status[i++]=SIR_STATUS_ILL_PH;
-#ifdef SCSI_SINGLE_STEP
-       start_script_status=(unsigned long)&script_status[0];
-       len_script_status=i*4;
-#endif
-       i=0;
-       script_complete[i++]=swap_script(SCR_REG_REG (SCNTL2, SCR_AND, 0x7f));
-       script_complete[i++]=0;
-       script_complete[i++]=swap_script(SCR_CLR (SCR_ACK|SCR_ATN));
-       script_complete[i++]=0;
-       script_complete[i++]=swap_script(SCR_WAIT_DISC);
-       script_complete[i++]=0;
-       script_complete[i++]=swap_script(SCR_REG_REG(GPREG, SCR_OR, 0x01));
-       script_complete[i++]=0; /* LED OFF */
-       script_complete[i++]=swap_script(SCR_INT);
-       script_complete[i++]=SIR_COMPLETE;
-#ifdef SCSI_SINGLE_STEP
-       start_script_complete=(unsigned long)&script_complete[0];
-       len_script_complete=i*4;
-#endif
-       i=0;
-       script_error[i++]=swap_script(SCR_INT); /* interrupt if error */
-       script_error[i++]=SIR_SCRIPT_ERROR;
-#ifdef SCSI_SINGLE_STEP
-       start_script_error=(unsigned long)&script_error[0];
-       len_script_error=i*4;
-#endif
-       i=0;
-       script_reselection[i++]=swap_script(SCR_CLR (SCR_TRG)); /* target status */
-       script_reselection[i++]=0;
-       script_reselection[i++]=swap_script(SCR_WAIT_RESEL);
-       script_reselection[i++]=swap_script(phys_to_bus(&script_select[0])); /* len = 4 */
-#ifdef SCSI_SINGLE_STEP
-       start_script_reselection=(unsigned long)&script_reselection[0];
-       len_script_reselection=i*4;
-#endif
-}
-
-
-void scsi_issue(ccb *pccb)
-{
-       int busdevfunc = pccb->priv;
-       int i;
-       unsigned short sstat;
-       int retrycnt;  /* retry counter */
-       for(i=0;i<3;i++)
-               int_stat[i]=0; /* delete all int status */
-       /* struct pccb must be set-up correctly */
-       retrycnt=0;
-       PRINTF("ID %d issue cmd %02X\n",pccb->target,pccb->cmd[0]);
-       pccb->trans_bytes=0; /* no bytes transferred yet */
-       scsi_set_script(pccb); /* fill in SCRIPT                */
-       scsi_int_mask=STO | UDC | MA; /* | CMP; / * Interrupts which are enabled */
-       script_int_mask=0xff; /* enable all Ints */
-       scsi_int_enable();
-       scsi_write_dsp(phys_to_bus(&script_select[0])); /* start script */
-       /* now we have to wait for IRQs */
-retry:
-       /*
-        * This version of the driver is _not_ interrupt driven,
-        * but polls the chip's interrupt registers (ISTAT, DSTAT).
-        */
-       while(int_stat[0]==0)
-               handle_scsi_int();
-
-       if(int_stat[0]==SIR_COMPLETE) {
-               if(pccb->msgin[0]==M_DISCONNECT) {
-                       PRINTF("Wait for reselection\n");
-                       for(i=0;i<3;i++)
-                               int_stat[i]=0; /* delete all int status */
-                       scsi_write_dsp(phys_to_bus(&script_reselection[0])); /* start reselection script */
-                       goto retry;
-               }
-               pccb->contr_stat=SIR_COMPLETE;
-               return;
-       }
-       if((int_stat[0] & SCSI_INT_STATE)==SCSI_INT_STATE) { /* scsi interrupt */
-               sstat=(unsigned short)int_stat[0];
-               if((sstat & STO)==STO) { /* selection timeout */
-                       pccb->contr_stat=SCSI_SEL_TIME_OUT;
-                       scsi_write_byte(GPREG,0x01);
-                       PRINTF("ID: %X Selection Timeout\n",pccb->target);
-                       return;
-               }
-               if((sstat & UDC)==UDC) { /* unexpected disconnect */
-                       pccb->contr_stat=SCSI_UNEXP_DIS;
-                       scsi_write_byte(GPREG,0x01);
-                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
-                       return;
-               }
-               if((sstat & RSL)==RSL) { /* reselection */
-                       pccb->contr_stat=SCSI_UNEXP_DIS;
-                       scsi_write_byte(GPREG,0x01);
-                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
-                       return;
-               }
-               if(((sstat & MA)==MA)||((sstat & HTH)==HTH)) { /* phase missmatch */
-                       if(retrycnt<SCSI_MAX_RETRY) {
-                               pccb->trans_bytes=pccb->datalen -
-                                       ((unsigned long)scsi_read_byte(DBC) |
-                                       ((unsigned long)scsi_read_byte(DBC+1)<<8) |
-                                       ((unsigned long)scsi_read_byte(DBC+2)<<16));
-                               for(i=0;i<3;i++)
-                                       int_stat[i]=0; /* delete all int status */
-                               retrycnt++;
-                               PRINTF("ID: %X Phase Missmatch Retry %d Phase %02X transferred %lx\n",
-                                               pccb->target,retrycnt,scsi_read_byte(SBCL),pccb->trans_bytes);
-                               scsi_write_dsp(phys_to_bus(&script_cmd[4])); /* start retry script */
-                               goto retry;
-                       }
-                       if((sstat & MA)==MA)
-                               pccb->contr_stat=SCSI_MA_TIME_OUT;
-                       else
-                               pccb->contr_stat=SCSI_HNS_TIME_OUT;
-                       PRINTF("Phase Missmatch stat %lx\n",pccb->contr_stat);
-                       return;
-               } /* no phase int */
-/*             if((sstat & CMP)==CMP) {
-                       pccb->contr_stat=SIR_COMPLETE;
-                       return;
-               }
-*/
-               PRINTF("SCSI INT %lX\n",int_stat[0]);
-               pccb->contr_stat=int_stat[0];
-               return;
-       } /* end scsi int */
-       PRINTF("SCRIPT INT %lX phase %02X\n",int_stat[0],scsi_read_byte(SBCL));
-       pccb->contr_stat=int_stat[0];
-       return;
-}
-
-int scsi_exec(ccb *pccb)
-{
-       unsigned char tmpcmd[16],tmpstat;
-       int i,retrycnt,t;
-       unsigned long transbytes,datalen;
-       unsigned char *tmpptr;
-       retrycnt=0;
-retry:
-       scsi_issue(pccb);
-       if(pccb->contr_stat!=SIR_COMPLETE)
-               return false;
-       if(pccb->status==S_GOOD)
-               return true;
-       if(pccb->status==S_CHECK_COND) { /* check condition */
-               for(i=0;i<16;i++)
-                       tmpcmd[i]=pccb->cmd[i];
-               pccb->cmd[0]=SCSI_REQ_SENSE;
-               pccb->cmd[1]=pccb->lun<<5;
-               pccb->cmd[2]=0;
-               pccb->cmd[3]=0;
-               pccb->cmd[4]=14;
-               pccb->cmd[5]=0;
-               pccb->cmdlen=6;
-               pccb->msgout[0]=SCSI_IDENTIFY;
-               transbytes=pccb->trans_bytes;
-               tmpptr=pccb->pdata;
-               pccb->pdata = &pccb->sense_buf[0];
-               datalen=pccb->datalen;
-               pccb->datalen=14;
-               tmpstat=pccb->status;
-               scsi_issue(pccb);
-               for(i=0;i<16;i++)
-                       pccb->cmd[i]=tmpcmd[i];
-               pccb->trans_bytes=transbytes;
-               pccb->pdata=tmpptr;
-               pccb->datalen=datalen;
-               pccb->status=tmpstat;
-               PRINTF("Request_sense sense key %x ASC %x ASCQ %x\n",pccb->sense_buf[2]&0x0f,
-                       pccb->sense_buf[12],pccb->sense_buf[13]);
-               switch(pccb->sense_buf[2]&0xf) {
-                       case SENSE_NO_SENSE:
-                       case SENSE_RECOVERED_ERROR:
-                               /* seems to be ok */
-                               return true;
-                               break;
-                       case SENSE_NOT_READY:
-                               if((pccb->sense_buf[12]!=0x04)||(pccb->sense_buf[13]!=0x01)) {
-                                       /* if device is not in process of becoming ready */
-                                       return false;
-                                       break;
-                               } /* else fall through */
-                       case SENSE_UNIT_ATTENTION:
-                               if(retrycnt<SCSI_MAX_RETRY_NOT_READY) {
-                                       PRINTF("Target %d not ready, retry %d\n",pccb->target,retrycnt);
-                                       for(t=0;t<SCSI_NOT_READY_TIME_OUT;t++)
-                                               udelay(1000); /* 1sec wait */
-                                       retrycnt++;
-                                       goto retry;
-                               }
-                               PRINTF("Target %d not ready, %d retried\n",pccb->target,retrycnt);
-                               return false;
-                       default:
-                               return false;
-               }
-       }
-       PRINTF("Status = %X\n",pccb->status);
-       return false;
-}
-
-
-void scsi_chip_init(void)
-{
-       /* first we issue a soft reset */
-       scsi_write_byte(ISTAT,SRST);
-       udelay(1000);
-       scsi_write_byte(ISTAT,0);
-       /* setup chip */
-       scsi_write_byte(SCNTL0,0xC0); /* full arbitration no start, no message, parity disabled, master */
-       scsi_write_byte(SCNTL1,0x00);
-       scsi_write_byte(SCNTL2,0x00);
-#ifndef CONFIG_SYS_SCSI_SYM53C8XX_CCF    /* config value for none 40 MHz clocks */
-       scsi_write_byte(SCNTL3,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */
-#else
-       scsi_write_byte(SCNTL3,CONFIG_SYS_SCSI_SYM53C8XX_CCF); /* config value for none 40 MHz clocks */
-#endif
-       scsi_write_byte(SCID,0x47); /* ID=7, enable reselection */
-       scsi_write_byte(SXFER,0x00); /* synchronous transfer period 10MHz, asynchronous */
-       scsi_write_byte(SDID,0x00);  /* targed SCSI ID = 0 */
-       scsi_int_mask=0x0000; /* no Interrupt is enabled */
-       script_int_mask=0x00;
-       scsi_int_enable();
-       scsi_write_byte(GPREG,0x01); /* GPIO0 is LED (off) */
-       scsi_write_byte(GPCNTL,0x0E); /* GPIO0 is Output */
-       scsi_write_byte(STIME0,0x08); /* handshake timer disabled, selection timeout 512msec */
-       scsi_write_byte(RESPID,0x80); /* repond only to the own ID (reselection) */
-       scsi_write_byte(STEST1,0x00); /* not isolated, SCLK is used */
-       scsi_write_byte(STEST2,0x00); /* no Lowlevel Mode? */
-       scsi_write_byte(STEST3,0x80); /* enable tolerANT */
-       scsi_write_byte(CTEST3,0x04); /* clear FIFO */
-       scsi_write_byte(CTEST4,0x00);
-       scsi_write_byte(CTEST5,0x00);
-#ifdef SCSI_SINGLE_STEP
-/*     scsi_write_byte(DCNTL,IRQM | SSM);      */
-       scsi_write_byte(DCNTL,IRQD | SSM);
-       scsi_write_byte(DMODE,MAN);
-#else
-/*     scsi_write_byte(DCNTL,IRQM);    */
-       scsi_write_byte(DCNTL,IRQD);
-       scsi_write_byte(DMODE,0x00);
-#endif
-}
-#endif
index 435cf98..fd2d4de 100644 (file)
@@ -15,4 +15,4 @@ obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o
 ifndef CONFIG_DM_DEV_READ_INLINE
 obj-$(CONFIG_OF_CONTROL) += read.o
 endif
-obj-$(CONFIG_OF_CONTROL) += of_extra.o ofnode.o
+obj-$(CONFIG_OF_CONTROL) += of_extra.o ofnode.o read_extra.o
index fd4596e..c3e109e 100644 (file)
@@ -8,6 +8,7 @@
 #include <dm.h>
 #include <mapmem.h>
 #include <dm/root.h>
+#include <dm/util.h>
 
 static void show_devices(struct udevice *dev, int depth, int last_flag)
 {
index b79f26d..6067914 100644 (file)
@@ -141,8 +141,7 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp)
        name = ofnode_get_name(node);
        dm_dbg("bind node %s\n", name);
 
-       compat_list = (const char *)ofnode_read_prop(node, "compatible",
-                                                    &compat_length);
+       compat_list = ofnode_get_property(node, "compatible", &compat_length);
        if (!compat_list) {
                if (compat_length == -FDT_ERR_NOTFOUND) {
                        dm_dbg("Device '%s' has no compatible string\n", name);
index 93a6560..2bb23ee 100644 (file)
@@ -96,6 +96,30 @@ int of_n_size_cells(const struct device_node *np)
        return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
 }
 
+int of_simple_addr_cells(const struct device_node *np)
+{
+       const __be32 *ip;
+
+       ip = of_get_property(np, "#address-cells", NULL);
+       if (ip)
+               return be32_to_cpup(ip);
+
+       /* Return a default of 2 to match fdt_address_cells()*/
+       return 2;
+}
+
+int of_simple_size_cells(const struct device_node *np)
+{
+       const __be32 *ip;
+
+       ip = of_get_property(np, "#size-cells", NULL);
+       if (ip)
+               return be32_to_cpup(ip);
+
+       /* Return a default of 2 to match fdt_size_cells()*/
+       return 2;
+}
+
 struct property *of_find_property(const struct device_node *np,
                                  const char *name, int *lenp)
 {
index ac312d6..fd068b0 100644 (file)
@@ -23,7 +23,7 @@ int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
        if (ofnode_is_np(node)) {
                return of_read_u32(ofnode_to_np(node), propname, outp);
        } else {
-               const int *cell;
+               const fdt32_t *cell;
                int len;
 
                cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
@@ -57,20 +57,16 @@ int ofnode_read_s32_default(ofnode node, const char *propname, s32 def)
 
 bool ofnode_read_bool(ofnode node, const char *propname)
 {
-       bool val;
+       const void *prop;
 
        assert(ofnode_valid(node));
        debug("%s: %s: ", __func__, propname);
 
-       if (ofnode_is_np(node)) {
-               val = !!of_find_property(ofnode_to_np(node), propname, NULL);
-       } else {
-               val = !!fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
-                                   propname, NULL);
-       }
-       debug("%s\n", val ? "true" : "false");
+       prop = ofnode_get_property(node, propname, NULL);
+
+       debug("%s\n", prop ? "true" : "false");
 
-       return val;
+       return prop ? true : false;
 }
 
 const char *ofnode_read_string(ofnode node, const char *propname)
@@ -260,6 +256,16 @@ int ofnode_read_string_index(ofnode node, const char *property, int index,
        }
 }
 
+int ofnode_read_string_count(ofnode node, const char *property)
+{
+       if (ofnode_is_np(node)) {
+               return of_property_count_strings(ofnode_to_np(node), property);
+       } else {
+               return fdt_stringlist_count(gd->fdt_blob,
+                                           ofnode_to_offset(node), property);
+       }
+}
+
 static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in,
                                            struct ofnode_phandle_args *out)
 {
@@ -422,19 +428,13 @@ int ofnode_decode_display_timing(ofnode parent, int index,
        return ret;
 }
 
-const u32 *ofnode_read_prop(ofnode node, const char *propname, int *lenp)
+const void *ofnode_get_property(ofnode node, const char *propname, int *lenp)
 {
-       if (ofnode_is_np(node)) {
-               struct property *prop;
-
-               prop = of_find_property(ofnode_to_np(node), propname, lenp);
-               if (!prop)
-                       return NULL;
-               return prop->value;
-       } else {
+       if (ofnode_is_np(node))
+               return of_get_property(ofnode_to_np(node), propname, lenp);
+       else
                return fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
                                   propname, lenp);
-       }
 }
 
 bool ofnode_is_available(ofnode node)
@@ -487,7 +487,7 @@ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
 int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
                         const char *propname, struct fdt_pci_addr *addr)
 {
-       const u32 *cell;
+       const fdt32_t *cell;
        int len;
        int ret = -ENOENT;
 
@@ -499,7 +499,7 @@ int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
         * #size-cells. They need to be 3 and 2 accordingly. However,
         * for simplicity we skip the check here.
         */
-       cell = ofnode_read_prop(node, propname, &len);
+       cell = ofnode_get_property(node, propname, &len);
        if (!cell)
                goto fail;
 
@@ -542,7 +542,7 @@ int ofnode_read_addr_cells(ofnode node)
 {
        if (ofnode_is_np(node))
                return of_n_addr_cells(ofnode_to_np(node));
-       else
+       else  /* NOTE: this call should walk up the parent stack */
                return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node));
 }
 
@@ -550,28 +550,44 @@ int ofnode_read_size_cells(ofnode node)
 {
        if (ofnode_is_np(node))
                return of_n_size_cells(ofnode_to_np(node));
+       else  /* NOTE: this call should walk up the parent stack */
+               return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+int ofnode_read_simple_addr_cells(ofnode node)
+{
+       if (ofnode_is_np(node))
+               return of_simple_addr_cells(ofnode_to_np(node));
+       else
+               return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+int ofnode_read_simple_size_cells(ofnode node)
+{
+       if (ofnode_is_np(node))
+               return of_simple_size_cells(ofnode_to_np(node));
        else
                return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node));
 }
 
 bool ofnode_pre_reloc(ofnode node)
 {
-       if (ofnode_read_prop(node, "u-boot,dm-pre-reloc", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
                return true;
 
 #ifdef CONFIG_TPL_BUILD
-       if (ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-tpl"))
                return true;
 #elif defined(CONFIG_SPL_BUILD)
-       if (ofnode_read_prop(node, "u-boot,dm-spl", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-spl"))
                return true;
 #else
        /*
         * In regular builds individual spl and tpl handling both
         * count as handled pre-relocation for later second init.
         */
-       if (ofnode_read_prop(node, "u-boot,dm-spl", NULL) ||
-           ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+       if (ofnode_read_bool(node, "u-boot,dm-spl") ||
+           ofnode_read_bool(node, "u-boot,dm-tpl"))
                return true;
 #endif
 
index 3131e53..eafe727 100644 (file)
@@ -94,6 +94,16 @@ int dev_read_size_cells(struct udevice *dev)
        return ofnode_read_size_cells(dev_ofnode(dev));
 }
 
+int dev_read_simple_addr_cells(struct udevice *dev)
+{
+       return ofnode_read_simple_addr_cells(dev_ofnode(dev));
+}
+
+int dev_read_simple_size_cells(struct udevice *dev)
+{
+       return ofnode_read_simple_size_cells(dev_ofnode(dev));
+}
+
 int dev_read_phandle(struct udevice *dev)
 {
        ofnode node = dev_ofnode(dev);
@@ -106,7 +116,7 @@ int dev_read_phandle(struct udevice *dev)
 
 const u32 *dev_read_prop(struct udevice *dev, const char *propname, int *lenp)
 {
-       return ofnode_read_prop(dev_ofnode(dev), propname, lenp);
+       return ofnode_get_property(dev_ofnode(dev), propname, lenp);
 }
 
 int dev_read_alias_seq(struct udevice *dev, int *devnump)
@@ -138,3 +148,14 @@ const uint8_t *dev_read_u8_array_ptr(struct udevice *dev, const char *propname,
 {
        return ofnode_read_u8_array_ptr(dev_ofnode(dev), propname, sz);
 }
+
+int dev_read_enabled(struct udevice *dev)
+{
+       ofnode node = dev_ofnode(dev);
+
+       if (ofnode_is_np(node))
+               return of_device_is_available(ofnode_to_np(node));
+       else
+               return fdtdec_get_is_enabled(gd->fdt_blob,
+                                            ofnode_to_offset(node));
+}
diff --git a/drivers/core/read_extra.c b/drivers/core/read_extra.c
new file mode 100644 (file)
index 0000000..a6d2f34
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/of_addr.h>
+#include <dm/read.h>
+#include <linux/ioport.h>
+
+int dev_read_resource(struct udevice *dev, uint index, struct resource *res)
+{
+       ofnode node = dev_ofnode(dev);
+
+#ifdef CONFIG_OF_LIVE
+       if (ofnode_is_np(node)) {
+               return of_address_to_resource(ofnode_to_np(node), index, res);
+       } else
+#endif
+               {
+               struct fdt_resource fres;
+               int ret;
+
+               ret = fdt_get_resource(gd->fdt_blob, ofnode_to_offset(node),
+                                      "reg", index, &fres);
+               if (ret < 0)
+                       return -EINVAL;
+               memset(res, '\0', sizeof(*res));
+               res->start = fres.start;
+               res->end = fres.end;
+
+               return 0;
+       }
+}
index 749d913..d4e16a2 100644 (file)
@@ -72,8 +72,8 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
        ofnode node = dev_ofnode(dev);
        struct resource r;
 
-       addr_len = dev_read_addr_cells(dev->parent);
-       size_len = dev_read_size_cells(dev->parent);
+       addr_len = dev_read_simple_addr_cells(dev->parent);
+       size_len = dev_read_simple_size_cells(dev->parent);
        both_len = addr_len + size_len;
 
        len = dev_read_size(dev, "reg");
index 21dc696..f5e4067 100644 (file)
@@ -366,8 +366,7 @@ int uclass_get_device_by_driver(enum uclass_id id,
        return -ENODEV;
 }
 
-int uclass_get_device_tail(struct udevice *dev, int ret,
-                                 struct udevice **devp)
+int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp)
 {
        if (ret)
                return ret;
@@ -493,6 +492,33 @@ int uclass_next_device(struct udevice **devp)
        return uclass_get_device_tail(dev, ret, devp);
 }
 
+int uclass_first_device_check(enum uclass_id id, struct udevice **devp)
+{
+       int ret;
+
+       *devp = NULL;
+       ret = uclass_find_first_device(id, devp);
+       if (ret)
+               return ret;
+       if (!*devp)
+               return 0;
+
+       return device_probe(*devp);
+}
+
+int uclass_next_device_check(struct udevice **devp)
+{
+       int ret;
+
+       ret = uclass_find_next_device(devp);
+       if (ret)
+               return ret;
+       if (!*devp)
+               return 0;
+
+       return device_probe(*devp);
+}
+
 int uclass_bind_device(struct udevice *dev)
 {
        struct uclass *uc;
index 5ceac8b..2e232d5 100644 (file)
@@ -5,9 +5,11 @@
  */
 
 #include <common.h>
+#include <dm/util.h>
 #include <libfdt.h>
 #include <vsprintf.h>
 
+#ifdef CONFIG_DM_WARN
 void dm_warn(const char *fmt, ...)
 {
        va_list args;
@@ -16,7 +18,9 @@ void dm_warn(const char *fmt, ...)
        vprintf(fmt, args);
        va_end(args);
 }
+#endif
 
+#ifdef DEBUG
 void dm_dbg(const char *fmt, ...)
 {
        va_list args;
@@ -25,6 +29,7 @@ void dm_dbg(const char *fmt, ...)
        vprintf(fmt, args);
        va_end(args);
 }
+#endif
 
 int list_count_items(struct list_head *head)
 {
index c96e26e..5924ade 100644 (file)
@@ -197,7 +197,7 @@ static int keyscan_read_fdt_matrix(struct ec_state *ec, ofnode node)
        int upto;
        int len;
 
-       cell = ofnode_read_prop(node, "linux,keymap", &len);
+       cell = ofnode_get_property(node, "linux,keymap", &len);
        ec->matrix_count = len / 4;
        ec->matrix = calloc(ec->matrix_count, sizeof(*ec->matrix));
        if (!ec->matrix) {
index b36ef33..86df141 100644 (file)
@@ -763,12 +763,12 @@ static int decode_regions(struct pci_controller *hose, ofnode parent_node,
        int len;
        int i;
 
-       prop = ofnode_read_prop(node, "ranges", &len);
+       prop = ofnode_get_property(node, "ranges", &len);
        if (!prop)
                return -EINVAL;
-       pci_addr_cells = ofnode_read_addr_cells(node);
-       addr_cells = ofnode_read_addr_cells(parent_node);
-       size_cells = ofnode_read_size_cells(node);
+       pci_addr_cells = ofnode_read_simple_addr_cells(node);
+       addr_cells = ofnode_read_simple_addr_cells(parent_node);
+       size_cells = ofnode_read_simple_size_cells(node);
 
        /* PCI addresses are always 3-cells */
        len /= sizeof(u32);
index 02e2690..114952a 100644 (file)
@@ -134,7 +134,7 @@ static int pinconfig_post_bind(struct udevice *dev)
                 * If this node has "compatible" property, this is not
                 * a pin configuration node, but a normal device. skip.
                 */
-               ofnode_read_prop(node, "compatible", &ret);
+               ofnode_get_property(node, "compatible", &ret);
                if (ret >= 0)
                        continue;
 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
new file mode 100644 (file)
index 0000000..db1606e
--- /dev/null
@@ -0,0 +1,17 @@
+config SCSI
+       bool "Support SCSI controllers"
+       help
+         This enables support for SCSI (Small Computer System Interface),
+         a parallel interface widely used with storage peripherals such as
+         hard drives and optical drives. The SCSI standards define physical
+         interfaces as well as protocols for controlling devices and
+         tranferring data.
+
+config DM_SCSI
+       bool "Support SCSI controllers with driver model"
+       depends on BLK
+       help
+         This option enables the SCSI (Small Computer System Interface) uclass
+         which supports SCSI and SATA HDDs. For every device configuration
+         (IDs/LUNs) a block device is created with RAW read/write and
+         filesystem support.
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
new file mode 100644 (file)
index 0000000..9e23699
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_DM_SCSI) += scsi-uclass.o
+obj-$(CONFIG_SCSI) += scsi.o
+endif
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_SATA_SUPPORT
+obj-$(CONFIG_DM_SCSI) += scsi-uclass.o
+obj-$(CONFIG_SCSI) += scsi.o
+endif
+endif
+
+obj-$(CONFIG_SANDBOX) += sandbox_scsi.o
similarity index 75%
rename from drivers/block/sandbox_scsi.c
rename to drivers/scsi/sandbox_scsi.c
index ad961bd..ac60ae0 100644 (file)
 #include <common.h>
 #include <scsi.h>
 
-void scsi_bus_reset(void)
+int scsi_bus_reset(struct udevice *dev)
 {
+       return 0;
 }
 
 void scsi_init(void)
 {
 }
 
-int scsi_exec(ccb *pccb)
+int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
 {
        return 0;
 }
-
-void scsi_print_error(ccb *pccb)
-{
-}
diff --git a/drivers/scsi/scsi-uclass.c b/drivers/scsi/scsi-uclass.c
new file mode 100644 (file)
index 0000000..31e8999
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ * Copyright (c) 2016 Xilinx, Inc
+ * Written by Michal Simek
+ *
+ * Based on ahci-uclass.c
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <scsi.h>
+
+int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
+{
+       struct scsi_ops *ops = scsi_get_ops(dev);
+
+       if (!ops->exec)
+               return -ENOSYS;
+
+       return ops->exec(dev, pccb);
+}
+
+int scsi_bus_reset(struct udevice *dev)
+{
+       struct scsi_ops *ops = scsi_get_ops(dev);
+
+       if (!ops->bus_reset)
+               return -ENOSYS;
+
+       return ops->bus_reset(dev);
+}
+
+UCLASS_DRIVER(scsi) = {
+       .id             = UCLASS_SCSI,
+       .name           = "scsi",
+       .per_device_platdata_auto_alloc_size = sizeof(struct scsi_platdata),
+};
similarity index 86%
rename from common/scsi.c
rename to drivers/scsi/scsi.c
index c456f5a..7ec7ecc 100644 (file)
 #include <dm/uclass-internal.h>
 
 #if !defined(CONFIG_DM_SCSI)
-#ifdef CONFIG_SCSI_DEV_LIST
-#define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
-#else
-#ifdef CONFIG_SCSI_SYM53C8XX
-#define SCSI_VEND_ID   0x1000
-#ifndef CONFIG_SCSI_DEV_ID
-#define SCSI_DEV_ID            0x0001
-#else
-#define SCSI_DEV_ID            CONFIG_SCSI_DEV_ID
-#endif
-#elif defined CONFIG_SATA_ULI5288
-
-#define SCSI_VEND_ID 0x10b9
-#define SCSI_DEV_ID  0x5288
-
-#elif !defined(CONFIG_SCSI_AHCI_PLAT)
-#error no scsi device defined
-#endif
-#define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
-#endif
+# ifdef CONFIG_SCSI_DEV_LIST
+#  define SCSI_DEV_LIST CONFIG_SCSI_DEV_LIST
+# else
+#  ifdef CONFIG_SATA_ULI5288
+
+#   define SCSI_VEND_ID 0x10b9
+#   define SCSI_DEV_ID  0x5288
+
+#  elif !defined(CONFIG_SCSI_AHCI_PLAT)
+#   error no scsi device defined
+#  endif
+# define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID}
+# endif
 #endif
 
-#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
+#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) && \
+       !defined(CONFIG_DM_SCSI)
 const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
 #endif
-static ccb tempccb;    /* temporary scsi command buffer */
+static struct scsi_cmd tempccb;        /* temporary scsi command buffer */
 
 static unsigned char tempbuff[512]; /* temporary data buffer */
 
@@ -55,8 +49,14 @@ static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
 #define SCSI_MAX_READ_BLK 0xFFFF
 #define SCSI_LBA48_READ        0xFFFFFFF
 
+static void scsi_print_error(struct scsi_cmd *pccb)
+{
+       /* Dummy function that could print an error for debugging */
+}
+
 #ifdef CONFIG_SYS_64BIT_LBA
-void scsi_setup_read16(ccb *pccb, lbaint_t start, unsigned long blocks)
+void scsi_setup_read16(struct scsi_cmd *pccb, lbaint_t start,
+                      unsigned long blocks)
 {
        pccb->cmd[0] = SCSI_READ16;
        pccb->cmd[1] = pccb->lun << 5;
@@ -84,7 +84,7 @@ void scsi_setup_read16(ccb *pccb, lbaint_t start, unsigned long blocks)
 }
 #endif
 
-static void scsi_setup_read_ext(ccb *pccb, lbaint_t start,
+static void scsi_setup_read_ext(struct scsi_cmd *pccb, lbaint_t start,
                                unsigned short blocks)
 {
        pccb->cmd[0] = SCSI_READ10;
@@ -105,7 +105,7 @@ static void scsi_setup_read_ext(ccb *pccb, lbaint_t start,
              pccb->cmd[7], pccb->cmd[8]);
 }
 
-static void scsi_setup_write_ext(ccb *pccb, lbaint_t start,
+static void scsi_setup_write_ext(struct scsi_cmd *pccb, lbaint_t start,
                                 unsigned short blocks)
 {
        pccb->cmd[0] = SCSI_WRITE10;
@@ -127,7 +127,7 @@ static void scsi_setup_write_ext(ccb *pccb, lbaint_t start,
              pccb->cmd[7], pccb->cmd[8]);
 }
 
-static void scsi_setup_inquiry(ccb *pccb)
+static void scsi_setup_inquiry(struct scsi_cmd *pccb)
 {
        pccb->cmd[0] = SCSI_INQUIRY;
        pccb->cmd[1] = pccb->lun << 5;
@@ -152,11 +152,14 @@ static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
 {
 #ifdef CONFIG_BLK
        struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+       struct udevice *bdev = dev->parent;
+#else
+       struct udevice *bdev = NULL;
 #endif
        lbaint_t start, blks;
        uintptr_t buf_addr;
        unsigned short smallblks = 0;
-       ccb *pccb = (ccb *)&tempccb;
+       struct scsi_cmd *pccb = (struct scsi_cmd *)&tempccb;
 
        /* Setup device */
        pccb->target = block_dev->target;
@@ -196,7 +199,7 @@ static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
                debug("scsi_read_ext: startblk " LBAF
                      ", blccnt %x buffer %" PRIXPTR "\n",
                      start, smallblks, buf_addr);
-               if (scsi_exec(pccb) != true) {
+               if (scsi_exec(bdev, pccb)) {
                        scsi_print_error(pccb);
                        blkcnt -= blks;
                        break;
@@ -225,11 +228,14 @@ static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
 {
 #ifdef CONFIG_BLK
        struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+       struct udevice *bdev = dev->parent;
+#else
+       struct udevice *bdev = NULL;
 #endif
        lbaint_t start, blks;
        uintptr_t buf_addr;
        unsigned short smallblks;
-       ccb *pccb = (ccb *)&tempccb;
+       struct scsi_cmd *pccb = (struct scsi_cmd *)&tempccb;
 
        /* Setup device */
        pccb->target = block_dev->target;
@@ -257,7 +263,7 @@ static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
                }
                debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
                      __func__, start, smallblks, buf_addr);
-               if (scsi_exec(pccb) != true) {
+               if (scsi_exec(bdev, pccb)) {
                        scsi_print_error(pccb);
                        blkcnt -= blks;
                        break;
@@ -269,7 +275,8 @@ static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
        return blkcnt;
 }
 
-#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
+#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) && \
+       !defined(CONFIG_DM_SCSI)
 void scsi_init(void)
 {
        int busdevfunc = -1;
@@ -321,7 +328,7 @@ void scsi_init(void)
 #endif
        bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
        scsi_low_level_init(busdevfunc);
-       scsi_scan(1);
+       scsi_scan(true);
        bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
 }
 #endif
@@ -351,8 +358,8 @@ static void scsi_ident_cpy(unsigned char *dest, unsigned char *src,
        *dest = '\0';
 }
 
-static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
-                             unsigned long *blksz)
+static int scsi_read_capacity(struct udevice *dev, struct scsi_cmd *pccb,
+                             lbaint_t *capacity, unsigned long *blksz)
 {
        *capacity = 0;
 
@@ -363,7 +370,7 @@ static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
        pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
 
        pccb->datalen = 8;
-       if (scsi_exec(pccb) != true)
+       if (scsi_exec(dev, pccb))
                return 1;
 
        *capacity = ((lbaint_t)pccb->pdata[0] << 24) |
@@ -388,7 +395,7 @@ static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
        pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
 
        pccb->datalen = 16;
-       if (scsi_exec(pccb) != true)
+       if (scsi_exec(dev, pccb))
                return 1;
 
        *capacity = ((uint64_t)pccb->pdata[0] << 56) |
@@ -416,7 +423,7 @@ static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
 /*
  * Some setup (fill-in) routines
  */
-static void scsi_setup_test_unit_ready(ccb *pccb)
+static void scsi_setup_test_unit_ready(struct scsi_cmd *pccb)
 {
        pccb->cmd[0] = SCSI_TST_U_RDY;
        pccb->cmd[1] = pccb->lun << 5;
@@ -481,19 +488,20 @@ static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum)
  *
  * Return: 0 on success, error value otherwise
  */
-static int scsi_detect_dev(int target, int lun, struct blk_desc *dev_desc)
+static int scsi_detect_dev(struct udevice *dev, int target, int lun,
+                          struct blk_desc *dev_desc)
 {
        unsigned char perq, modi;
        lbaint_t capacity;
        unsigned long blksz;
-       ccb *pccb = (ccb *)&tempccb;
+       struct scsi_cmd *pccb = (struct scsi_cmd *)&tempccb;
 
        pccb->target = target;
        pccb->lun = lun;
        pccb->pdata = (unsigned char *)&tempbuff;
        pccb->datalen = 512;
        scsi_setup_inquiry(pccb);
-       if (scsi_exec(pccb) != true) {
+       if (scsi_exec(dev, pccb)) {
                if (pccb->contr_stat == SCSI_SEL_TIME_OUT) {
                        /*
                          * selection timeout => assuming no
@@ -524,7 +532,7 @@ static int scsi_detect_dev(int target, int lun, struct blk_desc *dev_desc)
 
        pccb->datalen = 0;
        scsi_setup_test_unit_ready(pccb);
-       if (scsi_exec(pccb) != true) {
+       if (scsi_exec(dev, pccb)) {
                if (dev_desc->removable) {
                        dev_desc->type = perq;
                        goto removable;
@@ -532,7 +540,7 @@ static int scsi_detect_dev(int target, int lun, struct blk_desc *dev_desc)
                scsi_print_error(pccb);
                return -EINVAL;
        }
-       if (scsi_read_capacity(pccb, &capacity, &blksz)) {
+       if (scsi_read_capacity(dev, pccb, &capacity, &blksz)) {
                scsi_print_error(pccb);
                return -EINVAL;
        }
@@ -549,7 +557,7 @@ removable:
  * to the user if mode = 1
  */
 #if defined(CONFIG_DM_SCSI)
-static int do_scsi_scan_one(struct udevice *dev, int id, int lun, int mode)
+static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose)
 {
        int ret;
        struct udevice *bdev;
@@ -562,7 +570,7 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, int mode)
         * size, number of blocks) and other parameters (ids, type, ...)
         */
        scsi_init_dev_desc_priv(&bd);
-       if (scsi_detect_dev(id, lun, &bd))
+       if (scsi_detect_dev(dev, id, lun, &bd))
                return -ENODEV;
 
        /*
@@ -588,21 +596,42 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, int mode)
        memcpy(&bdesc->revision, &bd.revision,  sizeof(bd.revision));
        part_init(bdesc);
 
-       if (mode == 1) {
+       if (verbose) {
                printf("  Device %d: ", 0);
                dev_print(bdesc);
        }
        return 0;
 }
 
-int scsi_scan(int mode)
+int scsi_scan_dev(struct udevice *dev, bool verbose)
+{
+       struct scsi_platdata *uc_plat; /* scsi controller platdata */
+       int ret;
+       int i;
+       int lun;
+
+       /* probe SCSI controller driver */
+       ret = device_probe(dev);
+       if (ret)
+               return ret;
+
+       /* Get controller platdata */
+       uc_plat = dev_get_uclass_platdata(dev);
+
+       for (i = 0; i < uc_plat->max_id; i++)
+               for (lun = 0; lun < uc_plat->max_lun; lun++)
+                       do_scsi_scan_one(dev, i, lun, verbose);
+
+       return 0;
+}
+
+int scsi_scan(bool verbose)
 {
-       unsigned char i, lun;
        struct uclass *uc;
        struct udevice *dev; /* SCSI controller */
        int ret;
 
-       if (mode == 1)
+       if (verbose)
                printf("scanning bus for devices...\n");
 
        blk_unbind_all(IF_TYPE_SCSI);
@@ -612,30 +641,20 @@ int scsi_scan(int mode)
                return ret;
 
        uclass_foreach_dev(dev, uc) {
-               struct scsi_platdata *plat; /* scsi controller platdata */
-
-               /* probe SCSI controller driver */
-               ret = device_probe(dev);
+               ret = scsi_scan_dev(dev, verbose);
                if (ret)
                        return ret;
-
-               /* Get controller platdata */
-               plat = dev_get_platdata(dev);
-
-               for (i = 0; i < plat->max_id; i++)
-                       for (lun = 0; lun < plat->max_lun; lun++)
-                               do_scsi_scan_one(dev, i, lun, mode);
        }
 
        return 0;
 }
 #else
-int scsi_scan(int mode)
+int scsi_scan(bool verbose)
 {
        unsigned char i, lun;
        int ret;
 
-       if (mode == 1)
+       if (verbose)
                printf("scanning bus for devices...\n");
        for (i = 0; i < CONFIG_SYS_SCSI_MAX_DEVICE; i++)
                scsi_init_dev_desc(&scsi_dev_desc[i], i);
@@ -643,16 +662,16 @@ int scsi_scan(int mode)
        scsi_max_devs = 0;
        for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
                for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
-                       ret = scsi_detect_dev(i, lun,
+                       ret = scsi_detect_dev(NULL, i, lun,
                                              &scsi_dev_desc[scsi_max_devs]);
                        if (ret)
                                continue;
                        part_init(&scsi_dev_desc[scsi_max_devs]);
 
-                       if (mode == 1) {
+                       if (verbose) {
                                printf("  Device %d: ", 0);
                                dev_print(&scsi_dev_desc[scsi_max_devs]);
-                       } /* if mode */
+                       }
                        scsi_max_devs++;
                } /* next LUN */
        }
index e0e7024..c702304 100644 (file)
@@ -8,7 +8,6 @@
 #include <clk.h>
 #include <dm.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <ns16550.h>
 #include <serial.h>
 #include <watchdog.h>
@@ -395,7 +394,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
        int err;
 
        /* try Processor Local Bus device first */
-       addr = devfdt_get_addr(dev);
+       addr = dev_read_addr(dev);
 #if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI)
        if (addr == FDT_ADDR_T_NONE) {
                /* then try pci device */
index 200f4b9..f360534 100644 (file)
@@ -8,13 +8,13 @@
 #include <dm.h>
 #include <environment.h>
 #include <errno.h>
-#include <fdtdec.h>
 #include <os.h>
 #include <serial.h>
 #include <stdio_dev.h>
 #include <watchdog.h>
 #include <dm/lists.h>
 #include <dm/device-internal.h>
+#include <dm/of_access.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -27,11 +27,53 @@ static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
 #error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work"
 #endif
 
+static int serial_check_stdout(const void *blob, struct udevice **devp)
+{
+       int node;
+
+       /* Check for a chosen console */
+       node = fdtdec_get_chosen_node(blob, "stdout-path");
+       if (node < 0) {
+               const char *str, *p, *name;
+
+               /*
+                * Deal with things like
+                *      stdout-path = "serial0:115200n8";
+                *
+                * We need to look up the alias and then follow it to the
+                * correct node.
+                */
+               str = fdtdec_get_chosen_prop(blob, "stdout-path");
+               if (str) {
+                       p = strchr(str, ':');
+                       name = fdt_get_alias_namelen(blob, str,
+                                       p ? p - str : strlen(str));
+                       if (name)
+                               node = fdt_path_offset(blob, name);
+               }
+       }
+       if (node < 0)
+               node = fdt_path_offset(blob, "console");
+       if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, devp))
+               return 0;
+
+       /*
+        * If the console is not marked to be bound before relocation, bind it
+        * anyway.
+        */
+       if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
+                                       devp)) {
+               if (!device_probe(*devp))
+                       return 0;
+       }
+
+       return -ENODEV;
+}
+
 static void serial_find_console_or_panic(void)
 {
        const void *blob = gd->fdt_blob;
        struct udevice *dev;
-       int node;
 
        if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
                uclass_first_device(UCLASS_SERIAL, &dev);
@@ -40,43 +82,17 @@ static void serial_find_console_or_panic(void)
                        return;
                }
        } else if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
-               /* Check for a chosen console */
-               node = fdtdec_get_chosen_node(blob, "stdout-path");
-               if (node < 0) {
-                       const char *str, *p, *name;
-
-                       /*
-                        * Deal with things like
-                        *      stdout-path = "serial0:115200n8";
-                        *
-                        * We need to look up the alias and then follow it to
-                        * the correct node.
-                        */
-                       str = fdtdec_get_chosen_prop(blob, "stdout-path");
-                       if (str) {
-                               p = strchr(str, ':');
-                               name = fdt_get_alias_namelen(blob, str,
-                                               p ? p - str : strlen(str));
-                               if (name)
-                                       node = fdt_path_offset(blob, name);
-                       }
-               }
-               if (node < 0)
-                       node = fdt_path_offset(blob, "console");
-               if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node,
-                                                   &dev)) {
-                       gd->cur_serial_dev = dev;
-                       return;
-               }
+               /* Live tree has support for stdout */
+               if (of_live_active()) {
+                       struct device_node *np = of_get_stdout();
 
-               /*
-                * If the console is not marked to be bound before relocation,
-                * bind it anyway.
-                */
-               if (node > 0 &&
-                   !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
-                                   &dev)) {
-                       if (!device_probe(dev)) {
+                       if (np && !uclass_get_device_by_ofnode(UCLASS_SERIAL,
+                                       np_to_ofnode(np), &dev)) {
+                               gd->cur_serial_dev = dev;
+                               return;
+                       }
+               } else {
+                       if (!serial_check_stdout(blob, &dev)) {
                                gd->cur_serial_dev = dev;
                                return;
                        }
index 73fa82b..98d20c0 100644 (file)
@@ -244,7 +244,7 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat,
                              struct sandbox_flash_priv *priv, const void *buff,
                              int len)
 {
-       const struct SCSI_cmd_block *req = buff;
+       const struct scsi_cmd *req = buff;
 
        switch (*req->cmd) {
        case SCSI_INQUIRY: {
index 3697f49..fbd7bf7 100644 (file)
@@ -28,11 +28,13 @@ struct pwm_backlight_priv {
 static int pwm_backlight_enable(struct udevice *dev)
 {
        struct pwm_backlight_priv *priv = dev_get_priv(dev);
+       struct dm_regulator_uclass_platdata *plat;
        uint duty_cycle;
        int ret;
 
-       debug("%s: Enable '%s', regulator '%s'\n", __func__, dev->name,
-             priv->reg->name);
+       plat = dev_get_uclass_platdata(priv->reg);
+       debug("%s: Enable '%s', regulator '%s'/'%s'\n", __func__, dev->name,
+             priv->reg->name, plat->name);
        ret = regulator_set_enable(priv->reg, true);
        if (ret) {
                debug("%s: Cannot enable regulator for PWM '%s'\n", __func__,
@@ -59,12 +61,11 @@ static int pwm_backlight_enable(struct udevice *dev)
 static int pwm_backlight_ofdata_to_platdata(struct udevice *dev)
 {
        struct pwm_backlight_priv *priv = dev_get_priv(dev);
-       struct fdtdec_phandle_args args;
-       const void *blob = gd->fdt_blob;
-       int node = dev_of_offset(dev);
+       struct ofnode_phandle_args args;
        int index, ret, count, len;
        const u32 *cell;
 
+       debug("%s: start\n", __func__);
        ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
                                           "power-supply", &priv->reg);
        if (ret) {
@@ -79,14 +80,14 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev)
                if (ret != -ENOENT)
                        return ret;
        }
-       ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells",
-                                            0, 0, &args);
+       ret = dev_read_phandle_with_args(dev, "pwms", "#pwm-cells", 0, 0,
+                                        &args);
        if (ret) {
                debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret);
                return ret;
        }
 
-       ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm);
+       ret = uclass_get_device_by_ofnode(UCLASS_PWM, args.node, &priv->pwm);
        if (ret) {
                debug("%s: Cannot get PWM: ret=%d\n", __func__, ret);
                return ret;
@@ -94,8 +95,8 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev)
        priv->channel = args.args[0];
        priv->period_ns = args.args[1];
 
-       index = fdtdec_get_int(blob, node, "default-brightness-level", 255);
-       cell = fdt_getprop(blob, node, "brightness-levels", &len);
+       index = dev_read_u32_default(dev, "default-brightness-level", 255);
+       cell = dev_read_prop(dev, "brightness-levels", &len);
        count = len / sizeof(u32);
        if (cell && count > index) {
                priv->default_level = fdt32_to_cpu(cell[index]);
@@ -104,6 +105,7 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev)
                priv->default_level = index;
                priv->max_level = 255;
        }
+       debug("%s: done\n", __func__);
 
 
        return 0;
index baa95f6..c0ce199 100644 (file)
@@ -25,8 +25,10 @@ static int simple_panel_enable_backlight(struct udevice *dev)
        struct simple_panel_priv *priv = dev_get_priv(dev);
        int ret;
 
+       debug("%s: start, backlight = '%s'\n", __func__, priv->backlight->name);
        dm_gpio_set_value(&priv->enable, 1);
        ret = backlight_enable(priv->backlight);
+       debug("%s: done, ret = %d\n", __func__, ret);
        if (ret)
                return ret;
 
index bbbca13..47752b2 100644 (file)
@@ -471,7 +471,9 @@ static int tegra124_lcd_probe(struct udevice *dev)
        int ret;
 
        start = get_timer(0);
+       bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "lcd");
        ret = tegra124_lcd_init(dev, (void *)plat->base, VIDEO_BPP16);
+       bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD);
        debug("LCD init took %lu ms\n", get_timer(start));
        if (ret)
                printf("%s: Error %d\n", __func__, ret);
index e9a90b1..b5afd72 100644 (file)
@@ -77,6 +77,7 @@ static int vidconsole_back(struct udevice *dev)
                if (priv->ycur < 0)
                        priv->ycur = 0;
        }
+       video_sync(dev->parent);
 
        return 0;
 }
index a71bad1..9ad18f9 100644 (file)
@@ -1251,7 +1251,7 @@ int file_fat_detectfs(void)
        }
 
 #if defined(CONFIG_IDE) || \
-    defined(CONFIG_CMD_SATA) || \
+    defined(CONFIG_SATA) || \
     defined(CONFIG_SCSI) || \
     defined(CONFIG_CMD_USB) || \
     defined(CONFIG_MMC)
index 4876b41..818f344 100644 (file)
@@ -144,13 +144,25 @@ struct ahci_ioports {
        u32     rx_fis;
 };
 
-struct ahci_probe_ent {
+/**
+ * struct ahci_uc_priv - information about an AHCI controller
+ *
+ * When driver model is used, this is accessible using dev_get_uclass_priv(dev)
+ * where dev is the controller (although at present it sometimes stands alone).
+ */
+struct ahci_uc_priv {
 #if defined(CONFIG_DM_PCI) || defined(CONFIG_DM_SCSI)
+       /*
+        * TODO(sjg@chromium.org): Drop this once this structure is only used
+        * in a driver-model context (i.e. attached to a device with
+        * dev_get_uclass_priv()
+        */
        struct udevice *dev;
 #else
        pci_dev_t       dev;
 #endif
        struct ahci_ioports     port[AHCI_MAX_PORTS];
+       u16 *ataid[AHCI_MAX_PORTS];
        u32     n_ports;
        u32     hard_port_no;
        u32     host_flags;
@@ -167,4 +179,47 @@ struct ahci_probe_ent {
 int ahci_init(void __iomem *base);
 int ahci_reset(void __iomem *base);
 
+/**
+ * achi_init_one_dm() - set up a single AHCI port
+ *
+ * @dev: Controller to init
+ */
+int achi_init_one_dm(struct udevice *dev);
+
+/**
+ * achi_start_ports_dm() - start all AHCI ports for a controller
+ *
+ * @dev: Controller containing ports to start
+ */
+int achi_start_ports_dm(struct udevice *dev);
+
+/**
+ * ahci_init_dm() - init AHCI for a controller, finding all ports
+ *
+ * @dev: Device to init
+ */
+int ahci_init_dm(struct udevice *dev, void __iomem *base);
+
+/**
+ * ahci_bind_scsi() - bind a new SCSI bus as a child
+ *
+ * Note that the SCSI bus device will itself bind block devices
+ *
+ * @ahci_dev: AHCI parent device
+ * @devp: Returns new SCSI bus device
+ * @return 0 if OK, -ve on error
+ */
+int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp);
+
+/**
+ * ahci_probe_scsi() - probe and scan the attached SCSI bus
+ *
+ * Note that the SCSI device will itself bind block devices for any storage
+ * devices it finds.
+ *
+ * @ahci_dev: AHCI parent device
+ * @return 0 if OK, -ve on error
+ */
+int ahci_probe_scsi(struct udevice *ahci_dev);
+
 #endif
index b1f41ab..2874a78 100644 (file)
@@ -25,7 +25,6 @@
 #define CONFIG_CMD_READ                /* Read data from partition     */
 #define CONFIG_CMD_SANDBOX     /* sb command to access sandbox features */
 #define CONFIG_CMD_SAVES       /* save S record dump           */
-#define CONFIG_SCSI            /* SCSI Support                 */
 #define CONFIG_CMD_SDRAM       /* SDRAM DIMM SPD info printout */
 #define CONFIG_CMD_TERMINAL    /* built-in Serial Terminal     */
 #define CONFIG_CMD_UBIFS       /* UBIFS Support                */
index 4b2c493..d8dab8e 100644 (file)
 #define SCAN_DEV_FOR_EFI
 #endif
 
-#ifdef CONFIG_CMD_SATA
+#ifdef CONFIG_SATA
 #define BOOTENV_SHARED_SATA    BOOTENV_SHARED_BLKDEV(sata)
 #define BOOTENV_DEV_SATA       BOOTENV_DEV_BLKDEV
 #define BOOTENV_DEV_NAME_SATA  BOOTENV_DEV_NAME_BLKDEV
 #else
 #define BOOTENV_SHARED_SATA
 #define BOOTENV_DEV_SATA \
-       BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_CMD_SATA
+       BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_SATA
 #define BOOTENV_DEV_NAME_SATA \
-       BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_CMD_SATA
+       BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_SATA
 #endif
 
 #ifdef CONFIG_SCSI
index 2656c75..d1411f0 100644 (file)
@@ -48,7 +48,7 @@
 
 /* Rather than repeat this expression each time, add a define for it */
 #if defined(CONFIG_IDE) || \
-       defined(CONFIG_CMD_SATA) || \
+       defined(CONFIG_SATA) || \
        defined(CONFIG_SCSI) || \
        defined(CONFIG_CMD_USB) || \
        defined(CONFIG_CMD_PART) || \
index fbe033a..522f12c 100644 (file)
 
 #ifdef CONFIG_FSL_SATA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index 46f09d6..53e089a 100644 (file)
@@ -485,10 +485,6 @@ boards, we say we have two, but don't display a message if we find only one. */
        #define CONFIG_SUPPORT_VFAT
 #endif
 
-#ifdef CONFIG_SATA_SIL3114
-       #define CONFIG_CMD_SATA
-#endif
-
 #if defined(CONFIG_SATA_SIL3114) || defined(CONFIG_USB_STORAGE)
 #endif
 
index fcced0e..459efb5 100644 (file)
@@ -436,7 +436,6 @@ extern int board_pci_host_broken(void);
 
 #ifdef CONFIG_FSL_SATA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index 607b926..7afbc90 100644 (file)
 
 #ifdef CONFIG_FSL_SATA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index 18b6b4e..470bb72 100644 (file)
 
 #ifdef CONFIG_FSL_SATA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #if defined(CONFIG_TSEC_ENET)
index 3b62449..ffa8796 100644 (file)
@@ -352,7 +352,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #if defined(CONFIG_PCI)
     #define CONFIG_CMD_PCI
-    #define CONFIG_SCSI
 #endif
 
 /*
index 79e11bb..d8e0dfd 100644 (file)
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_SCSI
 #endif
 
 /*
index 2014450..1db3a63 100644 (file)
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_SCSI
 #endif
 
 #define CONFIG_WATCHDOG                        /* watchdog enabled */
index 7ec36eb..e87b111 100644 (file)
@@ -591,7 +591,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #if defined(CONFIG_PCI)
     #define CONFIG_CMD_PCI
-    #define CONFIG_SCSI
 #endif
 
 #undef CONFIG_WATCHDOG                 /* watchdog disabled */
index 220b070..0dc062a 100644 (file)
@@ -657,7 +657,6 @@ extern unsigned long get_sdram_size(void);
 #define CONFIG_SYS_SATA2               CONFIG_SYS_MPC85xx_SATA2_ADDR
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
-#define CONFIG_CMD_SATA
 #define CONFIG_LBA48
 #endif /* #ifdef CONFIG_FSL_SATA  */
 
index 3d12c84..2ee6c64 100644 (file)
 
 #ifdef CONFIG_FSL_SATA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_MMC
index b008e3d..967c83c 100644 (file)
@@ -548,7 +548,6 @@ unsigned long get_board_sys_clk(unsigned long dummy);
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_FMAN_ENET
index a6fa6a8..f192181 100644 (file)
@@ -12,7 +12,6 @@
 
 #define CONFIG_PCIE3
 
-#define CONFIG_CMD_SATA
 #define CONFIG_SATA_SIL
 #define CONFIG_SYS_SATA_MAX_DEVICE  2
 #define CONFIG_LIBATA
index 2209cfd..2e3a8c1 100644 (file)
@@ -628,7 +628,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_SATA1               CONFIG_SYS_MPC85xx_SATA1_ADDR
 #define CONFIG_SYS_SATA1_FLAGS         FLAGS_DMA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index 3953145..86f7880 100644 (file)
@@ -518,7 +518,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index 0035e67..350daca 100644 (file)
@@ -628,7 +628,6 @@ $(SRCTREE)/board/freescale/t104xrdb/t1042d4_sd_rcw.cfg
 #define CONFIG_SYS_SATA1_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index e792ec5..9edf190 100644 (file)
@@ -695,7 +695,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_SATA2               CONFIG_SYS_MPC85xx_SATA2_ADDR
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index fdafeeb..0e70aa8 100644 (file)
@@ -645,7 +645,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_SATA2               CONFIG_SYS_MPC85xx_SATA2_ADDR
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 /*
index dc3ebfa..f69746b 100644 (file)
@@ -489,7 +489,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_FMAN_ENET
index 0d9cdfb..ed3b0f7 100644 (file)
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_FMAN_ENET
@@ -671,7 +670,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_FMAN_ENET
index 8579290..9a7aa81 100644 (file)
 
 #define CONFIG_ENV_OVERWRITE
 
-#define CONFIG_CMD_SATA
 #define CONFIG_SATA_SIL
 #define CONFIG_SYS_SATA_MAX_DEVICE     2
 #define CONFIG_LIBATA
index f320792..66ee167 100644 (file)
@@ -39,7 +39,6 @@
 #define CONFIG_MXC_OCOTP
 
 /* SATA Configs */
-#define CONFIG_CMD_SATA
 #define CONFIG_DWC_AHSATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     1
 #define CONFIG_DWC_AHSATA_PORT_ID      0
index 7a42d79..98ce6c5 100644 (file)
@@ -99,7 +99,6 @@
 #define CONFIG_OMAP_USB3PHY1_HOST
 
 /* SATA */
-#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 8be586b..b4006a3 100644 (file)
 #define CONFIG_SUPPORT_EMMC_BOOT       /* eMMC specific */
 #define CONFIG_BOUNCE_BUFFER
 
-#ifdef CONFIG_MX6Q
-#define CONFIG_CMD_SATA
-#endif
-
 /*
  * SATA Configs
  */
index cad1357..5d797b4 100644 (file)
@@ -95,7 +95,6 @@
 #define CONFIG_IMX_HDMI
 
 /* SATA */
-#define CONFIG_CMD_SATA
 #define CONFIG_DWC_AHSATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     1
 #define CONFIG_DWC_AHSATA_PORT_ID      0
index dd8010c..1d9c165 100644 (file)
 #define CONFIG_SYS_I2C_EEPROM_BUS      2
 
 /* SATA */
-#define CONFIG_CMD_SATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     1
 #define CONFIG_LIBATA
 #define CONFIG_LBA48
index 14042ad..3647573 100644 (file)
@@ -49,7 +49,6 @@
 #define CONFIG_SPL_SATA_BOOT_DEVICE            0
 #define CONFIG_SYS_SATA_FAT_BOOT_PARTITION     1
 
-#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 6641408..072650d 100644 (file)
  */
 #define CONFIG_LIBATA
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 
 #define CONFIG_FSL_SATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     2
index a04af31..f10cdda 100644 (file)
@@ -51,7 +51,6 @@
  * SATA/SCSI/AHCI configuration
  */
 #define CONFIG_LIBATA
-#define CONFIG_SCSI
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
 #define CONFIG_SYS_SCSI_MAX_SCSI_ID    2
index 7bbe31c..92e6ee0 100644 (file)
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_FMAN_ENET
index a23da19..6079540 100644 (file)
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_FMAN_ENET
index 0890a4d..292bfb8 100644 (file)
@@ -25,7 +25,6 @@
  * Commands configuration
  */
 #define CONFIG_CMD_PCI
-#define CONFIG_SCSI
 
 /* I2C */
 #define CONFIG_SYS_I2C
index 821aa9d..187ead3 100644 (file)
@@ -27,7 +27,6 @@
  */
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SATA
 
 /* I2C */
 #define CONFIG_SYS_I2C
index d6c4a71..d2f7c7c 100644 (file)
 #define CONFIG_OMAP_USB2PHY2_HOST
 
 /* SATA */
-#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 5626061..9dcb481 100644 (file)
@@ -16,7 +16,6 @@
 #undef CONFIG_ENV_IS_IN_SPI_FLASH
 #define CONFIG_ENV_IS_NOWHERE
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_SCSI
 #undef CONFIG_INTEL_ICH6_GPIO
 #undef CONFIG_USB_EHCI_PCI
 
index dcbaade..00c5434 100644 (file)
@@ -24,7 +24,6 @@
 
 /* SATA is not supported in Quark SoC */
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_SCSI
 
 /* 10/100M Ethernet support */
 #define CONFIG_DESIGNWARE_ETH
index 2227eea..de08f2c 100644 (file)
 /*
  * SATA Configs
  */
-#define CONFIG_CMD_SATA
 #ifdef CONFIG_CMD_SATA
   #define CONFIG_DWC_AHSATA
   #define CONFIG_SYS_SATA_MAX_DEVICE   1
index e15b572..533d3e3 100644 (file)
@@ -46,7 +46,6 @@
 /*
  * Command line configuration.
  */
-#define CONFIG_SCSI
 
 #define CONFIG_BOOT_RETRY_TIME         -1
 #define CONFIG_RESET_TO_RETRY
index 5b8500b..9e6c7a7 100644 (file)
 
 /* SATA */
 #define CONFIG_LIBATA
-#define        CONFIG_SCSI
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
 #define CONFIG_CMD_SCSI
index 276fe10..0705bc5 100644 (file)
@@ -51,7 +51,6 @@
 
 /* SATA */
 #define CONFIG_LIBATA
-#define        CONFIG_SCSI
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
 #define CONFIG_CMD_SCSI
index 04d74ac..87ca36a 100644 (file)
@@ -98,7 +98,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_SCSI
 
 /* EEPROM */
 #define CONFIG_ID_EEPROM
index 5d2e819..77619ab 100644 (file)
@@ -153,7 +153,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_SCSI
 
 /* EEPROM */
 #define CONFIG_ID_EEPROM
index 6f649a6..8a6b4e6 100644 (file)
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_SCSI
 
 #define CONFIG_SYS_SATA                                AHCI_BASE_ADDR
 
index 8a8ee9d..5e1867d 100644 (file)
@@ -50,7 +50,6 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_SCSI
 
 #define CONFIG_SYS_SATA1                       AHCI_BASE_ADDR1
 #define CONFIG_SYS_SATA2                       AHCI_BASE_ADDR2
index 2dab065..e8aacd3 100644 (file)
@@ -68,7 +68,6 @@ unsigned long get_board_sys_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_SCSI
 
 #define CONFIG_SYS_SATA1                       AHCI_BASE_ADDR1
 #define CONFIG_SYS_SATA2                       AHCI_BASE_ADDR2
index 5181225..a92c228 100644 (file)
@@ -22,7 +22,6 @@
  */
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_NAND_TRIMFFS
-#define CONFIG_CMD_SATA
 
 /*
  * Memory configurations
index 5408490..eb80ac5 100644 (file)
 /*
  * SATA/SCSI/AHCI configuration
  */
-#define CONFIG_SCSI
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
 #define CONFIG_LIBATA
index 9d3aeef..ac116ed 100644 (file)
 /*
  * SATA/SCSI/AHCI configuration
  */
-#define CONFIG_SCSI
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
 #define CONFIG_LIBATA
index 1b6d868..c82e426 100644 (file)
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 0
 
-#define CONFIG_CMD_SATA
 #ifdef CONFIG_CMD_SATA
        #define CONFIG_DWC_AHSATA
        #define CONFIG_SYS_SATA_MAX_DEVICE      1
index 00b84f7..576b7b0 100644 (file)
 #define CONFIG_SYS_FSL_ESDHC_ADDR      0
 #define CONFIG_SYS_FSL_USDHC_NUM       2
 
-#ifdef CONFIG_MX6Q
-#define CONFIG_CMD_SATA
-#endif
-
 /*
  * SATA Configs
  */
index 1f1bf15..0411598 100644 (file)
@@ -18,7 +18,6 @@
 
 /* U-Boot Commands */
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SATA
 
 /* U-Boot general configurations */
 
index e7fac6d..15d06bb 100644 (file)
@@ -66,7 +66,6 @@
 
 #define CONSOLEDEV             "ttyO2"
 
-#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 0582fa3..7aeae7b 100644 (file)
 #define CONFIG_MXC_USB_PORTSC   (PORT_PTS_UTMI | PORT_PTS_PTW)
 #define CONFIG_USB_MAX_CONTROLLER_COUNT 2
 
-#ifdef CONFIG_MX6Q
-#define CONFIG_CMD_SATA
-#endif
-
 /*
  * SATA Configs
  */
index 71b4f40..a72a57c 100644 (file)
 #define CONFIG_TSEC_ENET       /* tsec ethernet support */
 #define CONFIG_ENV_OVERWRITE
 
-#define CONFIG_CMD_SATA
 #define CONFIG_SATA_SIL
 #define CONFIG_SYS_SATA_MAX_DEVICE     2
 #define CONFIG_LIBATA
index fd644f2..dffb15a 100644 (file)
@@ -50,7 +50,6 @@
 #define CONFIG_TSEC_ENET       /* tsec ethernet support */
 #define CONFIG_ENV_OVERWRITE
 
-#define CONFIG_CMD_SATA
 #define CONFIG_SATA_SIL3114
 #define CONFIG_SYS_SATA_MAX_DEVICE     2
 #define CONFIG_LIBATA
index 3509c2f..05eb5eb 100644 (file)
@@ -39,7 +39,6 @@
 #define CONFIG_ATAPI
 
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_SCSI
 #else
 #define CONFIG_SCSI_DEV_LIST           \
        {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_AHCI}
index 31ceb54..1e8404c 100644 (file)
@@ -41,6 +41,7 @@
 
 #define CONFIG_SYS_LONGHELP                    /* #undef to save memory */
 #define CONFIG_SYS_CBSIZE              1024    /* Console I/O Buffer Size */
+#define CONFIG_DISPLAY_BOARDINFO_LATE
 
 /* Print Buffer Size */
 #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
 #define CONFIG_SYS_ATA_STRIDE          4
 #endif
 
-#define CONFIG_SCSI
 #define CONFIG_SCSI_AHCI_PLAT
 #define CONFIG_SYS_SCSI_MAX_DEVICE     2
 #define CONFIG_SYS_SCSI_MAX_SCSI_ID    8
 #define CONFIG_SYS_SCSI_MAX_LUN                4
 
-#define CONFIG_CMD_SATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     2
 
 #define CONFIG_SYSTEMACE
index 9b514ff..fefd58f 100644 (file)
 #define CONFIG_SYS_SCSI_MAX_LUN                1
 #define CONFIG_SYS_SCSI_MAX_DEVICE     (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
                                         CONFIG_SYS_SCSI_MAX_LUN)
-#define CONFIG_SCSI
 #endif
 
 #define CONFIG_SETUP_MEMORY_TAGS
index 260cdee..6d8c78f 100644 (file)
 #define CONFIG_SYS_SATA2_FLAGS         FLAGS_DMA
 
 #define CONFIG_LBA48
-#define CONFIG_CMD_SATA
 #endif
 
 #ifdef CONFIG_FMAN_ENET
index 84ca1c4..79f6b16 100644 (file)
@@ -80,7 +80,6 @@
 #endif
 
 /* SATA */
-#define CONFIG_CMD_SATA
 #ifdef CONFIG_CMD_SATA
 #define CONFIG_DWC_AHSATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     1
index 27cae9d..94e207c 100644 (file)
@@ -23,7 +23,6 @@
 /*
  * Commands configuration
  */
-#define CONFIG_CMD_SATA
 
 /*
  * The debugging version enables USB support via defconfig.
index d84aa16..aef4563 100644 (file)
@@ -24,7 +24,6 @@
 
 /* SATA Configs */
 
-#define CONFIG_CMD_SATA
 #ifdef CONFIG_CMD_SATA
 #define CONFIG_DWC_AHSATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     1
index 2a6c6fb..afc5edf 100644 (file)
@@ -24,7 +24,6 @@
 
 /* SATA Configs */
 
-#define CONFIG_CMD_SATA
 #ifdef CONFIG_CMD_SATA
 #define CONFIG_DWC_AHSATA
 #define CONFIG_SYS_SATA_MAX_DEVICE     1
index a5ed852..d104449 100644 (file)
@@ -71,7 +71,6 @@
  * Command line configuration.
  */
 #define CONFIG_CMD_PCI
-#define CONFIG_SCSI
 
 #define CONFIG_CMD_ZBOOT
 
index 86a4579..c7fcd86 100644 (file)
 #define CONFIG_SYS_SCSI_MAX_LUN                1
 #define CONFIG_SYS_SCSI_MAX_DEVICE     (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
                                         CONFIG_SYS_SCSI_MAX_LUN)
-#define CONFIG_SCSI
 #endif
 
 #define CONFIG_SYS_BOOTM_LEN   (60 * 1024 * 1024)
index 3d37f6a..cea29ed 100644 (file)
@@ -42,6 +42,18 @@ void console_record_reset(void);
  */
 void console_record_reset_enable(void);
 
+/**
+ * console_announce_r() - print a U-Boot console on non-serial consoles
+ *
+ * When U-Boot starts up with a display it generally does not announce itself
+ * on the display. The banner is instead emitted on the UART before relocation.
+ * This function prints a banner on devices which (we assume) did not receive
+ * it before relocation.
+ *
+ * @return 0 (meaning no errors)
+ */
+int console_announce_r(void);
+
 /*
  * CONSOLE multiplexing.
  */
index ac44c45..d9c8f6d 100644 (file)
@@ -56,4 +56,23 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
  */
 int display_options(void);
 
+/* Suggested length of the buffer to pass to display_options_get_banner() */
+#define DISPLAY_OPTIONS_BANNER_LENGTH  200
+
+/**
+ * display_options_get_banner() - Get the U-Boot banner as a string
+ *
+ * This returns the U-Boot banner string
+ *
+ * @newlines: true to include two newlines at the start
+ * @buf: place to put string
+ * @size: Size of buf (string is truncated to fit)
+ * @return buf
+ */
+char *display_options_get_banner(bool newlines, char *buf, int size);
+
+/* This function is used for testing only */
+char *display_options_get_banner_priv(bool newlines, const char *build_tag,
+                                     char *buf, int size);
+
 #endif
index 142f0f4..c5ea391 100644 (file)
@@ -61,6 +61,26 @@ int of_n_addr_cells(const struct device_node *np);
 int of_n_size_cells(const struct device_node *np);
 
 /**
+ * of_simple_addr_cells() - Get the address cells property in a node
+ *
+ * This function matches fdt_address_cells().
+ *
+ * @np: Node pointer to check
+ * @return value of #address-cells property in this node, or 2 if none
+ */
+int of_simple_addr_cells(const struct device_node *np);
+
+/**
+ * of_simple_size_cells() - Get the size cells property in a node
+ *
+ * This function matches fdt_size_cells().
+ *
+ * @np: Node pointer to check
+ * @return value of #size-cells property in this node, or 2 if none
+ */
+int of_simple_size_cells(const struct device_node *np);
+
+/**
  * of_find_property() - find a property in a node
  *
  * @np: Pointer to device node holding property
@@ -261,6 +281,24 @@ static inline int of_property_read_string_index(const struct device_node *np,
 }
 
 /**
+ * of_property_count_strings() - Find and return the number of strings from a
+ * multiple strings property.
+ * @np:                device node from which the property value is to be read.
+ * @propname:  name of the property to be searched.
+ *
+ * Search for a property in a device tree node and retrieve the number of null
+ * terminated string contain in it. Returns the number of strings on
+ * success, -EINVAL if the property does not exist, -ENODATA if property
+ * does not have a value, and -EILSEQ if the string is not null-terminated
+ * within the length of the property data.
+ */
+static inline int of_property_count_strings(const struct device_node *np,
+                                           const char *propname)
+{
+       return of_property_read_string_helper(np, propname, NULL, 0, 0);
+}
+
+/**
  * of_parse_phandle - Resolve a phandle property to a device_node pointer
  * @np: Pointer to device node holding phandle property
  * @phandle_name: Name of property holding a phandle value
index 149622a..15ad519 100644 (file)
@@ -359,7 +359,7 @@ int ofnode_stringlist_search(ofnode node, const char *propname,
                             const char *string);
 
 /**
- * fdt_stringlist_get() - obtain the string at a given index in a string list
+ * ofnode_read_string_index() - obtain an indexed string from a string list
  *
  * Note that this will successfully extract strings from properties with
  * non-NUL-terminated values. For example on small-valued cell properties
@@ -380,6 +380,16 @@ int ofnode_read_string_index(ofnode node, const char *propname, int index,
                             const char **outp);
 
 /**
+ * ofnode_read_string_count() - find the number of strings in a string list
+ *
+ * @node: node to check
+ * @propname: name of the property containing the string list
+ * @return:
+ *   number of strings in the list, or -ve error value if not found
+ */
+int ofnode_read_string_count(ofnode node, const char *property);
+
+/**
  * ofnode_parse_phandle_with_args() - Find a node pointed by phandle in a list
  *
  * This function is useful to parse lists of phandles and their arguments.
@@ -463,14 +473,14 @@ int ofnode_decode_display_timing(ofnode node, int index,
                                 struct display_timing *config);
 
 /**
- * ofnode_read_prop()- - read a node property
+ * ofnode_get_property()- - get a pointer to the value of a node property
  *
  * @node: node to read
  * @propname: property to read
  * @lenp: place to put length on success
  * @return pointer to property, or NULL if not found
  */
-const u32 *ofnode_read_prop(ofnode node, const char *propname, int *lenp);
+const void *ofnode_get_property(ofnode node, const char *propname, int *lenp);
 
 /**
  * ofnode_is_available() - check if a node is marked available
@@ -552,6 +562,26 @@ int ofnode_read_addr_cells(ofnode node);
 int ofnode_read_size_cells(ofnode node);
 
 /**
+ * ofnode_read_simple_addr_cells() - Get the address cells property in a node
+ *
+ * This function matches fdt_address_cells().
+ *
+ * @np: Node pointer to check
+ * @return value of #address-cells property in this node, or 2 if none
+ */
+int ofnode_read_simple_addr_cells(ofnode node);
+
+/**
+ * ofnode_read_simple_size_cells() - Get the size cells property in a node
+ *
+ * This function matches fdt_size_cells().
+ *
+ * @np: Node pointer to check
+ * @return value of #size-cells property in this node, or 2 if none
+ */
+int ofnode_read_simple_size_cells(ofnode node);
+
+/**
  * ofnode_pre_reloc() - check if a node should be bound before relocation
  *
  * Device tree nodes can be marked as needing-to-be-bound in the loader stages
index 8c9846e..b86a2f5 100644 (file)
@@ -14,6 +14,8 @@
 #include <dm/ofnode.h>
 #include <dm/uclass.h>
 
+struct resource;
+
 #if CONFIG_IS_ENABLED(OF_LIVE)
 static inline const struct device_node *dev_np(struct udevice *dev)
 {
@@ -42,6 +44,16 @@ static inline bool dev_of_valid(struct udevice *dev)
        return ofnode_valid(dev_ofnode(dev));
 }
 
+/**
+ * dev_read_resource() - obtain an indexed resource from a device.
+ *
+ * @dev: devuce to examine
+ * @index index of the resource to retrieve (0 = first)
+ * @res returns the resource
+ * @return 0 if ok, negative on error
+ */
+int dev_read_resource(struct udevice *dev, uint index, struct resource *res);
+
 #ifndef CONFIG_DM_DEV_READ_INLINE
 /**
  * dev_read_u32_default() - read a 32-bit integer from a device's DT property
@@ -219,6 +231,26 @@ int dev_read_addr_cells(struct udevice *dev);
 int dev_read_size_cells(struct udevice *dev);
 
 /**
+ * dev_read_addr_cells() - Get the address cells property in a node
+ *
+ * This function matches fdt_address_cells().
+ *
+ * @dev: devioe to check
+ * @return number of address cells this node uses
+ */
+int dev_read_simple_addr_cells(struct udevice *dev);
+
+/**
+ * dev_read_size_cells() - Get the size cells property in a node
+ *
+ * This function matches fdt_size_cells().
+ *
+ * @dev: devioe to check
+ * @return number of size cells this node uses
+ */
+int dev_read_simple_size_cells(struct udevice *dev);
+
+/**
  * dev_read_phandle() - Get the phandle from a device
  *
  * @dev: device to check
@@ -303,6 +335,19 @@ ofnode dev_read_next_subnode(ofnode node);
 const uint8_t *dev_read_u8_array_ptr(struct udevice *dev, const char *propname,
                                     size_t sz);
 
+/**
+ * dev_read_enabled() - check whether a node is enabled
+ *
+ * This looks for a 'status' property. If this exists, then returns 1 if
+ * the status is 'ok' and 0 otherwise. If there is no status property,
+ * it returns 1 on the assumption that anything mentioned should be enabled
+ * by default.
+ *
+ * @dev: device to examine
+ * @return integer value 0 (not enabled) or 1 (enabled)
+ */
+int dev_read_enabled(struct udevice *dev);
+
 #else /* CONFIG_DM_DEV_READ_INLINE is enabled */
 
 static inline int dev_read_u32_default(struct udevice *dev,
@@ -373,11 +418,23 @@ static inline int dev_read_phandle_with_args(struct udevice *dev,
 
 static inline int dev_read_addr_cells(struct udevice *dev)
 {
+       /* NOTE: this call should walk up the parent stack */
        return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev));
 }
 
 static inline int dev_read_size_cells(struct udevice *dev)
 {
+       /* NOTE: this call should walk up the parent stack */
+       return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev));
+}
+
+static inline int dev_read_simple_addr_cells(struct udevice *dev)
+{
+       return fdt_address_cells(gd->fdt_blob, dev_of_offset(dev));
+}
+
+static inline int dev_read_simple_size_cells(struct udevice *dev)
+{
        return fdt_size_cells(gd->fdt_blob, dev_of_offset(dev));
 }
 
@@ -389,7 +446,7 @@ static inline int dev_read_phandle(struct udevice *dev)
 static inline const u32 *dev_read_prop(struct udevice *dev,
                                       const char *propname, int *lenp)
 {
-       return ofnode_read_prop(dev_ofnode(dev), propname, lenp);
+       return ofnode_get_property(dev_ofnode(dev), propname, lenp);
 }
 
 static inline int dev_read_alias_seq(struct udevice *dev, int *devnump)
@@ -420,6 +477,11 @@ static inline const uint8_t *dev_read_u8_array_ptr(struct udevice *dev,
        return ofnode_read_u8_array_ptr(dev_ofnode(dev), propname, sz);
 }
 
+static inline int dev_read_enabled(struct udevice *dev)
+{
+       return fdtdec_get_is_enabled(gd->fdt_blob, dev_of_offset(dev));
+}
+
 #endif /* CONFIG_DM_DEV_READ_INLINE */
 
 /**
index 1f7e32c..2e6498b 100644 (file)
@@ -18,6 +18,7 @@ enum uclass_id {
        UCLASS_TEST,
        UCLASS_TEST_FDT,
        UCLASS_TEST_BUS,
+       UCLASS_TEST_PROBE,
        UCLASS_SPI_EMUL,        /* sandbox SPI device emulator */
        UCLASS_I2C_EMUL,        /* sandbox I2C device emulator */
        UCLASS_PCI_EMUL,        /* sandbox PCI device emulator */
index 7f5a130..1818849 100644 (file)
@@ -241,8 +241,13 @@ int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv,
  *
  * The device returned is probed if necessary, and ready for use
  *
+ * This function is useful to start iterating through a list of devices which
+ * are functioning correctly and can be probed.
+ *
  * @id: Uclass ID to look up
- * @devp: Returns pointer to the first device in that uclass, or NULL if none
+ * @devp: Returns pointer to the first device in that uclass if no error
+ * occurred, or NULL if there is no first device, or an error occurred with
+ * that device.
  * @return 0 if OK (found or not found), other -ve on error
  */
 int uclass_first_device(enum uclass_id id, struct udevice **devp);
@@ -263,13 +268,48 @@ int uclass_first_device_err(enum uclass_id id, struct udevice **devp);
  *
  * The device returned is probed if necessary, and ready for use
  *
+ * This function is useful to start iterating through a list of devices which
+ * are functioning correctly and can be probed.
+ *
  * @devp: On entry, pointer to device to lookup. On exit, returns pointer
- * to the next device in the same uclass, or NULL if none
+ * to the next device in the uclass if no error occurred, or NULL if there is
+ * no next device, or an error occurred with that next device.
  * @return 0 if OK (found or not found), other -ve on error
  */
 int uclass_next_device(struct udevice **devp);
 
 /**
+ * uclass_first_device() - Get the first device in a uclass
+ *
+ * The device returned is probed if necessary, and ready for use
+ *
+ * This function is useful to start iterating through a list of devices which
+ * are functioning correctly and can be probed.
+ *
+ * @id: Uclass ID to look up
+ * @devp: Returns pointer to the first device in that uclass, or NULL if there
+ * is no first device
+ * @return 0 if OK (found or not found), other -ve on error. If an error occurs
+ * it is still possible to move to the next device.
+ */
+int uclass_first_device_check(enum uclass_id id, struct udevice **devp);
+
+/**
+ * uclass_next_device() - Get the next device in a uclass
+ *
+ * The device returned is probed if necessary, and ready for use
+ *
+ * This function is useful to start iterating through a list of devices which
+ * are functioning correctly and can be probed.
+ *
+ * @devp: On entry, pointer to device to lookup. On exit, returns pointer
+ * to the next device in the uclass if any
+ * @return 0 if OK (found or not found), other -ve on error. If an error occurs
+ * it is still possible to move to the next device.
+ */
+int uclass_next_device_check(struct udevice **devp);
+
+/**
  * uclass_resolve_seq() - Resolve a device's sequence number
  *
  * On entry dev->seq is -1, and dev->req_seq may be -1 (to allocate a
index 190dacd..7173912 100644 (file)
@@ -7,7 +7,7 @@
  #ifndef _SCSI_H
  #define _SCSI_H
 
-typedef struct SCSI_cmd_block{
+struct scsi_cmd {
        unsigned char           cmd[16];                                        /* command                                 */
        /* for request sense */
        unsigned char           sense_buf[64]
@@ -27,7 +27,7 @@ typedef struct SCSI_cmd_block{
        unsigned long           trans_bytes;                    /* tranfered bytes              */
 
        unsigned int            priv;
-}ccb;
+};
 
 /*-----------------------------------------------------------
 **
@@ -158,27 +158,6 @@ typedef struct SCSI_cmd_block{
 #define SCSI_WRITE_LONG        0x3F            /* Write Long (O) */
 #define SCSI_WRITE_SAME        0x41            /* Write Same (O) */
 
-
-/****************************************************************************
- * decleration of functions which have to reside in the LowLevel Part Driver
- */
-
-void scsi_print_error(ccb *pccb);
-int scsi_exec(ccb *pccb);
-void scsi_bus_reset(void);
-#if !defined(CONFIG_DM_SCSI)
-void scsi_low_level_init(int busdevfunc);
-#else
-void scsi_low_level_init(int busdevfunc, struct udevice *dev);
-#endif
-
-/***************************************************************************
- * functions residing inside cmd_scsi.c
- */
-void scsi_init(void);
-int scsi_scan(int mode);
-
-#if defined(CONFIG_DM_SCSI)
 /**
  * struct scsi_platdata - stores information about SCSI controller
  *
@@ -191,6 +170,66 @@ struct scsi_platdata {
        unsigned long max_lun;
        unsigned long max_id;
 };
+
+/* Operations for SCSI */
+struct scsi_ops {
+       /**
+        * exec() - execute a command
+        *
+        * @dev:        SCSI bus
+        * @cmd:        Command to execute
+        * @return 0 if OK, -ve on error
+        */
+       int (*exec)(struct udevice *dev, struct scsi_cmd *cmd);
+
+       /**
+        * bus_reset() - reset the bus
+        *
+        * @dev:        SCSI bus to reset
+        * @return 0 if OK, -ve on error
+        */
+       int (*bus_reset)(struct udevice *dev);
+};
+
+#define scsi_get_ops(dev)        ((struct scsi_ops *)(dev)->driver->ops)
+
+extern struct scsi_ops scsi_ops;
+
+/**
+ * scsi_exec() - execute a command
+ *
+ * @dev:       SCSI bus
+ * @cmd:       Command to execute
+ * @return 0 if OK, -ve on error
+ */
+int scsi_exec(struct udevice *dev, struct scsi_cmd *cmd);
+
+/**
+ * scsi_bus_reset() - reset the bus
+ *
+ * @dev:       SCSI bus to reset
+ * @return 0 if OK, -ve on error
+ */
+int scsi_bus_reset(struct udevice *dev);
+
+/**
+ * scsi_scan() - Scan all SCSI controllers for available devices
+ *
+ * @vebose: true to show information about each device found
+ */
+int scsi_scan(bool verbose);
+
+/**
+ * scsi_scan_dev() - scan a SCSI bus and create devices
+ *
+ * @dev:       SCSI bus
+ * @verbose:   true to show information about each device found
+ */
+int scsi_scan_dev(struct udevice *dev, bool verbose);
+
+#ifndef CONFIG_DM_SCSI
+void scsi_low_level_init(int busdevfunc);
+void scsi_init(void);
 #endif
 
 #define SCSI_IDENTIFY                                  0xC0  /* not used */
index 29343fc..4ea27ca 100644 (file)
 #include <linux/ctype.h>
 #include <asm/io.h>
 
-int display_options (void)
+char *display_options_get_banner_priv(bool newlines, const char *build_tag,
+                                     char *buf, int size)
 {
-#if defined(BUILD_TAG)
-       printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
-#else
-       printf ("\n\n%s\n\n", version_string);
+       int len;
+
+       len = snprintf(buf, size, "%s%s", newlines ? "\n\n" : "",
+                      version_string);
+       if (build_tag && len < size)
+               len += snprintf(buf + len, size - len, ", Build: %s",
+                               build_tag);
+       if (len > size - 3)
+               len = size - 3;
+       strcpy(buf + len, "\n\n");
+
+       return buf;
+}
+
+#ifndef BUILD_TAG
+#define BUILD_TAG NULL
 #endif
+
+char *display_options_get_banner(bool newlines, char *buf, int size)
+{
+       return display_options_get_banner_priv(newlines, BUILD_TAG, buf, size);
+}
+
+int display_options(void)
+{
+       char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
+
+       display_options_get_banner(true, buf, sizeof(buf));
+       printf("%s", buf);
+
        return 0;
 }
 
index 51927f9..f351483 100644 (file)
@@ -216,9 +216,12 @@ static void *unflatten_dt_node(const void *blob, void *mem, int *poffset,
        *poffset = fdt_next_node(blob, *poffset, &depth);
        if (depth < 0)
                depth = 0;
-       while (*poffset > 0 && depth > old_depth)
+       while (*poffset > 0 && depth > old_depth) {
                mem = unflatten_dt_node(blob, mem, poffset, np, NULL,
                                        fpsize, dryrun);
+               if (!mem)
+                       return NULL;
+       }
 
        if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND) {
                debug("unflatten: error %d processing FDT\n", *poffset);
@@ -286,6 +289,8 @@ static int unflatten_device_tree(const void *blob,
        start = 0;
        size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL,
                                                0, true);
+       if (!size)
+               return -EFAULT;
        size = ALIGN(size, 4);
 
        debug("  size is %lx, allocating...\n", size);
index 1ab6101..e261d02 100644 (file)
@@ -312,7 +312,6 @@ CONFIG_CMD_READ
 CONFIG_CMD_REGINFO
 CONFIG_CMD_REISER
 CONFIG_CMD_SANDBOX
-CONFIG_CMD_SATA
 CONFIG_CMD_SAVES
 CONFIG_CMD_SCSI
 CONFIG_CMD_SDRAM
@@ -2039,12 +2038,10 @@ CONFIG_SCIF_A
 CONFIG_SCIF_CONSOLE
 CONFIG_SCIF_EXT_CLOCK
 CONFIG_SCIF_USE_EXT_CLK
-CONFIG_SCSI
 CONFIG_SCSI_AHCI
 CONFIG_SCSI_AHCI_PLAT
 CONFIG_SCSI_DEV_ID
 CONFIG_SCSI_DEV_LIST
-CONFIG_SCSI_SYM53C8XX
 CONFIG_SC_TIMER_CLK
 CONFIG_SDCARD
 CONFIG_SDRAM_OFFSET_FOR_RT
@@ -4626,7 +4623,6 @@ CONFIG_SYS_SCSI_MAX_DEVICE
 CONFIG_SYS_SCSI_MAX_LUN
 CONFIG_SYS_SCSI_MAX_SCSI_ID
 CONFIG_SYS_SCSI_SPIN_UP_TIME
-CONFIG_SYS_SCSI_SYM53C8XX_CCF
 CONFIG_SYS_SDHC_CLK
 CONFIG_SYS_SDHC_CLK_2_PLL
 CONFIG_SYS_SDIO0
index 0f5de57..6305afb 100644 (file)
@@ -8,4 +8,5 @@ obj-$(CONFIG_UNIT_TEST) += cmd_ut.o
 obj-$(CONFIG_UNIT_TEST) += ut.o
 obj-$(CONFIG_SANDBOX) += command_ut.o
 obj-$(CONFIG_SANDBOX) += compression.o
+obj-$(CONFIG_SANDBOX) += print_ut.o
 obj-$(CONFIG_UT_TIME) += time_ut.o
index 987a265..dcc2ef8 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/io.h>
 #include <dm/test.h>
 #include <dm/root.h>
+#include <dm/device-internal.h>
 #include <dm/uclass-internal.h>
 #include <dm/util.h>
 #include <test/ut.h>
@@ -99,6 +100,36 @@ UCLASS_DRIVER(testfdt) = {
        .flags          = DM_UC_FLAG_SEQ_ALIAS,
 };
 
+struct dm_testprobe_pdata {
+       int probe_err;
+};
+
+static int testprobe_drv_probe(struct udevice *dev)
+{
+       struct dm_testprobe_pdata *pdata = dev_get_platdata(dev);
+
+       return pdata->probe_err;
+}
+
+static const struct udevice_id testprobe_ids[] = {
+       { .compatible = "denx,u-boot-probe-test" },
+       { }
+};
+
+U_BOOT_DRIVER(testprobe_drv) = {
+       .name   = "testprobe_drv",
+       .of_match       = testprobe_ids,
+       .id     = UCLASS_TEST_PROBE,
+       .probe  = testprobe_drv_probe,
+       .platdata_auto_alloc_size       = sizeof(struct dm_testprobe_pdata),
+};
+
+UCLASS_DRIVER(testprobe) = {
+       .name           = "testprobe",
+       .id             = UCLASS_TEST_PROBE,
+       .flags          = DM_UC_FLAG_SEQ_ALIAS,
+};
+
 int dm_check_devices(struct unit_test_state *uts, int num_devices)
 {
        struct udevice *dev;
@@ -267,3 +298,124 @@ static int dm_test_fdt_offset(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_fdt_offset,
        DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
+
+/**
+ * Test various error conditions with uclass_first_device() and
+ * uclass_next_device()
+ */
+static int dm_test_first_next_device(struct unit_test_state *uts)
+{
+       struct dm_testprobe_pdata *pdata;
+       struct udevice *dev, *parent = NULL;
+       int count;
+       int ret;
+
+       /* There should be 4 devices */
+       for (ret = uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0;
+            dev;
+            ret = uclass_next_device(&dev)) {
+               count++;
+               parent = dev_get_parent(dev);
+               }
+       ut_assertok(ret);
+       ut_asserteq(4, count);
+
+       /* Remove them and try again, with an error on the second one */
+       ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 1, &dev));
+       pdata = dev_get_platdata(dev);
+       pdata->probe_err = -ENOMEM;
+       device_remove(parent, DM_REMOVE_NORMAL);
+       ut_assertok(uclass_first_device(UCLASS_TEST_PROBE, &dev));
+       ut_asserteq(-ENOMEM, uclass_next_device(&dev));
+       ut_asserteq_ptr(dev, NULL);
+
+       /* Now an error on the first one */
+       ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 0, &dev));
+       pdata = dev_get_platdata(dev);
+       pdata->probe_err = -ENOENT;
+       device_remove(parent, DM_REMOVE_NORMAL);
+       ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev));
+
+       return 0;
+}
+DM_TEST(dm_test_first_next_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/**
+ * check_devices() - Check return values and pointers
+ *
+ * This runs through a full sequence of uclass_first_device_check()...
+ * uclass_next_device_check() checking that the return values and devices
+ * are correct.
+ *
+ * @uts: Test state
+ * @devlist: List of expected devices
+ * @mask: Indicates which devices should return an error. Device n should
+ *       return error (-NOENT - n) if bit n is set, or no error (i.e. 0) if
+ *       bit n is clear.
+ */
+static int check_devices(struct unit_test_state *uts,
+                        struct udevice *devlist[], int mask)
+{
+       int expected_ret;
+       struct udevice *dev;
+       int i;
+
+       expected_ret = (mask & 1) ? -ENOENT : 0;
+       mask >>= 1;
+       ut_asserteq(expected_ret,
+                   uclass_first_device_check(UCLASS_TEST_PROBE, &dev));
+       for (i = 0; i < 4; i++) {
+               ut_asserteq_ptr(devlist[i], dev);
+               expected_ret = (mask & 1) ? -ENOENT - (i + 1) : 0;
+               mask >>= 1;
+               ut_asserteq(expected_ret, uclass_next_device_check(&dev));
+       }
+       ut_asserteq_ptr(NULL, dev);
+
+       return 0;
+}
+
+/* Test uclass_first_device_check() and uclass_next_device_check() */
+static int dm_test_first_next_ok_device(struct unit_test_state *uts)
+{
+       struct dm_testprobe_pdata *pdata;
+       struct udevice *dev, *parent = NULL, *devlist[4];
+       int count;
+       int ret;
+
+       /* There should be 4 devices */
+       count = 0;
+       for (ret = uclass_first_device_check(UCLASS_TEST_PROBE, &dev);
+            dev;
+            ret = uclass_next_device_check(&dev)) {
+               ut_assertok(ret);
+               devlist[count++] = dev;
+               parent = dev_get_parent(dev);
+               }
+       ut_asserteq(4, count);
+       ut_assertok(uclass_first_device_check(UCLASS_TEST_PROBE, &dev));
+       ut_assertok(check_devices(uts, devlist, 0));
+
+       /* Remove them and try again, with an error on the second one */
+       pdata = dev_get_platdata(devlist[1]);
+       pdata->probe_err = -ENOENT - 1;
+       device_remove(parent, DM_REMOVE_NORMAL);
+       ut_assertok(check_devices(uts, devlist, 1 << 1));
+
+       /* Now an error on the first one */
+       pdata = dev_get_platdata(devlist[0]);
+       pdata->probe_err = -ENOENT - 0;
+       device_remove(parent, DM_REMOVE_NORMAL);
+       ut_assertok(check_devices(uts, devlist, 3 << 0));
+
+       /* Now errors on all */
+       pdata = dev_get_platdata(devlist[2]);
+       pdata->probe_err = -ENOENT - 2;
+       pdata = dev_get_platdata(devlist[3]);
+       pdata->probe_err = -ENOENT - 3;
+       device_remove(parent, DM_REMOVE_NORMAL);
+       ut_assertok(check_devices(uts, devlist, 0xf << 0));
+
+       return 0;
+}
+DM_TEST(dm_test_first_next_ok_device, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/print_ut.c b/test/print_ut.c
new file mode 100644 (file)
index 0000000..baad289
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, The Chromium Authors
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#define DEBUG
+
+#include <common.h>
+#include <display_options.h>
+#include <version.h>
+
+#define FAKE_BUILD_TAG "jenkins-u-boot-denx_uboot_dm-master-build-aarch64" \
+                       "and a lot more text to come"
+
+static int do_ut_print(cmd_tbl_t *cmdtp, int flag, int argc,
+                      char *const argv[])
+{
+       char big_str[400];
+       int big_str_len;
+       char str[10], *s;
+       int len;
+
+       printf("%s: Testing print\n", __func__);
+
+       snprintf(str, sizeof(str), "testing");
+       assert(!strcmp("testing", str));
+
+       snprintf(str, sizeof(str), "testing but too long");
+       assert(!strcmp("testing b", str));
+
+       snprintf(str, 1, "testing none");
+       assert(!strcmp("", str));
+
+       *str = 'x';
+       snprintf(str, 0, "testing none");
+       assert(*str == 'x');
+
+       /* Test the banner function */
+       s = display_options_get_banner(true, str, sizeof(str));
+       assert(s == str);
+       assert(!strcmp("\n\nU-Boo\n\n", s));
+
+       s = display_options_get_banner(true, str, 1);
+       assert(s == str);
+       assert(!strcmp("", s));
+
+       s = display_options_get_banner(true, str, 2);
+       assert(s == str);
+       assert(!strcmp("\n", s));
+
+       s = display_options_get_banner(false, str, sizeof(str));
+       assert(s == str);
+       assert(!strcmp("U-Boot \n\n", s));
+
+       /* Give it enough space for some of the version */
+       big_str_len = strlen(version_string) - 5;
+       s = display_options_get_banner_priv(false, FAKE_BUILD_TAG, big_str,
+                                           big_str_len);
+       assert(s == big_str);
+       assert(!strncmp(version_string, s, big_str_len - 3));
+       assert(!strcmp("\n\n", s + big_str_len - 3));
+
+       /* Give it enough space for the version and some of the build tag */
+       big_str_len = strlen(version_string) + 9 + 20;
+       s = display_options_get_banner_priv(false, FAKE_BUILD_TAG, big_str,
+                                           big_str_len);
+       assert(s == big_str);
+       len = strlen(version_string);
+       assert(!strncmp(version_string, s, len));
+       assert(!strncmp(", Build: ", s + len, 9));
+       assert(!strncmp(FAKE_BUILD_TAG, s + 9 + len, 12));
+       assert(!strcmp("\n\n", s + big_str_len - 3));
+
+       printf("%s: Everything went swimmingly\n", __func__);
+       return 0;
+}
+
+U_BOOT_CMD(
+       ut_print,       1,      1,      do_ut_print,
+       "Very basic test of printf(), etc.",
+       ""
+);
index 457c405..0660ce4 100644 (file)
@@ -4,35 +4,7 @@
 
 import pytest
 
-OF_PLATDATA_OUTPUT = '''
-of-platdata probe:
-bool 1
-byte 05
-bytearray 06 00 00
-int 1
-intarray 2 3 4 0
-longbytearray 09 0a 0b 0c 0d 0e 0f 10 11
-string message
-stringarray "multi-word" "message" ""
-of-platdata probe:
-bool 0
-byte 08
-bytearray 01 23 34
-int 3
-intarray 5 0 0 0
-longbytearray 09 00 00 00 00 00 00 00 00
-string message2
-stringarray "another" "multi-word" "message"
-of-platdata probe:
-bool 0
-byte 00
-bytearray 00 00 00
-int 0
-intarray 0 0 0 0
-longbytearray 00 00 00 00 00 00 00 00 00
-string <NULL>
-stringarray "one" "" ""
-'''
+OF_PLATDATA_OUTPUT = ''
 
 @pytest.mark.buildconfigspec('spl_of_platdata')
 def test_ofplatdata(u_boot_console):
index 95d3a04..09dc36a 100755 (executable)
@@ -17,15 +17,14 @@ import unittest
 
 # Bring in the patman and dtoc libraries
 our_path = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(our_path, '../patman'))
-sys.path.append(os.path.join(our_path, '../dtoc'))
-sys.path.append(os.path.join(our_path, '../'))
+for dirname in ['../patman', '../dtoc', '..']:
+    sys.path.insert(0, os.path.join(our_path, dirname))
 
 # Bring in the libfdt module
-sys.path.append('tools')
+sys.path.insert(0, 'tools')
 
 # Also allow entry-type modules to be brought in from the etype directory.
-sys.path.append(os.path.join(our_path, 'etype'))
+sys.path.insert(0, os.path.join(our_path, 'etype'))
 
 import cmdline
 import command
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
new file mode 100644 (file)
index 0000000..1f85343
--- /dev/null
@@ -0,0 +1,456 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2017 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+"""Device tree to platform data class
+
+This supports converting device tree data to C structures definitions and
+static data.
+"""
+
+import copy
+import sys
+
+import fdt
+import fdt_util
+
+# When we see these properties we ignore them - i.e. do not create a structure member
+PROP_IGNORE_LIST = [
+    '#address-cells',
+    '#gpio-cells',
+    '#size-cells',
+    'compatible',
+    'linux,phandle',
+    "status",
+    'phandle',
+    'u-boot,dm-pre-reloc',
+    'u-boot,dm-tpl',
+    'u-boot,dm-spl',
+]
+
+# C type declarations for the tyues we support
+TYPE_NAMES = {
+    fdt.TYPE_INT: 'fdt32_t',
+    fdt.TYPE_BYTE: 'unsigned char',
+    fdt.TYPE_STRING: 'const char *',
+    fdt.TYPE_BOOL: 'bool',
+}
+
+STRUCT_PREFIX = 'dtd_'
+VAL_PREFIX = 'dtv_'
+
+def conv_name_to_c(name):
+    """Convert a device-tree name to a C identifier
+
+    This uses multiple replace() calls instead of re.sub() since it is faster
+    (400ms for 1m calls versus 1000ms for the 're' version).
+
+    Args:
+        name:   Name to convert
+    Return:
+        String containing the C version of this name
+    """
+    new = name.replace('@', '_at_')
+    new = new.replace('-', '_')
+    new = new.replace(',', '_')
+    new = new.replace('.', '_')
+    return new
+
+def tab_to(num_tabs, line):
+    """Append tabs to a line of text to reach a tab stop.
+
+    Args:
+        num_tabs: Tab stop to obtain (0 = column 0, 1 = column 8, etc.)
+        line: Line of text to append to
+
+    Returns:
+        line with the correct number of tabs appeneded. If the line already
+        extends past that tab stop then a single space is appended.
+    """
+    if len(line) >= num_tabs * 8:
+        return line + ' '
+    return line + '\t' * (num_tabs - len(line) // 8)
+
+def get_value(ftype, value):
+    """Get a value as a C expression
+
+    For integers this returns a byte-swapped (little-endian) hex string
+    For bytes this returns a hex string, e.g. 0x12
+    For strings this returns a literal string enclosed in quotes
+    For booleans this return 'true'
+
+    Args:
+        type: Data type (fdt_util)
+        value: Data value, as a string of bytes
+    """
+    if ftype == fdt.TYPE_INT:
+        return '%#x' % fdt_util.fdt32_to_cpu(value)
+    elif ftype == fdt.TYPE_BYTE:
+        return '%#x' % ord(value[0])
+    elif ftype == fdt.TYPE_STRING:
+        return '"%s"' % value
+    elif ftype == fdt.TYPE_BOOL:
+        return 'true'
+
+def get_compat_name(node):
+    """Get a node's first compatible string as a C identifier
+
+    Args:
+        node: Node object to check
+    Return:
+        Tuple:
+            C identifier for the first compatible string
+            List of C identifiers for all the other compatible strings
+                (possibly empty)
+    """
+    compat = node.props['compatible'].value
+    aliases = []
+    if isinstance(compat, list):
+        compat, aliases = compat[0], compat[1:]
+    return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases]
+
+def is_phandle(prop):
+    """Check if a node contains phandles
+
+    We have no reliable way of detecting whether a node uses a phandle
+    or not. As an interim measure, use a list of known property names.
+
+    Args:
+        prop: Prop object to check
+    Return:
+        True if the object value contains phandles, else False
+    """
+    if prop.name in ['clocks']:
+        return True
+    return False
+
+
+class DtbPlatdata(object):
+    """Provide a means to convert device tree binary data to platform data
+
+    The output of this process is C structures which can be used in space-
+    constrained encvironments where the ~3KB code overhead of device tree
+    code is not affordable.
+
+    Properties:
+        _fdt: Fdt object, referencing the device tree
+        _dtb_fname: Filename of the input device tree binary file
+        _valid_nodes: A list of Node object with compatible strings
+        _include_disabled: true to include nodes marked status = "disabled"
+        _phandle_nodes: A dict of nodes indexed by phandle number (1, 2...)
+        _outfile: The current output file (sys.stdout or a real file)
+        _lines: Stashed list of output lines for outputting in the future
+        _phandle_nodes: A dict of Nodes indexed by phandle (an integer)
+    """
+    def __init__(self, dtb_fname, include_disabled):
+        self._fdt = None
+        self._dtb_fname = dtb_fname
+        self._valid_nodes = None
+        self._include_disabled = include_disabled
+        self._phandle_nodes = {}
+        self._outfile = None
+        self._lines = []
+        self._aliases = {}
+
+    def setup_output(self, fname):
+        """Set up the output destination
+
+        Once this is done, future calls to self.out() will output to this
+        file.
+
+        Args:
+            fname: Filename to send output to, or '-' for stdout
+        """
+        if fname == '-':
+            self._outfile = sys.stdout
+        else:
+            self._outfile = open(fname, 'w')
+
+    def out(self, line):
+        """Output a string to the output file
+
+        Args:
+            line: String to output
+        """
+        self._outfile.write(line)
+
+    def buf(self, line):
+        """Buffer up a string to send later
+
+        Args:
+            line: String to add to our 'buffer' list
+        """
+        self._lines.append(line)
+
+    def get_buf(self):
+        """Get the contents of the output buffer, and clear it
+
+        Returns:
+            The output buffer, which is then cleared for future use
+        """
+        lines = self._lines
+        self._lines = []
+        return lines
+
+    def scan_dtb(self):
+        """Scan the device tree to obtain a tree of notes and properties
+
+        Once this is done, self._fdt.GetRoot() can be called to obtain the
+        device tree root node, and progress from there.
+        """
+        self._fdt = fdt.FdtScan(self._dtb_fname)
+
+    def scan_node(self, root):
+        """Scan a node and subnodes to build a tree of node and phandle info
+
+        This adds each node to self._valid_nodes and each phandle to
+        self._phandle_nodes.
+
+        Args:
+            root: Root node for scan
+        """
+        for node in root.subnodes:
+            if 'compatible' in node.props:
+                status = node.props.get('status')
+                if (not self._include_disabled and not status or
+                        status.value != 'disabled'):
+                    self._valid_nodes.append(node)
+                    phandle_prop = node.props.get('phandle')
+                    if phandle_prop:
+                        phandle = phandle_prop.GetPhandle()
+                        self._phandle_nodes[phandle] = node
+
+            # recurse to handle any subnodes
+            self.scan_node(node)
+
+    def scan_tree(self):
+        """Scan the device tree for useful information
+
+        This fills in the following properties:
+            _phandle_nodes: A dict of Nodes indexed by phandle (an integer)
+            _valid_nodes: A list of nodes we wish to consider include in the
+                platform data
+        """
+        self._phandle_nodes = {}
+        self._valid_nodes = []
+        return self.scan_node(self._fdt.GetRoot())
+
+    def scan_structs(self):
+        """Scan the device tree building up the C structures we will use.
+
+        Build a dict keyed by C struct name containing a dict of Prop
+        object for each struct field (keyed by property name). Where the
+        same struct appears multiple times, try to use the 'widest'
+        property, i.e. the one with a type which can express all others.
+
+        Once the widest property is determined, all other properties are
+        updated to match that width.
+        """
+        structs = {}
+        for node in self._valid_nodes:
+            node_name, _ = get_compat_name(node)
+            fields = {}
+
+            # Get a list of all the valid properties in this node.
+            for name, prop in node.props.items():
+                if name not in PROP_IGNORE_LIST and name[0] != '#':
+                    fields[name] = copy.deepcopy(prop)
+
+            # If we've seen this node_name before, update the existing struct.
+            if node_name in structs:
+                struct = structs[node_name]
+                for name, prop in fields.items():
+                    oldprop = struct.get(name)
+                    if oldprop:
+                        oldprop.Widen(prop)
+                    else:
+                        struct[name] = prop
+
+            # Otherwise store this as a new struct.
+            else:
+                structs[node_name] = fields
+
+        upto = 0
+        for node in self._valid_nodes:
+            node_name, _ = get_compat_name(node)
+            struct = structs[node_name]
+            for name, prop in node.props.items():
+                if name not in PROP_IGNORE_LIST and name[0] != '#':
+                    prop.Widen(struct[name])
+            upto += 1
+
+            struct_name, aliases = get_compat_name(node)
+            for alias in aliases:
+                self._aliases[alias] = struct_name
+
+        return structs
+
+    def scan_phandles(self):
+        """Figure out what phandles each node uses
+
+        We need to be careful when outputing nodes that use phandles since
+        they must come after the declaration of the phandles in the C file.
+        Otherwise we get a compiler error since the phandle struct is not yet
+        declared.
+
+        This function adds to each node a list of phandle nodes that the node
+        depends on. This allows us to output things in the right order.
+        """
+        for node in self._valid_nodes:
+            node.phandles = set()
+            for pname, prop in node.props.items():
+                if pname in PROP_IGNORE_LIST or pname[0] == '#':
+                    continue
+                if isinstance(prop.value, list):
+                    if is_phandle(prop):
+                        # Process the list as pairs of (phandle, id)
+                        value_it = iter(prop.value)
+                        for phandle_cell, _ in zip(value_it, value_it):
+                            phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+                            target_node = self._phandle_nodes[phandle]
+                            node.phandles.add(target_node)
+
+
+    def generate_structs(self, structs):
+        """Generate struct defintions for the platform data
+
+        This writes out the body of a header file consisting of structure
+        definitions for node in self._valid_nodes. See the documentation in
+        README.of-plat for more information.
+        """
+        self.out('#include <stdbool.h>\n')
+        self.out('#include <libfdt.h>\n')
+
+        # Output the struct definition
+        for name in sorted(structs):
+            self.out('struct %s%s {\n' % (STRUCT_PREFIX, name))
+            for pname in sorted(structs[name]):
+                prop = structs[name][pname]
+                if is_phandle(prop):
+                    # For phandles, include a reference to the target
+                    self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'),
+                                             conv_name_to_c(prop.name),
+                                             len(prop.value) / 2))
+                else:
+                    ptype = TYPE_NAMES[prop.type]
+                    self.out('\t%s%s' % (tab_to(2, ptype),
+                                         conv_name_to_c(prop.name)))
+                    if isinstance(prop.value, list):
+                        self.out('[%d]' % len(prop.value))
+                self.out(';\n')
+            self.out('};\n')
+
+        for alias, struct_name in self._aliases.iteritems():
+            self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
+                                             STRUCT_PREFIX, struct_name))
+
+    def output_node(self, node):
+        """Output the C code for a node
+
+        Args:
+            node: node to output
+        """
+        struct_name, _ = get_compat_name(node)
+        var_name = conv_name_to_c(node.name)
+        self.buf('static struct %s%s %s%s = {\n' %
+                 (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
+        for pname, prop in node.props.items():
+            if pname in PROP_IGNORE_LIST or pname[0] == '#':
+                continue
+            member_name = conv_name_to_c(prop.name)
+            self.buf('\t%s= ' % tab_to(3, '.' + member_name))
+
+            # Special handling for lists
+            if isinstance(prop.value, list):
+                self.buf('{')
+                vals = []
+                # For phandles, output a reference to the platform data
+                # of the target node.
+                if is_phandle(prop):
+                    # Process the list as pairs of (phandle, id)
+                    value_it = iter(prop.value)
+                    for phandle_cell, id_cell in zip(value_it, value_it):
+                        phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+                        id_num = fdt_util.fdt32_to_cpu(id_cell)
+                        target_node = self._phandle_nodes[phandle]
+                        name = conv_name_to_c(target_node.name)
+                        vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num))
+                else:
+                    for val in prop.value:
+                        vals.append(get_value(prop.type, val))
+                self.buf(', '.join(vals))
+                self.buf('}')
+            else:
+                self.buf(get_value(prop.type, prop.value))
+            self.buf(',\n')
+        self.buf('};\n')
+
+        # Add a device declaration
+        self.buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
+        self.buf('\t.name\t\t= "%s",\n' % struct_name)
+        self.buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
+        self.buf('\t.platdata_size\t= sizeof(%s%s),\n' % (VAL_PREFIX, var_name))
+        self.buf('};\n')
+        self.buf('\n')
+
+        self.out(''.join(self.get_buf()))
+
+    def generate_tables(self):
+        """Generate device defintions for the platform data
+
+        This writes out C platform data initialisation data and
+        U_BOOT_DEVICE() declarations for each valid node. Where a node has
+        multiple compatible strings, a #define is used to make them equivalent.
+
+        See the documentation in doc/driver-model/of-plat.txt for more
+        information.
+        """
+        self.out('#include <common.h>\n')
+        self.out('#include <dm.h>\n')
+        self.out('#include <dt-structs.h>\n')
+        self.out('\n')
+        nodes_to_output = list(self._valid_nodes)
+
+        # Keep outputing nodes until there is none left
+        while nodes_to_output:
+            node = nodes_to_output[0]
+            # Output all the node's dependencies first
+            for req_node in node.phandles:
+                if req_node in nodes_to_output:
+                    self.output_node(req_node)
+                    nodes_to_output.remove(req_node)
+            self.output_node(node)
+            nodes_to_output.remove(node)
+
+
+def run_steps(args, dtb_file, include_disabled, output):
+    """Run all the steps of the dtoc tool
+
+    Args:
+        args: List of non-option arguments provided to the problem
+        dtb_file: Filename of dtb file to process
+        include_disabled: True to include disabled nodes
+        output: Name of output file
+    """
+    if not args:
+        raise ValueError('Please specify a command: struct, platdata')
+
+    plat = DtbPlatdata(dtb_file, include_disabled)
+    plat.scan_dtb()
+    plat.scan_tree()
+    plat.setup_output(output)
+    structs = plat.scan_structs()
+    plat.scan_phandles()
+
+    for cmd in args[0].split(','):
+        if cmd == 'struct':
+            plat.generate_structs(structs)
+        elif cmd == 'platdata':
+            plat.generate_tables()
+        else:
+            raise ValueError("Unknown command '%s': (use: struct, platdata)" %
+                             cmd)
index 08e35f1..ce7bc05 100755 (executable)
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-import copy
-from optparse import OptionError, OptionParser
-import os
-import struct
-import sys
-
-# Bring in the patman libraries
-our_path = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(our_path, '../patman'))
-
-import fdt
-import fdt_util
-
-# When we see these properties we ignore them - i.e. do not create a structure member
-PROP_IGNORE_LIST = [
-    '#address-cells',
-    '#gpio-cells',
-    '#size-cells',
-    'compatible',
-    'linux,phandle',
-    "status",
-    'phandle',
-    'u-boot,dm-pre-reloc',
-    'u-boot,dm-tpl',
-    'u-boot,dm-spl',
-]
-
-# C type declarations for the tyues we support
-TYPE_NAMES = {
-    fdt.TYPE_INT: 'fdt32_t',
-    fdt.TYPE_BYTE: 'unsigned char',
-    fdt.TYPE_STRING: 'const char *',
-    fdt.TYPE_BOOL: 'bool',
-};
-
-STRUCT_PREFIX = 'dtd_'
-VAL_PREFIX = 'dtv_'
-
-def Conv_name_to_c(name):
-    """Convert a device-tree name to a C identifier
-
-    Args:
-        name:   Name to convert
-    Return:
-        String containing the C version of this name
-    """
-    str = name.replace('@', '_at_')
-    str = str.replace('-', '_')
-    str = str.replace(',', '_')
-    str = str.replace('.', '_')
-    str = str.replace('/', '__')
-    return str
-
-def TabTo(num_tabs, str):
-    if len(str) >= num_tabs * 8:
-        return str + ' '
-    return str + '\t' * (num_tabs - len(str) // 8)
-
-class DtbPlatdata:
-    """Provide a means to convert device tree binary data to platform data
-
-    The output of this process is C structures which can be used in space-
-    constrained encvironments where the ~3KB code overhead of device tree
-    code is not affordable.
-
-    Properties:
-        fdt: Fdt object, referencing the device tree
-        _dtb_fname: Filename of the input device tree binary file
-        _valid_nodes: A list of Node object with compatible strings
-        _options: Command-line options
-        _phandle_node: A dict of nodes indexed by phandle number (1, 2...)
-        _outfile: The current output file (sys.stdout or a real file)
-        _lines: Stashed list of output lines for outputting in the future
-        _phandle_node: A dict of Nodes indexed by phandle (an integer)
-    """
-    def __init__(self, dtb_fname, options):
-        self._dtb_fname = dtb_fname
-        self._valid_nodes = None
-        self._options = options
-        self._phandle_node = {}
-        self._outfile = None
-        self._lines = []
-
-    def SetupOutput(self, fname):
-        """Set up the output destination
-
-        Once this is done, future calls to self.Out() will output to this
-        file.
-
-        Args:
-            fname: Filename to send output to, or '-' for stdout
-        """
-        if fname == '-':
-            self._outfile = sys.stdout
-        else:
-            self._outfile = open(fname, 'w')
-
-    def Out(self, str):
-        """Output a string to the output file
-
-        Args:
-            str: String to output
-        """
-        self._outfile.write(str)
-
-    def Buf(self, str):
-        """Buffer up a string to send later
-
-        Args:
-            str: String to add to our 'buffer' list
-        """
-        self._lines.append(str)
-
-    def GetBuf(self):
-        """Get the contents of the output buffer, and clear it
-
-        Returns:
-            The output buffer, which is then cleared for future use
-        """
-        lines = self._lines
-        self._lines = []
-        return lines
-
-    def GetValue(self, type, value):
-        """Get a value as a C expression
-
-        For integers this returns a byte-swapped (little-endian) hex string
-        For bytes this returns a hex string, e.g. 0x12
-        For strings this returns a literal string enclosed in quotes
-        For booleans this return 'true'
-
-        Args:
-            type: Data type (fdt_util)
-            value: Data value, as a string of bytes
-        """
-        if type == fdt.TYPE_INT:
-            return '%#x' % fdt_util.fdt32_to_cpu(value)
-        elif type == fdt.TYPE_BYTE:
-            return '%#x' % ord(value[0])
-        elif type == fdt.TYPE_STRING:
-            return '"%s"' % value
-        elif type == fdt.TYPE_BOOL:
-            return 'true'
-
-    def GetCompatName(self, node):
-        """Get a node's first compatible string as a C identifier
-
-        Args:
-            node: Node object to check
-        Return:
-            C identifier for the first compatible string
-        """
-        compat = node.props['compatible'].value
-        if type(compat) == list:
-            compat = compat[0]
-        return Conv_name_to_c(compat)
+"""Device tree to C tool
 
-    def ScanDtb(self):
-        """Scan the device tree to obtain a tree of notes and properties
+This tool converts a device tree binary file (.dtb) into two C files. The
+indent is to allow a C program to access data from the device tree without
+having to link against libfdt. By putting the data from the device tree into
+C structures, normal C code can be used. This helps to reduce the size of the
+compiled program.
 
-        Once this is done, self.fdt.GetRoot() can be called to obtain the
-        device tree root node, and progress from there.
-        """
-        self.fdt = fdt.FdtScan(self._dtb_fname)
+Dtoc produces two output files:
 
-    def ScanNode(self, root):
-        for node in root.subnodes:
-            if 'compatible' in node.props:
-                status = node.props.get('status')
-                if (not options.include_disabled and not status or
-                    status.value != 'disabled'):
-                    self._valid_nodes.append(node)
-                    phandle_prop = node.props.get('phandle')
-                    if phandle_prop:
-                        phandle = phandle_prop.GetPhandle()
-                        self._phandle_node[phandle] = node
+   dt-structs.h  - contains struct definitions
+   dt-platdata.c - contains data from the device tree using the struct
+                      definitions, as well as U-Boot driver definitions.
 
-            # recurse to handle any subnodes
-            self.ScanNode(node);
+This tool is used in U-Boot to provide device tree data to SPL without
+increasing the code size of SPL. This supports the CONFIG_SPL_OF_PLATDATA
+options. For more information about the use of this options and tool please
+see doc/driver-model/of-plat.txt
+"""
 
-    def ScanTree(self):
-        """Scan the device tree for useful information
-
-        This fills in the following properties:
-            _phandle_node: A dict of Nodes indexed by phandle (an integer)
-            _valid_nodes: A list of nodes we wish to consider include in the
-                platform data
-        """
-        self._phandle_node = {}
-        self._valid_nodes = []
-        return self.ScanNode(self.fdt.GetRoot());
-
-        for node in self.fdt.GetRoot().subnodes:
-            if 'compatible' in node.props:
-                status = node.props.get('status')
-                if (not options.include_disabled and not status or
-                    status.value != 'disabled'):
-                    node_list.append(node)
-                    phandle_prop = node.props.get('phandle')
-                    if phandle_prop:
-                        phandle = phandle_prop.GetPhandle()
-                        self._phandle_node[phandle] = node
-
-        self._valid_nodes = node_list
-
-    def IsPhandle(self, prop):
-        """Check if a node contains phandles
-
-        We have no reliable way of detecting whether a node uses a phandle
-        or not. As an interim measure, use a list of known property names.
-
-        Args:
-            prop: Prop object to check
-        Return:
-            True if the object value contains phandles, else False
-        """
-        if prop.name in ['clocks']:
-            return True
-        return False
-
-    def ScanStructs(self):
-        """Scan the device tree building up the C structures we will use.
-
-        Build a dict keyed by C struct name containing a dict of Prop
-        object for each struct field (keyed by property name). Where the
-        same struct appears multiple times, try to use the 'widest'
-        property, i.e. the one with a type which can express all others.
-
-        Once the widest property is determined, all other properties are
-        updated to match that width.
-        """
-        structs = {}
-        for node in self._valid_nodes:
-            node_name = self.GetCompatName(node)
-            fields = {}
-
-            # Get a list of all the valid properties in this node.
-            for name, prop in node.props.items():
-                if name not in PROP_IGNORE_LIST and name[0] != '#':
-                    fields[name] = copy.deepcopy(prop)
-
-            # If we've seen this node_name before, update the existing struct.
-            if node_name in structs:
-                struct = structs[node_name]
-                for name, prop in fields.items():
-                    oldprop = struct.get(name)
-                    if oldprop:
-                        oldprop.Widen(prop)
-                    else:
-                        struct[name] = prop
-
-            # Otherwise store this as a new struct.
-            else:
-                structs[node_name] = fields
-
-        upto = 0
-        for node in self._valid_nodes:
-            node_name = self.GetCompatName(node)
-            struct = structs[node_name]
-            for name, prop in node.props.items():
-                if name not in PROP_IGNORE_LIST and name[0] != '#':
-                    prop.Widen(struct[name])
-            upto += 1
-        return structs
-
-    def ScanPhandles(self):
-        """Figure out what phandles each node uses
-
-        We need to be careful when outputing nodes that use phandles since
-        they must come after the declaration of the phandles in the C file.
-        Otherwise we get a compiler error since the phandle struct is not yet
-        declared.
-
-        This function adds to each node a list of phandle nodes that the node
-        depends on. This allows us to output things in the right order.
-        """
-        for node in self._valid_nodes:
-            node.phandles = set()
-            for pname, prop in node.props.items():
-                if pname in PROP_IGNORE_LIST or pname[0] == '#':
-                    continue
-                if type(prop.value) == list:
-                    if self.IsPhandle(prop):
-                        # Process the list as pairs of (phandle, id)
-                        it = iter(prop.value)
-                        for phandle_cell, id_cell in zip(it, it):
-                            phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-                            id = fdt_util.fdt32_to_cpu(id_cell)
-                            target_node = self._phandle_node[phandle]
-                            node.phandles.add(target_node)
-
-
-    def GenerateStructs(self, structs):
-        """Generate struct defintions for the platform data
-
-        This writes out the body of a header file consisting of structure
-        definitions for node in self._valid_nodes. See the documentation in
-        README.of-plat for more information.
-        """
-        self.Out('#include <stdbool.h>\n')
-        self.Out('#include <libfdt.h>\n')
-
-        # Output the struct definition
-        for name in sorted(structs):
-            self.Out('struct %s%s {\n' % (STRUCT_PREFIX, name));
-            for pname in sorted(structs[name]):
-                prop = structs[name][pname]
-                if self.IsPhandle(prop):
-                    # For phandles, include a reference to the target
-                    self.Out('\t%s%s[%d]' % (TabTo(2, 'struct phandle_2_cell'),
-                                             Conv_name_to_c(prop.name),
-                                             len(prop.value) / 2))
-                else:
-                    ptype = TYPE_NAMES[prop.type]
-                    self.Out('\t%s%s' % (TabTo(2, ptype),
-                                         Conv_name_to_c(prop.name)))
-                    if type(prop.value) == list:
-                        self.Out('[%d]' % len(prop.value))
-                self.Out(';\n')
-            self.Out('};\n')
-
-    def OutputNode(self, node):
-        """Output the C code for a node
-
-        Args:
-            node: node to output
-        """
-        struct_name = self.GetCompatName(node)
-        var_name = Conv_name_to_c(node.name)
-        self.Buf('static struct %s%s %s%s = {\n' %
-            (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
-        for pname, prop in node.props.items():
-            if pname in PROP_IGNORE_LIST or pname[0] == '#':
-                continue
-            ptype = TYPE_NAMES[prop.type]
-            member_name = Conv_name_to_c(prop.name)
-            self.Buf('\t%s= ' % TabTo(3, '.' + member_name))
-
-            # Special handling for lists
-            if type(prop.value) == list:
-                self.Buf('{')
-                vals = []
-                # For phandles, output a reference to the platform data
-                # of the target node.
-                if self.IsPhandle(prop):
-                    # Process the list as pairs of (phandle, id)
-                    it = iter(prop.value)
-                    for phandle_cell, id_cell in zip(it, it):
-                        phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-                        id = fdt_util.fdt32_to_cpu(id_cell)
-                        target_node = self._phandle_node[phandle]
-                        name = Conv_name_to_c(target_node.name)
-                        vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id))
-                else:
-                    for val in prop.value:
-                        vals.append(self.GetValue(prop.type, val))
-                self.Buf(', '.join(vals))
-                self.Buf('}')
-            else:
-                self.Buf(self.GetValue(prop.type, prop.value))
-            self.Buf(',\n')
-        self.Buf('};\n')
-
-        # Add a device declaration
-        self.Buf('U_BOOT_DEVICE(%s) = {\n' % var_name)
-        self.Buf('\t.name\t\t= "%s",\n' % struct_name)
-        self.Buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
-        self.Buf('\t.platdata_size\t= sizeof(%s%s),\n' %
-                    (VAL_PREFIX, var_name))
-        self.Buf('};\n')
-        self.Buf('\n')
+from optparse import OptionParser
+import os
+import sys
+import unittest
 
-        self.Out(''.join(self.GetBuf()))
+# Bring in the patman libraries
+our_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(our_path, '../patman'))
 
-    def GenerateTables(self):
-        """Generate device defintions for the platform data
+import dtb_platdata
 
-        This writes out C platform data initialisation data and
-        U_BOOT_DEVICE() declarations for each valid node. See the
-        documentation in README.of-plat for more information.
-        """
-        self.Out('#include <common.h>\n')
-        self.Out('#include <dm.h>\n')
-        self.Out('#include <dt-structs.h>\n')
-        self.Out('\n')
-        nodes_to_output = list(self._valid_nodes)
+def run_tests():
+    """Run all the test we have for dtoc"""
+    import test_dtoc
 
-        # Keep outputing nodes until there is none left
-        while nodes_to_output:
-            node = nodes_to_output[0]
-            # Output all the node's dependencies first
-            for req_node in node.phandles:
-                if req_node in nodes_to_output:
-                    self.OutputNode(req_node)
-                    nodes_to_output.remove(req_node)
-            self.OutputNode(node)
-            nodes_to_output.remove(node)
+    result = unittest.TestResult()
+    sys.argv = [sys.argv[0]]
+    for module in (test_dtoc.TestDtoc,):
+        suite = unittest.TestLoader().loadTestsFromTestCase(module)
+        suite.run(result)
 
+    print result
+    for _, err in result.errors:
+        print err
+    for _, err in result.failures:
+        print err
 
-if __name__ != "__main__":
-    pass
+if __name__ != '__main__':
+    sys.exit(1)
 
 parser = OptionParser()
 parser.add_option('-d', '--dtb-file', action='store',
@@ -415,22 +63,14 @@ parser.add_option('--include-disabled', action='store_true',
                   help='Include disabled nodes')
 parser.add_option('-o', '--output', action='store', default='-',
                   help='Select output filename')
+parser.add_option('-t', '--test', action='store_true', dest='test',
+                  default=False, help='run tests')
 (options, args) = parser.parse_args()
 
-if not args:
-    raise ValueError('Please specify a command: struct, platdata')
-
-plat = DtbPlatdata(options.dtb_file, options)
-plat.ScanDtb()
-plat.ScanTree()
-plat.SetupOutput(options.output)
-structs = plat.ScanStructs()
-plat.ScanPhandles()
+# Run our meagre tests
+if options.test:
+    run_tests()
 
-for cmd in args[0].split(','):
-    if cmd == 'struct':
-        plat.GenerateStructs(structs)
-    elif cmd == 'platdata':
-        plat.GenerateTables()
-    else:
-        raise ValueError("Unknown command '%s': (use: struct, platdata)" % cmd)
+else:
+    dtb_platdata.run_steps(args, options.dtb_file, options.include_disabled,
+                           options.output)
diff --git a/tools/dtoc/dtoc_test.dts b/tools/dtoc/dtoc_test.dts
new file mode 100644 (file)
index 0000000..1e86655
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+};
diff --git a/tools/dtoc/dtoc_test_aliases.dts b/tools/dtoc/dtoc_test_aliases.dts
new file mode 100644 (file)
index 0000000..c727f18
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+       spl-test {
+               u-boot,dm-pre-reloc;
+               compatible = "compat1", "compat2.1-fred", "compat3";
+               intval = <1>;
+       };
+
+};
diff --git a/tools/dtoc/dtoc_test_empty.dts b/tools/dtoc/dtoc_test_empty.dts
new file mode 100644 (file)
index 0000000..1e86655
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+};
diff --git a/tools/dtoc/dtoc_test_phandle.dts b/tools/dtoc/dtoc_test_phandle.dts
new file mode 100644 (file)
index 0000000..e9828a6
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+       phandle: phandle-target {
+               u-boot,dm-pre-reloc;
+               compatible = "target";
+               intval = <1>;
+       };
+
+       phandle-source {
+               u-boot,dm-pre-reloc;
+               compatible = "source";
+               clocks = <&phandle 1>;
+       };
+};
diff --git a/tools/dtoc/dtoc_test_simple.dts b/tools/dtoc/dtoc_test_simple.dts
new file mode 100644 (file)
index 0000000..c736686
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+ /dts-v1/;
+
+/ {
+       spl-test {
+               u-boot,dm-pre-reloc;
+               compatible = "sandbox,spl-test";
+               boolval;
+               intval = <1>;
+               intarray = <2 3 4>;
+               byteval = [05];
+               bytearray = [06];
+               longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
+               stringval = "message";
+               stringarray = "multi-word", "message";
+       };
+
+       spl-test2 {
+               u-boot,dm-pre-reloc;
+               compatible = "sandbox,spl-test";
+               intval = <3>;
+               intarray = <5>;
+               byteval = [08];
+               bytearray = [01 23 34];
+               longbytearray = [09 0a 0b 0c];
+               stringval = "message2";
+               stringarray = "another", "multi-word", "message";
+       };
+
+       spl-test3 {
+               u-boot,dm-pre-reloc;
+               compatible = "sandbox,spl-test";
+               stringarray = "one";
+       };
+
+       spl-test4 {
+               u-boot,dm-pre-reloc;
+               compatible = "sandbox,spl-test.2";
+       };
+
+};
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
new file mode 100644 (file)
index 0000000..8b95c41
--- /dev/null
@@ -0,0 +1,271 @@
+#
+# Copyright (c) 2012 The Chromium OS Authors.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+"""Tests for the dtb_platdata module
+
+This includes unit tests for some functions and functional tests for
+"""
+
+import collections
+import os
+import struct
+import unittest
+
+import dtb_platdata
+from dtb_platdata import conv_name_to_c
+from dtb_platdata import get_compat_name
+from dtb_platdata import get_value
+from dtb_platdata import tab_to
+import fdt
+import fdt_util
+import tools
+
+our_path = os.path.dirname(os.path.realpath(__file__))
+
+
+def get_dtb_file(dts_fname):
+    """Compile a .dts file to a .dtb
+
+    Args:
+        dts_fname: Filename of .dts file in the current directory
+
+    Returns:
+        Filename of compiled file in output directory
+    """
+    return fdt_util.EnsureCompiled(os.path.join(our_path, dts_fname))
+
+
+class TestDtoc(unittest.TestCase):
+    """Tests for dtoc"""
+    @classmethod
+    def setUpClass(cls):
+        tools.PrepareOutputDir(None)
+
+    @classmethod
+    def tearDownClass(cls):
+        tools._RemoveOutputDir()
+
+    def test_name(self):
+        """Test conversion of device tree names to C identifiers"""
+        self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12'))
+        self.assertEqual('vendor_clock_frequency',
+                         conv_name_to_c('vendor,clock-frequency'))
+        self.assertEqual('rockchip_rk3399_sdhci_5_1',
+                         conv_name_to_c('rockchip,rk3399-sdhci-5.1'))
+
+    def test_tab_to(self):
+        """Test operation of tab_to() function"""
+        self.assertEqual('fred ', tab_to(0, 'fred'))
+        self.assertEqual('fred\t', tab_to(1, 'fred'))
+        self.assertEqual('fred was here ', tab_to(1, 'fred was here'))
+        self.assertEqual('fred was here\t\t', tab_to(3, 'fred was here'))
+        self.assertEqual('exactly8 ', tab_to(1, 'exactly8'))
+        self.assertEqual('exactly8\t', tab_to(2, 'exactly8'))
+
+    def test_get_value(self):
+        """Test operation of get_value() function"""
+        self.assertEqual('0x45',
+                         get_value(fdt.TYPE_INT, struct.pack('>I', 0x45)))
+        self.assertEqual('0x45',
+                         get_value(fdt.TYPE_BYTE, struct.pack('<I', 0x45)))
+        self.assertEqual('0x0',
+                         get_value(fdt.TYPE_BYTE, struct.pack('>I', 0x45)))
+        self.assertEqual('"test"', get_value(fdt.TYPE_STRING, 'test'))
+        self.assertEqual('true', get_value(fdt.TYPE_BOOL, None))
+
+    def test_get_compat_name(self):
+        """Test operation of get_compat_name() function"""
+        Prop = collections.namedtuple('Prop', ['value'])
+        Node = collections.namedtuple('Node', ['props'])
+
+        prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1'])
+        node = Node({'compatible': prop})
+        self.assertEqual(('rockchip_rk3399_sdhci_5_1', ['arasan_sdhci_5_1']),
+                         get_compat_name(node))
+
+        prop = Prop(['rockchip,rk3399-sdhci-5.1'])
+        node = Node({'compatible': prop})
+        self.assertEqual(('rockchip_rk3399_sdhci_5_1', []),
+                         get_compat_name(node))
+
+        prop = Prop(['rockchip,rk3399-sdhci-5.1', 'arasan,sdhci-5.1', 'third'])
+        node = Node({'compatible': prop})
+        self.assertEqual(('rockchip_rk3399_sdhci_5_1',
+                          ['arasan_sdhci_5_1', 'third']),
+                         get_compat_name(node))
+
+    def test_empty_file(self):
+        """Test output from a device tree file with no nodes"""
+        dtb_file = get_dtb_file('dtoc_test_empty.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            lines = infile.read().splitlines()
+        self.assertEqual(['#include <stdbool.h>', '#include <libfdt.h>'], lines)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            lines = infile.read().splitlines()
+        self.assertEqual(['#include <common.h>', '#include <dm.h>',
+                          '#include <dt-structs.h>', ''], lines)
+
+    def test_simple(self):
+        """Test output from some simple nodes with various types of data"""
+        dtb_file = get_dtb_file('dtoc_test_simple.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <stdbool.h>
+#include <libfdt.h>
+struct dtd_sandbox_spl_test {
+\tbool\t\tboolval;
+\tunsigned char\tbytearray[3];
+\tunsigned char\tbyteval;
+\tfdt32_t\t\tintarray[4];
+\tfdt32_t\t\tintval;
+\tunsigned char\tlongbytearray[9];
+\tconst char *\tstringarray[3];
+\tconst char *\tstringval;
+};
+struct dtd_sandbox_spl_test_2 {
+};
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+static struct dtd_sandbox_spl_test dtv_spl_test = {
+\t.bytearray\t\t= {0x6, 0x0, 0x0},
+\t.byteval\t\t= 0x5,
+\t.intval\t\t\t= 0x1,
+\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11},
+\t.stringval\t\t= "message",
+\t.boolval\t\t= true,
+\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
+\t.stringarray\t\t= {"multi-word", "message", ""},
+};
+U_BOOT_DEVICE(spl_test) = {
+\t.name\t\t= "sandbox_spl_test",
+\t.platdata\t= &dtv_spl_test,
+\t.platdata_size\t= sizeof(dtv_spl_test),
+};
+
+static struct dtd_sandbox_spl_test dtv_spl_test2 = {
+\t.bytearray\t\t= {0x1, 0x23, 0x34},
+\t.byteval\t\t= 0x8,
+\t.intval\t\t\t= 0x3,
+\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+\t.stringval\t\t= "message2",
+\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
+\t.stringarray\t\t= {"another", "multi-word", "message"},
+};
+U_BOOT_DEVICE(spl_test2) = {
+\t.name\t\t= "sandbox_spl_test",
+\t.platdata\t= &dtv_spl_test2,
+\t.platdata_size\t= sizeof(dtv_spl_test2),
+};
+
+static struct dtd_sandbox_spl_test dtv_spl_test3 = {
+\t.stringarray\t\t= {"one", "", ""},
+};
+U_BOOT_DEVICE(spl_test3) = {
+\t.name\t\t= "sandbox_spl_test",
+\t.platdata\t= &dtv_spl_test3,
+\t.platdata_size\t= sizeof(dtv_spl_test3),
+};
+
+static struct dtd_sandbox_spl_test_2 dtv_spl_test4 = {
+};
+U_BOOT_DEVICE(spl_test4) = {
+\t.name\t\t= "sandbox_spl_test_2",
+\t.platdata\t= &dtv_spl_test4,
+\t.platdata_size\t= sizeof(dtv_spl_test4),
+};
+
+''', data)
+
+    def test_phandle(self):
+        """Test output from a node containing a phandle reference"""
+        dtb_file = get_dtb_file('dtoc_test_phandle.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <stdbool.h>
+#include <libfdt.h>
+struct dtd_source {
+\tstruct phandle_2_cell clocks[1];
+};
+struct dtd_target {
+\tfdt32_t\t\tintval;
+};
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+static struct dtd_target dtv_phandle_target = {
+\t.intval\t\t\t= 0x1,
+};
+U_BOOT_DEVICE(phandle_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle_target,
+\t.platdata_size\t= sizeof(dtv_phandle_target),
+};
+
+static struct dtd_source dtv_phandle_source = {
+\t.clocks\t\t\t= {{&dtv_phandle_target, 1}},
+};
+U_BOOT_DEVICE(phandle_source) = {
+\t.name\t\t= "source",
+\t.platdata\t= &dtv_phandle_source,
+\t.platdata_size\t= sizeof(dtv_phandle_source),
+};
+
+''', data)
+
+    def test_aliases(self):
+        """Test output from a node with multiple compatible strings"""
+        dtb_file = get_dtb_file('dtoc_test_aliases.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <stdbool.h>
+#include <libfdt.h>
+struct dtd_compat1 {
+\tfdt32_t\t\tintval;
+};
+#define dtd_compat2_1_fred dtd_compat1
+#define dtd_compat3 dtd_compat1
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self.assertEqual('''#include <common.h>
+#include <dm.h>
+#include <dt-structs.h>
+
+static struct dtd_compat1 dtv_spl_test = {
+\t.intval\t\t\t= 0x1,
+};
+U_BOOT_DEVICE(spl_test) = {
+\t.name\t\t= "compat1",
+\t.platdata\t= &dtv_spl_test,
+\t.platdata_size\t= sizeof(dtv_spl_test),
+};
+
+''', data)
index 7aa9612..eb4927f 100755 (executable)
@@ -115,6 +115,128 @@ use your own.  Instead of modifying the list directly, you can give
 them via environments.
 
 
+Tips and trips
+--------------
+
+To sync only X86 defconfigs:
+
+   ./tools/moveconfig.py -s -d <(grep -l X86 configs/*)
+
+or:
+
+   grep -l X86 configs/* | ./tools/moveconfig.py -s -d -
+
+To process CONFIG_CMD_FPGAD only for a subset of configs based on path match:
+
+   ls configs/{hrcon*,iocon*,strider*} | \
+       ./tools/moveconfig.py -Cy CONFIG_CMD_FPGAD -d -
+
+
+Finding implied CONFIGs
+-----------------------
+
+Some CONFIG options can be implied by others and this can help to reduce
+the size of the defconfig files. For example, CONFIG_X86 implies
+CONFIG_CMD_IRQ, so we can put 'imply CMD_IRQ' under 'config X86' and
+all x86 boards will have that option, avoiding adding CONFIG_CMD_IRQ to
+each of the x86 defconfig files.
+
+This tool can help find such configs. To use it, first build a database:
+
+    ./tools/moveconfig.py -b
+
+Then try to query it:
+
+    ./tools/moveconfig.py -i CONFIG_CMD_IRQ
+    CONFIG_CMD_IRQ found in 311/2384 defconfigs
+    44 : CONFIG_SYS_FSL_ERRATUM_IFC_A002769
+    41 : CONFIG_SYS_FSL_ERRATUM_A007075
+    31 : CONFIG_SYS_FSL_DDR_VER_44
+    28 : CONFIG_ARCH_P1010
+    28 : CONFIG_SYS_FSL_ERRATUM_P1010_A003549
+    28 : CONFIG_SYS_FSL_ERRATUM_SEC_A003571
+    28 : CONFIG_SYS_FSL_ERRATUM_IFC_A003399
+    25 : CONFIG_SYS_FSL_ERRATUM_A008044
+    22 : CONFIG_ARCH_P1020
+    21 : CONFIG_SYS_FSL_DDR_VER_46
+    20 : CONFIG_MAX_PIRQ_LINKS
+    20 : CONFIG_HPET_ADDRESS
+    20 : CONFIG_X86
+    20 : CONFIG_PCIE_ECAM_SIZE
+    20 : CONFIG_IRQ_SLOT_COUNT
+    20 : CONFIG_I8259_PIC
+    20 : CONFIG_CPU_ADDR_BITS
+    20 : CONFIG_RAMBASE
+    20 : CONFIG_SYS_FSL_ERRATUM_A005871
+    20 : CONFIG_PCIE_ECAM_BASE
+    20 : CONFIG_X86_TSC_TIMER
+    20 : CONFIG_I8254_TIMER
+    20 : CONFIG_CMD_GETTIME
+    19 : CONFIG_SYS_FSL_ERRATUM_A005812
+    18 : CONFIG_X86_RUN_32BIT
+    17 : CONFIG_CMD_CHIP_CONFIG
+    ...
+
+This shows a list of config options which might imply CONFIG_CMD_EEPROM along
+with how many defconfigs they cover. From this you can see that CONFIG_X86
+implies CONFIG_CMD_EEPROM. Therefore, instead of adding CONFIG_CMD_EEPROM to
+the defconfig of every x86 board, you could add a single imply line to the
+Kconfig file:
+
+    config X86
+        bool "x86 architecture"
+        ...
+        imply CMD_EEPROM
+
+That will cover 20 defconfigs. Many of the options listed are not suitable as
+they are not related. E.g. it would be odd for CONFIG_CMD_GETTIME to imply
+CMD_EEPROM.
+
+Using this search you can reduce the size of moveconfig patches.
+
+You can automatically add 'imply' statements in the Kconfig with the -a
+option:
+
+    ./tools/moveconfig.py -s -i CONFIG_SCSI \
+            -a CONFIG_ARCH_LS1021A,CONFIG_ARCH_LS1043A
+
+This will add 'imply SCSI' to the two CONFIG options mentioned, assuming that
+the database indicates that they do actually imply CONFIG_SCSI and do not
+already have an 'imply SCSI'.
+
+The output shows where the imply is added:
+
+   18 : CONFIG_ARCH_LS1021A       arch/arm/cpu/armv7/ls102xa/Kconfig:1
+   13 : CONFIG_ARCH_LS1043A       arch/arm/cpu/armv8/fsl-layerscape/Kconfig:11
+   12 : CONFIG_ARCH_LS1046A       arch/arm/cpu/armv8/fsl-layerscape/Kconfig:31
+
+The first number is the number of boards which can avoid having a special
+CONFIG_SCSI option in their defconfig file if this 'imply' is added.
+The location at the right is the Kconfig file and line number where the config
+appears. For example, adding 'imply CONFIG_SCSI' to the 'config ARCH_LS1021A'
+in arch/arm/cpu/armv7/ls102xa/Kconfig at line 1 will help 18 boards to reduce
+the size of their defconfig files.
+
+If you want to add an 'imply' to every imply config in the list, you can use
+
+    ./tools/moveconfig.py -s -i CONFIG_SCSI -a all
+
+To control which ones are displayed, use -I <list> where list is a list of
+options (use '-I help' to see possible options and their meaning).
+
+To skip showing you options that already have an 'imply' attached, use -A.
+
+When you have finished adding 'imply' options you can regenerate the
+defconfig files for affected boards with something like:
+
+    git show --stat | ./tools/moveconfig.py -s -d -
+
+This will regenerate only those defconfigs changed in the current commit.
+If you start with (say) 100 defconfigs being changed in the commit, and add
+a few 'imply' options as above, then regenerate, hopefully you can reduce the
+number of defconfigs changed in the commit.
+
+
 Available options
 -----------------
 
@@ -128,7 +250,7 @@ Available options
 
  -d, --defconfigs
   Specify a file containing a list of defconfigs to move.  The defconfig
-  files can be given with shell-style wildcards.
+  files can be given with shell-style wildcards. Use '-' to read from stdin.
 
  -n, --dry-run
    Perform a trial run that does not make any changes.  It is useful to
@@ -169,7 +291,8 @@ Available options
 
  -y, --yes
    Instead of prompting, automatically go ahead with all operations. This
-   includes cleaning up headers and CONFIG_SYS_EXTRA_OPTIONS.
+   includes cleaning up headers, CONFIG_SYS_EXTRA_OPTIONS, the config whitelist
+   and the README.
 
 To see the complete list of supported options, run
 
@@ -177,6 +300,7 @@ To see the complete list of supported options, run
 
 """
 
+import collections
 import copy
 import difflib
 import filecmp
@@ -185,13 +309,18 @@ import glob
 import multiprocessing
 import optparse
 import os
+import Queue
 import re
 import shutil
 import subprocess
 import sys
 import tempfile
+import threading
 import time
 
+sys.path.append(os.path.join(os.path.dirname(__file__), 'buildman'))
+import kconfiglib
+
 SHOW_GNU_MAKE = 'scripts/show-gnu-make'
 SLEEP_TIME=0.03
 
@@ -244,6 +373,11 @@ COLOR_LIGHT_PURPLE = '1;35'
 COLOR_LIGHT_CYAN   = '1;36'
 COLOR_WHITE        = '1;37'
 
+AUTO_CONF_PATH = 'include/config/auto.conf'
+CONFIG_DATABASE = 'moveconfig.db'
+
+CONFIG_LEN = len('CONFIG_')
+
 ### helper functions ###
 def get_devnull():
     """Get the file object of '/dev/null' device."""
@@ -278,15 +412,47 @@ def get_make_cmd():
         sys.exit('GNU Make not found')
     return ret[0].rstrip()
 
+def get_matched_defconfig(line):
+    """Get the defconfig files that match a pattern
+
+    Args:
+        line: Path or filename to match, e.g. 'configs/snow_defconfig' or
+            'k2*_defconfig'. If no directory is provided, 'configs/' is
+            prepended
+
+    Returns:
+        a list of matching defconfig files
+    """
+    dirname = os.path.dirname(line)
+    if dirname:
+        pattern = line
+    else:
+        pattern = os.path.join('configs', line)
+    return glob.glob(pattern) + glob.glob(pattern + '_defconfig')
+
 def get_matched_defconfigs(defconfigs_file):
-    """Get all the defconfig files that match the patterns in a file."""
+    """Get all the defconfig files that match the patterns in a file.
+
+    Args:
+        defconfigs_file: File containing a list of defconfigs to process, or
+            '-' to read the list from stdin
+
+    Returns:
+        A list of paths to defconfig files, with no duplicates
+    """
     defconfigs = []
-    for i, line in enumerate(open(defconfigs_file)):
+    if defconfigs_file == '-':
+        fd = sys.stdin
+        defconfigs_file = 'stdin'
+    else:
+        fd = open(defconfigs_file)
+    for i, line in enumerate(fd):
         line = line.strip()
         if not line:
             continue # skip blank lines silently
-        pattern = os.path.join('configs', line)
-        matched = glob.glob(pattern) + glob.glob(pattern + '_defconfig')
+        if ' ' in line:
+            line = line.split(' ')[0]  # handle 'git log' input
+        matched = get_matched_defconfig(line)
         if not matched:
             print >> sys.stderr, "warning: %s:%d: no defconfig matched '%s'" % \
                                                  (defconfigs_file, i + 1, line)
@@ -682,6 +848,19 @@ class Progress:
         print ' %d defconfigs out of %d\r' % (self.current, self.total),
         sys.stdout.flush()
 
+
+class KconfigScanner:
+    """Kconfig scanner."""
+
+    def __init__(self):
+        """Scan all the Kconfig files and create a Config object."""
+        # Define environment variables referenced from Kconfig
+        os.environ['srctree'] = os.getcwd()
+        os.environ['UBOOTVERSION'] = 'dummy'
+        os.environ['KCONFIG_OBJDIR'] = ''
+        self.conf = kconfiglib.Config()
+
+
 class KconfigParser:
 
     """A parser of .config and include/autoconf.mk."""
@@ -703,8 +882,7 @@ class KconfigParser:
         self.autoconf = os.path.join(build_dir, 'include', 'autoconf.mk')
         self.spl_autoconf = os.path.join(build_dir, 'spl', 'include',
                                          'autoconf.mk')
-        self.config_autoconf = os.path.join(build_dir, 'include', 'config',
-                                            'auto.conf')
+        self.config_autoconf = os.path.join(build_dir, AUTO_CONF_PATH)
         self.defconfig = os.path.join(build_dir, 'defconfig')
 
     def get_cross_compile(self):
@@ -890,6 +1068,34 @@ class KconfigParser:
 
         return log
 
+
+class DatabaseThread(threading.Thread):
+    """This thread processes results from Slot threads.
+
+    It collects the data in the master config directary. There is only one
+    result thread, and this helps to serialise the build output.
+    """
+    def __init__(self, config_db, db_queue):
+        """Set up a new result thread
+
+        Args:
+            builder: Builder which will be sent each result
+        """
+        threading.Thread.__init__(self)
+        self.config_db = config_db
+        self.db_queue= db_queue
+
+    def run(self):
+        """Called to start up the result thread.
+
+        We collect the next result job and pass it on to the build.
+        """
+        while True:
+            defconfig, configs = self.db_queue.get()
+            self.config_db[defconfig] = configs
+            self.db_queue.task_done()
+
+
 class Slot:
 
     """A slot to store a subprocess.
@@ -899,7 +1105,8 @@ class Slot:
     for faster processing.
     """
 
-    def __init__(self, configs, options, progress, devnull, make_cmd, reference_src_dir):
+    def __init__(self, configs, options, progress, devnull, make_cmd,
+                 reference_src_dir, db_queue):
         """Create a new process slot.
 
         Arguments:
@@ -910,6 +1117,7 @@ class Slot:
           make_cmd: command name of GNU Make.
           reference_src_dir: Determine the true starting config state from this
                              source tree.
+          db_queue: output queue to write config info for the database
         """
         self.options = options
         self.progress = progress
@@ -917,6 +1125,7 @@ class Slot:
         self.devnull = devnull
         self.make_cmd = (make_cmd, 'O=' + self.build_dir)
         self.reference_src_dir = reference_src_dir
+        self.db_queue = db_queue
         self.parser = KconfigParser(configs, options, self.build_dir)
         self.state = STATE_IDLE
         self.failed_boards = set()
@@ -992,6 +1201,8 @@ class Slot:
             if self.current_src_dir:
                 self.current_src_dir = None
                 self.do_defconfig()
+            elif self.options.build_db:
+                self.do_build_db()
             else:
                 self.do_savedefconfig()
         elif self.state == STATE_SAVEDEFCONFIG:
@@ -1022,7 +1233,7 @@ class Slot:
         self.state = STATE_DEFCONFIG
 
     def do_autoconf(self):
-        """Run 'make include/config/auto.conf'."""
+        """Run 'make AUTO_CONF_PATH'."""
 
         self.cross_compile = self.parser.get_cross_compile()
         if self.cross_compile is None:
@@ -1035,12 +1246,23 @@ class Slot:
         if self.cross_compile:
             cmd.append('CROSS_COMPILE=%s' % self.cross_compile)
         cmd.append('KCONFIG_IGNORE_DUPLICATES=1')
-        cmd.append('include/config/auto.conf')
+        cmd.append(AUTO_CONF_PATH)
         self.ps = subprocess.Popen(cmd, stdout=self.devnull,
                                    stderr=subprocess.PIPE,
                                    cwd=self.current_src_dir)
         self.state = STATE_AUTOCONF
 
+    def do_build_db(self):
+        """Add the board to the database"""
+        configs = {}
+        with open(os.path.join(self.build_dir, AUTO_CONF_PATH)) as fd:
+            for line in fd.readlines():
+                if line.startswith('CONFIG'):
+                    config, value = line.split('=', 1)
+                    configs[config] = value.rstrip()
+        self.db_queue.put([self.defconfig, configs])
+        self.finish(True)
+
     def do_savedefconfig(self):
         """Update the .config and run 'make savedefconfig'."""
 
@@ -1123,7 +1345,7 @@ class Slots:
 
     """Controller of the array of subprocess slots."""
 
-    def __init__(self, configs, options, progress, reference_src_dir):
+    def __init__(self, configs, options, progress, reference_src_dir, db_queue):
         """Create a new slots controller.
 
         Arguments:
@@ -1132,6 +1354,7 @@ class Slots:
           progress: A progress indicator.
           reference_src_dir: Determine the true starting config state from this
                              source tree.
+          db_queue: output queue to write config info for the database
         """
         self.options = options
         self.slots = []
@@ -1139,7 +1362,7 @@ class Slots:
         make_cmd = get_make_cmd()
         for i in range(options.jobs):
             self.slots.append(Slot(configs, options, progress, devnull,
-                                   make_cmd, reference_src_dir))
+                                   make_cmd, reference_src_dir, db_queue))
 
     def add(self, defconfig):
         """Add a new subprocess if a vacant slot is found.
@@ -1251,7 +1474,7 @@ class ReferenceSource:
 
         return self.src_dir
 
-def move_config(configs, options):
+def move_config(configs, options, db_queue):
     """Move config options to defconfig files.
 
     Arguments:
@@ -1261,6 +1484,8 @@ def move_config(configs, options):
     if len(configs) == 0:
         if options.force_sync:
             print 'No CONFIG is specified. You are probably syncing defconfigs.',
+        elif options.build_db:
+            print 'Building %s database' % CONFIG_DATABASE
         else:
             print 'Neither CONFIG nor --force-sync is specified. Nothing will happen.',
     else:
@@ -1279,7 +1504,7 @@ def move_config(configs, options):
         defconfigs = get_all_defconfigs()
 
     progress = Progress(len(defconfigs))
-    slots = Slots(configs, options, progress, reference_src_dir)
+    slots = Slots(configs, options, progress, reference_src_dir, db_queue)
 
     # Main loop to process defconfig files:
     #  Add a new subprocess into a vacant slot.
@@ -1298,6 +1523,304 @@ def move_config(configs, options):
     slots.show_failed_boards()
     slots.show_suspicious_boards()
 
+def find_kconfig_rules(kconf, config, imply_config):
+    """Check whether a config has a 'select' or 'imply' keyword
+
+    Args:
+        kconf: Kconfig.Config object
+        config: Name of config to check (without CONFIG_ prefix)
+        imply_config: Implying config (without CONFIG_ prefix) which may or
+            may not have an 'imply' for 'config')
+
+    Returns:
+        Symbol object for 'config' if found, else None
+    """
+    sym = kconf.get_symbol(imply_config)
+    if sym:
+        for sel in sym.get_selected_symbols():
+            if sel.get_name() == config:
+                return sym
+    return None
+
+def check_imply_rule(kconf, config, imply_config):
+    """Check if we can add an 'imply' option
+
+    This finds imply_config in the Kconfig and looks to see if it is possible
+    to add an 'imply' for 'config' to that part of the Kconfig.
+
+    Args:
+        kconf: Kconfig.Config object
+        config: Name of config to check (without CONFIG_ prefix)
+        imply_config: Implying config (without CONFIG_ prefix) which may or
+            may not have an 'imply' for 'config')
+
+    Returns:
+        tuple:
+            filename of Kconfig file containing imply_config, or None if none
+            line number within the Kconfig file, or 0 if none
+            message indicating the result
+    """
+    sym = kconf.get_symbol(imply_config)
+    if not sym:
+        return 'cannot find sym'
+    locs = sym.get_def_locations()
+    if len(locs) != 1:
+        return '%d locations' % len(locs)
+    fname, linenum = locs[0]
+    cwd = os.getcwd()
+    if cwd and fname.startswith(cwd):
+        fname = fname[len(cwd) + 1:]
+    file_line = ' at %s:%d' % (fname, linenum)
+    with open(fname) as fd:
+        data = fd.read().splitlines()
+    if data[linenum - 1] != 'config %s' % imply_config:
+        return None, 0, 'bad sym format %s%s' % (data[linenum], file_line)
+    return fname, linenum, 'adding%s' % file_line
+
+def add_imply_rule(config, fname, linenum):
+    """Add a new 'imply' option to a Kconfig
+
+    Args:
+        config: config option to add an imply for (without CONFIG_ prefix)
+        fname: Kconfig filename to update
+        linenum: Line number to place the 'imply' before
+
+    Returns:
+        Message indicating the result
+    """
+    file_line = ' at %s:%d' % (fname, linenum)
+    data = open(fname).read().splitlines()
+    linenum -= 1
+
+    for offset, line in enumerate(data[linenum:]):
+        if line.strip().startswith('help') or not line:
+            data.insert(linenum + offset, '\timply %s' % config)
+            with open(fname, 'w') as fd:
+                fd.write('\n'.join(data) + '\n')
+            return 'added%s' % file_line
+
+    return 'could not insert%s'
+
+(IMPLY_MIN_2, IMPLY_TARGET, IMPLY_CMD, IMPLY_NON_ARCH_BOARD) = (
+    1, 2, 4, 8)
+
+IMPLY_FLAGS = {
+    'min2': [IMPLY_MIN_2, 'Show options which imply >2 boards (normally >5)'],
+    'target': [IMPLY_TARGET, 'Allow CONFIG_TARGET_... options to imply'],
+    'cmd': [IMPLY_CMD, 'Allow CONFIG_CMD_... to imply'],
+    'non-arch-board': [
+        IMPLY_NON_ARCH_BOARD,
+        'Allow Kconfig options outside arch/ and /board/ to imply'],
+};
+
+def do_imply_config(config_list, add_imply, imply_flags, skip_added,
+                    check_kconfig=True, find_superset=False):
+    """Find CONFIG options which imply those in the list
+
+    Some CONFIG options can be implied by others and this can help to reduce
+    the size of the defconfig files. For example, CONFIG_X86 implies
+    CONFIG_CMD_IRQ, so we can put 'imply CMD_IRQ' under 'config X86' and
+    all x86 boards will have that option, avoiding adding CONFIG_CMD_IRQ to
+    each of the x86 defconfig files.
+
+    This function uses the moveconfig database to find such options. It
+    displays a list of things that could possibly imply those in the list.
+    The algorithm ignores any that start with CONFIG_TARGET since these
+    typically refer to only a few defconfigs (often one). It also does not
+    display a config with less than 5 defconfigs.
+
+    The algorithm works using sets. For each target config in config_list:
+        - Get the set 'defconfigs' which use that target config
+        - For each config (from a list of all configs):
+            - Get the set 'imply_defconfig' of defconfigs which use that config
+            -
+            - If imply_defconfigs contains anything not in defconfigs then
+              this config does not imply the target config
+
+    Params:
+        config_list: List of CONFIG options to check (each a string)
+        add_imply: Automatically add an 'imply' for each config.
+        imply_flags: Flags which control which implying configs are allowed
+           (IMPLY_...)
+        skip_added: Don't show options which already have an imply added.
+        check_kconfig: Check if implied symbols already have an 'imply' or
+            'select' for the target config, and show this information if so.
+        find_superset: True to look for configs which are a superset of those
+            already found. So for example if CONFIG_EXYNOS5 implies an option,
+            but CONFIG_EXYNOS covers a larger set of defconfigs and also
+            implies that option, this will drop the former in favour of the
+            latter. In practice this option has not proved very used.
+
+    Note the terminoloy:
+        config - a CONFIG_XXX options (a string, e.g. 'CONFIG_CMD_EEPROM')
+        defconfig - a defconfig file (a string, e.g. 'configs/snow_defconfig')
+    """
+    kconf = KconfigScanner().conf if check_kconfig else None
+    if add_imply and add_imply != 'all':
+        add_imply = add_imply.split()
+
+    # key is defconfig name, value is dict of (CONFIG_xxx, value)
+    config_db = {}
+
+    # Holds a dict containing the set of defconfigs that contain each config
+    # key is config, value is set of defconfigs using that config
+    defconfig_db = collections.defaultdict(set)
+
+    # Set of all config options we have seen
+    all_configs = set()
+
+    # Set of all defconfigs we have seen
+    all_defconfigs = set()
+
+    # Read in the database
+    configs = {}
+    with open(CONFIG_DATABASE) as fd:
+        for line in fd.readlines():
+            line = line.rstrip()
+            if not line:  # Separator between defconfigs
+                config_db[defconfig] = configs
+                all_defconfigs.add(defconfig)
+                configs = {}
+            elif line[0] == ' ':  # CONFIG line
+                config, value = line.strip().split('=', 1)
+                configs[config] = value
+                defconfig_db[config].add(defconfig)
+                all_configs.add(config)
+            else:  # New defconfig
+                defconfig = line
+
+    # Work through each target config option in tern, independently
+    for config in config_list:
+        defconfigs = defconfig_db.get(config)
+        if not defconfigs:
+            print '%s not found in any defconfig' % config
+            continue
+
+        # Get the set of defconfigs without this one (since a config cannot
+        # imply itself)
+        non_defconfigs = all_defconfigs - defconfigs
+        num_defconfigs = len(defconfigs)
+        print '%s found in %d/%d defconfigs' % (config, num_defconfigs,
+                                                len(all_configs))
+
+        # This will hold the results: key=config, value=defconfigs containing it
+        imply_configs = {}
+        rest_configs = all_configs - set([config])
+
+        # Look at every possible config, except the target one
+        for imply_config in rest_configs:
+            if 'ERRATUM' in imply_config:
+                continue
+            if not (imply_flags & IMPLY_CMD):
+                if 'CONFIG_CMD' in imply_config:
+                    continue
+            if not (imply_flags & IMPLY_TARGET):
+                if 'CONFIG_TARGET' in imply_config:
+                    continue
+
+            # Find set of defconfigs that have this config
+            imply_defconfig = defconfig_db[imply_config]
+
+            # Get the intersection of this with defconfigs containing the
+            # target config
+            common_defconfigs = imply_defconfig & defconfigs
+
+            # Get the set of defconfigs containing this config which DO NOT
+            # also contain the taret config. If this set is non-empty it means
+            # that this config affects other defconfigs as well as (possibly)
+            # the ones affected by the target config. This means it implies
+            # things we don't want to imply.
+            not_common_defconfigs = imply_defconfig & non_defconfigs
+            if not_common_defconfigs:
+                continue
+
+            # If there are common defconfigs, imply_config may be useful
+            if common_defconfigs:
+                skip = False
+                if find_superset:
+                    for prev in imply_configs.keys():
+                        prev_count = len(imply_configs[prev])
+                        count = len(common_defconfigs)
+                        if (prev_count > count and
+                            (imply_configs[prev] & common_defconfigs ==
+                            common_defconfigs)):
+                            # skip imply_config because prev is a superset
+                            skip = True
+                            break
+                        elif count > prev_count:
+                            # delete prev because imply_config is a superset
+                            del imply_configs[prev]
+                if not skip:
+                    imply_configs[imply_config] = common_defconfigs
+
+        # Now we have a dict imply_configs of configs which imply each config
+        # The value of each dict item is the set of defconfigs containing that
+        # config. Rank them so that we print the configs that imply the largest
+        # number of defconfigs first.
+        ranked_iconfigs = sorted(imply_configs,
+                            key=lambda k: len(imply_configs[k]), reverse=True)
+        kconfig_info = ''
+        cwd = os.getcwd()
+        add_list = collections.defaultdict(list)
+        for iconfig in ranked_iconfigs:
+            num_common = len(imply_configs[iconfig])
+
+            # Don't bother if there are less than 5 defconfigs affected.
+            if num_common < (2 if imply_flags & IMPLY_MIN_2 else 5):
+                continue
+            missing = defconfigs - imply_configs[iconfig]
+            missing_str = ', '.join(missing) if missing else 'all'
+            missing_str = ''
+            show = True
+            if kconf:
+                sym = find_kconfig_rules(kconf, config[CONFIG_LEN:],
+                                         iconfig[CONFIG_LEN:])
+                kconfig_info = ''
+                if sym:
+                    locs = sym.get_def_locations()
+                    if len(locs) == 1:
+                        fname, linenum = locs[0]
+                        if cwd and fname.startswith(cwd):
+                            fname = fname[len(cwd) + 1:]
+                        kconfig_info = '%s:%d' % (fname, linenum)
+                        if skip_added:
+                            show = False
+                else:
+                    sym = kconf.get_symbol(iconfig[CONFIG_LEN:])
+                    fname = ''
+                    if sym:
+                        locs = sym.get_def_locations()
+                        if len(locs) == 1:
+                            fname, linenum = locs[0]
+                            if cwd and fname.startswith(cwd):
+                                fname = fname[len(cwd) + 1:]
+                    in_arch_board = not sym or (fname.startswith('arch') or
+                                                fname.startswith('board'))
+                    if (not in_arch_board and
+                        not (imply_flags & IMPLY_NON_ARCH_BOARD)):
+                        continue
+
+                    if add_imply and (add_imply == 'all' or
+                                      iconfig in add_imply):
+                        fname, linenum, kconfig_info = (check_imply_rule(kconf,
+                                config[CONFIG_LEN:], iconfig[CONFIG_LEN:]))
+                        if fname:
+                            add_list[fname].append(linenum)
+
+            if show and kconfig_info != 'skip':
+                print '%5d : %-30s%-25s %s' % (num_common, iconfig.ljust(30),
+                                              kconfig_info, missing_str)
+
+        # Having collected a list of things to add, now we add them. We process
+        # each file from the largest line number to the smallest so that
+        # earlier additions do not affect our line numbers. E.g. if we added an
+        # imply at line 20 it would change the position of each line after
+        # that.
+        for fname, linenums in add_list.iteritems():
+            for linenum in sorted(linenums, reverse=True):
+                add_imply_rule(config[CONFIG_LEN:], fname, linenum)
+
+
 def main():
     try:
         cpu_count = multiprocessing.cpu_count()
@@ -1306,12 +1829,26 @@ def main():
 
     parser = optparse.OptionParser()
     # Add options here
+    parser.add_option('-a', '--add-imply', type='string', default='',
+                      help='comma-separated list of CONFIG options to add '
+                      "an 'imply' statement to for the CONFIG in -i")
+    parser.add_option('-A', '--skip-added', action='store_true', default=False,
+                      help="don't show options which are already marked as "
+                      'implying others')
+    parser.add_option('-b', '--build-db', action='store_true', default=False,
+                      help='build a CONFIG database')
     parser.add_option('-c', '--color', action='store_true', default=False,
                       help='display the log in color')
     parser.add_option('-C', '--commit', action='store_true', default=False,
                       help='Create a git commit for the operation')
     parser.add_option('-d', '--defconfigs', type='string',
-                      help='a file containing a list of defconfigs to move')
+                      help='a file containing a list of defconfigs to move, '
+                      "one per line (for example 'snow_defconfig') "
+                      "or '-' to read from stdin")
+    parser.add_option('-i', '--imply', action='store_true', default=False,
+                      help='find options which imply others')
+    parser.add_option('-I', '--imply-flags', type='string', default='',
+                      help="control the -i option ('help' for help")
     parser.add_option('-n', '--dry-run', action='store_true', default=False,
                       help='perform a trial run (show log with no changes)')
     parser.add_option('-e', '--exit-on-error', action='store_true',
@@ -1336,7 +1873,8 @@ def main():
 
     (options, configs) = parser.parse_args()
 
-    if len(configs) == 0 and not options.force_sync:
+    if len(configs) == 0 and not any((options.force_sync, options.build_db,
+                                      options.imply)):
         parser.print_usage()
         sys.exit(1)
 
@@ -1346,10 +1884,32 @@ def main():
 
     check_top_directory()
 
+    if options.imply:
+        imply_flags = 0
+        for flag in options.imply_flags.split():
+            if flag == 'help' or flag not in IMPLY_FLAGS:
+                print "Imply flags: (separate with ',')"
+                for name, info in IMPLY_FLAGS.iteritems():
+                    print ' %-15s: %s' % (name, info[1])
+                parser.print_usage()
+                sys.exit(1)
+            imply_flags |= IMPLY_FLAGS[flag][0]
+
+        do_imply_config(configs, options.add_imply, imply_flags,
+                        options.skip_added)
+        return
+
+    config_db = {}
+    db_queue = Queue.Queue()
+    t = DatabaseThread(config_db, db_queue)
+    t.setDaemon(True)
+    t.start()
+
     if not options.cleanup_headers_only:
         check_clean_directory()
         update_cross_compile(options.color)
-        move_config(configs, options)
+        move_config(configs, options, db_queue)
+        db_queue.join()
 
     if configs:
         cleanup_headers(configs, options)
@@ -1369,5 +1929,13 @@ def main():
             msg += '\n\nRsync all defconfig files using moveconfig.py'
         subprocess.call(['git', 'commit', '-s', '-m', msg])
 
+    if options.build_db:
+        with open(CONFIG_DATABASE, 'w') as fd:
+            for defconfig, configs in config_db.iteritems():
+                print >>fd, '%s' % defconfig
+                for config in sorted(configs.keys()):
+                    print >>fd, '   %s=%s' % (config, configs[config])
+                print >>fd
+
 if __name__ == '__main__':
     main()