diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2006-12-29 19:49:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-30 13:56:43 -0500 |
commit | 44854add66811124a5667466245b6824f751143a (patch) | |
tree | 5413f8e9974860dee9831a0731d739376cef0045 | |
parent | 242ce41fc92214c3430495edd43783c3ba3dcd2b (diff) |
[PATCH] PIIX/SLC90E66: PIO mode fallback fix
The fallback to PIO mode in the hwif->dma_check() handler doesn't work in
the Intel PIIX and SMsC SLC90E66 IDE drivers because:
- config_drive_for_dma() calls the hwif->speedproc() handler with a wrong
mode number (unbiased by XFER_PIO_0) in case of the PIO fallback;
- hwif->tuneproc() handler doesn't really set the drive's own speed (this
is not fixed as yet).
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Acked-by: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/ide/pci/piix.c | 33 | ||||
-rw-r--r-- | drivers/ide/pci/slc90e66.c | 20 |
2 files changed, 25 insertions, 28 deletions
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 8ecd2d668dba..edb37f3d558d 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/piix.c Version 0.44 March 20, 2003 | 2 | * linux/drivers/ide/pci/piix.c Version 0.45 May 12, 2006 |
3 | * | 3 | * |
4 | * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer | 4 | * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer |
5 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | 5 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> |
6 | * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> | 6 | * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> |
7 | * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com> | ||
7 | * | 8 | * |
8 | * May be copied or modified under the terms of the GNU General Public License | 9 | * May be copied or modified under the terms of the GNU General Public License |
9 | * | 10 | * |
10 | * PIO mode setting function for Intel chipsets. | 11 | * PIO mode setting function for Intel chipsets. |
11 | * For use instead of BIOS settings. | 12 | * For use instead of BIOS settings. |
12 | * | 13 | * |
13 | * 40-41 | 14 | * 40-41 |
@@ -25,7 +26,7 @@ | |||
25 | * sitre = word42 & 0x4000; secondary | 26 | * sitre = word42 & 0x4000; secondary |
26 | * | 27 | * |
27 | * 44 8421|8421 hdd|hdb | 28 | * 44 8421|8421 hdd|hdb |
28 | * | 29 | * |
29 | * 48 8421 hdd|hdc|hdb|hda udma enabled | 30 | * 48 8421 hdd|hdc|hdb|hda udma enabled |
30 | * | 31 | * |
31 | * 0001 hda | 32 | * 0001 hda |
@@ -357,21 +358,20 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
357 | * @drive: IDE drive to configure | 358 | * @drive: IDE drive to configure |
358 | * | 359 | * |
359 | * Set up a PIIX interface channel for the best available speed. | 360 | * Set up a PIIX interface channel for the best available speed. |
360 | * We prefer UDMA if it is available and then MWDMA. If DMA is | 361 | * We prefer UDMA if it is available and then MWDMA. If DMA is |
361 | * not available we switch to PIO and return 0. | 362 | * not available we switch to PIO and return 0. |
362 | */ | 363 | */ |
363 | 364 | ||
364 | static int piix_config_drive_for_dma (ide_drive_t *drive) | 365 | static int piix_config_drive_for_dma (ide_drive_t *drive) |
365 | { | 366 | { |
366 | u8 speed = ide_dma_speed(drive, piix_ratemask(drive)); | 367 | u8 speed = ide_dma_speed(drive, piix_ratemask(drive)); |
367 | 368 | ||
368 | /* If no DMA speed was available or the chipset has DMA bugs | 369 | /* |
369 | then disable DMA and use PIO */ | 370 | * If no DMA speed was available or the chipset has DMA bugs |
370 | 371 | * then disable DMA and use PIO | |
371 | if (!speed || no_piix_dma) { | 372 | */ |
372 | u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); | 373 | if (!speed || no_piix_dma) |
373 | speed = piix_dma_2_pio(XFER_PIO_0 + tspeed); | 374 | return 0; |
374 | } | ||
375 | 375 | ||
376 | (void) piix_tune_chipset(drive, speed); | 376 | (void) piix_tune_chipset(drive, speed); |
377 | return ide_dma_enable(drive); | 377 | return ide_dma_enable(drive); |
@@ -394,17 +394,16 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive) | |||
394 | 394 | ||
395 | if ((id->capability & 1) && drive->autodma) { | 395 | if ((id->capability & 1) && drive->autodma) { |
396 | 396 | ||
397 | if (ide_use_dma(drive)) { | 397 | if (ide_use_dma(drive) && piix_config_drive_for_dma(drive)) |
398 | if (piix_config_drive_for_dma(drive)) | 398 | return hwif->ide_dma_on(drive); |
399 | return hwif->ide_dma_on(drive); | ||
400 | } | ||
401 | 399 | ||
402 | goto fast_ata_pio; | 400 | goto fast_ata_pio; |
403 | 401 | ||
404 | } else if ((id->capability & 8) || (id->field_valid & 2)) { | 402 | } else if ((id->capability & 8) || (id->field_valid & 2)) { |
405 | fast_ata_pio: | 403 | fast_ata_pio: |
406 | /* Find best PIO mode. */ | 404 | /* Find best PIO mode. */ |
407 | hwif->tuneproc(drive, 255); | 405 | (void) hwif->speedproc(drive, XFER_PIO_0 + |
406 | ide_get_best_pio_mode(drive, 255, 4, NULL)); | ||
408 | return hwif->ide_dma_off_quietly(drive); | 407 | return hwif->ide_dma_off_quietly(drive); |
409 | } | 408 | } |
410 | /* IORDY not supported */ | 409 | /* IORDY not supported */ |
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 4a1853af3bbb..9be7e49cba0e 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/slc90e66.c Version 0.11 September 11, 2002 | 2 | * linux/drivers/ide/pci/slc90e66.c Version 0.12 May 12, 2006 |
3 | * | 3 | * |
4 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> |
5 | * Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com> | ||
5 | * | 6 | * |
6 | * This a look-a-like variation of the ICH0 PIIX4 Ultra-66, | 7 | * This is a look-alike variation of the ICH0 PIIX4 Ultra-66, |
7 | * but this keeps the ISA-Bridge and slots alive. | 8 | * but this keeps the ISA-Bridge and slots alive. |
8 | * | 9 | * |
9 | */ | 10 | */ |
@@ -158,10 +159,8 @@ static int slc90e66_config_drive_for_dma (ide_drive_t *drive) | |||
158 | { | 159 | { |
159 | u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); | 160 | u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); |
160 | 161 | ||
161 | if (!(speed)) { | 162 | if (!speed) |
162 | u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); | 163 | return 0; |
163 | speed = slc90e66_dma_2_pio(XFER_PIO_0 + tspeed); | ||
164 | } | ||
165 | 164 | ||
166 | (void) slc90e66_tune_chipset(drive, speed); | 165 | (void) slc90e66_tune_chipset(drive, speed); |
167 | return ide_dma_enable(drive); | 166 | return ide_dma_enable(drive); |
@@ -176,16 +175,15 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) | |||
176 | 175 | ||
177 | if (id && (id->capability & 1) && drive->autodma) { | 176 | if (id && (id->capability & 1) && drive->autodma) { |
178 | 177 | ||
179 | if (ide_use_dma(drive)) { | 178 | if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) |
180 | if (slc90e66_config_drive_for_dma(drive)) | 179 | return hwif->ide_dma_on(drive); |
181 | return hwif->ide_dma_on(drive); | ||
182 | } | ||
183 | 180 | ||
184 | goto fast_ata_pio; | 181 | goto fast_ata_pio; |
185 | 182 | ||
186 | } else if ((id->capability & 8) || (id->field_valid & 2)) { | 183 | } else if ((id->capability & 8) || (id->field_valid & 2)) { |
187 | fast_ata_pio: | 184 | fast_ata_pio: |
188 | hwif->tuneproc(drive, 5); | 185 | (void) hwif->speedproc(drive, XFER_PIO_0 + |
186 | ide_get_best_pio_mode(drive, 255, 4, NULL)); | ||
189 | return hwif->ide_dma_off_quietly(drive); | 187 | return hwif->ide_dma_off_quietly(drive); |
190 | } | 188 | } |
191 | /* IORDY not supported */ | 189 | /* IORDY not supported */ |