Refactor and use the usb-serial infrastructure for line-control handling. This driver has been implemented based on sniffed traffic. A closer look at the requests sent during open and close reveals that these request appear to be standard CDC requests. If this is the case, then the control requests lack the interface argument. This patch will also make sure that the control lines are lowered at close (when HUPCL is set), something which could affect some modem reconnection issues that have been reported. Signed-off-by: Johan Hovold <johan@xxxxxxxxxx> --- drivers/usb/serial/zte_ev.c | 90 +++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 64 deletions(-) diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c index e40ab739c4a6..927c0d074e40 100644 --- a/drivers/usb/serial/zte_ev.c +++ b/drivers/usb/serial/zte_ev.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/usb.h> +#include <linux/usb/cdc.h> #include <linux/usb/serial.h> #include <linux/uaccess.h> @@ -31,6 +32,30 @@ static void debug_data(struct device *dev, const char *function, int len, len, len, data); } +void zte_ev_usb_serial_dtr_rts(struct usb_serial_port *port, int on) +{ + struct usb_serial *serial = port->serial; + struct usb_interface_descriptor *desc = + &serial->interface->cur_altsetting->desc; + unsigned int val; + int res; + + if (on) + val = 0x03; + else + val = 0; + + res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + USB_CDC_REQ_SET_CONTROL_LINE_STATE, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + val, desc->bInterfaceNumber, + NULL, 0, USB_CTRL_GET_TIMEOUT); + if (res) { + dev_err(&port->dev, "%s - failed to set control lines: %d\n", + __func__, res); + } +}; + static int zte_ev_usb_serial_open(struct tty_struct *tty, struct usb_serial_port *port) { @@ -44,15 +69,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, if (!buf) return -ENOMEM; - /* send 1st ctl cmd(CTL 21 22 01 00 00 00 00 00) */ - len = 0; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x22, 0x21, - 0x0001, 0x0000, NULL, len, - USB_CTRL_GET_TIMEOUT); - dev_dbg(dev, "result = %d\n", result); - - /* send 2st cmd and receive data */ /* * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 25.1.0(5) * 16.0 DI 00 96 00 00 00 00 08 @@ -64,7 +80,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); - /* send 3rd cmd */ /* * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 30.1.0 * 16.0 DO 80 25 00 00 00 00 08 .%..... 30.2.0 @@ -83,18 +98,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty, USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); - /* send 4th cmd */ - /* - * 16.0 CTL 21 22 03 00 00 00 00 00 - */ - len = 0; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x22, 0x21, - 0x0003, 0x0000, NULL, len, - USB_CTRL_GET_TIMEOUT); - dev_dbg(dev, "result = %d\n", result); - - /* send 5th cmd */ /* * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 33.1.0 * 16.0 DI 80 25 00 00 00 00 08 @@ -166,23 +169,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) if (!buf) return; - /* send 1st ctl cmd(CTL 21 22 02 00 00 00 00 00) */ - len = 0; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x22, 0x21, - 0x0002, 0x0000, NULL, len, - USB_CTRL_GET_TIMEOUT); - dev_dbg(dev, "result = %d\n", result); - - /* send 2st ctl cmd(CTL 21 22 03 00 00 00 00 00 ) */ - len = 0; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x22, 0x21, - 0x0003, 0x0000, NULL, len, - USB_CTRL_GET_TIMEOUT); - dev_dbg(dev, "result = %d\n", result); - - /* send 3st cmd and recieve data */ /* * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 25.1.0(5) * 16.0 DI 00 08 07 00 00 00 08 @@ -194,7 +180,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); - /* send 4th cmd */ /* * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 30.1.0 * 16.0 DO 00 c2 01 00 00 00 08 .%..... 30.2.0 @@ -213,18 +198,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); - /* send 5th cmd */ - /* - * 16.0 CTL 21 22 03 00 00 00 00 00 - */ - len = 0; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x22, 0x21, - 0x0003, 0x0000, NULL, len, - USB_CTRL_GET_TIMEOUT); - dev_dbg(dev, "result = %d\n", result); - - /* send 6th cmd */ /* * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 33.1.0 * 16.0 DI 00 c2 01 00 00 00 08 @@ -236,7 +209,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); - /* send 7th cmd */ /* * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 354.1.0 * 16.0 DO 00 c2 01 00 00 00 08 ....... 354.2.0 @@ -255,17 +227,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); - /* send 8th cmd */ - /* - * 16.0 CTL 21 22 03 00 00 00 00 00 - */ - len = 0; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x22, 0x21, - 0x0003, 0x0000, NULL, len, - USB_CTRL_GET_TIMEOUT); - dev_dbg(dev, "result = %d\n", result); - kfree(buf); usb_serial_generic_close(port); @@ -307,6 +268,7 @@ static struct usb_serial_driver zio_device = { .num_ports = 1, .open = zte_ev_usb_serial_open, .close = zte_ev_usb_serial_close, + .dtr_rts = zte_ev_usb_serial_dtr_rts, }; static struct usb_serial_driver * const serial_drivers[] = { -- 1.8.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html