USB: descriptor handling
authorStefan Althoefer <stefan.althoefer@web.de>
Sun, 7 Dec 2008 18:39:11 +0000 (19:39 +0100)
committerRemy Böhmer <linux@bohmer.net>
Tue, 9 Dec 2008 20:26:45 +0000 (21:26 +0100)
Hi,

I found a bug when working with the u-boot USB subsystem on IXP425 processor
(big endian Xscale aka ARMv5).
I recognized that the second usb_endpoint_descriptor of the attached memory
stick was corrupted.

The reason for this are the packed structures below (either u-boot and
u-boot-usb):

--------------
/* Endpoint descriptor */
struct usb_endpoint_descriptor {
unsigned char  bLength;
unsigned char  bDescriptorType;
unsigned char  bEndpointAddress;
unsigned char  bmAttributes;
unsigned short wMaxPacketSize;
unsigned char  bInterval;
unsigned char  bRefresh;
unsigned char  bSynchAddress;

} __attribute__ ((packed));
/* Interface descriptor */
struct usb_interface_descriptor {
unsigned char  bLength;
unsigned char  bDescriptorType;
unsigned char  bInterfaceNumber;
unsigned char  bAlternateSetting;
unsigned char  bNumEndpoints;
unsigned char  bInterfaceClass;
unsigned char  bInterfaceSubClass;
unsigned char  bInterfaceProtocol;
unsigned char  iInterface;

unsigned char  no_of_ep;
unsigned char  num_altsetting;
unsigned char  act_altsetting;
struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
} __attribute__ ((packed));
------------

As usb_endpoint_descriptor is only 7byte in length, the start of all
odd ep_desc[] structures is not word aligned. This makes wMaxPacketSize
of these structures also not word aligned.

ARMv5 Architecture however does not support non-aligned multibyte
data type (see A2.8 of ARM Architecture Reference Manual).

Signed-off-by: Stefan Althoefer <stefan.althoefer@web.de>
Signed-off-by: Remy Böhmer <linux@bohmer.net>
include/usb.h

index 84a77b2f8ba155217b724b61e8b80626c943c594..510df95d628e887fc49eaf3b9c58367f254e43e0 100644 (file)
@@ -91,7 +91,7 @@ struct usb_endpoint_descriptor {
        unsigned char   bInterval;
        unsigned char   bRefresh;
        unsigned char   bSynchAddress;
-} __attribute__ ((packed));
+} __attribute__ ((packed)) __attribute__ ((aligned(2)));
 
 /* Interface descriptor */
 struct usb_interface_descriptor {