aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-08-10 16:59:49 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-12 14:55:33 -0400
commit05d1efffdc9bf84311bb1a3c2e3db55b544ca119 (patch)
tree2529697f40bcc35c8f943ce8059db1967f3021ba /drivers/ata
parent4f34337b1f6f7c1e0f2e3c938eb9eadd340593fe (diff)
pata_cmd64x: Set up MWDMA modes properly
Set the MWDMA timing by updating the correct registers. Split the PIO path as this is mostly shared code. Wants testing. Signed-off-by: Alan Cox <alan@redhat.com> Tested-by: Mikael Pettersson <mikpe@it.uu.se> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/pata_cmd64x.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index e34b632487d7..922902a1b4ae 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -31,7 +31,7 @@
31#include <linux/libata.h> 31#include <linux/libata.h>
32 32
33#define DRV_NAME "pata_cmd64x" 33#define DRV_NAME "pata_cmd64x"
34#define DRV_VERSION "0.2.4" 34#define DRV_VERSION "0.2.5"
35 35
36/* 36/*
37 * CMD64x specific registers definition. 37 * CMD64x specific registers definition.
@@ -88,14 +88,15 @@ static int cmd648_cable_detect(struct ata_port *ap)
88} 88}
89 89
90/** 90/**
91 * cmd64x_set_piomode - set initial PIO mode data 91 * cmd64x_set_piomode - set PIO and MWDMA timing
92 * @ap: ATA interface 92 * @ap: ATA interface
93 * @adev: ATA device 93 * @adev: ATA device
94 * @mode: mode
94 * 95 *
95 * Called to do the PIO mode setup. 96 * Called to do the PIO and MWDMA mode setup.
96 */ 97 */
97 98
98static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) 99static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 mode)
99{ 100{
100 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 101 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
101 struct ata_timing t; 102 struct ata_timing t;
@@ -117,8 +118,9 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
117 int arttim = arttim_port[ap->port_no][adev->devno]; 118 int arttim = arttim_port[ap->port_no][adev->devno];
118 int drwtim = drwtim_port[ap->port_no][adev->devno]; 119 int drwtim = drwtim_port[ap->port_no][adev->devno];
119 120
120 121 /* ata_timing_compute is smart and will produce timings for MWDMA
121 if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) { 122 that don't violate the drives PIO capabilities. */
123 if (ata_timing_compute(adev, mode, &t, T, 0) < 0) {
122 printk(KERN_ERR DRV_NAME ": mode computation failed.\n"); 124 printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
123 return; 125 return;
124 } 126 }
@@ -168,6 +170,20 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
168} 170}
169 171
170/** 172/**
173 * cmd64x_set_piomode - set initial PIO mode data
174 * @ap: ATA interface
175 * @adev: ATA device
176 *
177 * Used when configuring the devices ot set the PIO timings. All the
178 * actual work is done by the PIO/MWDMA setting helper
179 */
180
181static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
182{
183 cmd64x_set_timing(ap, adev, adev->pio_mode);
184}
185
186/**
171 * cmd64x_set_dmamode - set initial DMA mode data 187 * cmd64x_set_dmamode - set initial DMA mode data
172 * @ap: ATA interface 188 * @ap: ATA interface
173 * @adev: ATA device 189 * @adev: ATA device
@@ -180,9 +196,6 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
180 static const u8 udma_data[] = { 196 static const u8 udma_data[] = {
181 0x30, 0x20, 0x10, 0x20, 0x10, 0x00 197 0x30, 0x20, 0x10, 0x20, 0x10, 0x00
182 }; 198 };
183 static const u8 mwdma_data[] = {
184 0x30, 0x20, 0x10
185 };
186 199
187 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 200 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
188 u8 regU, regD; 201 u8 regU, regD;
@@ -208,8 +221,10 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
208 regU |= 1 << adev->devno; /* UDMA on */ 221 regU |= 1 << adev->devno; /* UDMA on */
209 if (adev->dma_mode > 2) /* 15nS timing */ 222 if (adev->dma_mode > 2) /* 15nS timing */
210 regU |= 4 << adev->devno; 223 regU |= 4 << adev->devno;
211 } else 224 } else {
212 regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; 225 regU &= ~ (1 << adev->devno); /* UDMA off */
226 cmd64x_set_timing(ap, adev, adev->dma_mode);
227 }
213 228
214 regD |= 0x20 << adev->devno; 229 regD |= 0x20 << adev->devno;
215 230