summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-06-20 12:52:03 +0200
committerJohan Hovold <johan@kernel.org>2017-06-21 09:40:07 +0200
commitc22ac6d29f18d3210c545f77e4f95b856ab5f983 (patch)
treeff1af4ebd80766423bd762abc0a5e9736096d4f5 /drivers/usb
parentUSB: serial: refactor port endpoint setup (diff)
downloadlinux-c22ac6d29f18d3210c545f77e4f95b856ab5f983.tar.xz
linux-c22ac6d29f18d3210c545f77e4f95b856ab5f983.zip
USB: serial: propagate late probe errors
Propagate errnos for late probe errors (e.g. -ENOMEM on allocation failures) instead of always returning -EIO. Note that some drivers are currently returning -ENODEV from their attach callbacks when a device is not supported, but this has also been mapped to -EIO. Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/usb-serial.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index f68275dd1e9f..bb34f9f7eaf4 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -962,8 +962,10 @@ static int usb_serial_probe(struct usb_interface *interface,
dev_dbg(ddev, "setting up %d port structure(s)\n", max_endpoints);
for (i = 0; i < max_endpoints; ++i) {
port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
- if (!port)
- goto probe_error;
+ if (!port) {
+ retval = -ENOMEM;
+ goto err_free_epds;
+ }
tty_port_init(&port->port);
port->port.ops = &serial_port_ops;
port->serial = serial;
@@ -984,14 +986,14 @@ static int usb_serial_probe(struct usb_interface *interface,
for (i = 0; i < epds->num_bulk_in; ++i) {
retval = setup_port_bulk_in(serial->port[i], epds->bulk_in[i]);
if (retval)
- goto probe_error;
+ goto err_free_epds;
}
for (i = 0; i < epds->num_bulk_out; ++i) {
retval = setup_port_bulk_out(serial->port[i],
epds->bulk_out[i]);
if (retval)
- goto probe_error;
+ goto err_free_epds;
}
if (serial->type->read_int_callback) {
@@ -999,7 +1001,7 @@ static int usb_serial_probe(struct usb_interface *interface,
retval = setup_port_interrupt_in(serial->port[i],
epds->interrupt_in[i]);
if (retval)
- goto probe_error;
+ goto err_free_epds;
}
} else if (epds->num_interrupt_in) {
dev_dbg(ddev, "The device claims to support interrupt in transfers, but read_int_callback is not defined\n");
@@ -1010,7 +1012,7 @@ static int usb_serial_probe(struct usb_interface *interface,
retval = setup_port_interrupt_out(serial->port[i],
epds->interrupt_out[i]);
if (retval)
- goto probe_error;
+ goto err_free_epds;
}
} else if (epds->num_interrupt_out) {
dev_dbg(ddev, "The device claims to support interrupt out transfers, but write_int_callback is not defined\n");
@@ -1022,7 +1024,7 @@ static int usb_serial_probe(struct usb_interface *interface,
if (type->attach) {
retval = type->attach(serial);
if (retval < 0)
- goto probe_error;
+ goto err_free_epds;
serial->attached = 1;
if (retval > 0) {
/* quietly accept this device, but don't bind to a
@@ -1034,9 +1036,10 @@ static int usb_serial_probe(struct usb_interface *interface,
serial->attached = 1;
}
- if (allocate_minors(serial, num_ports)) {
+ retval = allocate_minors(serial, num_ports);
+ if (retval) {
dev_err(ddev, "No more free serial minor numbers\n");
- goto probe_error;
+ goto err_free_epds;
}
/* register all of the individual ports with the driver core */
@@ -1058,8 +1061,6 @@ exit:
module_put(type->driver.owner);
return 0;
-probe_error:
- retval = -EIO;
err_free_epds:
kfree(epds);
err_put_serial: