public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices
@ 2016-04-10  2:44 Simon Glass
  2016-04-10  2:44 ` [U-Boot] [PATCH 01/44] Revert "dm: sandbox: Drop the pre-DM host implementation" Simon Glass
                   ` (43 more replies)
  0 siblings, 44 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

This series adjusts the block device code to support conversion to driver
model. Specifically

- A new 'legacy' block interface is created, allowing block devices to be
defined by a linker list and accessed through function calls
- Block device commands (such as sata and scsi) are adjusted to use these
functions rather than the block device array directly
- These same function calls are then implemented by the block uclass
- The existing block-device table in part.c is dropped
- The opportunity is taken to clean up the code style, as block devices are
one of the few remaining dark corners in U-Boot

It is useful to enable all block device drivers with sandbox. This improves
sandbox code coverage and allows tests to be written. The following are
enabled by this series:

- IDE
- SCSI
- SATA
- Systemace

USB was already enabled. MMC will be enabled by a future series. Note that
these devices do not actually function in sandbox, but the code is compiled.

As mentioned, future work will enable MMC for sandbox including adding
rudimentary sandbox SD card emulation. It would also be possible to create
emulations for IDE, SCSI, SATA and Systemace but that work is not planned.

It should be noted that the current CONFIG_DM_MMC option does not fully
enable driver model for MMC, since the MMC operations are not running
through driver model. This will need to be addressed at some point.

This series is available at u-boot-dm/blka-working


Simon Glass (44):
  Revert "dm: sandbox: Drop the pre-DM host implementation"
  dm: sandbox: Add a board for sandbox without CONFIG_BLK
  pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
  dm: Rename disk uclass to ahci
  Allow iotrace byte access to use an address of any size
  sandbox: Add string and 16-bit I/O functions
  sandbox: Add dummy SCSI functions
  sandbox: Add dummy SATA functions
  dm: scsi: Remove the forward declarations
  dm: scsi: Fix up code style
  dm: ide: Correct various code style problems
  dm: ide: Remove the forward declarations
  dm: sata: Fix code style problems in cmd/sata.c
  dm: scsi: Rename CONFIG_CMD_SCSI to CONFIG_SCSI
  dm: blk: Add a legacy block interface
  dm: systemace: Add a legacy block interface
  dm: sandbox: Add a legacy host block interface
  dm: usb: Add a legacy block interface for USB storage
  dm: mmc: Add a legacy block interface for MMC
  dm: mmc: Add an implementation of the 'devnum' functions
  dm: scsi: Separate the non-command code into its own file
  dm: ide: Separate the non-command code into its own file
  dm: sata: Separate the non-command code into its own file
  dm: disk: Use legacy block driver info for block device access
  dm: usb: Drop the get_dev() function
  dm: ide: Drop the get_dev() function
  dm: mmc: Drop the get_dev() function
  dm: scsi: Drop the get_dev() function
  dm: sata: Drop the get_dev() function
  dm: systemace: Drop the get_dev() function
  dm: blk: Drop the systemace.h header
  dm: sandbox: Drop the host_get_dev() function
  dm: part: Drop the get_dev() method
  dm: ide: Add support for driver-model block devices
  dm: sandbox: Enable IDE
  dm: scsi: Add support for driver-model block devices
  dm: sandbox: Enable SCSI
  dm: sata: Add support for driver-model block devices
  dm: sandbox: Enable SATA
  dm: blk: Allow blk_create_device() to allocate the device number
  dm: blk: Add a easier way to create a named block device
  dm: systemace: Reorder function to avoid forward declarataions
  dm: systemace: Add driver-mode block-device support
  dm: sandbox: Enable systemace

 README                                         |    4 +-
 api/api_storage.c                              |    2 +-
 arch/arm/include/asm/arch-ls102xa/config.h     |    2 +-
 arch/sandbox/include/asm/io.h                  |   22 +
 arch/x86/Kconfig                               |    3 +
 arch/x86/cpu/broadwell/sata.c                  |    2 +-
 arch/x86/cpu/intel_common/cpu.c                |    2 +-
 arch/x86/cpu/ivybridge/bd82x6x.c               |    2 +-
 arch/x86/cpu/ivybridge/sata.c                  |    2 +-
 board/cm5200/fwupdate.c                        |    2 +-
 board/mpl/pip405/README                        |    6 +-
 board/sandbox/MAINTAINERS                      |    7 +
 cmd/Makefile                                   |    8 +-
 cmd/disk.c                                     |    2 +-
 cmd/ide.c                                      | 1352 +-----------------------
 cmd/mmc.c                                      |    2 +-
 cmd/sata.c                                     |  142 +--
 cmd/scsi.c                                     |  753 ++-----------
 cmd/usb.c                                      |   16 +-
 common/Makefile                                |    6 +
 common/board_r.c                               |    4 +-
 common/ide.c                                   | 1231 +++++++++++++++++++++
 common/sata.c                                  |  115 ++
 common/scsi.c                                  |  592 +++++++++++
 common/spl/spl_sata.c                          |    2 +-
 common/spl/spl_usb.c                           |    2 +-
 common/usb_storage.c                           |   37 +-
 configs/sandbox_noblk_defconfig                |   98 ++
 disk/part.c                                    |   22 +-
 drivers/Makefile                               |    1 +
 drivers/block/Kconfig                          |    5 +-
 drivers/block/Makefile                         |    8 +-
 drivers/block/{disk-uclass.c => ahci-uclass.c} |    6 +-
 drivers/block/blk-uclass.c                     |  324 ++++++
 drivers/block/blk_legacy.c                     |  258 +++++
 drivers/block/sandbox.c                        |  103 +-
 drivers/block/sandbox_scsi.c                   |   29 +
 drivers/block/sata_sandbox.c                   |   33 +
 drivers/block/sym53c8xx.c                      |    2 +-
 drivers/block/systemace.c                      |  110 +-
 drivers/mmc/mmc.c                              |   24 +-
 drivers/pci/pci.c                              |    4 -
 fs/fat/fat.c                                   |    2 +-
 include/blk.h                                  |  226 +++-
 include/config_cmd_all.h                       |    2 +-
 include/config_distro_bootcmd.h                |    6 +-
 include/config_fallbacks.h                     |    2 +-
 include/configs/MPC8544DS.h                    |    2 +-
 include/configs/MPC8572DS.h                    |    2 +-
 include/configs/MPC8610HPCD.h                  |    2 +-
 include/configs/MPC8641HPCN.h                  |    4 +-
 include/configs/PIP405.h                       |    2 +-
 include/configs/am57xx_evm.h                   |    2 +-
 include/configs/cm_t54.h                       |    2 +-
 include/configs/db-88f6820-gp.h                |    2 +-
 include/configs/dra7xx_evm.h                   |    2 +-
 include/configs/efi-x86.h                      |    2 +-
 include/configs/galileo.h                      |    2 +-
 include/configs/highbank.h                     |    2 +-
 include/configs/ls1043aqds.h                   |    2 +-
 include/configs/ls2080aqds.h                   |    2 +-
 include/configs/ls2080ardb.h                   |    2 +-
 include/configs/omap5_uevm.h                   |    2 +-
 include/configs/qemu-x86.h                     |    2 +-
 include/configs/sandbox.h                      |   23 +
 include/configs/sbc8641d.h                     |    2 -
 include/configs/sunxi-common.h                 |    2 +-
 include/configs/x86-common.h                   |    2 +-
 include/configs/xilinx_zynqmp.h                |    2 +-
 include/dm/uclass-id.h                         |    2 +-
 include/ide.h                                  |    8 +
 include/iotrace.h                              |    5 +-
 include/part.h                                 |   15 -
 include/systemace.h                            |   17 -
 include/usb.h                                  |    1 -
 75 files changed, 3392 insertions(+), 2308 deletions(-)
 create mode 100644 common/ide.c
 create mode 100644 common/sata.c
 create mode 100644 common/scsi.c
 create mode 100644 configs/sandbox_noblk_defconfig
 rename drivers/block/{disk-uclass.c => ahci-uclass.c} (72%)
 create mode 100644 drivers/block/blk_legacy.c
 create mode 100644 drivers/block/sandbox_scsi.c
 create mode 100644 drivers/block/sata_sandbox.c
 delete mode 100644 include/systemace.h

-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 01/44] Revert "dm: sandbox: Drop the pre-DM host implementation"
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
@ 2016-04-10  2:44 ` Simon Glass
  2016-04-10  2:44 ` [U-Boot] [PATCH 02/44] dm: sandbox: Add a board for sandbox without CONFIG_BLK Simon Glass
                   ` (42 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

Bring this support back so that sandbox can be compiled with CONFIG_BLK. This
allows sandbox to have greater build coverage during the block-device
transition. This can be removed again later.

This reverts commit 33cf727b1634dbd9cd68a6ebc444a88f053822d7.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/sandbox.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 2d340ef..6d41508 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -17,6 +17,19 @@
 
 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,6 +202,17 @@ 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);
+
+	if (!host_dev)
+		return -ENODEV;
+
+	if (!host_dev->blk_dev.priv)
+		return -ENOENT;
+
+	*blk_devp = &host_dev->blk_dev;
+#endif
 
 	return 0;
 }
@@ -139,6 +227,7 @@ struct blk_desc *host_get_dev(int dev)
 	return blk_dev;
 }
 
+#ifdef CONFIG_BLK
 static const struct blk_ops sandbox_host_blk_ops = {
 	.read	= host_block_read,
 	.write	= host_block_write,
@@ -150,3 +239,4 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
 	.ops		= &sandbox_host_blk_ops,
 	.priv_auto_alloc_size	= sizeof(struct host_block_dev),
 };
+#endif
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 02/44] dm: sandbox: Add a board for sandbox without CONFIG_BLK
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
  2016-04-10  2:44 ` [U-Boot] [PATCH 01/44] Revert "dm: sandbox: Drop the pre-DM host implementation" Simon Glass
@ 2016-04-10  2:44 ` Simon Glass
  2016-04-10  2:44 ` [U-Boot] [PATCH 03/44] pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE Simon Glass
                   ` (41 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

While the driver-model block device support is in progress, it is useful to
build sandbox both with and without CONFIG_BLK. Add a separate board for
the latter.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 board/sandbox/MAINTAINERS       |  7 +++
 configs/sandbox_noblk_defconfig | 98 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)
 create mode 100644 configs/sandbox_noblk_defconfig

diff --git a/board/sandbox/MAINTAINERS b/board/sandbox/MAINTAINERS
index 10d88a2..f5db773 100644
--- a/board/sandbox/MAINTAINERS
+++ b/board/sandbox/MAINTAINERS
@@ -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
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
new file mode 100644
index 0000000..038dad6
--- /dev/null
+++ b/configs/sandbox_noblk_defconfig
@@ -0,0 +1,98 @@
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_PCI=y
+CONFIG_DEFAULT_DEVICE_TREE="sandbox"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_CONSOLE_RECORD=y
+CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_SOUND=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_TPM_TEST=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_HOSTFILE=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_DEVRES=y
+CONFIG_ADC=y
+CONFIG_ADC_SANDBOX=y
+CONFIG_CLK=y
+CONFIG_SANDBOX_GPIO=y
+CONFIG_PM8916_GPIO=y
+CONFIG_SYS_I2C_SANDBOX=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_SANDBOX=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_PINCTRL_SANDBOX=y
+CONFIG_DM_PMIC=y
+CONFIG_DM_PMIC_SANDBOX=y
+CONFIG_PMIC_PM8916=y
+CONFIG_SPMI=y
+CONFIG_SPMI_SANDBOX=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_SANDBOX=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_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
+CONFIG_MMC=y
+CONFIG_SANDBOX_MMC=y
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 03/44] pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
  2016-04-10  2:44 ` [U-Boot] [PATCH 01/44] Revert "dm: sandbox: Drop the pre-DM host implementation" Simon Glass
  2016-04-10  2:44 ` [U-Boot] [PATCH 02/44] dm: sandbox: Add a board for sandbox without CONFIG_BLK Simon Glass
@ 2016-04-10  2:44 ` Simon Glass
  2016-04-11  5:02   ` Bin Meng
  2016-04-10  2:44 ` [U-Boot] [PATCH 04/44] dm: Rename disk uclass to ahci Simon Glass
                   ` (40 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

This option is not used by any board. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/pci/pci.c             | 4 ----
 include/configs/MPC8641HPCN.h | 2 --
 include/configs/sbc8641d.h    | 2 --
 3 files changed, 8 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4619089..4b73a0f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -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;
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h
index 1f4ed2a..cd8d91f 100644
--- a/include/configs/MPC8641HPCN.h
+++ b/include/configs/MPC8641HPCN.h
@@ -358,8 +358,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 */
 
 
diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h
index b7238fb..654e96e 100644
--- a/include/configs/sbc8641d.h
+++ b/include/configs/sbc8641d.h
@@ -305,8 +305,6 @@
 
 #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
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 04/44] dm: Rename disk uclass to ahci
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (2 preceding siblings ...)
  2016-04-10  2:44 ` [U-Boot] [PATCH 03/44] pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE Simon Glass
@ 2016-04-10  2:44 ` Simon Glass
  2016-04-10  2:44 ` [U-Boot] [PATCH 05/44] Allow iotrace byte access to use an address of any size Simon Glass
                   ` (39 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

This started as 'ahci' and was renamed to 'disk' during code review. But it
seems that this is too generic. Now that we have a 'blk' uclass, we can use
that as the generic piece, and revert to ahci for this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/Kconfig                               | 3 +++
 arch/x86/cpu/broadwell/sata.c                  | 2 +-
 arch/x86/cpu/intel_common/cpu.c                | 2 +-
 arch/x86/cpu/ivybridge/bd82x6x.c               | 2 +-
 arch/x86/cpu/ivybridge/sata.c                  | 2 +-
 drivers/block/Kconfig                          | 5 ++---
 drivers/block/Makefile                         | 2 +-
 drivers/block/{disk-uclass.c => ahci-uclass.c} | 6 +++---
 include/dm/uclass-id.h                         | 2 +-
 9 files changed, 14 insertions(+), 12 deletions(-)
 rename drivers/block/{disk-uclass.c => ahci-uclass.c} (72%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 4ef27dc..396023e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -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
 
diff --git a/arch/x86/cpu/broadwell/sata.c b/arch/x86/cpu/broadwell/sata.c
index dfb8486..2e47082 100644
--- a/arch/x86/cpu/broadwell/sata.c
+++ b/arch/x86/cpu/broadwell/sata.c
@@ -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,
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
index 93e4505..0fdef6f 100644
--- a/arch/x86/cpu/intel_common/cpu.c
+++ b/arch/x86/cpu/intel_common/cpu.c
@@ -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;
 }
diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index 4c039ac..5b58d6c 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -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)
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c
index c3d1057..1ce8195 100644
--- a/arch/x86/cpu/ivybridge/sata.c
+++ b/arch/x86/cpu/ivybridge/sata.c
@@ -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,
 };
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index fcc9ccd..80eea84 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -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
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index a43492f..b832ae1 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -7,7 +7,7 @@
 
 obj-$(CONFIG_BLK) += blk-uclass.o
 
-obj-$(CONFIG_DISK) += disk-uclass.o
+obj-$(CONFIG_AHCI) += ahci-uclass.o
 obj-$(CONFIG_SCSI_AHCI) += ahci.o
 obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
 obj-$(CONFIG_FSL_SATA) += fsl_sata.o
diff --git a/drivers/block/disk-uclass.c b/drivers/block/ahci-uclass.c
similarity index 72%
rename from drivers/block/disk-uclass.c
rename to drivers/block/ahci-uclass.c
index d665b35..7b8c326 100644
--- a/drivers/block/disk-uclass.c
+++ b/drivers/block/ahci-uclass.c
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <dm.h>
 
-UCLASS_DRIVER(disk) = {
-	.id		= UCLASS_DISK,
-	.name		= "disk",
+UCLASS_DRIVER(ahci) = {
+	.id		= UCLASS_AHCI,
+	.name		= "ahci",
 };
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index cbf9b2c..a5cf6e2 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -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 */
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 05/44] Allow iotrace byte access to use an address of any size
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (3 preceding siblings ...)
  2016-04-10  2:44 ` [U-Boot] [PATCH 04/44] dm: Rename disk uclass to ahci Simon Glass
@ 2016-04-10  2:44 ` Simon Glass
  2016-04-12 20:00   ` Stephen Warren
  2016-04-10  2:44 ` [U-Boot] [PATCH 06/44] sandbox: Add string and 16-bit I/O functions Simon Glass
                   ` (38 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

If an address is used with readb() and writeb() which is smaller than the
expected size (e.g. 32-bit value on a machine with 64-bit addresses), a
warning results. Fix this by adding a cast.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/iotrace.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/iotrace.h b/include/iotrace.h
index 9bd1f16..a0b59fb 100644
--- a/include/iotrace.h
+++ b/include/iotrace.h
@@ -31,10 +31,11 @@
 #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
 
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 06/44] sandbox: Add string and 16-bit I/O functions
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (4 preceding siblings ...)
  2016-04-10  2:44 ` [U-Boot] [PATCH 05/44] Allow iotrace byte access to use an address of any size Simon Glass
@ 2016-04-10  2:44 ` Simon Glass
  2016-04-12 20:02   ` Stephen Warren
  2016-04-10  2:44 ` [U-Boot] [PATCH 07/44] sandbox: Add dummy SCSI functions Simon Glass
                   ` (37 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

Add outsw() and insw() functions for sandbox, as these are needed by the IDE
code. The functions will not do anything useful if called, but allow the
code to be compiled.

Also add out16() and in16(), required by systemace.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/include/asm/io.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index 5b87fde..cdbb6ba 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -56,6 +56,28 @@ 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)
+{
+	u16 *data = (u16 *) buf;
+	while (ns--)
+		*data++ = *port;
+}
+
+static inline void _outsw(volatile u16 *port, const void *buf, int ns)
+{
+	u16 *data = (u16 *) buf;
+	while (ns--) {
+		*port = *data++;
+	}
+}
+
+#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>
 
 #endif
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 07/44] sandbox: Add dummy SCSI functions
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (5 preceding siblings ...)
  2016-04-10  2:44 ` [U-Boot] [PATCH 06/44] sandbox: Add string and 16-bit I/O functions Simon Glass
@ 2016-04-10  2:44 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 08/44] sandbox: Add dummy SATA functions Simon Glass
                   ` (36 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:44 UTC (permalink / raw)
  To: u-boot

Add some functions needed by the SCSI code. This allows it to be compiled
for sandbox, thus increasing build coverage.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/Makefile       |  2 +-
 drivers/block/sandbox_scsi.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 drivers/block/sandbox_scsi.c

diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index b832ae1..3b48eac 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -22,7 +22,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
 obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
 obj-$(CONFIG_SYSTEMACE) += systemace.o
 obj-$(CONFIG_BLOCK_CACHE) += blkcache.o
diff --git a/drivers/block/sandbox_scsi.c b/drivers/block/sandbox_scsi.c
new file mode 100644
index 0000000..d342a7a
--- /dev/null
+++ b/drivers/block/sandbox_scsi.c
@@ -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)
+{
+}
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 08/44] sandbox: Add dummy SATA functions
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (6 preceding siblings ...)
  2016-04-10  2:44 ` [U-Boot] [PATCH 07/44] sandbox: Add dummy SCSI functions Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 09/44] dm: scsi: Remove the forward declarations Simon Glass
                   ` (35 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add some functions needed by the SATA code. This allows it to be compiled
for sandbox, thus increasing build coverage.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/Makefile       |  2 +-
 drivers/block/sata_sandbox.c | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 drivers/block/sata_sandbox.c

diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 3b48eac..3f75934 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -22,7 +22,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 sandbox_scsi.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/sata_sandbox.c b/drivers/block/sata_sandbox.c
new file mode 100644
index 0000000..bd967d2
--- /dev/null
+++ b/drivers/block/sata_sandbox.c
@@ -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;
+}
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 09/44] dm: scsi: Remove the forward declarations
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (7 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 08/44] sandbox: Add dummy SATA functions Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:04   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 10/44] dm: scsi: Fix up code style Simon Glass
                   ` (34 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Reorder the code to avoid needing forward declarations.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/scsi.c | 755 +++++++++++++++++++++++++++++++------------------------------
 1 file changed, 378 insertions(+), 377 deletions(-)

diff --git a/cmd/scsi.c b/cmd/scsi.c
index 8991125..f875f51 100644
--- a/cmd/scsi.c
+++ b/cmd/scsi.c
@@ -50,6 +50,7 @@ static int scsi_curr_dev; /* current device */
 
 static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
 
+#if 0
 /********************************************************************************
  *  forward declerations of some Setup Routines
  */
@@ -70,110 +71,232 @@ 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);
+#endif
 
-
-/*********************************************************************************
- * (re)-scan the scsi bus and reports scsi device info
- * to the user if mode = 1
+/****************************************************************************************
+ * scsi_read
  */
-void scsi_scan(int mode)
+
+/* 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)
 {
-	unsigned char i,perq,modi,lun;
-	lbaint_t capacity;
-	unsigned long blksz;
-	ccb* pccb=(ccb *)&tempccb;
+	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
 
-	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;
+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]);
+}
 
-			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;
+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
-		scsi_curr_dev = -1;
+		pccb->cmd[4]=(unsigned char)pccb->datalen;
+	pccb->cmd[5]=0;
+	pccb->cmdlen=6;
+	pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+}
 
-	printf("Found %d device(s).\n", scsi_max_devs);
-#ifndef CONFIG_SPL_BUILD
-	setenv_ulong("scsidevs", scsi_max_devs);
+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;
 }
 
 int scsi_get_disk_count(void)
@@ -327,192 +450,69 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 				printf("... is now current device\n");
 				return 0;
 			}
-			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;
-			}
-	} /* switch */
-	return CMD_RET_USAGE;
-}
-
-U_BOOT_CMD(
-	scsi, 5, 1, do_scsi,
-	"SCSI sub-system",
-	"reset - reset SCSI controller\n"
-	"scsi info  - show available SCSI devices\n"
-	"scsi scan  - (re-)scan SCSI bus\n"
-	"scsi device [dev] - show or set current device\n"
-	"scsi part [dev] - print partition table of one or all SCSI devices\n"
-	"scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
-	"     to memory address `addr'\n"
-	"scsi write addr blk# cnt - write `cnt' blocks starting at block\n"
-	"     `blk#' from memory address `addr'"
-);
-
-U_BOOT_CMD(
-	scsiboot, 3, 1, do_scsiboot,
-	"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;
+			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;
+			}
+	} /* switch */
+	return CMD_RET_USAGE;
 }
 
+U_BOOT_CMD(
+	scsi, 5, 1, do_scsi,
+	"SCSI sub-system",
+	"reset - reset SCSI controller\n"
+	"scsi info  - show available SCSI devices\n"
+	"scsi scan  - (re-)scan SCSI bus\n"
+	"scsi device [dev] - show or set current device\n"
+	"scsi part [dev] - print partition table of one or all SCSI devices\n"
+	"scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
+	"     to memory address `addr'\n"
+	"scsi write addr blk# cnt - write `cnt' blocks starting at block\n"
+	"     `blk#' from memory address `addr'"
+);
+
+U_BOOT_CMD(
+	scsiboot, 3, 1, do_scsiboot,
+	"boot from SCSI device",
+	"loadAddr dev:part"
+);
+#endif
+
 /* copy src to dest, skipping leading and trailing blanks
  * and null terminate the string
  */
@@ -630,105 +630,106 @@ void scsi_setup_test_unit_ready(ccb * pccb)
 	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)
+/*********************************************************************************
+ * (re)-scan the scsi bus and reports scsi device info
+ * to the user if mode = 1
+ */
+void scsi_scan(int mode)
 {
-	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]);
-}
+	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;
 
-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;
+			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
-		pccb->cmd[4]=(unsigned char)pccb->datalen;
-	pccb->cmd[5]=0;
-	pccb->cmdlen=6;
-	pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+		scsi_curr_dev = -1;
+
+	printf("Found %d device(s).\n", scsi_max_devs);
+#ifndef CONFIG_SPL_BUILD
+	setenv_ulong("scsidevs", scsi_max_devs);
+#endif
 }
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 10/44] dm: scsi: Fix up code style
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (8 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 09/44] dm: scsi: Remove the forward declarations Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:05   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 11/44] dm: ide: Correct various code style problems Simon Glass
                   ` (33 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Update the code style of this file so that it passes checkpatch.pl.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/scsi.c | 482 +++++++++++++++++++++++++++++--------------------------------
 1 file changed, 226 insertions(+), 256 deletions(-)

diff --git a/cmd/scsi.c b/cmd/scsi.c
index f875f51..751fc58 100644
--- a/cmd/scsi.c
+++ b/cmd/scsi.c
@@ -50,82 +50,53 @@ static int scsi_curr_dev; /* current device */
 
 static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
 
-#if 0
-/********************************************************************************
- *  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);
-#endif
-
-/****************************************************************************************
- * scsi_read
- */
-
 /* 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)
+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[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[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]);
+	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->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 */
+	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],
@@ -136,12 +107,12 @@ 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[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[7] = ((unsigned char)(blocks >> 8)) & 0xff;
 	pccb->cmd[8] = (unsigned char)blocks & 0xff;
 	pccb->cmd[9] = 0;
 	pccb->cmdlen = 10;
@@ -155,33 +126,33 @@ void scsi_setup_write_ext(ccb *pccb, lbaint_t start, unsigned short blocks)
 
 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->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]);
+	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;
+	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->cmd[4] = (unsigned char)pccb->datalen;
+	pccb->cmd[5] = 0;
 	pccb->cmdlen=6;
-	pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+	pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
 }
 
 static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
@@ -193,18 +164,18 @@ static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
 	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;
+
+	/* 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;
+		pccb->pdata = (unsigned char *)buf_addr;
 #ifdef CONFIG_SYS_64BIT_LBA
 		if (start > SCSI_LBA48_READ) {
 			unsigned long blocks;
@@ -216,17 +187,18 @@ static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
 		} 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;
+			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;
+			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
@@ -234,14 +206,14 @@ static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
 		      start, smallblks, buf_addr);
 		if (scsi_exec(pccb) != true) {
 			scsi_print_error(pccb);
-			blkcnt-=blks;
+			blkcnt -= blks;
 			break;
 		}
 		buf_addr+=pccb->datalen;
-	} while(blks!=0);
+	} while (blks != 0);
 	debug("scsi_read_ext: end startblk " LBAF
 	      ", blccnt %x buffer %" PRIXPTR "\n", start, smallblks, buf_addr);
-	return(blkcnt);
+	return blkcnt;
 }
 
 /*******************************************************************************
@@ -388,106 +360,106 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		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], "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]);
 			}
-			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 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;
 			}
-			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;
-				}
-				scsi_curr_dev = dev;
-				printf("... is now current device\n");
-				return 0;
-			}
-			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) {
+			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]);
 				}
-				else {
-					printf ("\nSCSI device %d not available\n", dev);
-				}
-				return 1;
 			}
-			return CMD_RET_USAGE;
-    default:
-			/*@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;
+			if (!ok)
+				printf("\nno SCSI 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);
+			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;
+			scsi_curr_dev = dev;
+			printf("... is now current device\n");
+			return 0;
+		}
+		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;
+		}
 	} /* switch */
 	return CMD_RET_USAGE;
 }
@@ -516,25 +488,24 @@ U_BOOT_CMD(
 /* 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)
+void scsi_ident_cpy(unsigned char *dest, unsigned char *src, unsigned int len)
 {
 	int start,end;
 
-	start=0;
-	while(start<len) {
-		if(src[start]!=' ')
+	start = 0;
+	while (start < len) {
+		if (src[start] != ' ')
 			break;
 		start++;
 	}
-	end=len-1;
-	while(end>start) {
-		if(src[end]!=' ')
+	end = len-1;
+	while (end > start) {
+		if (src[end] != ' ')
 			break;
 		end--;
 	}
-	for( ; start<=end; start++) {
-		*dest++=src[start];
-	}
+	for (; start <= end; start++)
+		*dest ++= src[start];
 	*dest='\0';
 }
 
@@ -557,7 +528,7 @@ int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
 {
 	*capacity = 0;
 
-	memset(pccb->cmd, 0, sizeof(pccb->cmd));
+	memset(pccb->cmd, '\0', sizeof(pccb->cmd));
 	pccb->cmd[0] = SCSI_RD_CAPAC10;
 	pccb->cmd[1] = pccb->lun << 5;
 	pccb->cmdlen = 10;
@@ -582,8 +553,7 @@ int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
 	}
 
 	/* Read capacity (10) was insufficient. Use read capacity (16). */
-
-	memset(pccb->cmd, 0, sizeof(pccb->cmd));
+	memset(pccb->cmd, '\0', sizeof(pccb->cmd));
 	pccb->cmd[0] = SCSI_RD_CAPAC16;
 	pccb->cmd[1] = 0x10;
 	pccb->cmdlen = 16;
@@ -620,14 +590,14 @@ int scsi_read_capacity(ccb *pccb, lbaint_t *capacity, unsigned long *blksz)
  */
 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 */
+	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 */
 }
 
 /*********************************************************************************
@@ -641,50 +611,49 @@ void scsi_scan(int mode)
 	unsigned long blksz;
 	ccb* pccb=(ccb *)&tempccb;
 
-	if(mode==1) {
+	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 =
+	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].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].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].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_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);
+					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) {
+			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;
+			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);
@@ -692,14 +661,15 @@ void scsi_scan(int mode)
 				       &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;
+			scsi_dev_desc[scsi_max_devs].target = pccb->target;
+			scsi_dev_desc[scsi_max_devs].lun = pccb->lun;
 
-			pccb->datalen=0;
+			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;
+				if (scsi_dev_desc[scsi_max_devs].removable) {
+					scsi_dev_desc[scsi_max_devs].type =
+							perq;
 					goto removable;
 				}
 				scsi_print_error(pccb);
@@ -709,11 +679,11 @@ void scsi_scan(int mode)
 				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].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;
+			scsi_dev_desc[scsi_max_devs].type = perq;
 			part_init(&scsi_dev_desc[scsi_max_devs]);
 removable:
 			if(mode==1) {
@@ -723,8 +693,8 @@ removable:
 			scsi_max_devs++;
 		} /* next LUN */
 	}
-	if(scsi_max_devs>0)
-		scsi_curr_dev=0;
+	if (scsi_max_devs > 0)
+		scsi_curr_dev = 0;
 	else
 		scsi_curr_dev = -1;
 
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 11/44] dm: ide: Correct various code style problems
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (9 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 10/44] dm: scsi: Fix up code style Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 12/44] dm: ide: Remove the forward declarations Simon Glass
                   ` (32 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Adjust common/ide.c so that it passes most checkpatch.pl checks.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/ide.c | 57 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/cmd/ide.c b/cmd/ide.c
index c4c08c8..a46d0ac 100644
--- a/cmd/ide.c
+++ b/cmd/ide.c
@@ -58,13 +58,13 @@ struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
 /* ------------------------------------------------------------------------- */
 
 #ifdef CONFIG_IDE_RESET
-static void  ide_reset (void);
+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);
+static uchar ide_wait(int dev, ulong t);
 
 #define IDE_TIME_OUT	2000	/* 2 sec timeout */
 
@@ -72,14 +72,15 @@ static uchar ide_wait  (int dev, ulong t);
 
 #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);
+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 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
@@ -150,7 +151,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 		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) {
@@ -169,7 +170,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
 			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]);
@@ -194,13 +195,13 @@ 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 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];
@@ -223,13 +224,13 @@ 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);
@@ -833,7 +834,7 @@ ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
 	}
 IDE_READ_E:
 	ide_led(DEVICE_LED(device), 0);	/* LED off      */
-	return (n);
+	return n;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -922,7 +923,7 @@ ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
 	}
 WR_OUT:
 	ide_led(DEVICE_LED(device), 0);	/* LED off      */
-	return (n);
+	return n;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -974,7 +975,7 @@ static uchar ide_wait(int dev, ulong t)
 		if (delay-- == 0)
 			break;
 	}
-	return (c);
+	return c;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -1098,7 +1099,7 @@ static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res)
 		if (delay-- == 0)
 			break;
 	}
-	return (c);
+	return c;
 }
 
 /*
@@ -1142,7 +1143,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
 
 	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);
+		       device, c);
 		err = 0xFF;
 		goto AI_OUT;
 	}
@@ -1166,10 +1167,10 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
 		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);
+			      err, c);
 		} else {
 			printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x)  status 0x%02x\n",
-				ccb[0], c);
+			       ccb[0], c);
 			err = 0xFF;
 		}
 		goto AI_OUT;
@@ -1190,7 +1191,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
 	}
 	if (n != buflen) {
 		debug("WARNING, transfer bytes %d not equal with requested %d\n",
-			n, buflen);
+		      n, buflen);
 	}
 	if (n != 0) {		/* data transfer */
 		debug("ATAPI_ISSUE: %d Bytes to transfer\n", n);
@@ -1220,7 +1221,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
 	}
 AI_OUT:
 	ide_led(DEVICE_LED(device), 0);	/* LED off      */
-	return (err);
+	return err;
 }
 
 /*
@@ -1297,7 +1298,7 @@ retry:
 	       ascq);
 error:
 	debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq);
-	return (0xFF);
+	return 0xFF;
 }
 
 
@@ -1402,8 +1403,8 @@ ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
 	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);
+	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)
@@ -1428,14 +1429,14 @@ ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
 					(unsigned char *) buffer,
 					cnt * ATAPI_READ_BLOCK_SIZE)
 		    == 0xFF) {
-			return (n);
+			return n;
 		}
 		n += cnt;
 		blkcnt -= cnt;
 		blknr += cnt;
 		buffer += (cnt * ATAPI_READ_BLOCK_SIZE);
 	} while (blkcnt > 0);
-	return (n);
+	return n;
 }
 
 /* ------------------------------------------------------------------------- */
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 12/44] dm: ide: Remove the forward declarations
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (10 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 11/44] dm: ide: Correct various code style problems Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 13/44] dm: sata: Fix code style problems in cmd/sata.c Simon Glass
                   ` (31 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Reorder the code to avoid needing forward declarations. Fix up code style
as needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/ide.c | 1924 ++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 946 insertions(+), 978 deletions(-)

diff --git a/cmd/ide.c b/cmd/ide.c
index a46d0ac..db26f43 100644
--- a/cmd/ide.c
+++ b/cmd/ide.c
@@ -57,491 +57,518 @@ 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);
+#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);
 
-/* ------------------------------------------------------------------------- */
-
-int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+static void ide_reset(void)
 {
-	int rcode = 0;
-
-	switch (argc) {
-	case 0:
-	case 1:
-		return CMD_RET_USAGE;
-	case 2:
-		if (strncmp(argv[1], "res", 3) == 0) {
-			puts("\nReset IDE"
-#ifdef CONFIG_IDE_8xx_DIRECT
-			     " on PCMCIA " PCMCIA_SLOT_MSG
-#endif
-			     ": ");
-
-			ide_init();
-			return 0;
-		} else if (strncmp(argv[1], "inf", 3) == 0) {
-			int i;
+	int i;
 
-			putc('\n');
+	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;
 
-			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]);
-			}
-			return 0;
+	ide_set_reset(1);	/* assert reset */
 
-		} 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;
-			}
-			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;
+	/* the reset signal shall be asserted for et least 25 us */
+	udelay(25);
 
-			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;
-		}
-		return CMD_RET_USAGE;
-	case 3:
-		if (strncmp(argv[1], "dev", 3) == 0) {
-			int dev = (int)simple_strtoul(argv[2], NULL, 10);
+	WATCHDOG_RESET();
 
-			printf("\nIDE device %d: ", dev);
-			if (dev >= CONFIG_SYS_IDE_MAXDEVICE) {
-				puts("unknown device\n");
-				return 1;
-			}
-			dev_print(&ide_dev_desc[dev]);
-			/*ide_print (dev); */
+	/* de-assert RESET signal */
+	ide_set_reset(0);
 
-			if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
-				return 1;
+	/* wait 250 ms */
+	for (i = 0; i < 250; ++i)
+		udelay(1000);
+}
+#else
+#define ide_reset()	/* dummy */
+#endif /* CONFIG_IDE_RESET */
 
-			curr_device = dev;
+/*
+ * 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;
 
-			puts("... is now current device\n");
+	while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) {
+		udelay(100);
+		if (delay-- == 0)
+			break;
+	}
+	return c;
+}
 
-			return 0;
-		} else if (strncmp(argv[1], "part", 4) == 0) {
-			int dev = (int)simple_strtoul(argv[2], NULL, 10);
+/*
+ * 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;
 
-			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;
-			}
-			return rcode;
-		}
+	last = dst;
+	end = src + len - 1;
 
-		return CMD_RET_USAGE;
-	default:
-		/*@least 4 args */
+	/* reserve space for '\0' */
+	if (len < 2)
+		goto OUT;
 
-		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;
+	/* skip leading white space */
+	while ((*src) && (src < end) && (*src == ' '))
+		++src;
 
-#ifdef CONFIG_SYS_64BIT_LBA
-			lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
+	/* copy string, omitting trailing white space */
+	while ((*src) && (src < end)) {
+		*dst++ = *src;
+		if (*src++ != ' ')
+			last = dst;
+	}
+OUT:
+	*last = '\0';
+}
 
-			printf("\nIDE read: device %d block # %lld, count %ld...",
-			       curr_device, blk, cnt);
-#else
-			lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
+#ifdef CONFIG_ATAPI
+/****************************************************************************
+ * ATAPI Support
+ */
 
-			printf("\nIDE read: device %d block # %ld, count %ld...",
-			       curr_device, blk, cnt);
-#endif
+#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;
 
-			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);
+	pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+	dbuf = (ushort *)sect_buf;
 
-			printf("%ld blocks read: %s\n",
-			       n, (n == cnt) ? "OK" : "ERROR");
-			if (n == cnt)
-				return 0;
-			else
-				return 1;
-		} else if (strcmp(argv[1], "write") == 0) {
-			ulong addr = simple_strtoul(argv[2], NULL, 16);
-			ulong cnt = simple_strtoul(argv[4], NULL, 16);
-			ulong n;
+	debug("in output data shorts base for read is %lx\n",
+	      (unsigned long) pbuf);
 
-#ifdef CONFIG_SYS_64BIT_LBA
-			lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
+	while (shorts--) {
+		EIEIO;
+		*pbuf = *dbuf++;
+	}
+}
 
-			printf("\nIDE write: device %d block # %lld, count %ld...",
-			       curr_device, blk, cnt);
-#else
-			lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+{
+	ushort *dbuf;
+	volatile ushort *pbuf;
 
-			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);
+	pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG);
+	dbuf = (ushort *)sect_buf;
 
-			printf("%ld blocks written: %s\n",
-				n, (n == cnt) ? "OK" : "ERROR");
-			if (n == cnt)
-				return 0;
-			else
-				return 1;
-		} else {
-			return CMD_RET_USAGE;
-		}
+	debug("in input data shorts base for read is %lx\n",
+	      (unsigned long) pbuf);
 
-		return rcode;
+	while (shorts--) {
+		EIEIO;
+		*dbuf++ = *pbuf;
 	}
 }
 
-int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+#else  /* ! CONFIG_IDE_SWAP_IO */
+__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
 {
-	return common_diskboot(cmdtp, "ide", argc, argv);
+	outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
 }
 
-/* ------------------------------------------------------------------------- */
-
-__weak void ide_led(uchar led, uchar status)
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
 {
-#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;
+	insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
+}
 
-	if (status)		/* switch LED on        */
-		led_buffer |= led;
-	else			/* switch LED off       */
-		led_buffer &= ~led;
+#endif /* CONFIG_IDE_SWAP_IO */
 
-	*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)
+/*
+ * 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)
 {
-	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)));
+	ulong delay = 10 * t;	/* poll every 100 us */
+	uchar c;
 
-#if defined(CONFIG_IDE_AHB)
-	if (port) {
-		/* write command */
-		ide_write_register(dev, port, val);
-	} else {
-		/* write data */
-		outb(val, (ATA_CURR_BASE(dev)));
+	/* 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;
 	}
-#else
-	outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)));
-#endif
+	return c;
 }
 
-__weak unsigned char ide_inb(int dev, int port)
+/*
+ * issue an atapi command
+ */
+unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
+			  unsigned char *buffer, int buflen)
 {
-	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
+	unsigned char c, err, mask, res;
+	int n;
 
-	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;
-}
+	ide_led(DEVICE_LED(device), 1);	/* LED on       */
 
-void ide_init(void)
-{
-	unsigned char c;
-	int i, bus;
+	/* 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));
 
-#ifdef CONFIG_IDE_8xx_PCCARD
-	extern int ide_devices_found;	/* Initialized in check_ide_device() */
-#endif /* CONFIG_IDE_8xx_PCCARD */
+	ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
+	udelay(50);
 
-#ifdef CONFIG_IDE_PREINIT
-	WATCHDOG_RESET();
+	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 (ide_preinit()) {
-		puts("ide_preinit failed\n");
-		return;
+	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;
 	}
-#endif /* CONFIG_IDE_PREINIT */
 
-	WATCHDOG_RESET();
+	/* 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;
 	/*
-	 * Reset the IDE just to be sure.
-	 * Light LED's to show
+	 * if no data wait for DRQ = 0 BSY = 0
+	 * if data wait for DRQ = 1 BSY = 0
 	 */
-	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;
+	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;
 	}
-#endif /* CONFIG_IDE_INIT_POSTRESET */
+	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;
+}
 
-	/*
-	 * 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);
+/*
+ * sending the command to atapi_issue. If an status other than good
+ * returns, an request_sense will be issued
+ */
 
-#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);
+#define ATAPI_DRIVE_NOT_READY	100
+#define ATAPI_UNIT_ATTN		10
 
-		ide_bus_ok[bus] = 0;
+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;
 
-		/* 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 */
+	unitattn = ATAPI_UNIT_ATTN;
+	notready = ATAPI_DRIVE_NOT_READY;
 
-			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('.');
+retry:
+	res = atapi_issue(device, ccb, ccblen, buffer, buflen);
+	if (res == 0)
+		return 0;	/* Ok */
 
-		} while (c & ATA_STAT_BUSY);
+	if (res == 0xFF)
+		return 0xFF;	/* error */
 
-		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();
-	}
+	debug("(auto_req)atapi_issue returned sense key %X\n", res);
 
-	putc('\n');
+	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 */
 
-	ide_led((LED_IDE1 | LED_IDE2), 0);	/* LED's off    */
+	res = atapi_issue(device, sense_ccb, 12, sense_data, 18);
+	key = (sense_data[2] & 0xF);
+	asc = (sense_data[12]);
+	ascq = (sense_data[13]);
 
-	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]);
+	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 ((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;
+	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;
 	}
-	WATCHDOG_RESET();
+	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)
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *ide_get_dev(int dev)
+ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+		 void *buffer)
 {
-	return (dev < CONFIG_SYS_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL;
-}
-#endif
+	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);
 
-/* 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);
+	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;
 }
-#else
-__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
+
+static void atapi_inquiry(struct blk_desc *dev_desc)
 {
-	volatile ushort *pbuf =
-		(ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-	ushort *dbuf = (ushort *) sect_buf;
+	unsigned char ccb[12];	/* Command descriptor block */
+	unsigned char iobuf[64];	/* temp buf */
+	unsigned char c;
+	int device;
 
-	debug("in input swap data base for read is %lx\n",
-	      (unsigned long) pbuf);
+	device = dev_desc->devnum;
+	dev_desc->type = DEV_TYPE_UNKNOWN;	/* not yet valid */
+	dev_desc->block_read = atapi_read;
 
-	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 */
+	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);
 
-#if defined(CONFIG_IDE_SWAP_IO)
-__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
-{
-	ushort *dbuf;
-	volatile ushort *pbuf;
+	debug("ATAPI_CMD_INQUIRY returned %x\n", c);
+	if (c != 0)
+		return;
 
-	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 */
+	/* 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);
 
-#if defined(CONFIG_IDE_SWAP_IO)
-__weak void ide_input_data(int dev, ulong *sect_buf, int words)
-{
-	ushort *dbuf;
-	volatile ushort *pbuf;
+	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;
 
-	pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
-	dbuf = (ushort *) sect_buf;
+	if ((iobuf[1] & 0x80) == 0x80)
+		dev_desc->removable = 1;
+	else
+		dev_desc->removable = 0;
 
-	debug("in input data base for read is %lx\n", (unsigned long) pbuf);
+	memset(ccb, 0, sizeof(ccb));
+	memset(iobuf, 0, sizeof(iobuf));
+	ccb[0] = ATAPI_CMD_START_STOP;
+	ccb[4] = 0x03;		/* start */
 
-	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);
+	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_IDE_SWAP_IO */
+#endif /* CONFIG_ATAPI */
 
-/* -------------------------------------------------------------------------
- */
 static void ide_ident(struct blk_desc *dev_desc)
 {
 	unsigned char c;
@@ -633,11 +660,11 @@ static void ide_ident(struct blk_desc *dev_desc)
 
 	ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);
 
-	ident_cpy((unsigned char *) dev_desc->revision, iop.fw_rev,
+	ident_cpy((unsigned char *)dev_desc->revision, iop.fw_rev,
 		  sizeof(dev_desc->revision));
-	ident_cpy((unsigned char *) dev_desc->vendor, iop.model,
+	ident_cpy((unsigned char *)dev_desc->vendor, iop.model,
 		  sizeof(dev_desc->vendor));
-	ident_cpy((unsigned char *) dev_desc->product, iop.serial_no,
+	ident_cpy((unsigned char *)dev_desc->product, iop.serial_no,
 		  sizeof(dev_desc->product));
 #ifdef __LITTLE_ENDIAN
 	/*
@@ -711,737 +738,678 @@ static void ide_ident(struct blk_desc *dev_desc)
 #endif
 }
 
+/* ------------------------------------------------------------------------- */
+
+int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	int rcode = 0;
+
+	switch (argc) {
+	case 0:
+	case 1:
+		return CMD_RET_USAGE;
+	case 2:
+		if (strncmp(argv[1], "res", 3) == 0) {
+			puts("\nReset IDE"
+#ifdef CONFIG_IDE_8xx_DIRECT
+			     " on PCMCIA " PCMCIA_SLOT_MSG
+#endif
+			     ": ");
+
+			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]);
+			}
+			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;
+			}
+			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;
+		}
+		return CMD_RET_USAGE;
+	case 3:
+		if (strncmp(argv[1], "dev", 3) == 0) {
+			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;
+			}
+			dev_print(&ide_dev_desc[dev]);
+			/*ide_print (dev); */
 
-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 */
+			if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
+				return 1;
 
-#ifdef CONFIG_LBA48
-	unsigned char lba48 = 0;
+			curr_device = dev;
 
-	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);
+			puts("... is now current device\n");
 
-	ide_led(DEVICE_LED(device), 1);	/* LED on       */
+			return 0;
+		} else if (strncmp(argv[1], "part", 4) == 0) {
+			int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-	/* Select device
-	 */
-	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-	c = ide_wait(device, IDE_TIME_OUT);
+			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;
+			}
+			return rcode;
+		}
 
-	if (c & ATA_STAT_BUSY) {
-		printf("IDE read: device %d not ready\n", device);
-		goto IDE_READ_E;
-	}
+		return CMD_RET_USAGE;
+	default:
+		/* at least 4 args */
 
-	/* 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);
+		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;
 
-	c = ide_wait(device, IDE_TIME_OUT);	/* can't take over 500 ms */
+#ifdef CONFIG_SYS_64BIT_LBA
+			lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
 
-	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;
-	}
+			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);
+#endif
 
-	while (blkcnt-- > 0) {
+			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);
 
-		c = ide_wait(device, IDE_TIME_OUT);
+			printf("%ld blocks read: %s\n",
+			       n, (n == cnt) ? "OK" : "ERROR");
+			if (n == cnt)
+				return 0;
+			else
+				return 1;
+		} else if (strcmp(argv[1], "write") == 0) {
+			ulong addr = simple_strtoul(argv[2], NULL, 16);
+			ulong cnt = simple_strtoul(argv[4], NULL, 16);
+			ulong n;
 
-		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);
+			lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
+
+			printf("\nIDE write: device %d block # %lld, count %ld...",
+			       curr_device, blk, cnt);
 #else
-			ide_outb(device, ATA_LBA_MID, 0);
-			ide_outb(device, ATA_LBA_HIGH, 0);
+			lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
+
+			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);
+
+			printf("%ld blocks written: %s\n", n,
+			       n == cnt ? "OK" : "ERROR");
+			if (n == cnt)
+				return 0;
+			else
+				return 1;
+		} else {
+			return CMD_RET_USAGE;
 		}
-#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);
+		return rcode;
+	}
+}
 
-		} else
-#endif
-		{
-			ide_outb(device, ATA_DEV_HD, ATA_LBA |
-				 ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
-			ide_outb(device, ATA_COMMAND, ATA_CMD_READ);
-		}
+int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	return common_diskboot(cmdtp, "ide", argc, argv);
+}
 
-		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);
-		}
+__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 */
 
-		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;
-		}
+	uchar *led_port = LED_PORT;
 
-		ide_input_data(device, buffer, ATA_SECTORWORDS);
-		(void) ide_inb(device, ATA_STATUS);	/* clear IRQ */
+	if (status)		/* switch LED on        */
+		led_buffer |= led;
+	else			/* switch LED off       */
+		led_buffer &= ~led;
 
-		++n;
-		++blknr;
-		buffer += ATA_BLOCKSIZE;
-	}
-IDE_READ_E:
-	ide_led(DEVICE_LED(device), 0);	/* LED off      */
-	return n;
+	*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)));
 
-ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
-		const void *buffer)
+#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)
 {
-	int device = block_dev->devnum;
-	ulong n = 0;
 	unsigned char c;
+	int i, bus;
 
-#ifdef CONFIG_LBA48
-	unsigned char lba48 = 0;
+#ifdef CONFIG_IDE_8xx_PCCARD
+	extern int ide_devices_found;	/* Initialized in check_ide_device() */
+#endif /* CONFIG_IDE_8xx_PCCARD */
 
-	if (blknr & 0x0000fffff0000000ULL) {
-		/* more than 28 bits used, use 48bit mode */
-		lba48 = 1;
+#ifdef CONFIG_IDE_PREINIT
+	WATCHDOG_RESET();
+
+	if (ide_preinit()) {
+		puts("ide_preinit failed\n");
+		return;
 	}
-#endif
+#endif /* CONFIG_IDE_PREINIT */
 
-	ide_led(DEVICE_LED(device), 1);	/* LED on       */
+	WATCHDOG_RESET();
 
-	/* Select device
+	/*
+	 * Reset the IDE just to be sure.
+	 * Light LED's to show
 	 */
-	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+	ide_led((LED_IDE1 | LED_IDE2), 1);	/* LED's on     */
 
-	while (blkcnt-- > 0) {
+	/* ATAPI Drives seems to need a proper IDE Reset */
+	ide_reset();
 
-		c = ide_wait(device, IDE_TIME_OUT);
+#ifdef CONFIG_IDE_INIT_POSTRESET
+	WATCHDOG_RESET();
 
-		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
+	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
-		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);
+		printf("Bus %d: ", bus);
 
-#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);
+		ide_bus_ok[bus] = 0;
 
-		} else
-#endif
-		{
-			ide_outb(device, ATA_DEV_HD, ATA_LBA |
-				 ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
-			ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE);
-		}
+		/* 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 */
 
-		udelay(50);
+			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('.');
 
-		/* can't take over 500 ms */
-		c = ide_wait(device, IDE_TIME_OUT);
+		} while (c & ATA_STAT_BUSY);
 
-		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;
+		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;
 		}
-
-		ide_output_data(device, buffer, ATA_SECTORWORDS);
-		c = ide_inb(device, ATA_STATUS);	/* clear IRQ */
-		++n;
-		++blknr;
-		buffer += ATA_BLOCKSIZE;
+		WATCHDOG_RESET();
 	}
-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;
+	putc('\n');
 
-	/* reserve space for '\0' */
-	if (len < 2)
-		goto OUT;
+	ide_led((LED_IDE1 | LED_IDE2), 0);	/* LED's off    */
 
-	/* skip leading white space */
-	while ((*src) && (src < end) && (*src == ' '))
-		++src;
+	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]);
 
-	/* copy string, omitting trailing white space */
-	while ((*src) && (src < end)) {
-		*dst++ = *src;
-		if (*src++ != ' ')
-			last = dst;
+		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;
+		}
 	}
-OUT:
-	*last = '\0';
+	WATCHDOG_RESET();
 }
 
 /* ------------------------------------------------------------------------- */
 
-/*
- * Wait until Busy bit is off, or timeout (in ms)
- * Return last status
- */
-static uchar ide_wait(int dev, ulong t)
+#ifdef CONFIG_PARTITIONS
+struct blk_desc *ide_get_dev(int dev)
 {
-	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;
+	return (dev < CONFIG_SYS_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL;
 }
+#endif
 
 /* ------------------------------------------------------------------------- */
 
-#ifdef CONFIG_IDE_RESET
-extern void ide_set_reset(int idereset);
-
-static void ide_reset(void)
+/* 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)
 {
-	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);
+	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;
 
-#endif /* CONFIG_IDE_RESET */
-
-/* ------------------------------------------------------------------------- */
+	debug("in input swap data base for read is %lx\n",
+	      (unsigned long) pbuf);
 
-#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);
+	while (words--) {
+#ifdef __MIPS__
+		*dbuf++ = swab16p((u16 *)pbuf);
+		*dbuf++ = swab16p((u16 *)pbuf);
+#else
+		*dbuf++ = ld_le16(pbuf);
+		*dbuf++ = ld_le16(pbuf);
+#endif /* !MIPS */
+	}
 }
-#endif
-/* ------------------------------------------------------------------------- */
+#endif /* __LITTLE_ENDIAN */
 
-#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)
+__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;
-
-	debug("in output data shorts base for read is %lx\n",
-	      (unsigned long) pbuf);
-
-	while (shorts--) {
+	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 */
 
-__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+#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;
+	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);
+	debug("in input data base for read is %lx\n", (unsigned long) pbuf);
 
-	while (shorts--) {
+	while (words--) {
+		EIEIO;
+		*dbuf++ = *pbuf;
 		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)
+__weak void ide_input_data(int dev, ulong *sect_buf, int words)
 {
-	insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
+#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 */
 
-/*
- * 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 ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
+	       void *buffer)
 {
-	ulong delay = 10 * t;	/* poll every 100 us */
-	uchar c;
+	int device = block_dev->devnum;
+	ulong n = 0;
+	unsigned char c;
+	unsigned char pwrsave = 0;	/* power save */
 
-	/* prevents to read the status before valid */
-	c = ide_inb(dev, ATA_DEV_CTL);
+#ifdef CONFIG_LBA48
+	unsigned char lba48 = 0;
 
-	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;
+	if (blknr & 0x0000fffff0000000ULL) {
+		/* more than 28 bits used, use 48bit mode */
+		lba48 = 1;
 	}
-	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;
+#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
 	 */
-	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));
+	c = ide_wait(device, IDE_TIME_OUT);
 
-	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;
+	if (c & ATA_STAT_BUSY) {
+		printf("IDE read: device %d not ready\n", device);
+		goto IDE_READ_E;
 	}
-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);
+	/* 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);
 
-	if ((key == 0))
-		return 0;	/* ok device ready */
+	c = ide_wait(device, IDE_TIME_OUT);	/* can't take over 500 ms */
 
-	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 (c & ATA_STAT_BUSY) {
+		printf("IDE read: device %d not ready\n", device);
+		goto IDE_READ_E;
 	}
-	if (asc == 0x3a) {
-		debug("Media not present\n");
-		goto error;
+	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;
 	}
 
-	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;
-}
 
+	while (blkcnt-- > 0) {
 
-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;
+		c = ide_wait(device, IDE_TIME_OUT);
 
-	device = dev_desc->devnum;
-	dev_desc->type = DEV_TYPE_UNKNOWN;	/* not yet valid */
-	dev_desc->block_read = atapi_read;
+		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);
 
-	memset(ccb, 0, sizeof(ccb));
-	memset(iobuf, 0, sizeof(iobuf));
+#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);
 
-	ccb[0] = ATAPI_CMD_INQUIRY;
-	ccb[4] = 40;		/* allocation Legnth */
-	c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *) iobuf, 40);
+		} else
+#endif
+		{
+			ide_outb(device, ATA_DEV_HD, ATA_LBA |
+				 ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
+			ide_outb(device, ATA_COMMAND, ATA_CMD_READ);
+		}
 
-	debug("ATAPI_CMD_INQUIRY returned %x\n", c);
-	if (c != 0)
-		return;
+		udelay(50);
 
-	/* 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);
+		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);
+		}
 
-	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 ((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;
+		}
 
-	if ((iobuf[1] & 0x80) == 0x80)
-		dev_desc->removable = 1;
-	else
-		dev_desc->removable = 0;
+		ide_input_data(device, buffer, ATA_SECTORWORDS);
+		(void) ide_inb(device, ATA_STATUS);	/* clear IRQ */
 
-	memset(ccb, 0, sizeof(ccb));
-	memset(iobuf, 0, sizeof(iobuf));
-	ccb[0] = ATAPI_CMD_START_STOP;
-	ccb[4] = 0x03;		/* start */
+		++n;
+		++blknr;
+		buffer += ATA_BLOCKSIZE;
+	}
+IDE_READ_E:
+	ide_led(DEVICE_LED(device), 0);	/* LED off      */
+	return n;
+}
 
-	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);
+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;
 
-	debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c);
-	if (c != 0)
-		return;
+#ifdef CONFIG_LBA48
+	unsigned char lba48 = 0;
 
-	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;
+	if (blknr & 0x0000fffff0000000ULL) {
+		/* more than 28 bits used, use 48bit mode */
+		lba48 = 1;
+	}
+#endif
 
-	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]);
+	ide_led(DEVICE_LED(device), 1);	/* LED on       */
 
-	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;
-}
+	/* Select device
+	 */
+	ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
 
+	while (blkcnt-- > 0) {
+		c = ide_wait(device, IDE_TIME_OUT);
 
-/*
- * 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)
+		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);
 
-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;
+#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);
 
-	debug("atapi_read dev %d start " LBAF " blocks " LBAF
-	      " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer);
+		} else
+#endif
+		{
+			ide_outb(device, ATA_DEV_HD, ATA_LBA |
+				 ATA_DEVICE(device) | ((blknr >> 24) & 0xF));
+			ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE);
+		}
 
-	do {
-		if (blkcnt > ATAPI_READ_MAX_BLOCK)
-			cnt = ATAPI_READ_MAX_BLOCK;
-		else
-			cnt = blkcnt;
+		udelay(50);
 
-		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 */
+		/* can't take over 500 ms */
+		c = ide_wait(device, IDE_TIME_OUT);
 
-		if (atapi_issue_autoreq(device, ccb, 12,
-					(unsigned char *) buffer,
-					cnt * ATAPI_READ_BLOCK_SIZE)
-		    == 0xFF) {
-			return n;
+		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;
 		}
-		n += cnt;
-		blkcnt -= cnt;
-		blknr += cnt;
-		buffer += (cnt * ATAPI_READ_BLOCK_SIZE);
-	} while (blkcnt > 0);
+
+		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;
 }
 
 /* ------------------------------------------------------------------------- */
 
-#endif /* CONFIG_ATAPI */
+#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
+/* ------------------------------------------------------------------------- */
 
 U_BOOT_CMD(ide, 5, 1, do_ide,
 	   "IDE sub-system",
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 13/44] dm: sata: Fix code style problems in cmd/sata.c
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (11 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 12/44] dm: ide: Remove the forward declarations Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 14/44] dm: scsi: Rename CONFIG_CMD_SCSI to CONFIG_SCSI Simon Glass
                   ` (30 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This file has a few coding style problems. Fix these to make future updates
easier.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/sata.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/cmd/sata.c b/cmd/sata.c
index 8748cce..b1a64d9 100644
--- a/cmd/sata.c
+++ b/cmd/sata.c
@@ -105,25 +105,27 @@ 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) {
+		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);
+				printf("SATA device %d: ", i);
 				dev_print(&sata_dev_desc[i]);
 			}
 			return 0;
-		} else if (strncmp(argv[1],"dev", 3) == 0) {
-			if ((sata_curr_device < 0) || (sata_curr_device >= CONFIG_SYS_SATA_MAX_DEVICE)) {
+		} 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;
 			}
 			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) {
+		} else if (strncmp(argv[1], "part", 4) == 0) {
 			int dev, ok;
 
 			for (ok = 0, dev = 0; dev < CONFIG_SYS_SATA_MAX_DEVICE; ++dev) {
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 14/44] dm: scsi: Rename CONFIG_CMD_SCSI to CONFIG_SCSI
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (12 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 13/44] dm: sata: Fix code style problems in cmd/sata.c Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 15/44] dm: blk: Add a legacy block interface Simon Glass
                   ` (29 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This option currently enables both the command and the SCSI functionality.
Rename the existing option to CONFIG_SCSI since most of the code relates
to the feature.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 README                                     | 4 ++--
 api/api_storage.c                          | 2 +-
 arch/arm/include/asm/arch-ls102xa/config.h | 2 +-
 board/mpl/pip405/README                    | 6 +++---
 cmd/Makefile                               | 4 ++--
 cmd/disk.c                                 | 2 +-
 common/board_r.c                           | 4 ++--
 disk/part.c                                | 2 +-
 drivers/block/sym53c8xx.c                  | 2 +-
 fs/fat/fat.c                               | 2 +-
 include/config_cmd_all.h                   | 2 +-
 include/config_distro_bootcmd.h            | 6 +++---
 include/config_fallbacks.h                 | 2 +-
 include/configs/MPC8544DS.h                | 2 +-
 include/configs/MPC8572DS.h                | 2 +-
 include/configs/MPC8610HPCD.h              | 2 +-
 include/configs/MPC8641HPCN.h              | 2 +-
 include/configs/PIP405.h                   | 2 +-
 include/configs/am57xx_evm.h               | 2 +-
 include/configs/cm_t54.h                   | 2 +-
 include/configs/db-88f6820-gp.h            | 2 +-
 include/configs/dra7xx_evm.h               | 2 +-
 include/configs/efi-x86.h                  | 2 +-
 include/configs/galileo.h                  | 2 +-
 include/configs/highbank.h                 | 2 +-
 include/configs/ls1043aqds.h               | 2 +-
 include/configs/ls2080aqds.h               | 2 +-
 include/configs/ls2080ardb.h               | 2 +-
 include/configs/omap5_uevm.h               | 2 +-
 include/configs/qemu-x86.h                 | 2 +-
 include/configs/sunxi-common.h             | 2 +-
 include/configs/x86-common.h               | 2 +-
 include/configs/xilinx_zynqmp.h            | 2 +-
 33 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/README b/README
index 597d615..18caa97 100644
--- 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:
diff --git a/api/api_storage.c b/api/api_storage.c
index 8c30c56..d425a9a 100644
--- a/api/api_storage.c
+++ b/api/api_storage.c
@@ -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;
diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h
index ab4b697..cde5923 100644
--- a/arch/arm/include/asm/arch-ls102xa/config.h
+++ b/arch/arm/include/asm/arch-ls102xa/config.h
@@ -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
diff --git a/board/mpl/pip405/README b/board/mpl/pip405/README
index e900c56..f039817 100644
--- a/board/mpl/pip405/README
+++ b/board/mpl/pip405/README
@@ -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:
diff --git a/cmd/Makefile b/cmd/Makefile
index ba04197..2aaf978 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -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
@@ -157,7 +157,7 @@ endif # !CONFIG_SPL_BUILD
 
 ifdef CONFIG_SPL_BUILD
 ifdef CONFIG_SPL_SATA_SUPPORT
-obj-$(CONFIG_CMD_SCSI) += scsi.o
+obj-$(CONFIG_SCSI) += scsi.o
 endif
 endif # CONFIG_SPL_BUILD
 
diff --git a/cmd/disk.c b/cmd/disk.c
index 2fd1717..fcc4123 100644
--- a/cmd/disk.c
+++ b/cmd/disk.c
@@ -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[])
diff --git a/common/board_r.c b/common/board_r.c
index ad02549..d959ad3 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -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
diff --git a/disk/part.c b/disk/part.c
index 0aff954..a1d1d92 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -28,7 +28,7 @@ const struct block_drvr block_drvr[] = {
 #if defined(CONFIG_CMD_SATA)
 	{.name = "sata", .get_dev = sata_get_dev, },
 #endif
-#if defined(CONFIG_CMD_SCSI)
+#if defined(CONFIG_SCSI)
 	{ .name = "scsi", .get_dev = scsi_get_dev, },
 #endif
 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
diff --git a/drivers/block/sym53c8xx.c b/drivers/block/sym53c8xx.c
index c7c40af..5daede7 100644
--- a/drivers/block/sym53c8xx.c
+++ b/drivers/block/sym53c8xx.c
@@ -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
 /*
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 600a90e..826bd85 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -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:  ");
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index e858e55..a8a3307 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -60,7 +60,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_SNTP		/* SNTP support			*/
 #define CONFIG_CMD_SPI		/* SPI utility			*/
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index ad9045e..f419a4b 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -144,7 +144,7 @@
 	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 \
@@ -164,9 +164,9 @@
 #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
diff --git a/include/config_fallbacks.h b/include/config_fallbacks.h
index 6b6ec00..245bd4d 100644
--- a/include/config_fallbacks.h
+++ b/include/config_fallbacks.h
@@ -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) || \
diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h
index 2372d5f..7ba3d5f 100644
--- a/include/configs/MPC8544DS.h
+++ b/include/configs/MPC8544DS.h
@@ -383,7 +383,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
     #define CONFIG_CMD_EXT2
 #endif
 
diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h
index 95f59e0..0daf85c 100644
--- a/include/configs/MPC8572DS.h
+++ b/include/configs/MPC8572DS.h
@@ -586,7 +586,7 @@
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_CMD_EXT2
 #endif
 
diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h
index ac219d1..65d5c2b 100644
--- a/include/configs/MPC8610HPCD.h
+++ b/include/configs/MPC8610HPCD.h
@@ -464,7 +464,7 @@
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_CMD_EXT2
 #define CONFIG_CMD_USB
 #endif
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h
index cd8d91f..6a85890 100644
--- a/include/configs/MPC8641HPCN.h
+++ b/include/configs/MPC8641HPCN.h
@@ -620,7 +620,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
     #define CONFIG_CMD_EXT2
     #define CONFIG_CMD_USB
 #endif
diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h
index b5959c8..46eb0a8 100644
--- a/include/configs/PIP405.h
+++ b/include/configs/PIP405.h
@@ -49,7 +49,7 @@
 #define CONFIG_CMD_I2C
 #define CONFIG_CMD_REGINFO
 #define CONFIG_CMD_FDC
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_CMD_FAT
 #define CONFIG_CMD_DATE
 #define CONFIG_CMD_USB
diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index 1fffdb1..d982cd1 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -79,7 +79,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
diff --git a/include/configs/cm_t54.h b/include/configs/cm_t54.h
index c8c67c4..249e573 100644
--- a/include/configs/cm_t54.h
+++ b/include/configs/cm_t54.h
@@ -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
diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h
index ef14132..d838622 100644
--- a/include/configs/db-88f6820-gp.h
+++ b/include/configs/db-88f6820-gp.h
@@ -36,7 +36,7 @@
 #define CONFIG_CMD_MMC
 #define CONFIG_CMD_PCI
 #define CONFIG_CMD_PING
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_CMD_SF
 #define CONFIG_CMD_SPI
 #define CONFIG_CMD_TFTPPUT
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index 7734e8d..653c0e3 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -250,7 +250,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
diff --git a/include/configs/efi-x86.h b/include/configs/efi-x86.h
index 6dd0b32..95e46c5 100644
--- a/include/configs/efi-x86.h
+++ b/include/configs/efi-x86.h
@@ -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
 
diff --git a/include/configs/galileo.h b/include/configs/galileo.h
index 14a42b1..9fe543c 100644
--- a/include/configs/galileo.h
+++ b/include/configs/galileo.h
@@ -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
diff --git a/include/configs/highbank.h b/include/configs/highbank.h
index 510741b..e845465 100644
--- a/include/configs/highbank.h
+++ b/include/configs/highbank.h
@@ -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
diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h
index 7c19122..9421c49 100644
--- a/include/configs/ls1043aqds.h
+++ b/include/configs/ls1043aqds.h
@@ -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_CMD_FAT
 #define CONFIG_CMD_EXT2
 #define CONFIG_DOS_PARTITION
diff --git a/include/configs/ls2080aqds.h b/include/configs/ls2080aqds.h
index 91fad0a..ae9dec8 100644
--- a/include/configs/ls2080aqds.h
+++ b/include/configs/ls2080aqds.h
@@ -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_CMD_FAT
 #define CONFIG_CMD_EXT2
 #define CONFIG_DOS_PARTITION
diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h
index 15a1172..2e3aeca 100644
--- a/include/configs/ls2080ardb.h
+++ b/include/configs/ls2080ardb.h
@@ -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_CMD_FAT
 #define CONFIG_CMD_EXT2
 #define CONFIG_DOS_PARTITION
diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h
index a5cfa0c..d924ce3 100644
--- a/include/configs/omap5_uevm.h
+++ b/include/configs/omap5_uevm.h
@@ -131,7 +131,7 @@
 /* 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
diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h
index b0d2ffe..476d37d 100644
--- a/include/configs/qemu-x86.h
+++ b/include/configs/qemu-x86.h
@@ -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}
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 8f11eb9..8aff3a5 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -125,7 +125,7 @@
 #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
diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h
index ea815c2..6e4e3a9 100644
--- a/include/configs/x86-common.h
+++ b/include/configs/x86-common.h
@@ -106,7 +106,7 @@
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_TIME
 #define CONFIG_CMD_GETTIME
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 
 #define CONFIG_CMD_FAT
 #define CONFIG_CMD_EXT2
diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h
index 8cea610..1f85a20 100644
--- a/include/configs/xilinx_zynqmp.h
+++ b/include/configs/xilinx_zynqmp.h
@@ -231,7 +231,7 @@
 #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)
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 15/44] dm: blk: Add a legacy block interface
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (13 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 14/44] dm: scsi: Rename CONFIG_CMD_SCSI to CONFIG_SCSI Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:28   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 16/44] dm: systemace: " Simon Glass
                   ` (28 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

There is quite a bit of duplicated common code related to block devices
in the IDE and SCSI implementations.

Create some helper functions that can be used to reduce the duplication.
These rely on a linker list of interface-type drivers

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/Makefile     |   4 +
 drivers/block/blk_legacy.c | 258 +++++++++++++++++++++++++++++++++++++++++++++
 include/blk.h              | 193 +++++++++++++++++++++++++++++++++
 3 files changed, 455 insertions(+)
 create mode 100644 drivers/block/blk_legacy.c

diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 3f75934..436b79f 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -7,6 +7,10 @@
 
 obj-$(CONFIG_BLK) += blk-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
diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c
new file mode 100644
index 0000000..8da06ef
--- /dev/null
+++ b/drivers/block/blk_legacy.c
@@ -0,0 +1,258 @@
+/*
+ * 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 = blk_driver_lookup_type(if_type);
+	struct blk_desc *desc;
+	int devnum, ok;
+
+	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 (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_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/include/blk.h b/include/blk.h
index 263a791..ed868ef 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -346,6 +346,199 @@ 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).
+	 *
+	 * @desc:	Block device descriptor
+	 * @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 (*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
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 16/44] dm: systemace: Add a legacy block interface
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (14 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 15/44] dm: blk: Add a legacy block interface Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:31   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 17/44] dm: sandbox: Add a legacy host " Simon Glass
                   ` (27 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add a legacy block interface for systemace.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/systemace.c | 14 ++++++++++++++
 include/blk.h             |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index 09fe834..0d8e26f 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -132,6 +132,13 @@ struct blk_desc *systemace_get_dev(int dev)
 }
 #endif
 
+static int systemace_get_devp(int dev, struct blk_desc **descp)
+{
+	*descp = systemace_get_dev(dev);
+
+	return 0;
+}
+
 /*
  * This function is called (by dereferencing the block_read pointer in
  * the dev_desc) to read blocks of data. The return value is the
@@ -257,3 +264,10 @@ static unsigned long systemace_read(struct blk_desc *block_dev,
 
 	return blkcnt;
 }
+
+U_BOOT_LEGACY_BLK(systemace) = {
+	.if_typename	= "ace",
+	.if_type	= IF_TYPE_SYSTEMACE,
+	.max_devs	= 1,
+	.get_dev	= systemace_get_devp,
+};
diff --git a/include/blk.h b/include/blk.h
index ed868ef..12be6aa 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -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 */
 };
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 17/44] dm: sandbox: Add a legacy host block interface
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (15 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 16/44] dm: systemace: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 18/44] dm: usb: Add a legacy block interface for USB storage Simon Glass
                   ` (26 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add a legacy block interface for sandbox host.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/sandbox.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 6d41508..2b6a893 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -239,4 +239,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
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 18/44] dm: usb: Add a legacy block interface for USB storage
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (16 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 17/44] dm: sandbox: Add a legacy host " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 19/44] dm: mmc: Add a legacy block interface for MMC Simon Glass
                   ` (25 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add a legacy block interface for USB storage.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/usb_storage.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 9285c95..80bf3db 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -1555,4 +1555,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
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 19/44] dm: mmc: Add a legacy block interface for MMC
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (17 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 18/44] dm: usb: Add a legacy block interface for USB storage Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 20/44] dm: mmc: Add an implementation of the 'devnum' functions Simon Glass
                   ` (24 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add a legacy block interface for MMC.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/mmc/mmc.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d3c22ab..024368c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1582,14 +1582,31 @@ void mmc_destroy(struct mmc *mmc)
 	free(mmc);
 }
 
+static int mmc_get_devp(int dev, struct blk_desc **descp)
+{
+	struct mmc *mmc = find_mmc_device(dev);
+	int ret;
+
+	if (!mmc)
+		return -ENODEV;
+	ret = mmc_init(mmc);
+	if (ret)
+		return ret;
+
+	*descp = &mmc->block_dev;
+
+	return 0;
+}
+
 #ifdef CONFIG_PARTITIONS
 struct blk_desc *mmc_get_dev(int dev)
 {
-	struct mmc *mmc = find_mmc_device(dev);
-	if (!mmc || mmc_init(mmc))
+	struct blk_desc *desc;
+
+	if (mmc_get_devp(dev, &desc))
 		return NULL;
 
-	return &mmc->block_dev;
+	return desc;
 }
 #endif
 
@@ -1965,3 +1982,10 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
 			  enable);
 }
 #endif
+
+U_BOOT_LEGACY_BLK(mmc) = {
+	.if_typename	= "mmc",
+	.if_type	= IF_TYPE_MMC,
+	.max_devs	= -1,
+	.get_dev	= mmc_get_devp,
+};
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 20/44] dm: mmc: Add an implementation of the 'devnum' functions
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (18 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 19/44] dm: mmc: Add a legacy block interface for MMC Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:40   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 21/44] dm: scsi: Separate the non-command code into its own file Simon Glass
                   ` (23 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Now that the MMC code accesses devices by number, we can implement this same
interface for driver model, allowing MMC to support using driver model for
block devices.

Add the required functions to the uclass.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/blk-uclass.c | 280 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 280 insertions(+)

diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 617db22..3687b9a 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -11,6 +11,286 @@
 #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_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_first_device(int if_type, struct udevice **devp)
 {
 	struct blk_desc *desc;
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 21/44] dm: scsi: Separate the non-command code into its own file
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (19 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 20/44] dm: mmc: Add an implementation of the 'devnum' functions Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 22/44] dm: ide: " Simon Glass
                   ` (22 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

At present the SCSI command code includes both the command-processing code
and the core SCSI functions and data structures.

Separate the latter into its own file, adding functions as needed to avoid
the command code accessing data structures directly. This functions use the
new legacy block functions.

With this commit:
- There is no CONFIG option referenced from the command code
- The concept of a 'current SCSI device' is confined to the command code

This will make it easier to convert this code to driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/Makefile    |   6 -
 cmd/scsi.c      | 626 +++-----------------------------------------------------
 common/Makefile |   4 +
 common/scsi.c   | 567 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 600 insertions(+), 603 deletions(-)
 create mode 100644 common/scsi.c

diff --git a/cmd/Makefile b/cmd/Makefile
index 2aaf978..eb24704 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -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_SCSI) += scsi.o
-endif
-endif # CONFIG_SPL_BUILD
-
 obj-$(CONFIG_CMD_BLOB) += blob.o
 
 # core command
diff --git a/cmd/scsi.c b/cmd/scsi.c
index 751fc58..387ca1a 100644
--- a/cmd/scsi.c
+++ b/cmd/scsi.c
@@ -10,355 +10,27 @@
  */
 #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];
-
-/* 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 */
-}
-
-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;
-}
-
-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");
@@ -367,23 +39,15 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 			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]);
-			}
+			blk_list_devices(IF_TYPE_SCSI);
 			return 0;
 		}
 		if (strncmp(argv[1], "dev", 3) == 0) {
-			if (scsi_curr_dev < 0 ||
-			    scsi_curr_dev >= CONFIG_SYS_SCSI_MAX_DEVICE) {
+			if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) {
 				printf("\nno SCSI devices available\n");
-				return 1;
+				return CMD_RET_FAILURE;
 			}
-			printf("\n    Device %d: ", scsi_curr_dev);
-			dev_print(&scsi_dev_desc[scsi_curr_dev]);
+
 			return 0;
 		}
 		if (strncmp(argv[1], "scan", 4) == 0) {
@@ -391,46 +55,32 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 			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)
+			if (blk_list_part(IF_TYPE_SCSI))
 				printf("\nno SCSI devices available\n");
-			return 1;
+			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;
+
+			if (!blk_show_device(IF_TYPE_SCSI, dev)) {
+				scsi_curr_dev = dev;
+				printf("... is now current device\n");
+			} else {
+				return CMD_RET_FAILURE;
 			}
-			printf("\n    Device %d: ", dev);
-			dev_print(&scsi_dev_desc[dev]);
-			if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
-				return 1;
-			scsi_curr_dev = dev;
-			printf("... is now current device\n");
 			return 0;
 		}
 		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;
+
+			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:
@@ -440,10 +90,11 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 			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);
+			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;
@@ -452,10 +103,11 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 			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);
+			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;
@@ -483,223 +135,3 @@ U_BOOT_CMD(
 	"boot from SCSI device",
 	"loadAddr dev:part"
 );
-#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;
-		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) {
-					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
-}
diff --git a/common/Makefile b/common/Makefile
index 9a4b817..563bb94 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -83,6 +83,7 @@ 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_SCSI) += scsi.o
 obj-$(CONFIG_UPDATE_TFTP) += update.o
 obj-$(CONFIG_DFU_TFTP) += update.o
 obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
@@ -111,6 +112,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
diff --git a/common/scsi.c b/common/scsi.c
new file mode 100644
index 0000000..a336a10
--- /dev/null
+++ b/common/scsi.c
@@ -0,0 +1,567 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.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 */
+}
+
+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;
+}
+
+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
+
+/* 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;
+		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) {
+					/*
+					 * 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
+}
+
+U_BOOT_LEGACY_BLK(scsi) = {
+	.if_typename	= "sata",
+	.if_type	= IF_TYPE_SCSI,
+	.max_devs	= CONFIG_SYS_SCSI_MAX_DEVICE,
+	.desc		= scsi_dev_desc,
+};
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 22/44] dm: ide: Separate the non-command code into its own file
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (20 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 21/44] dm: scsi: Separate the non-command code into its own file Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 23/44] dm: sata: " Simon Glass
                   ` (21 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

At present the IDE command code includes both the command-processing code
and the core IDE functions and data structures.

Separate the latter into its own file, adding functions as needed to avoid
the command code accessing data structures directly.

With this commit:
- Most CONFIG option are referenced from the non-command code
- The concept of a 'current IDE device' is confined to the command code

This will make it easier to convert this code to driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/ide.c       | 1297 +------------------------------------------------------
 common/Makefile |    1 +
 common/ide.c    | 1206 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1228 insertions(+), 1276 deletions(-)
 create mode 100644 common/ide.c

diff --git a/cmd/ide.c b/cmd/ide.c
index db26f43..c942744 100644
--- a/cmd/ide.c
+++ b/cmd/ide.c
@@ -29,717 +29,9 @@
 # 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];
-/* ------------------------------------------------------------------------- */
-
-#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;
-
-	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);
-}
-#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
-}
-
-/* ------------------------------------------------------------------------- */
-
 int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
 	int rcode = 0;
