diff options
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2c9745a74d50..39cedd949ed4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4994,7 +4994,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
4994 | 4994 | ||
4995 | /** | 4995 | /** |
4996 | * ata_data_xfer - Transfer data by PIO | 4996 | * ata_data_xfer - Transfer data by PIO |
4997 | * @adev: device to target | 4997 | * @dev: device to target |
4998 | * @buf: data buffer | 4998 | * @buf: data buffer |
4999 | * @buflen: buffer length | 4999 | * @buflen: buffer length |
5000 | * @write_data: read/write | 5000 | * @write_data: read/write |
@@ -5003,37 +5003,44 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
5003 | * | 5003 | * |
5004 | * LOCKING: | 5004 | * LOCKING: |
5005 | * Inherited from caller. | 5005 | * Inherited from caller. |
5006 | * | ||
5007 | * RETURNS: | ||
5008 | * Bytes consumed. | ||
5006 | */ | 5009 | */ |
5007 | void ata_data_xfer(struct ata_device *adev, unsigned char *buf, | 5010 | unsigned int ata_data_xfer(struct ata_device *dev, unsigned char *buf, |
5008 | unsigned int buflen, int write_data) | 5011 | unsigned int buflen, int rw) |
5009 | { | 5012 | { |
5010 | struct ata_port *ap = adev->link->ap; | 5013 | struct ata_port *ap = dev->link->ap; |
5014 | void __iomem *data_addr = ap->ioaddr.data_addr; | ||
5011 | unsigned int words = buflen >> 1; | 5015 | unsigned int words = buflen >> 1; |
5012 | 5016 | ||
5013 | /* Transfer multiple of 2 bytes */ | 5017 | /* Transfer multiple of 2 bytes */ |
5014 | if (write_data) | 5018 | if (rw == READ) |
5015 | iowrite16_rep(ap->ioaddr.data_addr, buf, words); | 5019 | ioread16_rep(data_addr, buf, words); |
5016 | else | 5020 | else |
5017 | ioread16_rep(ap->ioaddr.data_addr, buf, words); | 5021 | iowrite16_rep(data_addr, buf, words); |
5018 | 5022 | ||
5019 | /* Transfer trailing 1 byte, if any. */ | 5023 | /* Transfer trailing 1 byte, if any. */ |
5020 | if (unlikely(buflen & 0x01)) { | 5024 | if (unlikely(buflen & 0x01)) { |
5021 | u16 align_buf[1] = { 0 }; | 5025 | u16 align_buf[1] = { 0 }; |
5022 | unsigned char *trailing_buf = buf + buflen - 1; | 5026 | unsigned char *trailing_buf = buf + buflen - 1; |
5023 | 5027 | ||
5024 | if (write_data) { | 5028 | if (rw == READ) { |
5025 | memcpy(align_buf, trailing_buf, 1); | 5029 | align_buf[0] = cpu_to_le16(ioread16(data_addr)); |
5026 | iowrite16(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr); | ||
5027 | } else { | ||
5028 | align_buf[0] = cpu_to_le16(ioread16(ap->ioaddr.data_addr)); | ||
5029 | memcpy(trailing_buf, align_buf, 1); | 5030 | memcpy(trailing_buf, align_buf, 1); |
5031 | } else { | ||
5032 | memcpy(align_buf, trailing_buf, 1); | ||
5033 | iowrite16(le16_to_cpu(align_buf[0]), data_addr); | ||
5030 | } | 5034 | } |
5035 | words++; | ||
5031 | } | 5036 | } |
5037 | |||
5038 | return words << 1; | ||
5032 | } | 5039 | } |
5033 | 5040 | ||
5034 | /** | 5041 | /** |
5035 | * ata_data_xfer_noirq - Transfer data by PIO | 5042 | * ata_data_xfer_noirq - Transfer data by PIO |
5036 | * @adev: device to target | 5043 | * @dev: device to target |
5037 | * @buf: data buffer | 5044 | * @buf: data buffer |
5038 | * @buflen: buffer length | 5045 | * @buflen: buffer length |
5039 | * @write_data: read/write | 5046 | * @write_data: read/write |
@@ -5043,14 +5050,21 @@ void ata_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
5043 | * | 5050 | * |
5044 | * LOCKING: | 5051 | * LOCKING: |
5045 | * Inherited from caller. | 5052 | * Inherited from caller. |
5053 | * | ||
5054 | * RETURNS: | ||
5055 | * Bytes consumed. | ||
5046 | */ | 5056 | */ |
5047 | void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, | 5057 | unsigned int ata_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, |
5048 | unsigned int buflen, int write_data) | 5058 | unsigned int buflen, int rw) |
5049 | { | 5059 | { |
5050 | unsigned long flags; | 5060 | unsigned long flags; |
5061 | unsigned int consumed; | ||
5062 | |||
5051 | local_irq_save(flags); | 5063 | local_irq_save(flags); |
5052 | ata_data_xfer(adev, buf, buflen, write_data); | 5064 | consumed = ata_data_xfer(dev, buf, buflen, rw); |
5053 | local_irq_restore(flags); | 5065 | local_irq_restore(flags); |
5066 | |||
5067 | return consumed; | ||
5054 | } | 5068 | } |
5055 | 5069 | ||
5056 | 5070 | ||