aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-sff.c
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 /drivers/ata/libata-sff.c
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>
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r--drivers/ata/libata-sff.c53
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
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