@@ -759,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);
 
-			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);
 
-			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;
@@ -841,7 +95,6 @@ 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
@@ -856,11 +109,8 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 			       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");
@@ -884,8 +134,8 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 			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");
@@ -906,511 +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
-}
-
-/* ------------------------------------------------------------------------- */
-
-__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 */
-
-/* ------------------------------------------------------------------------- */
-
-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;
-}
-
-/* ------------------------------------------------------------------------- */
-
-#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
-/* ------------------------------------------------------------------------- */
-
 U_BOOT_CMD(ide, 5, 1, do_ide,
 	   "IDE sub-system",
 	   "reset - reset IDE controller\n"
diff --git a/common/Makefile b/common/Makefile
index 563bb94..f648423 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -133,6 +133,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
diff --git a/common/ide.c b/common/ide.c
new file mode 100644
index 0000000..adc1966
--- /dev/null
+++ b/common/ide.c
@@ -0,0 +1,1206 @@
+/*
+ * (C) Copyright 2000-2011
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <ata.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;
+		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]);
+		}
+	}
+	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 */
+
+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;
+}
+
+#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
+
+U_BOOT_LEGACY_BLK(ide) = {
+	.if_typename	= "ide",
+	.if_type	= IF_TYPE_IDE,
+	.max_devs	= CONFIG_SYS_IDE_MAXDEVICE,
+	.desc		= ide_dev_desc,
+};
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 23/44] dm: sata: Separate the non-command code into its own file
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (21 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 22/44] dm: ide: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 24/44] dm: disk: Use legacy block driver info for block device access Simon Glass
                   ` (20 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

At present the SATA command code includes both the command-processing code
and the core SATA functions and data structures.

Separate the latter into its own file, adding functions as needed to avoid
the command code accessing data structures directly.

With this commit:
- All CONFIG option are referenced from the non-command code
- The concept of a 'current SATA device' is confined to the command code

This will make it easier to convert this code to driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/sata.c      | 138 ++++++++------------------------------------------------
 common/Makefile |   1 +
 common/sata.c   |  86 +++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+), 118 deletions(-)
 create mode 100644 common/sata.c

diff --git a/cmd/sata.c b/cmd/sata.c
index b1a64d9..d18b523 100644
--- a/cmd/sata.c
+++ b/cmd/sata.c
@@ -16,70 +16,6 @@
 #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[])
 {
@@ -106,70 +42,39 @@ static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		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]);
-			}
+			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;
+			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) {
+			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;
 		}
@@ -185,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");
@@ -204,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");
diff --git a/common/Makefile b/common/Makefile
index f648423..00d9dba 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -83,6 +83,7 @@ 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
diff --git a/common/sata.c b/common/sata.c
new file mode 100644
index 0000000..1d52fcb
--- /dev/null
+++ b/common/sata.c
@@ -0,0 +1,86 @@
+/*
+ * 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 <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
+
+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]);
+		}
+	}
+
+	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")));
+
+U_BOOT_LEGACY_BLK(sata) = {
+	.if_typename	= "sata",
+	.if_type	= IF_TYPE_SATA,
+	.max_devs	= CONFIG_SYS_SATA_MAX_DEVICE,
+	.desc		= sata_dev_desc,
+};
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 24/44] dm: disk: Use legacy block driver info for block device access
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (22 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 23/44] dm: sata: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 25/44] dm: usb: Drop the get_dev() function Simon Glass
                   ` (19 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Instead of calling xx_get_dev() functions for each interface type, use the
new legacy block driver which can provide the device through its interface.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 disk/part.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index a1d1d92..ec00feb 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -72,7 +72,6 @@ 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;
 	int ret;
@@ -86,16 +85,16 @@ static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
 #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);
+			struct blk_desc *dev_desc;
+
+			dev_desc = blk_get_devnum_by_typename(name, dev);
 			if (!dev_desc)
 				return NULL;
 			if (hwpart == 0 && !select_hwpart)
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 25/44] dm: usb: Drop the get_dev() function
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (23 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 24/44] dm: disk: Use legacy block driver info for block device access Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 26/44] dm: ide: " Simon Glass
                   ` (18 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This function is implemented by the legacy block functions now. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 board/cm5200/fwupdate.c |  2 +-
 cmd/usb.c               | 16 ++++++++++------
 common/spl/spl_usb.c    |  2 +-
 common/usb_storage.c    | 17 -----------------
 disk/part.c             |  2 +-
 drivers/Makefile        |  1 +
 include/part.h          |  2 --
 include/usb.h           |  1 -
 8 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/board/cm5200/fwupdate.c b/board/cm5200/fwupdate.c
index 2ed90de..4740c83 100644
--- a/board/cm5200/fwupdate.c
+++ b/board/cm5200/fwupdate.c
@@ -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;
 	}
diff --git a/cmd/usb.c b/cmd/usb.c
index 9ed5dc6..78e3e5b 100644
--- a/cmd/usb.c
+++ b/cmd/usb.c
@@ -719,7 +719,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) {
@@ -732,7 +733,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++;
@@ -758,7 +759,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");
@@ -779,7 +781,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");
@@ -792,7 +795,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;
@@ -806,7 +809,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;
diff --git a/common/spl/spl_usb.c b/common/spl/spl_usb.c
index c42848e..04fa667 100644
--- a/common/spl/spl_usb.c
+++ b/common/spl/spl_usb.c
@@ -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
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 80bf3db..f2da3a3 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -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(".");
diff --git a/disk/part.c b/disk/part.c
index ec00feb..7a1f75e 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -32,7 +32,7 @@ const struct block_drvr block_drvr[] = {
 	{ .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, },
+	{ .name = "usb", },
 #endif
 #if defined(CONFIG_MMC)
 	{
diff --git a/drivers/Makefile b/drivers/Makefile
index 6900097..696b3ac 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -36,6 +36,7 @@ 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/
 
 else
 
diff --git a/include/part.h b/include/part.h
index dc8e72e..9be75d2 100644
--- a/include/part.h
+++ b/include/part.h
@@ -76,7 +76,6 @@ 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);
 
 /**
@@ -178,7 +177,6 @@ static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
 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; }
diff --git a/include/usb.h b/include/usb.h
index 5adad36..02a0ccd 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -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);
 
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 26/44] dm: ide: Drop the get_dev() function
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (24 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 25/44] dm: usb: Drop the get_dev() function Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 27/44] dm: mmc: " Simon Glass
                   ` (17 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This function is implemented by the legacy block functions now. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/ide.c   | 7 -------
 disk/part.c    | 2 +-
 include/part.h | 2 --
 3 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/common/ide.c b/common/ide.c
index adc1966..5dc90d4 100644
--- a/common/ide.c
+++ b/common/ide.c
@@ -890,13 +890,6 @@ void ide_init(void)
 	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)
