diff options
author | Alan Cox <alan@redhat.com> | 2009-01-05 09:16:39 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-01-08 16:34:27 -0500 |
commit | 871af1210f13966ab911ed2166e4ab2ce775b99d (patch) | |
tree | f17f0016f6e966d54a379a3de6e6bbde3b9359fe | |
parent | e427fe042cf90c0652eed9a85e57a8fd8af89890 (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.c | 2 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 53 | ||||
-rw-r--r-- | drivers/ata/pata_ali.c | 6 | ||||
-rw-r--r-- | drivers/ata/pata_amd.c | 4 | ||||
-rw-r--r-- | drivers/ata/pata_mpiix.c | 3 | ||||
-rw-r--r-- | drivers/ata/pata_sil680.c | 4 | ||||
-rw-r--r-- | include/linux/libata.h | 3 |
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 | ||
312 | static struct ata_port_operations piix_pata_ops = { | 312 | static 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 | ||
81 | const struct ata_port_operations ata_bmdma32_port_ops = { | ||
82 | .inherits = &ata_bmdma_port_ops, | ||
83 | |||
84 | .sff_data_xfer = ata_sff_data_xfer32, | ||
85 | }; | ||
86 | EXPORT_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 | |||
745 | unsigned 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 | } | ||
772 | EXPORT_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 | ||
375 | static const struct ata_port_operations ali_dma_base_ops = { | 375 | static 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 | ||
347 | static const struct ata_port_operations amd_base_port_ops = { | 347 | static 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 | ||
40 | enum { | 40 | enum { |
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 | ||
151 | static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 152 | static 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 | ||
197 | static struct ata_port_operations sil680_port_ops = { | 197 | static 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 | ||
1519 | extern const struct ata_port_operations ata_sff_port_ops; | 1519 | extern const struct ata_port_operations ata_sff_port_ops; |
1520 | extern const struct ata_port_operations ata_bmdma_port_ops; | 1520 | extern const struct ata_port_operations ata_bmdma_port_ops; |
1521 | extern 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); |
1546 | extern unsigned int ata_sff_data_xfer(struct ata_device *dev, | 1547 | extern 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); |
1549 | extern unsigned int ata_sff_data_xfer32(struct ata_device *dev, | ||
1550 | unsigned char *buf, unsigned int buflen, int rw); | ||
1548 | extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, | 1551 | extern 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); |
1550 | extern u8 ata_sff_irq_on(struct ata_port *ap); | 1553 | extern u8 ata_sff_irq_on(struct ata_port *ap); |