[U-Boot] [RFC] setting pio modes for IDE devices

Steven A. Falco sfalco at harris.com
Fri Aug 15 19:53:26 CEST 2008


I realized that I should be checking to see if word 163 is applicable to
the ATA device in question.  To do that, I need to call ata_id_is_cfa() from
libata.h.  However, libata.h conflicts with ata.h because of duplicate
enum values.

Therefore, this respin of the proposed patch deletes the duplicate enums
from ata.h and instead includes libata.h to supply the enums.  Then, I
can call ata_id_is_cfa() and more accurately detect PIO 5 and 6.

I believe cleaning up ata.h is a good thing, because duplicating the enums in
both places invites them to get out of sync.

Signed-off-by: Steven A. Falco <sfalco at harris.com>
---
 common/cmd_ide.c |   50 ++++++++++++++++++++++++++++++++++++++++
 include/ata.h    |   66 ++++-------------------------------------------------
 2 files changed, 55 insertions(+), 61 deletions(-)

diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index b4d9719..19dd2c2 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -167,6 +167,10 @@ static void input_data(int dev, ulong *sect_buf, int words);
 static void output_data(int dev, ulong *sect_buf, int words);
 static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);

+#ifdef CONFIG_TUNE_PIO
+int inline ide_set_piomode(int pio_mode);
+#endif
+
 #ifndef CFG_ATA_PORT_ADDR
 #define CFG_ATA_PORT_ADDR(port) (port)
 #endif
@@ -838,6 +842,16 @@ __ide_inb(int dev, int port)
 unsigned char inline ide_inb(int dev, int port)
 			__attribute__((weak, alias("__ide_inb")));

+#ifdef CONFIG_TUNE_PIO
+int inline
+__ide_set_piomode(int pio_mode)
+{
+	return 0;
+}
+int inline ide_set_piomode(int pio_mode)
+			__attribute__((weak, alias("__ide_set_piomode")));
+#endif
+
 #ifdef __PPC__
 # ifdef CONFIG_AMIGAONEG3SE
 static void
@@ -1054,6 +1068,10 @@ static void ide_ident (block_dev_desc_t *dev_desc)
 	int do_retry = 0;
 #endif

+#ifdef CONFIG_TUNE_PIO
+	int pio_mode;
+#endif
+
 #if 0
 	int mode, cycle_time;
 #endif
@@ -1169,6 +1187,38 @@ static void ide_ident (block_dev_desc_t *dev_desc)
 	else
 		dev_desc->removable = 0;

