ext [EMAIL PROTECTED] wrote: > These USB API functions will do the full authorization/deauthorization > to be used for a device. When authorized we effectively allow a > configuration to be set. Reverse that when deauthorized. > > Effectively this means that we have to clean all the configuration > descriptors on deauthorize and reload them when we authorized. We > could do without throwing them out for wired devices, but for > wireless, we can read them only after authenticating, and thus, when > authorizing an authenticated device we would need to read them. So to > simplify, always release them on deauthorize(), re-read them on > authorize(). > > Signed-off-by: Inaky Perez-Gonzalez <[EMAIL PROTECTED]> > > --- > drivers/usb/core/generic.c | 2 - > drivers/usb/core/hub.c | 76 > +++++++++++++++++++++++++++++++++++++++++++++ > drivers/usb/core/usb.h | 3 + > 3 files changed, 80 insertions(+), 1 deletion(-) > > Index: linux.hg/drivers/usb/core/generic.c > =================================================================== > --- linux.hg.orig/drivers/usb/core/generic.c 2007-07-18 10:05:49.000000000 > -0700 > +++ linux.hg/drivers/usb/core/generic.c 2007-07-18 10:05:50.000000000 > -0700 > @@ -39,7 +39,7 @@ > && desc->bInterfaceProtocol == 1; > } > > -static int choose_configuration(struct usb_device *udev) > +int choose_configuration(struct usb_device *udev) > { > int i; > int num_configs; > Index: linux.hg/drivers/usb/core/hub.c > =================================================================== > --- linux.hg.orig/drivers/usb/core/hub.c 2007-07-18 10:05:49.000000000 > -0700 > +++ linux.hg/drivers/usb/core/hub.c 2007-07-18 10:05:50.000000000 -0700 > @@ -1452,6 +1452,82 @@ > return err; > } > > + > +/** > + * Similar to usb_disconnect() > + * > + * We share a lock (that we have) with device_del(), so we need to > + * defer its call. > + */ > +int usb_deauthorize_device(struct usb_device *usb_dev) > +{ > + unsigned cnt; > + usb_lock_device(usb_dev); > + if (usb_dev->authorized == 0) > + goto out_unauthorized; > + usb_dev->authorized = 0; > + usb_set_configuration(usb_dev, -1); > + usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); > + usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); > + usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); > + kfree(usb_dev->config); > + usb_dev->config = NULL; > + usb_dev->descriptor.bNumConfigurations = 0; "usb_dev->descriptor.bNumConfigurations" is always zero here ... in the "for" > + for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++) > + kfree(usb_dev->rawdescriptors[cnt]); > + kfree(usb_dev->rawdescriptors); > +out_unauthorized: > + usb_unlock_device(usb_dev); > + return 0; > +} > + > + > +int usb_authorize_device(struct usb_device *usb_dev) > +{ > + int result = 0, c; > + usb_lock_device(usb_dev); > + if (usb_dev->authorized == 1) > + goto out_authorized; > + kfree(usb_dev->product); > + kfree(usb_dev->manufacturer); > + kfree(usb_dev->serial); > + dev_err(&usb_dev->dev, "usb_dev state: %d\n", usb_dev->state); > + result = usb_autoresume_device(usb_dev); > + if (result < 0) { > + dev_err(&usb_dev->dev, > + "can't autoresume for authorization: %d\n", result); > + goto error_autoresume; > + } > + result = usb_get_device_descriptor(usb_dev, > sizeof(usb_dev->descriptor)); > + if (result < 0) { > + dev_err(&usb_dev->dev, "can't re-read device descriptor for " > + "authorization: %d\n", result); > + goto error_device_descriptor; > + } > + usb_dev->authorized = 1; > + usb_configure_device(usb_dev); > + /* Choose and set the configuration. This registers the interfaces > + * with the driver core and lets interface drivers bind to them. > + */ > + c = choose_configuration(usb_dev); > + if (c >= 0) { > + result = usb_set_configuration(usb_dev, c); > + if (result) { > + dev_err(&usb_dev->dev, > + "can't set config #%d, error %d\n", c, result); > + /* This need not be fatal. The user can try to > + * set other configurations. */ > + } > + } > + dev_info(&usb_dev->dev, "authorized to connect\n"); > +out_authorized: > +error_device_descriptor: > +error_autoresume: > + usb_unlock_device(usb_dev); // complements locktree > + return result; > +} > + > + > static int hub_port_status(struct usb_hub *hub, int port1, > u16 *status, u16 *change) > { > Index: linux.hg/drivers/usb/core/usb.h > =================================================================== > --- linux.hg.orig/drivers/usb/core/usb.h 2007-07-18 10:05:25.000000000 > -0700 > +++ linux.hg/drivers/usb/core/usb.h 2007-07-18 10:05:50.000000000 -0700 > @@ -13,12 +13,15 @@ > struct usb_interface *intf); > extern void usb_release_interface_cache(struct kref *ref); > extern void usb_disable_device (struct usb_device *dev, int skip_ep0); > +extern int usb_deauthorize_device (struct usb_device *); > +extern int usb_authorize_device (struct usb_device *); > extern void usb_detect_quirks(struct usb_device *udev); > > extern int usb_get_device_descriptor(struct usb_device *dev, > unsigned int size); > extern char *usb_cache_string(struct usb_device *udev, int index); > extern int usb_set_configuration(struct usb_device *dev, int configuration); > +extern int choose_configuration(struct usb_device *udev); > > extern void usb_kick_khubd(struct usb_device *dev); > extern int usb_match_device(struct usb_device *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/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel