Commit 28874b7ec47e1e5cfe2b67420c4d07c6297a43a9

Authored by Julien May
Committed by Greg Kroah-Hartman
1 parent df3e1ab733

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>

Showing 1 changed file with 19 additions and 4 deletions Side-by-side Diff

drivers/usb/host/isp116x-hcd.c
... ... @@ -94,6 +94,10 @@
94 94 u16 w;
95 95 int quot = len % 4;
96 96  
  97 + /* buffer is already in 'usb data order', which is LE. */
  98 + /* When reading buffer as u16, we have to take care byte order */
  99 + /* doesn't get mixed up */
  100 +
97 101 if ((unsigned long)dp2 & 1) {
98 102 /* not aligned */
99 103 for (; len > 1; len -= 2) {
... ... @@ -105,8 +109,11 @@
105 109 isp116x_write_data16(isp116x, (u16) * dp);
106 110 } else {
107 111 /* aligned */
108   - for (; len > 1; len -= 2)
109   - isp116x_raw_write_data16(isp116x, *dp2++);
  112 + for (; len > 1; len -= 2) {
  113 + /* Keep byte order ! */
  114 + isp116x_raw_write_data16(isp116x, cpu_to_le16(*dp2++));
  115 + }
  116 +
110 117 if (len)
111 118 isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
112 119 }
... ... @@ -124,6 +131,10 @@
124 131 u16 w;
125 132 int quot = len % 4;
126 133  
  134 + /* buffer is already in 'usb data order', which is LE. */
  135 + /* When reading buffer as u16, we have to take care byte order */
  136 + /* doesn't get mixed up */
  137 +
127 138 if ((unsigned long)dp2 & 1) {
128 139 /* not aligned */
129 140 for (; len > 1; len -= 2) {
130 141  
... ... @@ -131,12 +142,16 @@
131 142 *dp++ = w & 0xff;
132 143 *dp++ = (w >> 8) & 0xff;
133 144 }
  145 +
134 146 if (len)
135 147 *dp = 0xff & isp116x_read_data16(isp116x);
136 148 } else {
137 149 /* aligned */
138   - for (; len > 1; len -= 2)
139   - *dp2++ = isp116x_raw_read_data16(isp116x);
  150 + for (; len > 1; len -= 2) {
  151 + /* Keep byte order! */
  152 + *dp2++ = le16_to_cpu(isp116x_raw_read_data16(isp116x));
  153 + }
  154 +
140 155 if (len)
141 156 *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
142 157 }