diff options
Diffstat (limited to 'drivers/ata/pata_hpt3x2n.c')
-rw-r--r-- | drivers/ata/pata_hpt3x2n.c | 120 |
1 files changed, 56 insertions, 64 deletions
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index dd26bc73bd9a..01457b266f3d 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.8" | 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), |
@@ -45,25 +45,24 @@ struct hpt_chip { | |||
45 | 45 | ||
46 | /* key for bus clock timings | 46 | /* key for bus clock timings |
47 | * bit | 47 | * bit |
48 | * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW | 48 | * 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA. |
49 | * DMA. cycles = value + 1 | 49 | * cycles = value + 1 |
50 | * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW | 50 | * 4:8 data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA. |
51 | * DMA. cycles = value + 1 | 51 | * cycles = value + 1 |
52 | * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file | 52 | * 9:12 cmd_high_time. Inactive time of DIOW_/DIOR_ during task file |
53 | * register access. | 53 | * register access. |
54 | * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file | 54 | * 13:17 cmd_low_time. Active time of DIOW_/DIOR_ during task file |
55 | * register access. | 55 | * register access. |
56 | * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. | 56 | * 18:20 udma_cycle_time. Clock cycles for UDMA xfer. |
57 | * during task file register access. | 57 | * 21 CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock. |
58 | * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA | 58 | * 22:24 pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer. |
59 | * xfer. | 59 | * 25:27 cmd_pre_high_time. Time to initialize 1st PIO cycle for task file |
60 | * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task | ||
61 | * register access. | 60 | * register access. |
62 | * 28 UDMA enable | 61 | * 28 UDMA enable. |
63 | * 29 DMA enable | 62 | * 29 DMA enable. |
64 | * 30 PIO_MST enable. if set, the chip is in bus master mode during | 63 | * 30 PIO_MST enable. If set, the chip is in bus master mode during |
65 | * PIO. | 64 | * PIO xfer. |
66 | * 31 FIFO enable. | 65 | * 31 FIFO enable. Only for PIO. |
67 | */ | 66 | */ |
68 | 67 | ||
69 | /* 66MHz DPLL clocks */ | 68 | /* 66MHz DPLL clocks */ |
@@ -161,20 +160,12 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) | |||
161 | return ata_sff_prereset(link, deadline); | 160 | return ata_sff_prereset(link, deadline); |
162 | } | 161 | } |
163 | 162 | ||
164 | /** | 163 | static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev, |
165 | * hpt3x2n_set_piomode - PIO setup | 164 | 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 | { | 165 | { |
174 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 166 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
175 | u32 addr1, addr2; | 167 | u32 addr1, addr2; |
176 | u32 reg; | 168 | u32 reg, timing, mask; |
177 | u32 mode; | ||
178 | u8 fast; | 169 | u8 fast; |
179 | 170 | ||
180 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); | 171 | addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); |
@@ -185,11 +176,32 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
185 | fast &= ~0x07; | 176 | fast &= ~0x07; |
186 | pci_write_config_byte(pdev, addr2, fast); | 177 | pci_write_config_byte(pdev, addr2, fast); |
187 | 178 | ||
179 | /* Determine timing mask and find matching mode entry */ | ||
180 | if (mode < XFER_MW_DMA_0) | ||
181 | mask = 0xcfc3ffff; | ||
182 | else if (mode < XFER_UDMA_0) | ||
183 | mask = 0x31c001ff; | ||
184 | else | ||
185 | mask = 0x303c0000; | ||
186 | |||
187 | timing = hpt3x2n_find_mode(ap, mode); | ||
188 | |||
188 | pci_read_config_dword(pdev, addr1, ®); | 189 | pci_read_config_dword(pdev, addr1, ®); |
189 | mode = hpt3x2n_find_mode(ap, adev->pio_mode); | 190 | reg = (reg & ~mask) | (timing & mask); |
190 | mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ | 191 | pci_write_config_dword(pdev, addr1, reg); |
191 | reg &= ~0xCFC3FFFF; /* Strip timing bits */ | 192 | } |
192 | pci_write_config_dword(pdev, addr1, reg | mode); | 193 | |
194 | /** | ||
195 | * hpt3x2n_set_piomode - PIO setup | ||
196 | * @ap: ATA interface | ||
197 | * @adev: device on the interface | ||
198 | * | ||
199 | * Perform PIO mode setup. | ||
200 | */ | ||
201 | |||
202 | static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
203 | { | ||
204 | hpt3x2n_set_mode(ap, adev, adev->pio_mode); | ||
193 | } | 205 | } |
194 | 206 | ||
195 | /** | 207 | /** |
@@ -197,32 +209,12 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
197 | * @ap: ATA interface | 209 | * @ap: ATA interface |
198 | * @adev: Device being configured | 210 | * @adev: Device being configured |
199 | * | 211 | * |
200 | * Set up the channel for MWDMA or UDMA modes. Much the same as with | 212 | * Set up the channel for MWDMA or UDMA modes. |
201 | * PIO, load the mode number and then set MWDMA or UDMA flag. | ||
202 | */ | 213 | */ |
203 | 214 | ||
204 | static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) | 215 | static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) |
205 | { | 216 | { |
206 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 217 | 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 | } | 218 | } |
227 | 219 | ||
228 | /** | 220 | /** |
@@ -544,19 +536,19 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
544 | pci_mhz); | 536 | pci_mhz); |
545 | /* Set our private data up. We only need a few flags so we use | 537 | /* Set our private data up. We only need a few flags so we use |
546 | it directly */ | 538 | it directly */ |
547 | if (pci_mhz > 60) { | 539 | if (pci_mhz > 60) |
548 | hpriv = (void *)(PCI66 | USE_DPLL); | 540 | hpriv = (void *)(PCI66 | USE_DPLL); |
549 | /* | 541 | |
550 | * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in | 542 | /* |
551 | * the MISC. register to stretch the UltraDMA Tss timing. | 543 | * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in |
552 | * NOTE: This register is only writeable via I/O space. | 544 | * the MISC. register to stretch the UltraDMA Tss timing. |
553 | */ | 545 | * NOTE: This register is only writeable via I/O space. |
554 | if (dev->device == PCI_DEVICE_ID_TTI_HPT371) | 546 | */ |
555 | outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); | 547 | if (dev->device == PCI_DEVICE_ID_TTI_HPT371) |
556 | } | 548 | outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); |
557 | 549 | ||
558 | /* Now kick off ATA set up */ | 550 | /* Now kick off ATA set up */ |
559 | return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv); | 551 | return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0); |
560 | } | 552 | } |
561 | 553 | ||
562 | static const struct pci_device_id hpt3x2n[] = { | 554 | static const struct pci_device_id hpt3x2n[] = { |