diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-03-31 14:15:28 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-03-31 14:15:28 -0400 |
commit | 74638c84821c066d02c158bc843c84499ddc9764 (patch) | |
tree | cd6f79f34d87d25a621aaf1369ce226923de3c14 | |
parent | c4199930b119eb9c1ffb102ed57eaac4d4424d08 (diff) |
ide: add support for CFA specified transfer modes (take 3)
Add support for the CompactFlash specific PIO modes 5/6 and MWDMA modes 3/4.
Since there were no PIO5 capable hard drives produced and one would also need
66 MHz IDE clock to actually get the difference WRT the address setup timings
programmed, I decided to simply replace the old non-standard PIO mode 5 timings
with the CFA specified ones.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: stf_xl@wp.pl
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/ide-dma.c | 8 | ||||
-rw-r--r-- | drivers/ide/ide-iops.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-timings.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-xfer-mode.c | 15 | ||||
-rw-r--r-- | drivers/ide/sl82c105.c | 3 |
5 files changed, 40 insertions, 10 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index f9c91752f275..a0b8cab1d9a6 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -261,6 +261,14 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode) | |||
261 | break; | 261 | break; |
262 | case XFER_MW_DMA_0: | 262 | case XFER_MW_DMA_0: |
263 | mask = id[ATA_ID_MWDMA_MODES]; | 263 | mask = id[ATA_ID_MWDMA_MODES]; |
264 | |||
265 | /* Also look for the CF specific MWDMA modes... */ | ||
266 | if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 0x38)) { | ||
267 | u8 mode = ((id[ATA_ID_CFA_MODES] & 0x38) >> 3) - 1; | ||
268 | |||
269 | mask |= ((2 << mode) - 1) << 3; | ||
270 | } | ||
271 | |||
264 | if (port_ops && port_ops->mdma_filter) | 272 | if (port_ops && port_ops->mdma_filter) |
265 | mask &= port_ops->mdma_filter(drive); | 273 | mask &= port_ops->mdma_filter(drive); |
266 | else | 274 | else |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 0e62698146b6..0caca342802d 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -306,6 +306,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
306 | drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES]; | 306 | drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES]; |
307 | drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES]; | 307 | drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES]; |
308 | drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES]; | 308 | drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES]; |
309 | drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES]; | ||
309 | /* anything more ? */ | 310 | /* anything more ? */ |
310 | 311 | ||
311 | kfree(id); | 312 | kfree(id); |
@@ -390,7 +391,10 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
390 | id[ATA_ID_UDMA_MODES] &= ~0xFF00; | 391 | id[ATA_ID_UDMA_MODES] &= ~0xFF00; |
391 | id[ATA_ID_MWDMA_MODES] &= ~0x0700; | 392 | id[ATA_ID_MWDMA_MODES] &= ~0x0700; |
392 | id[ATA_ID_SWDMA_MODES] &= ~0x0700; | 393 | id[ATA_ID_SWDMA_MODES] &= ~0x0700; |
393 | } | 394 | if (ata_id_is_cfa(id)) |
395 | id[ATA_ID_CFA_MODES] &= ~0x0E00; | ||
396 | } else if (ata_id_is_cfa(id)) | ||
397 | id[ATA_ID_CFA_MODES] &= ~0x01C0; | ||
394 | 398 | ||
395 | skip: | 399 | skip: |
396 | #ifdef CONFIG_BLK_DEV_IDEDMA | 400 | #ifdef CONFIG_BLK_DEV_IDEDMA |
@@ -403,12 +407,18 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
403 | if (speed >= XFER_UDMA_0) { | 407 | if (speed >= XFER_UDMA_0) { |
404 | i = 1 << (speed - XFER_UDMA_0); | 408 | i = 1 << (speed - XFER_UDMA_0); |
405 | id[ATA_ID_UDMA_MODES] |= (i << 8 | i); | 409 | id[ATA_ID_UDMA_MODES] |= (i << 8 | i); |
410 | } else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) { | ||
411 | i = speed - XFER_MW_DMA_2; | ||
412 | id[ATA_ID_CFA_MODES] |= i << 9; | ||
406 | } else if (speed >= XFER_MW_DMA_0) { | 413 | } else if (speed >= XFER_MW_DMA_0) { |
407 | i = 1 << (speed - XFER_MW_DMA_0); | 414 | i = 1 << (speed - XFER_MW_DMA_0); |
408 | id[ATA_ID_MWDMA_MODES] |= (i << 8 | i); | 415 | id[ATA_ID_MWDMA_MODES] |= (i << 8 | i); |
409 | } else if (speed >= XFER_SW_DMA_0) { | 416 | } else if (speed >= XFER_SW_DMA_0) { |
410 | i = 1 << (speed - XFER_SW_DMA_0); | 417 | i = 1 << (speed - XFER_SW_DMA_0); |
411 | id[ATA_ID_SWDMA_MODES] |= (i << 8 | i); | 418 | id[ATA_ID_SWDMA_MODES] |= (i << 8 | i); |
419 | } else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) { | ||
420 | i = speed - XFER_PIO_4; | ||
421 | id[ATA_ID_CFA_MODES] |= i << 6; | ||
412 | } | 422 | } |
413 | 423 | ||
414 | if (!drive->init_speed) | 424 | if (!drive->init_speed) |
diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c index 81f527af8fae..001a56365be5 100644 --- a/drivers/ide/ide-timings.c +++ b/drivers/ide/ide-timings.c | |||
@@ -43,6 +43,8 @@ static struct ide_timing ide_timing[] = { | |||
43 | { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, | 43 | { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, |
44 | { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, | 44 | { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, |
45 | 45 | ||
46 | { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 }, | ||
47 | { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 }, | ||
46 | { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, | 48 | { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, |
47 | { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, | 49 | { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, |
48 | { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, | 50 | { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, |
@@ -51,7 +53,8 @@ static struct ide_timing ide_timing[] = { | |||
51 | { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, | 53 | { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, |
52 | { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, | 54 | { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, |
53 | 55 | ||
54 | { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 }, | 56 | { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 }, |
57 | { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 }, | ||
55 | { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, | 58 | { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, |
56 | { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, | 59 | { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, |
57 | 60 | ||
@@ -90,6 +93,10 @@ u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio) | |||
90 | /* conservative "downgrade" for all pre-ATA2 drives */ | 93 | /* conservative "downgrade" for all pre-ATA2 drives */ |
91 | if (pio < 3 && cycle < t->cycle) | 94 | if (pio < 3 && cycle < t->cycle) |
92 | cycle = 0; /* use standard timing */ | 95 | cycle = 0; /* use standard timing */ |
96 | |||
97 | /* Use the standard timing for the CF specific modes too */ | ||
98 | if (pio > 4 && ata_id_is_cfa(id)) | ||
99 | cycle = 0; | ||
93 | } | 100 | } |
94 | 101 | ||
95 | return cycle ? cycle : t->cycle; | 102 | return cycle ? cycle : t->cycle; |
@@ -161,7 +168,8 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed, | |||
161 | 168 | ||
162 | if (speed <= XFER_PIO_2) | 169 | if (speed <= XFER_PIO_2) |
163 | p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; | 170 | p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; |
164 | else if (speed <= XFER_PIO_5) | 171 | else if ((speed <= XFER_PIO_4) || |
172 | (speed == XFER_PIO_5 && !ata_id_is_cfa(id))) | ||
165 | p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; | 173 | p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY]; |
166 | else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) | 174 | else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) |
167 | p.cycle = id[ATA_ID_EIDE_DMA_MIN]; | 175 | p.cycle = id[ATA_ID_EIDE_DMA_MIN]; |
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c index 6910f6a257e8..af44be9d546c 100644 --- a/drivers/ide/ide-xfer-mode.c +++ b/drivers/ide/ide-xfer-mode.c | |||
@@ -9,11 +9,11 @@ static const char *udma_str[] = | |||
9 | { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44", | 9 | { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44", |
10 | "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" }; | 10 | "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" }; |
11 | static const char *mwdma_str[] = | 11 | static const char *mwdma_str[] = |
12 | { "MWDMA0", "MWDMA1", "MWDMA2" }; | 12 | { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" }; |
13 | static const char *swdma_str[] = | 13 | static const char *swdma_str[] = |
14 | { "SWDMA0", "SWDMA1", "SWDMA2" }; | 14 | { "SWDMA0", "SWDMA1", "SWDMA2" }; |
15 | static const char *pio_str[] = | 15 | static const char *pio_str[] = |
16 | { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" }; | 16 | { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" }; |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * ide_xfer_verbose - return IDE mode names | 19 | * ide_xfer_verbose - return IDE mode names |
@@ -30,11 +30,11 @@ const char *ide_xfer_verbose(u8 mode) | |||
30 | 30 | ||
31 | if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7) | 31 | if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7) |
32 | s = udma_str[i]; | 32 | s = udma_str[i]; |
33 | else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2) | 33 | else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4) |
34 | s = mwdma_str[i]; | 34 | s = mwdma_str[i]; |
35 | else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2) | 35 | else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2) |
36 | s = swdma_str[i]; | 36 | s = swdma_str[i]; |
37 | else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5) | 37 | else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6) |
38 | s = pio_str[i & 0x7]; | 38 | s = pio_str[i & 0x7]; |
39 | else if (mode == XFER_PIO_SLOW) | 39 | else if (mode == XFER_PIO_SLOW) |
40 | s = "PIO SLOW"; | 40 | s = "PIO SLOW"; |
@@ -79,7 +79,10 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */ | 81 | if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */ |
82 | if (ata_id_has_iordy(id)) { | 82 | if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7)) |
83 | pio_mode = 4 + min_t(int, 2, | ||
84 | id[ATA_ID_CFA_MODES] & 7); | ||
85 | else if (ata_id_has_iordy(id)) { | ||
83 | if (id[ATA_ID_PIO_MODES] & 7) { | 86 | if (id[ATA_ID_PIO_MODES] & 7) { |
84 | overridden = 0; | 87 | overridden = 0; |
85 | if (id[ATA_ID_PIO_MODES] & 4) | 88 | if (id[ATA_ID_PIO_MODES] & 4) |
@@ -239,7 +242,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | |||
239 | 242 | ||
240 | BUG_ON(rate < XFER_PIO_0); | 243 | BUG_ON(rate < XFER_PIO_0); |
241 | 244 | ||
242 | if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) | 245 | if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6) |
243 | return ide_set_pio_mode(drive, rate); | 246 | return ide_set_pio_mode(drive, rate); |
244 | 247 | ||
245 | return ide_set_dma_mode(drive, rate); | 248 | return ide_set_dma_mode(drive, rate); |
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index d6f8977191c8..b0a460625335 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c | |||
@@ -61,7 +61,8 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio) | |||
61 | if (cmd_off == 0) | 61 | if (cmd_off == 0) |
62 | cmd_off = 1; | 62 | cmd_off = 1; |
63 | 63 | ||
64 | if (pio > 2 || ata_id_has_iordy(drive->id)) | 64 | if ((pio > 2 || ata_id_has_iordy(drive->id)) && |
65 | !(pio > 4 && ata_id_is_cfa(drive->id))) | ||
65 | iordy = 0x40; | 66 | iordy = 0x40; |
66 | 67 | ||
67 | return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy; | 68 | return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy; |