Merge git://git.denx.de/u-boot-dm
authorTom Rini <trini@konsulko.com>
Tue, 17 May 2016 17:58:27 +0000 (13:58 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 17 May 2016 17:58:27 +0000 (13:58 -0400)
137 files changed:
README
api/api_storage.c
arch/arm/dts/exynos4210-universal_c210.dts
arch/arm/dts/tegra20-seaboard.dts
arch/arm/include/asm/arch-ls102xa/config.h
arch/m68k/cpu/mcf5227x/start.S
arch/m68k/cpu/mcf523x/start.S
arch/m68k/cpu/mcf52x2/start.S
arch/m68k/cpu/mcf530x/cpu_init.c
arch/m68k/cpu/mcf530x/start.S
arch/m68k/cpu/mcf532x/start.S
arch/m68k/cpu/mcf5445x/start.S
arch/m68k/cpu/mcf547x_8x/start.S
arch/m68k/include/asm/config.h
arch/sandbox/include/asm/io.h
arch/x86/Kconfig
arch/x86/cpu/broadwell/sata.c
arch/x86/cpu/intel_common/cpu.c
arch/x86/cpu/ivybridge/bd82x6x.c
arch/x86/cpu/ivybridge/sata.c
board/cm5200/fwupdate.c
board/mpl/pip405/README
board/sandbox/MAINTAINERS
cmd/Makefile
cmd/disk.c
cmd/ide.c
cmd/mmc.c
cmd/sata.c
cmd/scsi.c
cmd/usb.c
common/Makefile
common/board_r.c
common/env_mmc.c
common/ide.c [new file with mode: 0644]
common/sata.c [new file with mode: 0644]
common/scsi.c [new file with mode: 0644]
common/spl/spl_mmc.c
common/spl/spl_sata.c
common/spl/spl_usb.c
common/usb_storage.c
configs/sandbox_defconfig
configs/sandbox_noblk_defconfig [new file with mode: 0644]
disk/part.c
drivers/Makefile
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/ahci-uclass.c [new file with mode: 0644]
drivers/block/blk-uclass.c
drivers/block/blk_legacy.c [new file with mode: 0644]
drivers/block/disk-uclass.c [deleted file]
drivers/block/sandbox.c
drivers/block/sandbox_scsi.c [new file with mode: 0644]
drivers/block/sata_sandbox.c [new file with mode: 0644]
drivers/block/sym53c8xx.c
drivers/block/systemace.c
drivers/core/device-remove.c
drivers/core/device.c
drivers/core/lists.c
drivers/dfu/dfu_mmc.c
drivers/gpio/74x164_gpio.c [new file with mode: 0644]
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-uclass.c
drivers/gpio/intel_broadwell_gpio.c
drivers/gpio/omap_gpio.c
drivers/gpio/pca953x_gpio.c [new file with mode: 0644]
drivers/gpio/pic32_gpio.c
drivers/gpio/rk_gpio.c
drivers/gpio/s5p_gpio.c
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/mmc-uclass.c
drivers/mmc/mmc.c
drivers/mmc/mmc_legacy.c [new file with mode: 0644]
drivers/mmc/mmc_private.h
drivers/mmc/mmc_write.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/pic32_sdhci.c
drivers/mmc/rockchip_dw_mmc.c
drivers/mmc/sandbox_mmc.c
drivers/mmc/socfpga_dw_mmc.c
drivers/mmc/uniphier-sd.c
drivers/mmc/zynq_sdhci.c
drivers/pci/pci.c
drivers/serial/mcfuart.c
drivers/spi/soft_spi.c
drivers/spi/spi-uclass.c
drivers/usb/common/Makefile
drivers/usb/common/common.c [new file with mode: 0644]
drivers/video/tegra.c
fs/fat/fat.c
include/asm-generic/gpio.h
include/blk.h
include/config_cmd_all.h
include/config_distro_bootcmd.h
include/config_fallbacks.h
include/configs/MPC8544DS.h
include/configs/MPC8572DS.h
include/configs/MPC8610HPCD.h
include/configs/MPC8641HPCN.h
include/configs/PIP405.h
include/configs/am57xx_evm.h
include/configs/cm_t54.h
include/configs/db-88f6820-gp.h
include/configs/dra7xx_evm.h
include/configs/efi-x86.h
include/configs/galileo.h
include/configs/highbank.h
include/configs/ls1043aqds.h
include/configs/ls2080aqds.h
include/configs/ls2080ardb.h
include/configs/omap5_uevm.h
include/configs/qemu-x86.h
include/configs/sandbox.h
include/configs/sbc8641d.h
include/configs/sunxi-common.h
include/configs/x86-common.h
include/configs/xilinx_zynqmp.h
include/dm/device.h
include/dm/platform_data/serial_coldfire.h [new file with mode: 0644]
include/dm/uclass-id.h
include/ide.h
include/iotrace.h
include/linux/usb/otg.h
include/mmc.h
include/part.h
include/spi.h
include/systemace.h [deleted file]
include/usb.h
lib/efi_loader/efi_disk.c
test/dm/blk.c
test/dm/mmc.c
tools/buildman/README
tools/buildman/builder.py
tools/buildman/builderthread.py
tools/buildman/cmdline.py
tools/buildman/control.py

diff --git a/README b/README
index d881da2de288a26e623dd4e6412c167c93486f0b..94e9943b0460f5a41fab1994e745864e4ff92836 100644 (file)
--- a/README
+++ b/README
@@ -1066,7 +1066,7 @@ 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_CMD_SCSI         * SCSI Support
+               CONFIG_SCSI             * SCSI Support
                CONFIG_CMD_SDRAM        * print SDRAM configuration information
                                          (requires CONFIG_CMD_I2C)
                CONFIG_CMD_SETGETDCR      Support for DCR Register access
@@ -1254,7 +1254,7 @@ The following options need to be configured:
                CONFIG_MTD_PARTITIONS  Memory Technology Device partition table.
 
                If IDE or SCSI support is enabled (CONFIG_CMD_IDE or
-               CONFIG_CMD_SCSI) you must configure support for at
+               CONFIG_SCSI) you must configure support for at
                least one non-MTD partition type as well.
 
 - IDE Reset method:
index 8c30c56e497a1ddf74c2510f7a5eec7c92cccd29..d425a9ad1dbd7fce338e3065b294561c732a4120 100644 (file)
@@ -67,7 +67,7 @@ void dev_stor_init(void)
        specs[ENUM_SATA].type = DEV_TYP_STOR | DT_STOR_SATA;
        specs[ENUM_SATA].name = "sata";
 #endif
-#if defined(CONFIG_CMD_SCSI)
+#if defined(CONFIG_SCSI)
        specs[ENUM_SCSI].max_dev = CONFIG_SYS_SCSI_MAX_DEVICE;
        specs[ENUM_SCSI].enum_started = 0;
        specs[ENUM_SCSI].enum_ended = 0;
index 16948c93422725571ab05f2f7ed6e8977cb38571..ad3527ec6f118324e82e0168681c6d2e7774dec2 100644 (file)
        };
 
        soft-spi {
-               compatible = "u-boot,soft-spi";
-               cs-gpio = <&gpy4 3 0>;
-               sclk-gpio = <&gpy3 1 0>;
-               mosi-gpio = <&gpy3 3 0>;
-               miso-gpio = <&gpy3 0 0>;
+               compatible = "spi-gpio";
+               cs-gpios = <&gpy4 3 0>;
+               gpio-sck = <&gpy3 1 0>;
+               gpio-mosi = <&gpy3 3 0>;
+               gpio-miso = <&gpy3 0 0>;
                spi-delay-us = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
index eada59073efcfd8d41f70e1010a30496ac04b5e0..5893d2a3f84e67ad68d21ab108e442873011710c 100644 (file)
                                nvidia,panel = <&lcd_panel>;
                        };
                };
-
-               dc@54240000 {
-                       status = "disabled";
-               };
        };
 
        /* This is not used in U-Boot, but is expected to be in kernel .dts */
index 267bd17727c619c1475f6f924c6fce916a594151..d77c04a86a3c1d9f6c9e3143d9ada67aaec1c092 100644 (file)
@@ -82,7 +82,7 @@
 /* SATA */
 #define AHCI_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x02200000)
 #define CONFIG_BOARD_LATE_INIT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 23024f94c8586a6d4cff8f754f9b84e57fb57a56..13c036f746edd5d3750bb87515785b72f4472220 100644 (file)
@@ -372,14 +372,29 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for
-          the first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
+
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       bsr     board_init_f_alloc_reserve
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       bsr     board_init_f_init_reserve
 
        bsr cpu_init_f                  /* run low-level CPU init code (from flash) */
+       clr.l   %sp@-
        bsr board_init_f                /* run low-level board init code (from flash) */
 
        /* board_init_f() does not return */
index 1702f98ab1f11c97d7369a476da9722206e327c0..3aa4dd61faaa8b1894d6fc5ff83fd4e2ccca947d 100644 (file)
@@ -134,17 +134,34 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the
-          first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr     (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr     (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index 4af691f5aff7f4ff49845b48463746e2c627044a..a048884f6ce455c0129ff6bf6f08acb59e2989ba 100644 (file)
@@ -192,16 +192,34 @@ _after_flashbar_copy:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5                /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index 80dc23910e095cf50300b37fe61ec7cb29d425b0..b09eed80240341e810b3090a5fa911eda4cb15b2 100644 (file)
@@ -142,7 +142,7 @@ int cpu_init_r(void)
        return 0;
 }
 
-void uart_port_conf(void)
+void uart_port_conf(int port)
 {
 }
 
index 097958afda3eccfc6e9d94d5df4566a6cf869b57..ca8bb320630187713e6d991673ff5a387f795ab1 100644 (file)
@@ -126,21 +126,32 @@ _start:
        move.l  %d0, (%a1)
        move.l  %d0, (%a2)
 
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
+
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
        /*
-        * set stackpointer to internal sram end - 80
-        * (global data struct size + some bytes)
-        * get some stackspace for the first c-code,
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
         */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l   %sp@-
+       move.l  %sp, -(%sp)
+       bsr     board_init_f_alloc_reserve
 
-       /* put relocation table address to a5 */
-       move.l #__got_start, %a5
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       bsr     board_init_f_init_reserve
 
        /* run low-level CPU init code (from flash) */
        bsr cpu_init_f
 
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        bsr board_init_f
 
        /* board_init_f() does not return */
index 131ad6e392e9c48fabe730f46baf97222951528e..f25bc541be7cf6f1110b55d3c5d15669395ce15d 100644 (file)
@@ -148,17 +148,34 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the
-          first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr     (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr     (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index f50f147a4f3e6c4fb1722095998556519ff5e5a1..ba38678be3c1e79dc757df78f99ea960db513957 100644 (file)
@@ -657,17 +657,34 @@ _start:
        movec   %d0, %RAMBAR1
 #endif
 
-       /* set stackpointer to end of internal ram to get some stackspace for
-          the first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
+
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       move.l  #board_init_f_alloc_reserve, %a1
+       jsr     (%a1)
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       move.l  #board_init_f_init_reserve, %a1
+       jsr     (%a1)
 
        /* run low-level CPU init code (from flash) */
        move.l #cpu_init_f, %a1
        jsr (%a1)
        /* run low-level board init code (from flash) */
+       clr.l   %sp@-
        move.l #board_init_f, %a1
        jsr (%a1)
 
index 75de22d37c8a71dbbf10ac19797a5a1d94bf6997..9a87a0da230af6beb465f7dfecbf4fa3eab4f455 100644 (file)
@@ -141,14 +141,29 @@ _start:
        move.l %d0, (%a1)
        move.l %d0, (%a2)
 
-       /* set stackpointer to end of internal ram to get some stackspace for the
-          first c-code */
-       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp
-       clr.l %sp@-
+       /* put relocation table address to a5 */
+       move.l #__got_start, %a5
 
-       move.l #__got_start, %a5        /* put relocation table address to a5 */
+       /* setup stack initially on top of internal static ram  */
+       move.l  #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE), %sp
+
+       /*
+        * if configured, malloc_f arena will be reserved first,
+        * then (and always) gd struct space will be reserved
+        */
+       move.l  %sp, -(%sp)
+       bsr     board_init_f_alloc_reserve
+
+       /* update stack and frame-pointers */
+       move.l  %d0, %sp
+       move.l  %sp, %fp
+
+       /* initialize reserved area */
+       move.l  %d0, -(%sp)
+       bsr     board_init_f_init_reserve
 
        jbsr cpu_init_f                 /* run low-level CPU init code (from flash) */
+       clr.l   %sp@-
        jbsr board_init_f               /* run low-level board init code (from flash) */
 
        /* board_init_f() does not return */
index e1458acd2c76091b5217f163e72e0654973236d0..9c4d3fb8fd7e905fe9ba2bf598d095fea86e8e43 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_
 
-#define CONFIG_SYS_GENERIC_GLOBAL_DATA
-
 #define CONFIG_NEEDS_MANUAL_RELOC
 
 #define CONFIG_LMB
index b87ee19427f10b489865a3b8cff2c6a2cda155d7..69196329d76a5924bb1969c4917910c000d17a29 100644 (file)
@@ -56,6 +56,21 @@ void outl(unsigned int value, unsigned int addr);
 void outw(unsigned int value, unsigned int addr);
 void outb(unsigned int value, unsigned int addr);
 
+static inline void _insw(volatile u16 *port, void *buf, int ns)
+{
+}
+
+static inline void _outsw(volatile u16 *port, const void *buf, int ns)
+{
+}
+
+#define insw(port, buf, ns)            _insw((u16 *)port, buf, ns)
+#define outsw(port, buf, ns)           _outsw((u16 *)port, buf, ns)
+
+/* For systemace.c */
+#define out16(addr, val)
+#define in16(addr)             0
+
 #include <iotrace.h>
 #include <asm/types.h>
 
index 4ef27dc87a38f1fbf421f40735292fcba7d3c833..396023eee8deaf057027cc291d1f284da69536c4 100644 (file)
@@ -47,6 +47,9 @@ source "arch/x86/cpu/queensbay/Kconfig"
 
 # architecture-specific options below
 
+config AHCI
+       default y
+
 config SYS_MALLOC_F_LEN
        default 0x800
 
index dfb8486d0621e2b663bc1cad219f2834745fc8a4..2e4708262c1daa41411a7acc9b3b1e37778d3fbe 100644 (file)
@@ -261,7 +261,7 @@ static const struct udevice_id broadwell_ahci_ids[] = {
 
 U_BOOT_DRIVER(ahci_broadwell_drv) = {
        .name           = "ahci_broadwell",
-       .id             = UCLASS_DISK,
+       .id             = UCLASS_AHCI,
        .of_match       = broadwell_ahci_ids,
        .ofdata_to_platdata     = broadwell_sata_ofdata_to_platdata,
        .probe          = broadwell_sata_probe,
index 93e4505e4de50d635e2e7dd2353437d9115f86fa..0fdef6f3690b50ef1c472fa07fd4b7d8de771634 100644 (file)
@@ -58,7 +58,7 @@ int cpu_common_init(void)
                return -ENODEV;
 
        /* Cause the SATA device to do its early init */
-       uclass_first_device(UCLASS_DISK, &dev);
+       uclass_first_device(UCLASS_AHCI, &dev);
 
        return 0;
 }
index 4c039ac9c67317f50acb2e25440968de8e8958b1..5b58d6c427e9a1547798b867cb4f363840dc522b 100644 (file)
@@ -162,7 +162,7 @@ static int bd82x6x_probe(struct udevice *dev)
                return 0;
 
        /* Cause the SATA device to do its init */
-       uclass_first_device(UCLASS_DISK, &dev);
+       uclass_first_device(UCLASS_AHCI, &dev);
 
        ret = syscon_get_by_driver_data(X86_SYSCON_GMA, &gma_dev);
        if (ret)
index c3d1057c291d5b9aaf022b275b520e00c673b7cd..1ce81959e3ff1ece17ea69855895acb3eff4571c 100644 (file)
@@ -233,7 +233,7 @@ static const struct udevice_id bd82x6x_ahci_ids[] = {
 
 U_BOOT_DRIVER(ahci_ivybridge_drv) = {
        .name           = "ahci_ivybridge",
-       .id             = UCLASS_DISK,
+       .id             = UCLASS_AHCI,
        .of_match       = bd82x6x_ahci_ids,
        .probe          = bd82x6x_sata_probe,
 };
index 2ed90de9d529d41c01bafec0c6ec92407eb97729..4740c8394c5fa699088c2316df10e11f4ea06597 100644 (file)
@@ -105,7 +105,7 @@ static int load_rescue_image(ulong addr)
 
        /* Detect storage device */
        for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) {
-               stor_dev = usb_stor_get_dev(devno);
+               stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
                if (stor_dev->type != DEV_TYPE_UNKNOWN)
                        break;
        }
index e900c56f1591fdebd4b2d94816949c98c39d5b54..f039817b79374d5bbc6722e452b075e94ecfad3c 100644 (file)
@@ -32,8 +32,8 @@ Changed files:
 - include/cmd_bsp.h            added PIP405 commands definitions
 - include/cmd_condefs.h                added Floppy and SCSI support
 - include/cmd_disk.h           changed to work with block device description
-- include/config_LANTEC.h      excluded CONFIG_CMD_FDC and CONFIG_CMD_SCSI
-- include/config_hymod.h       excluded CONFIG_CMD_FDC and CONFIG_CMD_SCSI
+- include/config_LANTEC.h      excluded CONFIG_CMD_FDC and CONFIG_SCSI
+- include/config_hymod.h       excluded CONFIG_CMD_FDC and CONFIG_SCSI
 - include/flash.h              added INTEL_ID_28F320C3T  0x88C488C4
 - include/i2c.h                        added "defined(CONFIG_PIP405)"
 - include/image.h              added IH_OS_U_BOOT, IH_TYPE_FIRMWARE
@@ -86,7 +86,7 @@ section "Changes".
 
 New Commands:
 -------------
-CONFIG_CMD_SCSI        SCSI Support
+CONFIG_SCSI    SCSI Support
 CONFIG_CMF_FDC Floppy disk support
 
 IDE additions:
index 10d88a28a6f6bd3b8ce31c4a8d9063116732f7ea..f5db773a478ec827b525487207013fe1410c0da4 100644 (file)
@@ -4,3 +4,10 @@ S:     Maintained
 F:     board/sandbox/
 F:     include/configs/sandbox.h
 F:     configs/sandbox_defconfig
+
+SANDBOX_NOBLK BOARD
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+F:     board/sandbox/
+F:     include/configs/sandbox.h
+F:     configs/sandbox_noblk_defconfig
index f95759e6704424ea9edfb258d79937d68d783c91..e3e0c74ffc66d4de872466a18b9291c2ee18ae59 100644 (file)
@@ -112,7 +112,7 @@ obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o
 obj-$(CONFIG_SANDBOX) += host.o
 obj-$(CONFIG_CMD_SATA) += sata.o
 obj-$(CONFIG_CMD_SF) += sf.o
-obj-$(CONFIG_CMD_SCSI) += scsi.o
+obj-$(CONFIG_SCSI) += scsi.o
 obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
 obj-$(CONFIG_CMD_SOFTSWITCH) += softswitch.o
@@ -155,12 +155,6 @@ obj-$(CONFIG_CMD_PMIC) += pmic.o
 obj-$(CONFIG_CMD_REGULATOR) += regulator.o
 endif # !CONFIG_SPL_BUILD
 
-ifdef CONFIG_SPL_BUILD
-ifdef CONFIG_SPL_SATA_SUPPORT
-obj-$(CONFIG_CMD_SCSI) += scsi.o
-endif
-endif # CONFIG_SPL_BUILD
-
 obj-$(CONFIG_CMD_BLOB) += blob.o
 
 # core command
index 2fd1717e6a44680107f2c242ab29855a9baaad41..fcc412312719b755eef21e780345b80932175127 100644 (file)
@@ -8,7 +8,7 @@
 #include <command.h>
 #include <part.h>
 
-#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \
+#if defined(CONFIG_CMD_IDE) || defined(CONFIG_SCSI) || \
        defined(CONFIG_USB_STORAGE)
 int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
                    char *const argv[])
index c4c08c8855d131f63e4f22b0266d75757d7f10aa..c942744e72e6b3a71e243e6b5d1f44a7d3b4ebca 100644 (file)
--- a/cmd/ide.c
+++ b/cmd/ide.c
 # include <status_led.h>
 #endif
 
-#ifdef __PPC__
-# define EIEIO         __asm__ volatile ("eieio")
-# define SYNC          __asm__ volatile ("sync")
-#else
-# define EIEIO         /* nothing */
-# define SYNC          /* nothing */
-#endif
-
-/* ------------------------------------------------------------------------- */
-
 /* Current I/O Device  */
 static int curr_device = -1;
 
-/* Current offset for IDE0 / IDE1 bus access   */
-ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = {
-#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
-       CONFIG_SYS_ATA_IDE0_OFFSET,
-#endif
-#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1)
-       CONFIG_SYS_ATA_IDE1_OFFSET,
-#endif
-};
-
-static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS];
-
-struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_IDE_RESET
-static void  ide_reset (void);
-#else
-#define ide_reset()    /* dummy */
-#endif
-
-static void ide_ident(struct blk_desc *dev_desc);
-static uchar ide_wait  (int dev, ulong t);
-
-#define IDE_TIME_OUT   2000    /* 2 sec timeout */
-
-#define ATAPI_TIME_OUT 7000    /* 7 sec timeout (5 sec seems to work...) */
-
-#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
-
-static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
-
-#ifndef CONFIG_SYS_ATA_PORT_ADDR
-#define CONFIG_SYS_ATA_PORT_ADDR(port) (port)
-#endif
-
-#ifdef CONFIG_ATAPI
-static void    atapi_inquiry(struct blk_desc *dev_desc);
-static ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr,
-                       lbaint_t blkcnt, void *buffer);
-#endif
-
-
-/* ------------------------------------------------------------------------- */
-
 int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        int rcode = 0;
@@ -106,79 +51,41 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                        ide_init();
                        return 0;
                } else if (strncmp(argv[1], "inf", 3) == 0) {
-                       int i;
-
-                       putc('\n');
-
-                       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
-                               if (ide_dev_desc[i].type == DEV_TYPE_UNKNOWN)
-                                       continue;  /* list only known devices */
-                               printf("IDE device %d: ", i);
-                               dev_print(&ide_dev_desc[i]);
-                       }
+                       blk_list_devices(IF_TYPE_IDE);
                        return 0;
 
                } else if (strncmp(argv[1], "dev", 3) == 0) {
-                       if ((curr_device < 0)
-                           || (curr_device >= CONFIG_SYS_IDE_MAXDEVICE)) {
-                               puts("\nno IDE devices available\n");
-                               return 1;
+                       if (blk_print_device_num(IF_TYPE_IDE, curr_device)) {
+                               printf("\nno IDE devices available\n");
+                               return CMD_RET_FAILURE;
                        }
-                       printf("\nIDE device %d: ", curr_device);
-                       dev_print(&ide_dev_desc[curr_device]);
+
                        return 0;
                } else if (strncmp(argv[1], "part", 4) == 0) {
-                       int dev, ok;
-
-                       for (ok = 0, dev = 0;
-                            dev < CONFIG_SYS_IDE_MAXDEVICE;
-                            ++dev) {
-                               if (ide_dev_desc[dev].part_type !=
-                                   PART_TYPE_UNKNOWN) {
-                                       ++ok;
-                                       if (dev)
-                                               putc('\n');
-                                       part_print(&ide_dev_desc[dev]);
-                               }
-                       }
-                       if (!ok) {
-                               puts("\nno IDE devices available\n");
-                               rcode++;
-                       }
-                       return rcode;
+                       if (blk_list_part(IF_TYPE_IDE))
+                               printf("\nno IDE devices available\n");
+                       return 1;
                }
                return CMD_RET_USAGE;
        case 3:
                if (strncmp(argv[1], "dev", 3) == 0) {
-                       int dev = (int) simple_strtoul(argv[2], NULL, 10);
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       printf("\nIDE device %d: ", dev);
-                       if (dev >= CONFIG_SYS_IDE_MAXDEVICE) {
-                               puts("unknown device\n");
-                               return 1;
+                       if (!blk_show_device(IF_TYPE_IDE, dev)) {
+                               curr_device = dev;
+                               printf("... is now current device\n");
+                       } else {
+                               return CMD_RET_FAILURE;
                        }
-                       dev_print(&ide_dev_desc[dev]);
-                       /*ide_print (dev); */
-
-                       if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
-                               return 1;
-
-                       curr_device = dev;
-
-                       puts("... is now current device\n");
-
                        return 0;
                } else if (strncmp(argv[1], "part", 4) == 0) {
-                       int dev = (int) simple_strtoul(argv[2], NULL, 10);
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       if (ide_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
-                               part_print(&ide_dev_desc[dev]);
-                       } else {
-                               printf("\nIDE device %d not available\n",
-                                      dev);
-                               rcode = 1;
+                       if (blk_print_part_devnum(IF_TYPE_IDE, dev)) {
+                               printf("\nIDE device %d not available\n", dev);
+                               return CMD_RET_FAILURE;
                        }
-                       return rcode;
+                       return 1;
                }
 
                return CMD_RET_USAGE;
@@ -188,26 +95,22 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                if (strcmp(argv[1], "read") == 0) {
                        ulong addr = simple_strtoul(argv[2], NULL, 16);
                        ulong cnt = simple_strtoul(argv[4], NULL, 16);
-                       struct blk_desc *dev_desc;
                        ulong n;
 
 #ifdef CONFIG_SYS_64BIT_LBA
                        lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
 
-                       printf("\nIDE read: device %d block # %lld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE read: device %d block # %lld, count %ld...",
+                              curr_device, blk, cnt);
 #else
                        lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
 
-                       printf("\nIDE read: device %d block # %ld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE read: device %d block # %ld, count %ld...",
+                              curr_device, blk, cnt);
 #endif
 
-                       dev_desc = &ide_dev_desc[curr_device];
-                       n = blk_dread(dev_desc, blk, cnt, (ulong *)addr);
-                       /* flush cache after read */
-                       flush_cache(addr,
-                                   cnt * ide_dev_desc[curr_device].blksz);
+                       n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt,
+                                           (ulong *)addr);
 
                        printf("%ld blocks read: %s\n",
                               n, (n == cnt) ? "OK" : "ERROR");
@@ -223,19 +126,19 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 #ifdef CONFIG_SYS_64BIT_LBA
                        lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
 
-                       printf("\nIDE write: device %d block # %lld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE write: device %d block # %lld, count %ld...",
+                              curr_device, blk, cnt);
 #else
                        lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
 
-                       printf("\nIDE write: device %d block # %ld, count %ld ... ",
-                               curr_device, blk, cnt);
+                       printf("\nIDE write: device %d block # %ld, count %ld...",
+                              curr_device, blk, cnt);
 #endif
-                       n = ide_write(&ide_dev_desc[curr_device], blk, cnt,
-                                     (ulong *)addr);
+                       n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt,
+                                            (ulong *)addr);
 
-                       printf("%ld blocks written: %s\n",
-                               n, (n == cnt) ? "OK" : "ERROR");
+                       printf("%ld blocks written: %s\n", n,
+                              n == cnt ? "OK" : "ERROR");
                        if (n == cnt)
                                return 0;
                        else
@@ -253,1195 +156,6 @@ int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        return common_diskboot(cmdtp, "ide", argc, argv);
 }
 
-/* ------------------------------------------------------------------------- */
-
-__weak void ide_led(uchar led, uchar status)
-{
-#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */
-       static uchar led_buffer;        /* Buffer for current LED status */
-
-       uchar *led_port = LED_PORT;
-
-       if (status)             /* switch LED on        */
-               led_buffer |= led;
-       else                    /* switch LED off       */
-               led_buffer &= ~led;
-
-       *led_port = led_buffer;
-#endif
-}
-
-#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */
-# define DEVICE_LED(x) 0
-# define LED_IDE1 1
-# define LED_IDE2 2
-#endif
-
-/* ------------------------------------------------------------------------- */
-
-__weak void ide_outb(int dev, int port, unsigned char val)
-{
-       debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
-             dev, port, val,
-             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
-
-#if defined(CONFIG_IDE_AHB)
-       if (port) {
-               /* write command */
-               ide_write_register(dev, port, val);
-       } else {
-               /* write data */
-               outb(val, (ATA_CURR_BASE(dev)));
-       }
-#else
-       outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
-#endif
-}
-
-__weak unsigned char ide_inb(int dev, int port)
-{
-       uchar val;
-
-#if defined(CONFIG_IDE_AHB)
-       val = ide_read_register(dev, port);
-#else
-       val = inb((ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
-#endif
-
-       debug("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
-             dev, port,
-             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)), val);
-       return val;
-}
-
-void ide_init(void)
-{
-       unsigned char c;
-       int i, bus;
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-       extern int ide_devices_found;   /* Initialized in check_ide_device() */
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
-#ifdef CONFIG_IDE_PREINIT
-       WATCHDOG_RESET();
-
-       if (ide_preinit()) {
-               puts("ide_preinit failed\n");
-               return;
-       }
-#endif /* CONFIG_IDE_PREINIT */
-
-       WATCHDOG_RESET();
-
-       /*
-        * Reset the IDE just to be sure.
-        * Light LED's to show
-        */
-       ide_led((LED_IDE1 | LED_IDE2), 1);      /* LED's on     */
-
-       /* ATAPI Drives seems to need a proper IDE Reset */
-       ide_reset();
-
-#ifdef CONFIG_IDE_INIT_POSTRESET
-       WATCHDOG_RESET();
-
-       if (ide_init_postreset()) {
-               puts("ide_preinit_postreset failed\n");
-               return;
-       }
-#endif /* CONFIG_IDE_INIT_POSTRESET */
-
-       /*
-        * Wait for IDE to get ready.
-        * According to spec, this can take up to 31 seconds!
-        */
-       for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) {
-               int dev =
-                       bus * (CONFIG_SYS_IDE_MAXDEVICE /
-                              CONFIG_SYS_IDE_MAXBUS);
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-               /* Skip non-ide devices from probing */
-               if ((ide_devices_found & (1 << bus)) == 0) {
-                       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off */
-                       continue;
-               }
-#endif
-               printf("Bus %d: ", bus);
-
-               ide_bus_ok[bus] = 0;
-
-               /* Select device
-                */
-               udelay(100000); /* 100 ms */
-               ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
-               udelay(100000); /* 100 ms */
-               i = 0;
-               do {
-                       udelay(10000);  /* 10 ms */
-
-                       c = ide_inb(dev, ATA_STATUS);
-                       i++;
-                       if (i > (ATA_RESET_TIME * 100)) {
-                               puts("** Timeout **\n");
-                               /* LED's off */
-                               ide_led((LED_IDE1 | LED_IDE2), 0);
-                               return;
-                       }
-                       if ((i >= 100) && ((i % 100) == 0))
-                               putc('.');
-
-               } while (c & ATA_STAT_BUSY);
-
-               if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
-                       puts("not available  ");
-                       debug("Status = 0x%02X ", c);
-#ifndef CONFIG_ATAPI           /* ATAPI Devices do not set DRDY */
-               } else if ((c & ATA_STAT_READY) == 0) {
-                       puts("not available  ");
-                       debug("Status = 0x%02X ", c);
-#endif
-               } else {
-                       puts("OK ");
-                       ide_bus_ok[bus] = 1;
-               }
-               WATCHDOG_RESET();
-       }
-
-       putc('\n');
-
-       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off    */
-
-       curr_device = -1;
-       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
-               int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
-               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
-               ide_dev_desc[i].if_type = IF_TYPE_IDE;
-               ide_dev_desc[i].devnum = i;
-               ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
-               ide_dev_desc[i].blksz = 0;
-               ide_dev_desc[i].log2blksz =
-                       LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
-               ide_dev_desc[i].lba = 0;
-               ide_dev_desc[i].block_read = ide_read;
-               ide_dev_desc[i].block_write = ide_write;
-               if (!ide_bus_ok[IDE_BUS(i)])
-                       continue;
-               ide_led(led, 1);        /* LED on       */
-               ide_ident(&ide_dev_desc[i]);
-               ide_led(led, 0);        /* LED off      */
-               dev_print(&ide_dev_desc[i]);
-
-               if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
-                       /* initialize partition type */
-                       part_init(&ide_dev_desc[i]);
-                       if (curr_device < 0)
-                               curr_device = i;
-               }
-       }
-       WATCHDOG_RESET();
-}
-
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *ide_get_dev(int dev)
-{
-       return (dev < CONFIG_SYS_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL;
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-
-/* We only need to swap data if we are running on a big endian cpu. */
-#if defined(__LITTLE_ENDIAN)
-__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
-{
-       ide_input_data(dev, sect_buf, words);
-}
-#else
-__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
-{
-       volatile ushort *pbuf =
-               (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       ushort *dbuf = (ushort *) sect_buf;
-
-       debug("in input swap data base for read is %lx\n",
-             (unsigned long) pbuf);
-
-       while (words--) {
-#ifdef __MIPS__
-               *dbuf++ = swab16p((u16 *) pbuf);
-               *dbuf++ = swab16p((u16 *) pbuf);
-#else
-               *dbuf++ = ld_le16(pbuf);
-               *dbuf++ = ld_le16(pbuf);
-#endif /* !MIPS */
-       }
-}
-#endif /* __LITTLE_ENDIAN */
-
-
-#if defined(CONFIG_IDE_SWAP_IO)
-__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-       while (words--) {
-               EIEIO;
-               *pbuf = *dbuf++;
-               EIEIO;
-               *pbuf = *dbuf++;
-       }
-}
-#else  /* ! CONFIG_IDE_SWAP_IO */
-__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
-{
-#if defined(CONFIG_IDE_AHB)
-       ide_write_data(dev, sect_buf, words);
-#else
-       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
-#endif
-}
-#endif /* CONFIG_IDE_SWAP_IO */
-
-#if defined(CONFIG_IDE_SWAP_IO)
-__weak void ide_input_data(int dev, ulong *sect_buf, int words)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-
-       debug("in input data base for read is %lx\n", (unsigned long) pbuf);
-
-       while (words--) {
-               EIEIO;
-               *dbuf++ = *pbuf;
-               EIEIO;
-               *dbuf++ = *pbuf;
-       }
-}
-#else  /* ! CONFIG_IDE_SWAP_IO */
-__weak void ide_input_data(int dev, ulong *sect_buf, int words)
-{
-#if defined(CONFIG_IDE_AHB)
-       ide_read_data(dev, sect_buf, words);
-#else
-       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
-#endif
-}
-
-#endif /* CONFIG_IDE_SWAP_IO */
-
-/* -------------------------------------------------------------------------
- */
-static void ide_ident(struct blk_desc *dev_desc)
-{
-       unsigned char c;
-       hd_driveid_t iop;
-
-#ifdef CONFIG_ATAPI
-       int retries = 0;
-#endif
-       int device;
-
-       device = dev_desc->devnum;
-       printf("  Device %d: ", device);
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-       /* Select device
-        */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       dev_desc->if_type = IF_TYPE_IDE;
-#ifdef CONFIG_ATAPI
-
-       retries = 0;
-
-       /* Warning: This will be tricky to read */
-       while (retries <= 1) {
-               /* check signature */
-               if ((ide_inb(device, ATA_SECT_CNT) == 0x01) &&
-                   (ide_inb(device, ATA_SECT_NUM) == 0x01) &&
-                   (ide_inb(device, ATA_CYL_LOW) == 0x14) &&
-                   (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) {
-                       /* ATAPI Signature found */
-                       dev_desc->if_type = IF_TYPE_ATAPI;
-                       /*
-                        * Start Ident Command
-                        */
-                       ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT);
-                       /*
-                        * Wait for completion - ATAPI devices need more time
-                        * to become ready
-                        */
-                       c = ide_wait(device, ATAPI_TIME_OUT);
-               } else
-#endif
-               {
-                       /*
-                        * Start Ident Command
-                        */
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT);
-
-                       /*
-                        * Wait for completion
-                        */
-                       c = ide_wait(device, IDE_TIME_OUT);
-               }
-               ide_led(DEVICE_LED(device), 0); /* LED off      */
-
-               if (((c & ATA_STAT_DRQ) == 0) ||
-                   ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) {
-#ifdef CONFIG_ATAPI
-                       {
-                               /*
-                                * Need to soft reset the device
-                                * in case it's an ATAPI...
-                                */
-                               debug("Retrying...\n");
-                               ide_outb(device, ATA_DEV_HD,
-                                        ATA_LBA | ATA_DEVICE(device));
-                               udelay(100000);
-                               ide_outb(device, ATA_COMMAND, 0x08);
-                               udelay(500000); /* 500 ms */
-                       }
-                       /*
-                        * Select device
-                        */
-                       ide_outb(device, ATA_DEV_HD,
-                                ATA_LBA | ATA_DEVICE(device));
-                       retries++;
-#else
-                       return;
-#endif
-               }
-#ifdef CONFIG_ATAPI
-               else
-                       break;
-       }                       /* see above - ugly to read */
-
-       if (retries == 2)       /* Not found */
-               return;
-#endif
-
-       ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);
-
-       ident_cpy((unsigned char *) dev_desc->revision, iop.fw_rev,
-                 sizeof(dev_desc->revision));
-       ident_cpy((unsigned char *) dev_desc->vendor, iop.model,
-                 sizeof(dev_desc->vendor));
-       ident_cpy((unsigned char *) dev_desc->product, iop.serial_no,
-                 sizeof(dev_desc->product));
-#ifdef __LITTLE_ENDIAN
-       /*
-        * firmware revision, model, and serial number have Big Endian Byte
-        * order in Word. Convert all three to little endian.
-        *
-        * See CF+ and CompactFlash Specification Revision 2.0:
-        * 6.2.1.6: Identify Drive, Table 39 for more details
-        */
-
-       strswab(dev_desc->revision);
-       strswab(dev_desc->vendor);
-       strswab(dev_desc->product);
-#endif /* __LITTLE_ENDIAN */
-
-       if ((iop.config & 0x0080) == 0x0080)
-               dev_desc->removable = 1;
-       else
-               dev_desc->removable = 0;
-
-#ifdef CONFIG_ATAPI
-       if (dev_desc->if_type == IF_TYPE_ATAPI) {
-               atapi_inquiry(dev_desc);
-               return;
-       }
-#endif /* CONFIG_ATAPI */
-
-#ifdef __BIG_ENDIAN
-       /* swap shorts */
-       dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16);
-#else  /* ! __BIG_ENDIAN */
-       /*
-        * do not swap shorts on little endian
-        *
-        * See CF+ and CompactFlash Specification Revision 2.0:
-        * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details.
-        */
-       dev_desc->lba = iop.lba_capacity;
-#endif /* __BIG_ENDIAN */
-
-#ifdef CONFIG_LBA48
-       if (iop.command_set_2 & 0x0400) {       /* LBA 48 support */
-               dev_desc->lba48 = 1;
-               dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] |
-                       ((unsigned long long) iop.lba48_capacity[1] << 16) |
-                       ((unsigned long long) iop.lba48_capacity[2] << 32) |
-                       ((unsigned long long) iop.lba48_capacity[3] << 48);
-       } else {
-               dev_desc->lba48 = 0;
-       }
-#endif /* CONFIG_LBA48 */
-       /* assuming HD */
-       dev_desc->type = DEV_TYPE_HARDDISK;
-       dev_desc->blksz = ATA_BLOCKSIZE;
-       dev_desc->log2blksz = LOG2(dev_desc->blksz);
-       dev_desc->lun = 0;      /* just to fill something in... */
-
-#if 0                          /* only used to test the powersaving mode,
-                                * if enabled, the drive goes after 5 sec
-                                * in standby mode */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       c = ide_wait(device, IDE_TIME_OUT);
-       ide_outb(device, ATA_SECT_CNT, 1);
-       ide_outb(device, ATA_LBA_LOW, 0);
-       ide_outb(device, ATA_LBA_MID, 0);
-       ide_outb(device, ATA_LBA_HIGH, 0);
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       ide_outb(device, ATA_COMMAND, 0xe3);
-       udelay(50);
-       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
-#endif
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-              void *buffer)
-{
-       int device = block_dev->devnum;
-       ulong n = 0;
-       unsigned char c;
-       unsigned char pwrsave = 0;      /* power save */
-
-#ifdef CONFIG_LBA48
-       unsigned char lba48 = 0;
-
-       if (blknr & 0x0000fffff0000000ULL) {
-               /* more than 28 bits used, use 48bit mode */
-               lba48 = 1;
-       }
-#endif
-       debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
-             device, blknr, blkcnt, (ulong) buffer);
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
-       /* Select device
-        */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       c = ide_wait(device, IDE_TIME_OUT);
-
-       if (c & ATA_STAT_BUSY) {
-               printf("IDE read: device %d not ready\n", device);
-               goto IDE_READ_E;
-       }
-
-       /* first check if the drive is in Powersaving mode, if yes,
-        * increase the timeout value */
-       ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR);
-       udelay(50);
-
-       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
-
-       if (c & ATA_STAT_BUSY) {
-               printf("IDE read: device %d not ready\n", device);
-               goto IDE_READ_E;
-       }
-       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
-               printf("No Powersaving mode %X\n", c);
-       } else {
-               c = ide_inb(device, ATA_SECT_CNT);
-               debug("Powersaving %02X\n", c);
-               if (c == 0)
-                       pwrsave = 1;
-       }
-
-
-       while (blkcnt-- > 0) {
-
-               c = ide_wait(device, IDE_TIME_OUT);
-
-               if (c & ATA_STAT_BUSY) {
-                       printf("IDE read: device %d not ready\n", device);
-                       break;
-               }
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       /* write high bits */
-                       ide_outb(device, ATA_SECT_CNT, 0);
-                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
-#ifdef CONFIG_SYS_64BIT_LBA
-                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
-                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
-#else
-                       ide_outb(device, ATA_LBA_MID, 0);
-                       ide_outb(device, ATA_LBA_HIGH, 0);
-#endif
-               }
-#endif
-               ide_outb(device, ATA_SECT_CNT, 1);
-               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
-               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
-               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
-
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       ide_outb(device, ATA_DEV_HD,
-                                ATA_LBA | ATA_DEVICE(device));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT);
-
-               } else
-#endif
-               {
-                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
-                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ);
-               }
-
-               udelay(50);
-
-               if (pwrsave) {
-                       /* may take up to 4 sec */
-                       c = ide_wait(device, IDE_SPIN_UP_TIME_OUT);
-                       pwrsave = 0;
-               } else {
-                       /* can't take over 500 ms */
-                       c = ide_wait(device, IDE_TIME_OUT);
-               }
-
-               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
-                   ATA_STAT_DRQ) {
-                       printf("Error (no IRQ) dev %d blk " LBAF ": status "
-                              "%#02x\n", device, blknr, c);
-                       break;
-               }
-
-               ide_input_data(device, buffer, ATA_SECTORWORDS);
-               (void) ide_inb(device, ATA_STATUS);     /* clear IRQ */
-
-               ++n;
-               ++blknr;
-               buffer += ATA_BLOCKSIZE;
-       }
-IDE_READ_E:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
-       return (n);
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-               const void *buffer)
-{
-       int device = block_dev->devnum;
-       ulong n = 0;
-       unsigned char c;
-
-#ifdef CONFIG_LBA48
-       unsigned char lba48 = 0;
-
-       if (blknr & 0x0000fffff0000000ULL) {
-               /* more than 28 bits used, use 48bit mode */
-               lba48 = 1;
-       }
-#endif
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
-       /* Select device
-        */
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-
-       while (blkcnt-- > 0) {
-
-               c = ide_wait(device, IDE_TIME_OUT);
-
-               if (c & ATA_STAT_BUSY) {
-                       printf("IDE read: device %d not ready\n", device);
-                       goto WR_OUT;
-               }
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       /* write high bits */
-                       ide_outb(device, ATA_SECT_CNT, 0);
-                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
-#ifdef CONFIG_SYS_64BIT_LBA
-                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
-                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
-#else
-                       ide_outb(device, ATA_LBA_MID, 0);
-                       ide_outb(device, ATA_LBA_HIGH, 0);
-#endif
-               }
-#endif
-               ide_outb(device, ATA_SECT_CNT, 1);
-               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
-               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
-               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
-
-#ifdef CONFIG_LBA48
-               if (lba48) {
-                       ide_outb(device, ATA_DEV_HD,
-                                ATA_LBA | ATA_DEVICE(device));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT);
-
-               } else
-#endif
-               {
-                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
-                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
-                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE);
-               }
-
-               udelay(50);
-
-               /* can't take over 500 ms */
-               c = ide_wait(device, IDE_TIME_OUT);
-
-               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
-                   ATA_STAT_DRQ) {
-                       printf("Error (no IRQ) dev %d blk " LBAF ": status "
-                               "%#02x\n", device, blknr, c);
-                       goto WR_OUT;
-               }
-
-               ide_output_data(device, buffer, ATA_SECTORWORDS);
-               c = ide_inb(device, ATA_STATUS);        /* clear IRQ */
-               ++n;
-               ++blknr;
-               buffer += ATA_BLOCKSIZE;
-       }
-WR_OUT:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
-       return (n);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * copy src to dest, skipping leading and trailing blanks and null
- * terminate the string
- * "len" is the size of available memory including the terminating '\0'
- */
-static void ident_cpy(unsigned char *dst, unsigned char *src,
-                     unsigned int len)
-{
-       unsigned char *end, *last;
-
-       last = dst;
-       end = src + len - 1;
-
-       /* reserve space for '\0' */
-       if (len < 2)
-               goto OUT;
-
-       /* skip leading white space */
-       while ((*src) && (src < end) && (*src == ' '))
-               ++src;
-
-       /* copy string, omitting trailing white space */
-       while ((*src) && (src < end)) {
-               *dst++ = *src;
-               if (*src++ != ' ')
-                       last = dst;
-       }
-OUT:
-       *last = '\0';
-}
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * Wait until Busy bit is off, or timeout (in ms)
- * Return last status
- */
-static uchar ide_wait(int dev, ulong t)
-{
-       ulong delay = 10 * t;   /* poll every 100 us */
-       uchar c;
-
-       while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
-               udelay(100);
-               if (delay-- == 0)
-                       break;
-       }
-       return (c);
-}
-
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_IDE_RESET
-extern void ide_set_reset(int idereset);
-
-static void ide_reset(void)
-{
-       int i;
-
-       curr_device = -1;
-       for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i)
-               ide_bus_ok[i] = 0;
-       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i)
-               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
-
-       ide_set_reset(1);       /* assert reset */
-
-       /* the reset signal shall be asserted for et least 25 us */
-       udelay(25);
-
-       WATCHDOG_RESET();
-
-       /* de-assert RESET signal */
-       ide_set_reset(0);
-
-       /* wait 250 ms */
-       for (i = 0; i < 250; ++i)
-               udelay(1000);
-}
-
-#endif /* CONFIG_IDE_RESET */
-
-/* ------------------------------------------------------------------------- */
-
-#if defined(CONFIG_OF_IDE_FIXUP)
-int ide_device_present(int dev)
-{
-       if (dev >= CONFIG_SYS_IDE_MAXBUS)
-               return 0;
-       return (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN ? 0 : 1);
-}
-#endif
-/* ------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ATAPI
-/****************************************************************************
- * ATAPI Support
- */
-
-#if defined(CONFIG_IDE_SWAP_IO)
-/* since ATAPI may use commands with not 4 bytes alligned length
- * we have our own transfer functions, 2 bytes alligned */
-__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-
-       debug("in output data shorts base for read is %lx\n",
-             (unsigned long) pbuf);
-
-       while (shorts--) {
-               EIEIO;
-               *pbuf = *dbuf++;
-       }
-}
-
-__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       ushort *dbuf;
-       volatile ushort *pbuf;
-
-       pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-       dbuf = (ushort *) sect_buf;
-
-       debug("in input data shorts base for read is %lx\n",
-             (unsigned long) pbuf);
-
-       while (shorts--) {
-               EIEIO;
-               *dbuf++ = *pbuf;
-       }
-}
-
-#else  /* ! CONFIG_IDE_SWAP_IO */
-__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
-}
-
-__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
-{
-       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
-}
-
-#endif /* CONFIG_IDE_SWAP_IO */
-
-/*
- * Wait until (Status & mask) == res, or timeout (in ms)
- * Return last status
- * This is used since some ATAPI CD ROMs clears their Busy Bit first
- * and then they set their DRQ Bit
- */
-static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res)
-{
-       ulong delay = 10 * t;   /* poll every 100 us */
-       uchar c;
-
-       /* prevents to read the status before valid */
-       c = ide_inb(dev, ATA_DEV_CTL);
-
-       while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) {
-               /* break if error occurs (doesn't make sense to wait more) */
-               if ((c & ATA_STAT_ERR) == ATA_STAT_ERR)
-                       break;
-               udelay(100);
-               if (delay-- == 0)
-                       break;
-       }
-       return (c);
-}
-
-/*
- * issue an atapi command
- */
-unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
-                         unsigned char *buffer, int buflen)
-{
-       unsigned char c, err, mask, res;
-       int n;
-
-       ide_led(DEVICE_LED(device), 1); /* LED on       */
-
-       /* Select device
-        */
-       mask = ATA_STAT_BUSY | ATA_STAT_DRQ;
-       res = 0;
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-       if ((c & mask) != res) {
-               printf("ATAPI_ISSUE: device %d not ready status %X\n", device,
-                      c);
-               err = 0xFF;
-               goto AI_OUT;
-       }
-       /* write taskfile */
-       ide_outb(device, ATA_ERROR_REG, 0);     /* no DMA, no overlaped */
-       ide_outb(device, ATA_SECT_CNT, 0);
-       ide_outb(device, ATA_SECT_NUM, 0);
-       ide_outb(device, ATA_CYL_LOW, (unsigned char) (buflen & 0xFF));
-       ide_outb(device, ATA_CYL_HIGH,
-                (unsigned char) ((buflen >> 8) & 0xFF));
-       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-
-       ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
-       udelay(50);
-
-       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
-       res = ATA_STAT_DRQ;
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-
-       if ((c & mask) != res) {        /* DRQ must be 1, BSY 0 */
-               printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",
-                       device, c);
-               err = 0xFF;
-               goto AI_OUT;
-       }
-
-       /* write command block */
-       ide_output_data_shorts(device, (unsigned short *) ccb, ccblen / 2);
-
-       /* ATAPI Command written wait for completition */
-       udelay(5000);           /* device must set bsy */
-
-       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
-       /*
-        * if no data wait for DRQ = 0 BSY = 0
-        * if data wait for DRQ = 1 BSY = 0
-        */
-       res = 0;
-       if (buflen)
-               res = ATA_STAT_DRQ;
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-       if ((c & mask) != res) {
-               if (c & ATA_STAT_ERR) {
-                       err = (ide_inb(device, ATA_ERROR_REG)) >> 4;
-                       debug("atapi_issue 1 returned sense key %X status %02X\n",
-                               err, c);
-               } else {
-                       printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x)  status 0x%02x\n",
-                               ccb[0], c);
-                       err = 0xFF;
-               }
-               goto AI_OUT;
-       }
-       n = ide_inb(device, ATA_CYL_HIGH);
-       n <<= 8;
-       n += ide_inb(device, ATA_CYL_LOW);
-       if (n > buflen) {
-               printf("ERROR, transfer bytes %d requested only %d\n", n,
-                      buflen);
-               err = 0xff;
-               goto AI_OUT;
-       }
-       if ((n == 0) && (buflen < 0)) {
-               printf("ERROR, transfer bytes %d requested %d\n", n, buflen);
-               err = 0xff;
-               goto AI_OUT;
-       }
-       if (n != buflen) {
-               debug("WARNING, transfer bytes %d not equal with requested %d\n",
-                       n, buflen);
-       }
-       if (n != 0) {           /* data transfer */
-               debug("ATAPI_ISSUE: %d Bytes to transfer\n", n);
-               /* we transfer shorts */
-               n >>= 1;
-               /* ok now decide if it is an in or output */
-               if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) {
-                       debug("Write to device\n");
-                       ide_output_data_shorts(device,
-                               (unsigned short *) buffer, n);
-               } else {
-                       debug("Read from device @ %p shorts %d\n", buffer, n);
-                       ide_input_data_shorts(device,
-                               (unsigned short *) buffer, n);
-               }
-       }
-       udelay(5000);           /* seems that some CD ROMs need this... */
-       mask = ATA_STAT_BUSY | ATA_STAT_ERR;
-       res = 0;
-       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
-               err = (ide_inb(device, ATA_ERROR_REG) >> 4);
-               debug("atapi_issue 2 returned sense key %X status %X\n", err,
-                     c);
-       } else {
-               err = 0;
-       }
-AI_OUT:
-       ide_led(DEVICE_LED(device), 0); /* LED off      */
-       return (err);
-}
-
-/*
- * sending the command to atapi_issue. If an status other than good
- * returns, an request_sense will be issued
- */
-
-#define ATAPI_DRIVE_NOT_READY  100
-#define ATAPI_UNIT_ATTN                10
-
-unsigned char atapi_issue_autoreq(int device,
-                                 unsigned char *ccb,
-                                 int ccblen,
-                                 unsigned char *buffer, int buflen)
-{
-       unsigned char sense_data[18], sense_ccb[12];
-       unsigned char res, key, asc, ascq;
-       int notready, unitattn;
-
-       unitattn = ATAPI_UNIT_ATTN;
-       notready = ATAPI_DRIVE_NOT_READY;
-
-retry:
-       res = atapi_issue(device, ccb, ccblen, buffer, buflen);
-       if (res == 0)
-               return 0;       /* Ok */
-
-       if (res == 0xFF)
-               return 0xFF;    /* error */
-
-       debug("(auto_req)atapi_issue returned sense key %X\n", res);
-
-       memset(sense_ccb, 0, sizeof(sense_ccb));
-       memset(sense_data, 0, sizeof(sense_data));
-       sense_ccb[0] = ATAPI_CMD_REQ_SENSE;
-       sense_ccb[4] = 18;      /* allocation Length */
-
-       res = atapi_issue(device, sense_ccb, 12, sense_data, 18);
-       key = (sense_data[2] & 0xF);
-       asc = (sense_data[12]);
-       ascq = (sense_data[13]);
-
-       debug("ATAPI_CMD_REQ_SENSE returned %x\n", res);
-       debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
-             sense_data[0], key, asc, ascq);
-
-       if ((key == 0))
-               return 0;       /* ok device ready */
-
-       if ((key == 6) || (asc == 0x29) || (asc == 0x28)) { /* Unit Attention */
-               if (unitattn-- > 0) {
-                       udelay(200 * 1000);
-                       goto retry;
-               }
-               printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN);
-               goto error;
-       }
-       if ((asc == 0x4) && (ascq == 0x1)) {
-               /* not ready, but will be ready soon */
-               if (notready-- > 0) {
-                       udelay(200 * 1000);
-                       goto retry;
-               }
-               printf("Drive not ready, tried %d times\n",
-                      ATAPI_DRIVE_NOT_READY);
-               goto error;
-       }
-       if (asc == 0x3a) {
-               debug("Media not present\n");
-               goto error;
-       }
-
-       printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc,
-              ascq);
-error:
-       debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq);
-       return (0xFF);
-}
-
-
-static void atapi_inquiry(struct blk_desc *dev_desc)
-{
-       unsigned char ccb[12];  /* Command descriptor block */
-       unsigned char iobuf[64];        /* temp buf */
-       unsigned char c;
-       int device;
-
-       device = dev_desc->devnum;
-       dev_desc->type = DEV_TYPE_UNKNOWN;      /* not yet valid */
-       dev_desc->block_read = atapi_read;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-
-       ccb[0] = ATAPI_CMD_INQUIRY;
-       ccb[4] = 40;            /* allocation Legnth */
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 40);
-
-       debug("ATAPI_CMD_INQUIRY returned %x\n", c);
-       if (c != 0)
-               return;
-
-       /* copy device ident strings */
-       ident_cpy((unsigned char *) dev_desc->vendor, &iobuf[8], 8);
-       ident_cpy((unsigned char *) dev_desc->product, &iobuf[16], 16);
-       ident_cpy((unsigned char *) dev_desc->revision, &iobuf[32], 5);
-
-       dev_desc->lun = 0;
-       dev_desc->lba = 0;
-       dev_desc->blksz = 0;
-       dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
-       dev_desc->type = iobuf[0] & 0x1f;
-
-       if ((iobuf[1] & 0x80) == 0x80)
-               dev_desc->removable = 1;
-       else
-               dev_desc->removable = 0;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-       ccb[0] = ATAPI_CMD_START_STOP;
-       ccb[4] = 0x03;          /* start */
-
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 0);
-
-       debug("ATAPI_CMD_START_STOP returned %x\n", c);
-       if (c != 0)
-               return;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 0);
-
-       debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c);
-       if (c != 0)
-               return;
-
-       memset(ccb, 0, sizeof(ccb));
-       memset(iobuf, 0, sizeof(iobuf));
-       ccb[0] = ATAPI_CMD_READ_CAP;
-       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 8);
-       debug("ATAPI_CMD_READ_CAP returned %x\n", c);
-       if (c != 0)
-               return;
-
-       debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
-             iobuf[0], iobuf[1], iobuf[2], iobuf[3],
-             iobuf[4], iobuf[5], iobuf[6], iobuf[7]);
-
-       dev_desc->lba = ((unsigned long) iobuf[0] << 24) +
-               ((unsigned long) iobuf[1] << 16) +
-               ((unsigned long) iobuf[2] << 8) + ((unsigned long) iobuf[3]);
-       dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
-               ((unsigned long) iobuf[5] << 16) +
-               ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
-       dev_desc->log2blksz = LOG2(dev_desc->blksz);
-#ifdef CONFIG_LBA48
-       /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
-       dev_desc->lba48 = 0;
-#endif
-       return;
-}
-
-
-/*
- * atapi_read:
- * we transfer only one block per command, since the multiple DRQ per
- * command is not yet implemented
- */
-#define ATAPI_READ_MAX_BYTES   2048    /* we read max 2kbytes */
-#define ATAPI_READ_BLOCK_SIZE  2048    /* assuming CD part */
-#define ATAPI_READ_MAX_BLOCK   (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
-
-ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-                void *buffer)
-{
-       int device = block_dev->devnum;
-       ulong n = 0;
-       unsigned char ccb[12];  /* Command descriptor block */
-       ulong cnt;
-
-       debug("atapi_read dev %d start " LBAF " blocks " LBAF " buffer at %lX\n",
-             device, blknr, blkcnt, (ulong) buffer);
-
-       do {
-               if (blkcnt > ATAPI_READ_MAX_BLOCK)
-                       cnt = ATAPI_READ_MAX_BLOCK;
-               else
-                       cnt = blkcnt;
-
-               ccb[0] = ATAPI_CMD_READ_12;
-               ccb[1] = 0;     /* reserved */
-               ccb[2] = (unsigned char) (blknr >> 24) & 0xFF;  /* MSB Block */
-               ccb[3] = (unsigned char) (blknr >> 16) & 0xFF;  /*  */
-               ccb[4] = (unsigned char) (blknr >> 8) & 0xFF;
-               ccb[5] = (unsigned char) blknr & 0xFF;  /* LSB Block */
-               ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */
-               ccb[7] = (unsigned char) (cnt >> 16) & 0xFF;
-               ccb[8] = (unsigned char) (cnt >> 8) & 0xFF;
-               ccb[9] = (unsigned char) cnt & 0xFF;    /* LSB Block */
-               ccb[10] = 0;    /* reserved */
-               ccb[11] = 0;    /* reserved */
-
-               if (atapi_issue_autoreq(device, ccb, 12,
-                                       (unsigned char *) buffer,
-                                       cnt * ATAPI_READ_BLOCK_SIZE)
-                   == 0xFF) {
-                       return (n);
-               }
-               n += cnt;
-               blkcnt -= cnt;
-               blknr += cnt;
-               buffer += (cnt * ATAPI_READ_BLOCK_SIZE);
-       } while (blkcnt > 0);
-       return (n);
-}
-
-/* ------------------------------------------------------------------------- */
-
-#endif /* CONFIG_ATAPI */
-
 U_BOOT_CMD(ide, 5, 1, do_ide,
           "IDE sub-system",
           "reset - reset IDE controller\n"
index c5454bf2e130fac5b5d577fbfb2ee97ed3aaa268..eb4a547a9707939c71ad5396fe2fe386d9912084 100644 (file)
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -314,12 +314,14 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
        }
        /* Switch to the RPMB partition */
        original_part = mmc->block_dev.hwpart;
-       if (mmc_select_hwpart(curr_device, MMC_PART_RPMB) != 0)
+       if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) !=
+           0)
                return CMD_RET_FAILURE;
        ret = cp->cmd(cmdtp, flag, argc, argv);
 
        /* Return to original partition */
-       if (mmc_select_hwpart(curr_device, original_part) != 0)
+       if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) !=
+           0)
                return CMD_RET_FAILURE;
        return ret;
 }
@@ -346,7 +348,7 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
        printf("\nMMC read: dev # %d, block # %d, count %d ... ",
               curr_device, blk, cnt);
 
-       n = blk_dread(&mmc->block_dev, blk, cnt, addr);
+       n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
        /* flush cache after read */
        flush_cache((ulong)addr, cnt * 512); /* FIXME */
        printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
@@ -378,7 +380,7 @@ static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
                printf("Error: card is write protected!\n");
                return CMD_RET_FAILURE;
        }
-       n = blk_dwrite(&mmc->block_dev, blk, cnt, addr);
+       n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
        printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
@@ -406,7 +408,7 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
                printf("Error: card is write protected!\n");
                return CMD_RET_FAILURE;
        }
-       n = blk_derase(&mmc->block_dev, blk, cnt);
+       n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt);
        printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR");
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
@@ -432,7 +434,7 @@ static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
        if (!mmc)
                return CMD_RET_FAILURE;
 
-       mmc_dev = mmc_get_dev(curr_device);
+       mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device);
        if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
                part_print(mmc_dev);
                return CMD_RET_SUCCESS;
@@ -467,7 +469,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
        if (!mmc)
                return CMD_RET_FAILURE;
 
-       ret = mmc_select_hwpart(dev, part);
+       ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
        printf("switch to partitions #%d, %s\n",
               part, (!ret) ? "OK" : "ERROR");
        if (ret)
@@ -478,7 +480,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
                printf("mmc%d is current device\n", curr_device);
        else
                printf("mmc%d(part %d) is current device\n",
-                      curr_device, mmc->block_dev.hwpart);
+                      curr_device, mmc_get_blk_desc(mmc)->hwpart);
 
        return CMD_RET_SUCCESS;
 }
index 8748ccef69685fee1b250633118f908fac69db5c..d18b5233e6aa973457f29893c22d8463d825ecaa 100644 (file)
 #include <sata.h>
 
 static int sata_curr_device = -1;
-struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
-
-static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
-                               lbaint_t blkcnt, void *dst)
-{
-       return sata_read(block_dev->devnum, start, blkcnt, dst);
-}
-
-static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
-                                lbaint_t blkcnt, const void *buffer)
-{
-       return sata_write(block_dev->devnum, start, blkcnt, buffer);
-}
-
-int __sata_initialize(void)
-{
-       int rc;
-       int i;
-
-       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
-               memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
-               sata_dev_desc[i].if_type = IF_TYPE_SATA;
-               sata_dev_desc[i].devnum = i;
-               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
-               sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
-               sata_dev_desc[i].lba = 0;
-               sata_dev_desc[i].blksz = 512;
-               sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
-               sata_dev_desc[i].block_read = sata_bread;
-               sata_dev_desc[i].block_write = sata_bwrite;
-
-               rc = init_sata(i);
-               if (!rc) {
-                       rc = scan_sata(i);
-                       if (!rc && (sata_dev_desc[i].lba > 0) &&
-                               (sata_dev_desc[i].blksz > 0))
-                               part_init(&sata_dev_desc[i]);
-               }
-       }
-       sata_curr_device = 0;
-       return rc;
-}
-int sata_initialize(void) __attribute__((weak,alias("__sata_initialize")));
-
-__weak int __sata_stop(void)
-{
-       int i, err = 0;
-
-       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
-               err |= reset_sata(i);
-
-       if (err)
-               printf("Could not reset some SATA devices\n");
-
-       return err;
-}
-int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *sata_get_dev(int dev)
-{
-       return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
-}
-#endif
 
 static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -105,69 +41,40 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        case 1:
                return CMD_RET_USAGE;
        case 2:
-               if (strncmp(argv[1],"inf", 3) == 0) {
-                       int i;
-                       putc('\n');
-                       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; ++i) {
-                               if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN)
-                                       continue;
-                               printf ("SATA device %d: ", i);
-                               dev_print(&sata_dev_desc[i]);
-                       }
+               if (strncmp(argv[1], "inf", 3) == 0) {
+                       blk_list_devices(IF_TYPE_SATA);
                        return 0;
-               } else if (strncmp(argv[1],"dev", 3) == 0) {
-                       if ((sata_curr_device < 0) || (sata_curr_device >= CONFIG_SYS_SATA_MAX_DEVICE)) {
-                               puts("\nno SATA devices available\n");
-                               return 1;
+               } else if (strncmp(argv[1], "dev", 3) == 0) {
+                       if (blk_print_device_num(IF_TYPE_SATA,
+                                                sata_curr_device)) {
+                               printf("\nno SATA devices available\n");
+                               return CMD_RET_FAILURE;
                        }
-                       printf("\nSATA device %d: ", sata_curr_device);
-                       dev_print(&sata_dev_desc[sata_curr_device]);
                        return 0;
-               } else if (strncmp(argv[1],"part",4) == 0) {
-                       int dev, ok;
-
-                       for (ok = 0, dev = 0; dev < CONFIG_SYS_SATA_MAX_DEVICE; ++dev) {
-                               if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
-                                       ++ok;
-                                       if (dev)
-                                               putc ('\n');
-                                       part_print(&sata_dev_desc[dev]);
-                               }
-                       }
-                       if (!ok) {
+               } else if (strncmp(argv[1], "part", 4) == 0) {
+                       if (blk_list_part(IF_TYPE_SATA))
                                puts("\nno SATA devices available\n");
-                               rc ++;
-                       }
-                       return rc;
+                       return 0;
                }
                return CMD_RET_USAGE;
        case 3:
                if (strncmp(argv[1], "dev", 3) == 0) {
                        int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       printf("\nSATA device %d: ", dev);
-                       if (dev >= CONFIG_SYS_SATA_MAX_DEVICE) {
-                               puts ("unknown device\n");
-                               return 1;
+                       if (!blk_show_device(IF_TYPE_SATA, dev)) {
+                               sata_curr_device = dev;
+                               printf("... is now current device\n");
+                       } else {
+                               return CMD_RET_FAILURE;
                        }
-                       dev_print(&sata_dev_desc[dev]);
-
-                       if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
-                               return 1;
-
-                       sata_curr_device = dev;
-
-                       puts("... is now current device\n");
-
                        return 0;
                } else if (strncmp(argv[1], "part", 4) == 0) {
                        int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-                       if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
-                               part_print(&sata_dev_desc[dev]);
-                       } else {
-                               printf("\nSATA device %d not available\n", dev);
-                               rc = 1;
+                       if (blk_print_part_devnum(IF_TYPE_SATA, dev)) {
+                               printf("\nSATA device %d not available\n",
+                                      dev);
+                               return CMD_RET_FAILURE;
                        }
                        return rc;
                }
@@ -183,11 +90,8 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        printf("\nSATA read: device %d block # %ld, count %ld ... ",
                                sata_curr_device, blk, cnt);
 
-                       n = blk_dread(&sata_dev_desc[sata_curr_device],
-                                     blk, cnt, (u32 *)addr);
-
-                       /* flush cache after read */
-                       flush_cache(addr, cnt * sata_dev_desc[sata_curr_device].blksz);
+                       n = blk_read_devnum(IF_TYPE_SATA, sata_curr_device, blk,
+                                           cnt, (ulong *)addr);
 
                        printf("%ld blocks read: %s\n",
                                n, (n==cnt) ? "OK" : "ERROR");
@@ -202,8 +106,8 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        printf("\nSATA write: device %d block # %ld, count %ld ... ",
                                sata_curr_device, blk, cnt);
 
-                       n = blk_dwrite(&sata_dev_desc[sata_curr_device],
-                                      blk, cnt, (u32 *)addr);
+                       n = blk_write_devnum(IF_TYPE_SATA, sata_curr_device,
+                                            blk, cnt, (ulong *)addr);
 
                        printf("%ld blocks written: %s\n",
                                n, (n == cnt) ? "OK" : "ERROR");
index 8991125c66248a00f650e5846f6c586592e232d3..387ca1a262ab505c9e680c8874111a91bcf4bc5d 100644 (file)
  */
 #include <common.h>
 #include <command.h>
-#include <inttypes.h>
-#include <asm/processor.h>
 #include <scsi.h>
-#include <image.h>
-#include <pci.h>
-
-#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
-
-#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
-const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
-#endif
-static ccb tempccb;    /* temporary scsi command buffer */
-
-static unsigned char tempbuff[512]; /* temporary data buffer */
-
-static int scsi_max_devs; /* number of highest available scsi device */
 
 static int scsi_curr_dev; /* current device */
 
-static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
-
-/********************************************************************************
- *  forward declerations of some Setup Routines
- */
-void scsi_setup_test_unit_ready(ccb * pccb);
-void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks);
-void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks);
-void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks);
-
-static void scsi_setup_write_ext(ccb *pccb, lbaint_t start,
-                               unsigned short blocks);
-void scsi_setup_inquiry(ccb * pccb);
-void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
-
-
-static int scsi_read_capacity(ccb *pccb, lbaint_t *capacity,
-                             unsigned long *blksz);
-static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
-                      lbaint_t blkcnt, void *buffer);
-static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
-                       lbaint_t blkcnt, const void *buffer);
-
-
-/*********************************************************************************
- * (re)-scan the scsi bus and reports scsi device info
- * to the user if mode = 1
- */
-void scsi_scan(int mode)
-{
-       unsigned char i,perq,modi,lun;
-       lbaint_t capacity;
-       unsigned long blksz;
-       ccb* pccb=(ccb *)&tempccb;
-
-       if(mode==1) {
-               printf("scanning bus for devices...\n");
-       }
-       for(i=0;i<CONFIG_SYS_SCSI_MAX_DEVICE;i++) {
-               scsi_dev_desc[i].target=0xff;
-               scsi_dev_desc[i].lun=0xff;
-               scsi_dev_desc[i].lba=0;
-               scsi_dev_desc[i].blksz=0;
-               scsi_dev_desc[i].log2blksz =
-                       LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
-               scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
-               scsi_dev_desc[i].vendor[0]=0;
-               scsi_dev_desc[i].product[0]=0;
-               scsi_dev_desc[i].revision[0]=0;
-               scsi_dev_desc[i].removable = false;
-               scsi_dev_desc[i].if_type=IF_TYPE_SCSI;
-               scsi_dev_desc[i].devnum = i;
-               scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
-               scsi_dev_desc[i].block_read=scsi_read;
-               scsi_dev_desc[i].block_write = scsi_write;
-       }
-       scsi_max_devs=0;
-       for(i=0;i<CONFIG_SYS_SCSI_MAX_SCSI_ID;i++) {
-               pccb->target=i;
-               for(lun=0;lun<CONFIG_SYS_SCSI_MAX_LUN;lun++) {
-                       pccb->lun=lun;
-                       pccb->pdata=(unsigned char *)&tempbuff;
-                       pccb->datalen=512;
-                       scsi_setup_inquiry(pccb);
-                       if (scsi_exec(pccb) != true) {
-                               if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
-                                       debug ("Selection timeout ID %d\n",pccb->target);
-                                       continue; /* selection timeout => assuming no device present */
-                               }
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       perq=tempbuff[0];
-                       modi=tempbuff[1];
-                       if((perq & 0x1f)==0x1f) {
-                               continue; /* skip unknown devices */
-                       }
-                       if((modi&0x80)==0x80) /* drive is removable */
-                               scsi_dev_desc[scsi_max_devs].removable=true;
-                       /* get info for this device */
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].vendor[0],
-                                      &tempbuff[8], 8);
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].product[0],
-                                      &tempbuff[16], 16);
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc[scsi_max_devs].revision[0],
-                                      &tempbuff[32], 4);
-                       scsi_dev_desc[scsi_max_devs].target=pccb->target;
-                       scsi_dev_desc[scsi_max_devs].lun=pccb->lun;
-
-                       pccb->datalen=0;
-                       scsi_setup_test_unit_ready(pccb);
-                       if (scsi_exec(pccb) != true) {
-                               if (scsi_dev_desc[scsi_max_devs].removable == true) {
-                                       scsi_dev_desc[scsi_max_devs].type=perq;
-                                       goto removable;
-                               }
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       if (scsi_read_capacity(pccb, &capacity, &blksz)) {
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       scsi_dev_desc[scsi_max_devs].lba=capacity;
-                       scsi_dev_desc[scsi_max_devs].blksz=blksz;
-                       scsi_dev_desc[scsi_max_devs].log2blksz =
-                               LOG2(scsi_dev_desc[scsi_max_devs].blksz);
-                       scsi_dev_desc[scsi_max_devs].type=perq;
-                       part_init(&scsi_dev_desc[scsi_max_devs]);
-removable:
-                       if(mode==1) {
-                               printf ("  Device %d: ", scsi_max_devs);
-                               dev_print(&scsi_dev_desc[scsi_max_devs]);
-                       } /* if mode */
-                       scsi_max_devs++;
-               } /* next LUN */
-       }
-       if(scsi_max_devs>0)
-               scsi_curr_dev=0;
-       else
-               scsi_curr_dev = -1;
-
-       printf("Found %d device(s).\n", scsi_max_devs);
-#ifndef CONFIG_SPL_BUILD
-       setenv_ulong("scsidevs", scsi_max_devs);
-#endif
-}
-
-int scsi_get_disk_count(void)
-{
-       return scsi_max_devs;
-}
-
-#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
-void scsi_init(void)
-{
-       int busdevfunc = -1;
-       int i;
-       /*
-        * Find a device from the list, this driver will support a single
-        * controller.
-        */
-       for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
-               /* get PCI Device ID */
-#ifdef CONFIG_DM_PCI
-               struct udevice *dev;
-               int ret;
-
-               ret = dm_pci_find_device(scsi_device_list[i].vendor,
-                                        scsi_device_list[i].device, 0, &dev);
-               if (!ret) {
-                       busdevfunc = dm_pci_get_bdf(dev);
-                       break;
-               }
-#else
-               busdevfunc = pci_find_device(scsi_device_list[i].vendor,
-                                            scsi_device_list[i].device,
-                                            0);
-#endif
-               if (busdevfunc != -1)
-                       break;
-       }
-
-       if (busdevfunc == -1) {
-               printf("Error: SCSI Controller(s) ");
-               for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
-                       printf("%04X:%04X ",
-                              scsi_device_list[i].vendor,
-                              scsi_device_list[i].device);
-               }
-               printf("not found\n");
-               return;
-       }
-#ifdef DEBUG
-       else {
-               printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
-                      scsi_device_list[i].vendor,
-                      scsi_device_list[i].device,
-                      (busdevfunc >> 16) & 0xFF,
-                      (busdevfunc >> 11) & 0x1F,
-                      (busdevfunc >> 8) & 0x7);
-       }
-#endif
-       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
-       scsi_low_level_init(busdevfunc);
-       scsi_scan(1);
-       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
-}
-#endif
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *scsi_get_dev(int dev)
-{
-       return (dev < CONFIG_SYS_SCSI_MAX_DEVICE) ? &scsi_dev_desc[dev] : NULL;
-}
-#endif
-
-#ifndef CONFIG_SPL_BUILD
-/******************************************************************************
+/*
  * scsi boot command intepreter. Derived from diskboot
  */
-int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_scsiboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        return common_diskboot(cmdtp, "scsi", argc, argv);
 }
 
-/*********************************************************************************
+/*
  * scsi command intepreter
  */
-int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        switch (argc) {
        case 0:
        case 1:
                return CMD_RET_USAGE;
-
        case 2:
-                       if (strncmp(argv[1],"res",3) == 0) {
-                               printf("\nReset SCSI\n");
-                               scsi_bus_reset();
-                               scsi_scan(1);
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"inf",3) == 0) {
-                               int i;
-                               for (i=0; i<CONFIG_SYS_SCSI_MAX_DEVICE; ++i) {
-                                       if(scsi_dev_desc[i].type==DEV_TYPE_UNKNOWN)
-                                               continue; /* list only known devices */
-                                       printf ("SCSI dev. %d:  ", i);
-                                       dev_print(&scsi_dev_desc[i]);
-                               }
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"dev",3) == 0) {
-                               if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CONFIG_SYS_SCSI_MAX_DEVICE)) {
-                                       printf("\nno SCSI devices available\n");
-                                       return 1;
-                               }
-                               printf ("\n    Device %d: ", scsi_curr_dev);
-                               dev_print(&scsi_dev_desc[scsi_curr_dev]);
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"scan",4) == 0) {
-                               scsi_scan(1);
-                               return 0;
-                       }
-                       if (strncmp(argv[1],"part",4) == 0) {
-                               int dev, ok;
-                               for (ok=0, dev=0; dev<CONFIG_SYS_SCSI_MAX_DEVICE; ++dev) {
-                                       if (scsi_dev_desc[dev].type!=DEV_TYPE_UNKNOWN) {
-                                               ok++;
-                                               if (dev)
-                                                       printf("\n");
-                                               debug ("print_part of %x\n",dev);
-                                               part_print(&scsi_dev_desc[dev]);
-                                       }
-                               }
-                               if (!ok)
-                                       printf("\nno SCSI devices available\n");
-                               return 1;
+               if (strncmp(argv[1], "res", 3) == 0) {
+                       printf("\nReset SCSI\n");
+                       scsi_bus_reset();
+                       scsi_scan(1);
+                       return 0;
+               }
+               if (strncmp(argv[1], "inf", 3) == 0) {
+                       blk_list_devices(IF_TYPE_SCSI);
+                       return 0;
+               }
+               if (strncmp(argv[1], "dev", 3) == 0) {
+                       if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) {
+                               printf("\nno SCSI devices available\n");
+                               return CMD_RET_FAILURE;
                        }
-                       return CMD_RET_USAGE;
+
+                       return 0;
+               }
+               if (strncmp(argv[1], "scan", 4) == 0) {
+                       scsi_scan(1);
+                       return 0;
+               }
+               if (strncmp(argv[1], "part", 4) == 0) {
+                       if (blk_list_part(IF_TYPE_SCSI))
+                               printf("\nno SCSI devices available\n");
+                       return 0;
+               }
+               return CMD_RET_USAGE;
        case 3:
-                       if (strncmp(argv[1],"dev",3) == 0) {
-                               int dev = (int)simple_strtoul(argv[2], NULL, 10);
-                               printf ("\nSCSI device %d: ", dev);
-                               if (dev >= CONFIG_SYS_SCSI_MAX_DEVICE) {
-                                       printf("unknown device\n");
-                                       return 1;
-                               }
-                               printf ("\n    Device %d: ", dev);
-                               dev_print(&scsi_dev_desc[dev]);
-                               if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
-                                       return 1;
-                               }
+               if (strncmp(argv[1], "dev", 3) == 0) {
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+                       if (!blk_show_device(IF_TYPE_SCSI, dev)) {
                                scsi_curr_dev = dev;
                                printf("... is now current device\n");
-                               return 0;
+                       } else {
+                               return CMD_RET_FAILURE;
                        }
-                       if (strncmp(argv[1],"part",4) == 0) {
-                               int dev = (int)simple_strtoul(argv[2], NULL, 10);
-                               if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) {
-                                       part_print(&scsi_dev_desc[dev]);
-                               }
-                               else {
-                                       printf ("\nSCSI device %d not available\n", dev);
-                               }
-                               return 1;
-                       }
-                       return CMD_RET_USAGE;
-    default:
-                       /* at least 4 args */
-                       if (strcmp(argv[1],"read") == 0) {
-                               ulong addr = simple_strtoul(argv[2], NULL, 16);
-                               ulong blk  = simple_strtoul(argv[3], NULL, 16);
-                               ulong cnt  = simple_strtoul(argv[4], NULL, 16);
-                               ulong n;
-                               printf ("\nSCSI read: device %d block # %ld, count %ld ... ",
-                                               scsi_curr_dev, blk, cnt);
-                               n = scsi_read(&scsi_dev_desc[scsi_curr_dev],
-                                             blk, cnt, (ulong *)addr);
-                               printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR");
-                               return 0;
-                       } else if (strcmp(argv[1], "write") == 0) {
-                               ulong addr = simple_strtoul(argv[2], NULL, 16);
-                               ulong blk = simple_strtoul(argv[3], NULL, 16);
-                               ulong cnt = simple_strtoul(argv[4], NULL, 16);
-                               ulong n;
-                               printf("\nSCSI write: device %d block # %ld, "
-                                      "count %ld ... ",
-                                      scsi_curr_dev, blk, cnt);
-                               n = scsi_write(&scsi_dev_desc[scsi_curr_dev],
-                                              blk, cnt, (ulong *)addr);
-                               printf("%ld blocks written: %s\n", n,
-                                      (n == cnt) ? "OK" : "ERROR");
-                               return 0;
+                       return 0;
+               }
+               if (strncmp(argv[1], "part", 4) == 0) {
+                       int dev = (int)simple_strtoul(argv[2], NULL, 10);
+
+                       if (blk_print_part_devnum(IF_TYPE_SCSI, dev)) {
+                               printf("\nSCSI device %d not available\n",
+                                      dev);
+                               return CMD_RET_FAILURE;
                        }
+                       return 0;
+               }
+               return CMD_RET_USAGE;
+       default:
+               /* at least 4 args */
+               if (strcmp(argv[1], "read") == 0) {
+                       ulong addr = simple_strtoul(argv[2], NULL, 16);
+                       ulong blk  = simple_strtoul(argv[3], NULL, 16);
+                       ulong cnt  = simple_strtoul(argv[4], NULL, 16);
+                       ulong n;
+
+                       printf("\nSCSI read: device %d block # %ld, count %ld ... ",
+                              scsi_curr_dev, blk, cnt);
+                       n = blk_read_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk,
+                                           cnt, (ulong *)addr);
+                       printf("%ld blocks read: %s\n", n,
+                              n == cnt ? "OK" : "ERROR");
+                       return 0;
+               } else if (strcmp(argv[1], "write") == 0) {
+                       ulong addr = simple_strtoul(argv[2], NULL, 16);
+                       ulong blk = simple_strtoul(argv[3], NULL, 16);
+                       ulong cnt = simple_strtoul(argv[4], NULL, 16);
+                       ulong n;
+
+                       printf("\nSCSI write: device %d block # %ld, count %ld ... ",
+                              scsi_curr_dev, blk, cnt);
+                       n = blk_write_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk,
+                                            cnt, (ulong *)addr);
+                       printf("%ld blocks written: %s\n", n,
+                              n == cnt ? "OK" : "ERROR");
+                       return 0;
+               }
        } /* switch */
        return CMD_RET_USAGE;
 }
@@ -388,347 +135,3 @@ U_BOOT_CMD(
        "boot from SCSI device",
        "loadAddr dev:part"
 );
-#endif
-
-/****************************************************************************************
- * scsi_read
- */
-
-/* almost the maximum amount of the scsi_ext command.. */
-#define SCSI_MAX_READ_BLK 0xFFFF
-#define SCSI_LBA48_READ        0xFFFFFFF
-
-static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
-                      lbaint_t blkcnt, void *buffer)
-{
-       int device = block_dev->devnum;
-       lbaint_t start, blks;
-       uintptr_t buf_addr;
-       unsigned short smallblks = 0;
-       ccb* pccb=(ccb *)&tempccb;
-       device&=0xff;
-       /* Setup  device
-        */
-       pccb->target=scsi_dev_desc[device].target;
-       pccb->lun=scsi_dev_desc[device].lun;
-       buf_addr=(unsigned long)buffer;
-       start=blknr;
-       blks=blkcnt;
-       debug("\nscsi_read: dev %d startblk " LBAF
-             ", blccnt " LBAF " buffer %lx\n",
-             device, start, blks, (unsigned long)buffer);
-       do {
-               pccb->pdata=(unsigned char *)buf_addr;
-#ifdef CONFIG_SYS_64BIT_LBA
-               if (start > SCSI_LBA48_READ) {
-                       unsigned long blocks;
-                       blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
-                       pccb->datalen = scsi_dev_desc[device].blksz * blocks;
-                       scsi_setup_read16(pccb, start, blocks);
-                       start += blocks;
-                       blks -= blocks;
-               } else
-#endif
-               if (blks > SCSI_MAX_READ_BLK) {
-                       pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK;
-                       smallblks=SCSI_MAX_READ_BLK;
-                       scsi_setup_read_ext(pccb,start,smallblks);
-                       start+=SCSI_MAX_READ_BLK;
-                       blks-=SCSI_MAX_READ_BLK;
-               }
-               else {
-                       pccb->datalen=scsi_dev_desc[device].blksz * blks;
-                       smallblks=(unsigned short) blks;
-                       scsi_setup_read_ext(pccb,start,smallblks);
-                       start+=blks;
-                       blks=0;
-               }
-               debug("scsi_read_ext: startblk " LBAF
-                     ", blccnt %x buffer %" PRIXPTR "\n",
-                     start, smallblks, buf_addr);
-               if (scsi_exec(pccb) != true) {
-                       scsi_print_error(pccb);
-                       blkcnt-=blks;
-                       break;
-               }
-               buf_addr+=pccb->datalen;
-       } while(blks!=0);
-       debug("scsi_read_ext: end startblk " LBAF
-             ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
-       return(blkcnt);
-}
-
-/*******************************************************************************
- * scsi_write
- */
-
-/* Almost the maximum amount of the scsi_ext command.. */
-#define SCSI_MAX_WRITE_BLK 0xFFFF
-
-static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
-                       lbaint_t blkcnt, const void *buffer)
-{
-       int device = block_dev->devnum;
-       lbaint_t start, blks;
-       uintptr_t buf_addr;
-       unsigned short smallblks;
-       ccb* pccb = (ccb *)&tempccb;
-       device &= 0xff;
-       /* Setup  device
-        */
-       pccb->target = scsi_dev_desc[device].target;
-       pccb->lun = scsi_dev_desc[device].lun;
-       buf_addr = (unsigned long)buffer;
-       start = blknr;
-       blks = blkcnt;
-       debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
-             __func__, device, start, blks, (unsigned long)buffer);
-       do {
-               pccb->pdata = (unsigned char *)buf_addr;
-               if (blks > SCSI_MAX_WRITE_BLK) {
-                       pccb->datalen = (scsi_dev_desc[device].blksz *
-                                        SCSI_MAX_WRITE_BLK);
-                       smallblks = SCSI_MAX_WRITE_BLK;
-                       scsi_setup_write_ext(pccb, start, smallblks);
-                       start += SCSI_MAX_WRITE_BLK;
-                       blks -= SCSI_MAX_WRITE_BLK;
-               } else {
-                       pccb->datalen = scsi_dev_desc[device].blksz * blks;
-                       smallblks = (unsigned short)blks;
-                       scsi_setup_write_ext(pccb, start, smallblks);
-                       start += blks;
-                       blks = 0;
-               }
-               debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
-                     __func__, start, smallblks, buf_addr);
-               if (scsi_exec(pccb) != true) {
-                       scsi_print_error(pccb);
-                       blkcnt -= blks;
-                       break;
-               }
-               buf_addr += pccb->datalen;
-       } while (blks != 0);
-       debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
-             __func__, start, smallblks, buf_addr);
-       return blkcnt;
-}
-
-/* copy src to dest, skipping leading and trailing blanks
- * and null terminate the string
- */
-void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
-{
-       int start,end;
-
-       start=0;
-       while(start<len) {
-               if(src[start]!=' ')
-                       break;
-               start++;
-       }
-       end=len-1;
-       while(end>start) {
-               if(src[end]!=' ')
-                       break;
-               end--;
-       }
-       for( ; start<=end; start++) {
-               *dest++=src[start];
-       }
-       *dest='\0';
-}
-
-
-/* Trim trailing blanks, and NUL-terminate string
- */
-void scsi_trim_trail (unsigned char *str, unsigned int len)
-{
-       unsigned char *p = str + len - 1;
-
-       while (len-- > 0) {
-               *p-- = '\0';
-               if (*p != ' ') {
-                       return;
-               }
-       }
-}
-
-int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
-{
-       *capacity = 0;
-
-       memset(pccb->cmd, 0, sizeof(pccb->cmd));
-       pccb->cmd[0] = SCSI_RD_CAPAC10;
-       pccb->cmd[1] = pccb->lun << 5;
-       pccb->cmdlen = 10;
-       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
-
-       pccb->datalen = 8;
-       if (scsi_exec(pccb) != true)
-               return 1;
-
-       *capacity = ((lbaint_t)pccb->pdata[0] << 24) |
-                   ((lbaint_t)pccb->pdata[1] << 16) |
-                   ((lbaint_t)pccb->pdata[2] << 8)  |
-                   ((lbaint_t)pccb->pdata[3]);
-
-       if (*capacity != 0xffffffff) {
-               /* Read capacity (10) was sufficient for this drive. */
-               *blksz = ((unsigned long)pccb->pdata[4] << 24) |
-                        ((unsigned long)pccb->pdata[5] << 16) |
-                        ((unsigned long)pccb->pdata[6] << 8)  |
-                        ((unsigned long)pccb->pdata[7]);
-               return 0;
-       }
-
-       /* Read capacity (10) was insufficient. Use read capacity (16). */
-
-       memset(pccb->cmd, 0, sizeof(pccb->cmd));
-       pccb->cmd[0] = SCSI_RD_CAPAC16;
-       pccb->cmd[1] = 0x10;
-       pccb->cmdlen = 16;
-       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
-
-       pccb->datalen = 16;
-       if (scsi_exec(pccb) != true)
-               return 1;
-
-       *capacity = ((uint64_t)pccb->pdata[0] << 56) |
-                   ((uint64_t)pccb->pdata[1] << 48) |
-                   ((uint64_t)pccb->pdata[2] << 40) |
-                   ((uint64_t)pccb->pdata[3] << 32) |
-                   ((uint64_t)pccb->pdata[4] << 24) |
-                   ((uint64_t)pccb->pdata[5] << 16) |
-                   ((uint64_t)pccb->pdata[6] << 8)  |
-                   ((uint64_t)pccb->pdata[7]);
-
-       *blksz = ((uint64_t)pccb->pdata[8]  << 56) |
-                ((uint64_t)pccb->pdata[9]  << 48) |
-                ((uint64_t)pccb->pdata[10] << 40) |
-                ((uint64_t)pccb->pdata[11] << 32) |
-                ((uint64_t)pccb->pdata[12] << 24) |
-                ((uint64_t)pccb->pdata[13] << 16) |
-                ((uint64_t)pccb->pdata[14] << 8)  |
-                ((uint64_t)pccb->pdata[15]);
-
-       return 0;
-}
-
-
-/************************************************************************************
- * Some setup (fill-in) routines
- */
-void scsi_setup_test_unit_ready(ccb * pccb)
-{
-       pccb->cmd[0]=SCSI_TST_U_RDY;
-       pccb->cmd[1]=pccb->lun<<5;
-       pccb->cmd[2]=0;
-       pccb->cmd[3]=0;
-       pccb->cmd[4]=0;
-       pccb->cmd[5]=0;
-       pccb->cmdlen=6;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-}
-
-#ifdef CONFIG_SYS_64BIT_LBA
-void scsi_setup_read16(ccb * pccb, lbaint_t start, unsigned long blocks)
-{
-       pccb->cmd[0] = SCSI_READ16;
-       pccb->cmd[1] = pccb->lun<<5;
-       pccb->cmd[2] = ((unsigned char) (start >> 56)) & 0xff;
-       pccb->cmd[3] = ((unsigned char) (start >> 48)) & 0xff;
-       pccb->cmd[4] = ((unsigned char) (start >> 40)) & 0xff;
-       pccb->cmd[5] = ((unsigned char) (start >> 32)) & 0xff;
-       pccb->cmd[6] = ((unsigned char) (start >> 24)) & 0xff;
-       pccb->cmd[7] = ((unsigned char) (start >> 16)) & 0xff;
-       pccb->cmd[8] = ((unsigned char) (start >> 8)) & 0xff;
-       pccb->cmd[9] = ((unsigned char) (start)) & 0xff;
-       pccb->cmd[10] = 0;
-       pccb->cmd[11] = ((unsigned char) (blocks >> 24)) & 0xff;
-       pccb->cmd[12] = ((unsigned char) (blocks >> 16)) & 0xff;
-       pccb->cmd[13] = ((unsigned char) (blocks >> 8)) & 0xff;
-       pccb->cmd[14] = (unsigned char) blocks & 0xff;
-       pccb->cmd[15] = 0;
-       pccb->cmdlen = 16;
-       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
-       debug ("scsi_setup_read16: cmd: %02X %02X "
-              "startblk %02X%02X%02X%02X%02X%02X%02X%02X "
-              "blccnt %02X%02X%02X%02X\n",
-               pccb->cmd[0], pccb->cmd[1],
-               pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
-               pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
-               pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
-}
-#endif
-
-void scsi_setup_read_ext(ccb * pccb, lbaint_t start, unsigned short blocks)
-{
-       pccb->cmd[0]=SCSI_READ10;
-       pccb->cmd[1]=pccb->lun<<5;
-       pccb->cmd[2]=((unsigned char) (start>>24))&0xff;
-       pccb->cmd[3]=((unsigned char) (start>>16))&0xff;
-       pccb->cmd[4]=((unsigned char) (start>>8))&0xff;
-       pccb->cmd[5]=((unsigned char) (start))&0xff;
-       pccb->cmd[6]=0;
-       pccb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
-       pccb->cmd[8]=(unsigned char) blocks & 0xff;
-       pccb->cmd[6]=0;
-       pccb->cmdlen=10;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-       debug ("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
-               pccb->cmd[0],pccb->cmd[1],
-               pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5],
-               pccb->cmd[7],pccb->cmd[8]);
-}
-
-void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
-{
-       pccb->cmd[0] = SCSI_WRITE10;
-       pccb->cmd[1] = pccb->lun << 5;
-       pccb->cmd[2] = ((unsigned char) (start>>24)) & 0xff;
-       pccb->cmd[3] = ((unsigned char) (start>>16)) & 0xff;
-       pccb->cmd[4] = ((unsigned char) (start>>8)) & 0xff;
-       pccb->cmd[5] = ((unsigned char) (start)) & 0xff;
-       pccb->cmd[6] = 0;
-       pccb->cmd[7] = ((unsigned char) (blocks>>8)) & 0xff;
-       pccb->cmd[8] = (unsigned char)blocks & 0xff;
-       pccb->cmd[9] = 0;
-       pccb->cmdlen = 10;
-       pccb->msgout[0] = SCSI_IDENTIFY;  /* NOT USED */
-       debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
-             __func__,
-             pccb->cmd[0], pccb->cmd[1],
-             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
-             pccb->cmd[7], pccb->cmd[8]);
-}
-
-void scsi_setup_read6(ccb * pccb, lbaint_t start, unsigned short blocks)
-{
-       pccb->cmd[0]=SCSI_READ6;
-       pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f);
-       pccb->cmd[2]=((unsigned char) (start>>8))&0xff;
-       pccb->cmd[3]=((unsigned char) (start))&0xff;
-       pccb->cmd[4]=(unsigned char) blocks & 0xff;
-       pccb->cmd[5]=0;
-       pccb->cmdlen=6;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-       debug ("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
-               pccb->cmd[0],pccb->cmd[1],
-               pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]);
-}
-
-
-void scsi_setup_inquiry(ccb * pccb)
-{
-       pccb->cmd[0]=SCSI_INQUIRY;
-       pccb->cmd[1]=pccb->lun<<5;
-       pccb->cmd[2]=0;
-       pccb->cmd[3]=0;
-       if(pccb->datalen>255)
-               pccb->cmd[4]=255;
-       else
-               pccb->cmd[4]=(unsigned char)pccb->datalen;
-       pccb->cmd[5]=0;
-       pccb->cmdlen=6;
-       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
-}
index f1a7debdf3d918f0ca5c23dc94efbc0e956b647d..b83d3233b789fffb49599ce2c9cf63abcc21112e 100644 (file)
--- a/cmd/usb.c
+++ b/cmd/usb.c
@@ -723,7 +723,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                int devno, ok = 0;
                if (argc == 2) {
                        for (devno = 0; ; ++devno) {
-                               stor_dev = usb_stor_get_dev(devno);
+                               stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                                 devno);
                                if (stor_dev == NULL)
                                        break;
                                if (stor_dev->type != DEV_TYPE_UNKNOWN) {
@@ -736,7 +737,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        }
                } else {
                        devno = simple_strtoul(argv[2], NULL, 16);
-                       stor_dev = usb_stor_get_dev(devno);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, devno);
                        if (stor_dev != NULL &&
                            stor_dev->type != DEV_TYPE_UNKNOWN) {
                                ok++;
@@ -762,7 +763,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        unsigned long n;
                        printf("\nUSB read: device %d block # %ld, count %ld"
                                " ... ", usb_stor_curr_dev, blk, cnt);
-                       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                         usb_stor_curr_dev);
                        n = blk_dread(stor_dev, blk, cnt, (ulong *)addr);
                        printf("%ld blocks read: %s\n", n,
                                (n == cnt) ? "OK" : "ERROR");
@@ -783,7 +785,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        unsigned long n;
                        printf("\nUSB write: device %d block # %ld, count %ld"
                                " ... ", usb_stor_curr_dev, blk, cnt);
-                       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                         usb_stor_curr_dev);
                        n = blk_dwrite(stor_dev, blk, cnt, (ulong *)addr);
                        printf("%ld blocks write: %s\n", n,
                                (n == cnt) ? "OK" : "ERROR");
@@ -796,7 +799,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                if (argc == 3) {
                        int dev = (int)simple_strtoul(argv[2], NULL, 10);
                        printf("\nUSB device %d: ", dev);
-                       stor_dev = usb_stor_get_dev(dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, dev);
                        if (stor_dev == NULL) {
                                printf("unknown device\n");
                                return 1;
@@ -810,7 +813,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        return 0;
                } else {
                        printf("\nUSB device %d: ", usb_stor_curr_dev);
-                       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+                       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB,
+                                                         usb_stor_curr_dev);
                        dev_print(stor_dev);
                        if (stor_dev->type == DEV_TYPE_UNKNOWN)
                                return 1;
index b23f31200636e7b9bdbe6b54be0fb145cfaea635..f9b26b7bbe49d66f1bb0c7d470fd65c315bfa887 100644 (file)
@@ -84,6 +84,8 @@ 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
@@ -112,6 +114,9 @@ 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
@@ -130,6 +135,7 @@ obj-y += dlmalloc.o
 ifdef CONFIG_SYS_MALLOC_F_LEN
 obj-y += malloc_simple.o
 endif
+obj-$(CONFIG_CMD_IDE) += ide.o
 obj-y += image.o
 obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
 obj-$(CONFIG_$(SPL_)OF_LIBFDT) += image-fdt.o
index ad02549311ea84f64c377601de81aa6d3cd636e1..d959ad3c6f90ea2c2a422b6878c11a5437764a2c 100644 (file)
@@ -620,7 +620,7 @@ static int initr_ambapp_print(void)
 }
 #endif
 
-#if defined(CONFIG_CMD_SCSI)
+#if defined(CONFIG_SCSI)
 static int initr_scsi(void)
 {
        puts("SCSI:  ");
@@ -923,7 +923,7 @@ init_fnc_t init_sequence_r[] = {
        initr_ambapp_print,
 #endif
 #endif
-#ifdef CONFIG_CMD_SCSI
+#ifdef CONFIG_SCSI
        INIT_FUNC_WATCHDOG_RESET
        initr_scsi,
 #endif
index bdb452e58c598731c9edc8e93d5e37f19e280919..c7fef188cd21b9a6b816ab7b8c997de788b2d822 100644 (file)
@@ -86,8 +86,8 @@ static int mmc_set_env_part(struct mmc *mmc)
        dev = 0;
 #endif
 
-       env_mmc_orig_hwpart = mmc->block_dev.hwpart;
-       ret = mmc_select_hwpart(dev, part);
+       env_mmc_orig_hwpart = mmc_get_blk_desc(mmc)->hwpart;
+       ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part);
        if (ret)
                puts("MMC partition switch failed\n");
 
@@ -119,7 +119,7 @@ static void fini_mmc_for_env(struct mmc *mmc)
 #ifdef CONFIG_SPL_BUILD
        dev = 0;
 #endif
-       mmc_select_hwpart(dev, env_mmc_orig_hwpart);
+       blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart);
 #endif
 }
 
diff --git a/common/ide.c b/common/ide.c
new file mode 100644 (file)
index 0000000..ac5b91c
--- /dev/null
@@ -0,0 +1,1231 @@
+/*
+ * (C) Copyright 2000-2011
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <ata.h>
+#include <dm.h>
+#include <ide.h>
+#include <watchdog.h>
+#include <asm/io.h>
+
+#ifdef __PPC__
+# define EIEIO         __asm__ volatile ("eieio")
+# define SYNC          __asm__ volatile ("sync")
+#else
+# define EIEIO         /* nothing */
+# define SYNC          /* nothing */
+#endif
+
+/* Current offset for IDE0 / IDE1 bus access   */
+ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = {
+#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
+       CONFIG_SYS_ATA_IDE0_OFFSET,
+#endif
+#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1)
+       CONFIG_SYS_ATA_IDE1_OFFSET,
+#endif
+};
+
+static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS];
+
+struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
+
+#define IDE_TIME_OUT   2000    /* 2 sec timeout */
+
+#define ATAPI_TIME_OUT 7000    /* 7 sec timeout (5 sec seems to work...) */
+
+#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
+
+#ifndef CONFIG_SYS_ATA_PORT_ADDR
+#define CONFIG_SYS_ATA_PORT_ADDR(port) (port)
+#endif
+
+#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */
+# define DEVICE_LED(x) 0
+# define LED_IDE1 1
+# define LED_IDE2 2
+#endif
+
+#ifdef CONFIG_IDE_RESET
+extern void ide_set_reset(int idereset);
+
+static void ide_reset(void)
+{
+       int i;
+
+       for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i)
+               ide_bus_ok[i] = 0;
+       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i)
+               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+
+       ide_set_reset(1);       /* assert reset */
+
+       /* the reset signal shall be asserted for et least 25 us */
+       udelay(25);
+
+       WATCHDOG_RESET();
+
+       /* de-assert RESET signal */
+       ide_set_reset(0);
+
+       /* wait 250 ms */
+       for (i = 0; i < 250; ++i)
+               udelay(1000);
+}
+#else
+#define ide_reset()    /* dummy */
+#endif /* CONFIG_IDE_RESET */
+
+/*
+ * Wait until Busy bit is off, or timeout (in ms)
+ * Return last status
+ */
+static uchar ide_wait(int dev, ulong t)
+{
+       ulong delay = 10 * t;   /* poll every 100 us */
+       uchar c;
+
+       while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
+               udelay(100);
+               if (delay-- == 0)
+                       break;
+       }
+       return c;
+}
+
+/*
+ * copy src to dest, skipping leading and trailing blanks and null
+ * terminate the string
+ * "len" is the size of available memory including the terminating '\0'
+ */
+static void ident_cpy(unsigned char *dst, unsigned char *src,
+                     unsigned int len)
+{
+       unsigned char *end, *last;
+
+       last = dst;
+       end = src + len - 1;
+
+       /* reserve space for '\0' */
+       if (len < 2)
+               goto OUT;
+
+       /* skip leading white space */
+       while ((*src) && (src < end) && (*src == ' '))
+               ++src;
+
+       /* copy string, omitting trailing white space */
+       while ((*src) && (src < end)) {
+               *dst++ = *src;
+               if (*src++ != ' ')
+                       last = dst;
+       }
+OUT:
+       *last = '\0';
+}
+
+#ifdef CONFIG_ATAPI
+/****************************************************************************
+ * ATAPI Support
+ */
+
+#if defined(CONFIG_IDE_SWAP_IO)
+/* since ATAPI may use commands with not 4 bytes alligned length
+ * we have our own transfer functions, 2 bytes alligned */
+__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+
+       debug("in output data shorts base for read is %lx\n",
+             (unsigned long) pbuf);
+
+       while (shorts--) {
+               EIEIO;
+               *pbuf = *dbuf++;
+       }
+}
+
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+
+       debug("in input data shorts base for read is %lx\n",
+             (unsigned long) pbuf);
+
+       while (shorts--) {
+               EIEIO;
+               *dbuf++ = *pbuf;
+       }
+}
+
+#else  /* ! CONFIG_IDE_SWAP_IO */
+__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
+}
+
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
+}
+
+#endif /* CONFIG_IDE_SWAP_IO */
+
+/*
+ * Wait until (Status & mask) == res, or timeout (in ms)
+ * Return last status
+ * This is used since some ATAPI CD ROMs clears their Busy Bit first
+ * and then they set their DRQ Bit
+ */
+static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res)
+{
+       ulong delay = 10 * t;   /* poll every 100 us */
+       uchar c;
+
+       /* prevents to read the status before valid */
+       c = ide_inb(dev, ATA_DEV_CTL);
+
+       while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) {
+               /* break if error occurs (doesn't make sense to wait more) */
+               if ((c & ATA_STAT_ERR) == ATA_STAT_ERR)
+                       break;
+               udelay(100);
+               if (delay-- == 0)
+                       break;
+       }
+       return c;
+}
+
+/*
+ * issue an atapi command
+ */
+unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
+                         unsigned char *buffer, int buflen)
+{
+       unsigned char c, err, mask, res;
+       int n;
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+
+       /* Select device
+        */
+       mask = ATA_STAT_BUSY | ATA_STAT_DRQ;
+       res = 0;
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+       if ((c & mask) != res) {
+               printf("ATAPI_ISSUE: device %d not ready status %X\n", device,
+                      c);
+               err = 0xFF;
+               goto AI_OUT;
+       }
+       /* write taskfile */
+       ide_outb(device, ATA_ERROR_REG, 0);     /* no DMA, no overlaped */
+       ide_outb(device, ATA_SECT_CNT, 0);
+       ide_outb(device, ATA_SECT_NUM, 0);
+       ide_outb(device, ATA_CYL_LOW, (unsigned char) (buflen & 0xFF));
+       ide_outb(device, ATA_CYL_HIGH,
+                (unsigned char) ((buflen >> 8) & 0xFF));
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+
+       ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
+       udelay(50);
+
+       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
+       res = ATA_STAT_DRQ;
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+
+       if ((c & mask) != res) {        /* DRQ must be 1, BSY 0 */
+               printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",
+                      device, c);
+               err = 0xFF;
+               goto AI_OUT;
+       }
+
+       /* write command block */
+       ide_output_data_shorts(device, (unsigned short *)ccb, ccblen / 2);
+
+       /* ATAPI Command written wait for completition */
+       udelay(5000);           /* device must set bsy */
+
+       mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
+       /*
+        * if no data wait for DRQ = 0 BSY = 0
+        * if data wait for DRQ = 1 BSY = 0
+        */
+       res = 0;
+       if (buflen)
+               res = ATA_STAT_DRQ;
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+       if ((c & mask) != res) {
+               if (c & ATA_STAT_ERR) {
+                       err = (ide_inb(device, ATA_ERROR_REG)) >> 4;
+                       debug("atapi_issue 1 returned sense key %X status %02X\n",
+                             err, c);
+               } else {
+                       printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x)  status 0x%02x\n",
+                              ccb[0], c);
+                       err = 0xFF;
+               }
+               goto AI_OUT;
+       }
+       n = ide_inb(device, ATA_CYL_HIGH);
+       n <<= 8;
+       n += ide_inb(device, ATA_CYL_LOW);
+       if (n > buflen) {
+               printf("ERROR, transfer bytes %d requested only %d\n", n,
+                      buflen);
+               err = 0xff;
+               goto AI_OUT;
+       }
+       if ((n == 0) && (buflen < 0)) {
+               printf("ERROR, transfer bytes %d requested %d\n", n, buflen);
+               err = 0xff;
+               goto AI_OUT;
+       }
+       if (n != buflen) {
+               debug("WARNING, transfer bytes %d not equal with requested %d\n",
+                     n, buflen);
+       }
+       if (n != 0) {           /* data transfer */
+               debug("ATAPI_ISSUE: %d Bytes to transfer\n", n);
+               /* we transfer shorts */
+               n >>= 1;
+               /* ok now decide if it is an in or output */
+               if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) {
+                       debug("Write to device\n");
+                       ide_output_data_shorts(device, (unsigned short *)buffer,
+                                              n);
+               } else {
+                       debug("Read from device @ %p shorts %d\n", buffer, n);
+                       ide_input_data_shorts(device, (unsigned short *)buffer,
+                                             n);
+               }
+       }
+       udelay(5000);           /* seems that some CD ROMs need this... */
+       mask = ATA_STAT_BUSY | ATA_STAT_ERR;
+       res = 0;
+       c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
+       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+               err = (ide_inb(device, ATA_ERROR_REG) >> 4);
+               debug("atapi_issue 2 returned sense key %X status %X\n", err,
+                     c);
+       } else {
+               err = 0;
+       }
+AI_OUT:
+       ide_led(DEVICE_LED(device), 0); /* LED off      */
+       return err;
+}
+
+/*
+ * sending the command to atapi_issue. If an status other than good
+ * returns, an request_sense will be issued
+ */
+
+#define ATAPI_DRIVE_NOT_READY  100
+#define ATAPI_UNIT_ATTN                10
+
+unsigned char atapi_issue_autoreq(int device,
+                                 unsigned char *ccb,
+                                 int ccblen,
+                                 unsigned char *buffer, int buflen)
+{
+       unsigned char sense_data[18], sense_ccb[12];
+       unsigned char res, key, asc, ascq;
+       int notready, unitattn;
+
+       unitattn = ATAPI_UNIT_ATTN;
+       notready = ATAPI_DRIVE_NOT_READY;
+
+retry:
+       res = atapi_issue(device, ccb, ccblen, buffer, buflen);
+       if (res == 0)
+               return 0;       /* Ok */
+
+       if (res == 0xFF)
+               return 0xFF;    /* error */
+
+       debug("(auto_req)atapi_issue returned sense key %X\n", res);
+
+       memset(sense_ccb, 0, sizeof(sense_ccb));
+       memset(sense_data, 0, sizeof(sense_data));
+       sense_ccb[0] = ATAPI_CMD_REQ_SENSE;
+       sense_ccb[4] = 18;      /* allocation Length */
+
+       res = atapi_issue(device, sense_ccb, 12, sense_data, 18);
+       key = (sense_data[2] & 0xF);
+       asc = (sense_data[12]);
+       ascq = (sense_data[13]);
+
+       debug("ATAPI_CMD_REQ_SENSE returned %x\n", res);
+       debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",
+             sense_data[0], key, asc, ascq);
+
+       if ((key == 0))
+               return 0;       /* ok device ready */
+
+       if ((key == 6) || (asc == 0x29) || (asc == 0x28)) { /* Unit Attention */
+               if (unitattn-- > 0) {
+                       udelay(200 * 1000);
+                       goto retry;
+               }
+               printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN);
+               goto error;
+       }
+       if ((asc == 0x4) && (ascq == 0x1)) {
+               /* not ready, but will be ready soon */
+               if (notready-- > 0) {
+                       udelay(200 * 1000);
+                       goto retry;
+               }
+               printf("Drive not ready, tried %d times\n",
+                      ATAPI_DRIVE_NOT_READY);
+               goto error;
+       }
+       if (asc == 0x3a) {
+               debug("Media not present\n");
+               goto error;
+       }
+
+       printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc,
+              ascq);
+error:
+       debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq);
+       return 0xFF;
+}
+
+/*
+ * atapi_read:
+ * we transfer only one block per command, since the multiple DRQ per
+ * command is not yet implemented
+ */
+#define ATAPI_READ_MAX_BYTES   2048    /* we read max 2kbytes */
+#define ATAPI_READ_BLOCK_SIZE  2048    /* assuming CD part */
+#define ATAPI_READ_MAX_BLOCK   (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
+
+ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+                void *buffer)
+{
+       int device = block_dev->devnum;
+       ulong n = 0;
+       unsigned char ccb[12];  /* Command descriptor block */
+       ulong cnt;
+
+       debug("atapi_read dev %d start " LBAF " blocks " LBAF
+             " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer);
+
+       do {
+               if (blkcnt > ATAPI_READ_MAX_BLOCK)
+                       cnt = ATAPI_READ_MAX_BLOCK;
+               else
+                       cnt = blkcnt;
+
+               ccb[0] = ATAPI_CMD_READ_12;
+               ccb[1] = 0;     /* reserved */
+               ccb[2] = (unsigned char) (blknr >> 24) & 0xFF;  /* MSB Block */
+               ccb[3] = (unsigned char) (blknr >> 16) & 0xFF;  /*  */
+               ccb[4] = (unsigned char) (blknr >> 8) & 0xFF;
+               ccb[5] = (unsigned char) blknr & 0xFF;  /* LSB Block */
+               ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */
+               ccb[7] = (unsigned char) (cnt >> 16) & 0xFF;
+               ccb[8] = (unsigned char) (cnt >> 8) & 0xFF;
+               ccb[9] = (unsigned char) cnt & 0xFF;    /* LSB Block */
+               ccb[10] = 0;    /* reserved */
+               ccb[11] = 0;    /* reserved */
+
+               if (atapi_issue_autoreq(device, ccb, 12,
+                                       (unsigned char *)buffer,
+                                       cnt * ATAPI_READ_BLOCK_SIZE)
+                   == 0xFF) {
+                       return n;
+               }
+               n += cnt;
+               blkcnt -= cnt;
+               blknr += cnt;
+               buffer += (cnt * ATAPI_READ_BLOCK_SIZE);
+       } while (blkcnt > 0);
+       return n;
+}
+
+static void atapi_inquiry(struct blk_desc *dev_desc)
+{
+       unsigned char ccb[12];  /* Command descriptor block */
+       unsigned char iobuf[64];        /* temp buf */
+       unsigned char c;
+       int device;
+
+       device = dev_desc->devnum;
+       dev_desc->type = DEV_TYPE_UNKNOWN;      /* not yet valid */
+       dev_desc->block_read = atapi_read;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+
+       ccb[0] = ATAPI_CMD_INQUIRY;
+       ccb[4] = 40;            /* allocation Legnth */
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 40);
+
+       debug("ATAPI_CMD_INQUIRY returned %x\n", c);
+       if (c != 0)
+               return;
+
+       /* copy device ident strings */
+       ident_cpy((unsigned char *)dev_desc->vendor, &iobuf[8], 8);
+       ident_cpy((unsigned char *)dev_desc->product, &iobuf[16], 16);
+       ident_cpy((unsigned char *)dev_desc->revision, &iobuf[32], 5);
+
+       dev_desc->lun = 0;
+       dev_desc->lba = 0;
+       dev_desc->blksz = 0;
+       dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
+       dev_desc->type = iobuf[0] & 0x1f;
+
+       if ((iobuf[1] & 0x80) == 0x80)
+               dev_desc->removable = 1;
+       else
+               dev_desc->removable = 0;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+       ccb[0] = ATAPI_CMD_START_STOP;
+       ccb[4] = 0x03;          /* start */
+
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0);
+
+       debug("ATAPI_CMD_START_STOP returned %x\n", c);
+       if (c != 0)
+               return;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0);
+
+       debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c);
+       if (c != 0)
+               return;
+
+       memset(ccb, 0, sizeof(ccb));
+       memset(iobuf, 0, sizeof(iobuf));
+       ccb[0] = ATAPI_CMD_READ_CAP;
+       c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 8);
+       debug("ATAPI_CMD_READ_CAP returned %x\n", c);
+       if (c != 0)
+               return;
+
+       debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",
+             iobuf[0], iobuf[1], iobuf[2], iobuf[3],
+             iobuf[4], iobuf[5], iobuf[6], iobuf[7]);
+
+       dev_desc->lba = ((unsigned long) iobuf[0] << 24) +
+               ((unsigned long) iobuf[1] << 16) +
+               ((unsigned long) iobuf[2] << 8) + ((unsigned long) iobuf[3]);
+       dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
+               ((unsigned long) iobuf[5] << 16) +
+               ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
+       dev_desc->log2blksz = LOG2(dev_desc->blksz);
+#ifdef CONFIG_LBA48
+       /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
+       dev_desc->lba48 = 0;
+#endif
+       return;
+}
+
+#endif /* CONFIG_ATAPI */
+
+static void ide_ident(struct blk_desc *dev_desc)
+{
+       unsigned char c;
+       hd_driveid_t iop;
+
+#ifdef CONFIG_ATAPI
+       int retries = 0;
+#endif
+       int device;
+
+       device = dev_desc->devnum;
+       printf("  Device %d: ", device);
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+       /* Select device
+        */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       dev_desc->if_type = IF_TYPE_IDE;
+#ifdef CONFIG_ATAPI
+
+       retries = 0;
+
+       /* Warning: This will be tricky to read */
+       while (retries <= 1) {
+               /* check signature */
+               if ((ide_inb(device, ATA_SECT_CNT) == 0x01) &&
+                   (ide_inb(device, ATA_SECT_NUM) == 0x01) &&
+                   (ide_inb(device, ATA_CYL_LOW) == 0x14) &&
+                   (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) {
+                       /* ATAPI Signature found */
+                       dev_desc->if_type = IF_TYPE_ATAPI;
+                       /*
+                        * Start Ident Command
+                        */
+                       ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT);
+                       /*
+                        * Wait for completion - ATAPI devices need more time
+                        * to become ready
+                        */
+                       c = ide_wait(device, ATAPI_TIME_OUT);
+               } else
+#endif
+               {
+                       /*
+                        * Start Ident Command
+                        */
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT);
+
+                       /*
+                        * Wait for completion
+                        */
+                       c = ide_wait(device, IDE_TIME_OUT);
+               }
+               ide_led(DEVICE_LED(device), 0); /* LED off      */
+
+               if (((c & ATA_STAT_DRQ) == 0) ||
+                   ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) {
+#ifdef CONFIG_ATAPI
+                       {
+                               /*
+                                * Need to soft reset the device
+                                * in case it's an ATAPI...
+                                */
+                               debug("Retrying...\n");
+                               ide_outb(device, ATA_DEV_HD,
+                                        ATA_LBA | ATA_DEVICE(device));
+                               udelay(100000);
+                               ide_outb(device, ATA_COMMAND, 0x08);
+                               udelay(500000); /* 500 ms */
+                       }
+                       /*
+                        * Select device
+                        */
+                       ide_outb(device, ATA_DEV_HD,
+                                ATA_LBA | ATA_DEVICE(device));
+                       retries++;
+#else
+                       return;
+#endif
+               }
+#ifdef CONFIG_ATAPI
+               else
+                       break;
+       }                       /* see above - ugly to read */
+
+       if (retries == 2)       /* Not found */
+               return;
+#endif
+
+       ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);
+
+       ident_cpy((unsigned char *)dev_desc->revision, iop.fw_rev,
+                 sizeof(dev_desc->revision));
+       ident_cpy((unsigned char *)dev_desc->vendor, iop.model,
+                 sizeof(dev_desc->vendor));
+       ident_cpy((unsigned char *)dev_desc->product, iop.serial_no,
+                 sizeof(dev_desc->product));
+#ifdef __LITTLE_ENDIAN
+       /*
+        * firmware revision, model, and serial number have Big Endian Byte
+        * order in Word. Convert all three to little endian.
+        *
+        * See CF+ and CompactFlash Specification Revision 2.0:
+        * 6.2.1.6: Identify Drive, Table 39 for more details
+        */
+
+       strswab(dev_desc->revision);
+       strswab(dev_desc->vendor);
+       strswab(dev_desc->product);
+#endif /* __LITTLE_ENDIAN */
+
+       if ((iop.config & 0x0080) == 0x0080)
+               dev_desc->removable = 1;
+       else
+               dev_desc->removable = 0;
+
+#ifdef CONFIG_ATAPI
+       if (dev_desc->if_type == IF_TYPE_ATAPI) {
+               atapi_inquiry(dev_desc);
+               return;
+       }
+#endif /* CONFIG_ATAPI */
+
+#ifdef __BIG_ENDIAN
+       /* swap shorts */
+       dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16);
+#else  /* ! __BIG_ENDIAN */
+       /*
+        * do not swap shorts on little endian
+        *
+        * See CF+ and CompactFlash Specification Revision 2.0:
+        * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details.
+        */
+       dev_desc->lba = iop.lba_capacity;
+#endif /* __BIG_ENDIAN */
+
+#ifdef CONFIG_LBA48
+       if (iop.command_set_2 & 0x0400) {       /* LBA 48 support */
+               dev_desc->lba48 = 1;
+               dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] |
+                       ((unsigned long long) iop.lba48_capacity[1] << 16) |
+                       ((unsigned long long) iop.lba48_capacity[2] << 32) |
+                       ((unsigned long long) iop.lba48_capacity[3] << 48);
+       } else {
+               dev_desc->lba48 = 0;
+       }
+#endif /* CONFIG_LBA48 */
+       /* assuming HD */
+       dev_desc->type = DEV_TYPE_HARDDISK;
+       dev_desc->blksz = ATA_BLOCKSIZE;
+       dev_desc->log2blksz = LOG2(dev_desc->blksz);
+       dev_desc->lun = 0;      /* just to fill something in... */
+
+#if 0                          /* only used to test the powersaving mode,
+                                * if enabled, the drive goes after 5 sec
+                                * in standby mode */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       c = ide_wait(device, IDE_TIME_OUT);
+       ide_outb(device, ATA_SECT_CNT, 1);
+       ide_outb(device, ATA_LBA_LOW, 0);
+       ide_outb(device, ATA_LBA_MID, 0);
+       ide_outb(device, ATA_LBA_HIGH, 0);
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       ide_outb(device, ATA_COMMAND, 0xe3);
+       udelay(50);
+       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
+#endif
+}
+
+__weak void ide_led(uchar led, uchar status)
+{
+#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */
+       static uchar led_buffer;        /* Buffer for current LED status */
+
+       uchar *led_port = LED_PORT;
+
+       if (status)             /* switch LED on        */
+               led_buffer |= led;
+       else                    /* switch LED off       */
+               led_buffer &= ~led;
+
+       *led_port = led_buffer;
+#endif
+}
+
+__weak void ide_outb(int dev, int port, unsigned char val)
+{
+       debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
+             dev, port, val,
+             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
+
+#if defined(CONFIG_IDE_AHB)
+       if (port) {
+               /* write command */
+               ide_write_register(dev, port, val);
+       } else {
+               /* write data */
+               outb(val, (ATA_CURR_BASE(dev)));
+       }
+#else
+       outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
+}
+
+__weak unsigned char ide_inb(int dev, int port)
+{
+       uchar val;
+
+#if defined(CONFIG_IDE_AHB)
+       val = ide_read_register(dev, port);
+#else
+       val = inb((ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
+
+       debug("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
+             dev, port,
+             (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)), val);
+       return val;
+}
+
+void ide_init(void)
+{
+       unsigned char c;
+       int i, bus;
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+       extern int ide_devices_found;   /* Initialized in check_ide_device() */
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+#ifdef CONFIG_IDE_PREINIT
+       WATCHDOG_RESET();
+
+       if (ide_preinit()) {
+               puts("ide_preinit failed\n");
+               return;
+       }
+#endif /* CONFIG_IDE_PREINIT */
+
+       WATCHDOG_RESET();
+
+       /*
+        * Reset the IDE just to be sure.
+        * Light LED's to show
+        */
+       ide_led((LED_IDE1 | LED_IDE2), 1);      /* LED's on     */
+
+       /* ATAPI Drives seems to need a proper IDE Reset */
+       ide_reset();
+
+#ifdef CONFIG_IDE_INIT_POSTRESET
+       WATCHDOG_RESET();
+
+       if (ide_init_postreset()) {
+               puts("ide_preinit_postreset failed\n");
+               return;
+       }
+#endif /* CONFIG_IDE_INIT_POSTRESET */
+
+       /*
+        * Wait for IDE to get ready.
+        * According to spec, this can take up to 31 seconds!
+        */
+       for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) {
+               int dev =
+                       bus * (CONFIG_SYS_IDE_MAXDEVICE /
+                              CONFIG_SYS_IDE_MAXBUS);
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+               /* Skip non-ide devices from probing */
+               if ((ide_devices_found & (1 << bus)) == 0) {
+                       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off */
+                       continue;
+               }
+#endif
+               printf("Bus %d: ", bus);
+
+               ide_bus_ok[bus] = 0;
+
+               /* Select device
+                */
+               udelay(100000); /* 100 ms */
+               ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
+               udelay(100000); /* 100 ms */
+               i = 0;
+               do {
+                       udelay(10000);  /* 10 ms */
+
+                       c = ide_inb(dev, ATA_STATUS);
+                       i++;
+                       if (i > (ATA_RESET_TIME * 100)) {
+                               puts("** Timeout **\n");
+                               /* LED's off */
+                               ide_led((LED_IDE1 | LED_IDE2), 0);
+                               return;
+                       }
+                       if ((i >= 100) && ((i % 100) == 0))
+                               putc('.');
+
+               } while (c & ATA_STAT_BUSY);
+
+               if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
+                       puts("not available  ");
+                       debug("Status = 0x%02X ", c);
+#ifndef CONFIG_ATAPI           /* ATAPI Devices do not set DRDY */
+               } else if ((c & ATA_STAT_READY) == 0) {
+                       puts("not available  ");
+                       debug("Status = 0x%02X ", c);
+#endif
+               } else {
+                       puts("OK ");
+                       ide_bus_ok[bus] = 1;
+               }
+               WATCHDOG_RESET();
+       }
+
+       putc('\n');
+
+       ide_led((LED_IDE1 | LED_IDE2), 0);      /* LED's off    */
+
+       for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
+               int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
+               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+               ide_dev_desc[i].if_type = IF_TYPE_IDE;
+               ide_dev_desc[i].devnum = i;
+               ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+               ide_dev_desc[i].blksz = 0;
+               ide_dev_desc[i].log2blksz =
+                       LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
+               ide_dev_desc[i].lba = 0;
+#ifndef CONFIG_BLK
+               ide_dev_desc[i].block_read = ide_read;
+               ide_dev_desc[i].block_write = ide_write;
+#endif
+               if (!ide_bus_ok[IDE_BUS(i)])
+                       continue;
+               ide_led(led, 1);        /* LED on       */
+               ide_ident(&ide_dev_desc[i]);
+               ide_led(led, 0);        /* LED off      */
+               dev_print(&ide_dev_desc[i]);
+
+               if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
+                       /* initialize partition type */
+                       part_init(&ide_dev_desc[i]);
+               }
+       }
+       WATCHDOG_RESET();
+}
+
+/* We only need to swap data if we are running on a big endian cpu. */
+#if defined(__LITTLE_ENDIAN)
+__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
+{
+       ide_input_data(dev, sect_buf, words);
+}
+#else
+__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
+{
+       volatile ushort *pbuf =
+               (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       ushort *dbuf = (ushort *)sect_buf;
+
+       debug("in input swap data base for read is %lx\n",
+             (unsigned long) pbuf);
+
+       while (words--) {
+#ifdef __MIPS__
+               *dbuf++ = swab16p((u16 *)pbuf);
+               *dbuf++ = swab16p((u16 *)pbuf);
+#else
+               *dbuf++ = ld_le16(pbuf);
+               *dbuf++ = ld_le16(pbuf);
+#endif /* !MIPS */
+       }
+}
+#endif /* __LITTLE_ENDIAN */
+
+
+#if defined(CONFIG_IDE_SWAP_IO)
+__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+       while (words--) {
+               EIEIO;
+               *pbuf = *dbuf++;
+               EIEIO;
+               *pbuf = *dbuf++;
+       }
+}
+#else  /* ! CONFIG_IDE_SWAP_IO */
+__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
+{
+#if defined(CONFIG_IDE_AHB)
+       ide_write_data(dev, sect_buf, words);
+#else
+       outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
+#endif
+}
+#endif /* CONFIG_IDE_SWAP_IO */
+
+#if defined(CONFIG_IDE_SWAP_IO)
+__weak void ide_input_data(int dev, ulong *sect_buf, int words)
+{
+       ushort *dbuf;
+       volatile ushort *pbuf;
+
+       pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+       dbuf = (ushort *)sect_buf;
+
+       debug("in input data base for read is %lx\n", (unsigned long) pbuf);
+
+       while (words--) {
+               EIEIO;
+               *dbuf++ = *pbuf;
+               EIEIO;
+               *dbuf++ = *pbuf;
+       }
+}
+#else  /* ! CONFIG_IDE_SWAP_IO */
+__weak void ide_input_data(int dev, ulong *sect_buf, int words)
+{
+#if defined(CONFIG_IDE_AHB)
+       ide_read_data(dev, sect_buf, words);
+#else
+       insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1);
+#endif
+}
+
+#endif /* CONFIG_IDE_SWAP_IO */
+
+#ifdef CONFIG_BLK
+ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+              void *buffer)
+#else
+ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+              void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       ulong n = 0;
+       unsigned char c;
+       unsigned char pwrsave = 0;      /* power save */
+
+#ifdef CONFIG_LBA48
+       unsigned char lba48 = 0;
+
+       if (blknr & 0x0000fffff0000000ULL) {
+               /* more than 28 bits used, use 48bit mode */
+               lba48 = 1;
+       }
+#endif
+       debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
+             device, blknr, blkcnt, (ulong) buffer);
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+
+       /* Select device
+        */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       c = ide_wait(device, IDE_TIME_OUT);
+
+       if (c & ATA_STAT_BUSY) {
+               printf("IDE read: device %d not ready\n", device);
+               goto IDE_READ_E;
+       }
+
+       /* first check if the drive is in Powersaving mode, if yes,
+        * increase the timeout value */
+       ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR);
+       udelay(50);
+
+       c = ide_wait(device, IDE_TIME_OUT);     /* can't take over 500 ms */
+
+       if (c & ATA_STAT_BUSY) {
+               printf("IDE read: device %d not ready\n", device);
+               goto IDE_READ_E;
+       }
+       if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+               printf("No Powersaving mode %X\n", c);
+       } else {
+               c = ide_inb(device, ATA_SECT_CNT);
+               debug("Powersaving %02X\n", c);
+               if (c == 0)
+                       pwrsave = 1;
+       }
+
+
+       while (blkcnt-- > 0) {
+               c = ide_wait(device, IDE_TIME_OUT);
+
+               if (c & ATA_STAT_BUSY) {
+                       printf("IDE read: device %d not ready\n", device);
+                       break;
+               }
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       /* write high bits */
+                       ide_outb(device, ATA_SECT_CNT, 0);
+                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
+#ifdef CONFIG_SYS_64BIT_LBA
+                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
+                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
+#else
+                       ide_outb(device, ATA_LBA_MID, 0);
+                       ide_outb(device, ATA_LBA_HIGH, 0);
+#endif
+               }
+#endif
+               ide_outb(device, ATA_SECT_CNT, 1);
+               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
+               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
+               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       ide_outb(device, ATA_DEV_HD,
+                                ATA_LBA | ATA_DEVICE(device));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT);
+
+               } else
+#endif
+               {
+                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
+                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_READ);
+               }
+
+               udelay(50);
+
+               if (pwrsave) {
+                       /* may take up to 4 sec */
+                       c = ide_wait(device, IDE_SPIN_UP_TIME_OUT);
+                       pwrsave = 0;
+               } else {
+                       /* can't take over 500 ms */
+                       c = ide_wait(device, IDE_TIME_OUT);
+               }
+
+               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
+                   ATA_STAT_DRQ) {
+                       printf("Error (no IRQ) dev %d blk " LBAF
+                              ": status %#02x\n", device, blknr, c);
+                       break;
+               }
+
+               ide_input_data(device, buffer, ATA_SECTORWORDS);
+               (void) ide_inb(device, ATA_STATUS);     /* clear IRQ */
+
+               ++n;
+               ++blknr;
+               buffer += ATA_BLOCKSIZE;
+       }
+IDE_READ_E:
+       ide_led(DEVICE_LED(device), 0); /* LED off      */
+       return n;
+}
+
+#ifdef CONFIG_BLK
+ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+               const void *buffer)
+#else
+ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+               const void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       ulong n = 0;
+       unsigned char c;
+
+#ifdef CONFIG_LBA48
+       unsigned char lba48 = 0;
+
+       if (blknr & 0x0000fffff0000000ULL) {
+               /* more than 28 bits used, use 48bit mode */
+               lba48 = 1;
+       }
+#endif
+
+       ide_led(DEVICE_LED(device), 1); /* LED on       */
+
+       /* Select device
+        */
+       ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+
+       while (blkcnt-- > 0) {
+               c = ide_wait(device, IDE_TIME_OUT);
+
+               if (c & ATA_STAT_BUSY) {
+                       printf("IDE read: device %d not ready\n", device);
+                       goto WR_OUT;
+               }
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       /* write high bits */
+                       ide_outb(device, ATA_SECT_CNT, 0);
+                       ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
+#ifdef CONFIG_SYS_64BIT_LBA
+                       ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
+                       ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
+#else
+                       ide_outb(device, ATA_LBA_MID, 0);
+                       ide_outb(device, ATA_LBA_HIGH, 0);
+#endif
+               }
+#endif
+               ide_outb(device, ATA_SECT_CNT, 1);
+               ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
+               ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
+               ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
+
+#ifdef CONFIG_LBA48
+               if (lba48) {
+                       ide_outb(device, ATA_DEV_HD,
+                                ATA_LBA | ATA_DEVICE(device));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT);
+
+               } else
+#endif
+               {
+                       ide_outb(device, ATA_DEV_HD, ATA_LBA |
+                                ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
+                       ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE);
+               }
+
+               udelay(50);
+
+               /* can't take over 500 ms */
+               c = ide_wait(device, IDE_TIME_OUT);
+
+               if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
+                   ATA_STAT_DRQ) {
+                       printf("Error (no IRQ) dev %d blk " LBAF
+                              ": status %#02x\n", device, blknr, c);
+                       goto WR_OUT;
+               }
+
+               ide_output_data(device, buffer, ATA_SECTORWORDS);
+               c = ide_inb(device, ATA_STATUS);        /* clear IRQ */
+               ++n;
+               ++blknr;
+               buffer += ATA_BLOCKSIZE;
+       }
+WR_OUT:
+       ide_led(DEVICE_LED(device), 0); /* LED off      */
+       return n;
+}
+
+#if defined(CONFIG_OF_IDE_FIXUP)
+int ide_device_present(int dev)
+{
+       if (dev >= CONFIG_SYS_IDE_MAXBUS)
+               return 0;
+       return ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN ? 0 : 1;
+}
+#endif
+
+#ifdef CONFIG_BLK
+static const struct blk_ops ide_blk_ops = {
+       .read   = ide_read,
+       .write  = ide_write,
+};
+
+U_BOOT_DRIVER(ide_blk) = {
+       .name           = "ide_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &ide_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(ide) = {
+       .if_typename    = "ide",
+       .if_type        = IF_TYPE_IDE,
+       .max_devs       = CONFIG_SYS_IDE_MAXDEVICE,
+       .desc           = ide_dev_desc,
+};
+#endif
diff --git a/common/sata.c b/common/sata.c
new file mode 100644 (file)
index 0000000..88f08c9
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2000-2005, DENX Software Engineering
+ *             Wolfgang Denk <wd@denx.de>
+ * Copyright (C) Procsys. All rights reserved.
+ *             Mushtaq Khan <mushtaq_k@procsys.com>
+ *                     <mushtaqk_921@yahoo.co.in>
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ *             Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <sata.h>
+
+struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
+
+#ifdef CONFIG_PARTITIONS
+struct blk_desc *sata_get_dev(int dev)
+{
+       return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
+}
+#endif
+
+#ifdef CONFIG_BLK
+static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
+                               lbaint_t blkcnt, void *dst)
+{
+       return -ENOSYS;
+}
+
+static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       return -ENOSYS;
+}
+#else
+static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
+                               lbaint_t blkcnt, void *dst)
+{
+       return sata_read(block_dev->devnum, start, blkcnt, dst);
+}
+
+static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       return sata_write(block_dev->devnum, start, blkcnt, buffer);
+}
+#endif
+
+int __sata_initialize(void)
+{
+       int rc;
+       int i;
+
+       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
+               memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
+               sata_dev_desc[i].if_type = IF_TYPE_SATA;
+               sata_dev_desc[i].devnum = i;
+               sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+               sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
+               sata_dev_desc[i].lba = 0;
+               sata_dev_desc[i].blksz = 512;
+               sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
+#ifndef CONFIG_BLK
+               sata_dev_desc[i].block_read = sata_bread;
+               sata_dev_desc[i].block_write = sata_bwrite;
+#endif
+               rc = init_sata(i);
+               if (!rc) {
+                       rc = scan_sata(i);
+                       if (!rc && sata_dev_desc[i].lba > 0 &&
+                           sata_dev_desc[i].blksz > 0)
+                               part_init(&sata_dev_desc[i]);
+               }
+       }
+
+       return rc;
+}
+int sata_initialize(void) __attribute__((weak, alias("__sata_initialize")));
+
+__weak int __sata_stop(void)
+{
+       int i, err = 0;
+
+       for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
+               err |= reset_sata(i);
+
+       if (err)
+               printf("Could not reset some SATA devices\n");
+
+       return err;
+}
+int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
+
+#ifdef CONFIG_BLK
+static const struct blk_ops sata_blk_ops = {
+       .read   = sata_bread,
+       .write  = sata_bwrite,
+};
+
+U_BOOT_DRIVER(sata_blk) = {
+       .name           = "sata_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &sata_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(sata) = {
+       .if_typename    = "sata",
+       .if_type        = IF_TYPE_SATA,
+       .max_devs       = CONFIG_SYS_SATA_MAX_DEVICE,
+       .desc           = sata_dev_desc,
+};
+#endif
diff --git a/common/scsi.c b/common/scsi.c
new file mode 100644 (file)
index 0000000..8ac28dd
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <inttypes.h>
+#include <pci.h>
+#include <scsi.h>
+
+#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
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
+const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST };
+#endif
+static ccb tempccb;    /* temporary scsi command buffer */
+
+static unsigned char tempbuff[512]; /* temporary data buffer */
+
+static int scsi_max_devs; /* number of highest available scsi device */
+
+static int scsi_curr_dev; /* current device */
+
+static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
+
+/* almost the maximum amount of the scsi_ext command.. */
+#define SCSI_MAX_READ_BLK 0xFFFF
+#define SCSI_LBA48_READ        0xFFFFFFF
+
+#ifdef CONFIG_SYS_64BIT_LBA
+void scsi_setup_read16(ccb *pccb, lbaint_t start, unsigned long blocks)
+{
+       pccb->cmd[0] = SCSI_READ16;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = (unsigned char)(start >> 56) & 0xff;
+       pccb->cmd[3] = (unsigned char)(start >> 48) & 0xff;
+       pccb->cmd[4] = (unsigned char)(start >> 40) & 0xff;
+       pccb->cmd[5] = (unsigned char)(start >> 32) & 0xff;
+       pccb->cmd[6] = (unsigned char)(start >> 24) & 0xff;
+       pccb->cmd[7] = (unsigned char)(start >> 16) & 0xff;
+       pccb->cmd[8] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[9] = (unsigned char)start & 0xff;
+       pccb->cmd[10] = 0;
+       pccb->cmd[11] = (unsigned char)(blocks >> 24) & 0xff;
+       pccb->cmd[12] = (unsigned char)(blocks >> 16) & 0xff;
+       pccb->cmd[13] = (unsigned char)(blocks >> 8) & 0xff;
+       pccb->cmd[14] = (unsigned char)blocks & 0xff;
+       pccb->cmd[15] = 0;
+       pccb->cmdlen = 16;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+       debug("scsi_setup_read16: cmd: %02X %02X startblk %02X%02X%02X%02X%02X%02X%02X%02X blccnt %02X%02X%02X%02X\n",
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
+             pccb->cmd[6], pccb->cmd[7], pccb->cmd[8], pccb->cmd[9],
+             pccb->cmd[11], pccb->cmd[12], pccb->cmd[13], pccb->cmd[14]);
+}
+#endif
+
+void scsi_setup_read_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
+{
+       pccb->cmd[0] = SCSI_READ10;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
+       pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
+       pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[5] = (unsigned char)start & 0xff;
+       pccb->cmd[6] = 0;
+       pccb->cmd[7] = (unsigned char)(blocks >> 8) & 0xff;
+       pccb->cmd[8] = (unsigned char)blocks & 0xff;
+       pccb->cmd[6] = 0;
+       pccb->cmdlen = 10;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+       debug("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
+             pccb->cmd[7], pccb->cmd[8]);
+}
+
+void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
+{
+       pccb->cmd[0] = SCSI_WRITE10;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
+       pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
+       pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[5] = (unsigned char)start & 0xff;
+       pccb->cmd[6] = 0;
+       pccb->cmd[7] = ((unsigned char)(blocks >> 8)) & 0xff;
+       pccb->cmd[8] = (unsigned char)blocks & 0xff;
+       pccb->cmd[9] = 0;
+       pccb->cmdlen = 10;
+       pccb->msgout[0] = SCSI_IDENTIFY;  /* NOT USED */
+       debug("%s: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
+             __func__,
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4], pccb->cmd[5],
+             pccb->cmd[7], pccb->cmd[8]);
+}
+
+void scsi_setup_read6(ccb *pccb, lbaint_t start, unsigned short blocks)
+{
+       pccb->cmd[0] = SCSI_READ6;
+       pccb->cmd[1] = pccb->lun << 5 | ((unsigned char)(start >> 16) & 0x1f);
+       pccb->cmd[2] = (unsigned char)(start >> 8) & 0xff;
+       pccb->cmd[3] = (unsigned char)start & 0xff;
+       pccb->cmd[4] = (unsigned char)blocks & 0xff;
+       pccb->cmd[5] = 0;
+       pccb->cmdlen = 6;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+       debug("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
+             pccb->cmd[0], pccb->cmd[1],
+             pccb->cmd[2], pccb->cmd[3], pccb->cmd[4]);
+}
+
+
+void scsi_setup_inquiry(ccb *pccb)
+{
+       pccb->cmd[0] = SCSI_INQUIRY;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = 0;
+       pccb->cmd[3] = 0;
+       if (pccb->datalen > 255)
+               pccb->cmd[4] = 255;
+       else
+               pccb->cmd[4] = (unsigned char)pccb->datalen;
+       pccb->cmd[5] = 0;
+       pccb->cmdlen = 6;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+}
+
+#ifdef CONFIG_BLK
+static ulong scsi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                      void *buffer)
+#else
+static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
+                      lbaint_t blkcnt, void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       lbaint_t start, blks;
+       uintptr_t buf_addr;
+       unsigned short smallblks = 0;
+       ccb *pccb = (ccb *)&tempccb;
+       device &= 0xff;
+
+       /* Setup device */
+       pccb->target = scsi_dev_desc[device].target;
+       pccb->lun = scsi_dev_desc[device].lun;
+       buf_addr = (unsigned long)buffer;
+       start = blknr;
+       blks = blkcnt;
+       debug("\nscsi_read: dev %d startblk " LBAF
+             ", blccnt " LBAF " buffer %lx\n",
+             device, start, blks, (unsigned long)buffer);
+       do {
+               pccb->pdata = (unsigned char *)buf_addr;
+#ifdef CONFIG_SYS_64BIT_LBA
+               if (start > SCSI_LBA48_READ) {
+                       unsigned long blocks;
+                       blocks = min_t(lbaint_t, blks, SCSI_MAX_READ_BLK);
+                       pccb->datalen = scsi_dev_desc[device].blksz * blocks;
+                       scsi_setup_read16(pccb, start, blocks);
+                       start += blocks;
+                       blks -= blocks;
+               } else
+#endif
+               if (blks > SCSI_MAX_READ_BLK) {
+                       pccb->datalen = scsi_dev_desc[device].blksz *
+                               SCSI_MAX_READ_BLK;
+                       smallblks = SCSI_MAX_READ_BLK;
+                       scsi_setup_read_ext(pccb, start, smallblks);
+                       start += SCSI_MAX_READ_BLK;
+                       blks -= SCSI_MAX_READ_BLK;
+               } else {
+                       pccb->datalen = scsi_dev_desc[device].blksz * blks;
+                       smallblks = (unsigned short)blks;
+                       scsi_setup_read_ext(pccb, start, smallblks);
+                       start += blks;
+                       blks = 0;
+               }
+               debug("scsi_read_ext: startblk " LBAF
+                     ", blccnt %x buffer %" PRIXPTR "\n",
+                     start, smallblks, buf_addr);
+               if (scsi_exec(pccb) != true) {
+                       scsi_print_error(pccb);
+                       blkcnt -= blks;
+                       break;
+               }
+               buf_addr += pccb->datalen;
+       } while (blks != 0);
+       debug("scsi_read_ext: end startblk " LBAF
+             ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
+       return blkcnt;
+}
+
+/*******************************************************************************
+ * scsi_write
+ */
+
+/* Almost the maximum amount of the scsi_ext command.. */
+#define SCSI_MAX_WRITE_BLK 0xFFFF
+
+#ifdef CONFIG_BLK
+static ulong scsi_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                       const void *buffer)
+#else
+static ulong scsi_write(struct blk_desc *block_dev, lbaint_t blknr,
+                       lbaint_t blkcnt, const void *buffer)
+#endif
+{
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
+       int device = block_dev->devnum;
+       lbaint_t start, blks;
+       uintptr_t buf_addr;
+       unsigned short smallblks;
+       ccb *pccb = (ccb *)&tempccb;
+
+       device &= 0xff;
+
+       /* Setup device */
+       pccb->target = scsi_dev_desc[device].target;
+       pccb->lun = scsi_dev_desc[device].lun;
+       buf_addr = (unsigned long)buffer;
+       start = blknr;
+       blks = blkcnt;
+       debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
+             __func__, device, start, blks, (unsigned long)buffer);
+       do {
+               pccb->pdata = (unsigned char *)buf_addr;
+               if (blks > SCSI_MAX_WRITE_BLK) {
+                       pccb->datalen = (scsi_dev_desc[device].blksz *
+                                        SCSI_MAX_WRITE_BLK);
+                       smallblks = SCSI_MAX_WRITE_BLK;
+                       scsi_setup_write_ext(pccb, start, smallblks);
+                       start += SCSI_MAX_WRITE_BLK;
+                       blks -= SCSI_MAX_WRITE_BLK;
+               } else {
+                       pccb->datalen = scsi_dev_desc[device].blksz * blks;
+                       smallblks = (unsigned short)blks;
+                       scsi_setup_write_ext(pccb, start, smallblks);
+                       start += blks;
+                       blks = 0;
+               }
+               debug("%s: startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
+                     __func__, start, smallblks, buf_addr);
+               if (scsi_exec(pccb) != true) {
+                       scsi_print_error(pccb);
+                       blkcnt -= blks;
+                       break;
+               }
+               buf_addr += pccb->datalen;
+       } while (blks != 0);
+       debug("%s: end startblk " LBAF ", blccnt %x buffer %" PRIXPTR "\n",
+             __func__, start, smallblks, buf_addr);
+       return blkcnt;
+}
+
+int scsi_get_disk_count(void)
+{
+       return scsi_max_devs;
+}
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT)
+void scsi_init(void)
+{
+       int busdevfunc = -1;
+       int i;
+       /*
+        * Find a device from the list, this driver will support a single
+        * controller.
+        */
+       for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
+               /* get PCI Device ID */
+#ifdef CONFIG_DM_PCI
+               struct udevice *dev;
+               int ret;
+
+               ret = dm_pci_find_device(scsi_device_list[i].vendor,
+                                        scsi_device_list[i].device, 0, &dev);
+               if (!ret) {
+                       busdevfunc = dm_pci_get_bdf(dev);
+                       break;
+               }
+#else
+               busdevfunc = pci_find_device(scsi_device_list[i].vendor,
+                                            scsi_device_list[i].device,
+                                            0);
+#endif
+               if (busdevfunc != -1)
+                       break;
+       }
+
+       if (busdevfunc == -1) {
+               printf("Error: SCSI Controller(s) ");
+               for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) {
+                       printf("%04X:%04X ",
+                              scsi_device_list[i].vendor,
+                              scsi_device_list[i].device);
+               }
+               printf("not found\n");
+               return;
+       }
+#ifdef DEBUG
+       else {
+               printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n",
+                      scsi_device_list[i].vendor,
+                      scsi_device_list[i].device,
+                      (busdevfunc >> 16) & 0xFF,
+                      (busdevfunc >> 11) & 0x1F,
+                      (busdevfunc >> 8) & 0x7);
+       }
+#endif
+       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
+       scsi_low_level_init(busdevfunc);
+       scsi_scan(1);
+       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
+}
+#endif
+
+/* copy src to dest, skipping leading and trailing blanks
+ * and null terminate the string
+ */
+void scsi_ident_cpy(unsigned char *dest, unsigned char *src, unsigned int len)
+{
+       int start, end;
+
+       start = 0;
+       while (start < len) {
+               if (src[start] != ' ')
+                       break;
+               start++;
+       }
+       end = len-1;
+       while (end > start) {
+               if (src[end] != ' ')
+                       break;
+               end--;
+       }
+       for (; start <= end; start++)
+               *dest ++= src[start];
+       *dest = '\0';
+}
+
+
+/* Trim trailing blanks, and NUL-terminate string
+ */
+void scsi_trim_trail(unsigned char *str, unsigned int len)
+{
+       unsigned char *p = str + len - 1;
+
+       while (len-- > 0) {
+               *p-- = '\0';
+               if (*p != ' ')
+                       return;
+       }
+}
+
+int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
+{
+       *capacity = 0;
+
+       memset(pccb->cmd, '\0', sizeof(pccb->cmd));
+       pccb->cmd[0] = SCSI_RD_CAPAC10;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmdlen = 10;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+
+       pccb->datalen = 8;
+       if (scsi_exec(pccb) != true)
+               return 1;
+
+       *capacity = ((lbaint_t)pccb->pdata[0] << 24) |
+                   ((lbaint_t)pccb->pdata[1] << 16) |
+                   ((lbaint_t)pccb->pdata[2] << 8)  |
+                   ((lbaint_t)pccb->pdata[3]);
+
+       if (*capacity != 0xffffffff) {
+               /* Read capacity (10) was sufficient for this drive. */
+               *blksz = ((unsigned long)pccb->pdata[4] << 24) |
+                        ((unsigned long)pccb->pdata[5] << 16) |
+                        ((unsigned long)pccb->pdata[6] << 8)  |
+                        ((unsigned long)pccb->pdata[7]);
+               return 0;
+       }
+
+       /* Read capacity (10) was insufficient. Use read capacity (16). */
+       memset(pccb->cmd, '\0', sizeof(pccb->cmd));
+       pccb->cmd[0] = SCSI_RD_CAPAC16;
+       pccb->cmd[1] = 0x10;
+       pccb->cmdlen = 16;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+
+       pccb->datalen = 16;
+       if (scsi_exec(pccb) != true)
+               return 1;
+
+       *capacity = ((uint64_t)pccb->pdata[0] << 56) |
+                   ((uint64_t)pccb->pdata[1] << 48) |
+                   ((uint64_t)pccb->pdata[2] << 40) |
+                   ((uint64_t)pccb->pdata[3] << 32) |
+                   ((uint64_t)pccb->pdata[4] << 24) |
+                   ((uint64_t)pccb->pdata[5] << 16) |
+                   ((uint64_t)pccb->pdata[6] << 8)  |
+                   ((uint64_t)pccb->pdata[7]);
+
+       *blksz = ((uint64_t)pccb->pdata[8]  << 56) |
+                ((uint64_t)pccb->pdata[9]  << 48) |
+                ((uint64_t)pccb->pdata[10] << 40) |
+                ((uint64_t)pccb->pdata[11] << 32) |
+                ((uint64_t)pccb->pdata[12] << 24) |
+                ((uint64_t)pccb->pdata[13] << 16) |
+                ((uint64_t)pccb->pdata[14] << 8)  |
+                ((uint64_t)pccb->pdata[15]);
+
+       return 0;
+}
+
+
+/*
+ * Some setup (fill-in) routines
+ */
+void scsi_setup_test_unit_ready(ccb *pccb)
+{
+       pccb->cmd[0] = SCSI_TST_U_RDY;
+       pccb->cmd[1] = pccb->lun << 5;
+       pccb->cmd[2] = 0;
+       pccb->cmd[3] = 0;
+       pccb->cmd[4] = 0;
+       pccb->cmd[5] = 0;
+       pccb->cmdlen = 6;
+       pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
+}
+
+/*
+ * (re)-scan the scsi bus and reports scsi device info
+ * to the user if mode = 1
+ */
+void scsi_scan(int mode)
+{
+       unsigned char i, perq, modi, lun;
+       lbaint_t capacity;
+       unsigned long blksz;
+       ccb *pccb = (ccb *)&tempccb;
+
+       if (mode == 1)
+               printf("scanning bus for devices...\n");
+       for (i = 0; i < CONFIG_SYS_SCSI_MAX_DEVICE; i++) {
+               scsi_dev_desc[i].target = 0xff;
+               scsi_dev_desc[i].lun = 0xff;
+               scsi_dev_desc[i].lba = 0;
+               scsi_dev_desc[i].blksz = 0;
+               scsi_dev_desc[i].log2blksz =
+                       LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
+               scsi_dev_desc[i].type = DEV_TYPE_UNKNOWN;
+               scsi_dev_desc[i].vendor[0] = 0;
+               scsi_dev_desc[i].product[0] = 0;
+               scsi_dev_desc[i].revision[0] = 0;
+               scsi_dev_desc[i].removable = false;
+               scsi_dev_desc[i].if_type = IF_TYPE_SCSI;
+               scsi_dev_desc[i].devnum = i;
+               scsi_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+#ifndef CONFIG_BLK
+               scsi_dev_desc[i].block_read = scsi_read;
+               scsi_dev_desc[i].block_write = scsi_write;
+#endif
+       }
+       scsi_max_devs = 0;
+       for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
+               pccb->target = i;
+               for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
+                       pccb->lun = lun;
+                       pccb->pdata = (unsigned char *)&tempbuff;
+                       pccb->datalen = 512;
+                       scsi_setup_inquiry(pccb);
+                       if (scsi_exec(pccb) != true) {
+                               if (pccb->contr_stat == SCSI_SEL_TIME_OUT) {
+                                       /*
+                                        * selection timeout => assuming no
+                                        * device present
+                                        */
+                                       debug("Selection timeout ID %d\n",
+                                             pccb->target);
+                                       continue;
+                               }
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       perq = tempbuff[0];
+                       modi = tempbuff[1];
+                       if ((perq & 0x1f) == 0x1f)
+                               continue; /* skip unknown devices */
+                       if ((modi & 0x80) == 0x80) /* drive is removable */
+                               scsi_dev_desc[scsi_max_devs].removable = true;
+                       /* get info for this device */
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
+                                               [scsi_max_devs].vendor[0],
+                                      &tempbuff[8], 8);
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
+                                               [scsi_max_devs].product[0],
+                                      &tempbuff[16], 16);
+                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
+                                               [scsi_max_devs].revision[0],
+                                      &tempbuff[32], 4);
+                       scsi_dev_desc[scsi_max_devs].target = pccb->target;
+                       scsi_dev_desc[scsi_max_devs].lun = pccb->lun;
+
+                       pccb->datalen = 0;
+                       scsi_setup_test_unit_ready(pccb);
+                       if (scsi_exec(pccb) != true) {
+                               if (scsi_dev_desc[scsi_max_devs].removable) {
+                                       scsi_dev_desc[scsi_max_devs].type =
+                                                       perq;
+                                       goto removable;
+                               }
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       if (scsi_read_capacity(pccb, &capacity, &blksz)) {
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       scsi_dev_desc[scsi_max_devs].lba = capacity;
+                       scsi_dev_desc[scsi_max_devs].blksz = blksz;
+                       scsi_dev_desc[scsi_max_devs].log2blksz =
+                               LOG2(scsi_dev_desc[scsi_max_devs].blksz);
+                       scsi_dev_desc[scsi_max_devs].type = perq;
+                       part_init(&scsi_dev_desc[scsi_max_devs]);
+removable:
+                       if (mode == 1) {
+                               printf("  Device %d: ", scsi_max_devs);
+                               dev_print(&scsi_dev_desc[scsi_max_devs]);
+                       } /* if mode */
+                       scsi_max_devs++;
+               } /* next LUN */
+       }
+       if (scsi_max_devs > 0)
+               scsi_curr_dev = 0;
+       else
+               scsi_curr_dev = -1;
+
+       printf("Found %d device(s).\n", scsi_max_devs);
+#ifndef CONFIG_SPL_BUILD
+       setenv_ulong("scsidevs", scsi_max_devs);
+#endif
+}
+
+#ifdef CONFIG_BLK
+static const struct blk_ops scsi_blk_ops = {
+       .read   = scsi_read,
+       .write  = scsi_write,
+};
+
+U_BOOT_DRIVER(scsi_blk) = {
+       .name           = "scsi_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &scsi_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(scsi) = {
+       .if_typename    = "sata",
+       .if_type        = IF_TYPE_SCSI,
+       .max_devs       = CONFIG_SYS_SCSI_MAX_DEVICE,
+       .desc           = scsi_dev_desc,
+};
+#endif
index 360c754050f2821c479056d8f32830461a957cfe..5676acdde3f282da8062d0c679c02116d590b969 100644 (file)
@@ -300,7 +300,7 @@ int spl_mmc_load_image(u32 boot_device)
                        if (part == 7)
                                part = 0;
 
-                       err = mmc_switch_part(0, part);
+                       err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
                        if (err) {
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
                                puts("spl: mmc partition switch failed\n");
index 1719946ec5f0d7fbc0a7e2ec2d753ed0b0a640a6..9d8cc7c2ddf7a75eb9da4c61f1ca38216277f153 100644 (file)
@@ -34,7 +34,7 @@ int spl_sata_load_image(void)
        } else {
                /* try to recognize storage devices immediately */
                scsi_scan(0);
-               stor_dev = scsi_get_dev(0);
+               stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0);
                if (!stor_dev)
                        return -ENODEV;
        }
index c42848e6fc84800bc2a5f49e3380af37b16a924f..04fa66758cbc0255da1fa97632dd655aeb1dd918 100644 (file)
@@ -39,7 +39,7 @@ int spl_usb_load_image(void)
 #ifdef CONFIG_USB_STORAGE
        /* try to recognize storage devices immediately */
        usb_stor_curr_dev = usb_stor_scan(1);
-       stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+       stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, usb_stor_curr_dev);
        if (!stor_dev)
                return -ENODEV;
 #endif
index 9285c95c0553b719016f6edf38ecc6c82f486c74..7e6e52d2ec37a2383935721332a31e2636317e98 100644 (file)
@@ -136,23 +136,6 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
 #endif
 void uhci_show_temp_int_td(void);
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *usb_stor_get_dev(int index)
-{
-#ifdef CONFIG_BLK
-       struct udevice *dev;
-       int ret;
-
-       ret = blk_get_device(IF_TYPE_USB, index, &dev);
-       if (ret)
-               return NULL;
-       return dev_get_uclass_platdata(dev);
-#else
-       return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
-#endif
-}
-#endif
-
 static void usb_show_progress(void)
 {
        debug(".");
@@ -217,7 +200,6 @@ static int usb_stor_probe_device(struct usb_device *udev)
 
 #ifdef CONFIG_BLK
        struct us_data *data;
-       char dev_name[30], *str;
        int ret;
 #else
        int start;
@@ -240,14 +222,12 @@ static int usb_stor_probe_device(struct usb_device *udev)
        for (lun = 0; lun <= max_lun; lun++) {
                struct blk_desc *blkdev;
                struct udevice *dev;
+               char str[10];
 
-               snprintf(dev_name, sizeof(dev_name), "%s.lun%d",
-                        udev->dev->name, lun);
-               str = strdup(dev_name);
-               if (!str)
-                       return -ENOMEM;
-               ret = blk_create_device(udev->dev, "usb_storage_blk", str,
-                               IF_TYPE_USB, usb_max_devs, 512, 0, &dev);
+               snprintf(str, sizeof(str), "lun%d", lun);
+               ret = blk_create_devicef(udev->dev, "usb_storage_blk", str,
+                                        IF_TYPE_USB, usb_max_devs, 512, 0,
+                                        &dev);
                if (ret) {
                        debug("Cannot bind driver\n");
                        return ret;
@@ -1555,4 +1535,11 @@ U_BOOT_DRIVER(usb_storage_blk) = {
        .id             = UCLASS_BLK,
        .ops            = &usb_storage_ops,
 };
+#else
+U_BOOT_LEGACY_BLK(usb) = {
+       .if_typename    = "usb",
+       .if_type        = IF_TYPE_USB,
+       .max_devs       = USB_MAX_STOR_DEV,
+       .desc           = usb_dev_desc,
+};
 #endif
index afdf4a3ba7159430cbd7b85391dbb2b0abc09521..aec2e538a19ff0f0ffb4eda211d98519cf9fb366 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_MMC=y
 CONFIG_PCI=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
 CONFIG_I8042_KEYB=y
@@ -97,6 +98,7 @@ CONFIG_PWRSEQ=y
 CONFIG_SPL_PWRSEQ=y
 CONFIG_RESET=y
 CONFIG_DM_MMC=y
+CONFIG_SANDBOX_MMC=y
 CONFIG_SPI_FLASH_SANDBOX=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_ATMEL=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
new file mode 100644 (file)
index 0000000..93167c2
--- /dev/null
@@ -0,0 +1,168 @@
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_PCI=y
+CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_I8042_KEYB=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_BOOTSTAGE_USER_COUNT=0x20
+CONFIG_BOOTSTAGE_FDT=y
+CONFIG_BOOTSTAGE_STASH=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x0
+CONFIG_BOOTSTAGE_STASH_SIZE=0x4096
+CONFIG_CONSOLE_RECORD=y
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_GREPENV=y
+CONFIG_LOOPW=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MX_CYCLIC=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_DEMO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_TFTPSRV=y
+CONFIG_CMD_RARP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SOUND=y
+CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_HOSTFILE=y
+CONFIG_NETCONSOLE=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_DEVRES=y
+CONFIG_DEBUG_DEVRES=y
+CONFIG_ADC=y
+CONFIG_ADC_SANDBOX=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_DEMO=y
+CONFIG_DM_DEMO_SIMPLE=y
+CONFIG_DM_DEMO_SHAPE=y
+CONFIG_PM8916_GPIO=y
+CONFIG_SANDBOX_GPIO=y
+CONFIG_DM_I2C_COMPAT=y
+CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_I2C_CROS_EC_LDO=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_SANDBOX=y
+CONFIG_I2C_MUX=y
+CONFIG_SPL_I2C_MUX=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=y
+CONFIG_CROS_EC_KEYB=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_CMD_CROS_EC=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_I2C=y
+CONFIG_CROS_EC_LPC=y
+CONFIG_CROS_EC_SANDBOX=y
+CONFIG_CROS_EC_SPI=y
+CONFIG_PWRSEQ=y
+CONFIG_SPL_PWRSEQ=y
+CONFIG_RESET=y
+CONFIG_DM_MMC=y
+CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_SANDBOX=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_ROCKCHIP_PINCTRL=y
+CONFIG_ROCKCHIP_3036_PINCTRL=y
+CONFIG_PINCTRL_SANDBOX=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_PMIC_PFUZE100=y
+CONFIG_DM_PMIC_MAX77686=y
+CONFIG_PMIC_PM8916=y
+CONFIG_PMIC_RK808=y
+CONFIG_PMIC_S2MPS11=y
+CONFIG_DM_PMIC_SANDBOX=y
+CONFIG_PMIC_S5M8767=y
+CONFIG_PMIC_TPS65090=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_DM_REGULATOR_PFUZE100=y
+CONFIG_DM_REGULATOR_MAX77686=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK808=y
+CONFIG_REGULATOR_S5M8767=y
+CONFIG_DM_REGULATOR_SANDBOX=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_RAM=y
+CONFIG_REMOTEPROC_SANDBOX=y
+CONFIG_DM_RTC=y
+CONFIG_SANDBOX_SERIAL=y
+CONFIG_SOUND=y
+CONFIG_SOUND_SANDBOX=y
+CONFIG_SANDBOX_SPI=y
+CONFIG_SPMI=y
+CONFIG_SPMI_SANDBOX=y
+CONFIG_TIMER=y
+CONFIG_TIMER_EARLY=y
+CONFIG_SANDBOX_TIMER=y
+CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EMUL=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_SYS_USB_EVENT_POLL=y
+CONFIG_DM_VIDEO=y
+CONFIG_CONSOLE_ROTATION=y
+CONFIG_CONSOLE_TRUETYPE=y
+CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
+CONFIG_VIDEO_SANDBOX_SDL=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
+CONFIG_LZ4=y
+CONFIG_ERRNO_STR=y
+CONFIG_UNIT_TEST=y
+CONFIG_UT_TIME=y
+CONFIG_UT_DM=y
+CONFIG_UT_ENV=y
index 543cab8103204e0bc8fcba57e8b1b0474b4fe1bd..6a1c02d9fada7410c953cd144c2ea6968fb3a200 100644 (file)
 #define PRINTF(fmt,args...)
 #endif
 
-const struct block_drvr block_drvr[] = {
-#if defined(CONFIG_CMD_IDE)
-       { .name = "ide", .get_dev = ide_get_dev, },
-#endif
-#if defined(CONFIG_CMD_SATA)
-       {.name = "sata", .get_dev = sata_get_dev, },
-#endif
-#if defined(CONFIG_CMD_SCSI)
-       { .name = "scsi", .get_dev = scsi_get_dev, },
-#endif
-#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
-       { .name = "usb", .get_dev = usb_stor_get_dev, },
-#endif
-#if defined(CONFIG_MMC)
-       {
-               .name = "mmc",
-               .get_dev = mmc_get_dev,
-               .select_hwpart = mmc_select_hwpart,
-       },
-#endif
-#if defined(CONFIG_SYSTEMACE)
-       { .name = "ace", .get_dev = systemace_get_dev, },
-#endif
-#if defined(CONFIG_SANDBOX)
-       { .name = "host", .get_dev = host_get_dev, },
-#endif
-       { },
-};
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef HAVE_BLOCK_DEVICE
@@ -71,45 +42,23 @@ static struct part_driver *part_driver_lookup_type(int part_type)
 
 static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
 {
-       const struct block_drvr *drvr = block_drvr;
-       struct blk_desc* (*reloc_get_dev)(int dev);
-       int (*select_hwpart)(int dev_num, int hwpart);
-       char *name;
+       struct blk_desc *dev_desc;
        int ret;
 
-       if (!ifname)
+       dev_desc = blk_get_devnum_by_typename(ifname, dev);
+       if (!dev_desc) {
+               debug("%s: No device for iface '%s', dev %d\n", __func__,
+                     ifname, dev);
                return NULL;
-
-       name = drvr->name;
-#ifdef CONFIG_NEEDS_MANUAL_RELOC
-       name += gd->reloc_off;
-#endif
-       while (drvr->name) {
-               name = drvr->name;
-               reloc_get_dev = drvr->get_dev;
-               select_hwpart = drvr->select_hwpart;
-#ifdef CONFIG_NEEDS_MANUAL_RELOC
-               name += gd->reloc_off;
-               reloc_get_dev += gd->reloc_off;
-               if (select_hwpart)
-                       select_hwpart += gd->reloc_off;
-#endif
-               if (strncmp(ifname, name, strlen(name)) == 0) {
-                       struct blk_desc *dev_desc = reloc_get_dev(dev);
-                       if (!dev_desc)
-                               return NULL;
-                       if (hwpart == 0 && !select_hwpart)
-                               return dev_desc;
-                       if (!select_hwpart)
-                               return NULL;
-                       ret = select_hwpart(dev_desc->devnum, hwpart);
-                       if (ret < 0)
-                               return NULL;
-                       return dev_desc;
-               }
-               drvr++;
        }
-       return NULL;
+       ret = blk_dselect_hwpart(dev_desc, hwpart);
+       if (ret) {
+               debug("%s: Failed to select h/w partition: err-%d\n", __func__,
+                     ret);
+               return NULL;
+       }
+
+       return dev_desc;
 }
 
 struct blk_desc *blk_get_dev(const char *ifname, int dev)
@@ -401,7 +350,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
        if (*ep) {
                printf("** Bad device specification %s %s **\n",
                       ifname, dev_str);
-               dev = -1;
+               dev = -EINVAL;
                goto cleanup;
        }
 
@@ -410,7 +359,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
                if (*ep) {
                        printf("** Bad HW partition specification %s %s **\n",
                            ifname, hwpart_str);
-                       dev = -1;
+                       dev = -EINVAL;
                        goto cleanup;
                }
        }
@@ -418,7 +367,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
        *dev_desc = get_dev_hwpart(ifname, dev, hwpart);
        if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
                printf("** Bad device %s %s **\n", ifname, dev_hwpart_str);
-               dev = -1;
+               dev = -ENOENT;
                goto cleanup;
        }
 
index 6900097e79986785d3d6f1e4691f9614780073ff..99dd07fc7698f4f463840f0050ed3c138d4dbd42 100644 (file)
@@ -36,6 +36,8 @@ 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_USB_HOST_SUPPORT) += block/
+obj-$(CONFIG_SPL_MMC_SUPPORT) += block/
 
 else
 
index fcc9ccdd7f85e159a8886ce258db80d54e7f3c44..80eea84dc29731c96a48a2fd8814cd511375806b 100644 (file)
@@ -9,10 +9,9 @@ config BLK
          be partitioned into several areas, called 'partitions' in U-Boot.
          A filesystem can be placed in each partition.
 
-config DISK
-       bool "Support disk controllers with driver model"
+config AHCI
+       bool "Support SATA controllers with driver model"
        depends on DM
-       default y if 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
index a43492f208207c915692a87206ea97b4ce8c24e8..436b79f9816562102d0b1becac7067a2d5fc329f 100644 (file)
@@ -7,7 +7,11 @@
 
 obj-$(CONFIG_BLK) += blk-uclass.o
 
-obj-$(CONFIG_DISK) += disk-uclass.o
+ifndef CONFIG_BLK
+obj-y += blk_legacy.o
+endif
+
+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
@@ -22,7 +26,7 @@ obj-$(CONFIG_SATA_MV) += sata_mv.o
 obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
 obj-$(CONFIG_SATA_SIL) += sata_sil.o
 obj-$(CONFIG_IDE_SIL680) += sil680.o
-obj-$(CONFIG_SANDBOX) += sandbox.o
+obj-$(CONFIG_SANDBOX) += sandbox.o sandbox_scsi.o sata_sandbox.o
 obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
 obj-$(CONFIG_SYSTEMACE) += systemace.o
 obj-$(CONFIG_BLOCK_CACHE) += blkcache.o
diff --git a/drivers/block/ahci-uclass.c b/drivers/block/ahci-uclass.c
new file mode 100644 (file)
index 0000000..7b8c326
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+
+UCLASS_DRIVER(ahci) = {
+       .id             = UCLASS_AHCI,
+       .name           = "ahci",
+};
index 617db226a2480e069286ab462a2c85e1c4473829..6ba1026f5818efc61f69182112a79fd60d75fa1a 100644 (file)
 #include <dm/device-internal.h>
 #include <dm/lists.h>
 
+static const char *if_typename_str[IF_TYPE_COUNT] = {
+       [IF_TYPE_IDE]           = "ide",
+       [IF_TYPE_SCSI]          = "scsi",
+       [IF_TYPE_ATAPI]         = "atapi",
+       [IF_TYPE_USB]           = "usb",
+       [IF_TYPE_DOC]           = "doc",
+       [IF_TYPE_MMC]           = "mmc",
+       [IF_TYPE_SD]            = "sd",
+       [IF_TYPE_SATA]          = "sata",
+       [IF_TYPE_HOST]          = "host",
+       [IF_TYPE_SYSTEMACE]     = "ace",
+};
+
+static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
+       [IF_TYPE_IDE]           = UCLASS_INVALID,
+       [IF_TYPE_SCSI]          = UCLASS_INVALID,
+       [IF_TYPE_ATAPI]         = UCLASS_INVALID,
+       [IF_TYPE_USB]           = UCLASS_MASS_STORAGE,
+       [IF_TYPE_DOC]           = UCLASS_INVALID,
+       [IF_TYPE_MMC]           = UCLASS_MMC,
+       [IF_TYPE_SD]            = UCLASS_INVALID,
+       [IF_TYPE_SATA]          = UCLASS_AHCI,
+       [IF_TYPE_HOST]          = UCLASS_ROOT,
+       [IF_TYPE_SYSTEMACE]     = UCLASS_INVALID,
+};
+
+static enum if_type if_typename_to_iftype(const char *if_typename)
+{
+       int i;
+
+       for (i = 0; i < IF_TYPE_COUNT; i++) {
+               if (if_typename_str[i] &&
+                   !strcmp(if_typename, if_typename_str[i]))
+                       return i;
+       }
+
+       return IF_TYPE_UNKNOWN;
+}
+
+static enum uclass_id if_type_to_uclass_id(enum if_type if_type)
+{
+       return if_type_uclass_id[if_type];
+}
+
+struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       struct udevice *dev;
+       int ret;
+
+       ret = blk_get_device(if_type, devnum, &dev);
+       if (ret)
+               return NULL;
+       desc = dev_get_uclass_platdata(dev);
+
+       return desc;
+}
+
+/*
+ * This function is complicated with driver model. We look up the interface
+ * name in a local table. This gives us an interface type which we can match
+ * against the uclass of the block device's parent.
+ */
+struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
+{
+       enum uclass_id uclass_id;
+       enum if_type if_type;
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       if_type = if_typename_to_iftype(if_typename);
+       if (if_type == IF_TYPE_UNKNOWN) {
+               debug("%s: Unknown interface type '%s'\n", __func__,
+                     if_typename);
+               return NULL;
+       }
+       uclass_id = if_type_to_uclass_id(if_type);
+       if (uclass_id == UCLASS_INVALID) {
+               debug("%s: Unknown uclass for interface type'\n",
+                     if_typename_str[if_type]);
+               return NULL;
+       }
+
+       ret = uclass_get(UCLASS_BLK, &uc);
+       if (ret)
+               return NULL;
+       uclass_foreach_dev(dev, uc) {
+               struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+               debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
+                     if_type, devnum, dev->name, desc->if_type, desc->devnum);
+               if (desc->devnum != devnum)
+                       continue;
+
+               /* Find out the parent device uclass */
+               if (device_get_uclass_id(dev->parent) != uclass_id) {
+                       debug("%s: parent uclass %d, this dev %d\n", __func__,
+                             device_get_uclass_id(dev->parent), uclass_id);
+                       continue;
+               }
+
+               if (device_probe(dev))
+                       return NULL;
+
+               debug("%s: Device desc %p\n", __func__, desc);
+               return desc;
+       }
+       debug("%s: No device found\n", __func__);
+
+       return NULL;
+}
+
+/**
+ * get_desc() - Get the block device descriptor for the given device number
+ *
+ * @if_type:   Interface type
+ * @devnum:    Device number (0 = first)
+ * @descp:     Returns block device descriptor on success
+ * @return 0 on success, -ENODEV if there is no such device and no device
+ * with a higher device number, -ENOENT if there is no such device but there
+ * is one with a higher number, or other -ve on other error.
+ */
+static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
+{
+       bool found_more = false;
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       *descp = NULL;
+       ret = uclass_get(UCLASS_BLK, &uc);
+       if (ret)
+               return ret;
+       uclass_foreach_dev(dev, uc) {
+               struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+               debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
+                     if_type, devnum, dev->name, desc->if_type, desc->devnum);
+               if (desc->if_type == if_type) {
+                       if (desc->devnum == devnum) {
+                               ret = device_probe(dev);
+                               if (ret)
+                                       return ret;
+
+                       } else if (desc->devnum > devnum) {
+                               found_more = true;
+                       }
+               }
+       }
+
+       return found_more ? -ENOENT : -ENODEV;
+}
+
+int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = blk_get_device(if_type, devnum, &dev);
+       if (ret)
+               return ret;
+
+       return blk_select_hwpart(dev, hwpart);
+}
+
+int blk_list_part(enum if_type if_type)
+{
+       struct blk_desc *desc;
+       int devnum, ok;
+       int ret;
+
+       for (ok = 0, devnum = 0;; ++devnum) {
+               ret = get_desc(if_type, devnum, &desc);
+               if (ret == -ENODEV)
+                       break;
+               else if (ret)
+                       continue;
+               if (desc->part_type != PART_TYPE_UNKNOWN) {
+                       ++ok;
+                       if (devnum)
+                               putc('\n');
+                       part_print(desc);
+               }
+       }
+       if (!ok)
+               return -ENODEV;
+
+       return 0;
+}
+
+int blk_print_part_devnum(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+       part_print(desc);
+
+       return 0;
+}
+
+void blk_list_devices(enum if_type if_type)
+{
+       struct blk_desc *desc;
+       int ret;
+       int i;
+
+       for (i = 0;; ++i) {
+               ret = get_desc(if_type, i, &desc);
+               if (ret == -ENODEV)
+                       break;
+               else if (ret)
+                       continue;
+               if (desc->type == DEV_TYPE_UNKNOWN)
+                       continue;  /* list only known devices */
+               printf("Device %d: ", i);
+               dev_print(desc);
+       }
+}
+
+int blk_print_device_num(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       printf("\nIDE device %d: ", devnum);
+       dev_print(desc);
+
+       return 0;
+}
+
+int blk_show_device(enum if_type if_type, int devnum)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       printf("\nDevice %d: ", devnum);
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret == -ENODEV || ret == -ENOENT) {
+               printf("unknown device\n");
+               return -ENODEV;
+       }
+       if (ret)
+               return ret;
+       dev_print(desc);
+
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+
+       return 0;
+}
+
+ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                     lbaint_t blkcnt, void *buffer)
+{
+       struct blk_desc *desc;
+       ulong n;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       n = blk_dread(desc, start, blkcnt, buffer);
+       if (IS_ERR_VALUE(n))
+               return n;
+
+       /* flush cache after read */
+       flush_cache((ulong)buffer, blkcnt * desc->blksz);
+
+       return n;
+}
+
+ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                      lbaint_t blkcnt, const void *buffer)
+{
+       struct blk_desc *desc;
+       int ret;
+
+       ret = get_desc(if_type, devnum, &desc);
+       if (ret)
+               return ret;
+       return blk_dwrite(desc, start, blkcnt, buffer);
+}
+
+int blk_select_hwpart(struct udevice *dev, int hwpart)
+{
+       const struct blk_ops *ops = blk_get_ops(dev);
+
+       if (!ops)
+               return -ENOSYS;
+       if (!ops->select_hwpart)
+               return 0;
+
+       return ops->select_hwpart(dev, hwpart);
+}
+
+int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
+{
+       return blk_select_hwpart(desc->bdev, hwpart);
+}
+
 int blk_first_device(int if_type, struct udevice **devp)
 {
        struct blk_desc *desc;
@@ -131,6 +440,26 @@ int blk_prepare_device(struct udevice *dev)
        return 0;
 }
 
+int blk_find_max_devnum(enum if_type if_type)
+{
+       struct udevice *dev;
+       int max_devnum = -ENODEV;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(UCLASS_BLK, &uc);
+       if (ret)
+               return ret;
+       uclass_foreach_dev(dev, uc) {
+               struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+               if (desc->if_type == if_type && desc->devnum > max_devnum)
+                       max_devnum = desc->devnum;
+       }
+
+       return max_devnum;
+}
+
 int blk_create_device(struct udevice *parent, const char *drv_name,
                      const char *name, int if_type, int devnum, int blksz,
                      lbaint_t size, struct udevice **devp)
@@ -139,6 +468,15 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
        struct udevice *dev;
        int ret;
 
+       if (devnum == -1) {
+               ret = blk_find_max_devnum(if_type);
+               if (ret == -ENODEV)
+                       devnum = 0;
+               else if (ret < 0)
+                       return ret;
+               else
+                       devnum = ret + 1;
+       }
        ret = device_bind_driver(parent, drv_name, name, &dev);
        if (ret)
                return ret;
@@ -154,6 +492,29 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
        return 0;
 }
 
+int blk_create_devicef(struct udevice *parent, const char *drv_name,
+                      const char *name, int if_type, int devnum, int blksz,
+                      lbaint_t size, struct udevice **devp)
+{
+       char dev_name[30], *str;
+       int ret;
+
+       snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
+       str = strdup(dev_name);
+       if (!str)
+               return -ENOMEM;
+
+       ret = blk_create_device(parent, drv_name, str, if_type, devnum,
+                               blksz, size, devp);
+       if (ret) {
+               free(str);
+               return ret;
+       }
+       device_set_name_alloced(*devp);
+
+       return ret;
+}
+
 int blk_unbind_all(int if_type)
 {
        struct uclass *uc;
diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c
new file mode 100644 (file)
index 0000000..7b90a8a
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/err.h>
+
+struct blk_driver *blk_driver_lookup_type(int if_type)
+{
+       struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
+       const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
+       struct blk_driver *entry;
+
+       for (entry = drv; entry != drv + n_ents; entry++) {
+               if (if_type == entry->if_type)
+                       return entry;
+       }
+
+       /* Not found */
+       return NULL;
+}
+
+static struct blk_driver *blk_driver_lookup_typename(const char *if_typename)
+{
+       struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
+       const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
+       struct blk_driver *entry;
+
+       for (entry = drv; entry != drv + n_ents; entry++) {
+               if (!strcmp(if_typename, entry->if_typename))
+                       return entry;
+       }
+
+       /* Not found */
+       return NULL;
+}
+
+/**
+ * get_desc() - Get the block device descriptor for the given device number
+ *
+ * @drv:       Legacy block driver
+ * @devnum:    Device number (0 = first)
+ * @descp:     Returns block device descriptor on success
+ * @return 0 on success, -ENODEV if there is no such device, -ENOSYS if the
+ * driver does not provide a way to find a device, or other -ve on other
+ * error.
+ */
+static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp)
+{
+       if (drv->desc) {
+               if (devnum < 0 || devnum >= drv->max_devs)
+                       return -ENODEV;
+               *descp = &drv->desc[devnum];
+               return 0;
+       }
+       if (!drv->get_dev)
+               return -ENOSYS;
+
+       return drv->get_dev(devnum, descp);
+}
+
+#ifdef HAVE_BLOCK_DEVICE
+int blk_list_part(enum if_type if_type)
+{
+       struct blk_driver *drv;
+       struct blk_desc *desc;
+       int devnum, ok;
+       bool first = true;
+
+       drv = blk_driver_lookup_type(if_type);
+       if (!drv)
+               return -ENOSYS;
+       for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) {
+               if (get_desc(drv, devnum, &desc))
+                       continue;
+               if (desc->part_type != PART_TYPE_UNKNOWN) {
+                       ++ok;
+                       if (!first)
+                               putc('\n');
+                       part_print(desc);
+                       first = false;
+               }
+       }
+       if (!ok)
+               return -ENODEV;
+
+       return 0;
+}
+
+int blk_print_part_devnum(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+       part_print(desc);
+
+       return 0;
+}
+
+void blk_list_devices(enum if_type if_type)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int i;
+
+       if (!drv)
+               return;
+       for (i = 0; i < drv->max_devs; ++i) {
+               if (get_desc(drv, i, &desc))
+                       continue;
+               if (desc->type == DEV_TYPE_UNKNOWN)
+                       continue;  /* list only known devices */
+               printf("Device %d: ", i);
+               dev_print(desc);
+       }
+}
+
+int blk_print_device_num(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       printf("\n%s device %d: ", drv->if_typename, devnum);
+       dev_print(desc);
+
+       return 0;
+}
+
+int blk_show_device(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       printf("\nDevice %d: ", devnum);
+       if (devnum >= drv->max_devs) {
+               puts("unknown device\n");
+               return -ENODEV;
+       }
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       dev_print(desc);
+
+       if (desc->type == DEV_TYPE_UNKNOWN)
+               return -ENOENT;
+
+       return 0;
+}
+#endif /* HAVE_BLOCK_DEVICE */
+
+struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+
+       if (!drv)
+               return NULL;
+
+       if (get_desc(drv, devnum, &desc))
+               return NULL;
+
+       return desc;
+}
+
+int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(desc->if_type);
+
+       if (!drv)
+               return -ENOSYS;
+       if (drv->select_hwpart)
+               return drv->select_hwpart(desc, hwpart);
+
+       return 0;
+}
+
+struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
+{
+       struct blk_driver *drv = blk_driver_lookup_typename(if_typename);
+       struct blk_desc *desc;
+
+       if (!drv)
+               return NULL;
+
+       if (get_desc(drv, devnum, &desc))
+               return NULL;
+
+       return desc;
+}
+
+ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                     lbaint_t blkcnt, void *buffer)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       ulong n;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       n = desc->block_read(desc, start, blkcnt, buffer);
+       if (IS_ERR_VALUE(n))
+               return n;
+
+       /* flush cache after read */
+       flush_cache((ulong)buffer, blkcnt * desc->blksz);
+
+       return n;
+}
+
+ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                      lbaint_t blkcnt, const void *buffer)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       return desc->block_write(desc, start, blkcnt, buffer);
+}
+
+int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
+{
+       struct blk_driver *drv = blk_driver_lookup_type(if_type);
+       struct blk_desc *desc;
+       int ret;
+
+       if (!drv)
+               return -ENOSYS;
+       ret = get_desc(drv, devnum, &desc);
+       if (ret)
+               return ret;
+       return drv->select_hwpart(desc, hwpart);
+}
diff --git a/drivers/block/disk-uclass.c b/drivers/block/disk-uclass.c
deleted file mode 100644 (file)
index d665b35..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-
-UCLASS_DRIVER(disk) = {
-       .id             = UCLASS_DISK,
-       .name           = "disk",
-};
index 2d340efd32b520492cc2ccfd20be140d8babd9a2..ac28f834724490b23670ac3a3361310f53ee5c0a 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_BLK
+static struct host_block_dev host_devices[CONFIG_HOST_MAX_DEVICES];
+
+static struct host_block_dev *find_host_device(int dev)
+{
+       if (dev >= 0 && dev < CONFIG_HOST_MAX_DEVICES)
+               return &host_devices[dev];
+
+       return NULL;
+}
+#endif
+
+#ifdef CONFIG_BLK
 static unsigned long host_block_read(struct udevice *dev,
                                     unsigned long start, lbaint_t blkcnt,
                                     void *buffer)
@@ -24,6 +37,18 @@ static unsigned long host_block_read(struct udevice *dev,
        struct host_block_dev *host_dev = dev_get_priv(dev);
        struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
 
+#else
+static unsigned long host_block_read(struct blk_desc *block_dev,
+                                    unsigned long start, lbaint_t blkcnt,
+                                    void *buffer)
+{
+       int dev = block_dev->devnum;
+       struct host_block_dev *host_dev = find_host_device(dev);
+
+       if (!host_dev)
+               return -1;
+#endif
+
        if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
                        -1) {
                printf("ERROR: Invalid block %lx\n", start);
@@ -35,12 +60,21 @@ static unsigned long host_block_read(struct udevice *dev,
        return -1;
 }
 
+#ifdef CONFIG_BLK
 static unsigned long host_block_write(struct udevice *dev,
                                      unsigned long start, lbaint_t blkcnt,
                                      const void *buffer)
 {
        struct host_block_dev *host_dev = dev_get_priv(dev);
        struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#else
+static unsigned long host_block_write(struct blk_desc *block_dev,
+                                     unsigned long start, lbaint_t blkcnt,
+                                     const void *buffer)
+{
+       int dev = block_dev->devnum;
+       struct host_block_dev *host_dev = find_host_device(dev);
+#endif
 
        if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
                        -1) {
@@ -53,6 +87,7 @@ static unsigned long host_block_write(struct udevice *dev,
        return -1;
 }
 
+#ifdef CONFIG_BLK
 int host_dev_bind(int devnum, char *filename)
 {
        struct host_block_dev *host_dev;
@@ -115,9 +150,51 @@ err:
        free(str);
        return ret;
 }
+#else
+int host_dev_bind(int dev, char *filename)
+{
+       struct host_block_dev *host_dev = find_host_device(dev);
+
+       if (!host_dev)
+               return -1;
+       if (host_dev->blk_dev.priv) {
+               os_close(host_dev->fd);
+               host_dev->blk_dev.priv = NULL;
+       }
+       if (host_dev->filename)
+               free(host_dev->filename);
+       if (filename && *filename) {
+               host_dev->filename = strdup(filename);
+       } else {
+               host_dev->filename = NULL;
+               return 0;
+       }
+
+       host_dev->fd = os_open(host_dev->filename, OS_O_RDWR);
+       if (host_dev->fd == -1) {
+               printf("Failed to access host backing file '%s'\n",
+                      host_dev->filename);
+               return 1;
+       }
+
+       struct blk_desc *blk_dev = &host_dev->blk_dev;
+       blk_dev->if_type = IF_TYPE_HOST;
+       blk_dev->priv = host_dev;
+       blk_dev->blksz = 512;
+       blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz;
+       blk_dev->block_read = host_block_read;
+       blk_dev->block_write = host_block_write;
+       blk_dev->devnum = dev;
+       blk_dev->part_type = PART_TYPE_UNKNOWN;
+       part_init(blk_dev);
+
+       return 0;
+}
+#endif
 
 int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
 {
+#ifdef CONFIG_BLK
        struct udevice *dev;
        int ret;
 
@@ -125,20 +202,22 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
        if (ret)
                return ret;
        *blk_devp = dev_get_uclass_platdata(dev);
+#else
+       struct host_block_dev *host_dev = find_host_device(devnum);
 
-       return 0;
-}
+       if (!host_dev)
+               return -ENODEV;
 
-struct blk_desc *host_get_dev(int dev)
-{
-       struct blk_desc *blk_dev;
+       if (!host_dev->blk_dev.priv)
+               return -ENOENT;
 
-       if (host_get_dev_err(dev, &blk_dev))
-               return NULL;
+       *blk_devp = &host_dev->blk_dev;
+#endif
 
-       return blk_dev;
+       return 0;
 }
 
+#ifdef CONFIG_BLK
 static const struct blk_ops sandbox_host_blk_ops = {
        .read   = host_block_read,
        .write  = host_block_write,
@@ -150,3 +229,11 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
        .ops            = &sandbox_host_blk_ops,
        .priv_auto_alloc_size   = sizeof(struct host_block_dev),
 };
+#else
+U_BOOT_LEGACY_BLK(sandbox_host) = {
+       .if_typename    = "host",
+       .if_type        = IF_TYPE_HOST,
+       .max_devs       = CONFIG_HOST_MAX_DEVICES,
+       .get_dev        = host_get_dev_err,
+};
+#endif
diff --git a/drivers/block/sandbox_scsi.c b/drivers/block/sandbox_scsi.c
new file mode 100644 (file)
index 0000000..ad961bd
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * This file contains dummy implementations of SCSI functions requried so
+ * that CONFIG_SCSI can be enabled for sandbox.
+ */
+
+#include <common.h>
+#include <scsi.h>
+
+void scsi_bus_reset(void)
+{
+}
+
+void scsi_init(void)
+{
+}
+
+int scsi_exec(ccb *pccb)
+{
+       return 0;
+}
+
+void scsi_print_error(ccb *pccb)
+{
+}
diff --git a/drivers/block/sata_sandbox.c b/drivers/block/sata_sandbox.c
new file mode 100644 (file)
index 0000000..bd967d2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+
+int init_sata(int dev)
+{
+       return 0;
+}
+
+int reset_sata(int dev)
+{
+       return 0;
+}
+
+int scan_sata(int dev)
+{
+       return 0;
+}
+
+ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
+{
+       return 0;
+}
+
+ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
+{
+       return 0;
+}
index c7c40affaed11a7cde06994238f40e3721344f3f..5daede7279837b49eec2f57c88b3e4d1ba741c73 100644 (file)
@@ -33,7 +33,7 @@
 #define PRINTF(fmt,args...)
 #endif
 
-#if defined(CONFIG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
+#if defined(CONFIG_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
 
 #undef SCSI_SINGLE_STEP
 /*
index 09fe834e2270ef8c765e12d111d91b31ad11ab83..9392beaf052eb419ffb9f106018fd0746032c80d 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <common.h>
 #include <command.h>
-#include <systemace.h>
+#include <dm.h>
 #include <part.h>
 #include <asm/io.h>
 
@@ -69,11 +69,9 @@ static u16 ace_readw(unsigned off)
        return in16(base + off);
 }
 
-static unsigned long systemace_read(struct blk_desc *block_dev,
-                                   unsigned long start, lbaint_t blkcnt,
-                                   void *buffer);
-
+#ifndef CONFIG_BLK
 static struct blk_desc systemace_dev = { 0 };
+#endif
 
 static int get_cf_lock(void)
 {
@@ -104,42 +102,19 @@ static void release_cf_lock(void)
        ace_writew((val & 0xffff), 0x18);
 }
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *systemace_get_dev(int dev)
-{
-       /* The first time through this, the systemace_dev object is
-          not yet initialized. In that case, fill it in. */
-       if (systemace_dev.blksz == 0) {
-               systemace_dev.if_type = IF_TYPE_UNKNOWN;
-               systemace_dev.devnum = 0;
-               systemace_dev.part_type = PART_TYPE_UNKNOWN;
-               systemace_dev.type = DEV_TYPE_HARDDISK;
-               systemace_dev.blksz = 512;
-               systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
-               systemace_dev.removable = 1;
-               systemace_dev.block_read = systemace_read;
-
-               /*
-                * Ensure the correct bus mode (8/16 bits) gets enabled
-                */
-               ace_writew(width == 8 ? 0 : 0x0001, 0);
-
-               part_init(&systemace_dev);
-
-       }
-
-       return &systemace_dev;
-}
-#endif
-
 /*
  * This function is called (by dereferencing the block_read pointer in
  * the dev_desc) to read blocks of data. The return value is the
  * number of blocks read. A zero return indicates an error.
  */
+#ifdef CONFIG_BLK
+static unsigned long systemace_read(struct udevice *dev, unsigned long start,
+                                   lbaint_t blkcnt, void *buffer)
+#else
 static unsigned long systemace_read(struct blk_desc *block_dev,
                                    unsigned long start, lbaint_t blkcnt,
                                    void *buffer)
+#endif
 {
        int retry;
        unsigned blk_countdown;
@@ -257,3 +232,72 @@ static unsigned long systemace_read(struct blk_desc *block_dev,
 
        return blkcnt;
 }
+
+#ifdef CONFIG_BLK
+static int systemace_bind(struct udevice *dev)
+{
+       struct blk_desc *bdesc;
+       struct udevice *bdev;
+       int ret;
+
+       ret = blk_create_devicef(dev, "systemace_blk", "blk", IF_TYPE_SYSTEMACE,
+                                -1, 512, 0, &bdev);
+       if (ret) {
+               debug("Cannot create block device\n");
+               return ret;
+       }
+       bdesc = dev_get_uclass_platdata(bdev);
+       bdesc->removable = 1;
+       bdesc->part_type = PART_TYPE_UNKNOWN;
+       bdesc->log2blksz = LOG2(bdesc->blksz);
+
+       /* Ensure the correct bus mode (8/16 bits) gets enabled */
+       ace_writew(width == 8 ? 0 : 0x0001, 0);
+
+       return 0;
+}
+
+static const struct blk_ops systemace_blk_ops = {
+       .read   = systemace_read,
+};
+
+U_BOOT_DRIVER(systemace_blk) = {
+       .name           = "systemace_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &systemace_blk_ops,
+       .bind           = systemace_bind,
+};
+#else
+static int systemace_get_dev(int dev, struct blk_desc **descp)
+{
+       /* The first time through this, the systemace_dev object is
+          not yet initialized. In that case, fill it in. */
+       if (systemace_dev.blksz == 0) {
+               systemace_dev.if_type = IF_TYPE_UNKNOWN;
+               systemace_dev.devnum = 0;
+               systemace_dev.part_type = PART_TYPE_UNKNOWN;
+               systemace_dev.type = DEV_TYPE_HARDDISK;
+               systemace_dev.blksz = 512;
+               systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
+               systemace_dev.removable = 1;
+               systemace_dev.block_read = systemace_read;
+
+               /*
+                * Ensure the correct bus mode (8/16 bits) gets enabled
+                */
+               ace_writew(width == 8 ? 0 : 0x0001, 0);
+
+               part_init(&systemace_dev);
+       }
+       *descp = &systemace_dev;
+
+       return 0;
+}
+
+U_BOOT_LEGACY_BLK(systemace) = {
+       .if_typename    = "ace",
+       .if_type        = IF_TYPE_SYSTEMACE,
+       .max_devs       = 1,
+       .get_dev        = systemace_get_dev,
+};
+#endif
index e1714b2202b64145291eabd024206e261d57e0f3..0e56b23fbbf44b059b6e38afd1c8366ee245e764 100644 (file)
@@ -112,6 +112,8 @@ int device_unbind(struct udevice *dev)
 
        devres_release_all(dev);
 
+       if (dev->flags & DM_NAME_ALLOCED)
+               free((char *)dev->name);
        free(dev);
 
        return 0;
index 1322991d6c7b6e0599679518543da7c5cdb7c5ad..5c2dc7021fb1623347e2dfb7f27a14aa76254a1e 100644 (file)
@@ -657,8 +657,8 @@ fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
        int index;
 
-       index = fdt_find_string(gd->fdt_blob, dev->parent->of_offset,
-                               "reg-names", name);
+       index = fdt_find_string(gd->fdt_blob, dev->of_offset, "reg-names",
+                               name);
        if (index < 0)
                return index;
 
@@ -706,12 +706,18 @@ bool device_is_last_sibling(struct udevice *dev)
        return list_is_last(&dev->sibling_node, &parent->child_head);
 }
 
+void device_set_name_alloced(struct udevice *dev)
+{
+       dev->flags |= DM_NAME_ALLOCED;
+}
+
 int device_set_name(struct udevice *dev, const char *name)
 {
        name = strdup(name);
        if (!name)
                return -ENOMEM;
        dev->name = name;
+       device_set_name_alloced(dev);
 
        return 0;
 }
index c4fc216340d8169dde8c05cdc0f9556e7ed9815b..a72db13a119aa4241c2f5dfa42ffd9551f1e15b2 100644 (file)
@@ -171,6 +171,10 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
 
                dm_dbg("   - found match at '%s'\n", entry->name);
                ret = device_bind(parent, entry, name, NULL, offset, &dev);
+               if (ret == -ENODEV) {
+                       dm_dbg("Driver '%s' refuses to bind\n", entry->name);
+                       continue;
+               }
                if (ret) {
                        dm_warn("Error binding driver '%s': %d\n", entry->name,
                                ret);
index faece8883ac0a5bcf6b11a67d3425260d1b6a1b1..78724e467b24c7f816fef09767022bd8876b42a8 100644 (file)
@@ -50,8 +50,9 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
 
        if (dfu->data.mmc.hw_partition >= 0) {
                part_num_bkp = mmc->block_dev.hwpart;
-               ret = mmc_select_hwpart(dfu->data.mmc.dev_num,
-                                       dfu->data.mmc.hw_partition);
+               ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                              dfu->data.mmc.dev_num,
+                                              dfu->data.mmc.hw_partition);
                if (ret)
                        return ret;
        }
@@ -75,12 +76,16 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
        if (n != blk_count) {
                error("MMC operation failed");
                if (dfu->data.mmc.hw_partition >= 0)
-                       mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
+                       blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                                dfu->data.mmc.dev_num,
+                                                part_num_bkp);
                return -EIO;
        }
 
        if (dfu->data.mmc.hw_partition >= 0) {
-               ret = mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
+               ret = blk_select_hwpart_devnum(IF_TYPE_MMC,
+                                              dfu->data.mmc.dev_num,
+                                              part_num_bkp);
                if (ret)
                        return ret;
        }
diff --git a/drivers/gpio/74x164_gpio.c b/drivers/gpio/74x164_gpio.c
new file mode 100644 (file)
index 0000000..9ac10a7
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Take drivers/gpio/gpio-74x164.c as reference.
+ *
+ * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver
+ *
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <spi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * struct gen_74x164_chip - Data for 74Hx164
+ *
+ * @oe: OE pin
+ * @nregs: number of registers
+ * @buffer: buffer for chained chips
+ */
+#define GEN_74X164_NUMBER_GPIOS 8
+
+struct gen_74x164_priv {
+       struct gpio_desc oe;
+       u32 nregs;
+       /*
+        * Since the nregs are chained, every byte sent will make
+        * the previous byte shift to the next register in the
+        * chain. Thus, the first byte sent will end up in the last
+        * register at the end of the transfer. So, to have a logical
+        * numbering, store the bytes in reverse order.
+        */
+       u8 *buffer;
+};
+
+static int gen_74x164_write_conf(struct udevice *dev)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = dm_spi_claim_bus(dev);
+       if (ret)
+               return ret;
+
+       ret = dm_spi_xfer(dev, priv->nregs * 8, priv->buffer, NULL,
+                         SPI_XFER_BEGIN | SPI_XFER_END);
+
+       dm_spi_release_bus(dev);
+
+       return ret;
+}
+
+static int gen_74x164_get_value(struct udevice *dev, unsigned offset)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       uint bank = priv->nregs - 1 - offset / 8;
+       uint pin = offset % 8;
+
+       return (priv->buffer[bank] >> pin) & 0x1;
+}
+
+static int gen_74x164_set_value(struct udevice *dev, unsigned offset,
+                               int value)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       uint bank = priv->nregs - 1 - offset / 8;
+       uint pin = offset % 8;
+       int ret;
+
+       if (value)
+               priv->buffer[bank] |= 1 << pin;
+       else
+               priv->buffer[bank] &= ~(1 << pin);
+
+       ret = gen_74x164_write_conf(dev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int gen_74x164_direction_input(struct udevice *dev, unsigned offset)
+{
+       return -ENOSYS;
+}
+
+static int gen_74x164_direction_output(struct udevice *dev, unsigned offset,
+                                     int value)
+{
+       return gen_74x164_set_value(dev, offset, value);
+}
+
+static int gen_74x164_get_function(struct udevice *dev, unsigned offset)
+{
+       return GPIOF_OUTPUT;
+}
+
+static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc,
+                           struct fdtdec_phandle_args *args)
+{
+       desc->offset = args->args[0];
+       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+       return 0;
+}
+
+static const struct dm_gpio_ops gen_74x164_ops = {
+       .direction_input        = gen_74x164_direction_input,
+       .direction_output       = gen_74x164_direction_output,
+       .get_value              = gen_74x164_get_value,
+       .set_value              = gen_74x164_set_value,
+       .get_function           = gen_74x164_get_function,
+       .xlate                  = gen_74x164_xlate,
+};
+
+static int gen_74x164_probe(struct udevice *dev)
+{
+       struct gen_74x164_priv *priv = dev_get_priv(dev);
+       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       char *str, name[32];
+       int ret;
+       const void *fdt = gd->fdt_blob;
+       int node = dev->of_offset;
+
+       snprintf(name, sizeof(name), "%s_", dev->name);
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+
+       /*
+        * See Linux kernel:
+        * Documentation/devicetree/bindings/gpio/gpio-74x164.txt
+        */
+       priv->nregs = fdtdec_get_int(fdt, node, "registers-number", 1);
+       priv->buffer = calloc(priv->nregs, sizeof(u8));
+       if (!priv->buffer) {
+               ret = -ENOMEM;
+               goto free_str;
+       }
+
+       ret = fdtdec_get_byte_array(fdt, node, "registers-default",
+                                   priv->buffer, priv->nregs);
+       if (ret)
+               dev_dbg(dev, "No registers-default property\n");
+
+       ret = gpio_request_by_name(dev, "oe-gpios", 0, &priv->oe,
+                                  GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+       if (ret) {
+               dev_err(dev, "No oe-pins property\n");
+               goto free_buf;
+       }
+
+       uc_priv->bank_name = str;
+       uc_priv->gpio_count = priv->nregs * 8;
+
+       ret = gen_74x164_write_conf(dev);
+       if (ret)
+               goto free_buf;
+
+       dev_dbg(dev, "%s is ready\n", dev->name);
+
+       return 0;
+
+free_buf:
+       free(priv->buffer);
+free_str:
+       free(str);
+       return ret;
+}
+
+static const struct udevice_id gen_74x164_ids[] = {
+       { .compatible = "fairchild,74hc595" },
+       { }
+};
+
+U_BOOT_DRIVER(74x164) = {
+       .name           = "74x164",
+       .id             = UCLASS_GPIO,
+       .ops            = &gen_74x164_ops,
+       .probe          = gen_74x164_probe,
+       .priv_auto_alloc_size = sizeof(struct gen_74x164_priv),
+       .of_match       = gen_74x164_ids,
+};
index 2b4624d7f8075c166916e9edb0784d630e97886c..93a7e8c6c23088772d5a3848664cd0eb54a38d40 100644 (file)
@@ -143,4 +143,34 @@ config ZYNQ_GPIO
        help
          Supports GPIO access on Zynq SoC.
 
+config DM_74X164
+       bool "74x164 serial-in/parallel-out 8-bits shift register"
+       depends on DM_GPIO
+       help
+         Driver for 74x164 compatible serial-in/parallel-out 8-outputs
+         shift registers, such as 74lv165, 74hc595.
+         This driver can be used to provide access to more gpio outputs.
+
+config DM_PCA953X
+       bool "PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports"
+       depends on DM_GPIO
+       help
+         Say yes here to provide access to several register-oriented
+         SMBus I/O expanders, made mostly by NXP or TI.  Compatible
+         models include:
+
+         4 bits:       pca9536, pca9537
+
+         8 bits:       max7310, max7315, pca6107, pca9534, pca9538, pca9554,
+                       pca9556, pca9557, pca9574, tca6408, xra1202
+
+         16 bits:      max7312, max7313, pca9535, pca9539, pca9555, pca9575,
+                       tca6416
+
+         24 bits:      tca6424
+
+         40 bits:      pca9505, pca9698
+
+         Now, max 24 bits chips and PCA953X compatible chips are
+         supported
 endmenu
index 4f071c451727e1f24862c8e0936a20e71a48eb23..ddec1ef8dee8ac4db1374c7e665847b8dba1901b 100644 (file)
@@ -11,6 +11,9 @@ obj-$(CONFIG_AXP_GPIO)                += axp_gpio.o
 endif
 obj-$(CONFIG_DM_GPIO)          += gpio-uclass.o
 
+obj-$(CONFIG_DM_PCA953X)       += pca953x_gpio.o
+obj-$(CONFIG_DM_74X164)                += 74x164_gpio.o
+
 obj-$(CONFIG_AT91_GPIO)        += at91_gpio.o
 obj-$(CONFIG_ATMEL_PIO4)       += atmel_pio4.o
 obj-$(CONFIG_INTEL_ICH6_GPIO)  += intel_ich6_gpio.o
index b58d4e64e8ad92e51c52fe76f3ae5477180c540e..732b6c2afa12ac8b99b66ee97465971defeb1f73 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <errno.h>
 #include <fdtdec.h>
 #include <malloc.h>
@@ -113,19 +114,33 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
        return 0;
 }
 
+int gpio_xlate_offs_flags(struct udevice *dev,
+                                        struct gpio_desc *desc,
+                                        struct fdtdec_phandle_args *args)
+{
+       if (args->args_count < 1)
+               return -EINVAL;
+
+       desc->offset = args->args[0];
+
+       if (args->args_count < 2)
+               return 0;
+
+       if (args->args[1] & GPIO_ACTIVE_LOW)
+               desc->flags = GPIOD_ACTIVE_LOW;
+
+       return 0;
+}
+
 static int gpio_find_and_xlate(struct gpio_desc *desc,
                               struct fdtdec_phandle_args *args)
 {
        struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
 
-       /* Use the first argument as the offset by default */
-       if (args->args_count > 0)
-               desc->offset = args->args[0];
+       if (ops->xlate)
+               return ops->xlate(desc->dev, desc, args);
        else
-               desc->offset = -1;
-       desc->flags = 0;
-
-       return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
+               return gpio_xlate_offs_flags(desc->dev, desc, args);
 }
 
 int dm_gpio_request(struct gpio_desc *desc, const char *label)
@@ -605,6 +620,7 @@ static int _gpio_request_by_name_nodev(const void *blob, int node,
 
        desc->dev = NULL;
        desc->offset = 0;
+       desc->flags = 0;
        ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
                                             "#gpio-cells", 0, index, &args);
        if (ret) {
index 8cf76f96c276b2c77d6c9f41daa88a336db96f9a..81ce446e1a162d1e2c624e657623b1fc96714963 100644 (file)
@@ -162,15 +162,6 @@ static int broadwell_gpio_ofdata_to_platdata(struct udevice *dev)
        return 0;
 }
 
-static int broadwell_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                               struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static const struct dm_gpio_ops gpio_broadwell_ops = {
        .request                = broadwell_gpio_request,
        .direction_input        = broadwell_gpio_direction_input,
@@ -178,7 +169,6 @@ static const struct dm_gpio_ops gpio_broadwell_ops = {
        .get_value              = broadwell_gpio_get_value,
        .set_value              = broadwell_gpio_set_value,
        .get_function           = broadwell_gpio_get_function,
-       .xlate                  = broadwell_gpio_xlate,
 };
 
 static const struct udevice_id intel_broadwell_gpio_ids[] = {
index 93d18e44a54eb1a5dc57604dc52c795be3b56e3a..cd960dc013f0f128be8d625aab83996e3863eb65 100644 (file)
@@ -25,7 +25,6 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <malloc.h>
-#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -277,22 +276,12 @@ static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_INPUT;
 }
 
-static int omap_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                          struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static const struct dm_gpio_ops gpio_omap_ops = {
        .direction_input        = omap_gpio_direction_input,
        .direction_output       = omap_gpio_direction_output,
        .get_value              = omap_gpio_get_value,
        .set_value              = omap_gpio_set_value,
        .get_function           = omap_gpio_get_function,
-       .xlate                  = omap_gpio_xlate,
 };
 
 static int omap_gpio_probe(struct udevice *dev)
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
new file mode 100644 (file)
index 0000000..987d10e
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Take linux kernel driver drivers/gpio/gpio-pca953x.c for reference.
+ *
+ * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+/*
+ * Note:
+ * The driver's compatible table is borrowed from Linux Kernel,
+ * but now max supported gpio pins is 24 and only PCA953X_TYPE
+ * is supported. PCA957X_TYPE is not supported now.
+ * Also the Polarity Inversion feature is not supported now.
+ *
+ * TODO:
+ * 1. Support PCA957X_TYPE
+ * 2. Support max 40 gpio pins
+ * 3. Support Plolarity Inversion
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <malloc.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <dt-bindings/gpio/gpio.h>
+
+#define PCA953X_INPUT           0
+#define PCA953X_OUTPUT          1
+#define PCA953X_INVERT          2
+#define PCA953X_DIRECTION       3
+
+#define PCA_GPIO_MASK           0x00FF
+#define PCA_INT                 0x0100
+#define PCA953X_TYPE            0x1000
+#define PCA957X_TYPE            0x2000
+#define PCA_TYPE_MASK           0xF000
+#define PCA_CHIP_TYPE(x)        ((x) & PCA_TYPE_MASK)
+
+enum {
+       PCA953X_DIRECTION_IN,
+       PCA953X_DIRECTION_OUT,
+};
+
+#define MAX_BANK 3
+#define BANK_SZ 8
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * struct pca953x_info - Data for pca953x
+ *
+ * @dev: udevice structure for the device
+ * @addr: i2c slave address
+ * @invert: Polarity inversion or not
+ * @gpio_count: the number of gpio pins that the device supports
+ * @chip_type: indicate the chip type,PCA953X or PCA957X
+ * @bank_count: the number of banks that the device supports
+ * @reg_output: array to hold the value of output registers
+ * @reg_direction: array to hold the value of direction registers
+ */
+struct pca953x_info {
+       struct udevice *dev;
+       int addr;
+       int invert;
+       int gpio_count;
+       int chip_type;
+       int bank_count;
+       u8 reg_output[MAX_BANK];
+       u8 reg_direction[MAX_BANK];
+};
+
+static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
+                               int offset)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
+       int off = offset / BANK_SZ;
+       int ret = 0;
+
+       ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1);
+       if (ret) {
+               dev_err(dev, "%s error\n", __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int pca953x_read_single(struct udevice *dev, int reg, u8 *val,
+                              int offset)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
+       int off = offset / BANK_SZ;
+       int ret;
+       u8 byte;
+
+       ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1);
+       if (ret) {
+               dev_err(dev, "%s error\n", __func__);
+               return ret;
+       }
+
+       *val = byte;
+
+       return 0;
+}
+
+static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int ret = 0;
+
+       if (info->gpio_count <= 8) {
+               ret = dm_i2c_read(dev, reg, val, 1);
+       } else if (info->gpio_count <= 16) {
+               ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
+       } else {
+               dev_err(dev, "Unsupported now\n");
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int pca953x_is_output(struct udevice *dev, int offset)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+
+       int bank = offset / BANK_SZ;
+       int off = offset % BANK_SZ;
+
+       /*0: output; 1: input */
+       return !(info->reg_direction[bank] & (1 << off));
+}
+
+static int pca953x_get_value(struct udevice *dev, unsigned offset)
+{
+       int ret;
+       u8 val = 0;
+
+       ret = pca953x_read_single(dev, PCA953X_INPUT, &val, offset);
+       if (ret)
+               return ret;
+
+       return (val >> offset) & 0x1;
+}
+
+static int pca953x_set_value(struct udevice *dev, unsigned offset,
+                            int value)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank = offset / BANK_SZ;
+       int off = offset % BANK_SZ;
+       u8 val;
+       int ret;
+
+       if (value)
+               val = info->reg_output[bank] | (1 << off);
+       else
+               val = info->reg_output[bank] & ~(1 << off);
+
+       ret = pca953x_write_single(dev, PCA953X_OUTPUT, val, offset);
+       if (ret)
+               return ret;
+
+       info->reg_output[bank] = val;
+
+       return 0;
+}
+
+static int pca953x_set_direction(struct udevice *dev, unsigned offset, int dir)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       int bank = offset / BANK_SZ;
+       int off = offset % BANK_SZ;
+       u8 val;
+       int ret;
+
+       if (dir == PCA953X_DIRECTION_IN)
+               val = info->reg_direction[bank] | (1 << off);
+       else
+               val = info->reg_direction[bank] & ~(1 << off);
+
+       ret = pca953x_write_single(dev, PCA953X_DIRECTION, val, offset);
+       if (ret)
+               return ret;
+
+       info->reg_direction[bank] = val;
+
+       return 0;
+}
+
+static int pca953x_direction_input(struct udevice *dev, unsigned offset)
+{
+       return pca953x_set_direction(dev, offset, PCA953X_DIRECTION_IN);
+}
+
+static int pca953x_direction_output(struct udevice *dev, unsigned offset,
+                                   int value)
+{
+       /* Configure output value. */
+       pca953x_set_value(dev, offset, value);
+
+       /* Configure direction as output. */
+       pca953x_set_direction(dev, offset, PCA953X_DIRECTION_OUT);
+
+       return 0;
+}
+
+static int pca953x_get_function(struct udevice *dev, unsigned offset)
+{
+       if (pca953x_is_output(dev, offset))
+               return GPIOF_OUTPUT;
+       else
+               return GPIOF_INPUT;
+}
+
+static int pca953x_xlate(struct udevice *dev, struct gpio_desc *desc,
+                        struct fdtdec_phandle_args *args)
+{
+       desc->offset = args->args[0];
+       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+       return 0;
+}
+
+static const struct dm_gpio_ops pca953x_ops = {
+       .direction_input        = pca953x_direction_input,
+       .direction_output       = pca953x_direction_output,
+       .get_value              = pca953x_get_value,
+       .set_value              = pca953x_set_value,
+       .get_function           = pca953x_get_function,
+       .xlate                  = pca953x_xlate,
+};
+
+static int pca953x_probe(struct udevice *dev)
+{
+       struct pca953x_info *info = dev_get_platdata(dev);
+       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+       char name[32], *str;
+       int addr;
+       ulong driver_data;
+       int ret;
+
+       if (!info) {
+               dev_err(dev, "platdata not ready\n");
+               return -ENOMEM;
+       }
+
+       if (!chip) {
+               dev_err(dev, "i2c not ready\n");
+               return -ENODEV;
+       }
+
+       addr = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", 0);
+       if (addr == 0)
+               return -ENODEV;
+
+       info->addr = addr;
+
+       driver_data = dev_get_driver_data(dev);
+
+       info->gpio_count = driver_data & PCA_GPIO_MASK;
+       if (info->gpio_count > MAX_BANK * BANK_SZ) {
+               dev_err(dev, "Max support %d pins now\n", MAX_BANK * BANK_SZ);
+               return -EINVAL;
+       }
+
+       info->chip_type = PCA_CHIP_TYPE(driver_data);
+       if (info->chip_type != PCA953X_TYPE) {
+               dev_err(dev, "Only support PCA953X chip type now.\n");
+               return -EINVAL;
+       }
+
+       info->bank_count = DIV_ROUND_UP(info->gpio_count, BANK_SZ);
+
+       ret = pca953x_read_regs(dev, PCA953X_OUTPUT, info->reg_output);
+       if (ret) {
+               dev_err(dev, "Error reading output register\n");
+               return ret;
+       }
+
+       ret = pca953x_read_regs(dev, PCA953X_DIRECTION, info->reg_direction);
+       if (ret) {
+               dev_err(dev, "Error reading direction register\n");
+               return ret;
+       }
+
+       snprintf(name, sizeof(name), "gpio@%x_", info->addr);
+       str = strdup(name);
+       if (!str)
+               return -ENOMEM;
+       uc_priv->bank_name = str;
+       uc_priv->gpio_count = info->gpio_count;
+
+       dev_dbg(dev, "%s is ready\n", str);
+
+       return 0;
+}
+
+#define OF_953X(__nrgpio, __int) (ulong)(__nrgpio | PCA953X_TYPE | __int)
+#define OF_957X(__nrgpio, __int) (ulong)(__nrgpio | PCA957X_TYPE | __int)
+
+static const struct udevice_id pca953x_ids[] = {
+       { .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },
+       { .compatible = "nxp,pca9534", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "nxp,pca9536", .data = OF_953X(4, 0), },
+       { .compatible = "nxp,pca9537", .data = OF_953X(4, PCA_INT), },
+       { .compatible = "nxp,pca9538", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "nxp,pca9539", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "nxp,pca9554", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "nxp,pca9555", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "nxp,pca9556", .data = OF_953X(8, 0), },
+       { .compatible = "nxp,pca9557", .data = OF_953X(8, 0), },
+       { .compatible = "nxp,pca9574", .data = OF_957X(8, PCA_INT), },
+       { .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), },
+       { .compatible = "nxp,pca9698", .data = OF_953X(40, 0), },
+
+       { .compatible = "maxim,max7310", .data = OF_953X(8, 0), },
+       { .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "maxim,max7315", .data = OF_953X(8, PCA_INT), },
+
+       { .compatible = "ti,pca6107", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "ti,tca6408", .data = OF_953X(8, PCA_INT), },
+       { .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
+       { .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
+
+       { .compatible = "onsemi,pca9654", .data = OF_953X(8, PCA_INT), },
+
+       { .compatible = "exar,xra1202", .data = OF_953X(8, 0), },
+       { }
+};
+
+U_BOOT_DRIVER(pca953x) = {
+       .name           = "pca953x",
+       .id             = UCLASS_GPIO,
+       .ops            = &pca953x_ops,
+       .probe          = pca953x_probe,
+       .platdata_auto_alloc_size = sizeof(struct pca953x_info),
+       .of_match       = pca953x_ids,
+};
index 499b4fa5ad1e8fa56d550c665de862808a8acbb0..7a037f3a77cd1009d2ca495d4cc7d9a8530721e1 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <linux/compat.h>
-#include <dt-bindings/gpio/gpio.h>
 #include <mach/pic32.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -99,14 +98,6 @@ static int pic32_gpio_direction_output(struct udevice *dev,
        return 0;
 }
 
-static int pic32_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                           struct fdtdec_phandle_args *args)
-{
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static int pic32_gpio_get_function(struct udevice *dev, unsigned offset)
 {
        int ret = GPIOF_UNUSED;
@@ -131,7 +122,6 @@ static const struct dm_gpio_ops gpio_pic32_ops = {
        .get_value              = pic32_gpio_get_value,
        .set_value              = pic32_gpio_set_value,
        .get_function           = pic32_gpio_get_function,
-       .xlate                  = pic32_gpio_xlate,
 };
 
 static int pic32_gpio_probe(struct udevice *dev)
index 40e87bd1996a4249008bc649f19a1c6f55e2877b..fefe3ca20359ab0b849fe4d6735cae92a4b08c8b 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <dm/pinctrl.h>
-#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 
 enum {
@@ -98,15 +97,6 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
 #endif
 }
 
-static int rockchip_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                           struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static int rockchip_gpio_probe(struct udevice *dev)
 {
        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
@@ -135,7 +125,6 @@ static const struct dm_gpio_ops gpio_rockchip_ops = {
        .get_value              = rockchip_gpio_get_value,
        .set_value              = rockchip_gpio_set_value,
        .get_function           = rockchip_gpio_get_function,
-       .xlate                  = rockchip_gpio_xlate,
 };
 
 static const struct udevice_id rockchip_gpio_ids[] = {
index 0f22b238ba99ec09679df0d8fe840f98632f55d4..377fed467fb323a5d4beb721a1ac7efc33f2eebb 100644 (file)
@@ -13,7 +13,6 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <dm/device-internal.h>
-#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -276,22 +275,12 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_FUNC;
 }
 
-static int exynos_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
-                            struct fdtdec_phandle_args *args)
-{
-       desc->offset = args->args[0];
-       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
-
-       return 0;
-}
-
 static const struct dm_gpio_ops gpio_exynos_ops = {
        .direction_input        = exynos_gpio_direction_input,
        .direction_output       = exynos_gpio_direction_output,
        .get_value              = exynos_gpio_get_value,
        .set_value              = exynos_gpio_set_value,
        .get_function           = exynos_gpio_get_function,
-       .xlate                  = exynos_gpio_xlate,
 };
 
 static int gpio_exynos_probe(struct udevice *dev)
index 4d3df11a1b51e5a4bc9a8e2209b3cdcc5292820c..c80efc39a791872aab2216bd7fb518b437e270b2 100644 (file)
@@ -2,7 +2,7 @@ menu "MMC Host controller Support"
 
 config MMC
        bool "Enable MMC support"
-       depends on ARCH_SUNXI
+       depends on ARCH_SUNXI || SANDBOX
        help
          TODO: Move all architectures to use this option
 
@@ -58,4 +58,13 @@ config MMC_UNIPHIER
        help
          This selects support for the SD/MMC Host Controller on UniPhier SoCs.
 
+config SANDBOX_MMC
+       bool "Sandbox MMC support"
+       depends on MMC && SANDBOX
+       help
+         This select a dummy sandbox MMC driver. At present this does nothing
+         other than allow sandbox to be build with MMC support. This
+         improves build coverage for sandbox and makes it easier to detect
+         MMC build errors with sandbox.
+
 endmenu
index 585aaf31150140fec913cf0bee6f86637752a5f3..3da4817a189c6e00b8e780e8837509b38e3021c1 100644 (file)
@@ -5,7 +5,13 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_DM_MMC) += mmc-uclass.o
+ifdef CONFIG_DM_MMC
+obj-$(CONFIG_GENERIC_MMC) += mmc-uclass.o
+endif
+
+ifndef CONFIG_BLK
+obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o
+endif
 
 obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o
@@ -34,7 +40,11 @@ obj-$(CONFIG_ROCKCHIP_DWMMC) += rockchip_dw_mmc.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
 obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
 obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
+ifdef CONFIG_BLK
+ifdef CONFIG_GENERIC_MMC
 obj-$(CONFIG_SANDBOX) += sandbox_mmc.o
+endif
+endif
 obj-$(CONFIG_SDHCI) += sdhci.o
 obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
index 777489f5d8e9c63750849d91b78c55f572054db4..1b967d982bc74946ccd61fe1c74ae5826662cb6f 100644 (file)
@@ -21,6 +21,112 @@ struct mmc *mmc_get_mmc_dev(struct udevice *dev)
        return upriv->mmc;
 }
 
+#ifdef CONFIG_BLK
+struct mmc *find_mmc_device(int dev_num)
+{
+       struct udevice *dev, *mmc_dev;
+       int ret;
+
+       ret = blk_get_device(IF_TYPE_MMC, dev_num, &dev);
+
+       if (ret) {
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+               printf("MMC Device %d not found\n", dev_num);
+#endif
+               return NULL;
+       }
+
+       mmc_dev = dev_get_parent(dev);
+
+       return mmc_get_mmc_dev(mmc_dev);
+}
+
+int get_mmc_num(void)
+{
+       return max(blk_find_max_devnum(IF_TYPE_MMC), 0);
+}
+
+int mmc_get_next_devnum(void)
+{
+       int ret;
+
+       ret = get_mmc_num();
+       if (ret < 0)
+               return ret;
+
+       return ret + 1;
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       struct blk_desc *desc;
+       struct udevice *dev;
+
+       device_find_first_child(mmc->dev, &dev);
+       if (!dev)
+               return NULL;
+       desc = dev_get_uclass_platdata(dev);
+
+       return desc;
+}
+
+void mmc_do_preinit(void)
+{
+       struct udevice *dev;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(UCLASS_MMC, &uc);
+       if (ret)
+               return;
+       uclass_foreach_dev(dev, uc) {
+               struct mmc *m = mmc_get_mmc_dev(dev);
+
+               if (!m)
+                       continue;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+               mmc_set_preinit(m, 1);
+#endif
+               if (m->preinit)
+                       mmc_start_init(m);
+       }
+}
+
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+void print_mmc_devices(char separator)
+{
+       struct udevice *dev;
+       char *mmc_type;
+       bool first = true;
+
+       for (uclass_first_device(UCLASS_MMC, &dev);
+            dev;
+            uclass_next_device(&dev)) {
+               struct mmc *m = mmc_get_mmc_dev(dev);
+
+               if (!first) {
+                       printf("%c", separator);
+                       if (separator != '\n')
+                               puts(" ");
+               }
+               if (m->has_init)
+                       mmc_type = IS_SD(m) ? "SD" : "eMMC";
+               else
+                       mmc_type = NULL;
+
+               printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum);
+               if (mmc_type)
+                       printf(" (%s)", mmc_type);
+       }
+
+       printf("\n");
+}
+
+#else
+void print_mmc_devices(char separator) { }
+#endif
+#endif /* CONFIG_BLK */
+
 U_BOOT_DRIVER(mmc) = {
        .name   = "mmc",
        .id     = UCLASS_MMC,
index d3c22abfd5a8c198499308cb4b8e24f161f9be3d..74b3d68f871ccfc24c33e2fded971e5bba5c4739 100644 (file)
@@ -21,9 +21,6 @@
 #include <div64.h>
 #include "mmc_private.h"
 
-static struct list_head mmc_devices;
-static int cur_dev_num = -1;
-
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
        return -1;
@@ -178,25 +175,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
        return mmc_send_cmd(mmc, &cmd, NULL);
 }
 
-struct mmc *find_mmc_device(int dev_num)
-{
-       struct mmc *m;
-       struct list_head *entry;
-
-       list_for_each(entry, &mmc_devices) {
-               m = list_entry(entry, struct mmc, link);
-
-               if (m->block_dev.devnum == dev_num)
-                       return m;
-       }
-
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
-       printf("MMC Device %d not found\n", dev_num);
-#endif
-
-       return NULL;
-}
-
 static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
                           lbaint_t blkcnt)
 {
@@ -238,9 +216,17 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
        return blkcnt;
 }
 
+#ifdef CONFIG_BLK
+static ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+                      void *dst)
+#else
 static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
                       lbaint_t blkcnt, void *dst)
+#endif
 {
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
        int dev_num = block_dev->devnum;
        int err;
        lbaint_t cur, blocks_todo = blkcnt;
@@ -252,14 +238,14 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return 0;
 
-       err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+       err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
        if (err < 0)
                return 0;
 
-       if ((start + blkcnt) > mmc->block_dev.lba) {
+       if ((start + blkcnt) > block_dev->lba) {
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
-                       start + blkcnt, mmc->block_dev.lba);
+                       start + blkcnt, block_dev->lba);
 #endif
                return 0;
        }
@@ -577,58 +563,73 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num)
                return -1;
        }
 
-       mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+       mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len);
 
        return 0;
 }
 
-int mmc_select_hwpart(int dev_num, int hwpart)
+static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 {
-       struct mmc *mmc = find_mmc_device(dev_num);
        int ret;
 
-       if (!mmc)
-               return -ENODEV;
+       ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+                        (mmc->part_config & ~PART_ACCESS_MASK)
+                        | (part_num & PART_ACCESS_MASK));
 
-       if (mmc->block_dev.hwpart == hwpart)
+       /*
+        * Set the capacity if the switch succeeded or was intended
+        * to return to representing the raw device.
+        */
+       if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
+               ret = mmc_set_capacity(mmc, part_num);
+               mmc_get_blk_desc(mmc)->hwpart = part_num;
+       }
+
+       return ret;
+}
+
+#ifdef CONFIG_BLK
+static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
+{
+       struct udevice *mmc_dev = dev_get_parent(bdev);
+       struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
+       struct blk_desc *desc = dev_get_uclass_platdata(bdev);
+       int ret;
+
+       if (desc->hwpart == hwpart)
                return 0;
 
-       if (mmc->part_config == MMCPART_NOAVAILABLE) {
-               printf("Card doesn't support part_switch\n");
+       if (mmc->part_config == MMCPART_NOAVAILABLE)
                return -EMEDIUMTYPE;
-       }
 
-       ret = mmc_switch_part(dev_num, hwpart);
+       ret = mmc_switch_part(mmc, hwpart);
        if (ret)
                return ret;
 
        return 0;
 }
-
-
-int mmc_switch_part(int dev_num, unsigned int part_num)
+#else
+static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
 {
-       struct mmc *mmc = find_mmc_device(dev_num);
+       struct mmc *mmc = find_mmc_device(desc->devnum);
        int ret;
 
        if (!mmc)
-               return -1;
+               return -ENODEV;
 
-       ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
-                        (mmc->part_config & ~PART_ACCESS_MASK)
-                        | (part_num & PART_ACCESS_MASK));
+       if (mmc->block_dev.hwpart == hwpart)
+               return 0;
 
-       /*
-        * Set the capacity if the switch succeeded or was intended
-        * to return to representing the raw device.
-        */
-       if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
-               ret = mmc_set_capacity(mmc, part_num);
-               mmc->block_dev.hwpart = part_num;
-       }
+       if (mmc->part_config == MMCPART_NOAVAILABLE)
+               return -EMEDIUMTYPE;
 
-       return ret;
+       ret = mmc_switch_part(mmc, hwpart);
+       if (ret)
+               return ret;
+
+       return 0;
 }
+#endif
 
 int mmc_hwpart_config(struct mmc *mmc,
                      const struct mmc_hwpart_conf *conf,
@@ -1039,6 +1040,7 @@ static int mmc_startup(struct mmc *mmc)
        int timeout = 1000;
        bool has_parts = false;
        bool part_completed;
+       struct blk_desc *bdesc;
 
 #ifdef CONFIG_MMC_SPI_CRC_ON
        if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
@@ -1335,7 +1337,7 @@ static int mmc_startup(struct mmc *mmc)
                mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
        }
 
-       err = mmc_set_capacity(mmc, mmc->block_dev.hwpart);
+       err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
        if (err)
                return err;
 
@@ -1475,31 +1477,32 @@ static int mmc_startup(struct mmc *mmc)
        }
 
        /* fill in device description */
-       mmc->block_dev.lun = 0;
-       mmc->block_dev.hwpart = 0;
-       mmc->block_dev.type = 0;
-       mmc->block_dev.blksz = mmc->read_bl_len;
-       mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
-       mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
+       bdesc = mmc_get_blk_desc(mmc);
+       bdesc->lun = 0;
+       bdesc->hwpart = 0;
+       bdesc->type = 0;
+       bdesc->blksz = mmc->read_bl_len;
+       bdesc->log2blksz = LOG2(bdesc->blksz);
+       bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
 #if !defined(CONFIG_SPL_BUILD) || \
                (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
                !defined(CONFIG_USE_TINY_PRINTF))
-       sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
+       sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
                mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
                (mmc->cid[3] >> 16) & 0xffff);
-       sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
+       sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
                (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
                (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
                (mmc->cid[2] >> 24) & 0xff);
-       sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
+       sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
                (mmc->cid[2] >> 16) & 0xf);
 #else
-       mmc->block_dev.vendor[0] = 0;
-       mmc->block_dev.product[0] = 0;
-       mmc->block_dev.revision[0] = 0;
+       bdesc->vendor[0] = 0;
+       bdesc->product[0] = 0;
+       bdesc->revision[0] = 0;
 #endif
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
-       part_init(&mmc->block_dev);
+       part_init(bdesc);
 #endif
 
        return 0;
@@ -1537,8 +1540,55 @@ int __deprecated mmc_register(struct mmc *mmc)
        return -1;
 }
 
+#ifdef CONFIG_BLK
+int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
+{
+       struct blk_desc *bdesc;
+       struct udevice *bdev;
+       int ret;
+
+       ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512,
+                                0, &bdev);
+       if (ret) {
+               debug("Cannot create block device\n");
+               return ret;
+       }
+       bdesc = dev_get_uclass_platdata(bdev);
+       mmc->cfg = cfg;
+       mmc->priv = dev;
+
+       /* the following chunk was from mmc_register() */
+
+       /* Setup dsr related values */
+       mmc->dsr_imp = 0;
+       mmc->dsr = 0xffffffff;
+       /* Setup the universal parts of the block interface just once */
+       bdesc->removable = 1;
+
+       /* setup initial part type */
+       bdesc->part_type = mmc->cfg->part_type;
+       mmc->dev = dev;
+
+       return 0;
+}
+
+int mmc_unbind(struct udevice *dev)
+{
+       struct udevice *bdev;
+
+       device_find_first_child(dev, &bdev);
+       if (bdev) {
+               device_remove(bdev);
+               device_unbind(bdev);
+       }
+
+       return 0;
+}
+
+#else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
+       struct blk_desc *bdesc;
        struct mmc *mmc;
 
        /* quick validation */
@@ -1559,19 +1609,17 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
        mmc->dsr_imp = 0;
        mmc->dsr = 0xffffffff;
        /* Setup the universal parts of the block interface just once */
-       mmc->block_dev.if_type = IF_TYPE_MMC;
-       mmc->block_dev.devnum = cur_dev_num++;
-       mmc->block_dev.removable = 1;
-       mmc->block_dev.block_read = mmc_bread;
-       mmc->block_dev.block_write = mmc_bwrite;
-       mmc->block_dev.block_erase = mmc_berase;
+       bdesc = mmc_get_blk_desc(mmc);
+       bdesc->if_type = IF_TYPE_MMC;
+       bdesc->removable = 1;
+       bdesc->devnum = mmc_get_next_devnum();
+       bdesc->block_read = mmc_bread;
+       bdesc->block_write = mmc_bwrite;
+       bdesc->block_erase = mmc_berase;
 
        /* setup initial part type */
-       mmc->block_dev.part_type = mmc->cfg->part_type;
-
-       INIT_LIST_HEAD(&mmc->link);
-
-       list_add_tail(&mmc->link, &mmc_devices);
+       bdesc->part_type = mmc->cfg->part_type;
+       mmc_list_add(mmc);
 
        return mmc;
 }
@@ -1581,15 +1629,23 @@ void mmc_destroy(struct mmc *mmc)
        /* only freeing memory for now */
        free(mmc);
 }
+#endif
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *mmc_get_dev(int dev)
+#ifndef CONFIG_BLK
+static int mmc_get_dev(int dev, struct blk_desc **descp)
 {
        struct mmc *mmc = find_mmc_device(dev);
-       if (!mmc || mmc_init(mmc))
-               return NULL;
+       int ret;
 
-       return &mmc->block_dev;
+       if (!mmc)
+               return -ENODEV;
+       ret = mmc_init(mmc);
+       if (ret)
+               return ret;
+
+       *descp = &mmc->block_dev;
+
+       return 0;
 }
 #endif
 
@@ -1636,7 +1692,7 @@ int mmc_start_init(struct mmc *mmc)
                return err;
 
        /* The internal partition reset to user partition(0) at every CMD0*/
-       mmc->block_dev.hwpart = 0;
+       mmc_get_blk_desc(mmc)->hwpart = 0;
 
        /* Test for SD version 2 */
        err = mmc_send_if_cond(mmc);
@@ -1683,7 +1739,11 @@ int mmc_init(struct mmc *mmc)
 {
        int err = 0;
        unsigned start;
+#ifdef CONFIG_DM_MMC
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
 
+       upriv->mmc = mmc;
+#endif
        if (mmc->has_init)
                return 0;
 
@@ -1716,66 +1776,11 @@ __weak int board_mmc_init(bd_t *bis)
        return -1;
 }
 
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
-
-void print_mmc_devices(char separator)
-{
-       struct mmc *m;
-       struct list_head *entry;
-       char *mmc_type;
-
-       list_for_each(entry, &mmc_devices) {
-               m = list_entry(entry, struct mmc, link);
-
-               if (m->has_init)
-                       mmc_type = IS_SD(m) ? "SD" : "eMMC";
-               else
-                       mmc_type = NULL;
-
-               printf("%s: %d", m->cfg->name, m->block_dev.devnum);
-               if (mmc_type)
-                       printf(" (%s)", mmc_type);
-
-               if (entry->next != &mmc_devices) {
-                       printf("%c", separator);
-                       if (separator != '\n')
-                               puts (" ");
-               }
-       }
-
-       printf("\n");
-}
-
-#else
-void print_mmc_devices(char separator) { }
-#endif
-
-int get_mmc_num(void)
-{
-       return cur_dev_num;
-}
-
 void mmc_set_preinit(struct mmc *mmc, int preinit)
 {
        mmc->preinit = preinit;
 }
 
-static void do_preinit(void)
-{
-       struct mmc *m;
-       struct list_head *entry;
-
-       list_for_each(entry, &mmc_devices) {
-               m = list_entry(entry, struct mmc, link);
-
-#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
-               mmc_set_preinit(m, 1);
-#endif
-               if (m->preinit)
-                       mmc_start_init(m);
-       }
-}
-
 #if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD)
 static int mmc_probe(bd_t *bis)
 {
@@ -1828,9 +1833,9 @@ int mmc_initialize(bd_t *bis)
                return 0;
        initialized = 1;
 
-       INIT_LIST_HEAD (&mmc_devices);
-       cur_dev_num = 0;
-
+#ifndef CONFIG_BLK
+       mmc_list_init();
+#endif
        ret = mmc_probe(bis);
        if (ret)
                return ret;
@@ -1839,7 +1844,7 @@ int mmc_initialize(bd_t *bis)
        print_mmc_devices(',');
 #endif
 
-       do_preinit();
+       mmc_do_preinit();
        return 0;
 }
 
@@ -1965,3 +1970,25 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
                          enable);
 }
 #endif
+
+#ifdef CONFIG_BLK
+static const struct blk_ops mmc_blk_ops = {
+       .read   = mmc_bread,
+       .write  = mmc_bwrite,
+       .select_hwpart  = mmc_select_hwpart,
+};
+
+U_BOOT_DRIVER(mmc_blk) = {
+       .name           = "mmc_blk",
+       .id             = UCLASS_BLK,
+       .ops            = &mmc_blk_ops,
+};
+#else
+U_BOOT_LEGACY_BLK(mmc) = {
+       .if_typename    = "mmc",
+       .if_type        = IF_TYPE_MMC,
+       .max_devs       = -1,
+       .get_dev        = mmc_get_dev,
+       .select_hwpart  = mmc_select_hwpartp,
+};
+#endif
diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c
new file mode 100644 (file)
index 0000000..3ec649f
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+
+static struct list_head mmc_devices;
+static int cur_dev_num = -1;
+
+struct mmc *find_mmc_device(int dev_num)
+{
+       struct mmc *m;
+       struct list_head *entry;
+
+       list_for_each(entry, &mmc_devices) {
+               m = list_entry(entry, struct mmc, link);
+
+               if (m->block_dev.devnum == dev_num)
+                       return m;
+       }
+
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+       printf("MMC Device %d not found\n", dev_num);
+#endif
+
+       return NULL;
+}
+
+int mmc_get_next_devnum(void)
+{
+       return cur_dev_num++;
+}
+
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
+{
+       return &mmc->block_dev;
+}
+
+int get_mmc_num(void)
+{
+       return cur_dev_num;
+}
+
+void mmc_do_preinit(void)
+{
+       struct mmc *m;
+       struct list_head *entry;
+
+       list_for_each(entry, &mmc_devices) {
+               m = list_entry(entry, struct mmc, link);
+
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+               mmc_set_preinit(m, 1);
+#endif
+               if (m->preinit)
+                       mmc_start_init(m);
+       }
+}
+
+void mmc_list_init(void)
+{
+       INIT_LIST_HEAD(&mmc_devices);
+       cur_dev_num = 0;
+}
+
+void mmc_list_add(struct mmc *mmc)
+{
+       INIT_LIST_HEAD(&mmc->link);
+
+       list_add_tail(&mmc->link, &mmc_devices);
+}
+
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+void print_mmc_devices(char separator)
+{
+       struct mmc *m;
+       struct list_head *entry;
+       char *mmc_type;
+
+       list_for_each(entry, &mmc_devices) {
+               m = list_entry(entry, struct mmc, link);
+
+               if (m->has_init)
+                       mmc_type = IS_SD(m) ? "SD" : "eMMC";
+               else
+                       mmc_type = NULL;
+
+               printf("%s: %d", m->cfg->name, m->block_dev.devnum);
+               if (mmc_type)
+                       printf(" (%s)", mmc_type);
+
+               if (entry->next != &mmc_devices) {
+                       printf("%c", separator);
+                       if (separator != '\n')
+                               puts(" ");
+               }
+       }
+
+       printf("\n");
+}
+
+#else
+void print_mmc_devices(char separator) { }
+#endif
index d3f6bfe123cdde8930ad0b40e5307efd83274dab..27b9e5f56f8c284d489e817d9a7e33fc5dc3f8b2 100644 (file)
@@ -25,8 +25,13 @@ void mmc_adapter_card_type_ident(void);
 unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
                         lbaint_t blkcnt);
 
-unsigned long mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
-                        lbaint_t blkcnt, const void *src);
+#ifdef CONFIG_BLK
+ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+                const void *src);
+#else
+ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
+                const void *src);
+#endif
 
 #else /* CONFIG_SPL_BUILD */
 
@@ -46,4 +51,28 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
 
 #endif /* CONFIG_SPL_BUILD */
 
+/**
+ * mmc_get_next_devnum() - Get the next available MMC device number
+ *
+ * @return next available device number (0 = first), or -ve on error
+ */
+int mmc_get_next_devnum(void);
+
+/**
+ * mmc_do_preinit() - Get an MMC device ready for use
+ */
+void mmc_do_preinit(void);
+
+/**
+ * mmc_list_init() - Set up the list of MMC devices
+ */
+void mmc_list_init(void);
+
+/**
+ * mmc_list_add() - Add a new MMC device to the list of devices
+ *
+ * @mmc:       Device to add
+ */
+void mmc_list_add(struct mmc *mmc);
+
 #endif /* _MMC_PRIVATE_H_ */
index 7b186f8500d70c754b8237519c498741447e1f78..0f8b5c79d7c6073d47964e25140b1991b119cbc4 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <config.h>
 #include <common.h>
+#include <dm.h>
 #include <part.h>
 #include <div64.h>
 #include <linux/math64.h>
@@ -78,7 +79,8 @@ unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
        if (!mmc)
                return -1;
 
-       err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+       err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num,
+                                      block_dev->hwpart);
        if (err < 0)
                return -1;
 
@@ -121,9 +123,9 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
        struct mmc_data data;
        int timeout = 1000;
 
-       if ((start + blkcnt) > mmc->block_dev.lba) {
+       if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) {
                printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
-                      start + blkcnt, mmc->block_dev.lba);
+                      start + blkcnt, mmc_get_blk_desc(mmc)->lba);
                return 0;
        }
 
@@ -171,9 +173,17 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
        return blkcnt;
 }
 
+#ifdef CONFIG_BLK
+ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+                const void *src)
+#else
 ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
                 const void *src)
+#endif
 {
+#ifdef CONFIG_BLK
+       struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
        int dev_num = block_dev->devnum;
        lbaint_t cur, blocks_todo = blkcnt;
        int err;
@@ -182,7 +192,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
        if (!mmc)
                return 0;
 
-       err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+       err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart);
        if (err < 0)
                return 0;
 
index 85a832bd420f6d706df9912b0eb3c161915c2469..be34057ea2cef9108cd842c7237fc70726d853a8 100644 (file)
@@ -825,6 +825,7 @@ static int omap_hsmmc_probe(struct udevice *dev)
        gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN);
 #endif
 
+       mmc->dev = dev;
        upriv->mmc = mmc;
 
        return 0;
index e03d6dd51730f1579769986103fea8ff3bb8e043..abe74293edfdb609dde6fa0d308ff81e17b798bf 100644 (file)
@@ -41,7 +41,12 @@ static int pic32_sdhci_probe(struct udevice *dev)
                return ret;
        }
 
-       return add_sdhci(host, f_min_max[1], f_min_max[0]);
+       ret = add_sdhci(host, f_min_max[1], f_min_max[0]);
+       if (ret)
+               return ret;
+       host->mmc->dev = dev;
+
+       return 0;
 }
 
 static const struct udevice_id pic32_sdhci_ids[] = {
index cb9e1048d0351041e54817e0dc4ab4130ada53ac..0a261c51a84b897139679b9b967d30405ea6cac8 100644 (file)
@@ -104,6 +104,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
        if (ret)
                return ret;
 
+       host->mmc->dev = dev;
        upriv->mmc = host->mmc;
 
        return 0;
index f4646a824fa148e683cb258cf314e84d8dc2a946..7da059c43cd69650911572183b777d85fdb23612 100644 (file)
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <fdtdec.h>
 #include <mmc.h>
 #include <asm/test.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct sandbox_mmc_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
+/**
+ * sandbox_mmc_send_cmd() - Emulate SD commands
+ *
+ * This emulate an SD card version 2. Single-block reads result in zero data.
+ * Multiple-block reads return a test string.
+ */
+static int sandbox_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+                               struct mmc_data *data)
+{
+       switch (cmd->cmdidx) {
+       case MMC_CMD_ALL_SEND_CID:
+               break;
+       case SD_CMD_SEND_RELATIVE_ADDR:
+               cmd->response[0] = 0 << 16; /* mmc->rca */
+       case MMC_CMD_GO_IDLE_STATE:
+               break;
+       case SD_CMD_SEND_IF_COND:
+               cmd->response[0] = 0xaa;
+               break;
+       case MMC_CMD_SEND_STATUS:
+               cmd->response[0] = MMC_STATUS_RDY_FOR_DATA;
+               break;
+       case MMC_CMD_SELECT_CARD:
+               break;
+       case MMC_CMD_SEND_CSD:
+               cmd->response[0] = 0;
+               cmd->response[1] = 10 << 16;    /* 1 << block_len */
+               break;
+       case SD_CMD_SWITCH_FUNC: {
+               u32 *resp = (u32 *)data->dest;
+
+               resp[7] = cpu_to_be32(SD_HIGHSPEED_BUSY);
+               break;
+       }
+       case MMC_CMD_READ_SINGLE_BLOCK:
+               memset(data->dest, '\0', data->blocksize);
+               break;
+       case MMC_CMD_READ_MULTIPLE_BLOCK:
+               strcpy(data->dest, "this is a test");
+               break;
+       case MMC_CMD_STOP_TRANSMISSION:
+               break;
+       case SD_CMD_APP_SEND_OP_COND:
+               cmd->response[0] = OCR_BUSY | OCR_HCS;
+               cmd->response[1] = 0;
+               cmd->response[2] = 0;
+               break;
+       case MMC_CMD_APP_CMD:
+               break;
+       case MMC_CMD_SET_BLOCKLEN:
+               debug("block len %d\n", cmd->cmdarg);
+               break;
+       case SD_CMD_APP_SEND_SCR: {
+               u32 *scr = (u32 *)data->dest;
+
+               scr[0] = cpu_to_be32(2 << 24 | 1 << 15);  /* SD version 3 */
+               break;
+       }
+       default:
+               debug("%s: Unknown command %d\n", __func__, cmd->cmdidx);
+               break;
+       }
+
+       return 0;
+}
+
+static void sandbox_mmc_set_ios(struct mmc *mmc)
+{
+}
+
+static int sandbox_mmc_init(struct mmc *mmc)
+{
+       return 0;
+}
+
+static int sandbox_mmc_getcd(struct mmc *mmc)
+{
+       return 1;
+}
+
+static const struct mmc_ops sandbox_mmc_ops = {
+       .send_cmd = sandbox_mmc_send_cmd,
+       .set_ios = sandbox_mmc_set_ios,
+       .init = sandbox_mmc_init,
+       .getcd = sandbox_mmc_getcd,
+};
+
+int sandbox_mmc_probe(struct udevice *dev)
+{
+       struct sandbox_mmc_plat *plat = dev_get_platdata(dev);
+
+       return mmc_init(&plat->mmc);
+}
+
+int sandbox_mmc_bind(struct udevice *dev)
+{
+       struct sandbox_mmc_plat *plat = dev_get_platdata(dev);
+       struct mmc_config *cfg = &plat->cfg;
+       int ret;
+
+       cfg->name = dev->name;
+       cfg->ops = &sandbox_mmc_ops;
+       cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_8BIT;
+       cfg->voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
+       cfg->f_min = 1000000;
+       cfg->f_max = 52000000;
+       cfg->b_max = U32_MAX;
+
+       ret = mmc_bind(dev, &plat->mmc, cfg);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+int sandbox_mmc_unbind(struct udevice *dev)
+{
+       mmc_unbind(dev);
+
+       return 0;
+}
+
 static const struct udevice_id sandbox_mmc_ids[] = {
        { .compatible = "sandbox,mmc" },
        { }
 };
 
-U_BOOT_DRIVER(warm_mmc_sandbox) = {
+U_BOOT_DRIVER(mmc_sandbox) = {
        .name           = "mmc_sandbox",
        .id             = UCLASS_MMC,
        .of_match       = sandbox_mmc_ids,
+       .bind           = sandbox_mmc_bind,
+       .unbind         = sandbox_mmc_unbind,
+       .probe          = sandbox_mmc_probe,
+       .platdata_auto_alloc_size = sizeof(struct sandbox_mmc_plat),
 };
index 097db81b05131a63d030983def8c593beac0dfe8..6a0e9719b8a49cb354b46ed711350e2bb47a2293 100644 (file)
@@ -108,6 +108,7 @@ static int socfpga_dwmmc_probe(struct udevice *dev)
                return ret;
 
        upriv->mmc = host->mmc;
+       host->mmc->dev = dev;
 
        return 0;
 }
index 81a80cdbc2ca98728a28ea8466b4bd9c8dfb6bd9..4978cca76d898f712b6091409d7084a77817902d 100644 (file)
@@ -725,6 +725,7 @@ int uniphier_sd_probe(struct udevice *dev)
                return -EIO;
 
        upriv->mmc = priv->mmc;
+       priv->mmc->dev = dev;
 
        return 0;
 }
index b59feca80b5cf1d649e4b03a81eb232ecee38bf6..d405929b64140fa4355bf7c399850ab76a3da645 100644 (file)
@@ -35,6 +35,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
                  CONFIG_ZYNQ_SDHCI_MIN_FREQ);
 
        upriv->mmc = host->mmc;
+       host->mmc->dev = dev;
 
        return 0;
 }
index 461908941de2ef7f6220a22e9a7ab2e69c082f48..4b73a0ff9cb273cd3f01d7aeaff1bfc8b537bfca 100644 (file)
@@ -175,11 +175,7 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
        int bus;
 
        for (hose = pci_get_hose_head(); hose; hose = hose->next) {
-#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
-               for (bus = hose->last_busno; bus >= hose->first_busno; bus--) {
-#else
                for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
-#endif
                        bdf = pci_hose_find_devices(hose, bus, ids, &index);
                        if (bdf != -1)
                                return bdf;
index 407354fc4cdf2acac18fee8d014e4d92f63078f3..059cb0fc6e549d6e088374667ca0f9f9a3e4dbdc 100644 (file)
@@ -2,6 +2,9 @@
  * (C) Copyright 2004-2007 Freescale Semiconductor, Inc.
  * TsiChung Liew, Tsi-Chung.Liew@freescale.com.
  *
+ * Modified to add device model (DM) support
+ * (C) Copyright 2015  Angelo Dureghello <angelo@sysam.it>
+ *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
  */
 
 #include <common.h>
+#include <dm.h>
+#include <dm/platform_data/serial_coldfire.h>
 #include <serial.h>
 #include <linux/compiler.h>
-
 #include <asm/immap.h>
 #include <asm/uart.h>
 
@@ -21,91 +25,110 @@ DECLARE_GLOBAL_DATA_PTR;
 
 extern void uart_port_conf(int port);
 
-static int mcf_serial_init(void)
+static int mcf_serial_init_common(uart_t *uart, int port_idx, int baudrate)
 {
-       volatile uart_t *uart;
        u32 counter;
 
-       uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
-
-       uart_port_conf(CONFIG_SYS_UART_PORT);
+       uart_port_conf(port_idx);
 
        /* write to SICR: SIM2 = uart mode,dcd does not affect rx */
-       uart->ucr = UART_UCR_RESET_RX;
-       uart->ucr = UART_UCR_RESET_TX;
-       uart->ucr = UART_UCR_RESET_ERROR;
-       uart->ucr = UART_UCR_RESET_MR;
+       writeb(UART_UCR_RESET_RX, &uart->ucr);
+       writeb(UART_UCR_RESET_TX, &uart->ucr);
+       writeb(UART_UCR_RESET_ERROR, &uart->ucr);
+       writeb(UART_UCR_RESET_MR, &uart->ucr);
        __asm__("nop");
 
-       uart->uimr = 0;
+       writeb(0, &uart->uimr);
 
        /* write to CSR: RX/TX baud rate from timers */
-       uart->ucsr = (UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK);
+       writeb(UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK, &uart->ucsr);
 
-       uart->umr = (UART_UMR_BC_8 | UART_UMR_PM_NONE);
-       uart->umr = UART_UMR_SB_STOP_BITS_1;
+       writeb(UART_UMR_BC_8 | UART_UMR_PM_NONE, &uart->umr);
+       writeb(UART_UMR_SB_STOP_BITS_1, &uart->umr);
 
        /* Setting up BaudRate */
-       counter = (u32) ((gd->bus_clk / 32) + (gd->baudrate / 2));
-       counter = counter / gd->baudrate;
+       counter = (u32) ((gd->bus_clk / 32) + (baudrate / 2));
+       counter = counter / baudrate;
 
        /* write to CTUR: divide counter upper byte */
-       uart->ubg1 = (u8) ((counter & 0xff00) >> 8);
+       writeb((u8)((counter & 0xff00) >> 8), &uart->ubg1);
        /* write to CTLR: divide counter lower byte */
-       uart->ubg2 = (u8) (counter & 0x00ff);
+       writeb((u8)(counter & 0x00ff), &uart->ubg2);
 
-       uart->ucr = (UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED);
+       writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
 
        return (0);
 }
 
+static void mcf_serial_setbrg_common(uart_t *uart, int baudrate)
+{
+       u32 counter;
+
+       /* Setting up BaudRate */
+       counter = (u32) ((gd->bus_clk / 32) + (baudrate / 2));
+       counter = counter / baudrate;
+
+       /* write to CTUR: divide counter upper byte */
+       writeb(((counter & 0xff00) >> 8), &uart->ubg1);
+       /* write to CTLR: divide counter lower byte */
+       writeb((counter & 0x00ff), &uart->ubg2);
+
+       writeb(UART_UCR_RESET_RX, &uart->ucr);
+       writeb(UART_UCR_RESET_TX, &uart->ucr);
+
+       writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
+}
+
+#ifndef CONFIG_DM_SERIAL
+
+static int mcf_serial_init(void)
+{
+       uart_t *uart_base;
+       int port_idx;
+
+       uart_base = (uart_t *)CONFIG_SYS_UART_BASE;
+       port_idx = CONFIG_SYS_UART_PORT;
+
+       return mcf_serial_init_common(uart_base, port_idx, gd->baudrate);
+}
+
 static void mcf_serial_putc(const char c)
 {
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
        if (c == '\n')
                serial_putc('\r');
 
        /* Wait for last character to go. */
-       while (!(uart->usr & UART_USR_TXRDY)) ;
+       while (!(readb(&uart->usr) & UART_USR_TXRDY))
+               ;
 
-       uart->utb = c;
+       writeb(c, &uart->utb);
 }
 
 static int mcf_serial_getc(void)
 {
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
        /* Wait for a character to arrive. */
-       while (!(uart->usr & UART_USR_RXRDY)) ;
-       return uart->urb;
-}
-
-static int mcf_serial_tstc(void)
-{
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
+       while (!(readb(&uart->usr) & UART_USR_RXRDY))
+               ;
 
-       return (uart->usr & UART_USR_RXRDY);
+       return readb(&uart->urb);
 }
 
 static void mcf_serial_setbrg(void)
 {
-       volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
-       u32 counter;
-
-       /* Setting up BaudRate */
-       counter = (u32) ((gd->bus_clk / 32) + (gd->baudrate / 2));
-       counter = counter / gd->baudrate;
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
-       /* write to CTUR: divide counter upper byte */
-       uart->ubg1 = ((counter & 0xff00) >> 8);
-       /* write to CTLR: divide counter lower byte */
-       uart->ubg2 = (counter & 0x00ff);
+       mcf_serial_setbrg_common(uart, gd->baudrate);
+}
 
-       uart->ucr = UART_UCR_RESET_RX;
-       uart->ucr = UART_UCR_RESET_TX;
+static int mcf_serial_tstc(void)
+{
+       uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
 
-       uart->ucr = UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED;
+       return readb(&uart->usr) & UART_USR_RXRDY;
 }
 
 static struct serial_device mcf_serial_drv = {
@@ -128,3 +151,80 @@ __weak struct serial_device *default_serial_console(void)
 {
        return &mcf_serial_drv;
 }
+
+#endif
+
+#ifdef CONFIG_DM_SERIAL
+
+static int coldfire_serial_probe(struct udevice *dev)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+
+       return mcf_serial_init_common((uart_t *)plat->base,
+                                               plat->port, plat->baudrate);
+}
+
+static int coldfire_serial_putc(struct udevice *dev, const char ch)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)plat->base;
+
+       /* Wait for last character to go. */
+       if (!(readb(&uart->usr) & UART_USR_TXRDY))
+               return -EAGAIN;
+
+       writeb(ch, &uart->utb);
+
+       return 0;
+}
+
+static int coldfire_serial_getc(struct udevice *dev)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)(plat->base);
+
+       /* Wait for a character to arrive. */
+       if (!(readb(&uart->usr) & UART_USR_RXRDY))
+               return -EAGAIN;
+
+       return readb(&uart->urb);
+}
+
+int coldfire_serial_setbrg(struct udevice *dev, int baudrate)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)(plat->base);
+
+       mcf_serial_setbrg_common(uart, baudrate);
+
+       return 0;
+}
+
+static int coldfire_serial_pending(struct udevice *dev, bool input)
+{
+       struct coldfire_serial_platdata *plat = dev->platdata;
+       uart_t *uart = (uart_t *)(plat->base);
+
+       if (input)
+               return readb(&uart->usr) & UART_USR_RXRDY ? 1 : 0;
+       else
+               return readb(&uart->usr) & UART_USR_TXRDY ? 0 : 1;
+
+       return 0;
+}
+
+static const struct dm_serial_ops coldfire_serial_ops = {
+       .putc = coldfire_serial_putc,
+       .pending = coldfire_serial_pending,
+       .getc = coldfire_serial_getc,
+       .setbrg = coldfire_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_coldfire) = {
+       .name = "serial_coldfire",
+       .id = UCLASS_SERIAL,
+       .probe = coldfire_serial_probe,
+       .ops = &coldfire_serial_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
+#endif
index aa4abcc3d24ddc0ab011126fe9f42b13ad4c28b0..d23dc81a211edc865b516f07a1e8e3a45f9e4993 100644 (file)
@@ -26,15 +26,20 @@ struct soft_spi_platdata {
        struct gpio_desc mosi;
        struct gpio_desc miso;
        int spi_delay_us;
+       int flags;
 };
 
+#define SPI_MASTER_NO_RX        BIT(0)
+#define SPI_MASTER_NO_TX        BIT(1)
+
 struct soft_spi_priv {
        unsigned int mode;
 };
 
 static int soft_spi_scl(struct udevice *dev, int bit)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->sclk, bit);
 
@@ -43,7 +48,8 @@ static int soft_spi_scl(struct udevice *dev, int bit)
 
 static int soft_spi_sda(struct udevice *dev, int bit)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->mosi, bit);
 
@@ -52,7 +58,8 @@ static int soft_spi_sda(struct udevice *dev, int bit)
 
 static int soft_spi_cs_activate(struct udevice *dev)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->cs, 0);
        dm_gpio_set_value(&plat->sclk, 0);
@@ -63,7 +70,8 @@ static int soft_spi_cs_activate(struct udevice *dev)
 
 static int soft_spi_cs_deactivate(struct udevice *dev)
 {
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
 
        dm_gpio_set_value(&plat->cs, 0);
 
@@ -100,8 +108,9 @@ static int soft_spi_release_bus(struct udevice *dev)
 static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
                         const void *dout, void *din, unsigned long flags)
 {
-       struct soft_spi_priv *priv = dev_get_priv(dev);
-       struct soft_spi_platdata *plat = dev->platdata;
+       struct udevice *bus = dev_get_parent(dev);
+       struct soft_spi_priv *priv = dev_get_priv(bus);
+       struct soft_spi_platdata *plat = dev_get_platdata(bus);
        uchar           tmpdin  = 0;
        uchar           tmpdout = 0;
        const u8        *txd = dout;
@@ -134,14 +143,16 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
 
                if (!cpha)
                        soft_spi_scl(dev, 0);
-               soft_spi_sda(dev, tmpdout & 0x80);
+               if ((plat->flags & SPI_MASTER_NO_TX) == 0)
+                       soft_spi_sda(dev, !!(tmpdout & 0x80));
                udelay(plat->spi_delay_us);
                if (cpha)
                        soft_spi_scl(dev, 0);
                else
                        soft_spi_scl(dev, 1);
                tmpdin  <<= 1;
-               tmpdin  |= dm_gpio_get_value(&plat->miso);
+               if ((plat->flags & SPI_MASTER_NO_RX) == 0)
+                       tmpdin  |= dm_gpio_get_value(&plat->miso);
                tmpdout <<= 1;
                udelay(plat->spi_delay_us);
                if (cpha)
@@ -203,24 +214,36 @@ static int soft_spi_probe(struct udevice *dev)
        struct spi_slave *slave = dev_get_parent_priv(dev);
        struct soft_spi_platdata *plat = dev->platdata;
        int cs_flags, clk_flags;
+       int ret;
 
        cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
        clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;
-       if (gpio_request_by_name(dev, "cs-gpio", 0, &plat->cs,
+
+       if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
                                 GPIOD_IS_OUT | cs_flags) ||
-           gpio_request_by_name(dev, "sclk-gpio", 0, &plat->sclk,
-                                GPIOD_IS_OUT | clk_flags) ||
-           gpio_request_by_name(dev, "mosi-gpio", 0, &plat->mosi,
-                                GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE) ||
-           gpio_request_by_name(dev, "miso-gpio", 0, &plat->miso,
-                                GPIOD_IS_IN))
+           gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
+                                GPIOD_IS_OUT | clk_flags))
+               return -EINVAL;
+
+       ret = gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi,
+                                  GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+       if (ret)
+               plat->flags |= SPI_MASTER_NO_TX;
+
+       ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
+                                  GPIOD_IS_IN);
+       if (ret)
+               plat->flags |= SPI_MASTER_NO_RX;
+
+       if ((plat->flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX)) ==
+           (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX))
                return -EINVAL;
 
        return 0;
 }
 
 static const struct udevice_id soft_spi_ids[] = {
-       { .compatible = "u-boot,soft-spi" },
+       { .compatible = "spi-gpio" },
        { }
 };
 
index 5561f36762f9c6e45eff240c5e377920b96a0482..84b6786517cc667ebd04d6542003bac26dc85175 100644 (file)
@@ -45,12 +45,12 @@ static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
        return 0;
 }
 
-int spi_claim_bus(struct spi_slave *slave)
+int dm_spi_claim_bus(struct udevice *dev)
 {
-       struct udevice *dev = slave->dev;
        struct udevice *bus = dev->parent;
        struct dm_spi_ops *ops = spi_get_ops(bus);
        struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
+       struct spi_slave *slave = dev_get_parent_priv(dev);
        int speed;
        int ret;
 
@@ -73,9 +73,8 @@ int spi_claim_bus(struct spi_slave *slave)
        return ops->claim_bus ? ops->claim_bus(dev) : 0;
 }
 
-void spi_release_bus(struct spi_slave *slave)
+void dm_spi_release_bus(struct udevice *dev)
 {
-       struct udevice *dev = slave->dev;
        struct udevice *bus = dev->parent;
        struct dm_spi_ops *ops = spi_get_ops(bus);
 
@@ -83,10 +82,9 @@ void spi_release_bus(struct spi_slave *slave)
                ops->release_bus(dev);
 }
 
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-            const void *dout, void *din, unsigned long flags)
+int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
+               const void *dout, void *din, unsigned long flags)
 {
-       struct udevice *dev = slave->dev;
        struct udevice *bus = dev->parent;
 
        if (bus->uclass->uc_drv->id != UCLASS_SPI)
@@ -95,6 +93,22 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
 }
 
+int spi_claim_bus(struct spi_slave *slave)
+{
+       return dm_spi_claim_bus(slave->dev);
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+       dm_spi_release_bus(slave->dev);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+            const void *dout, void *din, unsigned long flags)
+{
+       return dm_spi_xfer(slave->dev, bitlen, dout, din, flags);
+}
+
 static int spi_post_bind(struct udevice *dev)
 {
        /* Scan the bus for devices */
index 2f3d43d9395c3f2b2c546eadb6cab4c91f659163..2f46d38d2b31ec9c82ca371954f45155923d7264 100644 (file)
@@ -3,5 +3,6 @@
 # SPDX-License-Identifier:      GPL-2.0+
 #
 
+obj-$(CONFIG_DM_USB) += common.o
 obj-$(CONFIG_USB_EHCI_FSL) += fsl-dt-fixup.o
 obj-$(CONFIG_USB_XHCI_FSL) += fsl-dt-fixup.o
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
new file mode 100644 (file)
index 0000000..35c2dc1
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Provides code common for host and device side USB.
+ *
+ * (C) Copyright 2016
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <linux/usb/otg.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char *const usb_dr_modes[] = {
+       [USB_DR_MODE_UNKNOWN]           = "",
+       [USB_DR_MODE_HOST]              = "host",
+       [USB_DR_MODE_PERIPHERAL]        = "peripheral",
+       [USB_DR_MODE_OTG]               = "otg",
+};
+
+enum usb_dr_mode usb_get_dr_mode(int node)
+{
+       const void *fdt = gd->fdt_blob;
+       const char *dr_mode;
+       int i;
+
+       dr_mode = fdt_getprop(fdt, node, "dr_mode", NULL);
+       if (!dr_mode) {
+               error("usb dr_mode not found\n");
+               return USB_DR_MODE_UNKNOWN;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
+               if (!strcmp(dr_mode, usb_dr_modes[i]))
+                       return i;
+
+       return USB_DR_MODE_UNKNOWN;
+}
index 7fd10e6af35e9b80f624c6f6aec04ffb906e1e1f..c01809e89e142a0de3a3b609e478e55c19f03bbb 100644 (file)
@@ -620,6 +620,13 @@ static int tegra_lcd_ofdata_to_platdata(struct udevice *dev)
 static int tegra_lcd_bind(struct udevice *dev)
 {
        struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+       const void *blob = gd->fdt_blob;
+       int node = dev->of_offset;
+       int rgb;
+
+       rgb = fdt_subnode_offset(blob, node, "rgb");
+       if ((rgb < 0) || !fdtdec_get_is_enabled(blob, rgb))
+               return -ENODEV;
 
        plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
                (1 << LCD_MAX_LOG2_BPP) / 8;
index 600a90e30922621c03c1db8c65119b7fbe85f50a..826bd852860aed9a078a75ad618f5d204cdef9f1 100644 (file)
@@ -1254,7 +1254,7 @@ int file_fat_detectfs(void)
 
 #if defined(CONFIG_CMD_IDE) || \
     defined(CONFIG_CMD_SATA) || \
-    defined(CONFIG_CMD_SCSI) || \
+    defined(CONFIG_SCSI) || \
     defined(CONFIG_CMD_USB) || \
     defined(CONFIG_MMC)
        printf("Interface:  ");
index 68b5f0b3c28248110377f2209b84c12e103f56bc..2500c10450062542b0b9ba2262adb6af6a7a5c6a 100644 (file)
@@ -206,6 +206,16 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...)
 
 struct fdtdec_phandle_args;
 
+/**
+ * gpio_xlate_offs_flags() - implementation for common use of dm_gpio_ops.xlate
+ *
+ * This routine sets the offset field to args[0] and the flags field to
+ * GPIOD_ACTIVE_LOW if the GPIO_ACTIVE_LOW flag is present in args[1].
+ *
+ */
+int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
+                         struct fdtdec_phandle_args *args);
+
 /**
  * struct struct dm_gpio_ops - Driver model GPIO operations
  *
@@ -258,12 +268,11 @@ struct dm_gpio_ops {
         *
         *   @desc->dev to @dev
         *   @desc->flags to 0
-        *   @desc->offset to the value of the first argument in args, if any,
-        *              otherwise -1 (which is invalid)
+        *   @desc->offset to 0
         *
-        * This method is optional so if the above defaults suit it can be
-        * omitted. Typical behaviour is to set up the GPIOD_ACTIVE_LOW flag
-        * in desc->flags.
+        * This method is optional and defaults to gpio_xlate_offs_flags,
+        * which will parse offset and the GPIO_ACTIVE_LOW flag in the first
+        * two arguments.
         *
         * Note that @dev is passed in as a parameter to follow driver model
         * uclass conventions, even though it is already available as
index f62467105a203f51bc0a2758f49de1cc293f5fd3..66a1c55cc8b69c256e9caf214642bbc60c439406 100644 (file)
@@ -30,6 +30,7 @@ enum if_type {
        IF_TYPE_SD,
        IF_TYPE_SATA,
        IF_TYPE_HOST,
+       IF_TYPE_SYSTEMACE,
 
        IF_TYPE_COUNT,                  /* Number of interface types */
 };
@@ -62,6 +63,11 @@ struct blk_desc {
        char            product[20+1];  /* IDE Serial no, SCSI product */
        char            revision[8+1];  /* firmware revision */
 #ifdef CONFIG_BLK
+       /*
+        * For now we have a few functions which take struct blk_desc as a
+        * parameter. This field allows them to look up the associated
+        * device. Once these functions are removed we can drop this field.
+        */
        struct udevice *bdev;
 #else
        unsigned long   (*block_read)(struct blk_desc *block_dev,
@@ -210,6 +216,25 @@ struct blk_ops {
         */
        unsigned long (*erase)(struct udevice *dev, lbaint_t start,
                               lbaint_t blkcnt);
+
+       /**
+        * select_hwpart() - select a particular hardware partition
+        *
+        * Some devices (e.g. MMC) can support partitioning at the hardware
+        * level. This is quite separate from the normal idea of
+        * software-based partitions. MMC hardware partitions must be
+        * explicitly selected. Once selected only the region of the device
+        * covered by that partition is accessible.
+        *
+        * The MMC standard provides for two boot partitions (numbered 1 and 2),
+        * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
+        *
+        * @desc:       Block device to update
+        * @hwpart:     Hardware partition number to select. 0 means the raw
+        *              device, 1 is the first partition, 2 is the second, etc.
+        * @return 0 if OK, -ve on error
+        */
+       int (*select_hwpart)(struct udevice *dev, int hwpart);
 };
 
 #define blk_get_ops(dev)       ((struct blk_ops *)(dev)->driver->ops)
@@ -269,7 +294,8 @@ int blk_next_device(struct udevice **devp);
  * @drv_name:  Driver name to use for the block device
  * @name:      Name for the device
  * @if_type:   Interface type (enum if_type_t)
- * @devnum:    Device number, specific to the interface type
+ * @devnum:    Device number, specific to the interface type, or -1 to
+ *             allocate the next available number
  * @blksz:     Block size of the device in bytes (typically 512)
  * @size:      Total size of the device in bytes
  * @devp:      the new device (which has not been probed)
@@ -278,6 +304,23 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
                      const char *name, int if_type, int devnum, int blksz,
                      lbaint_t size, struct udevice **devp);
 
+/**
+ * blk_create_devicef() - Create a new named block device
+ *
+ * @parent:    Parent of the new device
+ * @drv_name:  Driver name to use for the block device
+ * @name:      Name for the device (parent name is prepended)
+ * @if_type:   Interface type (enum if_type_t)
+ * @devnum:    Device number, specific to the interface type, or -1 to
+ *             allocate the next available number
+ * @blksz:     Block size of the device in bytes (typically 512)
+ * @size:      Total size of the device in bytes
+ * @devp:      the new device (which has not been probed)
+ */
+int blk_create_devicef(struct udevice *parent, const char *drv_name,
+                      const char *name, int if_type, int devnum, int blksz,
+                      lbaint_t size, struct udevice **devp);
+
 /**
  * blk_prepare_device() - Prepare a block device for use
  *
@@ -298,6 +341,29 @@ int blk_prepare_device(struct udevice *dev);
  */
 int blk_unbind_all(int if_type);
 
+/**
+ * blk_find_max_devnum() - find the maximum device number for an interface type
+ *
+ * Finds the last allocated device number for an interface type @if_type. The
+ * next number is safe to use for a newly allocated device.
+ *
+ * @if_type:   Interface type to scan
+ * @return maximum device number found, or -ENODEV if none, or other -ve on
+ * error
+ */
+int blk_find_max_devnum(enum if_type if_type);
+
+/**
+ * blk_select_hwpart() - select a hardware partition
+ *
+ * Select a hardware partition if the device supports it (typically MMC does)
+ *
+ * @dev:       Device to update
+ * @hwpart:    Partition number to select
+ * @return 0 if OK, -ve on error
+ */
+int blk_select_hwpart(struct udevice *dev, int hwpart);
+
 #else
 #include <errno.h>
 /*
@@ -340,6 +406,201 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
        blkcache_invalidate(block_dev->if_type, block_dev->devnum);
        return block_dev->block_erase(block_dev, start, blkcnt);
 }
+
+/**
+ * struct blk_driver - Driver for block interface types
+ *
+ * This provides access to the block devices for each interface type. One
+ * driver should be provided using U_BOOT_LEGACY_BLK() for each interface
+ * type that is to be supported.
+ *
+ * @if_typename:       Interface type name
+ * @if_type:           Interface type
+ * @max_devs:          Maximum number of devices supported
+ * @desc:              Pointer to list of devices for this interface type,
+ *                     or NULL to use @get_dev() instead
+ */
+struct blk_driver {
+       const char *if_typename;
+       enum if_type if_type;
+       int max_devs;
+       struct blk_desc *desc;
+       /**
+        * get_dev() - get a pointer to a block device given its number
+        *
+        * Each interface allocates its own devices and typically
+        * struct blk_desc is contained with the interface's data structure.
+        * There is no global numbering for block devices. This method allows
+        * the device for an interface type to be obtained when @desc is NULL.
+        *
+        * @devnum:     Device number (0 for first device on that interface,
+        *              1 for second, etc.
+        * @descp:      Returns pointer to the block device on success
+        * @return 0 if OK, -ve on error
+        */
+       int (*get_dev)(int devnum, struct blk_desc **descp);
+
+       /**
+        * select_hwpart() - Select a hardware partition
+        *
+        * Some devices (e.g. MMC) can support partitioning at the hardware
+        * level. This is quite separate from the normal idea of
+        * software-based partitions. MMC hardware partitions must be
+        * explicitly selected. Once selected only the region of the device
+        * covered by that partition is accessible.
+        *
+        * The MMC standard provides for two boot partitions (numbered 1 and 2),
+        * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
+        * Partition 0 is the main user-data partition.
+        *
+        * @desc:       Block device descriptor
+        * @hwpart:     Hardware partition number to select. 0 means the main
+        *              user-data partition, 1 is the first partition, 2 is
+        *              the second, etc.
+        * @return 0 if OK, other value for an error
+        */
+       int (*select_hwpart)(struct blk_desc *desc, int hwpart);
+};
+
+/*
+ * Declare a new U-Boot legacy block driver. New drivers should use driver
+ * model (UCLASS_BLK).
+ */
+#define U_BOOT_LEGACY_BLK(__name)                                      \
+       ll_entry_declare(struct blk_driver, __name, blk_driver)
+
+struct blk_driver *blk_driver_lookup_type(int if_type);
+
 #endif /* !CONFIG_BLK */
 
+/**
+ * blk_get_devnum_by_typename() - Get a block device by type and number
+ *
+ * This looks through the available block devices of the given type, returning
+ * the one with the given @devnum.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return point to block device descriptor, or NULL if not found
+ */
+struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum);
+
+/**
+ * blk_get_devnum_by_type() - Get a block device by type name, and number
+ *
+ * This looks up the block device type based on @if_typename, then calls
+ * blk_get_devnum_by_type().
+ *
+ * @if_typename:       Block device type name
+ * @devnum:            Device number
+ * @return point to block device descriptor, or NULL if not found
+ */
+struct blk_desc *blk_get_devnum_by_typename(const char *if_typename,
+                                           int devnum);
+
+/**
+ * blk_dselect_hwpart() - select a hardware partition
+ *
+ * This selects a hardware partition (such as is supported by MMC). The block
+ * device size may change as this effectively points the block device to a
+ * partition at the hardware level. See the select_hwpart() method above.
+ *
+ * @desc:      Block device descriptor for the device to select
+ * @hwpart:    Partition number to select
+ * @return 0 if OK, -ve on error
+ */
+int blk_dselect_hwpart(struct blk_desc *desc, int hwpart);
+
+/**
+ * blk_list_part() - list the partitions for block devices of a given type
+ *
+ * This looks up the partition type for each block device of type @if_type,
+ * then displays a list of partitions.
+ *
+ * @if_type:   Block device type
+ * @return 0 if OK, -ENODEV if there is none of that type
+ */
+int blk_list_part(enum if_type if_type);
+
+/**
+ * blk_list_devices() - list the block devices of a given type
+ *
+ * This lists each block device of the type @if_type, showing the capacity
+ * as well as type-specific information.
+ *
+ * @if_type:   Block device type
+ */
+void blk_list_devices(enum if_type if_type);
+
+/**
+ * blk_show_device() - show information about a given block device
+ *
+ * This shows the block device capacity as well as type-specific information.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return 0 if OK, -ENODEV for invalid device number
+ */
+int blk_show_device(enum if_type if_type, int devnum);
+
+/**
+ * blk_print_device_num() - show information about a given block device
+ *
+ * This is similar to blk_show_device() but returns an error if the block
+ * device type is unknown.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return 0 if OK, -ENODEV for invalid device number, -ENOENT if the block
+ * device is not connected
+ */
+int blk_print_device_num(enum if_type if_type, int devnum);
+
+/**
+ * blk_print_part_devnum() - print the partition information for a device
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @return 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if
+ * the interface type is not supported, other -ve on other error
+ */
+int blk_print_part_devnum(enum if_type if_type, int devnum);
+
+/**
+ * blk_read_devnum() - read blocks from a device
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @blkcnt:    Number of blocks to read
+ * @buffer:    Address to write data to
+ * @return number of blocks read, or -ve error number on error
+ */
+ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                     lbaint_t blkcnt, void *buffer);
+
+/**
+ * blk_write_devnum() - write blocks to a device
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @blkcnt:    Number of blocks to write
+ * @buffer:    Address to read data from
+ * @return number of blocks written, or -ve error number on error
+ */
+ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
+                      lbaint_t blkcnt, const void *buffer);
+
+/**
+ * blk_select_hwpart_devnum() - select a hardware partition
+ *
+ * This is similar to blk_dselect_hwpart() but it looks up the interface and
+ * device number.
+ *
+ * @if_type:   Block device type
+ * @devnum:    Device number
+ * @hwpart:    Partition number to select
+ * @return 0 if OK, -ve on error
+ */
+int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
+
 #endif
index ed502a191ff6cebc9b077d27e63c6cf8d0c6a769..b5fd6c68e8fefbde16fcff2f9c8f2cf91222be5e 100644 (file)
@@ -45,7 +45,7 @@
 #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_CMD_SCSI                /* SCSI Support                 */
+#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_UBI         /* UBI Support                  */
index 7f673448c92d0cb71d894b203e05bc9ba3df9482..5a8d7f270867c8bad06145d6c5f393515060e11d 100644 (file)
        BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_CMD_SATA
 #endif
 
-#ifdef CONFIG_CMD_SCSI
+#ifdef CONFIG_SCSI
 #define BOOTENV_RUN_SCSI_INIT "run scsi_init; "
 #define BOOTENV_SET_SCSI_NEED_INIT "setenv scsi_need_init; "
 #define BOOTENV_SHARED_SCSI \
 #define BOOTENV_SET_SCSI_NEED_INIT
 #define BOOTENV_SHARED_SCSI
 #define BOOTENV_DEV_SCSI \
-       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
+       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_SCSI
 #define BOOTENV_DEV_NAME_SCSI \
-       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
+       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_SCSI
 #endif
 
 #ifdef CONFIG_CMD_IDE
index 266619186643f82abd7bffd1d2343ce7eade19eb..2ad54b7bf6611106b770d0f3b495ba7f4ce32a8f 100644 (file)
@@ -45,7 +45,7 @@
 /* Rather than repeat this expression each time, add a define for it */
 #if defined(CONFIG_CMD_IDE) || \
        defined(CONFIG_CMD_SATA) || \
-       defined(CONFIG_CMD_SCSI) || \
+       defined(CONFIG_SCSI) || \
        defined(CONFIG_CMD_USB) || \
        defined(CONFIG_CMD_PART) || \
        defined(CONFIG_CMD_GPT) || \
index 26d92daff1d96f45b2a497bb3957ef8d2950e3b2..f3036c1dc2638a4ed3006d0b3f42b0fe7f2e022c 100644 (file)
@@ -373,7 +373,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #if defined(CONFIG_PCI)
     #define CONFIG_CMD_PCI
-    #define CONFIG_CMD_SCSI
+    #define CONFIG_SCSI
 #endif
 
 /*
index 8c4e5e21ca9814eff22d40eb9fdc808bffd5f78c..bb7f38e34a530e27b8eba9fb6d6421fde39dc88c 100644 (file)
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 /*
index e7f01d00d1d7663879944dde01a69f1b477e6e2f..f6d45a9e40a8ff8183e37f40e8ff0460e90dc242 100644 (file)
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 #define CONFIG_WATCHDOG                        /* watchdog enabled */
index 2f94c8214eb0d6ed304a66d195594245d177bc38..9b2623c72620a54ec23b585286f5fc4b477a6bd9 100644 (file)
@@ -354,8 +354,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup */
 
-#undef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
-
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 
 #undef CONFIG_EEPRO100
@@ -612,7 +610,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #if defined(CONFIG_PCI)
     #define CONFIG_CMD_PCI
-    #define CONFIG_CMD_SCSI
+    #define CONFIG_SCSI
 #endif
 
 #undef CONFIG_WATCHDOG                 /* watchdog disabled */
index 4bd06a45bf6dbd1b24b4c657015b51d4a734352b..4506d86eee7671a3d2c91f6cc0a8f1a07333f06c 100644 (file)
@@ -43,7 +43,7 @@
 #define CONFIG_CMD_EEPROM
 #define CONFIG_CMD_REGINFO
 #define CONFIG_CMD_FDC
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_CMD_DATE
 #define CONFIG_CMD_SDRAM
 #define CONFIG_CMD_SAVES
index 32d7d4d0bd0aa015a345203607a7bf3373fad525..d53b0fdd89c44a8e866d46a76cc36761a5596eaf 100644 (file)
@@ -75,7 +75,7 @@
 
 /* SATA */
 #define CONFIG_BOARD_LATE_INIT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 9b13aa6b5ac309b37ed894159fb56dbf75e6c2e6..ac6103c0665ef60561ef5e64bf29a55f093ee852 100644 (file)
@@ -60,7 +60,7 @@
 #define CONFIG_SPL_SATA_BOOT_DEVICE            0
 #define CONFIG_SYS_SATA_FAT_BOOT_PARTITION     1
 
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index d84dde39c104ac4bac910cdda1484d5f0b44752b..3539a62790f75508aeb4652787bf5a156f280681 100644 (file)
@@ -27,7 +27,7 @@
 #define CONFIG_SYS_NO_FLASH            /* Declare no flash (NOR/SPI) */
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 
 /* I2C */
 #define CONFIG_SYS_I2C
index 79b6c0995120d506867ee218d0c07c9eb41ffe82..8a0cd66cd0fac6fe4c884a2a3a42a7ee5bbc0565 100644 (file)
 
 /* SATA */
 #define CONFIG_BOARD_LATE_INIT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index 6dd0b32daef964a8107d14c130d392647ba327b1..95e46c558d2c1722fbd983f73b0b97ef9b1c777b 100644 (file)
@@ -18,7 +18,7 @@
 #undef CONFIG_VIDEO
 #undef CONFIG_CFB_CONSOLE
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_CMD_SCSI
+#undef CONFIG_SCSI
 #undef CONFIG_INTEL_ICH6_GPIO
 #undef CONFIG_USB_EHCI_PCI
 
index 2f1f6d44554581fed366d253438645ff4fae9531..40f7fba833b1d7408e4202dea8b88dbde29fe8a1 100644 (file)
@@ -29,7 +29,7 @@
 
 /* SATA is not supported in Quark SoC */
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_CMD_SCSI
+#undef CONFIG_SCSI
 
 /* Video is not supported in Quark SoC */
 #undef CONFIG_VIDEO
index 3bce12bbb85713b9d7f154f081890cd30e3096c8..5cefddc2e0eedbdafa6ca099b415b2648e8522d9 100644 (file)
@@ -51,7 +51,7 @@
 /*
  * Command line configuration.
  */
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 
 #define CONFIG_BOOT_RETRY_TIME         -1
 #define CONFIG_RESET_TO_RETRY
index d71a229c6133550f03623226a246265b82c2526b..af1f73dbaa8ba260fc9a889787d3649c6722f0c0 100644 (file)
@@ -108,7 +108,7 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_DOS_PARTITION
 #define CONFIG_BOARD_LATE_INIT
 
index 2d7567f394fca161701d77500d295434cc5f7efe..f8c9e51ae7fe547914db21ffe25e38ae96b99f4f 100644 (file)
@@ -44,7 +44,7 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_DOS_PARTITION
 #define CONFIG_BOARD_LATE_INIT
 
index 5bec5099af78b463b9dfe6315b9726ebdbf2a20c..4577919ca121492537fe98c3d961ca2d5d19a066 100644 (file)
@@ -62,7 +62,7 @@ unsigned long get_board_sys_clk(void);
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_DOS_PARTITION
 #define CONFIG_BOARD_LATE_INIT
 
index 86cefa3b8f88e5094b502f5fd0e66ff716e20f89..4ddc49211267235ddda14f26919e03c4bfc731b2 100644 (file)
 /* Max time to hold reset on this board, see doc/README.omap-reset-time */
 #define CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC       16296
 
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_LIBATA
 #define CONFIG_SCSI_AHCI
 #define CONFIG_SCSI_AHCI_PLAT
index b0d2ffe5b4c842b9086072c2463abb00d35c2eb7..476d37d4bce93ce9abc0ca5021f22118b099526f 100644 (file)
@@ -43,7 +43,7 @@
 #define CONFIG_ATAPI
 
 #undef CONFIG_SCSI_AHCI
-#undef CONFIG_CMD_SCSI
+#undef CONFIG_SCSI
 #else
 #define CONFIG_SCSI_DEV_LIST           \
        {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_AHCI}
index 9790a14b02b0fce4f0f25e851311ea9c1b563ba4..23a0c40ca528a8377416d4036f6d46ffdeff29e2 100644 (file)
 #define CONFIG_CMD_LZMADEC
 #define CONFIG_CMD_DATE
 
+#define CONFIG_CMD_IDE
+#define CONFIG_SYS_IDE_MAXBUS          1
+#define CONFIG_SYS_ATA_IDE0_OFFSET     0
+#define CONFIG_SYS_IDE_MAXDEVICE       2
+#define CONFIG_SYS_ATA_BASE_ADDR       0x100
+#define CONFIG_SYS_ATA_DATA_OFFSET     0
+#define CONFIG_SYS_ATA_REG_OFFSET      1
+#define CONFIG_SYS_ATA_ALT_OFFSET      2
+#define CONFIG_SYS_ATA_STRIDE          4
+
+#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
+#define CONFIG_SYS_SYSTEMACE_WIDTH     16
+#define CONFIG_SYS_SYSTEMACE_BASE      0
+
+#define CONFIG_GENERIC_MMC
+
 #endif
index a7c7aef71ab9414cb9c43fdd38a47cd520a0430b..c9970f1f3e2a103f9450c79ba775b8e456310224 100644 (file)
 
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup */
 
-#undef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
-
 #define CONFIG_PCI_PNP                 /* do pci plug-and-play */
 
 #undef CONFIG_EEPRO100
index 2406115e3e21774837af1c953ead070008807664..ac2d93114b53567e1ac47bdea0d6982fa20c7ee2 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_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 #define CONFIG_SETUP_MEMORY_TAGS
index a2822e01146f938440d93bcfe8988d4f053b2cbb..b79f47baf3fefa52adf8c4e1cb23a942ca913ffd 100644 (file)
 #define CONFIG_CMD_IRQ
 #define CONFIG_CMD_PCI
 #define CONFIG_CMD_GETTIME
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 
 #define CONFIG_CMD_ZBOOT
 
index 060bca985e058d4457c4941ab2dee5a79468dd80..6b8e3ea8657d453d20277f4eb72c59cb20ce376a 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_CMD_SCSI
+#define CONFIG_SCSI
 #endif
 
 #define CONFIG_SYS_BOOTM_LEN   (60 * 1024 * 1024)
index 8970fc015c7eb1158644110338d8e6f181181d1d..e9a8ec72c90eba36d93b365e9afe49c2298df7a5 100644 (file)
@@ -41,6 +41,9 @@ struct driver_info;
 /* Device is bound */
 #define DM_FLAG_BOUND                  (1 << 6)
 
+/* Device name is allocated and should be freed on unbind() */
+#define DM_NAME_ALLOCED                        (1 << 7)
+
 /**
  * struct udevice - An instance of a driver
  *
@@ -523,6 +526,9 @@ bool device_is_last_sibling(struct udevice *dev);
  * this is unnecessary but for probed devices which don't get a useful name
  * this function can be helpful.
  *
+ * The name is allocated and will be freed automatically when the device is
+ * unbound.
+ *
  * @dev:       Device to update
  * @name:      New name (this string is allocated new memory and attached to
  *             the device)
@@ -531,6 +537,16 @@ bool device_is_last_sibling(struct udevice *dev);
  */
 int device_set_name(struct udevice *dev, const char *name);
 
+/**
+ * device_set_name_alloced() - note that a device name is allocated
+ *
+ * This sets the DM_NAME_ALLOCED flag for the device, so that when it is
+ * unbound the name will be freed. This avoids memory leaks.
+ *
+ * @dev:       Device to update
+ */
+void device_set_name_alloced(struct udevice *dev);
+
 /**
  * device_is_on_pci_bus - Test if a device is on a PCI bus
  *
diff --git a/include/dm/platform_data/serial_coldfire.h b/include/dm/platform_data/serial_coldfire.h
new file mode 100644 (file)
index 0000000..5d86456
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015  Angelo Dureghello <angelo@sysam.it>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __serial_coldfire_h
+#define __serial_coldfire_h
+
+/*
+ * struct coldfire_serial_platdata - information about a coldfire port
+ *
+ * @base:               Uart port base register address
+ * @port:               Uart port index, for cpu with pinmux for uart / gpio
+ * baudrtatre:          Uart port baudrate
+ */
+struct coldfire_serial_platdata {
+       unsigned long base;
+       int port;
+       int baudrate;
+};
+
+#endif /* __serial_coldfire_h */
index cbf9b2ca235190714b81fc1c07460d997e5e95d5..a5cf6e201c0b1f1de0d74f3de004eef2c1f0db98 100644 (file)
@@ -26,11 +26,11 @@ enum uclass_id {
 
        /* U-Boot uclasses start here - in alphabetical order */
        UCLASS_ADC,             /* Analog-to-digital converter */
+       UCLASS_AHCI,            /* SATA disk controller */
        UCLASS_BLK,             /* Block device */
        UCLASS_CLK,             /* Clock source, e.g. used by peripherals */
        UCLASS_CPU,             /* CPU, typically part of an SoC */
        UCLASS_CROS_EC,         /* Chrome OS EC */
-       UCLASS_DISK,            /* Disk controller, e.g. SATA */
        UCLASS_DISPLAY,         /* Display (e.g. DisplayPort, HDMI) */
        UCLASS_DMA,             /* Direct Memory Access */
        UCLASS_RAM,             /* RAM controller */
index a4e65cf2a9420dbc7523c6d2ae9b91ce6c87209e..9b0a4a96fa5d64a5598e498aa2bd7b649004fdb6 100644 (file)
@@ -34,10 +34,18 @@ void ide_led(uchar led, uchar status);
 
 void ide_init(void);
 struct blk_desc;
+struct udevice;
+#ifdef CONFIG_BLK
+ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+              void *buffer);
+ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+               const void *buffer);
+#else
 ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
               void *buffer);
 ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
                const void *buffer);
+#endif
 
 #ifdef CONFIG_IDE_PREINIT
 int ide_preinit(void);
index 9bd1f167abe5ea3c4a9d61df1338af7fb6f28b81..e4ceb6180537ed62ce4ae96f60ca56268ab9f5e8 100644 (file)
 #define writew(val, addr)      iotrace_writew(val, (const void *)(addr))
 
 #undef readb
-#define readb(addr)    iotrace_readb((const void *)(addr))
+#define readb(addr)    iotrace_readb((const void *)(uintptr_t)addr)
 
 #undef writeb
-#define writeb(val, addr)      iotrace_writeb(val, (const void *)(addr))
+#define writeb(val, addr) \
+       iotrace_writeb(val, (const void *)(uintptr_t)addr)
 
 #endif
 
index 7ec5550f4bfaed064b175f90ddbb5c8aea430b69..8f8ac6aeefe3ea72c9ce191ee800aeb1426cabbb 100644 (file)
@@ -17,4 +17,13 @@ enum usb_dr_mode {
        USB_DR_MODE_OTG,
 };
 
+/**
+ * usb_get_dr_mode() - Get dual role mode for given device
+ * @node: Node offset to the given device
+ *
+ * The function gets phy interface string from property 'dr_mode',
+ * and returns the correspondig enum usb_dr_mode
+ */
+enum usb_dr_mode usb_get_dr_mode(int node);
+
 #endif /* __LINUX_USB_OTG_H */
index cdb56e7ac14eaaeef3d952876756beb6359ad0bb..a5c6573ddd6efcf7fbd76903089b5c06e278cefd 100644 (file)
@@ -344,7 +344,9 @@ struct mmc_config {
 
 /* TODO struct mmc should be in mmc_private but it's hard to fix right now */
 struct mmc {
+#ifndef CONFIG_BLK
        struct list_head link;
+#endif
        const struct mmc_config *cfg;   /* provided configuration */
        uint version;
        void *priv;
@@ -376,11 +378,16 @@ struct mmc {
        u64 capacity_gp[4];
        u64 enh_user_start;
        u64 enh_user_size;
+#ifndef CONFIG_BLK
        struct blk_desc block_dev;
+#endif
        char op_cond_pending;   /* 1 if we are waiting on an op_cond command */
        char init_in_progress;  /* 1 if we have done mmc_start_init() */
        char preinit;           /* start init as early as possible */
        int ddr_mode;
+#ifdef CONFIG_DM_MMC
+       struct udevice *dev;    /* Device for this MMC controller */
+#endif
 };
 
 struct mmc_hwpart_conf {
@@ -406,7 +413,29 @@ enum mmc_hwpart_conf_mode {
 
 int mmc_register(struct mmc *mmc);
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
+
+/**
+ * mmc_bind() - Set up a new MMC device ready for probing
+ *
+ * A child block device is bound with the IF_TYPE_MMC interface type. This
+ * allows the device to be used with CONFIG_BLK
+ *
+ * @dev:       MMC device to set up
+ * @mmc:       MMC struct
+ * @cfg:       MMC configuration
+ * @return 0 if OK, -ve on error
+ */
+int mmc_bind(struct udevice *dev, struct mmc *mmc,
+            const struct mmc_config *cfg);
 void mmc_destroy(struct mmc *mmc);
+
+/**
+ * mmc_unbind() - Unbind a MMC device's child block device
+ *
+ * @dev:       MMC device
+ * @return 0 if OK, -ve on error
+ */
+int mmc_unbind(struct udevice *dev);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
@@ -415,7 +444,6 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
-int mmc_switch_part(int dev_num, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
                      enum mmc_hwpart_conf_mode mode);
 int mmc_getcd(struct mmc *mmc);
@@ -498,4 +526,12 @@ int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported);
 #define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
 #endif
 
+/**
+ * mmc_get_blk_desc() - Get the block descriptor for an MMC device
+ *
+ * @mmc:       MMC device
+ * @return block device if found, else NULL
+ */
+struct blk_desc *mmc_get_blk_desc(struct mmc *mmc);
+
 #endif /* _MMC_H_ */
index e3811c68de8a31c3bf3daddad1d87f9e3187334a..226b5be9df26384818e0299fde0d5f0e9d782646 100644 (file)
@@ -12,7 +12,6 @@
 
 struct block_drvr {
        char *name;
-       struct blk_desc* (*get_dev)(int dev);
        int (*select_hwpart)(int dev_num, int hwpart);
 };
 
@@ -73,32 +72,8 @@ typedef struct disk_partition {
  *        error occurred.
  */
 struct blk_desc *blk_get_dev(const char *ifname, int dev);
-struct blk_desc *ide_get_dev(int dev);
-struct blk_desc *sata_get_dev(int dev);
-struct blk_desc *scsi_get_dev(int dev);
-struct blk_desc *usb_stor_get_dev(int dev);
-struct blk_desc *mmc_get_dev(int dev);
 
-/**
- * mmc_select_hwpart() - Select the MMC hardware partiion on an MMC device
- *
- * MMC devices can support partitioning at the hardware level. This is quite
- * separate from the normal idea of software-based partitions. MMC hardware
- * partitions must be explicitly selected. Once selected only the region of
- * the device covered by that partition is accessible.
- *
- * The MMC standard provides for two boot partitions (numbered 1 and 2),
- * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
- *
- * @dev_num:   Block device number (struct blk_desc->dev value)
- * @hwpart:    Hardware partition number to select. 0 means the raw device,
- *             1 is the first partition, 2 is the second, etc.
- * @return 0 if OK, other value for an error
- */
-int mmc_select_hwpart(int dev_num, int hwpart);
-struct blk_desc *systemace_get_dev(int dev);
 struct blk_desc *mg_disk_get_dev(int dev);
-struct blk_desc *host_get_dev(int dev);
 int host_get_dev_err(int dev, struct blk_desc **blk_devp);
 
 /* disk/part.c */
@@ -175,15 +150,7 @@ extern const struct block_drvr block_drvr[];
 #else
 static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
 { return NULL; }
-static inline struct blk_desc *ide_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *sata_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *scsi_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *usb_stor_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *mmc_get_dev(int dev) { return NULL; }
-static inline int mmc_select_hwpart(int dev_num, int hwpart) { return -1; }
-static inline struct blk_desc *systemace_get_dev(int dev) { return NULL; }
 static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; }
-static inline struct blk_desc *host_get_dev(int dev) { return NULL; }
 
 static inline int part_get_info(struct blk_desc *dev_desc, int part,
                                disk_partition_t *info) { return -1; }
index 4b88d3986e78cea0e3bf117a5b6351f88c011146..ca96fa4b31b6cda4cdbbca9b0fcbe25406f6e5b7 100644 (file)
@@ -612,6 +612,58 @@ int sandbox_spi_get_emul(struct sandbox_state *state,
                         struct udevice *bus, struct udevice *slave,
                         struct udevice **emulp);
 
+/**
+ * Claim the bus and prepare it for communication with a given slave.
+ *
+ * This must be called before doing any transfers with a SPI slave. It
+ * will enable and initialize any SPI hardware as necessary, and make
+ * sure that the SCK line is in the correct idle state. It is not
+ * allowed to claim the same bus for several slaves without releasing
+ * the bus in between.
+ *
+ * @dev:       The SPI slave device
+ *
+ * Returns: 0 if the bus was claimed successfully, or a negative value
+ * if it wasn't.
+ */
+int dm_spi_claim_bus(struct udevice *dev);
+
+/**
+ * Release the SPI bus
+ *
+ * This must be called once for every call to dm_spi_claim_bus() after
+ * all transfers have finished. It may disable any SPI hardware as
+ * appropriate.
+ *
+ * @slave:     The SPI slave device
+ */
+void dm_spi_release_bus(struct udevice *dev);
+
+/**
+ * SPI transfer
+ *
+ * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
+ * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
+ *
+ * The source of the outgoing bits is the "dout" parameter and the
+ * destination of the input bits is the "din" parameter.  Note that "dout"
+ * and "din" can point to the same memory location, in which case the
+ * input data overwrites the output data (since both are buffered by
+ * temporary variables, this is OK).
+ *
+ * dm_spi_xfer() interface:
+ * @dev:       The SPI slave device which will be sending/receiving the data.
+ * @bitlen:    How many bits to write and read.
+ * @dout:      Pointer to a string of bits to send out.  The bits are
+ *             held in a byte array and are sent MSB first.
+ * @din:       Pointer to a string of bits that will be filled in.
+ * @flags:     A bitwise combination of SPI_XFER_* flags.
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
+               const void *dout, void *din, unsigned long flags);
+
 /* Access the operations for a SPI device */
 #define spi_get_ops(dev)       ((struct dm_spi_ops *)(dev)->driver->ops)
 #define spi_emul_get_ops(dev)  ((struct dm_spi_emul_ops *)(dev)->driver->ops)
diff --git a/include/systemace.h b/include/systemace.h
deleted file mode 100644 (file)
index 3b6ec7d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __SYSTEMACE_H
-#define __SYSTEMACE_H
-/*
- * Copyright (c) 2004 Picture Elements, Inc.
- *    Stephen Williams (steve@picturel.com)
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#ifdef CONFIG_SYSTEMACE
-
-# include  <part.h>
-
-struct blk_desc *systemace_get_dev(int dev);
-
-#endif /* CONFIG_SYSTEMACE */
-#endif /* __SYSTEMACE_H */
index 5adad368380897eadae2ac6d39b7934aefa1bd82..02a0ccdd77b370b4bd62d858a2c797e926fd03f2 100644 (file)
@@ -228,7 +228,6 @@ int board_usb_cleanup(int index, enum usb_init_type init);
 #ifdef CONFIG_USB_STORAGE
 
 #define USB_MAX_STOR_DEV 7
-struct blk_desc *usb_stor_get_dev(int index);
 int usb_stor_scan(int mode);
 int usb_stor_info(void);
 
index 28e5b7fce59ce1b4470b4c82fd7e5d5c09899b52..075fd3401450d41320353d2db42ad9fdb03ccc59 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <blk.h>
 #include <efi_loader.h>
 #include <inttypes.h>
 #include <part.h>
@@ -142,7 +143,7 @@ static const struct efi_block_io block_io_disk_template = {
 };
 
 static void efi_disk_add_dev(char *name,
-                            const struct block_drvr *cur_drvr,
+                            const struct blk_driver *cur_drvr,
                             const struct blk_desc *desc,
                             int dev_index,
                             lbaint_t offset)
@@ -160,7 +161,7 @@ static void efi_disk_add_dev(char *name,
        diskobj->parent.protocols[1].open = efi_disk_open_dp;
        diskobj->parent.handle = diskobj;
        diskobj->ops = block_io_disk_template;
-       diskobj->ifname = cur_drvr->name;
+       diskobj->ifname = cur_drvr->if_typename;
        diskobj->dev_index = dev_index;
        diskobj->offset = offset;
 
@@ -189,7 +190,7 @@ static void efi_disk_add_dev(char *name,
 }
 
 static int efi_disk_create_eltorito(struct blk_desc *desc,
-                                   const struct block_drvr *cur_drvr,
+                                   const struct blk_driver *cur_drvr,
                                    int diskid)
 {
        int disks = 0;
@@ -202,8 +203,8 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
                return 0;
 
        while (!part_get_info(desc, part, &info)) {
-               snprintf(devname, sizeof(devname), "%s%d:%d", cur_drvr->name,
-                        diskid, part);
+               snprintf(devname, sizeof(devname), "%s%d:%d",
+                        cur_drvr->if_typename, diskid, part);
                efi_disk_add_dev(devname, cur_drvr, desc, diskid, info.start);
                part++;
                disks++;
@@ -222,25 +223,29 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
  */
 int efi_disk_register(void)
 {
-       const struct block_drvr *cur_drvr;
-       int i;
+       const struct blk_driver *cur_drvr;
+       int i, if_type;
        int disks = 0;
 
        /* Search for all available disk devices */
-       for (cur_drvr = block_drvr; cur_drvr->name; cur_drvr++) {
-               printf("Scanning disks on %s...\n", cur_drvr->name);
+       for (if_type = 0; if_type < IF_TYPE_COUNT; if_type++) {
+               cur_drvr = blk_driver_lookup_type(if_type);
+               if (!cur_drvr)
+                       continue;
+
+               printf("Scanning disks on %s...\n", cur_drvr->if_typename);
                for (i = 0; i < 4; i++) {
                        struct blk_desc *desc;
                        char devname[32] = { 0 }; /* dp->str is u16[32] long */
 
-                       desc = blk_get_dev(cur_drvr->name, i);
+                       desc = blk_get_devnum_by_type(if_type, i);
                        if (!desc)
                                continue;
                        if (desc->type == DEV_TYPE_UNKNOWN)
                                continue;
 
                        snprintf(devname, sizeof(devname), "%s%d",
-                                cur_drvr->name, i);
+                                cur_drvr->if_typename, i);
                        efi_disk_add_dev(devname, cur_drvr, desc, i, 0);
                        disks++;
 
index f4ea32e83e514095d277046bf8a0d249f8235c6a..012bf4cab56ef43fbfa605c7bac9a32eebd4baa1 100644 (file)
@@ -83,12 +83,12 @@ static int dm_test_blk_usb(struct unit_test_state *uts)
        ut_asserteq_ptr(usb_dev, dev_get_parent(dev));
 
        /* Check we have one block device for each mass storage device */
-       ut_asserteq(3, count_blk_devices());
+       ut_asserteq(4, count_blk_devices());
 
        /* Now go around again, making sure the old devices were unbound */
        ut_assertok(usb_stop());
        ut_assertok(usb_init());
-       ut_asserteq(3, count_blk_devices());
+       ut_asserteq(4, count_blk_devices());
        ut_assertok(usb_stop());
 
        return 0;
index 046142322da2c70f697f84bd61087f95a5e2dcbb..5bca4b79d597b43fe2ea0ffde788d422e5b2fa93 100644 (file)
@@ -25,3 +25,22 @@ static int dm_test_mmc_base(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_mmc_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int dm_test_mmc_blk(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+       struct blk_desc *dev_desc;
+       char cmp[1024];
+
+       ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
+       ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
+
+       /* Read a few blocks and look for the string we expect */
+       ut_asserteq(512, dev_desc->blksz);
+       memset(cmp, '\0', sizeof(cmp));
+       ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
+       ut_assertok(strcmp(cmp, "this is a test"));
+
+       return 0;
+}
+DM_TEST(dm_test_mmc_blk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
index 4705d2644b8f075da0a83802bbb42a908fde8e0b..26755c5955e21c5f0cb89ba59cb1c890fa011502 100644 (file)
@@ -898,6 +898,48 @@ when using the -b flag. For example:
 will build commits in us-buildman that are not in upstream/master.
 
 
+Building Faster
+===============
+
+By default, buildman executes 'make mrproper' prior to building the first
+commit for each board. This causes everything to be built from scratch. If you
+trust the build system's incremental build capabilities, you can pass the -I
+flag to skip the 'make mproper' invocation, which will reduce the amount of
+work 'make' does, and hence speed up the build. This flag will speed up any
+buildman invocation, since it reduces the amount of work done on any build.
+
+One possible application of buildman is as part of a continual edit, build,
+edit, build, ... cycle; repeatedly applying buildman to the same change or
+series of changes while making small incremental modifications to the source
+each time. This provides quick feedback regarding the correctness of recent
+modifications. In this scenario, buildman's default choice of build directory
+causes more build work to be performed than strictly necessary.
+
+By default, each buildman thread uses a single directory for all builds. When a
+thread builds multiple boards, the configuration built in this directory will
+cycle through various different configurations, one per board built by the
+thread. Variations in the configuration will force a rebuild of affected source
+files when a thread switches between boards. Ideally, such buildman-induced
+rebuilds would not happen, thus allowing the build to operate as efficiently as
+the build system and source changes allow. buildman's -P flag may be used to
+enable this; -P causes each board to be built in a separate (board-specific)
+directory, thus avoiding any buildman-induced configuration changes in any
+build directory.
+
+U-Boot's build system embeds information such as a build timestamp into the
+final binary. This information varies each time U-Boot is built. This causes
+various files to be rebuilt even if no source changes are made, which in turn
+requires that the final U-Boot binary be re-linked. This unnecessary work can
+be avoided by turning off the timestamp feature. This can be achieved by
+setting the SOURCE_DATE_EPOCH environment variable to 0.
+
+Combining all of these options together yields the command-line shown below.
+This will provide the quickest possible feedback regarding the current content
+of the source tree, thus allowing rapid tested evolution of the code.
+
+    SOURCE_DATE_EPOCH=0 ./tools/buildman/buildman -I -P tegra
+
+
 Other options
 =============
 
index 141bf6469136aa7f5f18bb6e07701dfcfd5d135d..8ec3551729015ed7a6b2a3cb9bea134251ced4f6 100644 (file)
@@ -205,7 +205,8 @@ class Builder:
 
     def __init__(self, toolchains, base_dir, git_dir, num_threads, num_jobs,
                  gnu_make='make', checkout=True, show_unknown=True, step=1,
-                 no_subdirs=False, full_path=False, verbose_build=False):
+                 no_subdirs=False, full_path=False, verbose_build=False,
+                 incremental=False, per_board_out_dir=False):
         """Create a new Builder object
 
         Args:
@@ -224,6 +225,10 @@ class Builder:
             full_path: Return the full path in CROSS_COMPILE and don't set
                 PATH
             verbose_build: Run build with V=1 and don't use 'make -s'
+            incremental: Always perform incremental builds; don't run make
+                mrproper when configuring
+            per_board_out_dir: Build in a separate persistent directory per
+                board rather than a thread-specific directory
         """
         self.toolchains = toolchains
         self.base_dir = base_dir
@@ -263,7 +268,8 @@ class Builder:
         self.queue = Queue.Queue()
         self.out_queue = Queue.Queue()
         for i in range(self.num_threads):
-            t = builderthread.BuilderThread(self, i)
+            t = builderthread.BuilderThread(self, i, incremental,
+                    per_board_out_dir)
             t.setDaemon(True)
             t.start()
             self.threads.append(t)
index cf25bb8f1a7e325192b8410d3081cea27c864bf0..c512d3b521f755d0945030e4cb6cc958170c24a9 100644 (file)
@@ -80,11 +80,13 @@ class BuilderThread(threading.Thread):
         thread_num: Our thread number (0-n-1), used to decide on a
                 temporary directory
     """
-    def __init__(self, builder, thread_num):
+    def __init__(self, builder, thread_num, incremental, per_board_out_dir):
         """Set up a new builder thread"""
         threading.Thread.__init__(self)
         self.builder = builder
         self.thread_num = thread_num
+        self.incremental = incremental
+        self.per_board_out_dir = per_board_out_dir
 
     def Make(self, commit, brd, stage, cwd, *args, **kwargs):
         """Run 'make' on a particular commit and board.
@@ -136,7 +138,11 @@ class BuilderThread(threading.Thread):
         if self.builder.in_tree:
             out_dir = work_dir
         else:
-            out_dir = os.path.join(work_dir, 'build')
+            if self.per_board_out_dir:
+                out_rel_dir = os.path.join('..', brd.target)
+            else:
+                out_rel_dir = 'build'
+            out_dir = os.path.join(work_dir, out_rel_dir)
 
         # Check if the job was already completed last time
         done_file = self.builder.GetDoneFile(commit_upto, brd.target)
@@ -197,12 +203,12 @@ class BuilderThread(threading.Thread):
                         #
                         # Symlinks can confuse U-Boot's Makefile since
                         # we may use '..' in our path, so remove them.
-                        work_dir = os.path.realpath(work_dir)
-                        args.append('O=%s/build' % work_dir)
+                        out_dir = os.path.realpath(out_dir)
+                        args.append('O=%s' % out_dir)
                         cwd = None
                         src_dir = os.getcwd()
                     else:
-                        args.append('O=build')
+                        args.append('O=%s' % out_rel_dir)
                 if self.builder.verbose_build:
                     args.append('V=1')
                 else:
@@ -215,9 +221,11 @@ class BuilderThread(threading.Thread):
 
                 # If we need to reconfigure, do that now
                 if do_config:
-                    result = self.Make(commit, brd, 'mrproper', cwd,
-                            'mrproper', *args, env=env)
-                    config_out = result.combined
+                    config_out = ''
+                    if not self.incremental:
+                        result = self.Make(commit, brd, 'mrproper', cwd,
+                                'mrproper', *args, env=env)
+                        config_out += result.combined
                     result = self.Make(commit, brd, 'config', cwd,
                             *(args + config_args), env=env)
                     config_out += result.combined
index 8341ab145cfa1f5eb1776ef1a821cd2ab95e8972..3e3bd63e32c771e6439faa803ad0e7dc9cb520f8 100644 (file)
@@ -49,6 +49,8 @@ def ParseArgs():
     parser.add_option('-i', '--in-tree', dest='in_tree',
           action='store_true', default=False,
           help='Build in the source tree instead of a separate directory')
+    parser.add_option('-I', '--incremental', action='store_true',
+          default=False, help='Do not run make mrproper (when reconfiguring)')
     parser.add_option('-j', '--jobs', dest='jobs', type='int',
           default=None, help='Number of jobs to run at once (passed to make)')
     parser.add_option('-k', '--keep-outputs', action='store_true',
@@ -70,6 +72,8 @@ def ParseArgs():
           default=False, help='Do a rough build, with limited warning resolution')
     parser.add_option('-p', '--full-path', action='store_true',
           default=False, help="Use full toolchain path in CROSS_COMPILE")
+    parser.add_option('-P', '--per-board-out-dir', action='store_true',
+          default=False, help="Use an O= (output) directory per board rather than per thread")
     parser.add_option('-s', '--summary', action='store_true',
           default=False, help='Show a build summary')
     parser.add_option('-S', '--show-sizes', action='store_true',
index c2c54bf0e81b63676279391cec512358ee10bdcd..aeb128a6a3e92cd5b0649ff6967d0f3bd67a3eeb 100644 (file)
@@ -250,7 +250,9 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
             options.threads, options.jobs, gnu_make=gnu_make, checkout=True,
             show_unknown=options.show_unknown, step=options.step,
             no_subdirs=options.no_subdirs, full_path=options.full_path,
-            verbose_build=options.verbose_build)
+            verbose_build=options.verbose_build,
+            incremental=options.incremental,
+            per_board_out_dir=options.per_board_out_dir,)
     builder.force_config_on_failure = not options.quick
     if make_func:
         builder.do_make = make_func