1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-10-22 10:31:56 +02:00

USB: Use (get|put)_unaligned for accessing wMaxPacketSize

In 9792987721 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>
This commit is contained in:
Tom Rini
2011-12-15 08:40:51 -07:00
committed by Remy Bohmer
parent ddc7e541ae
commit b2fb47f187
6 changed files with 39 additions and 21 deletions

View File

@@ -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: