diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-03-31 14:15:27 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-03-31 14:15:27 -0400 |
commit | 8d64fcd9357798ad0d61f8877de13d5e1b1ab510 (patch) | |
tree | 7e0737ef385b80faf9fa3f5d0c1df1f22254d0d8 /drivers | |
parent | 985232e388714d4a9e94b4d96ee69b6ff8c9dc31 (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')
-rw-r--r-- | drivers/ide/cs5530.c | 3 | ||||
-rw-r--r-- | drivers/ide/ide-dma-sff.c | 7 | ||||
-rw-r--r-- | drivers/ide/ide-dma.c | 32 | ||||
-rw-r--r-- | drivers/ide/sc1200.c | 3 |
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 | } |
99 | out: | 98 | out: |
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; |
407 | err_out: | 403 | err_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 | } |
122 | out: | 121 | out: |