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); }
int usb_find_devices(void) { struct usb_bus *bus; int ret, changes = 0; for (bus = usb_busses; bus; bus = bus->next) { struct usb_device *devices, *dev; /* Find all of the devices and put them into a temporary list */ ret = usb_os_find_devices(bus, &devices); if (ret < 0) return ret; /* * Now walk through all of the devices we know about and compare * against this new list. Any duplicates will be removed from the new * list. If we don't find it in the new list, the device was removed. * Any devices still in the new list, are new to us. */ dev = bus->devices; while (dev) { int found = 0; struct usb_device *ndev, *tdev = dev->next; ndev = devices; while (ndev) { struct usb_device *tndev = ndev->next; if (!strcmp(dev->filename, ndev->filename)) { /* Remove it from the new devices list */ LIST_DEL(devices, ndev); usb_free_dev(ndev); found = 1; break; } ndev = tndev; } if (!found) { /* The device was removed from the system */ LIST_DEL(bus->devices, dev); usb_free_dev(dev); changes++; } dev = tdev; } /* * Anything on the *devices list is new. So add them to bus->devices and * process them like the new device it is. */ dev = devices; while (dev) { struct usb_device *tdev = dev->next; /* * Remove it from the temporary list first and add it to the real * bus->devices list. */ LIST_DEL(devices, dev); LIST_ADD(bus->devices, dev); /* * Some ports fetch the descriptors on scanning (like Linux) so we don't * need to fetch them again. */ if (!dev->config) { usb_dev_handle *udev; udev = usb_open(dev); if (udev) { usb_fetch_and_parse_descriptors(udev); usb_close(udev); } } changes++; dev = tdev; } usb_os_determine_children(bus); } return changes; }
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_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); }