static int proc_setconfig(struct dev_state *ps, void __user *arg)
{
- unsigned int u;
+ int u;
int status = 0;
struct usb_host_config *actconfig;
- if (get_user(u, (unsigned int __user *)arg))
+ if (get_user(u, (int __user *)arg))
return -EFAULT;
actconfig = ps->dev->actconfig;
/* if this is only an unbind, not a physical disconnect, then
* unconfigure the device */
if (udev->actconfig)
- usb_set_configuration(udev, 0);
+ usb_set_configuration(udev, -1);
usb_remove_sysfs_dev_files(udev);
}
* use this kind of configurability; many devices only have one
* configuration.
*
+ * @configuration is the value of the configuration to be installed.
+ * According to the USB spec (e.g. section 9.1.1.5), configuration values
+ * must be non-zero; a value of zero indicates that the device in
+ * unconfigured. However some devices erroneously use 0 as one of their
+ * configuration values. To help manage such devices, this routine will
+ * accept @configuration = -1 as indicating the device should be put in
+ * an unconfigured state.
+ *
* USB device configurations may affect Linux interoperability,
* power consumption and the functionality available. For example,
* the default configuration is limited to using 100mA of bus power,
struct usb_interface **new_interfaces = NULL;
int n, nintf;
- for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
- if (dev->config[i].desc.bConfigurationValue == configuration) {
- cp = &dev->config[i];
- break;
+ if (configuration == -1)
+ configuration = 0;
+ else {
+ for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+ if (dev->config[i].desc.bConfigurationValue ==
+ configuration) {
+ cp = &dev->config[i];
+ break;
+ }
}
}
if ((!cp && configuration != 0))
/* The USB spec says configuration 0 means unconfigured.
* But if a device includes a configuration numbered 0,
* we will accept it as a correctly configured state.
+ * Use -1 if you really want to unconfigure the device.
*/
if (cp && configuration == 0)
dev_warn(&dev->dev, "config 0 descriptor??\n");
struct usb_device *udev = to_usb_device(dev);
int config, value;
- if (sscanf(buf, "%u", &config) != 1 || config > 255)
+ if (sscanf(buf, "%d", &config) != 1 || config < -1 || config > 255)
return -EINVAL;
usb_lock_device(udev);
value = usb_set_configuration(udev, config);