USB: serial: visor: clean up treo endpoint hack
authorJohan Hovold <johan@kernel.org>
Thu, 16 Mar 2017 16:13:53 +0000 (17:13 +0100)
committerJohan Hovold <johan@kernel.org>
Tue, 28 Mar 2017 09:14:11 +0000 (11:14 +0200)
Use the new endpoint-remap functionality to configure the ports for
treo devices instead of poking around in the port structures after the
ports have been setup.

Signed-off-by: Johan Hovold <johan@kernel.org>
drivers/usb/serial/visor.c

index 41d135f..9f3317a 100644 (file)
@@ -46,7 +46,6 @@ static int  clie_5_calc_num_ports(struct usb_serial *serial,
                                        struct usb_serial_endpoints *epds);
 static void visor_read_int_callback(struct urb *urb);
 static int  clie_3_5_startup(struct usb_serial *serial);
-static int  treo_attach(struct usb_serial *serial);
 static int palm_os_3_probe(struct usb_serial *serial,
                                        const struct usb_device_id *id);
 static int palm_os_4_probe(struct usb_serial *serial,
@@ -176,7 +175,6 @@ static struct usb_serial_driver handspring_device = {
        .close =                visor_close,
        .throttle =             usb_serial_generic_throttle,
        .unthrottle =           usb_serial_generic_unthrottle,
-       .attach =               treo_attach,
        .probe =                visor_probe,
        .calc_num_ports =       visor_calc_num_ports,
        .read_int_callback =    visor_read_int_callback,
@@ -471,11 +469,35 @@ static int visor_probe(struct usb_serial *serial,
 static int visor_calc_num_ports(struct usb_serial *serial,
                                        struct usb_serial_endpoints *epds)
 {
+       unsigned int vid = le16_to_cpu(serial->dev->descriptor.idVendor);
        int num_ports = (int)(long)(usb_get_serial_data(serial));
 
        if (num_ports)
                usb_set_serial_data(serial, NULL);
 
+       /*
+        * Only swap the bulk endpoints for the Handspring devices with
+        * interrupt in endpoints, which for now are the Treo devices.
+        */
+       if (!(vid == HANDSPRING_VENDOR_ID || vid == KYOCERA_VENDOR_ID) ||
+                       epds->num_interrupt_in == 0)
+               goto out;
+
+       if (epds->num_bulk_in < 2 || epds->num_interrupt_in < 2) {
+               dev_err(&serial->interface->dev, "missing endpoints\n");
+               return -ENODEV;
+       }
+
+       /*
+        * It appears that Treos and Kyoceras want to use the
+        * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
+        * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
+        * Note that swapping the bulk out endpoints would break lots of
+        * apps that want to communicate on the second port.
+        */
+       swap(epds->bulk_in[0], epds->bulk_in[1]);
+       swap(epds->interrupt_in[0], epds->interrupt_in[1]);
+out:
        return num_ports;
 }
 
@@ -553,62 +575,6 @@ out:
        return result;
 }
 
-static int treo_attach(struct usb_serial *serial)
-{
-       struct usb_serial_port *swap_port;
-
-       /* Only do this endpoint hack for the Handspring devices with
-        * interrupt in endpoints, which for now are the Treo devices. */
-       if (!((le16_to_cpu(serial->dev->descriptor.idVendor)
-                                               == HANDSPRING_VENDOR_ID) ||
-               (le16_to_cpu(serial->dev->descriptor.idVendor)
-                                               == KYOCERA_VENDOR_ID)) ||
-               (serial->num_interrupt_in == 0))
-               return 0;
-
-       if (serial->num_bulk_in < 2 || serial->num_interrupt_in < 2) {
-               dev_err(&serial->interface->dev, "missing endpoints\n");
-               return -ENODEV;
-       }
-
-       /*
-       * It appears that Treos and Kyoceras want to use the
-       * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
-       * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
-       * Note that swapping the bulk out endpoints would break lots of
-       * apps that want to communicate on the second port.
-       */
-#define COPY_PORT(dest, src)                                           \
-       do { \
-               int i;                                                  \
-                                                                       \
-               for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) {      \
-                       dest->read_urbs[i] = src->read_urbs[i];         \
-                       dest->read_urbs[i]->context = dest;             \
-                       dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \
-               }                                                       \
-               dest->read_urb = src->read_urb;                         \
-               dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
-               dest->bulk_in_buffer = src->bulk_in_buffer;             \
-               dest->bulk_in_size = src->bulk_in_size;                 \
-               dest->interrupt_in_urb = src->interrupt_in_urb;         \
-               dest->interrupt_in_urb->context = dest;                 \
-               dest->interrupt_in_endpointAddress = \
-                                       src->interrupt_in_endpointAddress;\
-               dest->interrupt_in_buffer = src->interrupt_in_buffer;   \
-       } while (0);
-
-       swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL);
-       if (!swap_port)
-               return -ENOMEM;
-       COPY_PORT(swap_port, serial->port[0]);
-       COPY_PORT(serial->port[0], serial->port[1]);
-       COPY_PORT(serial->port[1], swap_port);
-       kfree(swap_port);
-
-       return 0;
-}
-
 module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);