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:
27
common/usb.c
27
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:
|
||||
|
||||
Reference in New Issue
Block a user