Commit 4a110609 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: usb_new_device() updates

Changes a handful of things in enumeration error paths.

Bugfixes:
  - consistent cleanup, and consistent return of -Ewhatever/0;
  - a usb_put_dev() gets rid of the extra refcount; this
    one's in bugzilla at osdl.

Diagnostics:
  - new diagnostic for when there's a choice of configurations;
  - merges some diagnostics, for slight rodata reduction.
parent cc1374a2
...@@ -994,7 +994,7 @@ int usb_set_address(struct usb_device *dev) ...@@ -994,7 +994,7 @@ int usb_set_address(struct usb_device *dev)
#define SET_ADDRESS_RETRYS 2 #define SET_ADDRESS_RETRYS 2
int usb_new_device(struct usb_device *dev, struct device *parent) int usb_new_device(struct usb_device *dev, struct device *parent)
{ {
int err = 0; int err = -EINVAL;
int i; int i;
int j; int j;
...@@ -1036,7 +1036,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1036,7 +1036,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
i = 8; i = 8;
break; break;
default: default:
return -EINVAL; goto fail;
} }
dev->epmaxpacketin [0] = i; dev->epmaxpacketin [0] = i;
dev->epmaxpacketout[0] = i; dev->epmaxpacketout[0] = i;
...@@ -1050,12 +1050,10 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1050,12 +1050,10 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
wait_ms(200); wait_ms(200);
} }
if (err < 0) { if (err < 0) {
dev_err(&dev->dev, "USB device not accepting new address=%d (error=%d)\n", dev_err(&dev->dev,
"device not accepting address %d, error %d\n",
dev->devnum, err); dev->devnum, err);
dev->state = USB_STATE_DEFAULT; goto fail;
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
} }
wait_ms(10); /* Let the SET_ADDRESS settle */ wait_ms(10); /* Let the SET_ADDRESS settle */
...@@ -1068,13 +1066,8 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1068,13 +1066,8 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
} }
if (err < 8) { if (err < 8) {
if (err < 0) dev_err(&dev->dev, "device descriptor read/8, error %d\n", err);
dev_err(&dev->dev, "USB device not responding, giving up (error=%d)\n", err); goto fail;
else
dev_err(&dev->dev, "USB device descriptor short read (expected %i, got %i)\n", 8, err);
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
} }
if (dev->speed == USB_SPEED_FULL) { if (dev->speed == USB_SPEED_FULL) {
dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
...@@ -1085,34 +1078,29 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1085,34 +1078,29 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
err = usb_get_device_descriptor(dev); err = usb_get_device_descriptor(dev);
if (err < (signed)sizeof(dev->descriptor)) { if (err < (signed)sizeof(dev->descriptor)) {
if (err < 0) dev_err(&dev->dev, "device descriptor read/all, error %d\n", err);
dev_err(&dev->dev, "unable to get device descriptor (error=%d)\n", err); goto fail;
else
dev_err(&dev->dev, "USB device descriptor short read (expected %Zi, got %i)\n",
sizeof(dev->descriptor), err);
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
} }
err = usb_get_configuration(dev); err = usb_get_configuration(dev);
if (err < 0) { if (err < 0) {
dev_err(&dev->dev, "unable to get device %d configuration (error=%d)\n", dev_err(&dev->dev, "unable to get device %d configuration (error=%d)\n",
dev->devnum, err); dev->devnum, err);
clear_bit(dev->devnum, dev->bus->devmap.devicemap); goto fail;
dev->devnum = -1;
return 1;
} }
/* we set the default configuration here */ /* choose and set the configuration here */
if (dev->descriptor.bNumConfigurations != 1) {
dev_info(&dev->dev,
"configuration #%d chosen from %d choices\n",
dev->config[0].desc.bConfigurationValue,
dev->descriptor.bNumConfigurations);
}
err = usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue); err = usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue);
if (err) { if (err) {
dev_err(&dev->dev, "failed to set device %d default configuration (error=%d)\n", dev_err(&dev->dev, "failed to set device %d default configuration (error=%d)\n",
dev->devnum, err); dev->devnum, err);
clear_bit(dev->devnum, dev->bus->devmap.devicemap); goto fail;
dev->devnum = -1;
return 1;
} }
/* USB device state == configured ... tell the world! */ /* USB device state == configured ... tell the world! */
...@@ -1132,7 +1120,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1132,7 +1120,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
/* put into sysfs, with device and config specific files */ /* put into sysfs, with device and config specific files */
err = device_add (&dev->dev); err = device_add (&dev->dev);
if (err) if (err)
return err; goto fail;
usb_create_driverfs_dev_files (dev); usb_create_driverfs_dev_files (dev);
/* Register all of the interfaces for this device with the driver core. /* Register all of the interfaces for this device with the driver core.
...@@ -1158,6 +1146,12 @@ int usb_new_device(struct usb_device *dev, struct device *parent) ...@@ -1158,6 +1146,12 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
usbfs_add_device(dev); usbfs_add_device(dev);
return 0; return 0;
fail:
dev->state = USB_STATE_DEFAULT;
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
usb_put_dev(dev);
return err;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment