Clean up control requests sent during open and close. 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. Based on the sniffed traffic the driver currently does the following during open GET_LINE_CODING (38400 8N1) SET_LINE_CODING 9600 8N1 GET_LINE_CODING (9600 8N1) and during close GET_LINE_CODING (460800 8N1) SET_LINE_CODING 115200 8N1 GET_LINE_CODING (115200 8N1) where the values in parentheses are the expected values based on comments in the driver. This patch replaces the above with a single SET_LINE_CODING 9600 8N1 during open, and makes sure that the interface number is included in the request. Signed-off-by: Johan Hovold <johan@xxxxxxxxxx> --- drivers/usb/serial/zte_ev.c | 200 +++++--------------------------------------- 1 file changed, 23 insertions(+), 177 deletions(-) diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c index 927c0d074e40..69fba6b1af3c 100644 --- a/drivers/usb/serial/zte_ev.c +++ b/drivers/usb/serial/zte_ev.c @@ -21,17 +21,6 @@ #include <linux/usb/serial.h> #include <linux/uaccess.h> -#define MAX_SETUP_DATA_SIZE 32 - -static void debug_data(struct device *dev, const char *function, int len, - const unsigned char *data, int result) -{ - dev_dbg(dev, "result = %d\n", result); - if (result == len) - dev_dbg(dev, "%s - length = %d, data = %*ph\n", function, - len, len, data); -} - void zte_ev_usb_serial_dtr_rts(struct usb_serial_port *port, int on) { struct usb_serial *serial = port->serial; @@ -59,179 +48,37 @@ void zte_ev_usb_serial_dtr_rts(struct usb_serial_port *port, int on) static int zte_ev_usb_serial_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct usb_device *udev = port->serial->dev; - struct device *dev = &port->dev; - int result = 0; - int len; - unsigned char *buf; + struct usb_serial *serial = port->serial; + struct usb_interface_descriptor *desc = + &serial->interface->cur_altsetting->desc; + struct usb_cdc_line_coding *lc; + int res; - buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL); - if (!buf) + lc = kzalloc(sizeof(*lc), GFP_KERNEL); + if (!lc) return -ENOMEM; - /* - * 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 - */ - len = 0x0007; - result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x21, 0xa1, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); - - /* - * 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 - */ - len = 0x0007; - buf[0] = 0x80; - buf[1] = 0x25; - buf[2] = 0x00; - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x08; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x20, 0x21, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); - - /* - * 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 - */ - len = 0x0007; - result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x21, 0xa1, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); + /* Set line coding to 9600 baud 8N1 */ + lc->dwDTERate = cpu_to_le32(9600); + lc->bCharFormat = USB_CDC_1_STOP_BITS; + lc->bParityType = USB_CDC_NO_PARITY; + lc->bDataBits = 8; + res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + USB_CDC_REQ_SET_LINE_CODING, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, desc->bInterfaceNumber, + lc, sizeof(*lc), + USB_CTRL_GET_TIMEOUT); + if (res != sizeof(*lc)) { + dev_err(&port->dev, "%s - failed to set line coding: %d\n", + __func__, res); + } - /* send 6th cmd */ - /* - * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 34.1.0 - * 16.0 DO 80 25 00 00 00 00 08 - */ - len = 0x0007; - buf[0] = 0x80; - buf[1] = 0x25; - buf[2] = 0x00; - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x08; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x20, 0x21, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); - kfree(buf); + kfree(lc); return usb_serial_generic_open(tty, port); } -/* - * CTL 21 22 02 00 00 00 00 00 CLASS 338.1.0 - * - * 16.1 DI a1 20 00 00 00 00 02 00 02 00 . ........ 340.1.0 - * 16.0 CTL 21 22 03 00 00 00 00 00 CLASS 341.1.0 - * - * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 346.1.0(3) - * 16.0 DI 00 08 07 00 00 00 08 ....... 346.2.0 - * - * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 349.1.0 - * 16.0 DO 00 c2 01 00 00 00 08 ....... 349.2.0 - * - * 16.0 CTL 21 22 03 00 00 00 00 00 CLASS 350.1.0(2) - * - * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 352.1.0 - * 16.0 DI 00 c2 01 00 00 00 08 ....... 352.2.0 - * - * 16.1 DI a1 20 00 00 00 00 02 00 02 00 . ........ 353.1.0 - * - * 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 - * - * 16.0 CTL 21 22 03 00 00 00 00 00 -*/ - -static void zte_ev_usb_serial_close(struct usb_serial_port *port) -{ - struct usb_device *udev = port->serial->dev; - struct device *dev = &port->dev; - int result = 0; - int len; - unsigned char *buf; - - buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL); - if (!buf) - return; - - /* - * 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 - */ - len = 0x0007; - result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x21, 0xa1, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); - - /* - * 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 - */ - len = 0x0007; - buf[0] = 0x00; - buf[1] = 0xc2; - buf[2] = 0x01; - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x08; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x20, 0x21, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); - - /* - * 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 - */ - len = 0x0007; - result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x21, 0xa1, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); - - /* - * 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 - */ - len = 0x0007; - buf[0] = 0x00; - buf[1] = 0xc2; - buf[2] = 0x01; - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x08; - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x20, 0x21, - 0x0000, 0x0000, buf, len, - USB_CTRL_GET_TIMEOUT); - debug_data(dev, __func__, len, buf, result); - - kfree(buf); - - usb_serial_generic_close(port); -} - static const struct usb_device_id id_table[] = { /* AC8710, AC8710T */ { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) }, @@ -267,7 +114,6 @@ static struct usb_serial_driver zio_device = { .id_table = id_table, .num_ports = 1, .open = zte_ev_usb_serial_open, - .close = zte_ev_usb_serial_close, .dtr_rts = zte_ev_usb_serial_dtr_rts, }; -- 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