aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_hpt3x2n.c
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2009-12-07 14:30:06 -0500
committerJeff Garzik <jgarzik@redhat.com>2010-03-01 14:58:43 -0500
commit1a1b172b9672e88d37adb5925b509e9236625d7e (patch)
tree9ccb1bb12343ed4ab5799d9ab08bd67f5b75bfba /drivers/ata/pata_hpt3x2n.c
parent60661933995bc7a09686c901439e17c2a4ea7d5d (diff)
pata_hpt{37x|3x2n}: unify mode programming
As these drivers' set_piomode() and set_dmamode() methods are almost identical, factor out the common hpt{37x|3x2n}_set_mode() function to be called by both of them, the same as in 'pata_hpt366' driver. This results in ~5% decrease in the 'pata_hpt37x' driver binary size and in ~4% decrease in the 'pata_hpt3x2n' driver binary size (as measured on x86-32). Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/pata_hpt3x2n.c')
-rw-r--r--drivers/ata/pata_hpt3x2n.c69
1 files changed, 31 insertions, 38 deletions
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 269b5dbe51bb..b131c8f824d7 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -25,7 +25,7 @@
25#include <linux/libata.h> 25#include <linux/libata.h>
26 26
27#define DRV_NAME "pata_hpt3x2n" 27#define DRV_NAME "pata_hpt3x2n"
28#define DRV_VERSION "0.3.9" 28#define DRV_VERSION "0.3.10"
29 29
30enum { 30enum {
31 HPT_PCI_FAST = (1 << 31), 31 HPT_PCI_FAST = (1 << 31),
@@ -161,20 +161,12 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline)
161 return ata_sff_prereset(link, deadline); 161 return ata_sff_prereset(link, deadline);
162} 162}
163 163
164/** 164static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev,
165 * hpt3x2n_set_piomode - PIO setup 165 u8 mode)
166 * @ap: ATA interface
167 * @adev: device on the interface
168 *
169 * Perform PIO mode setup.
170 */
171
172static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev)
173{ 166{
174 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 167 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
175 u32 addr1, addr2; 168 u32 addr1, addr2;
176 u32 reg; 169 u32 reg, timing, mask;
177 u32 mode;
178 u8 fast; 170 u8 fast;
179 171
180 addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); 172 addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
@@ -185,11 +177,32 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev)
185 fast &= ~0x07; 177 fast &= ~0x07;
186 pci_write_config_byte(pdev, addr2, fast); 178 pci_write_config_byte(pdev, addr2, fast);
187 179
180 /* Determine timing mask and find matching mode entry */
181 if (mode < XFER_MW_DMA_0)
182 mask = 0xcfc3ffff;
183 else if (mode < XFER_UDMA_0)
184 mask = 0x31c001ff;
185 else
186 mask = 0x303c0000;
187
188 timing = hpt3x2n_find_mode(ap, mode);
189
188 pci_read_config_dword(pdev, addr1, &reg); 190 pci_read_config_dword(pdev, addr1, &reg);
189 mode = hpt3x2n_find_mode(ap, adev->pio_mode); 191 reg = (reg & ~mask) | (timing & mask);
190 mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ 192 pci_write_config_dword(pdev, addr1, reg);
191 reg &= ~0xCFC3FFFF; /* Strip timing bits */ 193}
192 pci_write_config_dword(pdev, addr1, reg | mode); 194
195/**
196 * hpt3x2n_set_piomode - PIO setup
197 * @ap: ATA interface
198 * @adev: device on the interface
199 *
200 * Perform PIO mode setup.
201 */
202
203static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev)
204{
205 hpt3x2n_set_mode(ap, adev, adev->pio_mode);
193} 206}
194 207
195/** 208/**
@@ -197,32 +210,12 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev)
197 * @ap: ATA interface 210 * @ap: ATA interface
198 * @adev: Device being configured 211 * @adev: Device being configured
199 * 212 *
200 * Set up the channel for MWDMA or UDMA modes. Much the same as with 213 * Set up the channel for MWDMA or UDMA modes.
201 * PIO, load the mode number and then set MWDMA or UDMA flag.
202 */ 214 */
203 215
204static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) 216static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev)
205{ 217{
206 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 218 hpt3x2n_set_mode(ap, adev, adev->dma_mode);
207 u32 addr1, addr2;
208 u32 reg, mode, mask;
209 u8 fast;
210
211 addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
212 addr2 = 0x51 + 4 * ap->port_no;
213
214 /* Fast interrupt prediction disable, hold off interrupt disable */
215 pci_read_config_byte(pdev, addr2, &fast);
216 fast &= ~0x07;
217 pci_write_config_byte(pdev, addr2, fast);
218
219 mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000;
220
221 pci_read_config_dword(pdev, addr1, &reg);
222 mode = hpt3x2n_find_mode(ap, adev->dma_mode);
223 mode &= mask;
224 reg &= ~mask;
225 pci_write_config_dword(pdev, addr1, reg | mode);
226} 219}
227 220
228/** 221/**