Commit 871af1210f13966ab911ed2166e4ab2ce775b99d
Committed by
Jeff Garzik
1 parent
e427fe042c
Exists in
master
and in
7 other branches
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>
Showing 7 changed files with 66 additions and 9 deletions Side-by-side Diff
drivers/ata/ata_piix.c
... | ... | @@ -310,7 +310,7 @@ |
310 | 310 | }; |
311 | 311 | |
312 | 312 | static struct ata_port_operations piix_pata_ops = { |
313 | - .inherits = &ata_bmdma_port_ops, | |
313 | + .inherits = &ata_bmdma32_port_ops, | |
314 | 314 | .cable_detect = ata_cable_40wire, |
315 | 315 | .set_piomode = piix_set_piomode, |
316 | 316 | .set_dmamode = piix_set_dmamode, |
drivers/ata/libata-sff.c
... | ... | @@ -78,6 +78,13 @@ |
78 | 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 | 89 | * ata_fill_sg - Fill PCI IDE PRD table |
83 | 90 | * @qc: Metadata associated with taskfile to be transferred |
... | ... | @@ -717,6 +724,52 @@ |
717 | 724 | |
718 | 725 | return words << 1; |
719 | 726 | } |
727 | + | |
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); | |
720 | 773 | |
721 | 774 | /** |
722 | 775 | * ata_sff_data_xfer_noirq - Transfer data by PIO |
drivers/ata/pata_ali.c
... | ... | @@ -151,8 +151,7 @@ |
151 | 151 | |
152 | 152 | pci_read_config_byte(pdev, pio_fifo, &fifo); |
153 | 153 | fifo &= ~(0x0F << shift); |
154 | - if (on) | |
155 | - fifo |= (on << shift); | |
154 | + fifo |= (on << shift); | |
156 | 155 | pci_write_config_byte(pdev, pio_fifo, fifo); |
157 | 156 | } |
158 | 157 | |
159 | 158 | |
... | ... | @@ -370,10 +369,11 @@ |
370 | 369 | .inherits = &ata_sff_port_ops, |
371 | 370 | .cable_detect = ata_cable_40wire, |
372 | 371 | .set_piomode = ali_set_piomode, |
372 | + .sff_data_xfer = ata_sff_data_xfer32, | |
373 | 373 | }; |
374 | 374 | |
375 | 375 | static const struct ata_port_operations ali_dma_base_ops = { |
376 | - .inherits = &ata_bmdma_port_ops, | |
376 | + .inherits = &ata_bmdma32_port_ops, | |
377 | 377 | .set_piomode = ali_set_piomode, |
378 | 378 | .set_dmamode = ali_set_dmamode, |
379 | 379 | }; |
drivers/ata/pata_amd.c
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | #include <linux/libata.h> |
25 | 25 | |
26 | 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 | 30 | * timing_setup - shared timing computation and load |
... | ... | @@ -345,7 +345,7 @@ |
345 | 345 | }; |
346 | 346 | |
347 | 347 | static const struct ata_port_operations amd_base_port_ops = { |
348 | - .inherits = &ata_bmdma_port_ops, | |
348 | + .inherits = &ata_bmdma32_port_ops, | |
349 | 349 | .prereset = amd_pre_reset, |
350 | 350 | }; |
351 | 351 |
drivers/ata/pata_mpiix.c
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | #include <linux/libata.h> |
36 | 36 | |
37 | 37 | #define DRV_NAME "pata_mpiix" |
38 | -#define DRV_VERSION "0.7.6" | |
38 | +#define DRV_VERSION "0.7.7" | |
39 | 39 | |
40 | 40 | enum { |
41 | 41 | IDETIM = 0x6C, /* IDE control register */ |
... | ... | @@ -146,6 +146,7 @@ |
146 | 146 | .cable_detect = ata_cable_40wire, |
147 | 147 | .set_piomode = mpiix_set_piomode, |
148 | 148 | .prereset = mpiix_pre_reset, |
149 | + .sff_data_xfer = ata_sff_data_xfer32, | |
149 | 150 | }; |
150 | 151 | |
151 | 152 | static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
drivers/ata/pata_sil680.c
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | #include <linux/libata.h> |
33 | 33 | |
34 | 34 | #define DRV_NAME "pata_sil680" |
35 | -#define DRV_VERSION "0.4.8" | |
35 | +#define DRV_VERSION "0.4.9" | |
36 | 36 | |
37 | 37 | #define SIL680_MMIO_BAR 5 |
38 | 38 | |
... | ... | @@ -195,7 +195,7 @@ |
195 | 195 | }; |
196 | 196 | |
197 | 197 | static struct ata_port_operations sil680_port_ops = { |
198 | - .inherits = &ata_bmdma_port_ops, | |
198 | + .inherits = &ata_bmdma32_port_ops, | |
199 | 199 | .cable_detect = sil680_cable_detect, |
200 | 200 | .set_piomode = sil680_set_piomode, |
201 | 201 | .set_dmamode = sil680_set_dmamode, |
include/linux/libata.h
... | ... | @@ -1518,6 +1518,7 @@ |
1518 | 1518 | |
1519 | 1519 | extern const struct ata_port_operations ata_sff_port_ops; |
1520 | 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 | 1523 | /* PIO only, sg_tablesize and dma_boundary limits can be removed */ |
1523 | 1524 | #define ATA_PIO_SHT(drv_name) \ |
... | ... | @@ -1544,6 +1545,8 @@ |
1544 | 1545 | extern void ata_sff_exec_command(struct ata_port *ap, |
1545 | 1546 | const struct ata_taskfile *tf); |
1546 | 1547 | extern unsigned int ata_sff_data_xfer(struct ata_device *dev, |
1548 | + unsigned char *buf, unsigned int buflen, int rw); | |
1549 | +extern unsigned int ata_sff_data_xfer32(struct ata_device *dev, | |
1547 | 1550 | unsigned char *buf, unsigned int buflen, int rw); |
1548 | 1551 | extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, |
1549 | 1552 | unsigned char *buf, unsigned int buflen, int rw); |