static int do_detect(int argc, char *argv[]) { struct device_d *dev; int opt, i, ret; int option_list = 0; int option_error = 0; int option_all = 0; while ((opt = getopt(argc, argv, "ela")) > 0) { switch (opt) { case 'l': option_list = 1; break; case 'e': option_error = 1; break; case 'a': option_all = 1; break; default: return COMMAND_ERROR_USAGE; } } if (option_list) { for_each_device(dev) { if (dev->detect) printf("%s\n", dev_name(dev)); } return 0; } if (option_all) { for_each_device(dev) { ret = device_detect(dev); if (ret && ret != -ENOSYS && option_error) return ret; } return 0; } if (argc == optind) return COMMAND_ERROR_USAGE; for (i = optind; i < argc; i++) { dev = get_device_by_name(argv[i]); if (!dev) return -ENODEV; ret = device_detect(dev); if (ret && option_error) return ret; } return 0; }
static int usb_hub_detect(struct device_d *dev) { struct usb_device *usbdev = container_of(dev, struct usb_device, dev); int i; usb_hub_configure_ports(usbdev); for (i = 0; i < usbdev->maxchild; i++) { if (usbdev->children[i]) device_detect(&usbdev->children[i]->dev); } return 0; }
/** * of_find_path - translate a path description in the devicetree to a barebox * path * * @node: the node containing the property with the path description * @propname: the property name of the path description * @outpath: if this function returns 0 outpath will contain the path belonging * to the input path description. Must be freed with free(). * * pathes in the devicetree have the form of a multistring property. The first * string contains the full path to the physical device containing the path. * The remaining strings have the form "<type>:<options>". Currently supported * for <type> are: * * partname:<partname> - find a partition by its partition name. For mtd * partitions this is the label. For DOS partitions * this is the number beginning with 0. * * examples: * * device-path = &mmc0, "partname:0"; * device-path = &norflash, "partname:barebox-environment"; */ int of_find_path(struct device_node *node, const char *propname, char **outpath) { struct of_path op = {}; struct device_node *rnode; const char *path, *str; int i, len, ret; path = of_get_property(node, propname, &len); if (!path) return -EINVAL; rnode = of_find_node_by_path(path); if (!rnode) return -ENODEV; op.dev = of_find_device_by_node_path(rnode->full_name); if (!op.dev) return -ENODEV; device_detect(op.dev); i = 1; while (1) { ret = of_property_read_string_index(node, propname, i++, &str); if (ret) break; ret = of_path_parse_one(&op, str); if (ret) return ret; } if (!op.cdev) return -ENOENT; *outpath = asprintf("/dev/%s", op.cdev->name); return 0; }
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); }