#include <asm/processor.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <usb.h>
#ifdef CONFIG_4xx
return dev->epmaxpacketin[((pipe>>15) & 0xf)];
}
-/* The routine usb_set_maxpacket_ep() is extracted from the loop of routine
+/*
+ * The routine usb_set_maxpacket_ep() is extracted from the loop of routine
* usb_set_maxpacket(), because the optimizer of GCC 4.x chokes on this routine
* when it is inlined in 1 single routine. What happens is that the register r3
* is used as loop-count 'i', but gets overwritten later on.
* This is clearly a compiler bug, but it is easier to workaround it here than
* to update the compiler (Occurs with at least several GCC 4.{1,2},x
* CodeSourcery compilers like e.g. 2007q3, 2008q1, 2008q3 lite editions on ARM)
+ *
+ * NOTE: Similar behaviour was observed with GCC4.6 on ARMv5.
*/
static void __attribute__((noinline))
-usb_set_maxpacket_ep(struct usb_device *dev, struct usb_endpoint_descriptor *ep)
+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]);
}
for (i = 0; i < dev->config.desc.bNumInterfaces; i++)
for (ii = 0; ii < dev->config.if_desc[i].desc.bNumEndpoints; ii++)
- usb_set_maxpacket_ep(dev,
- &dev->config.if_desc[i].ep_desc[ii]);
+ usb_set_maxpacket_ep(dev, i, ii);
return 0;
}
struct usb_descriptor_header *head;
int index, ifno, epno, curr_if_num;
int i;
+ u16 ep_wMaxPacketSize;
ifno = -1;
epno = -1;
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: