diff options
author | Johan Hovold <johan@kernel.org> | 2017-06-20 13:52:03 +0300 |
---|---|---|
committer | Johan Hovold <johan@kernel.org> | 2017-06-21 10:40:07 +0300 |
commit | c22ac6d29f18d3210c545f77e4f95b856ab5f983 (patch) | |
tree | ff1af4ebd80766423bd762abc0a5e9736096d4f5 /drivers/usb/serial/usb-serial.c | |
parent | 45e5d4d418f37cb9b2746c1fc63ab89b7b521d78 (diff) | |
download | linux-c22ac6d29f18d3210c545f77e4f95b856ab5f983.tar.xz |
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/serial/usb-serial.c')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 23 |
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: |