RFC/patch 4/6: usb: stablish a per-host default device authorization state
Inaky Perez-Gonzalez <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Organization | Intel Corporation |
| Message-ID | <[email protected]> |
# HG changeset patch # User Inaky Perez-Gonzalez <[email protected]> # Date 1177452551 25200 # Node ID a1f71724f48c863b6b84d2bc56d9035edc8284bc # Parent 4a813201f50ac479b26852a2591588e2260e7a9d usb: stablish a per-host default device authorization state By poking in /sys/class/uwb_host/X/authorize_default, we can set that by default all devices connected to the host controller need to be authorized first (or not). By default, wired USB controllers authorize all devices, WUSB don't. Used this change to clean up the error paths in usb_add_hcd(). diff -r 4a813201f50a -r a1f71724f48c drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Tue Apr 24 15:07:10 2007 -0700 +++ b/drivers/usb/core/hcd.c Tue Apr 24 15:09:11 2007 -0700 @@ -663,6 +663,57 @@ static int usb_rh_urb_dequeue (struct us return 0; } + + +/* + * Show & store the current value of authorized_default + */ +static +ssize_t usb_host_authorized_default_show(struct class_device *dev, char *buf) +{ + struct usb_bus *usb_bus = class_get_devdata(dev); + struct usb_hcd *usb_hcd = container_of(usb_bus, struct usb_hcd, self); + return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); +} + +static +ssize_t usb_host_authorized_default_store(struct class_device *dev, + const char *buf, size_t size) +{ + ssize_t result; + struct usb_bus *usb_bus = class_get_devdata(dev); + struct usb_hcd *usb_hcd = container_of(usb_bus, struct usb_hcd, self); + unsigned val; + result = sscanf(buf, "%u\n", &val); + if (result == 1) { + usb_hcd->authorized_default = val? 1 : 0; + result = size; + } + else + result = -EINVAL; + return result; +} + +CLASS_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[] = { + &class_device_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; @@ -716,28 +767,30 @@ static void usb_bus_init (struct usb_bus */ static int usb_register_bus(struct usb_bus *bus) { + int result = -E2BIG; int busnum; mutex_lock(&usb_bus_list_lock); busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); - if (busnum < USB_MAXBUS) { - set_bit (busnum, busmap.busmap); - bus->busnum = busnum; - } else { + if (busnum >= USB_MAXBUS) { printk (KERN_ERR "%s: too many buses\n", usbcore_name); - mutex_unlock(&usb_bus_list_lock); - return -E2BIG; - } - + goto error_find_busnum; + } + set_bit (busnum, busmap.busmap); + bus->busnum = busnum; bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0), - bus->controller, "usb_host%d", busnum); - if (IS_ERR(bus->class_dev)) { - clear_bit(busnum, busmap.busmap); - mutex_unlock(&usb_bus_list_lock); - return PTR_ERR(bus->class_dev); - } - + bus->controller, "usb_host%d", + busnum); + result = PTR_ERR(bus->class_dev); + if (IS_ERR(bus->class_dev)) + goto error_create_class_dev; class_set_devdata(bus->class_dev, bus); + result = sysfs_create_group(&bus->class_dev->kobj, &usb_bus_attr_group); + if (result < 0) { + printk(KERN_ERR "Cannot register USB bus attributes: %d\n", + result); + goto error_create_attr_group; + } /* Add it to the local list of buses */ list_add (&bus->bus_list, &usb_bus_list); @@ -745,8 +798,17 @@ static int usb_register_bus(struct usb_b usb_notify_add_bus(bus); - dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); + dev_info (bus->controller, "new USB bus registered, assigned bus " + "number %d\n", bus->busnum); return 0; + +error_create_attr_group: + class_device_unregister(bus->class_dev); +error_create_class_dev: + clear_bit(busnum, busmap.busmap); +error_find_busnum: + mutex_unlock(&usb_bus_list_lock); + return result; } /** @@ -774,6 +836,7 @@ static void usb_deregister_bus (struct u clear_bit (bus->busnum, busmap.busmap); + sysfs_remove_group(&bus->class_dev->kobj, &usb_bus_attr_group); class_device_unregister(bus->class_dev); } @@ -1504,7 +1567,7 @@ struct usb_hcd *usb_create_hcd (const st hcd->driver = driver; hcd->product_desc = (driver->product_desc) ? driver->product_desc : "USB Host Controller"; - + hcd->authorized_default = hcd->wireless? 0 : 1; return hcd; } EXPORT_SYMBOL (usb_create_hcd); diff -r 4a813201f50a -r a1f71724f48c drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Tue Apr 24 15:07:10 2007 -0700 +++ b/drivers/usb/core/hcd.h Tue Apr 24 15:09:11 2007 -0700 @@ -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. */ /*-------------------------------------------------------------------------*/ @@ -87,7 +93,8 @@ 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 */ u64 rsrc_start; /* memory/io resource start */ diff -r 4a813201f50a -r a1f71724f48c drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Tue Apr 24 15:07:10 2007 -0700 +++ b/drivers/usb/core/usb.c Tue Apr 24 15:09:11 2007 -0700 @@ -264,6 +264,7 @@ usb_alloc_dev(struct usb_device *parent, usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) { struct usb_device *dev; + struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) @@ -328,12 +329,12 @@ usb_alloc_dev(struct usb_device *parent, INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); dev->autosuspend_delay = usb_autosuspend_delay * HZ; #endif - if (usb_bus_is_wusb(bus)) { /* If WUSB, will default to NOT auth */ - dev->authorized = 0; + if (usb_bus_is_wusb(bus)) { + dev->authorized = usb_hcd->authorized_default; dev->wusb = 1; } else { - dev->authorized = 1; + dev->authorized = usb_hcd->authorized_default; dev->wusb = 0; } return dev; ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ [email protected] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel