Skip to contentSkip to conversation

dm: blk: Add more driver-model support for block devices

PATCH Superseded Simon Glass 3 participants 62 messages Apr 10, 2016 – May 1, 2016

Subsystems (8)
Arm (32-bit) x86 Block layer PCI +4 more subsystems

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover dm: blk: Add more driver-model support for block devices

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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#1 lore raw

PATCH 1/44 Revert "dm: sandbox: Drop the pre-DM host implementation"

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.

---

 drivers/block/sandbox.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)
drivers/block/sandbox.c +90 -0
index 2d340ef..6d41508 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#2 lore raw

PATCH 2/44 dm: sandbox: Add a board for sandbox without CONFIG_BLK

In reply to Simon Glass

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.

---

 board/sandbox/MAINTAINERS       |  7 +++
 configs/sandbox_noblk_defconfig | 98 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)
 create mode 100644 configs/sandbox_noblk_defconfig
board/sandbox/MAINTAINERS +7 -0
index 10d88a2..f5db773 100644
@@ -4,3 +4,10 @@ S:	Maintained
 F:	board/sandbox/
 F:	include/configs/sandbox.h
 F:	configs/sandbox_defconfig
+
+SANDBOX_NOBLK BOARD
+M:	Simon Glass <[email protected]>
+S:	Maintained
+F:	board/sandbox/
+F:	include/configs/sandbox.h
+F:	configs/sandbox_noblk_defconfig
configs/sandbox_noblk_defconfig new file +98 -0

98 lines not on this page · raw message

Signature · 1 line
2.8.0.rc3.226.g39d4020
#3 lore raw

PATCH 3/44 pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE

In reply to Simon Glass

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

---

 drivers/pci/pci.c             | 4 ----
 include/configs/MPC8641HPCN.h | 2 --
 include/configs/sbc8641d.h    | 2 --
 3 files changed, 8 deletions(-)
drivers/pci/pci.c +0 -4
index 4619089..4b73a0f 100644
@@ -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;
include/configs/MPC8641HPCN.h +0 -2
index 1f4ed2a..cd8d91f 100644
@@ -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 */
 
 
include/configs/sbc8641d.h +0 -2
index b7238fb..654e96e 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#4 lore raw

PATCH 3/44 pci: Drop CONFIG_SYS_SCSI_SCAN_BUS_REVERSE

Quoted 10 lines · Simon Glass

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

---

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

PATCH 4/44 dm: Rename disk uclass to ahci

In reply to Simon Glass

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.

---

 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%)
arch/x86/Kconfig +3 -0
index 4ef27dc..396023e 100644
@@ -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
 
arch/x86/cpu/broadwell/sata.c +1 -1
index dfb8486..2e47082 100644
@@ -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,
arch/x86/cpu/intel_common/cpu.c +1 -1
index 93e4505..0fdef6f 100644
@@ -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;
 }
arch/x86/cpu/ivybridge/bd82x6x.c +1 -1
index 4c039ac..5b58d6c 100644
@@ -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)
arch/x86/cpu/ivybridge/sata.c +1 -1
index c3d1057..1ce8195 100644
@@ -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,
 };
drivers/block/Kconfig +2 -3
index fcc9ccd..80eea84 100644
@@ -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
drivers/block/Makefile +1 -1
index a43492f..b832ae1 100644
@@ -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
drivers/block/ahci-uclass.c renamed from drivers/block/disk-uclass.c +3 -3
similarity index 72%
rename from drivers/block/disk-uclass.c
rename to drivers/block/ahci-uclass.c
index d665b35..7b8c326 100644
@@ -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",
 };
include/dm/uclass-id.h +1 -1
index cbf9b2c..a5cf6e2 100644
@@ -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 */
Signature · 1 line
2.8.0.rc3.226.g39d4020
#6 lore raw

PATCH 5/44 Allow iotrace byte access to use an address of any size

In reply to Simon Glass

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.

---

 include/iotrace.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
include/iotrace.h +3 -2
index 9bd1f16..a0b59fb 100644
@@ -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
 
Signature · 1 line
2.8.0.rc3.226.g39d4020
#7 lore raw

PATCH 5/44 Allow iotrace byte access to use an address of any size

include/iotrace.h line 34

Quoted 8 lines · Simon Glass

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.

include/iotrace.h +1 -1
 
