Commit 1fd4bbec authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz Committed by Jeff Garzik

pata_atiixp: fix second channel support

PIO and MWDMA timings are never programmed for the second channel
because timing registers are treated as 16-bit long ones.

The bug is an attixp -> pata_atiixp regression and goes back to:

	commit 669a5db4
	Author: Jeff Garzik <jeff@garzik.org>
	Date:   Tue Aug 29 18:12:40 2006 -0400

	    [libata] Add a bunch of PATA drivers.

Cc: Krystian Juskowiak <jusko@tlen.pl>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Borislav Petkov <bbpetkov@yahoo.de>
Cc: Robert Hancock <hancockrwd@gmail.com>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent df9eba8c
/* /*
* pata_atiixp.c - ATI PATA for new ATA layer * pata_atiixp.c - ATI PATA for new ATA layer
* (C) 2005 Red Hat Inc * (C) 2005 Red Hat Inc
* (C) 2009 Bartlomiej Zolnierkiewicz
* *
* Based on * Based on
* *
...@@ -61,20 +62,19 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, ...@@ -61,20 +62,19 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev,
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dn = 2 * ap->port_no + adev->devno; int dn = 2 * ap->port_no + adev->devno;
/* Check this is correct - the order is odd in both drivers */
int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1); int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
u16 pio_mode_data, pio_timing_data; u32 pio_timing_data;
u16 pio_mode_data;
pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data); pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
pio_mode_data &= ~(0x7 << (4 * dn)); pio_mode_data &= ~(0x7 << (4 * dn));
pio_mode_data |= pio << (4 * dn); pio_mode_data |= pio << (4 * dn);
pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data); pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data); pci_read_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
pio_timing_data &= ~(0xFF << timing_shift); pio_timing_data &= ~(0xFF << timing_shift);
pio_timing_data |= (pio_timings[pio] << timing_shift); pio_timing_data |= (pio_timings[pio] << timing_shift);
pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); pci_write_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
} }
/** /**
...@@ -119,16 +119,17 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) ...@@ -119,16 +119,17 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
udma_mode_data |= dma << (4 * dn); udma_mode_data |= dma << (4 * dn);
pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data); pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data);
} else { } else {
u16 mwdma_timing_data;
/* Check this is correct - the order is odd in both drivers */
int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1); int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
u32 mwdma_timing_data;
dma -= XFER_MW_DMA_0; dma -= XFER_MW_DMA_0;
pci_read_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, &mwdma_timing_data); pci_read_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
&mwdma_timing_data);
mwdma_timing_data &= ~(0xFF << timing_shift); mwdma_timing_data &= ~(0xFF << timing_shift);
mwdma_timing_data |= (mwdma_timings[dma] << timing_shift); mwdma_timing_data |= (mwdma_timings[dma] << timing_shift);
pci_write_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, mwdma_timing_data); pci_write_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
mwdma_timing_data);
} }
/* /*
* We must now look at the PIO mode situation. We may need to * We must now look at the PIO mode situation. We may need to
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment