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 /drivers/ata/libata-sff.c | |
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>
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 53 |
1 files changed, 53 insertions, 0 deletions
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 |