aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_via.c
diff options
context:
space:
mode:
authorAlan <alan@lxorguk.ukuu.org.uk>2007-01-08 12:11:13 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-09 17:39:30 -0500
commitd73f30e1c9a9af14757fa5bf4014343926047156 (patch)
treed38dbf9c1fa994cabe0714ca3e2345b39487e0f6 /drivers/ata/sata_via.c
parent7dcbc1f2c89b14745ff13eae3e57b72f05161786 (diff)
sata_via: PATA support
Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_via.c')
-rw-r--r--drivers/ata/sata_via.c108
1 files changed, 102 insertions, 6 deletions
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 038d49d0f2ab..e95acfac30b9 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -59,11 +59,14 @@ enum {
59 SATA_INT_GATE = 0x41, /* SATA interrupt gating */ 59 SATA_INT_GATE = 0x41, /* SATA interrupt gating */
60 SATA_NATIVE_MODE = 0x42, /* Native mode enable */ 60 SATA_NATIVE_MODE = 0x42, /* Native mode enable */
61 SATA_PATA_SHARING = 0x49, /* PATA/SATA sharing func ctrl */ 61 SATA_PATA_SHARING = 0x49, /* PATA/SATA sharing func ctrl */
62 62 PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */
63 PATA_PIO_TIMING = 0xAB, /* PATA timing register */
64
63 PORT0 = (1 << 1), 65 PORT0 = (1 << 1),
64 PORT1 = (1 << 0), 66 PORT1 = (1 << 0),
65 ALL_PORTS = PORT0 | PORT1, 67 ALL_PORTS = PORT0 | PORT1,
66 N_PORTS = 2, 68 PATA_PORT = 2, /* PATA is port 2 */
69 N_PORTS = 3,
67 70
68 NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), 71 NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
69 72
@@ -76,6 +79,11 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
76static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); 79static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
77static void svia_noop_freeze(struct ata_port *ap); 80static void svia_noop_freeze(struct ata_port *ap);
78static void vt6420_error_handler(struct ata_port *ap); 81static void vt6420_error_handler(struct ata_port *ap);
82static void vt6421_sata_error_handler(struct ata_port *ap);
83static void vt6421_pata_error_handler(struct ata_port *ap);
84static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
85static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
86static int vt6421_port_start(struct ata_port *ap);
79 87
80static const struct pci_device_id svia_pci_tbl[] = { 88static const struct pci_device_id svia_pci_tbl[] = {
81 { PCI_VDEVICE(VIA, 0x5337), vt6420 }, 89 { PCI_VDEVICE(VIA, 0x5337), vt6420 },
@@ -142,9 +150,43 @@ static const struct ata_port_operations vt6420_sata_ops = {
142 .host_stop = ata_host_stop, 150 .host_stop = ata_host_stop,
143}; 151};
144 152
145static const struct ata_port_operations vt6421_sata_ops = { 153static const struct ata_port_operations vt6421_pata_ops = {
146 .port_disable = ata_port_disable, 154 .port_disable = ata_port_disable,
155
156 .set_piomode = vt6421_set_pio_mode,
157 .set_dmamode = vt6421_set_dma_mode,
158
159 .tf_load = ata_tf_load,
160 .tf_read = ata_tf_read,
161 .check_status = ata_check_status,
162 .exec_command = ata_exec_command,
163 .dev_select = ata_std_dev_select,
164
165 .bmdma_setup = ata_bmdma_setup,
166 .bmdma_start = ata_bmdma_start,
167 .bmdma_stop = ata_bmdma_stop,
168 .bmdma_status = ata_bmdma_status,
169
170 .qc_prep = ata_qc_prep,
171 .qc_issue = ata_qc_issue_prot,
172 .data_xfer = ata_pio_data_xfer,
173
174 .freeze = ata_bmdma_freeze,
175 .thaw = ata_bmdma_thaw,
176 .error_handler = vt6421_pata_error_handler,
177 .post_internal_cmd = ata_bmdma_post_internal_cmd,
147 178
179 .irq_handler = ata_interrupt,
180 .irq_clear = ata_bmdma_irq_clear,
181
182 .port_start = vt6421_port_start,
183 .port_stop = ata_port_stop,
184 .host_stop = ata_host_stop,
185};
186
187static const struct ata_port_operations vt6421_sata_ops = {
188 .port_disable = ata_port_disable,
189
148 .tf_load = ata_tf_load, 190 .tf_load = ata_tf_load,
149 .tf_read = ata_tf_read, 191 .tf_read = ata_tf_read,
150 .check_status = ata_check_status, 192 .check_status = ata_check_status,
@@ -162,7 +204,7 @@ static const struct ata_port_operations vt6421_sata_ops = {
162 204
163 .freeze = ata_bmdma_freeze, 205 .freeze = ata_bmdma_freeze,
164 .thaw = ata_bmdma_thaw, 206 .thaw = ata_bmdma_thaw,
165 .error_handler = ata_bmdma_error_handler, 207 .error_handler = vt6421_sata_error_handler,
166 .post_internal_cmd = ata_bmdma_post_internal_cmd, 208 .post_internal_cmd = ata_bmdma_post_internal_cmd,
167 209
168 .irq_handler = ata_interrupt, 210 .irq_handler = ata_interrupt,
@@ -171,7 +213,7 @@ static const struct ata_port_operations vt6421_sata_ops = {
171 .scr_read = svia_scr_read, 213 .scr_read = svia_scr_read,
172 .scr_write = svia_scr_write, 214 .scr_write = svia_scr_write,
173 215
174 .port_start = ata_port_start, 216 .port_start = vt6421_port_start,
175 .port_stop = ata_port_stop, 217 .port_stop = ata_port_stop,
176 .host_stop = ata_host_stop, 218 .host_stop = ata_host_stop,
177}; 219};
@@ -289,6 +331,61 @@ static void vt6420_error_handler(struct ata_port *ap)
289 NULL, ata_std_postreset); 331 NULL, ata_std_postreset);
290} 332}
291 333
334static int vt6421_pata_prereset(struct ata_port *ap)
335{
336 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
337 u8 tmp;
338
339 pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp);
340 if (tmp & 0x10)
341 ap->cbl = ATA_CBL_PATA40;
342 else
343 ap->cbl = ATA_CBL_PATA80;
344 return 0;
345}
346
347static void vt6421_pata_error_handler(struct ata_port *ap)
348{
349 return ata_bmdma_drive_eh(ap, vt6421_pata_prereset, ata_std_softreset,
350 NULL, ata_std_postreset);
351}
352
353static int vt6421_sata_prereset(struct ata_port *ap)
354{
355 ap->cbl = ATA_CBL_SATA;
356 return 0;
357}
358
359static void vt6421_sata_error_handler(struct ata_port *ap)
360{
361 return ata_bmdma_drive_eh(ap, vt6421_sata_prereset, ata_std_softreset,
362 NULL, ata_std_postreset);
363}
364
365static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
366{
367 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
368 static const u8 pio_bits[] = { 0xA8, 0x65, 0x65, 0x31, 0x20 };
369 pci_write_config_byte(pdev, PATA_PIO_TIMING, pio_bits[adev->pio_mode - XFER_PIO_0]);
370}
371
372static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
373{
374 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
375 static const u8 udma_bits[] = { 0xEE, 0xE8, 0xE6, 0xE4, 0xE2, 0xE1, 0xE0, 0xE0 };
376 pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->pio_mode - XFER_UDMA_0]);
377}
378
379static int vt6421_port_start(struct ata_port *ap)
380{
381 if (ap->port_no == PATA_PORT) {
382 ap->ops = &vt6421_pata_ops;
383 ap->mwdma_mask = 0;
384 ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST;
385 }
386 return ata_port_start(ap);
387}
388
292static const unsigned int svia_bar_sizes[] = { 389static const unsigned int svia_bar_sizes[] = {
293 8, 4, 8, 4, 16, 256 390 8, 4, 8, 4, 16, 256
294}; 391};
@@ -511,4 +608,3 @@ static void __exit svia_exit(void)
511 608
512module_init(svia_init); 609module_init(svia_init);
513module_exit(svia_exit); 610module_exit(svia_exit);
514