aboutsummaryrefslogtreecommitdiff
path: root/common/usb.c
diff options
context:
space:
mode:
authorTom Rini <trini@ti.com>2011-12-15 08:40:51 -0700
committerRemy Bohmer <linux@bohmer.net>2011-12-16 21:37:17 +0100
commitb2fb47f1873ae812ce33129996a22b11a36d0aa9 (patch)
tree8afeef2bce3d0ca0aa44ed59956086f6dae2767c /common/usb.c
parentddc7e541ae62f29d85b35cdf8d12c7322d353d51 (diff)
USB: Use (get|put)_unaligned for accessing wMaxPacketSize
In 9792987721c7980453fe6447c3fa6593b44f8458 Stefan describes a usecase where the previous behavior of leaving wMaxPacketSize be unaligned caused fatal problems. The initial fix for this problem was incomplete however as it showed another cases of non-aligned access that previously worked implicitly. This switches to making sure that all access of wMaxPacketSize are done via (get|put)_unaligned. In order to maintain a level of readability to the code in some cases we now use a variable for the value of wMaxPacketSize and in others, a macro. Cc: Minkyu Kang <mk7.kang@samsung.com> Cc: Remy Bohmer <linux@bohmer.net> OpenRISC: Tested-by: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> Beagleboard xM, Pandaboard run-tested, s5p_goni build-tested. Signed-off-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'common/usb.c')
-rw-r--r--common/usb.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/common/usb.c b/common/usb.c
index 4418c70f4..63a11c8f5 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -49,6 +49,7 @@
#include <asm/processor.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <usb.h>
#ifdef CONFIG_4xx
@@ -279,30 +280,32 @@ usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)
{
int b;
struct usb_endpoint_descriptor *ep;
+ u16 ep_wMaxPacketSize;
ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize);
if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_CONTROL) {
/* Control => bidirectional */
- dev->epmaxpacketout[b] = ep->wMaxPacketSize;
- dev->epmaxpacketin[b] = ep->wMaxPacketSize;
+ dev->epmaxpacketout[b] = ep_wMaxPacketSize;
+ dev->epmaxpacketin[b] = ep_wMaxPacketSize;
USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n",
b, dev->epmaxpacketin[b]);
} else {
if ((ep->bEndpointAddress & 0x80) == 0) {
/* OUT Endpoint */
- if (ep->wMaxPacketSize > dev->epmaxpacketout[b]) {
- dev->epmaxpacketout[b] = ep->wMaxPacketSize;
+ if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) {
+ dev->epmaxpacketout[b] = ep_wMaxPacketSize;
USB_PRINTF("##EP epmaxpacketout[%d] = %d\n",
b, dev->epmaxpacketout[b]);
}
} else {
/* IN Endpoint */
- if (ep->wMaxPacketSize > dev->epmaxpacketin[b]) {
- dev->epmaxpacketin[b] = ep->wMaxPacketSize;
+ if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) {
+ dev->epmaxpacketin[b] = ep_wMaxPacketSize;
USB_PRINTF("##EP epmaxpacketin[%d] = %d\n",
b, dev->epmaxpacketin[b]);
}
@@ -333,6 +336,7 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
struct usb_descriptor_header *head;
int index, ifno, epno, curr_if_num;
int i;
+ u16 ep_wMaxPacketSize;
ifno = -1;
epno = -1;
@@ -378,8 +382,15 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
dev->config.if_desc[ifno].no_of_ep++;
memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
&buffer[index], buffer[index]);
- le16_to_cpus(&(dev->config.if_desc[ifno].ep_desc[epno].\
- wMaxPacketSize));
+ ep_wMaxPacketSize = get_unaligned(&dev->config.\
+ if_desc[ifno].\
+ ep_desc[epno].\
+ wMaxPacketSize);
+ put_unaligned(le16_to_cpu(ep_wMaxPacketSize),
+ &dev->config.\
+ if_desc[ifno].\
+ ep_desc[epno].\
+ wMaxPacketSize);
USB_PRINTF("if %d, ep %d\n", ifno, epno);
break;
default: