
Wolfgang Denk wrote:
Dear "Steven A. Falco",
In message 48A35533.1010901@harris.com you wrote:
The following patch adds the ability to call-out from the ide_ident routine to a board-specific routine to set the PIO mode of an attached device.
This feature is controlled by the preprocessor variable CONFIG_TUNE_CFA.
What does CFA mean?
CFA is "Compact Flash Association". Since this hook could be used more generally, a better name is probably CONFIG_TUNE_PIO, so that is what I used in the respin of the patch shown below.
cmd_ide.c is modified to use the "drive identify information" read from the device to compute a pio mode in the range 0 to 6. This is then passed to a board-specific routine, ide_set_piomode, to set the mode in hardware.
Two other files are touched: file ata.h, to include word 163, which is the "advanced CF parameters", and file ide.h, to add a prototype for the board-specific routine (again controlled by the CONFIG_TUNE_CFA variable).
Is there a specific reason for using #ifdef's instead of a weak function?
No reason. The respin below uses weak linkage. I still included ifdefs, because I'm guessing that if one does not use the tuning feature, then we wouldn't want the overhead of calculating the pio_mode, only to discard it. But I can remove the ifdefs completely if you prefer.
I can also present some example code showing how I am using this hook in a BSP I am working on. But the BSP is not in good enough shape for submission.
Best regards,
Wolfgang Denk
Steve
Signed-off-by: Steven A. Falco sfalco@harris.com --- common/cmd_ide.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/ata.h | 4 +++- 2 files changed, 55 insertions(+), 1 deletions(-)
diff --git a/common/cmd_ide.c b/common/cmd_ide.c index b4d9719..0e435a7 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,40 @@ 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((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..3269636 100644 --- a/include/ata.h +++ b/include/ata.h @@ -294,7 +294,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;