#include <asm/4xx_pci.h>
#endif
-#undef USB_DEBUG
-
-#ifdef USB_DEBUG
-#define USB_PRINTF(fmt, args...) printf(fmt , ##args)
+#ifdef DEBUG
+#define USB_DEBUG 1
+#define USB_HUB_DEBUG 1
#else
-#define USB_PRINTF(fmt, args...)
+#define USB_DEBUG 0
+#define USB_HUB_DEBUG 0
#endif
+#define USB_PRINTF(fmt, args...) debug_cond(USB_DEBUG, fmt, ##args)
+#define USB_HUB_PRINTF(fmt, args...) debug_cond(USB_HUB_DEBUG, fmt, ##args)
+
#define USB_BUFSIZ 512
static struct usb_device usb_dev[USB_MAX_DEVICE];
/*
* disables the asynch behaviour of the control message. This is used for data
* transfers that uses the exclusiv access to the control and bulk messages.
+ * Returns the old value so it can be restored later.
*/
-void usb_disable_asynch(int disable)
+int usb_disable_asynch(int disable)
{
+ int old_value = asynch_allowed;
+
asynch_allowed = !disable;
+ return old_value;
}
if (timeout == 0)
return (int)size;
- if (dev->status != 0) {
- /*
- * Let's wait a while for the timeout to elapse.
- * It has no real use, but it keeps the interface happy.
- */
- wait_ms(timeout);
- return -1;
+ /*
+ * Wait for status to update until timeout expires, USB driver
+ * interrupt handler may set the status when the USB operation has
+ * been completed.
+ */
+ while (timeout--) {
+ if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
+ break;
+ wait_ms(1);
}
+ if (dev->status)
+ return -1;
return dev->act_len;
+
}
/*-------------------------------------------------------------------
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;
{
int i, ii;
- for (i = 0; i < dev->config.bNumInterfaces; i++)
- for (ii = 0; ii < dev->config.if_desc[i].bNumEndpoints; ii++)
- usb_set_maxpacket_ep(dev,
- &dev->config.if_desc[i].ep_desc[ii]);
+ 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, i, ii);
return 0;
}
struct usb_descriptor_header *head;
int index, ifno, epno, curr_if_num;
int i;
- unsigned char *ch;
ifno = -1;
epno = -1;
return -1;
}
memcpy(&dev->config, buffer, buffer[0]);
- le16_to_cpus(&(dev->config.wTotalLength));
+ le16_to_cpus(&(dev->config.desc.wTotalLength));
dev->config.no_of_if = 0;
- index = dev->config.bLength;
+ index = dev->config.desc.bLength;
/* Ok the first entry must be a configuration entry,
* now process the others */
head = (struct usb_descriptor_header *) &buffer[index];
- while (index + 1 < dev->config.wTotalLength) {
+ while (index + 1 < dev->config.desc.wTotalLength) {
switch (head->bDescriptorType) {
case USB_DT_INTERFACE:
if (((struct usb_interface_descriptor *) \
dev->config.if_desc[ifno].no_of_ep = 0;
dev->config.if_desc[ifno].num_altsetting = 1;
curr_if_num =
- dev->config.if_desc[ifno].bInterfaceNumber;
+ dev->config.if_desc[ifno].desc.bInterfaceNumber;
} else {
/* found alternate setting for the interface */
dev->config.if_desc[ifno].num_altsetting++;
head->bDescriptorType);
{
- ch = (unsigned char *)head;
+#ifdef USB_DEBUG
+ unsigned char *ch = (unsigned char *)head;
+#endif
for (i = 0; i < head->bLength; i++)
USB_PRINTF("%02X ", *ch++);
USB_PRINTF("\n\n\n");
{
int result;
unsigned int tmp;
- struct usb_config_descriptor *config;
+ struct usb_configuration_descriptor *config;
-
- config = (struct usb_config_descriptor *)&buffer[0];
+ config = (struct usb_configuration_descriptor *)&buffer[0];
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
if (result < 9) {
if (result < 0)
*/
int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
- struct usb_interface_descriptor *if_face = NULL;
+ struct usb_interface *if_face = NULL;
int ret, i;
- for (i = 0; i < dev->config.bNumInterfaces; i++) {
- if (dev->config.if_desc[i].bInterfaceNumber == interface) {
+ for (i = 0; i < dev->config.desc.bNumInterfaces; i++) {
+ if (dev->config.if_desc[i].desc.bInterfaceNumber == interface) {
if_face = &dev->config.if_desc[i];
break;
}
usb_parse_config(dev, &tmpbuf[0], 0);
usb_set_maxpacket(dev);
/* we set the default configuration here */
- if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {
+ if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
printf("failed to set default configuration " \
"len %d, status %lX\n", dev->act_len, dev->status);
return -1;
/* insert "driver" if possible */
#ifdef CONFIG_USB_KEYBOARD
drv_usb_kbd_init();
- USB_PRINTF("scan end\n");
#endif
+ USB_PRINTF("scan end\n");
}
* Probes device for being a hub and configurate it
*/
-#undef USB_HUB_DEBUG
-
-#ifdef USB_HUB_DEBUG
-#define USB_HUB_PRINTF(fmt, args...) printf(fmt , ##args)
-#else
-#define USB_HUB_PRINTF(fmt, args...)
-#endif
-
-
static struct usb_hub_device hub_dev[USB_MAX_HUB];
static int usb_hub_index;
{
struct usb_device *usb;
struct usb_port_status portsts;
- unsigned short portstatus, portchange;
+ unsigned short portstatus;
/* Check status */
if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
}
portstatus = le16_to_cpu(portsts.wPortStatus);
- portchange = le16_to_cpu(portsts.wPortChange);
USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
- portstatus, portchange, portspeed(portstatus));
+ portstatus,
+ le16_to_cpu(portsts.wPortChange),
+ portspeed(portstatus));
/* Clear the connection change status */
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
dev->children[port] = usb;
usb->parent = dev;
+ usb->portnr = port + 1;
/* Run it through the hoops (find a driver, etc) */
if (usb_new_device(usb)) {
/* Woops, disable the port */
int usb_hub_configure(struct usb_device *dev)
{
+ int i;
unsigned char buffer[USB_BUFSIZ], *bitmap;
struct usb_hub_descriptor *descriptor;
- struct usb_hub_status *hubsts;
- int i;
struct usb_hub_device *hub;
+#ifdef USB_HUB_DEBUG
+ struct usb_hub_status *hubsts;
+#endif
/* "allocate" Hub device */
hub = usb_hub_allocate();
hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];
for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
- hub->desc.DeviceRemovable[i] = descriptor->PortPowerCtrlMask[i];
+ hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
dev->maxchild = descriptor->bNbrPorts;
USB_HUB_PRINTF("%d ports detected\n", dev->maxchild);
return -1;
}
+#ifdef USB_HUB_DEBUG
hubsts = (struct usb_hub_status *)buffer;
+#endif
USB_HUB_PRINTF("get_hub_status returned status %X, change %X\n",
le16_to_cpu(hubsts->wHubStatus),
le16_to_cpu(hubsts->wHubChange));
int usb_hub_probe(struct usb_device *dev, int ifnum)
{
- struct usb_interface_descriptor *iface;
+ struct usb_interface *iface;
struct usb_endpoint_descriptor *ep;
int ret;
iface = &dev->config.if_desc[ifnum];
/* Is it a hub? */
- if (iface->bInterfaceClass != USB_CLASS_HUB)
+ if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
return 0;
/* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
- if ((iface->bInterfaceSubClass != 0) &&
- (iface->bInterfaceSubClass != 1))
+ if ((iface->desc.bInterfaceSubClass != 0) &&
+ (iface->desc.bInterfaceSubClass != 1))
return 0;
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
- if (iface->bNumEndpoints != 1)
+ if (iface->desc.bNumEndpoints != 1)
return 0;
ep = &iface->ep_desc[0];
/* Output endpoint? Curiousier and curiousier.. */