diff --git a/disk/part.c b/disk/part.c
index 7a1f75e..a3a476e 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -23,7 +23,7 @@
 
 const struct block_drvr block_drvr[] = {
 #if defined(CONFIG_CMD_IDE)
-	{ .name = "ide", .get_dev = ide_get_dev, },
+	{ .name = "ide", },
 #endif
 #if defined(CONFIG_CMD_SATA)
 	{.name = "sata", .get_dev = sata_get_dev, },
diff --git a/include/part.h b/include/part.h
index 9be75d2..f005a7c 100644
--- a/include/part.h
+++ b/include/part.h
@@ -73,7 +73,6 @@ 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 *mmc_get_dev(int dev);
@@ -174,7 +173,6 @@ 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 *mmc_get_dev(int dev) { return NULL; }
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 27/44] dm: mmc: Drop the get_dev() function
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (25 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 26/44] dm: ide: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 28/44] dm: scsi: " Simon Glass
                   ` (16 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This function is implemented by the legacy block functions now. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/mmc.c         |  2 +-
 disk/part.c       |  1 -
 drivers/mmc/mmc.c | 16 ++--------------
 include/part.h    |  2 --
 4 files changed, 3 insertions(+), 18 deletions(-)

diff --git a/cmd/mmc.c b/cmd/mmc.c
index 39ef072..0fed790 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -432,7 +432,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;
diff --git a/disk/part.c b/disk/part.c
index a3a476e..c294866 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -37,7 +37,6 @@ const struct block_drvr block_drvr[] = {
 #if defined(CONFIG_MMC)
 	{
 		.name = "mmc",
-		.get_dev = mmc_get_dev,
 		.select_hwpart = mmc_select_hwpart,
 	},
 #endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 024368c..185d7b2 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1582,7 +1582,7 @@ void mmc_destroy(struct mmc *mmc)
 	free(mmc);
 }
 
-static int mmc_get_devp(int dev, struct blk_desc **descp)
+static int mmc_get_dev(int dev, struct blk_desc **descp)
 {
 	struct mmc *mmc = find_mmc_device(dev);
 	int ret;
@@ -1598,18 +1598,6 @@ static int mmc_get_devp(int dev, struct blk_desc **descp)
 	return 0;
 }
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *mmc_get_dev(int dev)
-{
-	struct blk_desc *desc;
-
-	if (mmc_get_devp(dev, &desc))
-		return NULL;
-
-	return desc;
-}
-#endif
-
 /* board-specific MMC power initializations. */
 __weak void board_mmc_power_init(void)
 {
@@ -1987,5 +1975,5 @@ U_BOOT_LEGACY_BLK(mmc) = {
 	.if_typename	= "mmc",
 	.if_type	= IF_TYPE_MMC,
 	.max_devs	= -1,
-	.get_dev	= mmc_get_devp,
+	.get_dev	= mmc_get_dev,
 };
diff --git a/include/part.h b/include/part.h
index f005a7c..45c6476 100644
--- a/include/part.h
+++ b/include/part.h
@@ -75,7 +75,6 @@ typedef struct disk_partition {
 struct blk_desc *blk_get_dev(const char *ifname, int dev);
 struct blk_desc *sata_get_dev(int dev);
 struct blk_desc *scsi_get_dev(int dev);
-struct blk_desc *mmc_get_dev(int dev);
 
 /**
  * mmc_select_hwpart() - Select the MMC hardware partiion on an MMC device
@@ -175,7 +174,6 @@ static inline struct blk_desc *blk_get_dev(const char *ifname, 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 *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; }
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 28/44] dm: scsi: Drop the get_dev() function
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (26 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 27/44] dm: mmc: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 29/44] dm: sata: " Simon Glass
                   ` (15 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This function is implemented by the legacy block functions now. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/scsi.c         | 7 -------
 common/spl/spl_sata.c | 2 +-
 disk/part.c           | 2 +-
 include/part.h        | 2 --
 4 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/common/scsi.c b/common/scsi.c
index a336a10..5b6531f 100644
--- a/common/scsi.c
+++ b/common/scsi.c
@@ -327,13 +327,6 @@ void scsi_init(void)
 }
 #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
-
 /* copy src to dest, skipping leading and trailing blanks
  * and null terminate the string
  */
diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c
index 1719946..9d8cc7c 100644
--- a/common/spl/spl_sata.c
+++ b/common/spl/spl_sata.c
@@ -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;
 	}
diff --git a/disk/part.c b/disk/part.c
index c294866..182d706 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -29,7 +29,7 @@ const struct block_drvr block_drvr[] = {
 	{.name = "sata", .get_dev = sata_get_dev, },
 #endif
 #if defined(CONFIG_SCSI)
-	{ .name = "scsi", .get_dev = scsi_get_dev, },
+	{ .name = "scsi", },
 #endif
 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
 	{ .name = "usb", },
diff --git a/include/part.h b/include/part.h
index 45c6476..ec2dad8 100644
--- a/include/part.h
+++ b/include/part.h
@@ -74,7 +74,6 @@ typedef struct disk_partition {
  */
 struct blk_desc *blk_get_dev(const char *ifname, int dev);
 struct blk_desc *sata_get_dev(int dev);
-struct blk_desc *scsi_get_dev(int dev);
 
 /**
  * mmc_select_hwpart() - Select the MMC hardware partiion on an MMC device
@@ -173,7 +172,6 @@ extern const struct block_drvr block_drvr[];
 static inline struct blk_desc *blk_get_dev(const char *ifname, 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 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; }
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 29/44] dm: sata: Drop the get_dev() function
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (27 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 28/44] dm: scsi: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 30/44] dm: systemace: " Simon Glass
                   ` (14 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This function is implemented by the legacy block functions now. Drop it.

We cannot yet make sata_dev_desc[] private to common/sata.c as it is used by
the SATA drivers. This will require the SATA interface to be reworked.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 disk/part.c    | 2 +-
 include/part.h | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index 182d706..30ae030 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -26,7 +26,7 @@ const struct block_drvr block_drvr[] = {
 	{ .name = "ide", },
 #endif
 #if defined(CONFIG_CMD_SATA)
-	{.name = "sata", .get_dev = sata_get_dev, },
+	{.name = "sata", },
 #endif
 #if defined(CONFIG_SCSI)
 	{ .name = "scsi", },
diff --git a/include/part.h b/include/part.h
index ec2dad8..03d4b3d 100644
--- a/include/part.h
+++ b/include/part.h
@@ -73,7 +73,6 @@ typedef struct disk_partition {
  *	   error occurred.
  */
 struct blk_desc *blk_get_dev(const char *ifname, int dev);
-struct blk_desc *sata_get_dev(int dev);
 
 /**
  * mmc_select_hwpart() - Select the MMC hardware partiion on an MMC device
@@ -171,7 +170,6 @@ 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 *sata_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; }
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 30/44] dm: systemace: Drop the get_dev() function
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (28 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 29/44] dm: sata: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 31/44] dm: blk: Drop the systemace.h header Simon Glass
                   ` (13 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This function is implemented by the legacy block functions now. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 disk/part.c               |  2 +-
 drivers/block/systemace.c | 14 +++-----------
 include/part.h            |  2 --
 include/systemace.h       |  7 -------
 4 files changed, 4 insertions(+), 21 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index 30ae030..d52d48b 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -41,7 +41,7 @@ const struct block_drvr block_drvr[] = {
 	},
 #endif
 #if defined(CONFIG_SYSTEMACE)
-	{ .name = "ace", .get_dev = systemace_get_dev, },
+	{ .name = "ace", },
 #endif
 #if defined(CONFIG_SANDBOX)
 	{ .name = "host", .get_dev = host_get_dev, },
diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index 0d8e26f..4f14d5f 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -104,8 +104,7 @@ static void release_cf_lock(void)
 	ace_writew((val & 0xffff), 0x18);
 }
 
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *systemace_get_dev(int dev)
+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. */
@@ -127,14 +126,7 @@ struct blk_desc *systemace_get_dev(int dev)
 		part_init(&systemace_dev);
 
 	}
-
-	return &systemace_dev;
-}
-#endif
-
-static int systemace_get_devp(int dev, struct blk_desc **descp)
-{
-	*descp = systemace_get_dev(dev);
+	*descp = &systemace_dev;
 
 	return 0;
 }
@@ -269,5 +261,5 @@ U_BOOT_LEGACY_BLK(systemace) = {
 	.if_typename	= "ace",
 	.if_type	= IF_TYPE_SYSTEMACE,
 	.max_devs	= 1,
-	.get_dev	= systemace_get_devp,
+	.get_dev	= systemace_get_dev,
 };
diff --git a/include/part.h b/include/part.h
index 03d4b3d..29625f6 100644
--- a/include/part.h
+++ b/include/part.h
@@ -91,7 +91,6 @@ struct blk_desc *blk_get_dev(const char *ifname, int dev);
  * @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);
@@ -171,7 +170,6 @@ extern const struct block_drvr block_drvr[];
 static inline struct blk_desc *blk_get_dev(const char *ifname, 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; }
 
diff --git a/include/systemace.h b/include/systemace.h
index 3b6ec7d..bccb2a2 100644
--- a/include/systemace.h
+++ b/include/systemace.h
@@ -7,11 +7,4 @@
  * 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 */
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 31/44] dm: blk: Drop the systemace.h header
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (29 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 30/44] dm: systemace: " Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 32/44] dm: sandbox: Drop the host_get_dev() function Simon Glass
                   ` (12 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This has nothing of consequence. Remove it and its only inclusion site.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/systemace.c |  1 -
 include/systemace.h       | 10 ----------
 2 files changed, 11 deletions(-)
 delete mode 100644 include/systemace.h

diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index 4f14d5f..79e1263 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -27,7 +27,6 @@
 
 #include <common.h>
 #include <command.h>
-#include <systemace.h>
 #include <part.h>
 #include <asm/io.h>
 
diff --git a/include/systemace.h b/include/systemace.h
deleted file mode 100644
index bccb2a2..0000000
--- a/include/systemace.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __SYSTEMACE_H
-#define __SYSTEMACE_H
-/*
- * Copyright (c) 2004 Picture Elements, Inc.
- *    Stephen Williams (steve at picturel.com)
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#endif	/* __SYSTEMACE_H */
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 32/44] dm: sandbox: Drop the host_get_dev() function
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (30 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 31/44] dm: blk: Drop the systemace.h header Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 33/44] dm: part: Drop the get_dev() method Simon Glass
                   ` (11 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This function is implemented by the legacy block functions now. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 disk/part.c             |  2 +-
 drivers/block/sandbox.c | 10 ----------
 include/part.h          |  2 --
 3 files changed, 1 insertion(+), 13 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index d52d48b..8d5f028 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -44,7 +44,7 @@ const struct block_drvr block_drvr[] = {
 	{ .name = "ace", },
 #endif
 #if defined(CONFIG_SANDBOX)
-	{ .name = "host", .get_dev = host_get_dev, },
+	{ .name = "host", },
 #endif
 	{ },
 };
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index 2b6a893..ac28f83 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -217,16 +217,6 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
 	return 0;
 }
 
-struct blk_desc *host_get_dev(int dev)
-{
-	struct blk_desc *blk_dev;
-
-	if (host_get_dev_err(dev, &blk_dev))
-		return NULL;
-
-	return blk_dev;
-}
-
 #ifdef CONFIG_BLK
 static const struct blk_ops sandbox_host_blk_ops = {
 	.read	= host_block_read,
diff --git a/include/part.h b/include/part.h
index 29625f6..1b17436 100644
--- a/include/part.h
+++ b/include/part.h
@@ -92,7 +92,6 @@ struct blk_desc *blk_get_dev(const char *ifname, int dev);
  */
 int mmc_select_hwpart(int dev_num, int hwpart);
 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 */
@@ -171,7 +170,6 @@ static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
 { return NULL; }
 static inline int mmc_select_hwpart(int dev_num, int hwpart) { return -1; }
 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; }
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 33/44] dm: part: Drop the get_dev() method
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (31 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 32/44] dm: sandbox: Drop the host_get_dev() function Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 34/44] dm: ide: Add support for driver-model block devices Simon Glass
                   ` (10 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

This is now handled by the legacy block driver. The get_dev() method is
no-longer used. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/part.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/part.h b/include/part.h
index 1b17436..afe5633 100644
--- a/include/part.h
+++ b/include/part.h
@@ -12,7 +12,6 @@
 
 struct block_drvr {
 	char *name;
-	struct blk_desc* (*get_dev)(int dev);
 	int (*select_hwpart)(int dev_num, int hwpart);
 };
 
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 34/44] dm: ide: Add support for driver-model block devices
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (32 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 33/44] dm: part: Drop the get_dev() method Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:49   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 35/44] dm: sandbox: Enable IDE Simon Glass
                   ` (9 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add driver-model block-device support to the IDE implementation.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/ide.c  | 32 ++++++++++++++++++++++++++++++++
 include/ide.h |  8 ++++++++
 2 files changed, 40 insertions(+)

diff --git a/common/ide.c b/common/ide.c
index 5dc90d4..ac5b91c 100644
--- a/common/ide.c
+++ b/common/ide.c
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <ata.h>
+#include <dm.h>
 #include <ide.h>
 #include <watchdog.h>
 #include <asm/io.h>
@@ -873,8 +874,10 @@ void ide_init(void)
 		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       */
@@ -975,9 +978,17 @@ __weak void ide_input_data(int dev, ulong *sect_buf, int words)
 
 #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;
@@ -1097,9 +1108,17 @@ IDE_READ_E:
 	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;
@@ -1191,9 +1210,22 @@ int ide_device_present(int dev)
 }
 #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/include/ide.h b/include/ide.h
