aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-05 09:16:39 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-01-08 16:34:27 -0500
commit871af1210f13966ab911ed2166e4ab2ce775b99d (patch)
treef17f0016f6e966d54a379a3de6e6bbde3b9359fe
parente427fe042cf90c0652eed9a85e57a8fd8af89890 (diff)
libata: Add 32bit PIO support
This matters for some controllers and in one or two cases almost doubles PIO performance. Add a bmdma32 operations set we can inherit and activate it for some controllers Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/ata_piix.c2
-rw-r--r--drivers/ata/libata-sff.c53
-rw-r--r--drivers/ata/pata_ali.c6
-rw-r--r--drivers/ata/pata_amd.c4
-rw-r--r--drivers/ata/pata_mpiix.c3
-rw-r--r--drivers/ata/pata_sil680.c4
-rw-r--r--include/linux/libata.h3
7 files changed, 66 insertions, 9 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 78659546130c..887d8f46a287 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -310,7 +310,7 @@ static struct scsi_host_template piix_sht = {
310}; 310};
311 311
312static struct ata_port_operations piix_pata_ops = { 312static struct ata_port_operations piix_pata_ops = {
313 .inherits = &ata_bmdma_port_ops, 313 .inherits = &ata_bmdma32_port_ops,
314 .cable_detect = ata_cable_40wire, 314 .cable_detect = ata_cable_40wire,
315 .set_piomode = piix_set_piomode, 315 .set_piomode = piix_set_piomode,
316 .set_dmamode = piix_set_dmamode, 316 .set_dmamode = piix_set_dmamode,
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 9033d164c4ec..b58549fac460 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -78,6 +78,13 @@ const struct ata_port_operations ata_bmdma_port_ops = {
78 .bmdma_status = ata_bmdma_status, 78 .bmdma_status = ata_bmdma_status,
79}; 79};
80 80
81const struct ata_port_operations ata_bmdma32_port_ops = {
82 .inherits = &ata_bmdma_port_ops,
83
84 .sff_data_xfer = ata_sff_data_xfer32,
85};
86EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
87
81/** 88/**
82 * ata_fill_sg - Fill PCI IDE PRD table 89 * ata_fill_sg - Fill PCI IDE PRD table
83 * @qc: Metadata associated with taskfile to be transferred 90 * @qc: Metadata associated with taskfile to be transferred
@@ -719,6 +726,52 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
719} 726}
720 727
721/** 728/**
729 * ata_sff_data_xfer32 - Transfer data by PIO
730 * @dev: device to target
731 * @buf: data buffer
732 * @buflen: buffer length
733 * @rw: read/write
734 *
735 * Transfer data from/to the device data register by PIO using 32bit
736 * I/O operations.
737 *
738 * LOCKING:
739 * Inherited from caller.
740 *
741 * RETURNS:
742 * Bytes consumed.
743 */
744
745unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
746 unsigned int buflen, int rw)
747{
748 struct ata_port *ap = dev->link->ap;
749 void __iomem *data_addr = ap->ioaddr.data_addr;
750 unsigned int words = buflen >> 2;
751 int slop = buflen & 3;
752
753 /* Transfer multiple of 4 bytes */
754 if (rw == READ)
755 ioread32_rep(data_addr, buf, words);
756 else
757 iowrite32_rep(data_addr, buf, words);
758
759 if (unlikely(slop)) {
760 __le32 pad;
761 if (rw == READ) {
762 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
763 memcpy(buf + buflen - slop, &pad, slop);
764 } else {
765 memcpy(&pad, buf + buflen - slop, slop);
766 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
767 }
768 words++;
769 }
770 return words << 2;
771}
772EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
773
774/**
722 * ata_sff_data_xfer_noirq - Transfer data by PIO 775 * ata_sff_data_xfer_noirq - Transfer data by PIO
723 * @dev: device to target 776 * @dev: device to target
724 * @buf: data buffer 777 * @buf: data buffer
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index a4f9e39442c6..a7999c19f0c9 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -151,8 +151,7 @@ static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int o
151 151
152 pci_read_config_byte(pdev, pio_fifo, &fifo); 152 pci_read_config_byte(pdev, pio_fifo, &fifo);
153 fifo &= ~(0x0F << shift); 153 fifo &= ~(0x0F << shift);
154 if (on) 154 fifo |= (on << shift);
155 fifo |= (on << shift);
156 pci_write_config_byte(pdev, pio_fifo, fifo); 155 pci_write_config_byte(pdev, pio_fifo, fifo);
157} 156}
158 157
@@ -370,10 +369,11 @@ static struct ata_port_operations ali_early_port_ops = {
370 .inherits = &ata_sff_port_ops, 369 .inherits = &ata_sff_port_ops,
371 .cable_detect = ata_cable_40wire, 370 .cable_detect = ata_cable_40wire,
372 .set_piomode = ali_set_piomode, 371 .set_piomode = ali_set_piomode,
372 .sff_data_xfer = ata_sff_data_xfer32,
373}; 373};
374 374
375static const struct ata_port_operations ali_dma_base_ops = { 375static const struct ata_port_operations ali_dma_base_ops = {
376 .inherits = &ata_bmdma_port_ops, 376 .inherits = &ata_bmdma32_port_ops,
377 .set_piomode = ali_set_piomode, 377 .set_piomode = ali_set_piomode,
378 .set_dmamode = ali_set_dmamode, 378 .set_dmamode = ali_set_dmamode,
379}; 379};
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 0ec9c7d9fe9d..63719ab9ea44 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -24,7 +24,7 @@
24#include <linux/libata.h> 24#include <linux/libata.h>
25 25
26#define DRV_NAME "pata_amd" 26#define DRV_NAME "pata_amd"
27#define DRV_VERSION "0.3.10" 27#define DRV_VERSION "0.3.11"
28 28
29/** 29/**
30 * timing_setup - shared timing computation and load 30 * timing_setup - shared timing computation and load
@@ -345,7 +345,7 @@ static struct scsi_host_template amd_sht = {
345}; 345};
346 346
347static const struct ata_port_operations amd_base_port_ops = { 347static const struct ata_port_operations amd_base_port_ops = {
348 .inherits = &ata_bmdma_port_ops, 348 .inherits = &ata_bmdma32_port_ops,
349 .prereset = amd_pre_reset, 349 .prereset = amd_pre_reset,
350}; 350};
351 351
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 7c8faa48b5f3..aa576cac4d17 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -35,7 +35,7 @@
35#include <linux/libata.h> 35#include <linux/libata.h>
36 36
37#define DRV_NAME "pata_mpiix" 37#define DRV_NAME "pata_mpiix"
38#define DRV_VERSION "0.7.6" 38#define DRV_VERSION "0.7.7"
39 39
40enum { 40enum {
41 IDETIM = 0x6C, /* IDE control register */ 41 IDETIM = 0x6C, /* IDE control register */
@@ -146,6 +146,7 @@ static struct ata_port_operations mpiix_port_ops = {
146 .cable_detect = ata_cable_40wire, 146 .cable_detect = ata_cable_40wire,
147 .set_piomode = mpiix_set_piomode, 147 .set_piomode = mpiix_set_piomode,
148 .prereset = mpiix_pre_reset, 148 .prereset = mpiix_pre_reset,
149 .sff_data_xfer = ata_sff_data_xfer32,
149}; 150};
150 151
151static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) 152static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 83580a59db58..9e764e5747e6 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -32,7 +32,7 @@
32#include <linux/libata.h> 32#include <linux/libata.h>
33 33
34#define DRV_NAME "pata_sil680" 34#define DRV_NAME "pata_sil680"
35#define DRV_VERSION "0.4.8" 35#define DRV_VERSION "0.4.9"
36 36
37#define SIL680_MMIO_BAR 5 37#define SIL680_MMIO_BAR 5
38 38
@@ -195,7 +195,7 @@ static struct scsi_host_template sil680_sht = {
195}; 195};
196 196
197static struct ata_port_operations sil680_port_ops = { 197static struct ata_port_operations sil680_port_ops = {
198 .inherits = &ata_bmdma_port_ops, 198 .inherits = &ata_bmdma32_port_ops,
199 .cable_detect = sil680_cable_detect, 199 .cable_detect = sil680_cable_detect,
200 .set_piomode = sil680_set_piomode, 200 .set_piomode = sil680_set_piomode,
201 .set_dmamode = sil680_set_dmamode, 201 .set_dmamode = sil680_set_dmamode,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 3449de597eff..4f7c8fb4d3fe 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1518,6 +1518,7 @@ extern void sata_pmp_error_handler(struct ata_port *ap);
1518 1518
1519extern const struct ata_port_operations ata_sff_port_ops; 1519extern const struct ata_port_operations ata_sff_port_ops;
1520extern const struct ata_port_operations ata_bmdma_port_ops; 1520extern const struct ata_port_operations ata_bmdma_port_ops;
1521extern const struct ata_port_operations ata_bmdma32_port_ops;
1521 1522
1522/* PIO only, sg_tablesize and dma_boundary limits can be removed */ 1523/* PIO only, sg_tablesize and dma_boundary limits can be removed */
1523#define ATA_PIO_SHT(drv_name) \ 1524#define ATA_PIO_SHT(drv_name) \
@@ -1545,6 +1546,8 @@ extern void ata_sff_exec_command(struct ata_port *ap,
1545 const struct ata_taskfile *tf); 1546 const struct ata_taskfile *tf);
1546extern unsigned int ata_sff_data_xfer(struct ata_device *dev, 1547extern unsigned int ata_sff_data_xfer(struct ata_device *dev,
1547 unsigned char *buf, unsigned int buflen, int rw); 1548 unsigned char *buf, unsigned int buflen, int rw);
1549extern unsigned int ata_sff_data_xfer32(struct ata_device *dev,
1550 unsigned char *buf, unsigned int buflen, int rw);
1548extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, 1551extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev,
1549 unsigned char *buf, unsigned int buflen, int rw); 1552 unsigned char *buf, unsigned int buflen, int rw);
1550extern u8 ata_sff_irq_on(struct ata_port *ap); 1553extern u8 ata_sff_irq_on(struct ata_port *ap);