+#ifdef CONFIG_TUNE_PIO
+	/* Mode 0 - 2 only, are directly determined by word 51. */
+	pio_mode = iop->tPIO;
+	if (pio_mode > 2) {
+		printf("WARNING: Invalid PIO (word 51 = %d).\n", pio_mode);
+		pio_mode = 0; /* Force it to dead slow, and hope for the best... */
+	}
+
+	/* Any CompactFlash Storage Card that supports PIO mode 3 or above
+	 * shall set bit 1 of word 53 to one and support the fields contained
+	 * in words 64 through 70.
+	 */
+	if (iop->field_valid & 0x02) {
+		/* Mode 3 and above are possible.  Check in order from slow
+		 * to fast, so we wind up with the highest mode allowed.
+		 */
+		if (iop->eide_pio_modes & 0x01)
+			pio_mode = 3;
+		if (iop->eide_pio_modes & 0x02)
+			pio_mode = 4;
+		if (ata_id_is_cfa((u16 *)iop)) {
+			if ((iop->cf_advanced_caps & 0x07) == 0x01)
+				pio_mode = 5;
+			if ((iop->cf_advanced_caps & 0x07) == 0x02)
+				pio_mode = 6;
+		}
+	}
+
+	/* System-specific, depends on bus speeds, etc. */
+	ide_set_piomode(pio_mode);
+#endif /* CONFIG_TUNE_PIO */
+
 #if 0
 	/*
 	 * Drive PIO mode autoselection
diff --git a/include/ata.h b/include/ata.h
index aa6e90d..2396769 100644
--- a/include/ata.h
+++ b/include/ata.h
@@ -33,6 +33,8 @@
 #ifndef	_ATA_H
 #define _ATA_H

+#include <libata.h>
+
 /* Register addressing depends on the hardware design; for instance,
  * 8-bit (register) and 16-bit (data) accesses might use different
  * address spaces. This is implemented by the following definitions.
@@ -83,66 +85,6 @@
 #define ATA_DEVICE(x)	((x & 1)<<4)
 #define ATA_LBA		0xE0

-enum {
-	ATA_MAX_DEVICES = 1,	/* per bus/port */
-	ATA_MAX_PRD = 256,	/* we could make these 256/256 */
-	ATA_SECT_SIZE = 256,	/*256 words per sector */
-
-	/* bits in ATA command block registers */
-	ATA_HOB = (1 << 7),	/* LBA48 selector */
-	ATA_NIEN = (1 << 1),	/* disable-irq flag */
-	/*ATA_LBA                 = (1 << 6), */ /* LBA28 selector */
-	ATA_DEV1 = (1 << 4),	/* Select Device 1 (slave) */
-	ATA_DEVICE_OBS = (1 << 7) | (1 << 5),	/* obs bits in dev reg */
-	ATA_DEVCTL_OBS = (1 << 3),	/* obsolete bit in devctl reg */
-	ATA_BUSY = (1 << 7),	/* BSY status bit */
-	ATA_DRDY = (1 << 6),	/* device ready */
-	ATA_DF = (1 << 5),	/* device fault */
-	ATA_DRQ = (1 << 3),	/* data request i/o */
-	ATA_ERR = (1 << 0),	/* have an error */
-	ATA_SRST = (1 << 2),	/* software reset */
-	ATA_ABORTED = (1 << 2),	/* command aborted */
-	/* ATA command block registers */
-	ATA_REG_DATA = 0x00,
-	ATA_REG_ERR = 0x01,
-	ATA_REG_NSECT = 0x02,
-	ATA_REG_LBAL = 0x03,
-	ATA_REG_LBAM = 0x04,
-	ATA_REG_LBAH = 0x05,
-	ATA_REG_DEVICE = 0x06,
-	ATA_REG_STATUS = 0x07,
-	ATA_PCI_CTL_OFS = 0x02,
-	/* and their aliases */
-	ATA_REG_FEATURE = ATA_REG_ERR,
-	ATA_REG_CMD = ATA_REG_STATUS,
-	ATA_REG_BYTEL = ATA_REG_LBAM,
-	ATA_REG_BYTEH = ATA_REG_LBAH,
-	ATA_REG_DEVSEL = ATA_REG_DEVICE,
-	ATA_REG_IRQ = ATA_REG_NSECT,
-
-	/* SETFEATURES stuff */
-	SETFEATURES_XFER = 0x03,
-	XFER_UDMA_7 = 0x47,
-	XFER_UDMA_6 = 0x46,
-	XFER_UDMA_5 = 0x45,
-	XFER_UDMA_4 = 0x44,
-	XFER_UDMA_3 = 0x43,
-	XFER_UDMA_2 = 0x42,
-	XFER_UDMA_1 = 0x41,
-	XFER_UDMA_0 = 0x40,
-	XFER_MW_DMA_2 = 0x22,
-	XFER_MW_DMA_1 = 0x21,
-	XFER_MW_DMA_0 = 0x20,
-	XFER_PIO_4 = 0x0C,
-	XFER_PIO_3 = 0x0B,
-	XFER_PIO_2 = 0x0A,
-	XFER_PIO_1 = 0x09,
-	XFER_PIO_0 = 0x08,
-	XFER_SW_DMA_2 = 0x12,
-	XFER_SW_DMA_1 = 0x11,
-	XFER_SW_DMA_0 = 0x10,
-	XFER_PIO_SLOW = 0x00
-};
 /*
  * ATA Commands (only mandatory commands listed here)
  */
@@ -294,7 +236,9 @@ typedef struct hd_driveid {
 	unsigned short	words130_155[26];/* reserved vendor words 130-155 */
 	unsigned short	word156;
 	unsigned short	words157_159[3];/* reserved vendor words 157-159 */
-	unsigned short	words160_255[95];/* reserved words 160-255 */
+	unsigned short	words160_162[3];/* reserved words 160-162 */
+	unsigned short	cf_advanced_caps;
+	unsigned short	words164_255[92];/* reserved words 164-255 */
 } hd_driveid_t;


-- 
1.5.5.1




More information about the U-Boot mailing list