index a4e65cf..9b0a4a9 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -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);
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 35/44] dm: sandbox: Enable IDE
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (33 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 34/44] dm: ide: Add support for driver-model block devices Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:50   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 36/44] dm: scsi: Add support for driver-model block devices Simon Glass
                   ` (8 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Enable building the IDE code for sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/configs/sandbox.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index cc22467..08a45f9 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -210,4 +210,14 @@
 #define CONFIG_CMD_USB
 #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
+
 #endif
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 36/44] dm: scsi: Add support for driver-model block devices
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (34 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 35/44] dm: sandbox: Enable IDE Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 37/44] dm: sandbox: Enable SCSI Simon Glass
                   ` (7 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add driver-model block-device support to the SCSI implementation.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/scsi.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/common/scsi.c b/common/scsi.c
index 5b6531f..8ac28dd 100644
--- a/common/scsi.c
+++ b/common/scsi.c
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <inttypes.h>
 #include <pci.h>
 #include <scsi.h>
@@ -149,9 +150,17 @@ void scsi_setup_inquiry(ccb *pccb)
 	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;
@@ -216,9 +225,17 @@ static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr,
 /* 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;
@@ -469,8 +486,10 @@ void scsi_scan(int mode)
 		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++) {
@@ -552,9 +571,22 @@ removable:
 #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
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 37/44] dm: sandbox: Enable SCSI
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (35 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 36/44] dm: scsi: Add support for driver-model block devices Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 38/44] dm: sata: Add support for driver-model block devices Simon Glass
                   ` (6 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Enable building the SCSI code for sandbox. This increases build coverage
for sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/configs/sandbox.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 08a45f9..6d8ce13 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -220,4 +220,10 @@
 #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
+
 #endif
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 38/44] dm: sata: Add support for driver-model block devices
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (36 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 37/44] dm: sandbox: Enable SCSI Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 39/44] dm: sandbox: Enable SATA Simon Glass
                   ` (5 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add driver-model block-device support to the SATA implementation. This is
just a dummy implementation for now, since the SATA low-level API uses
numbered devices and that doesn't fit with driver model.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/sata.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/common/sata.c b/common/sata.c
index 1d52fcb..88f08c9 100644
--- a/common/sata.c
+++ b/common/sata.c
@@ -11,6 +11,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <sata.h>
 
 struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
@@ -22,6 +23,19 @@ struct blk_desc *sata_get_dev(int dev)
 }
 #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)
 {
@@ -33,6 +47,7 @@ static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
 {
 	return sata_write(block_dev->devnum, start, blkcnt, buffer);
 }
+#endif
 
 int __sata_initialize(void)
 {
@@ -48,9 +63,10 @@ int __sata_initialize(void)
 		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);
@@ -78,9 +94,22 @@ __weak int __sata_stop(void)
 }
 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
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 39/44] dm: sandbox: Enable SATA
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (37 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 38/44] dm: sata: Add support for driver-model block devices Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 40/44] dm: blk: Allow blk_create_device() to allocate the device number Simon Glass
                   ` (4 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Enable building the SATA code for sandbox. This increases build coverage
for sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/configs/sandbox.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 6d8ce13..8c497bb 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -226,4 +226,7 @@
 #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
+
 #endif
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 40/44] dm: blk: Allow blk_create_device() to allocate the device number
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (38 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 39/44] dm: sandbox: Enable SATA Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-12 20:56   ` Stephen Warren
  2016-04-10  2:45 ` [U-Boot] [PATCH 41/44] dm: blk: Add a easier way to create a named block device Simon Glass
                   ` (3 subsequent siblings)
  43 siblings, 1 reply; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Allow a devnum parameter of -1 to indicate that the device number should be
alocated automatically. The next highest available device number for that
interface type is used.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/blk-uclass.c | 29 +++++++++++++++++++++++++++++
 include/blk.h              | 15 ++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 3687b9a..c947d95 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -411,6 +411,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)
@@ -428,6 +448,15 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
 	desc->lba = size / blksz;
 	desc->part_type = PART_TYPE_UNKNOWN;
 	desc->bdev = dev;
+	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;
+	}
 	desc->devnum = devnum;
 	*devp = dev;
 
diff --git a/include/blk.h b/include/blk.h
index 12be6aa..9f4a63d 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -276,7 +276,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)
@@ -305,6 +306,18 @@ 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);
+
 #else
 #include <errno.h>
 /*
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 41/44] dm: blk: Add a easier way to create a named block device
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (39 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 40/44] dm: blk: Allow blk_create_device() to allocate the device number Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 42/44] dm: systemace: Reorder function to avoid forward declarataions Simon Glass
                   ` (2 subsequent siblings)
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add a function that automatically builds the device name given the parent
and a supplied string. Most callers will want to do this, so putting this
functionality in one place makes more sense.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/usb_storage.c       | 13 +++++--------
 drivers/block/blk-uclass.c | 15 +++++++++++++++
 include/blk.h              | 17 +++++++++++++++++
 3 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index f2da3a3..7e6e52d 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -200,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;
@@ -223,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;
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index c947d95..6ecbff0 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -463,6 +463,21 @@ 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;
+
+	snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
+	str = strdup(dev_name);
+	if (!str)
+		return -ENOMEM;
+
+	return blk_create_device(parent, drv_name, str, if_type, devnum,
+				 blksz, size, devp);
+}
+
 int blk_unbind_all(int if_type)
 {
 	struct uclass *uc;
diff --git a/include/blk.h b/include/blk.h
index 9f4a63d..19bc6a4 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -287,6 +287,23 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
 		      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
  *
  * This reads partition information from the device if supported.
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 42/44] dm: systemace: Reorder function to avoid forward declarataions
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (40 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 41/44] dm: blk: Add a easier way to create a named block device Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 43/44] dm: systemace: Add driver-mode block-device support Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 44/44] dm: sandbox: Enable systemace Simon Glass
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Move the systemace_get_dev() function below systemace_read() so that we can
avoid a forward declaration.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/systemace.c | 57 +++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 31 deletions(-)

diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index 79e1263..eeba7f0 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -68,10 +68,6 @@ 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);
-
 static struct blk_desc systemace_dev = { 0 };
 
 static int get_cf_lock(void)
@@ -103,33 +99,6 @@ static void release_cf_lock(void)
 	ace_writew((val & 0xffff), 0x18);
 }
 
-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;
-}
-
 /*
  * This function is called (by dereferencing the block_read pointer in
  * the dev_desc) to read blocks of data. The return value is the
@@ -256,6 +225,32 @@ static unsigned long systemace_read(struct blk_desc *block_dev,
 	return blkcnt;
 }
 
+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,
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 43/44] dm: systemace: Add driver-mode block-device support
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (41 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 42/44] dm: systemace: Reorder function to avoid forward declarataions Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  2016-04-10  2:45 ` [U-Boot] [PATCH 44/44] dm: sandbox: Enable systemace Simon Glass
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Add support for CONFIG_BLK to the systemace driver.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/systemace.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index eeba7f0..9392bea 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -27,6 +27,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <part.h>
 #include <asm/io.h>
 
@@ -68,7 +69,9 @@ static u16 ace_readw(unsigned off)
 	return in16(base + off);
 }
 
+#ifndef CONFIG_BLK
 static struct blk_desc systemace_dev = { 0 };
+#endif
 
 static int get_cf_lock(void)
 {
@@ -104,9 +107,14 @@ static void release_cf_lock(void)
  * 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;
@@ -225,6 +233,41 @@ 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
@@ -257,3 +300,4 @@ U_BOOT_LEGACY_BLK(systemace) = {
 	.max_devs	= 1,
 	.get_dev	= systemace_get_dev,
 };
+#endif
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 44/44] dm: sandbox: Enable systemace
  2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
                   ` (42 preceding siblings ...)
  2016-04-10  2:45 ` [U-Boot] [PATCH 43/44] dm: systemace: Add driver-mode block-device support Simon Glass
@ 2016-04-10  2:45 ` Simon Glass
  43 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-04-10  2:45 UTC (permalink / raw)
  To: u-boot

Enable building the systemace code for sandbox. This increases build
coverage for sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/configs/sandbox.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 8c497bb..f0f7cd4 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -229,4 +229,8 @@
 #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
+
 #endif
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 03/44] pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
  2016-04-10  2:44 ` [U-Boot] [PATCH 03/44] pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE Simon Glass
@ 2016-04-11  5:02   ` Bin Meng
  0 siblings, 0 replies; 62+ messages in thread
From: Bin Meng @ 2016-04-11  5:02 UTC (permalink / raw)
  To: u-boot

On Sun, Apr 10, 2016 at 10:44 AM, Simon Glass <sjg@chromium.org> wrote:
> This option is not used by any board. Drop it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  drivers/pci/pci.c             | 4 ----
>  include/configs/MPC8641HPCN.h | 2 --
>  include/configs/sbc8641d.h    | 2 --
>  3 files changed, 8 deletions(-)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 05/44] Allow iotrace byte access to use an address of any size
  2016-04-10  2:44 ` [U-Boot] [PATCH 05/44] Allow iotrace byte access to use an address of any size Simon Glass
@ 2016-04-12 20:00   ` Stephen Warren
  0 siblings, 0 replies; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:00 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:44 PM, Simon Glass wrote:
> If an address is used with readb() and writeb() which is smaller than the
> expected size (e.g. 32-bit value on a machine with 64-bit addresses), a
> warning results. Fix this by adding a cast.

> diff --git a/include/iotrace.h b/include/iotrace.h

> -#define readb(addr)	iotrace_readb((const void *)(addr))
> +#define readb(addr)	iotrace_readb((const void *)((uintptr_t)addr))

Nit: I think (type)(othertype)val is as good as (type)((othertype)val)

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 06/44] sandbox: Add string and 16-bit I/O functions
  2016-04-10  2:44 ` [U-Boot] [PATCH 06/44] sandbox: Add string and 16-bit I/O functions Simon Glass
@ 2016-04-12 20:02   ` Stephen Warren
  0 siblings, 0 replies; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:02 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:44 PM, Simon Glass wrote:
> Add outsw() and insw() functions for sandbox, as these are needed by the IDE
> code. The functions will not do anything useful if called, but allow the
> code to be compiled.

> diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h

> +static inline void _insw(volatile u16 *port, void *buf, int ns)
> +{
> +	u16 *data = (u16 *) buf;
> +	while (ns--)
> +		*data++ = *port;
> +}
> +
> +static inline void _outsw(volatile u16 *port, const void *buf, int ns)
> +{
> +	u16 *data = (u16 *) buf;
> +	while (ns--) {
> +		*port = *data++;
> +	}
> +}

Why make those have anything other than an empty body if they don't need 
to do anything? The other functions in this file (e.g. out16/in16 added 
in this patch) are just no-ops. If those functions are called, they'll 
cause memory corruption or a crash.

> +/* For systemace.c */
> +#define out16(addr, val)
> +#define in16(addr)		0

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 09/44] dm: scsi: Remove the forward declarations
  2016-04-10  2:45 ` [U-Boot] [PATCH 09/44] dm: scsi: Remove the forward declarations Simon Glass
@ 2016-04-12 20:04   ` Stephen Warren
  0 siblings, 0 replies; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:04 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> Reorder the code to avoid needing forward declarations.

> diff --git a/cmd/scsi.c b/cmd/scsi.c

> @@ -50,6 +50,7 @@ static int scsi_curr_dev; /* current device */
>
>   static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
>
> +#if 0
>   /********************************************************************************
>    *  forward declerations of some Setup Routines
>    */
> @@ -70,110 +71,232 @@ 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);
> +#endif

I assume that should all be deleted; it was just #if 0 for testing this 
change?

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 10/44] dm: scsi: Fix up code style
  2016-04-10  2:45 ` [U-Boot] [PATCH 10/44] dm: scsi: Fix up code style Simon Glass
@ 2016-04-12 20:05   ` Stephen Warren
  0 siblings, 0 replies; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:05 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> Update the code style of this file so that it passes checkpatch.pl.

> diff --git a/cmd/scsi.c b/cmd/scsi.c

