Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ata_piix: unify code for programming PIO and MWDMA timings

Besides making things noticably simpler it results in ~2% decrease in
the driver LOC count and also ~2% decrease in the driver binary size
(as measured on x86-32).

Fix piix_set_piomode() documentation while at it.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

authored by

Bartlomiej Zolnierkiewicz and committed by
Jeff Garzik
6a94a746 ce986690

+38 -73
+38 -73
drivers/ata/ata_piix.c
··· 731 731 732 732 static DEFINE_SPINLOCK(piix_lock); 733 733 734 - /** 735 - * piix_set_piomode - Initialize host controller PATA PIO timings 736 - * @ap: Port whose timings we are configuring 737 - * @adev: um 738 - * 739 - * Set PIO mode for device, in host controller PCI config space. 740 - * 741 - * LOCKING: 742 - * None (inherited from caller). 743 - */ 744 - 745 - static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) 734 + static void piix_set_timings(struct ata_port *ap, struct ata_device *adev, 735 + u8 pio) 746 736 { 747 737 struct pci_dev *dev = to_pci_dev(ap->host->dev); 748 738 unsigned long flags; 749 - unsigned int pio = adev->pio_mode - XFER_PIO_0; 750 739 unsigned int is_slave = (adev->devno != 0); 751 740 unsigned int master_port= ap->port_no ? 0x42 : 0x40; 752 741 unsigned int slave_port = 0x44; ··· 760 771 control |= 1; /* TIME1 enable */ 761 772 if (ata_pio_need_iordy(adev)) 762 773 control |= 2; /* IE enable */ 763 - 764 774 /* Intel specifies that the PPE functionality is for disk only */ 765 775 if (adev->class == ATA_DEV_ATA) 766 776 control |= 4; /* PPE enable */ 777 + /* 778 + * If the drive MWDMA is faster than it can do PIO then 779 + * we must force PIO into PIO0 780 + */ 781 + if (adev->pio_mode < XFER_PIO_0 + pio) 782 + /* Enable DMA timing only */ 783 + control |= 8; /* PIO cycles in PIO0 */ 767 784 768 785 spin_lock_irqsave(&piix_lock, flags); 769 786 ··· 818 823 } 819 824 820 825 /** 826 + * piix_set_piomode - Initialize host controller PATA PIO timings 827 + * @ap: Port whose timings we are configuring 828 + * @adev: Drive in question 829 + * 830 + * Set PIO mode for device, in host controller PCI config space. 831 + * 832 + * LOCKING: 833 + * None (inherited from caller). 834 + */ 835 + 836 + static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) 837 + { 838 + piix_set_timings(ap, adev, adev->pio_mode - XFER_PIO_0); 839 + } 840 + 841 + /** 821 842 * do_pata_set_dmamode - Initialize host controller PATA PIO timings 822 843 * @ap: Port whose timings we are configuring 823 844 * @adev: Drive in question ··· 849 838 { 850 839 struct pci_dev *dev = to_pci_dev(ap->host->dev); 851 840 unsigned long flags; 852 - u8 master_port = ap->port_no ? 0x42 : 0x40; 853 - u16 master_data; 854 841 u8 speed = adev->dma_mode; 855 842 int devid = adev->devno + 2 * ap->port_no; 856 843 u8 udma_enable = 0; 857 844 858 - static const /* ISP RTC */ 859 - u8 timings[][2] = { { 0, 0 }, 860 - { 0, 0 }, 861 - { 1, 0 }, 862 - { 2, 1 }, 863 - { 2, 3 }, }; 864 - 865 - spin_lock_irqsave(&piix_lock, flags); 866 - 867 - pci_read_config_word(dev, master_port, &master_data); 868 - if (ap->udma_mask) 869 - pci_read_config_byte(dev, 0x48, &udma_enable); 870 - 871 845 if (speed >= XFER_UDMA_0) { 872 - unsigned int udma = adev->dma_mode - XFER_UDMA_0; 846 + unsigned int udma = speed - XFER_UDMA_0; 873 847 u16 udma_timing; 874 848 u16 ideconf; 875 849 int u_clock, u_speed; 850 + 851 + spin_lock_irqsave(&piix_lock, flags); 852 + 853 + pci_read_config_byte(dev, 0x48, &udma_enable); 876 854 877 855 /* 878 856 * UDMA is handled by a combination of clock switching and ··· 895 895 performance (WR_PingPong_En) */ 896 896 pci_write_config_word(dev, 0x54, ideconf); 897 897 } 898 + 899 + pci_write_config_byte(dev, 0x48, udma_enable); 900 + 901 + spin_unlock_irqrestore(&piix_lock, flags); 898 902 } else { 899 - /* 900 - * MWDMA is driven by the PIO timings. We must also enable 901 - * IORDY unconditionally along with TIME1. PPE has already 902 - * been set when the PIO timing was set. 903 - */ 904 - unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0; 905 - unsigned int control; 906 - u8 slave_data; 903 + /* MWDMA is driven by the PIO timings. */ 904 + unsigned int mwdma = speed - XFER_MW_DMA_0; 907 905 const unsigned int needed_pio[3] = { 908 906 XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 909 907 }; 910 908 int pio = needed_pio[mwdma] - XFER_PIO_0; 911 909 912 - control = 3; /* IORDY|TIME1 */ 913 - 914 - /* If the drive MWDMA is faster than it can do PIO then 915 - we must force PIO into PIO0 */ 916 - 917 - if (adev->pio_mode < needed_pio[mwdma]) 918 - /* Enable DMA timing only */ 919 - control |= 8; /* PIO cycles in PIO0 */ 920 - 921 - if (adev->devno) { /* Slave */ 922 - master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ 923 - master_data |= control << 4; 924 - pci_read_config_byte(dev, 0x44, &slave_data); 925 - slave_data &= (ap->port_no ? 0x0f : 0xf0); 926 - /* Load the matching timing */ 927 - slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); 928 - pci_write_config_byte(dev, 0x44, slave_data); 929 - } else { /* Master */ 930 - master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY 931 - and master timing bits */ 932 - master_data |= control; 933 - master_data |= 934 - (timings[pio][0] << 12) | 935 - (timings[pio][1] << 8); 936 - } 937 - 938 - if (ap->udma_mask) 939 - udma_enable &= ~(1 << devid); 940 - 941 - pci_write_config_word(dev, master_port, master_data); 910 + /* XFER_PIO_0 is never used currently */ 911 + piix_set_timings(ap, adev, pio); 942 912 } 943 - /* Don't scribble on 0x48 if the controller does not support UDMA */ 944 - if (ap->udma_mask) 945 - pci_write_config_byte(dev, 0x48, udma_enable); 946 - 947 - spin_unlock_irqrestore(&piix_lock, flags); 948 913 } 949 914 950 915 /**