USB: serial: refactor port endpoint setup
authorJohan Hovold <johan@kernel.org>
Tue, 20 Jun 2017 10:52:02 +0000 (12:52 +0200)
committerJohan Hovold <johan@kernel.org>
Wed, 21 Jun 2017 07:38:58 +0000 (09:38 +0200)
Make the probe callback more readable by refactoring the port
endpoint-resource setup by adding four helper functions.

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
drivers/usb/serial/usb-serial.c

index c7ca95f..f68275d 100644 (file)
@@ -742,6 +742,124 @@ static void find_endpoints(struct usb_serial *serial,
        }
 }
 
+static int setup_port_bulk_in(struct usb_serial_port *port,
+                                       struct usb_endpoint_descriptor *epd)
+{
+       struct usb_serial_driver *type = port->serial->type;
+       struct usb_device *udev = port->serial->dev;
+       int buffer_size;
+       int i;
+
+       buffer_size = max_t(int, type->bulk_in_size, usb_endpoint_maxp(epd));
+       port->bulk_in_size = buffer_size;
+       port->bulk_in_endpointAddress = epd->bEndpointAddress;
+
+       for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
+               set_bit(i, &port->read_urbs_free);
+               port->read_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
+               if (!port->read_urbs[i])
+                       return -ENOMEM;
+               port->bulk_in_buffers[i] = kmalloc(buffer_size, GFP_KERNEL);
+               if (!port->bulk_in_buffers[i])
+                       return -ENOMEM;
+               usb_fill_bulk_urb(port->read_urbs[i], udev,
+                               usb_rcvbulkpipe(udev, epd->bEndpointAddress),
+                               port->bulk_in_buffers[i], buffer_size,
+                               type->read_bulk_callback, port);
+       }
+
+       port->read_urb = port->read_urbs[0];
+       port->bulk_in_buffer = port->bulk_in_buffers[0];
+
+       return 0;
+}
+
+static int setup_port_bulk_out(struct usb_serial_port *port,
+                                       struct usb_endpoint_descriptor *epd)
+{
+       struct usb_serial_driver *type = port->serial->type;
+       struct usb_device *udev = port->serial->dev;
+       int buffer_size;
+       int i;
+
+       if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))
+               return -ENOMEM;
+       if (type->bulk_out_size)
+               buffer_size = type->bulk_out_size;
+       else
+               buffer_size = usb_endpoint_maxp(epd);
+       port->bulk_out_size = buffer_size;
+       port->bulk_out_endpointAddress = epd->bEndpointAddress;
+
+       for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {
+               set_bit(i, &port->write_urbs_free);
+               port->write_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
+               if (!port->write_urbs[i])
+                       return -ENOMEM;
+               port->bulk_out_buffers[i] = kmalloc(buffer_size, GFP_KERNEL);
+               if (!port->bulk_out_buffers[i])
+                       return -ENOMEM;
+               usb_fill_bulk_urb(port->write_urbs[i], udev,
+                               usb_sndbulkpipe(udev, epd->bEndpointAddress),
+                               port->bulk_out_buffers[i], buffer_size,
+                               type->write_bulk_callback, port);
+       }
+
+       port->write_urb = port->write_urbs[0];
+       port->bulk_out_buffer = port->bulk_out_buffers[0];
+
+       return 0;
+}
+
+static int setup_port_interrupt_in(struct usb_serial_port *port,
+                                       struct usb_endpoint_descriptor *epd)
+{
+       struct usb_serial_driver *type = port->serial->type;
+       struct usb_device *udev = port->serial->dev;
+       int buffer_size;
+
+       port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!port->interrupt_in_urb)
+               return -ENOMEM;
+       buffer_size = usb_endpoint_maxp(epd);
+       port->interrupt_in_endpointAddress = epd->bEndpointAddress;
+       port->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+       if (!port->interrupt_in_buffer)
+               return -ENOMEM;
+       usb_fill_int_urb(port->interrupt_in_urb, udev,
+                       usb_rcvintpipe(udev, epd->bEndpointAddress),
+                       port->interrupt_in_buffer, buffer_size,
+                       type->read_int_callback, port,
+                       epd->bInterval);
+
+       return 0;
+}
+
+static int setup_port_interrupt_out(struct usb_serial_port *port,
+                                       struct usb_endpoint_descriptor *epd)
+{
+       struct usb_serial_driver *type = port->serial->type;
+       struct usb_device *udev = port->serial->dev;
+       int buffer_size;
+
+       port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!port->interrupt_out_urb)
+               return -ENOMEM;
+       buffer_size = usb_endpoint_maxp(epd);
+       port->interrupt_out_size = buffer_size;
+       port->interrupt_out_endpointAddress = epd->bEndpointAddress;
+       port->interrupt_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+       if (!port->interrupt_out_buffer)
+               return -ENOMEM;
+       usb_fill_int_urb(port->interrupt_out_urb, udev,
+                       usb_sndintpipe(udev, epd->bEndpointAddress),
+                       port->interrupt_out_buffer, buffer_size,
+                       type->write_int_callback, port,
+                       epd->bInterval);
+
+       return 0;
+}
+
 static int usb_serial_probe(struct usb_interface *interface,
                               const struct usb_device_id *id)
 {
@@ -749,13 +867,10 @@ static int usb_serial_probe(struct usb_interface *interface,
        struct usb_device *dev = interface_to_usbdev(interface);
        struct usb_serial *serial = NULL;
        struct usb_serial_port *port;
-       struct usb_endpoint_descriptor *endpoint;
        struct usb_serial_endpoints *epds;
        struct usb_serial_driver *type = NULL;
        int retval;
-       int buffer_size;
        int i;
-       int j;
        int num_ports = 0;
        unsigned char max_endpoints;
 
@@ -867,86 +982,24 @@ static int usb_serial_probe(struct usb_interface *interface,
 
        /* set up the endpoint information */
        for (i = 0; i < epds->num_bulk_in; ++i) {
-               endpoint = epds->bulk_in[i];
-               port = serial->port[i];
-               buffer_size = max_t(int, serial->type->bulk_in_size,
-                               usb_endpoint_maxp(endpoint));
-               port->bulk_in_size = buffer_size;
-               port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
-
-               for (j = 0; j < ARRAY_SIZE(port->read_urbs); ++j) {
-                       set_bit(j, &port->read_urbs_free);
-                       port->read_urbs[j] = usb_alloc_urb(0, GFP_KERNEL);
-                       if (!port->read_urbs[j])
-                               goto probe_error;
-                       port->bulk_in_buffers[j] = kmalloc(buffer_size,
-                                                               GFP_KERNEL);
-                       if (!port->bulk_in_buffers[j])
-                               goto probe_error;
-                       usb_fill_bulk_urb(port->read_urbs[j], dev,
-                                       usb_rcvbulkpipe(dev,
-                                               endpoint->bEndpointAddress),
-                                       port->bulk_in_buffers[j], buffer_size,
-                                       serial->type->read_bulk_callback,
-                                       port);
-               }
-
-               port->read_urb = port->read_urbs[0];
-               port->bulk_in_buffer = port->bulk_in_buffers[0];
+               retval = setup_port_bulk_in(serial->port[i], epds->bulk_in[i]);
+               if (retval)
+                       goto probe_error;
        }
 
        for (i = 0; i < epds->num_bulk_out; ++i) {
-               endpoint = epds->bulk_out[i];
-               port = serial->port[i];
-               if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))
+               retval = setup_port_bulk_out(serial->port[i],
+                               epds->bulk_out[i]);
+               if (retval)
                        goto probe_error;
-               buffer_size = serial->type->bulk_out_size;
-               if (!buffer_size)
-                       buffer_size = usb_endpoint_maxp(endpoint);
-               port->bulk_out_size = buffer_size;
-               port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
-
-               for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) {
-                       set_bit(j, &port->write_urbs_free);
-                       port->write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL);
-                       if (!port->write_urbs[j])
-                               goto probe_error;
-                       port->bulk_out_buffers[j] = kmalloc(buffer_size,
-                                                               GFP_KERNEL);
-                       if (!port->bulk_out_buffers[j])
-                               goto probe_error;
-                       usb_fill_bulk_urb(port->write_urbs[j], dev,
-                                       usb_sndbulkpipe(dev,
-                                               endpoint->bEndpointAddress),
-                                       port->bulk_out_buffers[j], buffer_size,
-                                       serial->type->write_bulk_callback,
-                                       port);
-               }
-
-               port->write_urb = port->write_urbs[0];
-               port->bulk_out_buffer = port->bulk_out_buffers[0];
        }
 
        if (serial->type->read_int_callback) {
                for (i = 0; i < epds->num_interrupt_in; ++i) {
-                       endpoint = epds->interrupt_in[i];
-                       port = serial->port[i];
-                       port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
-                       if (!port->interrupt_in_urb)
-                               goto probe_error;
-                       buffer_size = usb_endpoint_maxp(endpoint);
-                       port->interrupt_in_endpointAddress =
-                                               endpoint->bEndpointAddress;
-                       port->interrupt_in_buffer = kmalloc(buffer_size,
-                                                               GFP_KERNEL);
-                       if (!port->interrupt_in_buffer)
+                       retval = setup_port_interrupt_in(serial->port[i],
+                                       epds->interrupt_in[i]);
+                       if (retval)
                                goto probe_error;
-                       usb_fill_int_urb(port->interrupt_in_urb, dev,
-                               usb_rcvintpipe(dev,
-                                               endpoint->bEndpointAddress),
-                               port->interrupt_in_buffer, buffer_size,
-                               serial->type->read_int_callback, port,
-                               endpoint->bInterval);
                }
        } 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");
@@ -954,25 +1007,10 @@ static int usb_serial_probe(struct usb_interface *interface,
 
        if (serial->type->write_int_callback) {
                for (i = 0; i < epds->num_interrupt_out; ++i) {
-                       endpoint = epds->interrupt_out[i];
-                       port = serial->port[i];
-                       port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
-                       if (!port->interrupt_out_urb)
-                               goto probe_error;
-                       buffer_size = usb_endpoint_maxp(endpoint);
-                       port->interrupt_out_size = buffer_size;
-                       port->interrupt_out_endpointAddress =
-                                               endpoint->bEndpointAddress;
-                       port->interrupt_out_buffer = kmalloc(buffer_size,
-                                                               GFP_KERNEL);
-                       if (!port->interrupt_out_buffer)
+                       retval = setup_port_interrupt_out(serial->port[i],
+                                       epds->interrupt_out[i]);
+                       if (retval)
                                goto probe_error;
-                       usb_fill_int_urb(port->interrupt_out_urb, dev,
-                               usb_sndintpipe(dev,
-                                                 endpoint->bEndpointAddress),
-                               port->interrupt_out_buffer, buffer_size,
-                               serial->type->write_int_callback, port,
-                               endpoint->bInterval);
                }
        } 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");