> @@ -50,82 +50,53 @@ static int scsi_curr_dev; /* current device */
>
>   static struct blk_desc scsi_dev_desc[CONFIG_SYS_SCSI_MAX_DEVICE];
>
> -#if 0
> -/********************************************************************************
> - *  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);
> -#endif
> -

Ah, that answers my previous question. I guess that chunk just got 
squashed into one commit too late.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 15/44] dm: blk: Add a legacy block interface
  2016-04-10  2:45 ` [U-Boot] [PATCH 15/44] dm: blk: Add a legacy block interface Simon Glass
@ 2016-04-12 20:28   ` Stephen Warren
  2016-05-01 18:56     ` Simon Glass
  0 siblings, 1 reply; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:28 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> There is quite a bit of duplicated common code related to block devices
> in the IDE and SCSI implementations.
>
> Create some helper functions that can be used to reduce the duplication.
> These rely on a linker list of interface-type drivers

It'd be useful to know if this gets thrown away later in the series if 
everything is converted to DM. That would affect how thoroughly one 
reviews it.

At this point I'm slightly lost where the series is going, since it all 
seems to be adding a slew of stuff for legacy paths more than converting 
to DM block devices. Perhaps it'll become more clear as I go along.

> diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c

> +#ifdef HAVE_BLOCK_DEVICE
> +int blk_list_part(enum if_type if_type)
> +{
> +	struct blk_driver *drv = blk_driver_lookup_type(if_type);
> +	struct blk_desc *desc;
> +	int devnum, ok;
> +
> +	if (!drv)
> +		return -ENOSYS;

Nit: If drv can be NULL, I'd prefer to see the assignment right before 
the line that tests it rather than in the declaration. That makes it 
clearer to someone that they can't insert a line into the variable 
declarations that uses drv. That's something I've seen happen, and it's 
hard to spot the issue in a patch if the context isn't long enough to 
see this not-yet-happened test later in the code.

> +	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 (devnum)
> +				putc('\n');
> +			part_print(desc);

Does this function support dumping the partition list for multiple 
devices in one invocation? If so, that seems odd; is there any command 
to do that? If not, I would expect a break here, and I'm not sure what 
if (devnum) putc() is about. Also, shouldn't the putc happen if a 
previous iteration of the for loop did print something, not based on the 
index in the list, since presumably it's possible that entries 0..2 are 
PART_TYPE_UNKNOWN and entry 3 isn't?

> +int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)

What does "dselect" mean as opposed to "select"?

> +struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)

Doesn't this get a desc not a devnum? It seems to be /by/ typename+devnum.

> diff --git a/include/blk.h b/include/blk.h

> +struct blk_driver {

> +	/**
> +	 * 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).

There's also partition 0, the main user data partition, which is what is 
primarily used.

> +	 *
> +	 * @desc:	Block device descriptor
> +	 * @hwpart:	Hardware partition number to select. 0 means the raw
> +	 *		device, 1 is the first partition, 2 is the second, etc.

0 isn't really "raw". At least to me, "raw" implies access to all data 
on the storage medium including partition tables, inter-partition gaps, 
and data across all partitions. However, for eMMC "0" means just another 
partition like any other partition, but this one just happens to be the 
one that's used most/typically.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 16/44] dm: systemace: Add a legacy block interface
  2016-04-10  2:45 ` [U-Boot] [PATCH 16/44] dm: systemace: " Simon Glass
@ 2016-04-12 20:31   ` Stephen Warren
  2016-05-01 18:56     ` Simon Glass
  0 siblings, 1 reply; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:31 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> Add a legacy block interface for systemace.

> diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c

> +static int systemace_get_devp(int dev, struct blk_desc **descp)

I'm not sure what "devp" means here rather than "dev". I suppose it's to 
avoid a naming conflict with an existing identically named function. 
Perhaps s/get_devp/get_dev_legacy/ since it's part of the legacy block 
device API?

Actually, it looks like this name is temporary and thrown away later, so 
it's probably not worth fixing.

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 20/44] dm: mmc: Add an implementation of the 'devnum' functions
  2016-04-10  2:45 ` [U-Boot] [PATCH 20/44] dm: mmc: Add an implementation of the 'devnum' functions Simon Glass
@ 2016-04-12 20:40   ` Stephen Warren
  2016-05-01 18:56     ` Simon Glass
  0 siblings, 1 reply; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:40 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> Now that the MMC code accesses devices by number, we can implement this same
> interface for driver model, allowing MMC to support using driver model for
> block devices.
>
> Add the required functions to the uclass.

> +int blk_list_part(enum if_type if_type)

I have the same comment for this function as the earlier similar 
function, although given the function signature here it does seem 
obvious that it's really meant to list partitions on multiple devices. 
How does the user invoke that from the command-line? Hmm, it looks like 
"ide part" works differently (prints for all devices) than "part list" 
(which works on a single user-specified device); odd..

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 34/44] dm: ide: Add support for driver-model block devices
  2016-04-10  2:45 ` [U-Boot] [PATCH 34/44] dm: ide: Add support for driver-model block devices Simon Glass
@ 2016-04-12 20:49   ` Stephen Warren
  2016-05-01 18:56     ` Simon Glass
  0 siblings, 1 reply; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:49 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> Add driver-model block-device support to the IDE implementation.

> diff --git a/include/ide.h b/include/ide.h

> +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

Does anything outside of the IDE code itself rely on these prototypes 
when CONFIG_BLK is enabled? I'd hope to see #ifndef CONFIG_BLK added, 
without an actual prototype since the function itself should be static 
once IDE is converted to CONFIG_BLK?

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 35/44] dm: sandbox: Enable IDE
  2016-04-10  2:45 ` [U-Boot] [PATCH 35/44] dm: sandbox: Enable IDE Simon Glass
@ 2016-04-12 20:50   ` Stephen Warren
  2016-05-01 18:56     ` Simon Glass
  0 siblings, 1 reply; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:50 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> Enable building the IDE code for sandbox.

It might be worth mentioning dumy/fake/compile-only in the commit 
subject/description lest anyone think they can actually try out emulated 
devices?

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 40/44] dm: blk: Allow blk_create_device() to allocate the device number
  2016-04-10  2:45 ` [U-Boot] [PATCH 40/44] dm: blk: Allow blk_create_device() to allocate the device number Simon Glass
@ 2016-04-12 20:56   ` Stephen Warren
  2016-05-01 18:56     ` Simon Glass
  0 siblings, 1 reply; 62+ messages in thread
From: Stephen Warren @ 2016-04-12 20:56 UTC (permalink / raw)
  To: u-boot

On 04/09/2016 08:45 PM, Simon Glass wrote:
> Allow a devnum parameter of -1 to indicate that the device number should be
> alocated automatically. The next highest available device number for that
> interface type is used.

> diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c

> +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;

I'm tempted to suggest that the -ENODEV special case be place here, and 
return 0 instead. Of course, that would require the devnum to be a 
pointer/output parameter rather than encoded into the return value, so 
that other errors could still be returned. Perhaps not worth it.

My reasoning is that clients of this function should just be able to ask 
"what's the next device number" and not care about implementing the 
special cases, but rather rely on this function encoding everything. 
This doesn't matter so much if there's only one call-site though. If 
there is only one call-site, should this be static?

Hmm. This could all be solved by having the function return the next 
free devnum (0..n) (or -ve error) rather than the highest used devnum. 
That way, the -ENODEV special case would return 0, and clients could 
just do:

devnum = blk_find_next_free_devnum(...);
if (devnum < 0)
     return devnum;

and nothing else.

> @@ -428,6 +448,15 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
>   	desc->lba = size / blksz;
>   	desc->part_type = PART_TYPE_UNKNOWN;
>   	desc->bdev = dev;
> +	if (devnum == -1) {
> +		ret = blk_find_max_devnum(if_type);
> +		if (ret == -ENODEV)
> +			devnum = 0;

I'm thinking that clients should have to care about implementing that 
ever time they use the function.

> +		else if (ret < 0)
> +			return ret;
> +		else
> +			devnum = ret + 1;
> +	}
>   	desc->devnum = devnum;

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 15/44] dm: blk: Add a legacy block interface
  2016-04-12 20:28   ` Stephen Warren
@ 2016-05-01 18:56     ` Simon Glass
  0 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-05-01 18:56 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On 12 April 2016 at 14:28, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/09/2016 08:45 PM, Simon Glass wrote:
>>
>> There is quite a bit of duplicated common code related to block devices
>> in the IDE and SCSI implementations.
>>
>> Create some helper functions that can be used to reduce the duplication.
>> These rely on a linker list of interface-type drivers
>
>
> It'd be useful to know if this gets thrown away later in the series if
> everything is converted to DM. That would affect how thoroughly one reviews
> it.
>
> At this point I'm slightly lost where the series is going, since it all
> seems to be adding a slew of stuff for legacy paths more than converting to
> DM block devices. Perhaps it'll become more clear as I go along.

It's a bit of a pain to review. If it's any consolation it was more of
a pain to write. The goal is to create a 'legacy' driver which can be
used for non-DM code. It is just too painful to try to have the old
code and DM code co-exist without a common API.

>
>> diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c
>
>
>> +#ifdef HAVE_BLOCK_DEVICE
>> +int blk_list_part(enum if_type if_type)
>> +{
>> +       struct blk_driver *drv = blk_driver_lookup_type(if_type);
>> +       struct blk_desc *desc;
>> +       int devnum, ok;
>> +
>> +       if (!drv)
>> +               return -ENOSYS;
>
>
> Nit: If drv can be NULL, I'd prefer to see the assignment right before the
> line that tests it rather than in the declaration. That makes it clearer to
> someone that they can't insert a line into the variable declarations that
> uses drv. That's something I've seen happen, and it's hard to spot the issue
> in a patch if the context isn't long enough to see this not-yet-happened
> test later in the code.

OK.

>
>> +       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 (devnum)
>> +                               putc('\n');
>> +                       part_print(desc);
>
>
> Does this function support dumping the partition list for multiple devices
> in one invocation? If so, that seems odd; is there any command to do that?
> If not, I would expect a break here, and I'm not sure what if (devnum)
> putc() is about. Also, shouldn't the putc happen if a previous iteration of
> the for loop did print something, not based on the index in the list, since
> presumably it's possible that entries 0..2 are PART_TYPE_UNKNOWN and entry 3
> isn't?

Yes it supports that. I'll fix the newline handling. Actually I'm not
sure that it can happy, but let's assume it can.

>
>> +int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
>
>
> What does "dselect" mean as opposed to "select"?

There is a comment next to the main ones:

/*
 * These functions should take struct udevice instead of struct blk_desc,
 * but this is convenient for migration to driver model. Add a 'd' prefix
 * to the function operations, so that blk_read(), etc. can be reserved for
 * functions with the correct arguments.
 */

>
>> +struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int
>> devnum)
>
>
> Doesn't this get a desc not a devnum? It seems to be /by/ typename+devnum.

It had to find the desc, given the interface type devnum.

>
>> diff --git a/include/blk.h b/include/blk.h
>
>
>> +struct blk_driver {
>
>
>> +       /**
>> +        * 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).
>
>
> There's also partition 0, the main user data partition, which is what is
> primarily used.

OK, will update comment.

>
>> +        *
>> +        * @desc:       Block device descriptor
>> +        * @hwpart:     Hardware partition number to select. 0 means the
>> raw
>> +        *              device, 1 is the first partition, 2 is the second,
>> etc.
>
>
> 0 isn't really "raw". At least to me, "raw" implies access to all data on
> the storage medium including partition tables, inter-partition gaps, and
> data across all partitions. However, for eMMC "0" means just another
> partition like any other partition, but this one just happens to be the one
> that's used most/typically.

OK will update comment. I want to get a bit more detail into the API
comments so that the meaning of these things is clear.

Regards,
Simon

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 16/44] dm: systemace: Add a legacy block interface
  2016-04-12 20:31   ` Stephen Warren
@ 2016-05-01 18:56     ` Simon Glass
  0 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-05-01 18:56 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On 12 April 2016 at 14:31, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/09/2016 08:45 PM, Simon Glass wrote:
>>
>> Add a legacy block interface for systemace.
>
>
>> diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
>
>
>> +static int systemace_get_devp(int dev, struct blk_desc **descp)
>
>
> I'm not sure what "devp" means here rather than "dev". I suppose it's to
> avoid a naming conflict with an existing identically named function. Perhaps
> s/get_devp/get_dev_legacy/ since it's part of the legacy block device API?
>
> Actually, it looks like this name is temporary and thrown away later, so
> it's probably not worth fixing.

Yes that's right. It is temporary.

Regards,
Simon

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 20/44] dm: mmc: Add an implementation of the 'devnum' functions
  2016-04-12 20:40   ` Stephen Warren
@ 2016-05-01 18:56     ` Simon Glass
  0 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-05-01 18:56 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On 12 April 2016 at 14:40, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/09/2016 08:45 PM, Simon Glass wrote:
>>
>> Now that the MMC code accesses devices by number, we can implement this
>> same
>> interface for driver model, allowing MMC to support using driver model for
>> block devices.
>>
>> Add the required functions to the uclass.
>
>
>> +int blk_list_part(enum if_type if_type)
>
>
> I have the same comment for this function as the earlier similar function,
> although given the function signature here it does seem obvious that it's
> really meant to list partitions on multiple devices. How does the user
> invoke that from the command-line? Hmm, it looks like "ide part" works
> differently (prints for all devices) than "part list" (which works on a
> single user-specified device); odd..

For example 'scsi part'.

It will be easier to keep things the same when we don't have separate
implementations for each interface type.

Regards,
Simon

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 34/44] dm: ide: Add support for driver-model block devices
  2016-04-12 20:49   ` Stephen Warren
@ 2016-05-01 18:56     ` Simon Glass
  0 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-05-01 18:56 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On 12 April 2016 at 14:49, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/09/2016 08:45 PM, Simon Glass wrote:
>>
>> Add driver-model block-device support to the IDE implementation.
>
>
>> diff --git a/include/ide.h b/include/ide.h
>
>
>> +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
>
>
> Does anything outside of the IDE code itself rely on these prototypes when
> CONFIG_BLK is enabled? I'd hope to see #ifndef CONFIG_BLK added, without an
> actual prototype since the function itself should be static once IDE is
> converted to CONFIG_BLK?

Yes - see common/ide.c, which does use these functions. Cleaning that
up might be a future task. There is certainly more potential here.

Regards,
Simon

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 35/44] dm: sandbox: Enable IDE
  2016-04-12 20:50   ` Stephen Warren
@ 2016-05-01 18:56     ` Simon Glass
  0 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-05-01 18:56 UTC (permalink / raw)
  To: u-boot

On 12 April 2016 at 14:50, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/09/2016 08:45 PM, Simon Glass wrote:
>>
>> Enable building the IDE code for sandbox.
>
>
> It might be worth mentioning dumy/fake/compile-only in the commit
> subject/description lest anyone think they can actually try out emulated
> devices?

OK will do.

- Simon

^ permalink raw reply	[flat|nested] 62+ messages in thread

* [U-Boot] [PATCH 40/44] dm: blk: Allow blk_create_device() to allocate the device number
  2016-04-12 20:56   ` Stephen Warren
@ 2016-05-01 18:56     ` Simon Glass
  0 siblings, 0 replies; 62+ messages in thread
From: Simon Glass @ 2016-05-01 18:56 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On 12 April 2016 at 14:56, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 04/09/2016 08:45 PM, Simon Glass wrote:
>>
>> Allow a devnum parameter of -1 to indicate that the device number should
>> be
>> alocated automatically. The next highest available device number for that
>> interface type is used.
>
>
>> diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
>
>
>> +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;
>
>
> I'm tempted to suggest that the -ENODEV special case be place here, and
> return 0 instead. Of course, that would require the devnum to be a
> pointer/output parameter rather than encoded into the return value, so that
> other errors could still be returned. Perhaps not worth it.
>
> My reasoning is that clients of this function should just be able to ask
> "what's the next device number" and not care about implementing the special
> cases, but rather rely on this function encoding everything. This doesn't
> matter so much if there's only one call-site though. If there is only one
> call-site, should this be static?
>
> Hmm. This could all be solved by having the function return the next free
> devnum (0..n) (or -ve error) rather than the highest used devnum. That way,
> the -ENODEV special case would return 0, and clients could just do:
>
> devnum = blk_find_next_free_devnum(...);
> if (devnum < 0)
>     return devnum;
>
> and nothing else.

Yes that was my first implementation. But I had to change it because
MMC needs to find the maximum device number at present (in the next
series). It's a little painful but some future work may centralise
things better.

>
>> @@ -428,6 +448,15 @@ int blk_create_device(struct udevice *parent, const
>> char *drv_name,
>>         desc->lba = size / blksz;
>>         desc->part_type = PART_TYPE_UNKNOWN;
>>         desc->bdev = dev;
>> +       if (devnum == -1) {
>> +               ret = blk_find_max_devnum(if_type);
>> +               if (ret == -ENODEV)
>> +                       devnum = 0;
>
>
> I'm thinking that clients should have to care about implementing that ever
> time they use the function.

Right, but there really are only two callers - one in this code and one in MMC.

>
>
>> +               else if (ret < 0)
>> +                       return ret;
>> +               else
>> +                       devnum = ret + 1;
>> +       }
>>         desc->devnum = devnum;
>
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 62+ messages in thread

end of thread, other threads:[~2016-05-01 18:56 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-10  2:44 [U-Boot] [PATCH 00/44] dm: blk: Add more driver-model support for block devices Simon Glass
2016-04-10  2:44 ` [U-Boot] [PATCH 01/44] Revert "dm: sandbox: Drop the pre-DM host implementation" Simon Glass
2016-04-10  2:44 ` [U-Boot] [PATCH 02/44] dm: sandbox: Add a board for sandbox without CONFIG_BLK Simon Glass
2016-04-10  2:44 ` [U-Boot] [PATCH 03/44] pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE Simon Glass
2016-04-11  5:02   ` Bin Meng
2016-04-10  2:44 ` [U-Boot] [PATCH 04/44] dm: Rename disk uclass to ahci Simon Glass
2016-04-10  2:44 ` [U-Boot] [PATCH 05/44] Allow iotrace byte access to use an address of any size Simon Glass
2016-04-12 20:00   ` Stephen Warren
2016-04-10  2:44 ` [U-Boot] [PATCH 06/44] sandbox: Add string and 16-bit I/O functions Simon Glass
2016-04-12 20:02   ` Stephen Warren
2016-04-10  2:44 ` [U-Boot] [PATCH 07/44] sandbox: Add dummy SCSI functions Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 08/44] sandbox: Add dummy SATA functions Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 09/44] dm: scsi: Remove the forward declarations Simon Glass
2016-04-12 20:04   ` Stephen Warren
2016-04-10  2:45 ` [U-Boot] [PATCH 10/44] dm: scsi: Fix up code style Simon Glass
2016-04-12 20:05   ` Stephen Warren
2016-04-10  2:45 ` [U-Boot] [PATCH 11/44] dm: ide: Correct various code style problems Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 12/44] dm: ide: Remove the forward declarations Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 13/44] dm: sata: Fix code style problems in cmd/sata.c Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 14/44] dm: scsi: Rename CONFIG_CMD_SCSI to CONFIG_SCSI Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 15/44] dm: blk: Add a legacy block interface Simon Glass
2016-04-12 20:28   ` Stephen Warren
2016-05-01 18:56     ` Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 16/44] dm: systemace: " Simon Glass
2016-04-12 20:31   ` Stephen Warren
2016-05-01 18:56     ` Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 17/44] dm: sandbox: Add a legacy host " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 18/44] dm: usb: Add a legacy block interface for USB storage Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 19/44] dm: mmc: Add a legacy block interface for MMC Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 20/44] dm: mmc: Add an implementation of the 'devnum' functions Simon Glass
2016-04-12 20:40   ` Stephen Warren
2016-05-01 18:56     ` Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 21/44] dm: scsi: Separate the non-command code into its own file Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 22/44] dm: ide: " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 23/44] dm: sata: " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 24/44] dm: disk: Use legacy block driver info for block device access Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 25/44] dm: usb: Drop the get_dev() function Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 26/44] dm: ide: " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 27/44] dm: mmc: " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 28/44] dm: scsi: " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 29/44] dm: sata: " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 30/44] dm: systemace: " Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 31/44] dm: blk: Drop the systemace.h header Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 32/44] dm: sandbox: Drop the host_get_dev() function Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 33/44] dm: part: Drop the get_dev() method Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 34/44] dm: ide: Add support for driver-model block devices Simon Glass
2016-04-12 20:49   ` Stephen Warren
2016-05-01 18:56     ` Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 35/44] dm: sandbox: Enable IDE Simon Glass
2016-04-12 20:50   ` Stephen Warren
2016-05-01 18:56     ` Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 36/44] dm: scsi: Add support for driver-model block devices Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 37/44] dm: sandbox: Enable SCSI Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 38/44] dm: sata: Add support for driver-model block devices Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 39/44] dm: sandbox: Enable SATA Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 40/44] dm: blk: Allow blk_create_device() to allocate the device number Simon Glass
2016-04-12 20:56   ` Stephen Warren
2016-05-01 18:56     ` Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 41/44] dm: blk: Add a easier way to create a named block device Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 42/44] dm: systemace: Reorder function to avoid forward declarataions Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 43/44] dm: systemace: Add driver-mode block-device support Simon Glass
2016-04-10  2:45 ` [U-Boot] [PATCH 44/44] dm: sandbox: Enable systemace Simon Glass

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox