aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
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
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')
-rw-r--r--drivers/ata/libata-core.c46
-rw-r--r--drivers/ata/pata_bf54x.c28
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c26
-rw-r--r--drivers/ata/pata_legacy.c36
-rw-r--r--drivers/ata/pata_qdi.c30
-rw-r--r--drivers/ata/pata_scc.c30
-rw-r--r--drivers/ata/pata_winbond.c28
7 files changed, 127 insertions, 97 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 */
5007void ata_data_xfer(struct ata_device *adev, unsigned char *buf, 5010unsigned 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 */
5047void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, 5057unsigned 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
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 7842cc487359..41cd921082ba 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1167,34 +1167,36 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap)
1167 * Note: Original code is ata_data_xfer(). 1167 * Note: Original code is ata_data_xfer().
1168 */ 1168 */
1169 1169
1170static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf, 1170static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf,
1171 unsigned int buflen, int write_data) 1171 unsigned int buflen, int rw)
1172{ 1172{
1173 struct ata_port *ap = adev->link->ap; 1173 struct ata_port *ap = dev->link->ap;
1174 unsigned int words = buflen >> 1;
1175 unsigned short *buf16 = (u16 *) buf;
1176 void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; 1174 void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
1175 unsigned int words = buflen >> 1;
1176 unsigned short *buf16 = (u16 *)buf;
1177 1177
1178 /* Transfer multiple of 2 bytes */ 1178 /* Transfer multiple of 2 bytes */
1179 if (write_data) { 1179 if (rw == READ)
1180 write_atapi_data(base, words, buf16);
1181 } else {
1182 read_atapi_data(base, words, buf16); 1180 read_atapi_data(base, words, buf16);
1183 } 1181 else
1182 write_atapi_data(base, words, buf16);
1184 1183
1185 /* Transfer trailing 1 byte, if any. */ 1184 /* Transfer trailing 1 byte, if any. */
1186 if (unlikely(buflen & 0x01)) { 1185 if (unlikely(buflen & 0x01)) {
1187 unsigned short align_buf[1] = { 0 }; 1186 unsigned short align_buf[1] = { 0 };
1188 unsigned char *trailing_buf = buf + buflen - 1; 1187 unsigned char *trailing_buf = buf + buflen - 1;
1189 1188
1190 if (write_data) { 1189 if (rw == READ) {
1191 memcpy(align_buf, trailing_buf, 1);
1192 write_atapi_data(base, 1, align_buf);
1193 } else {
1194 read_atapi_data(base, 1, align_buf); 1190 read_atapi_data(base, 1, align_buf);
1195 memcpy(trailing_buf, align_buf, 1); 1191 memcpy(trailing_buf, align_buf, 1);
1192 } else {
1193 memcpy(align_buf, trailing_buf, 1);
1194 write_atapi_data(base, 1, align_buf);
1196 } 1195 }
1196 words++;
1197 } 1197 }
1198
1199 return words << 1;
1198} 1200}
1199 1201
1200/** 1202/**
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 120b5bfa7ce6..030878fedeb5 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -42,13 +42,13 @@ static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error)
42 return 0; 42 return 0;
43} 43}
44 44
45static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, 45static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev,
46 unsigned int buflen, int write_data) 46 unsigned char *buf, unsigned int buflen, int rw)
47{ 47{
48 unsigned int i; 48 unsigned int i;
49 unsigned int words = buflen >> 1; 49 unsigned int words = buflen >> 1;
50 u16 *buf16 = (u16 *) buf; 50 u16 *buf16 = (u16 *) buf;
51 struct ata_port *ap = adev->link->ap; 51 struct ata_port *ap = dev->link->ap;
52 void __iomem *mmio = ap->ioaddr.data_addr; 52 void __iomem *mmio = ap->ioaddr.data_addr;
53 struct ixp4xx_pata_data *data = ap->host->dev->platform_data; 53 struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
54 54
@@ -59,30 +59,32 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
59 udelay(100); 59 udelay(100);
60 60
61 /* Transfer multiple of 2 bytes */ 61 /* Transfer multiple of 2 bytes */
62 if (write_data) { 62 if (rw == READ)
63 for (i = 0; i < words; i++)
64 writew(buf16[i], mmio);
65 } else {
66 for (i = 0; i < words; i++) 63 for (i = 0; i < words; i++)
67 buf16[i] = readw(mmio); 64 buf16[i] = readw(mmio);
68 } 65 else
66 for (i = 0; i < words; i++)
67 writew(buf16[i], mmio);
69 68
70 /* Transfer trailing 1 byte, if any. */ 69 /* Transfer trailing 1 byte, if any. */
71 if (unlikely(buflen & 0x01)) { 70 if (unlikely(buflen & 0x01)) {
72 u16 align_buf[1] = { 0 }; 71 u16 align_buf[1] = { 0 };
73 unsigned char *trailing_buf = buf + buflen - 1; 72 unsigned char *trailing_buf = buf + buflen - 1;
74 73
75 if (write_data) { 74 if (rw == READ) {
76 memcpy(align_buf, trailing_buf, 1);
77 writew(align_buf[0], mmio);
78 } else {
79 align_buf[0] = readw(mmio); 75 align_buf[0] = readw(mmio);
80 memcpy(trailing_buf, align_buf, 1); 76 memcpy(trailing_buf, align_buf, 1);
77 } else {
78 memcpy(align_buf, trailing_buf, 1);
79 writew(align_buf[0], mmio);
81 } 80 }
81 words++;
82 } 82 }
83 83
84 udelay(100); 84 udelay(100);
85 *data->cs0_cfg |= 0x01; 85 *data->cs0_cfg |= 0x01;
86
87 return words << 1;
86} 88}
87 89
88static struct scsi_host_template ixp4xx_sht = { 90static struct scsi_host_template ixp4xx_sht = {
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 17159b5e1e43..dae85aa12e32 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -249,13 +249,14 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
249 249
250} 250}
251 251
252static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) 252static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
253 unsigned char *buf, unsigned int buflen, int rw)
253{ 254{
254 struct ata_port *ap = adev->link->ap;
255 int slop = buflen & 3;
256 unsigned long flags;
257
258 if (ata_id_has_dword_io(adev->id)) { 255 if (ata_id_has_dword_io(adev->id)) {
256 struct ata_port *ap = dev->link->ap;
257 int slop = buflen & 3;
258 unsigned long flags;
259
259 local_irq_save(flags); 260 local_irq_save(flags);
260 261
261 /* Perform the 32bit I/O synchronization sequence */ 262 /* Perform the 32bit I/O synchronization sequence */
@@ -264,26 +265,27 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig
264 ioread8(ap->ioaddr.nsect_addr); 265 ioread8(ap->ioaddr.nsect_addr);
265 266
266 /* Now the data */ 267 /* Now the data */
267 268 if (rw == READ)
268 if (write_data)
269 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
270 else
271 ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); 269 ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
270 else
271 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
272 272
273 if (unlikely(slop)) { 273 if (unlikely(slop)) {
274 __le32 pad = 0; 274 u32 pad;
275 if (write_data) { 275 if (rw == READ) {
276 memcpy(&pad, buf + buflen - slop, slop);
277 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
278 } else {
279 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); 276 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
280 memcpy(buf + buflen - slop, &pad, slop); 277 memcpy(buf + buflen - slop, &pad, slop);
278 } else {
279 memcpy(&pad, buf + buflen - slop, slop);
280 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
281 } 281 }
282 buflen += 4 - slop;
282 } 283 }
283 local_irq_restore(flags); 284 local_irq_restore(flags);
284 } 285 } else
285 else 286 buflen = ata_data_xfer_noirq(dev, buf, buflen, rw);
286 ata_data_xfer_noirq(adev, buf, buflen, write_data); 287
288 return buflen;
287} 289}
288 290
289static struct ata_port_operations pdc20230_port_ops = { 291static struct ata_port_operations pdc20230_port_ops = {
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index a4c0e502cb42..9f308ed76cc8 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -124,29 +124,33 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
124 return ata_qc_issue_prot(qc); 124 return ata_qc_issue_prot(qc);
125} 125}
126 126
127static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) 127static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf,
128 unsigned int buflen, int rw)
128{ 129{
129 struct ata_port *ap = adev->link->ap; 130 if (ata_id_has_dword_io(dev->id)) {
130 int slop = buflen & 3; 131 struct ata_port *ap = dev->link->ap;
132 int slop = buflen & 3;
131 133
132 if (ata_id_has_dword_io(adev->id)) { 134 if (rw == READ)
133 if (write_data)
134 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
135 else
136 ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); 135 ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
136 else
137 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
137 138
138 if (unlikely(slop)) { 139 if (unlikely(slop)) {
139 __le32 pad = 0; 140 u32 pad;
140 if (write_data) { 141 if (rw == READ) {
141 memcpy(&pad, buf + buflen - slop, slop);
142 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
143 } else {
144 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); 142 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
145 memcpy(buf + buflen - slop, &pad, slop); 143 memcpy(buf + buflen - slop, &pad, slop);
144 } else {
145 memcpy(&pad, buf + buflen - slop, slop);
146 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
146 } 147 }
148 buflen += 4 - slop;
147 } 149 }
148 } else 150 } else
149 ata_data_xfer(adev, buf, buflen, write_data); 151 buflen = ata_data_xfer(dev, buf, buflen, rw);
152
153 return buflen;
150} 154}
151 155
152static struct scsi_host_template qdi_sht = { 156static struct scsi_host_template qdi_sht = {
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/**
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 7116a9e7a8b2..7312e9182d69 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -92,29 +92,33 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
92} 92}
93 93
94 94
95static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) 95static void winbond_data_xfer(struct ata_device *dev, unsigned char *buf,
96 unsigned int buflen, int rw)
96{ 97{
97 struct ata_port *ap = adev->link->ap; 98 struct ata_port *ap = dev->link->ap;
98 int slop = buflen & 3; 99 int slop = buflen & 3;
99 100
100 if (ata_id_has_dword_io(adev->id)) { 101 if (ata_id_has_dword_io(dev->id)) {
101 if (write_data) 102 if (rw == READ)
102 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
103 else
104 ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); 103 ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
104 else
105 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
105 106
106 if (unlikely(slop)) { 107 if (unlikely(slop)) {
107 __le32 pad = 0; 108 u32 pad;
108 if (write_data) { 109 if (rw == READ) {
109 memcpy(&pad, buf + buflen - slop, slop);
110 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
111 } else {
112 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); 110 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
113 memcpy(buf + buflen - slop, &pad, slop); 111 memcpy(buf + buflen - slop, &pad, slop);
112 } else {
113 memcpy(&pad, buf + buflen - slop, slop);
114 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
114 } 115 }
116 buflen += 4 - slop;
115 } 117 }
116 } else 118 } else
117 ata_data_xfer(adev, buf, buflen, write_data); 119 buflen = ata_data_xfer(dev, buf, buflen, rw);
120
121 return buflen;
118} 122}
119 123
120static struct scsi_host_template winbond_sht = { 124static struct scsi_host_template winbond_sht = {