diff options
author | Tom Rini <trini@ti.com> | 2011-12-15 08:40:51 -0700 |
---|---|---|
committer | Remy Bohmer <linux@bohmer.net> | 2011-12-16 21:37:17 +0100 |
commit | b2fb47f1873ae812ce33129996a22b11a36d0aa9 (patch) | |
tree | 8afeef2bce3d0ca0aa44ed59956086f6dae2767c /drivers/usb | |
parent | ddc7e541ae62f29d85b35cdf8d12c7322d353d51 (diff) | |
download | u-boot-imx-b2fb47f1873ae812ce33129996a22b11a36d0aa9.zip u-boot-imx-b2fb47f1873ae812ce33129996a22b11a36d0aa9.tar.gz u-boot-imx-b2fb47f1873ae812ce33129996a22b11a36d0aa9.tar.bz2 |
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 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/epautoconf.c | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/s3c_udc_otg.c | 10 |
2 files changed, 11 insertions, 7 deletions
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 1896489..5b8776e 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -25,6 +25,7 @@ #include <linux/usb/ch9.h> #include <asm/errno.h> #include <linux/usb/gadget.h> +#include <asm/unaligned.h> #include "gadget_chips.h" #define isdigit(c) ('0' <= (c) && (c) <= '9') @@ -127,7 +128,7 @@ static int ep_matches( * where it's an output parameter representing the full speed limit. * the usb spec fixes high speed bulk maxpacket at 512 bytes. */ - max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize); + max = 0x7ff & le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)); switch (type) { case USB_ENDPOINT_XFER_INT: /* INT: limit 64 bytes full speed, 1024 high speed */ @@ -143,7 +144,8 @@ static int ep_matches( return 0; /* BOTH: "high bandwidth" works only at high speed */ - if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) { + if ((get_unaligned(&desc->wMaxPacketSize) & + __constant_cpu_to_le16(3<<11))) { if (!gadget->is_dualspeed) return 0; /* configure your hardware with enough buffering!! */ @@ -176,7 +178,7 @@ static int ep_matches( /* min() doesn't work on bitfields with gcc-3.5 */ if (size > 64) size = 64; - desc->wMaxPacketSize = cpu_to_le16(size); + put_unaligned(cpu_to_le16(size), &desc->wMaxPacketSize); } return 1; } diff --git a/drivers/usb/gadget/s3c_udc_otg.c b/drivers/usb/gadget/s3c_udc_otg.c index 5a3ac78..901fac9 100644 --- a/drivers/usb/gadget/s3c_udc_otg.c +++ b/drivers/usb/gadget/s3c_udc_otg.c @@ -40,6 +40,7 @@ #include <linux/usb/gadget.h> #include <asm/byteorder.h> +#include <asm/unaligned.h> #include <asm/io.h> #include <asm/mach-types.h> @@ -586,7 +587,8 @@ static int s3c_ep_enable(struct usb_ep *_ep, if (!_ep || !desc || ep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress - || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) { + || ep_maxpacket(ep) < + le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) { DEBUG("%s: bad ep or descriptor\n", __func__); return -EINVAL; @@ -603,8 +605,8 @@ static int s3c_ep_enable(struct usb_ep *_ep, /* hardware _could_ do smaller, but driver doesn't */ if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK - && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep)) - || !desc->wMaxPacketSize) { + && le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)) != + ep_maxpacket(ep)) || !get_unaligned(&desc->wMaxPacketSize)) { DEBUG("%s: bad %s maxpacket\n", __func__, _ep->name); return -ERANGE; @@ -620,7 +622,7 @@ static int s3c_ep_enable(struct usb_ep *_ep, ep->stopped = 0; ep->desc = desc; ep->pio_irqs = 0; - ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)); /* Reset halt state */ s3c_udc_set_nak(ep); |