aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien May <mailinglist@miromico.ch>2008-06-27 15:01:18 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2008-07-21 15:16:48 -0700
commit28874b7ec47e1e5cfe2b67420c4d07c6297a43a9 (patch)
tree3e86dd66bb7ab04d086ba080e456a71bbe5daf31
parentUSB: fix double kfree in ipaq in error case (diff)
downloadlinux-dev-28874b7ec47e1e5cfe2b67420c4d07c6297a43a9.tar.xz
linux-dev-28874b7ec47e1e5cfe2b67420c4d07c6297a43a9.zip
USB: Fix bug with byte order in isp116x-hcd.c fio write/read
URB payload data are transfered in wrong byte order on a big endinan architecture (AVR32). Signed-off-by: Julien May <mailinglist@miromico.ch> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/isp116x-hcd.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 109dee82a376..31178e10cbbe 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -94,6 +94,10 @@ static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
u16 w;
int quot = len % 4;
+ /* buffer is already in 'usb data order', which is LE. */
+ /* When reading buffer as u16, we have to take care byte order */
+ /* doesn't get mixed up */
+
if ((unsigned long)dp2 & 1) {
/* not aligned */
for (; len > 1; len -= 2) {
@@ -105,8 +109,11 @@ static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
isp116x_write_data16(isp116x, (u16) * dp);
} else {
/* aligned */
- for (; len > 1; len -= 2)
- isp116x_raw_write_data16(isp116x, *dp2++);
+ for (; len > 1; len -= 2) {
+ /* Keep byte order ! */
+ isp116x_raw_write_data16(isp116x, cpu_to_le16(*dp2++));
+ }
+
if (len)
isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
}
@@ -124,6 +131,10 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
u16 w;
int quot = len % 4;
+ /* buffer is already in 'usb data order', which is LE. */
+ /* When reading buffer as u16, we have to take care byte order */
+ /* doesn't get mixed up */
+
if ((unsigned long)dp2 & 1) {
/* not aligned */
for (; len > 1; len -= 2) {
@@ -131,12 +142,16 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
*dp++ = w & 0xff;
*dp++ = (w >> 8) & 0xff;
}
+
if (len)
*dp = 0xff & isp116x_read_data16(isp116x);
} else {
/* aligned */
- for (; len > 1; len -= 2)
- *dp2++ = isp116x_raw_read_data16(isp116x);
+ for (; len > 1; len -= 2) {
+ /* Keep byte order! */
+ *dp2++ = le16_to_cpu(isp116x_raw_read_data16(isp116x));
+ }
+
if (len)
*(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
}