-#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)

#8 lore raw

PATCH 6/44 sandbox: Add string and 16-bit I/O functions

In reply to Simon Glass

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.

---

 arch/sandbox/include/asm/io.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
arch/sandbox/include/asm/io.h +22 -0
index 5b87fde..cdbb6ba 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#9 lore raw

PATCH 6/44 sandbox: Add string and 16-bit I/O functions

Quoted 10 lines · Simon Glass

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.

arch/sandbox/include/asm/io.h +4 -0
 
+static inline void _insw(volatile u16 *port, void *buf, int ns)
+{
+	u16 *data = (u16 *) buf;
+	while (ns--)

arch/sandbox/include/asm/io.h void outl(unsigned int value, unsigned int addr); · line 72

Quoted 10 lines
arch/sandbox/include/asm/io.h +10 -0
+		*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.

Quoted 3 lines
arch/sandbox/include/asm/io.h +3 -0
+/* For systemace.c */
+#define out16(addr, val)
+#define in16(addr)		0
#10 lore raw

PATCH 7/44 sandbox: Add dummy SCSI functions

In reply to Simon Glass

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

---

 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
drivers/block/Makefile +1 -1
index b832ae1..3b48eac 100644
@@ -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
drivers/block/sandbox_scsi.c new file +29 -0
new file mode 100644
index 0000000..d342a7a
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * 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)
+{
+}
Signature · 1 line
2.8.0.rc3.226.g39d4020
#11 lore raw

PATCH 8/44 sandbox: Add dummy SATA functions

In reply to Simon Glass

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

---

 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
drivers/block/Makefile +1 -1
index 3b48eac..3f75934 100644
@@ -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
drivers/block/sata_sandbox.c new file +33 -0
new file mode 100644
index 0000000..bd967d2
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * 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;
+}
Signature · 1 line
2.8.0.rc3.226.g39d4020
#12 lore raw

PATCH 9/44 dm: scsi: Remove the forward declarations

In reply to Simon Glass

Reorder the code to avoid needing forward declarations.

---

 cmd/scsi.c | 755 +++++++++++++++++++++++++++++++------------------------------
 1 file changed, 378 insertions(+), 377 deletions(-)
cmd/scsi.c +378 -377
index 8991125..f875f51 100644
@@ -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
 }
Signature · 1 line
2.8.0.rc3.226.g39d4020
#13 lore raw

PATCH 9/44 dm: scsi: Remove the forward declarations

Quoted 13 lines · Simon Glass

Reorder the code to avoid needing forward declarations.

cmd/scsi.c +1 -0
@@ -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
   */

cmd/scsi.c static ulong scsi_read(struct blk_desc *block_dev, lbaint_t blknr, · line 74

Quoted 4 lines
cmd/scsi.c +1 -0
@@ -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?

#14 lore raw

PATCH 10/44 dm: scsi: Fix up code style

In reply to Simon Glass

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

---

 cmd/scsi.c | 482 +++++++++++++++++++++++++++++--------------------------------
 1 file changed, 226 insertions(+), 256 deletions(-)
cmd/scsi.c +226 -256
index f875f51..751fc58 100644
@@ -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;
 
Signature · 1 line
2.8.0.rc3.226.g39d4020
#15 lore raw

PATCH 10/44 dm: scsi: Fix up code style

Quoted 21 lines · Simon Glass

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

cmd/scsi.c +0 -13
@@ -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);

cmd/scsi.c static int scsi_curr_dev; /* current device */ · line 75

Quoted 10 lines
cmd/scsi.c +0 -10
-
-
-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.

#16 lore raw

PATCH 11/44 dm: ide: Correct various code style problems

In reply to Simon Glass

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

---

 cmd/ide.c | 57 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 29 insertions(+), 28 deletions(-)
cmd/ide.c +29 -28
index c4c08c8..a46d0ac 100644
@@ -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;
 }
 
 /* ------------------------------------------------------------------------- */
Signature · 1 line
2.8.0.rc3.226.g39d4020
#17 lore raw

PATCH 12/44 dm: ide: Remove the forward declarations

In reply to Simon Glass

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

---

 cmd/ide.c | 1924 ++++++++++++++++++++++++++++++-------------------------------
 1 file changed, 946 insertions(+), 978 deletions(-)
cmd/ide.c +946 -978
index a46d0ac..db26f43 100644
@@ -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",
Signature · 1 line
2.8.0.rc3.226.g39d4020
#18 lore raw

PATCH 13/44 dm: sata: Fix code style problems in cmd/sata.c

In reply to Simon Glass

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

---

 cmd/sata.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
cmd/sata.c +7 -5
index 8748cce..b1a64d9 100644
@@ -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) {
Signature · 1 line
2.8.0.rc3.226.g39d4020
#19 lore raw

PATCH 14/44 dm: scsi: Rename CONFIG_CMD_SCSI to CONFIG_SCSI

In reply to Simon Glass

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.

---

 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(-)
README +2 -2
index 597d615..18caa97 100644
@@ -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:
api/api_storage.c +1 -1
index 8c30c56..d425a9a 100644
@@ -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;
arch/arm/include/asm/arch-ls102xa/config.h +1 -1
index ab4b697..cde5923 100644
@@ -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
board/mpl/pip405/README +3 -3
index e900c56..f039817 100644
@@ -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:
cmd/Makefile +2 -2
index ba04197..2aaf978 100644
@@ -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
 
cmd/disk.c +1 -1
index 2fd1717..fcc4123 100644
@@ -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[])
common/board_r.c +2 -2
index ad02549..d959ad3 100644
@@ -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
disk/part.c +1 -1
index 0aff954..a1d1d92 100644
@@ -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)
drivers/block/sym53c8xx.c +1 -1
index c7c40af..5daede7 100644
@@ -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
 /*
fs/fat/fat.c +1 -1
index 600a90e..826bd85 100644
@@ -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:  ");
include/config_cmd_all.h +1 -1
index e858e55..a8a3307 100644
@@ -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			*/
include/config_distro_bootcmd.h +3 -3
index ad9045e..f419a4b 100644
@@ -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
include/config_fallbacks.h +1 -1
index 6b6ec00..245bd4d 100644
@@ -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) || \
include/configs/MPC8544DS.h +1 -1
index 2372d5f..7ba3d5f 100644
@@ -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
 
include/configs/MPC8572DS.h +1 -1
index 95f59e0..0daf85c 100644
@@ -586,7 +586,7 @@
 
 #if defined(CONFIG_PCI)
 #define CONFIG_CMD_PCI
-#define CONFIG_CMD_SCSI
+#define CONFIG_SCSI
 #define CONFIG_CMD_EXT2
 #endif
 
include/configs/MPC8610HPCD.h +1 -1
index ac219d1..65d5c2b 100644
@@ -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
include/configs/MPC8641HPCN.h +1 -1
index cd8d91f..6a85890 100644
@@ -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
include/configs/PIP405.h +1 -1
index b5959c8..46eb0a8 100644
@@ -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
include/configs/am57xx_evm.h +1 -1
index 1fffdb1..d982cd1 100644
@@ -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
include/configs/cm_t54.h +1 -1
index c8c67c4..249e573 100644
@@ -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
include/configs/db-88f6820-gp.h +1 -1
index ef14132..d838622 100644
@@ -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
include/configs/dra7xx_evm.h +1 -1
index 7734e8d..653c0e3 100644
@@ -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
include/configs/efi-x86.h +1 -1
index 6dd0b32..95e46c5 100644
@@ -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
 
include/configs/galileo.h +1 -1
index 14a42b1..9fe543c 100644
@@ -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
include/configs/highbank.h +1 -1
index 510741b..e845465 100644
@@ -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
include/configs/ls1043aqds.h +1 -1
index 7c19122..9421c49 100644
@@ -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
include/configs/ls2080aqds.h +1 -1
index 91fad0a..ae9dec8 100644
@@ -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
include/configs/ls2080ardb.h +1 -1
index 15a1172..2e3aeca 100644
@@ -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
include/configs/omap5_uevm.h +1 -1
index a5cfa0c..d924ce3 100644
@@ -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
include/configs/qemu-x86.h +1 -1
index b0d2ffe..476d37d 100644
@@ -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}
include/configs/sunxi-common.h +1 -1
index 8f11eb9..8aff3a5 100644
@@ -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
include/configs/x86-common.h +1 -1
index ea815c2..6e4e3a9 100644
@@ -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
include/configs/xilinx_zynqmp.h +1 -1
index 8cea610..1f85a20 100644
@@ -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)
Signature · 1 line
2.8.0.rc3.226.g39d4020
#20 lore raw

PATCH 15/44 dm: blk: Add a legacy block interface

In reply to Simon Glass

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

---

 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
drivers/block/Makefile +4 -0
index 3f75934..436b79f 100644
@@ -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
drivers/block/blk_legacy.c new file +258 -0

258 lines not on this page · raw message

include/blk.h +193 -0

199 lines not on this page · raw message

Signature · 1 line
2.8.0.rc3.226.g39d4020
#21 lore raw

PATCH 15/44 dm: blk: Add a legacy block interface

Quoted 5 lines · Simon Glass

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.

drivers/block/blk_legacy.c line 73

Quoted 11 lines
drivers/block/blk_legacy.c +9 -0
 
+#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.

drivers/block/blk_legacy.c line 81

Quoted 8 lines
drivers/block/blk_legacy.c +8 -0
+	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?

Quoted 1 line

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

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

Quoted 1 line

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

Quoted 5 lines
include/blk.h +2 -0
 
+struct blk_driver {
 
+	/**

include/blk.h static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, · line 393

Quoted 10 lines
include/blk.h +10 -0
+	 * 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.

include/blk.h static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, · line 397

Quoted 4 lines
include/blk.h +4 -0
+	 *
+	 * @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.

#22 lore raw

PATCH 15/44 dm: blk: Add a legacy block interface

Hi Stephen,

Quoted 9 lines · Stephen Warren
Quoted 6 lines · Simon Glass

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

Quoted 7 lines

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.

Quoted 15 lines

drivers/block/blk_legacy.c line 73

Quoted 13 lines
drivers/block/blk_legacy.c +9 -0
 
 
+#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;
Quoted 6 lines

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.

Quoted 11 lines

drivers/block/blk_legacy.c line 81

Quoted 9 lines
drivers/block/blk_legacy.c +8 -0
+       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);
Quoted 7 lines

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.

Quoted 5 lines
Quoted 2 lines

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

Quoted 6 lines
Quoted 3 lines

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

Quoted 24 lines
Quoted 19 lines
include/blk.h +5 -0
 
 
+struct blk_driver {
 
 
+       /**
+        * select_hwpart() - Select a hardware partition
+        *
+        * Some devices (e.g. MMC) can support partitioning at the

hardware

include/blk.h +3 -0
+        * 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

include/blk.h +3 -0
+        * covered by that partition is accessible.
+        *
+        * The MMC standard provides for two boot partitions (numbered 1
Quoted 3 lines

and 2),
+ * rpmb (3), and up to 4 addition general-purpose partitions
(4-7).

Quoted 2 lines

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

OK, will update comment.

Quoted 9 lines
Quoted 7 lines
include/blk.h +3 -0
+        *
+        * @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.

Quoted 5 lines

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

#23 lore raw

PATCH 16/44 dm: systemace: Add a legacy block interface

In reply to Simon Glass

Add a legacy block interface for systemace.

---

 drivers/block/systemace.c | 14 ++++++++++++++
 include/blk.h             |  1 +
 2 files changed, 15 insertions(+)
drivers/block/systemace.c +14 -0
index 09fe834..0d8e26f 100644
@@ -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,
+};
include/blk.h +1 -0
index ed868ef..12be6aa 100644
@@ -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 */
 };
Signature · 1 line
2.8.0.rc3.226.g39d4020
#24 lore raw

PATCH 16/44 dm: systemace: Add a legacy block interface

drivers/block/systemace.c struct blk_desc *systemace_get_dev(int dev) · line 135

Quoted 5 lines · Simon Glass

Add a legacy block interface for systemace.

drivers/block/systemace.c +1 -0
 
+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.

#25 lore raw

PATCH 16/44 dm: systemace: Add a legacy block interface

Hi Stephen,

Quoted 11 lines · Stephen Warren

drivers/block/systemace.c struct blk_desc *systemace_get_dev(int dev) · line 135

Quoted 8 lines · Simon Glass

Add a legacy block interface for systemace.

drivers/block/systemace.c +1 -0
 
 
+static int systemace_get_devp(int dev, struct blk_desc **descp)
Quoted 6 lines

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

#26 lore raw

PATCH 17/44 dm: sandbox: Add a legacy host block interface

In reply to Simon Glass

Add a legacy block interface for sandbox host.

---

 drivers/block/sandbox.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/block/sandbox.c +7 -0
index 6d41508..2b6a893 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#27 lore raw

PATCH 18/44 dm: usb: Add a legacy block interface for USB storage

In reply to Simon Glass

Add a legacy block interface for USB storage.

---

 common/usb_storage.c | 7 +++++++
 1 file changed, 7 insertions(+)
common/usb_storage.c +7 -0
index 9285c95..80bf3db 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#28 lore raw

PATCH 19/44 dm: mmc: Add a legacy block interface for MMC

In reply to Simon Glass

Add a legacy block interface for MMC.

---

 drivers/mmc/mmc.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)
drivers/mmc/mmc.c +27 -3
index d3c22ab..024368c 100644
@@ -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,
+};
Signature · 1 line
2.8.0.rc3.226.g39d4020
#29 lore raw

PATCH 20/44 dm: mmc: Add an implementation of the 'devnum' functions

In reply to Simon Glass

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.

---

 drivers/block/blk-uclass.c | 280 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 280 insertions(+)
drivers/block/blk-uclass.c +280 -0
index 617db22..3687b9a 100644
@@ -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;
Signature · 1 line
2.8.0.rc3.226.g39d4020
#30 lore raw

PATCH 20/44 dm: mmc: Add an implementation of the 'devnum' functions

Quoted 7 lines · Simon Glass

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

#31 lore raw

PATCH 20/44 dm: mmc: Add an implementation of the 'devnum' functions

Hi Stephen,

Quoted 13 lines · Stephen Warren
Quoted 10 lines · Simon Glass

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)

Quoted 6 lines

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

#32 lore raw

PATCH 21/44 dm: scsi: Separate the non-command code into its own file

In reply to Simon Glass

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.

---

 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
cmd/Makefile +0 -6
index 2aaf978..eb24704 100644
@@ -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
cmd/scsi.c +29 -597

696 lines not on this page · raw message

common/Makefile +4 -0
index 9a4b817..563bb94 100644
@@ -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
common/scsi.c new file +567 -0

567 lines not on this page · raw message

Signature · 1 line
2.8.0.rc3.226.g39d4020
#33 lore raw

PATCH 22/44 dm: ide: Separate the non-command code into its own file

In reply to Simon Glass

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.

---

 cmd/ide.c       | 1297 +------------------------------------------------------
 common/Makefile |    1 +
 common/ide.c    | 1206 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1228 insertions(+), 1276 deletions(-)
 create mode 100644 common/ide.c
cmd/ide.c +21 -1276
index db26f43..c942744 100644
@@ -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"
common/Makefile +1 -0
index 563bb94..f648423 100644
@@ -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
common/ide.c new file +1206 -0

1,206 lines not on this page · raw message

Signature · 1 line
2.8.0.rc3.226.g39d4020
#34 lore raw

PATCH 23/44 dm: sata: Separate the non-command code into its own file

In reply to Simon Glass

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.

---

 cmd/sata.c      | 138 ++++++++------------------------------------------------
 common/Makefile |   1 +
 common/sata.c   |  86 +++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+), 118 deletions(-)
 create mode 100644 common/sata.c
cmd/sata.c +20 -118
index b1a64d9..d18b523 100644
@@ -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");
common/Makefile +1 -0
index f648423..00d9dba 100644
@@ -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
common/sata.c new file +86 -0

86 lines not on this page · raw message

Signature · 1 line
2.8.0.rc3.226.g39d4020
#35 lore raw

PATCH 24/44 dm: disk: Use legacy block driver info for block device access

In reply to Simon Glass

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.

---

 disk/part.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
disk/part.c +3 -4
index a1d1d92..ec00feb 100644
@@ -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)
Signature · 1 line
2.8.0.rc3.226.g39d4020
#36 lore raw

PATCH 25/44 dm: usb: Drop the get_dev() function

In reply to Simon Glass

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

---

 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(-)
board/cm5200/fwupdate.c +1 -1
index 2ed90de..4740c83 100644
@@ -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;
 	}
