diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-05 02:43:07 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:14 -0500 |
commit | 55dba3120fbcbea6800f9a18503d25f73212a347 (patch) | |
tree | 1b23e606aad8bc58dbe68ca905c0658625fb176e /drivers/ata/pata_scc.c | |
parent | ceb0c642624f634c5b4f46b0e22df19be87a2e53 (diff) |
libata: update ->data_xfer hook for ATAPI
Depending on how many bytes are transferred as a unit, PIO data
transfer may consume more bytes than requested. Knowing how much
data is consumed is necessary to determine how much is left for
draining. This patch update ->data_xfer such that it returns the
number of consumed bytes.
While at it, it also makes the following changes.
* s/adev/dev/
* use READ/WRITE constants for rw indication
* misc clean ups
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/pata_scc.c')
-rw-r--r-- | drivers/ata/pata_scc.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index ea2ef9fc15be..55055b27524c 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -768,45 +768,47 @@ static u8 scc_bmdma_status (struct ata_port *ap) | |||
768 | 768 | ||
769 | /** | 769 | /** |
770 | * scc_data_xfer - Transfer data by PIO | 770 | * scc_data_xfer - Transfer data by PIO |
771 | * @adev: device for this I/O | 771 | * @dev: device for this I/O |
772 | * @buf: data buffer | 772 | * @buf: data buffer |
773 | * @buflen: buffer length | 773 | * @buflen: buffer length |
774 | * @write_data: read/write | 774 | * @rw: read/write |
775 | * | 775 | * |
776 | * Note: Original code is ata_data_xfer(). | 776 | * Note: Original code is ata_data_xfer(). |
777 | */ | 777 | */ |
778 | 778 | ||
779 | static void scc_data_xfer (struct ata_device *adev, unsigned char *buf, | 779 | static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, |
780 | unsigned int buflen, int write_data) | 780 | unsigned int buflen, int rw) |
781 | { | 781 | { |
782 | struct ata_port *ap = adev->link->ap; | 782 | struct ata_port *ap = dev->link->ap; |
783 | unsigned int words = buflen >> 1; | 783 | unsigned int words = buflen >> 1; |
784 | unsigned int i; | 784 | unsigned int i; |
785 | u16 *buf16 = (u16 *) buf; | 785 | u16 *buf16 = (u16 *) buf; |
786 | void __iomem *mmio = ap->ioaddr.data_addr; | 786 | void __iomem *mmio = ap->ioaddr.data_addr; |
787 | 787 | ||
788 | /* Transfer multiple of 2 bytes */ | 788 | /* Transfer multiple of 2 bytes */ |
789 | if (write_data) { | 789 | if (rw == READ) |
790 | for (i = 0; i < words; i++) | ||
791 | out_be32(mmio, cpu_to_le16(buf16[i])); | ||
792 | } else { | ||
793 | for (i = 0; i < words; i++) | 790 | for (i = 0; i < words; i++) |
794 | buf16[i] = le16_to_cpu(in_be32(mmio)); | 791 | buf16[i] = le16_to_cpu(in_be32(mmio)); |
795 | } | 792 | else |
793 | for (i = 0; i < words; i++) | ||
794 | out_be32(mmio, cpu_to_le16(buf16[i])); | ||
796 | 795 | ||
797 | /* Transfer trailing 1 byte, if any. */ | 796 | /* Transfer trailing 1 byte, if any. */ |
798 | if (unlikely(buflen & 0x01)) { | 797 | if (unlikely(buflen & 0x01)) { |
799 | u16 align_buf[1] = { 0 }; | 798 | u16 align_buf[1] = { 0 }; |
800 | unsigned char *trailing_buf = buf + buflen - 1; | 799 | unsigned char *trailing_buf = buf + buflen - 1; |
801 | 800 | ||
802 | if (write_data) { | 801 | if (rw == READ) { |
803 | memcpy(align_buf, trailing_buf, 1); | ||
804 | out_be32(mmio, cpu_to_le16(align_buf[0])); | ||
805 | } else { | ||
806 | align_buf[0] = le16_to_cpu(in_be32(mmio)); | 802 | align_buf[0] = le16_to_cpu(in_be32(mmio)); |
807 | memcpy(trailing_buf, align_buf, 1); | 803 | memcpy(trailing_buf, align_buf, 1); |
804 | } else { | ||
805 | memcpy(align_buf, trailing_buf, 1); | ||
806 | out_be32(mmio, cpu_to_le16(align_buf[0])); | ||
808 | } | 807 | } |
808 | words++; | ||
809 | } | 809 | } |
810 | |||
811 | return words << 1; | ||
810 | } | 812 | } |
811 | 813 | ||
812 | /** | 814 | /** |