diff options
Diffstat (limited to 'drivers/usb/serial/cp210x.c')
-rw-r--r-- | drivers/usb/serial/cp210x.c | 77 |
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 08a5575724c..0310e2df59f 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -49,6 +49,7 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, unsigned int, unsigned int); static void cp210x_break_ctl(struct tty_struct *, int); static int cp210x_startup(struct usb_serial *); +static void cp210x_release(struct usb_serial *); static void cp210x_dtr_rts(struct usb_serial_port *p, int on); static bool debug; @@ -121,6 +122,8 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ @@ -149,12 +152,15 @@ static const struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); +struct cp210x_port_private { + __u8 bInterfaceNumber; +}; + static struct usb_driver cp210x_driver = { .name = "cp210x", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table, - .no_dynamic_id = 1, }; static struct usb_serial_driver cp210x_device = { @@ -162,7 +168,6 @@ static struct usb_serial_driver cp210x_device = { .owner = THIS_MODULE, .name = "cp210x", }, - .usb_driver = &cp210x_driver, .id_table = id_table, .num_ports = 1, .bulk_in_size = 256, @@ -174,9 +179,14 @@ static struct usb_serial_driver cp210x_device = { .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, .attach = cp210x_startup, + .release = cp210x_release, .dtr_rts = cp210x_dtr_rts }; +static struct usb_serial_driver * const serial_drivers[] = { + &cp210x_device, NULL +}; + /* Config request types */ #define REQTYPE_HOST_TO_DEVICE 0x41 #define REQTYPE_DEVICE_TO_HOST 0xc1 @@ -261,6 +271,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); __le32 *buf; int result, i, length; @@ -276,7 +287,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - 0, buf, size, 300); + port_priv->bInterfaceNumber, buf, size, 300); /* Convert data into an array of integers */ for (i = 0; i < length; i++) @@ -286,7 +297,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, if (result != size) { dbg("%s - Unable to send config request, " - "request=0x%x size=%d result=%d\n", + "request=0x%x size=%d result=%d", __func__, request, size, result); if (result > 0) result = -EPROTO; @@ -307,6 +318,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); __le32 *buf; int result, i, length; @@ -328,19 +340,19 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, - 0, buf, size, 300); + port_priv->bInterfaceNumber, buf, size, 300); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], - 0, NULL, 0, 300); + port_priv->bInterfaceNumber, NULL, 0, 300); } kfree(buf); if ((size > 2 && result != size) || result < 0) { dbg("%s - Unable to send request, " - "request=0x%x size=%d result=%d\n", + "request=0x%x size=%d result=%d", __func__, request, size, result); if (result > 0) result = -EPROTO; @@ -683,13 +695,13 @@ static void cp210x_set_termios(struct tty_struct *tty, default: dbg("cp210x driver does not " "support the number of bits requested," - " using 8 bit mode\n"); + " using 8 bit mode"); bits |= BITS_DATA_8; break; } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of data bits requested " - "not supported by device\n"); + "not supported by device"); } if ((cflag & (PARENB|PARODD|CMSPAR)) != @@ -716,8 +728,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) - dbg("Parity mode not supported " - "by device\n"); + dbg("Parity mode not supported by device"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { @@ -732,7 +743,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of stop bits requested " - "not supported by device\n"); + "not supported by device"); } if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { @@ -844,40 +855,40 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state) static int cp210x_startup(struct usb_serial *serial) { + struct cp210x_port_private *port_priv; + int i; + /* cp210x buffers behave strangely unless device is reset */ usb_reset_device(serial->dev); - return 0; -} -static int __init cp210x_init(void) -{ - int retval; + for (i = 0; i < serial->num_ports; i++) { + port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); + if (!port_priv) + return -ENOMEM; - retval = usb_serial_register(&cp210x_device); - if (retval) - return retval; /* Failed to register */ + memset(port_priv, 0x00, sizeof(*port_priv)); + port_priv->bInterfaceNumber = + serial->interface->cur_altsetting->desc.bInterfaceNumber; - retval = usb_register(&cp210x_driver); - if (retval) { - /* Failed to register */ - usb_serial_deregister(&cp210x_device); - return retval; + usb_set_serial_port_data(serial->port[i], port_priv); } - /* Success */ - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); return 0; } -static void __exit cp210x_exit(void) +static void cp210x_release(struct usb_serial *serial) { - usb_deregister(&cp210x_driver); - usb_serial_deregister(&cp210x_device); + struct cp210x_port_private *port_priv; + int i; + + for (i = 0; i < serial->num_ports; i++) { + port_priv = usb_get_serial_port_data(serial->port[i]); + kfree(port_priv); + usb_set_serial_port_data(serial->port[i], NULL); + } } -module_init(cp210x_init); -module_exit(cp210x_exit); +module_usb_serial_driver(cp210x_driver, serial_drivers); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_VERSION(DRIVER_VERSION); |