Skip to contentSkip to conversation

GCC4.6: Fix common/usb.c on xscale

PATCH New Marek Vasut 2 participants 2 messages Nov 5, 2011 – Nov 14, 2011

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 GCC4.6: Fix common/usb.c on xscale

The problem was that the code, when the function was compiled with -Os, was misgenerated. As in the function description, this is likely another manifestation of the bug in GCC.

Cc Wolfgang Denk <[email protected]>
Cc Remy Bohmer <[email protected]>
---
 common/usb.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
common/usb.c +9 -4
index bed5116..4418c70 100644
@@ -263,18 +263,24 @@ int usb_maxpacket(struct usb_device *dev, unsigned long pipe)
 		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;
+
+	ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
 
 	b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 
@@ -313,8 +319,7 @@ int usb_set_maxpacket(struct usb_device *dev)
 
 	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;
 }
Signature · 1 line
1.7.6.3
#1 lore raw

PATCH 1/1 GCC4.6: Fix common/usb.c on xscale

Quoted 3 lines · Marek Vasut

The problem was that the code, when the function was compiled with -Os, was misgenerated. As in the function description, this is likely another manifestation of the bug in GCC.

Tested with GCC 4.6.1 and 4.3.4. This fixed problem on MX28EVK based board.

--
Veli-Pekka Peltola