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

Commit 7b4f1a13 authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Jeff Garzik
Browse files

(2.6.20) pata_mpiix: fix PIO setup issues



Fix clearing/setting the wrong TIME/IE/PPE bits for a slave drive caused by a
wrong shift count.
Fix the PIO mode 1 being overclocked by wrongly selecting the fast timing bank.
Also, fix/rephrase some comments while at it.

Signed-off-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 409ba47c
Loading
Loading
Loading
Loading
+10 −9
Original line number Original line Diff line number Diff line
@@ -35,7 +35,7 @@
#include <linux/libata.h>
#include <linux/libata.h>


#define DRV_NAME "pata_mpiix"
#define DRV_NAME "pata_mpiix"
#define DRV_VERSION "0.7.3"
#define DRV_VERSION "0.7.4"


enum {
enum {
	IDETIM = 0x6C,		/* IDE control register */
	IDETIM = 0x6C,		/* IDE control register */
@@ -80,8 +80,8 @@ static void mpiix_error_handler(struct ata_port *ap)
 *	@adev: ATA device
 *	@adev: ATA device
 *
 *
 *	Called to do the PIO mode setup. The MPIIX allows us to program the
 *	Called to do the PIO mode setup. The MPIIX allows us to program the
 *	IORDY sample point (2-5 clocks), recovery 1-4 clocks and whether
 *	IORDY sample point (2-5 clocks), recovery (1-4 clocks) and whether
 *	prefetching or iordy are used.
 *	prefetching or IORDY are used.
 *
 *
 *	This would get very ugly because we can only program timing for one
 *	This would get very ugly because we can only program timing for one
 *	device at a time, the other gets PIO0. Fortunately libata calls
 *	device at a time, the other gets PIO0. Fortunately libata calls
@@ -103,18 +103,19 @@ static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
			    { 2, 3 }, };
			    { 2, 3 }, };


	pci_read_config_word(pdev, IDETIM, &idetim);
	pci_read_config_word(pdev, IDETIM, &idetim);
	/* Mask the IORDY/TIME/PPE0 bank for this device */

	/* Mask the IORDY/TIME/PPE for this device */
	if (adev->class == ATA_DEV_ATA)
	if (adev->class == ATA_DEV_ATA)
		control |= PPE;		/* PPE enable for disk */
		control |= PPE;		/* Enable prefetch/posting for disk */
	if (ata_pio_need_iordy(adev))
	if (ata_pio_need_iordy(adev))
		control |= IORDY;	/* IORDY */
		control |= IORDY;
	if (pio > 0)
	if (pio > 1)
		control |= FTIM;	/* This drive is on the fast timing bank */
		control |= FTIM;	/* This drive is on the fast timing bank */


	/* Mask out timing and clear both TIME bank selects */
	/* Mask out timing and clear both TIME bank selects */
	idetim &= 0xCCEE;
	idetim &= 0xCCEE;
	idetim &= ~(0x07  << (2 * adev->devno));
	idetim &= ~(0x07  << (4 * adev->devno));
	idetim |= (control << (2 * adev->devno));
	idetim |= control << (4 * adev->devno);


	idetim |= (timings[pio][0] << 12) | (timings[pio][1] << 8);
	idetim |= (timings[pio][0] << 12) | (timings[pio][1] << 8);
	pci_write_config_word(pdev, IDETIM, idetim);
	pci_write_config_word(pdev, IDETIM, idetim);