aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2009-03-31 14:15:27 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-03-31 14:15:27 -0400
commit8d64fcd9357798ad0d61f8877de13d5e1b1ab510 (patch)
tree7e0737ef385b80faf9fa3f5d0c1df1f22254d0d8 /drivers/ide
parent985232e388714d4a9e94b4d96ee69b6ff8c9dc31 (diff)
ide: identify data word 53 bit 1 doesn't cover words 62 and 63 (take 3)
The IDE code assumed for years that the bit 1 of the identify data word 53 also covers the validity of the SW/MW DMA information in words 62 and 63, but it has always covered only words 64 thru 70, with words 62 and 63 being defined in the original ATA spec, not in ATA-2... This fix however should only concern *very* old hard disks and rather old CF cards... Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/cs5530.c3
-rw-r--r--drivers/ide/ide-dma-sff.c7
-rw-r--r--drivers/ide/ide-dma.c32
-rw-r--r--drivers/ide/sc1200.c3
4 files changed, 19 insertions, 26 deletions
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index 8e8b35a89901..40bf05eddf6e 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -92,8 +92,7 @@ static u8 cs5530_udma_filter(ide_drive_t *drive)
92 if ((mateid[ATA_ID_FIELD_VALID] & 4) && 92 if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
93 (mateid[ATA_ID_UDMA_MODES] & 7)) 93 (mateid[ATA_ID_UDMA_MODES] & 7))
94 goto out; 94 goto out;
95 if ((mateid[ATA_ID_FIELD_VALID] & 2) && 95 if (mateid[ATA_ID_MWDMA_MODES] & 7)
96 (mateid[ATA_ID_MWDMA_MODES] & 7))
97 mask = 0; 96 mask = 0;
98 } 97 }
99out: 98out:
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index f8c7d0cd2ff8..16fc46edc32d 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -38,10 +38,9 @@ int config_drive_for_dma(ide_drive_t *drive)
38 * Enable DMA on any drive that has mode2 DMA 38 * Enable DMA on any drive that has mode2 DMA
39 * (multi or single) enabled 39 * (multi or single) enabled
40 */ 40 */
41 if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */ 41 if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
42 if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 || 42 (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
43 (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404) 43 return 1;
44 return 1;
45 44
46 /* Consult the list of known "good" drives */ 45 /* Consult the list of known "good" drives */
47 if (ide_dma_good_drive(drive)) 46 if (ide_dma_good_drive(drive))
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index a5612eadc306..f9c91752f275 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -245,12 +245,11 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
245 case XFER_UDMA_0: 245 case XFER_UDMA_0:
246 if ((id[ATA_ID_FIELD_VALID] & 4) == 0) 246 if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
247 break; 247 break;
248 248 mask = id[ATA_ID_UDMA_MODES];
249 if (port_ops && port_ops->udma_filter) 249 if (port_ops && port_ops->udma_filter)
250 mask = port_ops->udma_filter(drive); 250 mask &= port_ops->udma_filter(drive);
251 else 251 else
252 mask = hwif->ultra_mask; 252 mask &= hwif->ultra_mask;
253 mask &= id[ATA_ID_UDMA_MODES];
254 253
255 /* 254 /*
256 * avoid false cable warning from eighty_ninty_three() 255 * avoid false cable warning from eighty_ninty_three()
@@ -261,18 +260,15 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
261 } 260 }
262 break; 261 break;
263 case XFER_MW_DMA_0: 262 case XFER_MW_DMA_0:
264 if ((id[ATA_ID_FIELD_VALID] & 2) == 0) 263 mask = id[ATA_ID_MWDMA_MODES];
265 break;
266 if (port_ops && port_ops->mdma_filter) 264 if (port_ops && port_ops->mdma_filter)
267 mask = port_ops->mdma_filter(drive); 265 mask &= port_ops->mdma_filter(drive);
268 else 266 else
269 mask = hwif->mwdma_mask; 267 mask &= hwif->mwdma_mask;
270 mask &= id[ATA_ID_MWDMA_MODES];
271 break; 268 break;
272 case XFER_SW_DMA_0: 269 case XFER_SW_DMA_0:
273 if (id[ATA_ID_FIELD_VALID] & 2) { 270 mask = id[ATA_ID_SWDMA_MODES];
274 mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask; 271 if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) {
275 } else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
276 u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8; 272 u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
277 273
278 /* 274 /*
@@ -280,8 +276,9 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
280 * (the maximum allowed mode is XFER_SW_DMA_2) 276 * (the maximum allowed mode is XFER_SW_DMA_2)
281 */ 277 */
282 if (mode <= 2) 278 if (mode <= 2)
283 mask = ((2 << mode) - 1) & hwif->swdma_mask; 279 mask = (2 << mode) - 1;
284 } 280 }
281 mask &= hwif->swdma_mask;
285 break; 282 break;
286 default: 283 default:
287 BUG(); 284 BUG();
@@ -398,11 +395,10 @@ int ide_id_dma_bug(ide_drive_t *drive)
398 if ((id[ATA_ID_UDMA_MODES] >> 8) && 395 if ((id[ATA_ID_UDMA_MODES] >> 8) &&
399 (id[ATA_ID_MWDMA_MODES] >> 8)) 396 (id[ATA_ID_MWDMA_MODES] >> 8))
400 goto err_out; 397 goto err_out;
401 } else if (id[ATA_ID_FIELD_VALID] & 2) { 398 } else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
402 if ((id[ATA_ID_MWDMA_MODES] >> 8) && 399 (id[ATA_ID_SWDMA_MODES] >> 8))
403 (id[ATA_ID_SWDMA_MODES] >> 8)) 400 goto err_out;
404 goto err_out; 401
405 }
406 return 0; 402 return 0;
407err_out: 403err_out:
408 printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name); 404 printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index 13e3988f00f0..d467478d68da 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -115,8 +115,7 @@ static u8 sc1200_udma_filter(ide_drive_t *drive)
115 if ((mateid[ATA_ID_FIELD_VALID] & 4) && 115 if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
116 (mateid[ATA_ID_UDMA_MODES] & 7)) 116 (mateid[ATA_ID_UDMA_MODES] & 7))
117 goto out; 117 goto out;
118 if ((mateid[ATA_ID_FIELD_VALID] & 2) && 118 if (mateid[ATA_ID_MWDMA_MODES] & 7)
119 (mateid[ATA_ID_MWDMA_MODES] & 7))
120 mask = 0; 119 mask = 0;
121 } 120 }
122out: 121out: