diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2009-12-07 14:30:06 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-03-01 14:58:43 -0500 |
commit | 1a1b172b9672e88d37adb5925b509e9236625d7e (patch) | |
tree | 9ccb1bb12343ed4ab5799d9ab08bd67f5b75bfba /drivers/ata/pata_hpt3x2n.c | |
parent | 60661933995bc7a09686c901439e17c2a4ea7d5d (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.c | 69 |
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 | ||
30 | enum { | 30 | enum { |
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 | /** | 164 | static 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 | |||
172 | static 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, ®); | 190 | pci_read_config_dword(pdev, addr1, ®); |
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 | |||
203 | static 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 | ||
204 | static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) | 216 | static 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, ®); | ||
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 | /** |