Skip to content

Commit

Permalink
usb: add the concept of default authorization to USB hosts
Browse files Browse the repository at this point in the history
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: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Inaky Perez-Gonzalez authored and Greg Kroah-Hartman committed Oct 12, 2007
1 parent da04b7a commit 5234ce1
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
73 changes: 72 additions & 1 deletion drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions drivers/usb/core/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/

/*-------------------------------------------------------------------------*/
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 5234ce1

Please sign in to comment.