
Wolfgang Denk wrote:
Dear "Steven A. Falco",
In message 48A5C296.1060801@harris.com you wrote:
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.
It is, but can you please split this into two independent patches?
Thanks in advance.
Best regards,
Wolfgang Denk
[PATCH 2/3] Add a hook to allow board-specific PIO mode setting.
This patch adds a hook whereby a board-specific routine can be called to configure hardware for a PIO mode. The prototype for the board-specific routine is:
int inline ide_set_piomode(int pio_mode)
ide_set_piomode should be prepared to configure hardware for a pio_mode between 0 and 6, inclusive. It should return 0 on success or 1 on failure.
Signed-off-by: Steven A. Falco sfalco@harris.com --- common/cmd_ide.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ include/ata.h | 4 +++- 2 files changed, 49 insertions(+), 1 deletions(-)
diff --git a/common/cmd_ide.c b/common/cmd_ide.c index d6ba79f..0691007 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -543,6 +543,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 + void ide_init (void) {
@@ -1053,6 +1063,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 @@ -1168,6 +1182,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 b669423..2396769 100644 --- a/include/ata.h +++ b/include/ata.h @@ -236,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;