Commit 5234ce1b authored by Inaky Perez-Gonzalez's avatar Inaky Perez-Gonzalez Committed by Greg Kroah-Hartman
Browse files

usb: add the concept of default authorization to USB hosts



This introduces /sys/bus/devices/usb*/authorized_default; it dictates
what is going to be the default authorization state for devices
connected to the host. User space can set that using the sysfs file.

We hook to the root hub instead of to the device controller as it is
quite easy to get to it in sysfs from the device structure (device
5-4.3 is usb5) vs. backtracking to the controller device.

By default it is set to be 'authorized' (!0) for normal, wired USB
devices and 'unauthorized' (0) for Wireless USB devices.

As suggested by Adrian Bunk, make authorized_default static

Signed-off-by: default avatarInaky Perez-Gonzalez <inaky@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent da04b7a4
Loading
Loading
Loading
Loading
+72 −1
Original line number Diff line number Diff line
@@ -679,6 +679,66 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
	return 0;
}



/*
 * Show & store the current value of authorized_default
 */
static ssize_t usb_host_authorized_default_show(struct device *dev,
						struct device_attribute *attr,
						char *buf)
{
	struct usb_device *rh_usb_dev = to_usb_device(dev);
	struct usb_bus *usb_bus = rh_usb_dev->bus;
	struct usb_hcd *usb_hcd;

	if (usb_bus == NULL)	/* FIXME: not sure if this case is possible */
		return -ENODEV;
	usb_hcd = bus_to_hcd(usb_bus);
	return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default);
}

static ssize_t usb_host_authorized_default_store(struct device *dev,
						 struct device_attribute *attr,
						 const char *buf, size_t size)
{
	ssize_t result;
	unsigned val;
	struct usb_device *rh_usb_dev = to_usb_device(dev);
	struct usb_bus *usb_bus = rh_usb_dev->bus;
	struct usb_hcd *usb_hcd;

	if (usb_bus == NULL)	/* FIXME: not sure if this case is possible */
		return -ENODEV;
	usb_hcd = bus_to_hcd(usb_bus);
	result = sscanf(buf, "%u\n", &val);
	if (result == 1) {
		usb_hcd->authorized_default = val? 1 : 0;
		result = size;
	}
	else
		result = -EINVAL;
	return result;
}

static DEVICE_ATTR(authorized_default, 0644,
	    usb_host_authorized_default_show,
	    usb_host_authorized_default_store);


/* Group all the USB bus attributes */
static struct attribute *usb_bus_attrs[] = {
		&dev_attr_authorized_default.attr,
		NULL,
};

static struct attribute_group usb_bus_attr_group = {
	.name = NULL,	/* we want them in the same directory */
	.attrs = usb_bus_attrs,
};



/*-------------------------------------------------------------------------*/

static struct class *usb_host_class;
@@ -1542,7 +1602,6 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
	hcd->driver = driver;
	hcd->product_desc = (driver->product_desc) ? driver->product_desc :
			"USB Host Controller";

	return hcd;
}
EXPORT_SYMBOL (usb_create_hcd);
@@ -1587,6 +1646,7 @@ int usb_add_hcd(struct usb_hcd *hcd,

	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);

	hcd->authorized_default = hcd->wireless? 0 : 1;
	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

	/* HC is in reset state, but accessible.  Now do the one-time init,
@@ -1663,10 +1723,20 @@ int usb_add_hcd(struct usb_hcd *hcd,
	if ((retval = register_root_hub(hcd)) != 0)
		goto err_register_root_hub;

	retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
	if (retval < 0) {
		printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
		       retval);
		goto error_create_attr_group;
	}
	if (hcd->uses_new_polling && hcd->poll_rh)
		usb_hcd_poll_rh_status(hcd);
	return retval;

error_create_attr_group:
	mutex_lock(&usb_bus_list_lock);
	usb_disconnect(&hcd->self.root_hub);
	mutex_unlock(&usb_bus_list_lock);
err_register_root_hub:
	hcd->driver->stop(hcd);
err_hcd_driver_start:
@@ -1708,6 +1778,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
	cancel_work_sync(&hcd->wakeup_work);
#endif

	sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group);
	mutex_lock(&usb_bus_list_lock);
	usb_disconnect(&hcd->self.root_hub);
	mutex_unlock(&usb_bus_list_lock);
+7 −0
Original line number Diff line number Diff line
@@ -51,6 +51,12 @@
 *
 * Since "struct usb_bus" is so thin, you can't share much code in it.
 * This framework is a layer over that, and should be more sharable.
 *
 * @authorized_default: Specifies if new devices are authorized to
 *                      connect by default or they require explicit
 *                      user space authorization; this bit is settable
 *                      through /sys/class/usb_host/X/authorized_default.
 *                      For the rest is RO, so we don't lock to r/w it.
 */

/*-------------------------------------------------------------------------*/
@@ -90,6 +96,7 @@ struct usb_hcd {
	unsigned		poll_rh:1;	/* poll for rh status? */
	unsigned		poll_pending:1;	/* status has changed? */
	unsigned		wireless:1;	/* Wireless USB HCD */
	unsigned		authorized_default:1;

	int			irq;		/* irq allocated */
	void __iomem		*regs;		/* device memory/io */