int usb_init(void) { int result; void *ctrl; int i, start_index = 0; struct usb_device *dev; gpio_init_usb(1); running=0; dev_index=0; asynch_allowed=1; usb_hub_reset(); /* first make all devices unknown */ for (i = 0; i < USB_MAX_DEVICE; i++) { memset(&usb_dev[i], 0, sizeof(struct usb_device)); usb_dev[i].devnum = -1; } /* init low_level USB */ #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { /* init low_level USB */ printf("USB%d: ", i); if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl)) { puts("lowlevel init failed\n"); continue; } /* * lowlevel init is OK, now scan the bus for devices * i.e. search HUBs and configure them */ start_index = dev_index; printf("scanning bus %d for devices... ", i); dev = usb_alloc_new_device(ctrl); /* * device 0 is always present * (root hub, so let it analyze) */ if (dev) usb_new_device(dev); if (start_index == dev_index) puts("No USB Device found\n"); else printf("%d USB Device(s) found\n", dev_index - start_index); running = 1; } USB_PRINTF("scan end\n"); if (!running) { puts("USB error: all controllers failed lowlevel init\n"); return -1; } return 0; }
/*************************************************************************** * Init USB Device */ int usb_init(void) { void *ctrl; struct usb_device *dev; int i, start_index = 0; dev_index = 0; asynch_allowed = 1; usb_hub_reset(); /* first make all devices unknown */ for (i = 0; i < USB_MAX_DEVICE; i++) { memset(&usb_dev[i], 0, sizeof(struct usb_device)); usb_dev[i].devnum = -1; } /* init low_level USB */ for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { /* init low_level USB */ printf("USB%d: ", i); if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl)) { #if defined(CONFIG_OCTEON) && defined(CONFIG_OCTEON_OCX) if (i == 0) #endif puts("lowlevel init failed\n"); continue; } usb_controller_initialized[i] = true; /* * lowlevel init is OK, now scan the bus for devices * i.e. search HUBs and configure them */ start_index = dev_index; printf("scanning bus %d for devices... ", i); dev = usb_alloc_new_device(ctrl); /* * device 0 is always present * (root hub, so let it analyze) */ if (dev) usb_new_device(dev); if (start_index == dev_index) puts("No USB Device found\n"); else printf("%d USB Device(s) found\n", dev_index - start_index); usb_started = 1; } debug("scan end\n"); /* if we were not able to find at least one working bus, bail out */ if (!usb_started) { puts("USB error: all controllers failed lowlevel init\n"); return -1; } return 0; }
void usb_hub_port_connect_change(struct usb_device *dev, int port) { struct usb_device *usb; ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus; /* Check status */ if (usb_get_port_status(dev, port + 1, portsts) < 0) { USB_HUB_PRINTF("get_port_status failed\n"); return; } portstatus = le16_to_cpu(portsts->wPortStatus); USB_HUB_PRINTF("portstatus %x, change %x, %s\n", 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); /* Disconnect any existing devices under this port */ if (((!(portstatus & USB_PORT_STAT_CONNECTION)) && (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) { USB_HUB_PRINTF("usb_disconnect(&hub->children[port]);\n"); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) return; } /* Reset the port */ if (hub_port_reset(dev, port, &portstatus) < 0) { printf("cannot reset port %i!?\n", port + 1); return; } /* Allocate a new device struct for it */ usb = usb_alloc_new_device(dev->controller); if (portstatus & USB_PORT_STAT_HIGH_SPEED) usb->speed = USB_SPEED_HIGH; else if (portstatus & USB_PORT_STAT_LOW_SPEED) usb->speed = USB_SPEED_LOW; else usb->speed = USB_SPEED_FULL; 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 */ usb_free_device(); dev->children[port] = NULL; USB_HUB_PRINTF("hub: disabling port %d\n", port + 1); usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE); } }
/* * test_find_usbdev * using our driver, attempt to find * a usb device that our driver can use, * and set the pointers in our test interface * structure to the device pointer so that * it can be used future test calls */ static int test_find_usbdev() { struct usb_device *udev = (struct usb_device *)kmalloc(sizeof(struct usb_device), GFP_KERNEL); struct usb_bus *bus = (struct usb_bus *)kmalloc(sizeof(struct usb_bus), GFP_KERNEL); /* Zero out the ltp_usb */ memset(<p_usb, 0, sizeof(tusb_user_t)); ltp_usb.bus = bus; ltp_usb.dev = udev; /* allocate the usb_bus pointer */ #if 0 bus = usb_alloc_bus(&test_device_operations); if (!bus) { printk("tusb: Did not allocate a bus\n"); return 1; } else { printk("tusb: Allocated a bus pointer\n"); memcpy(ltp_usb.bus, bus, sizeof(struct usb_bus)); printk("test1\n"); } /* allocate the usb_device pointer */ udev = usb_alloc_dev(NULL, bus); if (udev) { printk("tusb: Found a usb device pointer\n"); memcpy(ltp_usb.dev, udev, sizeof(struct usb_device)); } else { printk("tusb: Failed find usb device pointer\n"); return 1; } /* connect the new device and setup pointers */ usb_connect(udev); usb_new_device(udev); #endif return 0; }
/*************************************************************************** * Function Name : rh_connect_rh * * This function connect the virtual root hub to the USB stack * * Input: urb = USB request block * * Return: 0 **************************************************************************/ static int rh_connect_rh (hci_t * hci) { struct usb_device *usb_dev; hci->rh.devnum = 0; usb_dev = usb_alloc_dev (NULL, hci->bus, 0); if (!usb_dev) return -ENOMEM; hci->bus->root_hub = usb_dev; usb_dev->devnum = 1; usb_dev->bus->devnum_next = usb_dev->devnum + 1; set_bit (usb_dev->devnum, usb_dev->bus->devmap.devicemap); if (usb_new_device (usb_dev) != 0) { usb_put_dev (usb_dev); return -ENODEV; } return 0; }
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, u16 portstatus, u16 portchange) { struct usb_device *hub = hubstate->dev; struct usb_device *dev; unsigned int delay = HUB_SHORT_RESET_TIME; int i; char *portstr, *tempstr; DBG_HOST_HUB("### >>> Enter hub.c file --> usb_hub_port_connect_change function \n"); dbg("port %d, portstatus %x, change %x, %s", port + 1, portstatus, portchange, portspeed (portstatus)); /* Clear the connection change status */ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION); /* Disconnect any existing devices under this port */ if (hub->children[port]) usb_disconnect(&hub->children[port]); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { if (portstatus & USB_PORT_STAT_ENABLE) usb_hub_port_disable(hub, port); return; } if (usb_hub_port_debounce(hub, port)) { err("connect-debounce failed, port %d disabled", port+1); usb_hub_port_disable(hub, port); return; } down(&usb_address0_sem); tempstr = kmalloc(1024, GFP_KERNEL); portstr = kmalloc(1024, GFP_KERNEL); for (i = 0; i < HUB_PROBE_TRIES; i++) { struct usb_device *pdev, *cdev; /* Allocate a new device struct */ dev = usb_alloc_dev(hub, hub->bus); if (!dev) { err("couldn't allocate usb_device"); break; } hub->children[port] = dev; /* Reset the device */ if (usb_hub_port_reset(hub, port, dev, delay)) { usb_free_dev(dev); break; } /* Find a new device ID for it */ usb_connect(dev); /* Set up TT records, if needed */ if (hub->tt) { dev->tt = hub->tt; dev->ttport = hub->ttport; } else if (dev->speed != USB_SPEED_HIGH && hub->speed == USB_SPEED_HIGH) { dev->tt = &hubstate->tt; dev->ttport = port + 1; } /* Create a readable topology string */ cdev = dev; pdev = dev->parent; if (portstr && tempstr) { portstr[0] = 0; while (pdev) { int port; for (port = 0; port < pdev->maxchild; port++) if (pdev->children[port] == cdev) break; strcpy(tempstr, portstr); if (!strlen(tempstr)) sprintf(portstr, "%d", port + 1); else sprintf(portstr, "%d/%s", port + 1, tempstr); cdev = pdev; pdev = pdev->parent; } info("USB new device connect on bus%d/%s, assigned device number %d", dev->bus->busnum, portstr, dev->devnum); } else info("USB new device connect on bus%d, assigned device number %d", dev->bus->busnum, dev->devnum); /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev)) goto done; /* Free the configuration if there was an error */ usb_free_dev(dev); /* Switch to a long reset time */ delay = HUB_LONG_RESET_TIME; } hub->children[port] = NULL; usb_hub_port_disable(hub, port); done: up(&usb_address0_sem); if (portstr) kfree(portstr); if (tempstr) kfree(tempstr); }
static void usb_hub_port_connect_change(struct usb_device *hub, int port, struct usb_port_status *portsts) { struct usb_device *dev; unsigned short portstatus, portchange; unsigned int delay = HUB_SHORT_RESET_TIME; int i; char *portstr, *tempstr; int devnum; portstatus = le16_to_cpu(portsts->wPortStatus); portchange = le16_to_cpu(portsts->wPortChange); dbg("port %d, portstatus %x, change %x, %s", port + 1, portstatus, portchange, portspeed (portstatus)); /* Clear the connection change status */ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION); /* Disconnect any existing devices under this port */ down(&hub->bus->dev_tree_sem); if (hub->children[port]) usb_disconnect(&hub->children[port]); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { if (portstatus & USB_PORT_STAT_ENABLE) usb_hub_port_disable(hub, port); up(&hub->bus->dev_tree_sem); return; } up(&hub->bus->dev_tree_sem); /* Some low speed devices have problems with the quick delay, so */ /* be a bit pessimistic with those devices. RHbug #23670 */ if (portstatus & USB_PORT_STAT_LOW_SPEED) { wait_ms(400); delay = HUB_LONG_RESET_TIME; } down(&usb_address0_sem); down(&hub->bus->dev_tree_sem); tempstr = kmalloc(1024, GFP_KERNEL); portstr = kmalloc(1024, GFP_KERNEL); for (i = 0; i < HUB_PROBE_TRIES; i++) { struct usb_device *pdev, *cdev; /* Allocate a new device struct */ dev = usb_alloc_dev(hub, hub->bus); if (!dev) { err("couldn't allocate usb_device"); break; } hub->children[port] = dev; /* Reset the device */ if (usb_hub_port_reset(hub, port, dev, delay)) { usb_free_dev(dev); break; } /* Find a new device ID for it */ usb_connect(dev); /* Create a readable topology string */ cdev = dev; pdev = dev->parent; if (portstr && tempstr) { portstr[0] = 0; while (pdev) { int port; for (port = 0; port < pdev->maxchild; port++) if (pdev->children[port] == cdev) break; strcpy(tempstr, portstr); if (!strlen(tempstr)) sprintf(portstr, "%d", port + 1); else sprintf(portstr, "%d/%s", port + 1, tempstr); cdev = pdev; pdev = pdev->parent; } info("USB new device connect on bus%d/%s, assigned device number %d", dev->bus->busnum, portstr, dev->devnum); } else info("USB new device connect on bus%d, assigned device number %d", dev->bus->busnum, dev->devnum); devnum = dev->devnum; /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev)) goto done; /* Free the configuration if there was an error */ usb_free_dev(dev); /* Switch to a long reset time */ delay = HUB_LONG_RESET_TIME; } err("failed adding a new device. Address=%d",devnum); hub->children[port] = NULL; usb_hub_port_disable(hub, port); done: up(&hub->bus->dev_tree_sem); up(&usb_address0_sem); if (portstr) kfree(portstr); if (tempstr) kfree(tempstr); }
/*************************************************************************** * Init USB Device */ int usb_init(void) { void *ctrl; struct usb_device *dev; int i, start_index = 0; int controllers_initialized = 0; int ret; dev_index = 0; asynch_allowed = 1; usb_hub_reset(); /* first make all devices unknown */ for (i = 0; i < USB_MAX_DEVICE; i++) { memset(&usb_dev[i], 0, sizeof(struct usb_device)); usb_dev[i].devnum = -1; } /* init low_level USB */ for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { /* init low_level USB */ printf("USB%d: ", i); ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl); if (ret == -ENODEV) { /* No such device. */ puts("Port not available.\n"); controllers_initialized++; continue; } if (ret) { /* Other error. */ puts("lowlevel init failed\n"); continue; } /* * lowlevel init is OK, now scan the bus for devices * i.e. search HUBs and configure them */ controllers_initialized++; start_index = dev_index; printf("scanning bus %d for devices... ", i); ret = usb_alloc_new_device(ctrl, &dev); if (ret) break; /* * device 0 is always present * (root hub, so let it analyze) */ ret = usb_new_device(dev); if (ret) usb_free_device(dev->controller); if (start_index == dev_index) { puts("No USB Device found\n"); continue; } else { printf("%d USB Device(s) found\n", dev_index - start_index); } usb_started = 1; } debug("scan end\n"); /* if we were not able to find at least one working bus, bail out */ if (controllers_initialized == 0) puts("USB error: all controllers failed lowlevel init\n"); return usb_started ? 0 : -ENODEV; }
int usb_hub_port_connect_change(struct usb_device *dev, int port) { ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus; int ret, speed; /* Check status */ ret = usb_get_port_status(dev, port + 1, portsts); if (ret < 0) { debug("get_port_status failed\n"); return ret; } portstatus = le16_to_cpu(portsts->wPortStatus); debug("portstatus %x, change %x, %s\n", 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); /* Disconnect any existing devices under this port */ if (((!(portstatus & USB_PORT_STAT_CONNECTION)) && (!(portstatus & USB_PORT_STAT_ENABLE))) || usb_device_has_child_on_port(dev, port)) { debug("usb_disconnect(&hub->children[port]);\n"); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) return -ENOTCONN; } mdelay(200); /* Reset the port */ ret = legacy_hub_port_reset(dev, port, &portstatus); if (ret < 0) { if (ret != -ENXIO) printf("cannot reset port %i!?\n", port + 1); return ret; } mdelay(200); switch (portstatus & USB_PORT_STAT_SPEED_MASK) { case USB_PORT_STAT_SUPER_SPEED: speed = USB_SPEED_SUPER; break; case USB_PORT_STAT_HIGH_SPEED: speed = USB_SPEED_HIGH; break; case USB_PORT_STAT_LOW_SPEED: speed = USB_SPEED_LOW; break; default: speed = USB_SPEED_FULL; break; } #ifdef CONFIG_DM_USB struct udevice *child; ret = usb_scan_device(dev->dev, port + 1, speed, &child); #else struct usb_device *usb; ret = usb_alloc_new_device(dev->controller, &usb); if (ret) { printf("cannot create new device: ret=%d", ret); return ret; } dev->children[port] = usb; usb->speed = speed; usb->parent = dev; usb->portnr = port + 1; /* Run it through the hoops (find a driver, etc) */ ret = usb_new_device(usb); if (ret < 0) { /* Woops, disable the port */ usb_free_device(dev->controller); dev->children[port] = NULL; } #endif if (ret < 0) { debug("hub: disabling port %d\n", port + 1); usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE); } return ret; }
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, u16 portstatus, u16 portchange) { struct usb_device *hub = hubstate->dev; struct usb_device *dev; unsigned int delay = HUB_SHORT_RESET_TIME; int i; dbg("port %d, portstatus %x, change %x, %s", port + 1, portstatus, portchange, portspeed (portstatus)); /* Clear the connection change status */ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION); /* Disconnect any existing devices under this port */ if (hub->children[port]) usb_disconnect(&hub->children[port]); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { if (portstatus & USB_PORT_STAT_ENABLE) usb_hub_port_disable(hub, port); return; } if (usb_hub_port_debounce(hub, port)) { err("connect-debounce failed, port %d disabled", port+1); usb_hub_port_disable(hub, port); return; } down(&usb_address0_sem); for (i = 0; i < HUB_PROBE_TRIES; i++) { struct usb_device *pdev; int len; /* Allocate a new device struct */ dev = usb_alloc_dev(hub, hub->bus); if (!dev) { err("couldn't allocate usb_device"); break; } /* Reset the device */ if (usb_hub_port_reset(hub, port, dev, delay)) { usb_free_dev(dev); break; } /* Find a new device ID for it */ usb_connect(dev); /* Set up TT records, if needed */ if (hub->tt) { dev->tt = hub->tt; dev->ttport = hub->ttport; } else if (dev->speed != USB_SPEED_HIGH && hub->speed == USB_SPEED_HIGH) { dev->tt = &hubstate->tt; dev->ttport = port + 1; } /* Save readable and stable topology id, distinguishing * devices by location for diagnostics, tools, etc. The * string is a path along hub ports, from the root. Each * device's id will be stable until USB is re-cabled, and * hubs are often labeled with these port numbers. * * Initial size: ".NN" times five hubs + NUL = 16 bytes max * (quite rare, since most hubs have 4-6 ports). */ pdev = dev->parent; if (pdev->devpath [0] != '0') /* parent not root? */ len = snprintf (dev->devpath, sizeof dev->devpath, "%s.%d", pdev->devpath, port + 1); /* root == "0", root port 2 == "2", port 3 that hub "2.3" */ else len = snprintf (dev->devpath, sizeof dev->devpath, "%d", port + 1); if (len == sizeof dev->devpath) warn ("devpath size! usb/%03d/%03d path %s", dev->bus->busnum, dev->devnum, dev->devpath); USB_SET_LED(USB_CONNECT); //2005-02-24 by kanki for USB LED info("new USB device %s-%s, assigned address %d", dev->bus->bus_name, dev->devpath, dev->devnum); /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev)) { hub->children[port] = dev; goto done; } /* Free the configuration if there was an error */ usb_free_dev(dev); /* Switch to a long reset time */ delay = HUB_LONG_RESET_TIME; } usb_hub_port_disable(hub, port); done: up(&usb_address0_sem); }
static void usb_hub_port_connect_change(struct usb_device *dev, int port) { struct usb_device *usb; struct usb_port_status portsts; unsigned short portstatus, portchange; /* Check status */ if (usb_get_port_status(dev, port + 1, &portsts) < 0) { dev_dbg(&dev->dev, "get_port_status failed\n"); return; } portstatus = le16_to_cpu(portsts.wPortStatus); portchange = le16_to_cpu(portsts.wPortChange); dev_dbg(&dev->dev, "portstatus %x, change %x, %s\n", portstatus, portchange, portspeed(portstatus)); /* Clear the connection change status */ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION); /* Disconnect any existing devices under this port */ if (dev->children[port] && !(portstatus & USB_PORT_STAT_CONNECTION)) { dev_dbg(&dev->dev, "disconnect detected on port %d\n", port + 1); usb_remove_device(dev->children[port]); if (!dev->parent && dev->host->usbphy) usb_phy_notify_disconnect(dev->host->usbphy, dev->speed); return; } /* Remove disabled but connected devices */ if (dev->children[port] && !(portstatus & USB_PORT_STAT_ENABLE)) usb_remove_device(dev->children[port]); mdelay(200); /* Reset the port */ if (hub_port_reset(dev, port, &portstatus) < 0) { dev_warn(&dev->dev, "cannot reset port %i!?\n", port + 1); return; } mdelay(200); /* Allocate a new device struct for it */ usb = usb_alloc_new_device(); usb->dev.parent = &dev->dev; usb->host = dev->host; if (portstatus & USB_PORT_STAT_HIGH_SPEED) usb->speed = USB_SPEED_HIGH; else if (portstatus & USB_PORT_STAT_LOW_SPEED) usb->speed = USB_SPEED_LOW; else usb->speed = USB_SPEED_FULL; 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 */ dev_dbg(&dev->dev, "hub: disabling port %d\n", port + 1); usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE); usb_free_device(usb); return; } if (!dev->parent && dev->host->usbphy) usb_phy_notify_connect(dev->host->usbphy, usb->speed); device_detect(&usb->dev); }
static void hub_port_connect_change(struct usb_hub *hubstate, int port, u16 portstatus, u16 portchange) { struct usb_device *hub = interface_to_usbdev(hubstate->intf); struct usb_device *dev; unsigned int delay = HUB_SHORT_RESET_TIME; int i; dev_dbg (&hubstate->intf->dev, "port %d, status %x, change %x, %s\n", port + 1, portstatus, portchange, portspeed (portstatus)); /* Clear the connection change status */ clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION); /* Disconnect any existing devices under this port */ if (hub->children[port]) usb_disconnect(&hub->children[port]); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { if (portstatus & USB_PORT_STAT_ENABLE) hub_port_disable(hub, port); return; } if (hub_port_debounce(hub, port)) { dev_err (&hubstate->intf->dev, "connect-debounce failed, port %d disabled\n", port+1); hub_port_disable(hub, port); return; } /* Some low speed devices have problems with the quick delay, so */ /* be a bit pessimistic with those devices. RHbug #23670 */ if (portstatus & USB_PORT_STAT_LOW_SPEED) delay = HUB_LONG_RESET_TIME; down(&usb_address0_sem); for (i = 0; i < HUB_PROBE_TRIES; i++) { struct usb_device *pdev; int len; /* Allocate a new device struct */ dev = usb_alloc_dev(hub, hub->bus); if (!dev) { dev_err (&hubstate->intf->dev, "couldn't allocate usb_device\n"); break; } hub->children[port] = dev; dev->state = USB_STATE_POWERED; /* Reset the device, and detect its speed */ if (hub_port_reset(hub, port, dev, delay)) { usb_put_dev(dev); break; } /* Find a new address for it */ usb_connect(dev); /* Set up TT records, if needed */ if (hub->tt) { dev->tt = hub->tt; dev->ttport = hub->ttport; } else if (dev->speed != USB_SPEED_HIGH && hub->speed == USB_SPEED_HIGH) { dev->tt = &hubstate->tt; dev->ttport = port + 1; } /* Save readable and stable topology id, distinguishing * devices by location for diagnostics, tools, etc. The * string is a path along hub ports, from the root. Each * device's id will be stable until USB is re-cabled, and * hubs are often labeled with these port numbers. * * Initial size: ".NN" times five hubs + NUL = 16 bytes max * (quite rare, since most hubs have 4-6 ports). */ pdev = dev->parent; if (pdev->devpath [0] != '0') /* parent not root? */ len = snprintf (dev->devpath, sizeof dev->devpath, "%s.%d", pdev->devpath, port + 1); /* root == "0", root port 2 == "2", port 3 that hub "2.3" */ else len = snprintf (dev->devpath, sizeof dev->devpath, "%d", port + 1); if (len == sizeof dev->devpath) dev_err (&hubstate->intf->dev, "devpath size! usb/%03d/%03d path %s\n", dev->bus->busnum, dev->devnum, dev->devpath); dev_info (&hubstate->intf->dev, "new USB device on port %d, assigned address %d\n", port + 1, dev->devnum); /* put the device in the global device tree. the hub port * is the "bus_id"; hubs show in hierarchy like bridges */ dev->dev.parent = dev->parent->dev.parent->parent; /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev, &hub->dev)) goto done; /* Free the configuration if there was an error */ usb_put_dev(dev); /* Switch to a long reset time */ delay = HUB_LONG_RESET_TIME; } hub->children[port] = NULL; hub_port_disable(hub, port); done: up(&usb_address0_sem); }
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, u16 portstatus, u16 portchange) { struct usb_device *hub = hubstate->dev; struct usb_device *dev; unsigned int delay = HUB_SHORT_RESET_TIME; int i; dbg("port %d, portstatus %x, change %x, %s", port + 1, portstatus, portchange, portspeed (portstatus)); /* Clear the connection change status */ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION); /* Disconnect any existing devices under this port */ if (hub->children[port]) usb_disconnect(&hub->children[port]); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { if (portstatus & USB_PORT_STAT_ENABLE) usb_hub_port_disable(hub, port); return; } if (usb_hub_port_debounce(hub, port)) { err("connect-debounce failed, port %d disabled", port+1); usb_hub_port_disable(hub, port); return; } down(&usb_address0_sem); for (i = 0; i < HUB_PROBE_TRIES; i++) { struct usb_device *pdev; int len; /* Allocate a new device struct */ dev = usb_alloc_dev(hub, hub->bus); if (!dev) { err("couldn't allocate usb_device"); break; } hub->children[port] = dev; /* add by Levis for wakeup BP */ int begin = 0; #ifdef CONFIG_ARCH_EZXBASE set_GPIO_mode(GPIO_IN | GPIO_BP_RDY); if(!GPIO_is_high(GPIO_BP_RDY)) { if(GPIO_is_high(GPIO_AP_RDY )) { GPCR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY ); udelay(WAKE_UP_BP_UDELAY); GPSR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY ); }else { GPSR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY ); udelay(WAKE_UP_BP_UDELAY); GPCR(GPIO_AP_RDY ) = GPIO_bit(GPIO_AP_RDY ); } begin = jiffies; while(!GPIO_is_high(GPIO_BP_RDY) && (jiffies < (begin+HZ))) ; if(!GPIO_is_high(GPIO_BP_RDY)) { printk("%s: Wakeup BP timeout! BP is still in sleep state!\n", __FUNCTION__); } } #else set_GPIO_mode(GPIO_IN | 41); if(GPIO_is_high(41)) { if(GPIO_is_high(GPIO_MCU_INT_SW)) GPCR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW); else { GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW); } begin = jiffies; while(GPIO_is_high(41) && (jiffies < (begin+HZ))) printk("%s: waitting for BP active!\n", __FUNCTION__); if(GPIO_is_high(GPIO_MCU_INT_SW)) GPCR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW); else { GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW); } } #endif /* end Levis */ /* Reset the device */ if (usb_hub_port_reset(hub, port, dev, delay)) { usb_free_dev(dev); break; } /* Find a new device ID for it */ usb_connect(dev); /* Set up TT records, if needed */ if (hub->tt) { dev->tt = hub->tt; dev->ttport = hub->ttport; } else if (dev->speed != USB_SPEED_HIGH && hub->speed == USB_SPEED_HIGH) { dev->tt = &hubstate->tt; dev->ttport = port + 1; } /* Save readable and stable topology id, distinguishing * devices by location for diagnostics, tools, etc. The * string is a path along hub ports, from the root. Each * device's id will be stable until USB is re-cabled, and * hubs are often labeled with these port numbers. * * Initial size: ".NN" times five hubs + NUL = 16 bytes max * (quite rare, since most hubs have 4-6 ports). */ pdev = dev->parent; if (pdev->devpath [0] != '0') /* parent not root? */ len = snprintf (dev->devpath, sizeof dev->devpath, "%s.%d", pdev->devpath, port + 1); /* root == "0", root port 2 == "2", port 3 that hub "2.3" */ else len = snprintf (dev->devpath, sizeof dev->devpath, "%d", port + 1); if (len == sizeof dev->devpath) warn ("devpath size! usb/%03d/%03d path %s", dev->bus->busnum, dev->devnum, dev->devpath); info("new USB device %s-%s, assigned address %d", dev->bus->bus_name, dev->devpath, dev->devnum); /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev)) goto done; /* Free the configuration if there was an error */ usb_free_dev(dev); /* Switch to a long reset time */ delay = HUB_LONG_RESET_TIME; } hub->children[port] = NULL; usb_hub_port_disable(hub, port); done: up(&usb_address0_sem); }