Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44854add authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Linus Torvalds
Browse files

[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: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Acked-by: default avatarBartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 242ce41f
Loading
Loading
Loading
Loading
+16 −17
Original line number Original line Diff line number Diff line
/*
/*
 *  linux/drivers/ide/pci/piix.c	Version 0.44	March 20, 2003
 *  linux/drivers/ide/pci/piix.c	Version 0.45	May 12, 2006
 *
 *
 *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
 *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
 *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
 *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
 *  Copyright (C) 2003 Red Hat Inc <alan@redhat.com>
 *  Copyright (C) 2003 Red Hat Inc <alan@redhat.com>
 *  Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com>
 *
 *
 *  May be copied or modified under the terms of the GNU General Public License
 *  May be copied or modified under the terms of the GNU General Public License
 *
 *
@@ -365,13 +366,12 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
{
{
	u8 speed = ide_dma_speed(drive, piix_ratemask(drive));
	u8 speed = ide_dma_speed(drive, piix_ratemask(drive));


	/* If no DMA speed was available or the chipset has DMA bugs
	/*
	   then disable DMA and use PIO */
	 * If no DMA speed was available or the chipset has DMA bugs
	   
	 * then disable DMA and use PIO
	if (!speed || no_piix_dma) {
	 */
		u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
	if (!speed || no_piix_dma)
		speed = piix_dma_2_pio(XFER_PIO_0 + tspeed);
		return 0;
	}


	(void) piix_tune_chipset(drive, speed);
	(void) piix_tune_chipset(drive, speed);
	return ide_dma_enable(drive);
	return ide_dma_enable(drive);
@@ -394,17 +394,16 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive)


	if ((id->capability & 1) && drive->autodma) {
	if ((id->capability & 1) && drive->autodma) {


		if (ide_use_dma(drive)) {
		if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
			if (piix_config_drive_for_dma(drive))
			return hwif->ide_dma_on(drive);
			return hwif->ide_dma_on(drive);
		}


		goto fast_ata_pio;
		goto fast_ata_pio;


	} else if ((id->capability & 8) || (id->field_valid & 2)) {
	} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
fast_ata_pio:
		/* Find best PIO mode. */
		/* Find best PIO mode. */
		hwif->tuneproc(drive, 255);
		(void) hwif->speedproc(drive, XFER_PIO_0 +
				       ide_get_best_pio_mode(drive, 255, 4, NULL));
		return hwif->ide_dma_off_quietly(drive);
		return hwif->ide_dma_off_quietly(drive);
	}
	}
	/* IORDY not supported */
	/* IORDY not supported */
+9 −11
Original line number Original line Diff line number Diff line
/*
/*
 *  linux/drivers/ide/pci/slc90e66.c	Version 0.11	September 11, 2002
 *  linux/drivers/ide/pci/slc90e66.c	Version 0.12	May 12, 2006
 *
 *
 *  Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
 *  Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
 *  Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com>
 *
 *
 * This a look-a-like variation of the ICH0 PIIX4 Ultra-66,
 * This is a look-alike variation of the ICH0 PIIX4 Ultra-66,
 * but this keeps the ISA-Bridge and slots alive.
 * but this keeps the ISA-Bridge and slots alive.
 *
 *
 */
 */
@@ -158,10 +159,8 @@ static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
{
{
	u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive));
	u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive));


	if (!(speed)) {
	if (!speed)
		u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
		return 0;
		speed = slc90e66_dma_2_pio(XFER_PIO_0 + tspeed);
	}


	(void) slc90e66_tune_chipset(drive, speed);
	(void) slc90e66_tune_chipset(drive, speed);
	return ide_dma_enable(drive);
	return ide_dma_enable(drive);
@@ -176,16 +175,15 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)


	if (id && (id->capability & 1) && drive->autodma) {
	if (id && (id->capability & 1) && drive->autodma) {


		if (ide_use_dma(drive)) {
		if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
			if (slc90e66_config_drive_for_dma(drive))
			return hwif->ide_dma_on(drive);
			return hwif->ide_dma_on(drive);
		}


		goto fast_ata_pio;
		goto fast_ata_pio;


	} else if ((id->capability & 8) || (id->field_valid & 2)) {
	} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
fast_ata_pio:
		hwif->tuneproc(drive, 5);
		(void) hwif->speedproc(drive, XFER_PIO_0 +
				       ide_get_best_pio_mode(drive, 255, 4, NULL));
		return hwif->ide_dma_off_quietly(drive);
		return hwif->ide_dma_off_quietly(drive);
	}
	}
	/* IORDY not supported */
	/* IORDY not supported */