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);