diff options
author | Tejun Heo <htejun@gmail.com> | 2007-05-25 13:16:58 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-07-09 12:17:34 -0400 |
commit | a5bf5f5a370ba7c10f5362265e360952145a7da1 (patch) | |
tree | 841c33286cf77a73e909b9764a6ab488c1c9560e /drivers | |
parent | dab632e8c483532bd84e1f3401c72612e39a7c40 (diff) |
ata_piix: fix pio/mwdma programming
Fix various bugs in pio/mwdma mode programming.
* Control bits in the timing register wasn't cleared properly while
programming PIO mode.
* MWDMA mode programming cleared the wrong part of control bits.
* MWDMA mode programming cleared udma_mask even when the controller
doesn't support UDMA.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Art Haas <ahaas@airmail.net>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ata_piix.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 9c07b88631be..924e4474068d 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -685,8 +685,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
685 | if (adev->class == ATA_DEV_ATA) | 685 | if (adev->class == ATA_DEV_ATA) |
686 | control |= 4; /* PPE enable */ | 686 | control |= 4; /* PPE enable */ |
687 | 687 | ||
688 | /* PIO configuration clears DTE unconditionally. It will be | ||
689 | * programmed in set_dmamode which is guaranteed to be called | ||
690 | * after set_piomode if any DMA mode is available. | ||
691 | */ | ||
688 | pci_read_config_word(dev, master_port, &master_data); | 692 | pci_read_config_word(dev, master_port, &master_data); |
689 | if (is_slave) { | 693 | if (is_slave) { |
694 | /* clear TIME1|IE1|PPE1|DTE1 */ | ||
695 | master_data &= 0xff0f; | ||
690 | /* Enable SITRE (seperate slave timing register) */ | 696 | /* Enable SITRE (seperate slave timing register) */ |
691 | master_data |= 0x4000; | 697 | master_data |= 0x4000; |
692 | /* enable PPE1, IE1 and TIME1 as needed */ | 698 | /* enable PPE1, IE1 and TIME1 as needed */ |
@@ -694,12 +700,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
694 | pci_read_config_byte(dev, slave_port, &slave_data); | 700 | pci_read_config_byte(dev, slave_port, &slave_data); |
695 | slave_data &= (ap->port_no ? 0x0f : 0xf0); | 701 | slave_data &= (ap->port_no ? 0x0f : 0xf0); |
696 | /* Load the timing nibble for this slave */ | 702 | /* Load the timing nibble for this slave */ |
697 | slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); | 703 | slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) |
704 | << (ap->port_no ? 4 : 0); | ||
698 | } else { | 705 | } else { |
699 | /* Master keeps the bits in a different format */ | 706 | /* clear ISP|RCT|TIME0|IE0|PPE0|DTE0 */ |
700 | master_data &= 0xccf8; | 707 | master_data &= 0xccf0; |
701 | /* Enable PPE, IE and TIME as appropriate */ | 708 | /* Enable PPE, IE and TIME as appropriate */ |
702 | master_data |= control; | 709 | master_data |= control; |
710 | /* load ISP and RCT */ | ||
703 | master_data |= | 711 | master_data |= |
704 | (timings[pio][0] << 12) | | 712 | (timings[pio][0] << 12) | |
705 | (timings[pio][1] << 8); | 713 | (timings[pio][1] << 8); |
@@ -816,7 +824,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i | |||
816 | master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ | 824 | master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ |
817 | master_data |= control << 4; | 825 | master_data |= control << 4; |
818 | pci_read_config_byte(dev, 0x44, &slave_data); | 826 | pci_read_config_byte(dev, 0x44, &slave_data); |
819 | slave_data &= (0x0F + 0xE1 * ap->port_no); | 827 | slave_data &= (ap->port_no ? 0x0f : 0xf0); |
820 | /* Load the matching timing */ | 828 | /* Load the matching timing */ |
821 | slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); | 829 | slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); |
822 | pci_write_config_byte(dev, 0x44, slave_data); | 830 | pci_write_config_byte(dev, 0x44, slave_data); |
@@ -828,8 +836,11 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i | |||
828 | (timings[pio][0] << 12) | | 836 | (timings[pio][0] << 12) | |
829 | (timings[pio][1] << 8); | 837 | (timings[pio][1] << 8); |
830 | } | 838 | } |
831 | udma_enable &= ~(1 << devid); | 839 | |
832 | pci_write_config_word(dev, master_port, master_data); | 840 | if (ap->udma_mask) { |
841 | udma_enable &= ~(1 << devid); | ||
842 | pci_write_config_word(dev, master_port, master_data); | ||
843 | } | ||
833 | } | 844 | } |
834 | /* Don't scribble on 0x48 if the controller does not support UDMA */ | 845 | /* Don't scribble on 0x48 if the controller does not support UDMA */ |
835 | if (ap->udma_mask) | 846 | if (ap->udma_mask) |