aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2009-03-31 14:15:28 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-03-31 14:15:28 -0400
commit74638c84821c066d02c158bc843c84499ddc9764 (patch)
treecd6f79f34d87d25a621aaf1369ce226923de3c14 /drivers/ide
parentc4199930b119eb9c1ffb102ed57eaac4d4424d08 (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>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-dma.c8
-rw-r--r--drivers/ide/ide-iops.c12
-rw-r--r--drivers/ide/ide-timings.c12
-rw-r--r--drivers/ide/ide-xfer-mode.c15
-rw-r--r--drivers/ide/sl82c105.c3
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" };
11static const char *mwdma_str[] = 11static const char *mwdma_str[] =
12 { "MWDMA0", "MWDMA1", "MWDMA2" }; 12 { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
13static const char *swdma_str[] = 13static const char *swdma_str[] =
14 { "SWDMA0", "SWDMA1", "SWDMA2" }; 14 { "SWDMA0", "SWDMA1", "SWDMA2" };
15static const char *pio_str[] = 15static 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;