cmd/usb.c +10 -6
index 9ed5dc6..78e3e5b 100644
@@ -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;
common/spl/spl_usb.c +1 -1
index c42848e..04fa667 100644
@@ -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
common/usb_storage.c +0 -17
index 80bf3db..f2da3a3 100644
@@ -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(".");
disk/part.c +1 -1
index ec00feb..7a1f75e 100644
@@ -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)
 	{
drivers/Makefile +1 -0
index 6900097..696b3ac 100644
@@ -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
 
include/part.h +0 -2
index dc8e72e..9be75d2 100644
@@ -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; }
include/usb.h +0 -1
index 5adad36..02a0ccd 100644
@@ -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);
 
Signature · 1 line
2.8.0.rc3.226.g39d4020
#37 lore raw

PATCH 26/44 dm: ide: Drop the get_dev() function

In reply to Simon Glass

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

---

 common/ide.c   | 7 -------
 disk/part.c    | 2 +-
 include/part.h | 2 --
 3 files changed, 1 insertion(+), 10 deletions(-)
common/ide.c +0 -7
index adc1966..5dc90d4 100644
@@ -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)
disk/part.c +1 -1
index 7a1f75e..a3a476e 100644
@@ -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, },
include/part.h +0 -2
index 9be75d2..f005a7c 100644
@@ -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; }
Signature · 1 line
2.8.0.rc3.226.g39d4020
#38 lore raw

PATCH 27/44 dm: mmc: Drop the get_dev() function

In reply to Simon Glass

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

---

 cmd/mmc.c         |  2 +-
 disk/part.c       |  1 -
 drivers/mmc/mmc.c | 16 ++--------------
 include/part.h    |  2 --
 4 files changed, 3 insertions(+), 18 deletions(-)
cmd/mmc.c +1 -1
index 39ef072..0fed790 100644
@@ -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;
disk/part.c +0 -1
index a3a476e..c294866 100644
@@ -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
drivers/mmc/mmc.c +2 -14
index 024368c..185d7b2 100644
@@ -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,
 };
include/part.h +0 -2
index f005a7c..45c6476 100644
@@ -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; }
Signature · 1 line
2.8.0.rc3.226.g39d4020
#39 lore raw

PATCH 28/44 dm: scsi: Drop the get_dev() function

In reply to Simon Glass

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

---

 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(-)
common/scsi.c +0 -7
index a336a10..5b6531f 100644
@@ -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
  */
common/spl/spl_sata.c +1 -1
index 1719946..9d8cc7c 100644
@@ -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;
 	}
disk/part.c +1 -1
index c294866..182d706 100644
@@ -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", },
include/part.h +0 -2
index 45c6476..ec2dad8 100644
@@ -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; }
Signature · 1 line
2.8.0.rc3.226.g39d4020
#40 lore raw

PATCH 29/44 dm: sata: Drop the get_dev() function

In reply to Simon Glass

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.

---

 disk/part.c    | 2 +-
 include/part.h | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)
disk/part.c +1 -1
index 182d706..30ae030 100644
@@ -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", },
include/part.h +0 -2
index ec2dad8..03d4b3d 100644
@@ -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; }
Signature · 1 line
2.8.0.rc3.226.g39d4020
#41 lore raw

PATCH 30/44 dm: systemace: Drop the get_dev() function

In reply to Simon Glass

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

---

 disk/part.c               |  2 +-
 drivers/block/systemace.c | 14 +++-----------
 include/part.h            |  2 --
 include/systemace.h       |  7 -------
 4 files changed, 4 insertions(+), 21 deletions(-)
disk/part.c +1 -1
index 30ae030..d52d48b 100644
@@ -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, },
drivers/block/systemace.c +3 -11
index 0d8e26f..4f14d5f 100644
@@ -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,
 };
include/part.h +0 -2
index 03d4b3d..29625f6 100644
@@ -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; }
 
include/systemace.h +0 -7
index 3b6ec7d..bccb2a2 100644
@@ -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 */
Signature · 1 line
2.8.0.rc3.226.g39d4020
#42 lore raw

PATCH 31/44 dm: blk: Drop the systemace.h header

In reply to Simon Glass

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

---

 drivers/block/systemace.c |  1 -
 include/systemace.h       | 10 ----------
 2 files changed, 11 deletions(-)
 delete mode 100644 include/systemace.h
drivers/block/systemace.c +0 -1
index 4f14d5f..79e1263 100644
@@ -27,7 +27,6 @@
 
 #include <common.h>
 #include <command.h>
