Esempio n. 1
0
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;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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);
}