diff options
Diffstat (limited to 'drivers/usb/core/sysfs.c')
| -rw-r--r-- | drivers/usb/core/sysfs.c | 121 | 
1 files changed, 121 insertions, 0 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 7e88fdfe3cf5..f19694e69f5c 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -15,6 +15,7 @@  #include <linux/kernel.h>  #include <linux/string.h>  #include <linux/usb.h> +#include <linux/usb/hcd.h>  #include <linux/usb/quirks.h>  #include <linux/of.h>  #include "usb.h" @@ -922,6 +923,116 @@ static struct bin_attribute dev_bin_attr_descriptors = {  	.size = 18 + 65535,	/* dev descr + max-size raw descriptor */  }; +/* + * Show & store the current value of authorized_default + */ +static ssize_t 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 *hcd; + +	hcd = bus_to_hcd(usb_bus); +	return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy); +} + +static ssize_t authorized_default_store(struct device *dev, +					struct device_attribute *attr, +					const char *buf, size_t size) +{ +	ssize_t result; +	unsigned int val; +	struct usb_device *rh_usb_dev = to_usb_device(dev); +	struct usb_bus *usb_bus = rh_usb_dev->bus; +	struct usb_hcd *hcd; + +	hcd = bus_to_hcd(usb_bus); +	result = sscanf(buf, "%u\n", &val); +	if (result == 1) { +		hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ? +			val : USB_DEVICE_AUTHORIZE_ALL; +		result = size; +	} else { +		result = -EINVAL; +	} +	return result; +} +static DEVICE_ATTR_RW(authorized_default); + +/* + * interface_authorized_default_show - show default authorization status + * for USB interfaces + * + * note: interface_authorized_default is the default value + *       for initializing the authorized attribute of interfaces + */ +static ssize_t interface_authorized_default_show(struct device *dev, +		struct device_attribute *attr, char *buf) +{ +	struct usb_device *usb_dev = to_usb_device(dev); +	struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); + +	return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd)); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_authorized_default is the default value + *       for initializing the authorized attribute of interfaces + */ +static ssize_t interface_authorized_default_store(struct device *dev, +		struct device_attribute *attr, const char *buf, size_t count) +{ +	struct usb_device *usb_dev = to_usb_device(dev); +	struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); +	int rc = count; +	bool val; + +	if (strtobool(buf, &val) != 0) +		return -EINVAL; + +	if (val) +		set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); +	else +		clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); + +	return rc; +} +static DEVICE_ATTR_RW(interface_authorized_default); + +/* Group all the USB bus attributes */ +static struct attribute *usb_bus_attrs[] = { +		&dev_attr_authorized_default.attr, +		&dev_attr_interface_authorized_default.attr, +		NULL, +}; + +static const struct attribute_group usb_bus_attr_group = { +	.name = NULL,	/* we want them in the same directory */ +	.attrs = usb_bus_attrs, +}; + + +static int add_default_authorized_attributes(struct device *dev) +{ +	int rc = 0; + +	if (is_usb_device(dev)) +		rc = sysfs_create_group(&dev->kobj, &usb_bus_attr_group); + +	return rc; +} + +static void remove_default_authorized_attributes(struct device *dev) +{ +	if (is_usb_device(dev)) { +		sysfs_remove_group(&dev->kobj, &usb_bus_attr_group); +	} +} +  int usb_create_sysfs_dev_files(struct usb_device *udev)  {  	struct device *dev = &udev->dev; @@ -938,7 +1049,14 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)  	retval = add_power_attributes(dev);  	if (retval)  		goto error; + +	if (is_root_hub(udev)) { +		retval = add_default_authorized_attributes(dev); +		if (retval) +			goto error; +	}  	return retval; +  error:  	usb_remove_sysfs_dev_files(udev);  	return retval; @@ -948,6 +1066,9 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)  {  	struct device *dev = &udev->dev; +	if (is_root_hub(udev)) +		remove_default_authorized_attributes(dev); +  	remove_power_attributes(dev);  	remove_persist_attributes(dev);  	device_remove_bin_file(dev, &dev_bin_attr_descriptors);  | 
