aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_scc.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-05 02:43:07 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:14 -0500
commit55dba3120fbcbea6800f9a18503d25f73212a347 (patch)
tree1b23e606aad8bc58dbe68ca905c0658625fb176e /drivers/ata/pata_scc.c
parentceb0c642624f634c5b4f46b0e22df19be87a2e53 (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.c30
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
779static void scc_data_xfer (struct ata_device *adev, unsigned char *buf, 779static 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/**