USB: usb_wwan/option: generalize option_send_setup for other drivers
authorDavid Ward <david.ward@ll.mit.edu>
Wed, 16 Sep 2015 16:27:57 +0000 (12:27 -0400)
committerJohan Hovold <johan@kernel.org>
Fri, 9 Oct 2015 10:42:40 +0000 (12:42 +0200)
Only the option driver implements the send_setup callback; it uses the
SET_CONTROL_LINE_STATE request in CDC ACM to generate DTR/RTS signals
on the port. This is not driver-specific though and is needed by other
drivers, so move the function to the usb_wwan driver (with formatting
tweaks), and replace the callback pointer with a flag that enables the
request.

Suggested-by: Bjørn Mork <bjorn@mork.no>
Suggested-by: Johan Hovold <johan@kernel.org>
Signed-off-by: David Ward <david.ward@ll.mit.edu>
Signed-off-by: Johan Hovold <johan@kernel.org>
drivers/usb/serial/option.c
drivers/usb/serial/usb-wwan.h
drivers/usb/serial/usb_wwan.c

index 4d16c97..edfaec1 100644 (file)
@@ -48,7 +48,6 @@ static int  option_probe(struct usb_serial *serial,
                        const struct usb_device_id *id);
 static int option_attach(struct usb_serial *serial);
 static void option_release(struct usb_serial *serial);
-static int option_send_setup(struct usb_serial_port *port);
 static void option_instat_callback(struct urb *urb);
 
 /* Vendor and product IDs */
@@ -1890,7 +1889,7 @@ static int option_attach(struct usb_serial *serial)
 
        if (!blacklist || !test_bit(iface_desc->bInterfaceNumber,
                                                &blacklist->sendsetup)) {
-               data->send_setup = option_send_setup;
+               data->use_send_setup = 1;
        }
        spin_lock_init(&data->susp_lock);
 
@@ -1961,39 +1960,6 @@ static void option_instat_callback(struct urb *urb)
        }
 }
 
-/** send RTS/DTR state to the port.
- *
- * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN
- * CDC.
-*/
-static int option_send_setup(struct usb_serial_port *port)
-{
-       struct usb_serial *serial = port->serial;
-       struct usb_wwan_port_private *portdata;
-       int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
-       int val = 0;
-       int res;
-
-       portdata = usb_get_serial_port_data(port);
-
-       if (portdata->dtr_state)
-               val |= 0x01;
-       if (portdata->rts_state)
-               val |= 0x02;
-
-       res = usb_autopm_get_interface(serial->interface);
-       if (res)
-               return res;
-
-       res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                               0x22, 0x21, val, ifNum, NULL,
-                               0, USB_CTRL_SET_TIMEOUT);
-
-       usb_autopm_put_interface(serial->interface);
-
-       return res;
-}
-
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
index f22dff5..44b25c0 100644 (file)
@@ -34,9 +34,9 @@ extern int usb_wwan_resume(struct usb_serial *serial);
 struct usb_wwan_intf_private {
        spinlock_t susp_lock;
        unsigned int suspended:1;
+       unsigned int use_send_setup:1;
        int in_flight;
        unsigned int open_ports;
-       int (*send_setup) (struct usb_serial_port *port);
        void *private;
 };
 
index 825305c..be9cb61 100644 (file)
 #include <linux/serial.h>
 #include "usb-wwan.h"
 
+/*
+ * Generate DTR/RTS signals on the port using the SET_CONTROL_LINE_STATE request
+ * in CDC ACM.
+ */
+static int usb_wwan_send_setup(struct usb_serial_port *port)
+{
+       struct usb_serial *serial = port->serial;
+       struct usb_wwan_port_private *portdata;
+       int val = 0;
+       int ifnum;
+       int res;
+
+       portdata = usb_get_serial_port_data(port);
+
+       if (portdata->dtr_state)
+               val |= 0x01;
+       if (portdata->rts_state)
+               val |= 0x02;
+
+       ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
+
+       res = usb_autopm_get_interface(serial->interface);
+       if (res)
+               return res;
+
+       res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                               0x22, 0x21, val, ifnum, NULL, 0,
+                               USB_CTRL_SET_TIMEOUT);
+
+       usb_autopm_put_interface(port->serial->interface);
+
+       return res;
+}
+
 void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
 {
        struct usb_wwan_port_private *portdata;
@@ -43,7 +77,7 @@ void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
 
        intfdata = usb_get_serial_data(port->serial);
 
-       if (!intfdata->send_setup)
+       if (!intfdata->use_send_setup)
                return;
 
        portdata = usb_get_serial_port_data(port);
@@ -51,7 +85,7 @@ void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
        portdata->rts_state = on;
        portdata->dtr_state = on;
 
-       intfdata->send_setup(port);
+       usb_wwan_send_setup(port);
 }
 EXPORT_SYMBOL(usb_wwan_dtr_rts);
 
@@ -84,7 +118,7 @@ int usb_wwan_tiocmset(struct tty_struct *tty,
        portdata = usb_get_serial_port_data(port);
        intfdata = usb_get_serial_data(port->serial);
 
-       if (!intfdata->send_setup)
+       if (!intfdata->use_send_setup)
                return -EINVAL;
 
        /* FIXME: what locks portdata fields ? */
@@ -97,7 +131,7 @@ int usb_wwan_tiocmset(struct tty_struct *tty,
                portdata->rts_state = 0;
        if (clear & TIOCM_DTR)
                portdata->dtr_state = 0;
-       return intfdata->send_setup(port);
+       return usb_wwan_send_setup(port);
 }
 EXPORT_SYMBOL(usb_wwan_tiocmset);