-#include <systemace.h>
 #include <part.h>
 #include <asm/io.h>
 
include/systemace.h deleted +0 -10
deleted file mode 100644
index bccb2a2..0000000
@@ -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 */
Signature · 1 line
2.8.0.rc3.226.g39d4020
#43 lore raw

PATCH 32/44 dm: sandbox: Drop the host_get_dev() function

In reply to Simon Glass

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

---

 disk/part.c             |  2 +-
 drivers/block/sandbox.c | 10 ----------
 include/part.h          |  2 --
 3 files changed, 1 insertion(+), 13 deletions(-)
disk/part.c +1 -1
index d52d48b..8d5f028 100644
@@ -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
 	{ },
 };
drivers/block/sandbox.c +0 -10
index 2b6a893..ac28f83 100644
@@ -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,
include/part.h +0 -2
index 29625f6..1b17436 100644
@@ -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; }
Signature · 1 line
2.8.0.rc3.226.g39d4020
#44 lore raw

PATCH 33/44 dm: part: Drop the get_dev() method

In reply to Simon Glass

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

---

 include/part.h | 1 -
 1 file changed, 1 deletion(-)
include/part.h +0 -1
index 1b17436..afe5633 100644
@@ -12,7 +12,6 @@
 
 struct block_drvr {
 	char *name;
-	struct blk_desc* (*get_dev)(int dev);
 	int (*select_hwpart)(int dev_num, int hwpart);
 };
 
Signature · 1 line
2.8.0.rc3.226.g39d4020
#45 lore raw

PATCH 34/44 dm: ide: Add support for driver-model block devices

In reply to Simon Glass

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

---

 common/ide.c  | 32 ++++++++++++++++++++++++++++++++
 include/ide.h |  8 ++++++++
 2 files changed, 40 insertions(+)
common/ide.c +32 -0
index 5dc90d4..ac5b91c 100644
@@ -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
include/ide.h +8 -0
index a4e65cf..9b0a4a9 100644
@@ -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);
Signature · 1 line
2.8.0.rc3.226.g39d4020
#46 lore raw

PATCH 34/44 dm: ide: Add support for driver-model block devices

Quoted 6 lines · Simon Glass

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

include/ide.h +2 -0
 
+struct udevice;
+#ifdef CONFIG_BLK

include/ide.h void ide_led(uchar led, uchar status); · line 48

Quoted 10 lines
include/ide.h +6 -0
+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?

#47 lore raw

PATCH 34/44 dm: ide: Add support for driver-model block devices

Hi Stephen,

Quoted 20 lines · Stephen Warren
Quoted 19 lines · Simon Glass

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

include/ide.h +7 -0
 
 
+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,

Quoted 8 lines
Quoted 2 lines
                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

#48 lore raw

PATCH 35/44 dm: sandbox: Enable IDE

In reply to Simon Glass

Enable building the IDE code for sandbox.

---

 include/configs/sandbox.h | 10 ++++++++++
 1 file changed, 10 insertions(+)
include/configs/sandbox.h +10 -0
index cc22467..08a45f9 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#49 lore raw

PATCH 35/44 dm: sandbox: Enable IDE

Quoted 1 line · Simon Glass

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?

#50 lore raw

PATCH 35/44 dm: sandbox: Enable IDE

Quoted 8 lines · Stephen Warren
Quoted 2 lines · Simon Glass

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

#51 lore raw

PATCH 36/44 dm: scsi: Add support for driver-model block devices

In reply to Simon Glass

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

---

 common/scsi.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
common/scsi.c +32 -0
index 5b6531f..8ac28dd 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#52 lore raw

PATCH 37/44 dm: sandbox: Enable SCSI

In reply to Simon Glass

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

---

 include/configs/sandbox.h | 6 ++++++
 1 file changed, 6 insertions(+)
include/configs/sandbox.h +6 -0
index 08a45f9..6d8ce13 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#53 lore raw

PATCH 38/44 dm: sata: Add support for driver-model block devices

In reply to Simon Glass

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.

---

 common/sata.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)
common/sata.c +30 -1
index 1d52fcb..88f08c9 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#54 lore raw

PATCH 39/44 dm: sandbox: Enable SATA

In reply to Simon Glass

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

---

 include/configs/sandbox.h | 3 +++
 1 file changed, 3 insertions(+)
include/configs/sandbox.h +3 -0
index 6d8ce13..8c497bb 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#55 lore raw

PATCH 40/44 dm: blk: Allow blk_create_device() to allocate the device number

In reply to Simon Glass

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.

---

 drivers/block/blk-uclass.c | 29 +++++++++++++++++++++++++++++
 include/blk.h              | 15 ++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)
drivers/block/blk-uclass.c +29 -0
index 3687b9a..c947d95 100644
@@ -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;
 
include/blk.h +14 -1
index 12be6aa..9f4a63d 100644
@@ -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>
 /*
Signature · 1 line
2.8.0.rc3.226.g39d4020
#56 lore raw

PATCH 40/44 dm: blk: Allow blk_create_device() to allocate the device number

Quoted 6 lines · Simon Glass

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.

drivers/block/blk-uclass.c +0 -0
 

drivers/block/blk-uclass.c int blk_prepare_device(struct udevice *dev) · line 423

Quoted 10 lines
drivers/block/blk-uclass.c +10 -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;

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.

drivers/block/blk-uclass.c int blk_create_device(struct udevice *parent, const char *drv_name, · line 454

Quoted 8 lines
drivers/block/blk-uclass.c +4 -0
@@ -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.

Quoted 6 lines
drivers/block/blk-uclass.c +5 -0
+		else if (ret < 0)
+			return ret;
+		else
+			devnum = ret + 1;
+	}
  	desc->devnum = devnum;
#57 lore raw

PATCH 40/44 dm: blk: Allow blk_create_device() to allocate the device number

Hi Stephen,

Quoted 38 lines · Stephen Warren
Quoted 10 lines · Simon Glass

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.

drivers/block/blk-uclass.c +0 -0
 
 

drivers/block/blk-uclass.c int blk_prepare_device(struct udevice *dev) · line 423

Quoted 10 lines
drivers/block/blk-uclass.c +10 -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;

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:

Quoted 5 lines

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.

Quoted 14 lines

drivers/block/blk-uclass.c int blk_create_device(struct udevice *parent, const · line 455

Quoted 10 lines
drivers/block/blk-uclass.c +4 -0
@@ -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.

Quoted 10 lines

drivers/block/blk-uclass.c int blk_create_device(struct udevice *parent, const char *drv_name, · line 460

Quoted 8 lines
drivers/block/blk-uclass.c +5 -0
+               else if (ret < 0)
+                       return ret;
+               else
+                       devnum = ret + 1;
+       }
        desc->devnum = devnum;

Regards,
Simon

#58 lore raw

PATCH 41/44 dm: blk: Add a easier way to create a named block device

In reply to Simon Glass

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.

---

 common/usb_storage.c       | 13 +++++--------
 drivers/block/blk-uclass.c | 15 +++++++++++++++
 include/blk.h              | 17 +++++++++++++++++
 3 files changed, 37 insertions(+), 8 deletions(-)
common/usb_storage.c +5 -8
index f2da3a3..7e6e52d 100644
@@ -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;
drivers/block/blk-uclass.c +15 -0
index c947d95..6ecbff0 100644
@@ -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;
include/blk.h +17 -0
index 9f4a63d..19bc6a4 100644
@@ -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.
Signature · 1 line
2.8.0.rc3.226.g39d4020
#59 lore raw

PATCH 42/44 dm: systemace: Reorder function to avoid forward declarataions

In reply to Simon Glass

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

---

 drivers/block/systemace.c | 57 +++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 31 deletions(-)
drivers/block/systemace.c +26 -31
index 79e1263..eeba7f0 100644
@@ -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,
Signature · 1 line
2.8.0.rc3.226.g39d4020
#60 lore raw

PATCH 43/44 dm: systemace: Add driver-mode block-device support

In reply to Simon Glass

Add support for CONFIG_BLK to the systemace driver.

---

 drivers/block/systemace.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)
drivers/block/systemace.c +44 -0
index eeba7f0..9392bea 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020
#61 lore raw

PATCH 44/44 dm: sandbox: Enable systemace

In reply to Simon Glass

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

---

 include/configs/sandbox.h | 4 ++++
 1 file changed, 4 insertions(+)
include/configs/sandbox.h +4 -0
index 8c497bb..f0f7cd4 100644
@@ -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
Signature · 1 line
2.8.0.rc3.226.g39d4020