Commit 8d64fcd9357798ad0d61f8877de13d5e1b1ab510

Authored by Sergei Shtylyov
Committed by Bartlomiej Zolnierkiewicz
1 parent 985232e388

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>

Showing 4 changed files with 19 additions and 26 deletions Side-by-side Diff

drivers/ide/cs5530.c
... ... @@ -92,8 +92,7 @@
92 92 if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
93 93 (mateid[ATA_ID_UDMA_MODES] & 7))
94 94 goto out;
95   - if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
96   - (mateid[ATA_ID_MWDMA_MODES] & 7))
  95 + if (mateid[ATA_ID_MWDMA_MODES] & 7)
97 96 mask = 0;
98 97 }
99 98 out:
drivers/ide/ide-dma-sff.c
... ... @@ -38,10 +38,9 @@
38 38 * Enable DMA on any drive that has mode2 DMA
39 39 * (multi or single) enabled
40 40 */
41   - if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */
42   - if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
43   - (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
44   - return 1;
  41 + if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
  42 + (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
  43 + return 1;
45 44  
46 45 /* Consult the list of known "good" drives */
47 46 if (ide_dma_good_drive(drive))
drivers/ide/ide-dma.c
... ... @@ -245,12 +245,11 @@
245 245 case XFER_UDMA_0:
246 246 if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
247 247 break;
248   -
  248 + mask = id[ATA_ID_UDMA_MODES];
249 249 if (port_ops && port_ops->udma_filter)
250   - mask = port_ops->udma_filter(drive);
  250 + mask &= port_ops->udma_filter(drive);
251 251 else
252   - mask = hwif->ultra_mask;
253   - mask &= id[ATA_ID_UDMA_MODES];
  252 + mask &= hwif->ultra_mask;
254 253  
255 254 /*
256 255 * avoid false cable warning from eighty_ninty_three()
257 256  
258 257  
259 258  
... ... @@ -261,18 +260,15 @@
261 260 }
262 261 break;
263 262 case XFER_MW_DMA_0:
264   - if ((id[ATA_ID_FIELD_VALID] & 2) == 0)
265   - break;
  263 + mask = id[ATA_ID_MWDMA_MODES];
266 264 if (port_ops && port_ops->mdma_filter)
267   - mask = port_ops->mdma_filter(drive);
  265 + mask &= port_ops->mdma_filter(drive);
268 266 else
269   - mask = hwif->mwdma_mask;
270   - mask &= id[ATA_ID_MWDMA_MODES];
  267 + mask &= hwif->mwdma_mask;
271 268 break;
272 269 case XFER_SW_DMA_0:
273   - if (id[ATA_ID_FIELD_VALID] & 2) {
274   - mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask;
275   - } else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
  270 + mask = id[ATA_ID_SWDMA_MODES];
  271 + if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) {
276 272 u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
277 273  
278 274 /*
279 275  
... ... @@ -280,8 +276,9 @@
280 276 * (the maximum allowed mode is XFER_SW_DMA_2)
281 277 */
282 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 282 break;
286 283 default:
287 284 BUG();
... ... @@ -398,11 +395,10 @@
398 395 if ((id[ATA_ID_UDMA_MODES] >> 8) &&
399 396 (id[ATA_ID_MWDMA_MODES] >> 8))
400 397 goto err_out;
401   - } else if (id[ATA_ID_FIELD_VALID] & 2) {
402   - if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
403   - (id[ATA_ID_SWDMA_MODES] >> 8))
404   - goto err_out;
405   - }
  398 + } else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
  399 + (id[ATA_ID_SWDMA_MODES] >> 8))
  400 + goto err_out;
  401 +
406 402 return 0;
407 403 err_out:
408 404 printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
drivers/ide/sc1200.c
... ... @@ -115,8 +115,7 @@
115 115 if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
116 116 (mateid[ATA_ID_UDMA_MODES] & 7))
117 117 goto out;
118   - if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
119   - (mateid[ATA_ID_MWDMA_MODES] & 7))
  118 + if (mateid[ATA_ID_MWDMA_MODES] & 7)
120 119 mask = 0;
121 120 }
122 121 out: