X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=src%2Fcp210x.c;h=1ec4b8eaa403d9c581e0474dde5d695933744e62;hb=adcc360e576188af96b2dd22be2bed75e151d769;hp=0df92df9a41894e7c49ffe35e8203299007f7d07;hpb=affe5c7c95eab8dd65c10631bb7435acbae8b1c4;p=cp210x.git diff --git a/src/cp210x.c b/src/cp210x.c index 0df92df..1ec4b8e 100644 --- a/src/cp210x.c +++ b/src/cp210x.c @@ -1,5 +1,5 @@ /* - * Silicon Laboratories CP2101/CP2102/CP2103 USB to RS232 serial adaptor driver + * Silicon Laboratories CP210x USB to RS232 serial adaptor driver * * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk) * @@ -11,15 +11,6 @@ * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow * control thanks to Munir Nassar nassarmu@real-time.com * - * Silicon Labs RJM: updated to 0.11 for 2.6.15 and later kernels - * - * Port configuration, usb descriptor and gpio management by R. Steve McKown - * rsmckown@gmail.com. - * - * Outstanding Issues: - * Buffers are not flushed when the port is opened. - * Multiple calls to write() may fail with "Resource temporarily unavailable" - * */ #include @@ -32,42 +23,48 @@ #include #include #include +#include "cp210x.h" /* * Version Information */ -#define DRIVER_VERSION "v0.11tmi" -#define DRIVER_DESC "Silicon Labs CP2101/CP2102/CP2103 RS232 serial adaptor driver" +#define DRIVER_VERSION "vxxPKGVERxxtmi" +#define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver" /* * Function Prototypes */ -static int cp2101_open(struct usb_serial_port*, struct file*); -static void cp2101_cleanup(struct usb_serial_port*); -static void cp2101_close(struct usb_serial_port*, struct file*); -static void cp2101_get_termios(struct usb_serial_port*); -static void cp2101_set_termios(struct usb_serial_port*, struct ktermios*); -static int cp2101_tiocmget (struct usb_serial_port *, struct file *); -static int cp2101_tiocmset (struct usb_serial_port *, struct file *, +static int cp210x_open(struct usb_serial_port*, struct file*); +static void cp210x_cleanup(struct usb_serial_port*); +static void cp210x_close(struct usb_serial_port*, struct file*); +static void cp210x_get_termios(struct usb_serial_port*); +static void cp210x_set_termios(struct usb_serial_port*, struct ktermios*); +static int cp210x_tiocmget(struct usb_serial_port *, struct file *); +static int cp210x_tiocmset(struct usb_serial_port *, struct file *, unsigned int, unsigned int); -static void cp2101_break_ctl(struct usb_serial_port*, int); -static int cp2101_startup (struct usb_serial *); -static void cp2101_shutdown(struct usb_serial*); -static int cp2101_ioctl(struct usb_serial_port *, struct file *, +static void cp210x_break_ctl(struct usb_serial_port*, int); +static int cp210x_startup(struct usb_serial *); +static void cp210x_shutdown(struct usb_serial*); +static int cp210x_ioctl(struct usb_serial_port *, struct file *, unsigned int, unsigned long); static int debug; -static struct usb_device_id id_table [] = { +static const struct usb_device_id id_table[] = { { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ + { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ + { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ + { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ + { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */ + { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */ { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ @@ -79,6 +76,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ + { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ @@ -88,12 +86,17 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ + { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */ + { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ - { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ + { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */ + { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ + { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ + { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ @@ -102,16 +105,19 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */ { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */ + { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ + { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ + { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; -MODULE_DEVICE_TABLE (usb, id_table); +MODULE_DEVICE_TABLE(usb, id_table); -static struct usb_driver cp2101_driver = { +static struct usb_driver cp210x_driver = { .name = "cp210x", .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, @@ -119,26 +125,26 @@ static struct usb_driver cp2101_driver = { .no_dynamic_id = 1, }; -static struct usb_serial_driver cp2101_device = { +static struct usb_serial_driver cp210x_device = { .driver = { .owner = THIS_MODULE, .name = "cp210x", }, - .usb_driver = &cp2101_driver, + .usb_driver = &cp210x_driver, .id_table = id_table, .num_interrupt_in = 0, .num_bulk_in = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE, .num_ports = 1, - .open = cp2101_open, - .close = cp2101_close, - .ioctl = cp2101_ioctl, - .break_ctl = cp2101_break_ctl, - .set_termios = cp2101_set_termios, - .tiocmget = cp2101_tiocmget, - .tiocmset = cp2101_tiocmset, - .attach = cp2101_startup, - .shutdown = cp2101_shutdown, + .open = cp210x_open, + .close = cp210x_close, + .ioctl = cp210x_ioctl, + .break_ctl = cp210x_break_ctl, + .set_termios = cp210x_set_termios, + .tiocmget = cp210x_tiocmget, + .tiocmset = cp210x_tiocmset, + .attach = cp210x_startup, + .shutdown = cp210x_shutdown, }; /* Config request types */ @@ -195,102 +201,93 @@ static struct usb_serial_driver cp2101_device = { #define CONTROL_WRITE_DTR 0x0100 #define CONTROL_WRITE_RTS 0x0200 -/* CP2103 ioctls */ -#define IOCTL_GPIOGET 0x8000 /* Get gpio bits */ -#define IOCTL_GPIOSET 0x8001 /* Set gpio bits */ -#define IOCTL_GPIOBIC 0x8002 /* Clear specific gpio bit(s) */ -#define IOCTL_GPIOBIS 0x8003 /* Set specific gpio bit(s) */ - -/* CP210x ioctls principally used during initial device configuration */ -#define IOCTL_DEVICERESET 0x8004 /* Reset the cp210x */ -#define IOCTL_PORTCONFGET 0x8005 /* Get port configuration */ -#define IOCTL_PORTCONFSET 0x8006 /* Set port configuration */ -#define IOCTL_SETVID 0x8007 /* Set vendor id */ -#define IOCTL_SETPID 0x8008 /* Set product id */ -#define IOCTL_SETMFG 0x8009 /* Set manufacturer string */ -#define IOCTL_SETPRODUCT 0x800a /* Set product string */ -#define IOCTL_SETSERIAL 0x800b /* Set serial number string */ -#define IOCTL_SETDEVVER 0x800c /* set device version id */ -/* FIXME: where is IOCTL_SETMFG? */ - -/* CP2103 GPIO */ -#define GPIO_0 0x01 -#define GPIO_1 0x02 -#define GPIO_2 0x04 -#define GPIO_3 0x08 -#define GPIO_MASK (GPIO_0|GPIO_1|GPIO_2|GPIO_3) - -/* GetDeviceVersion() return codes */ -#define CP210x_CP2101_VERSION 0x01 -#define CP210x_CP2102_VERSION 0x02 -#define CP210x_CP2103_VERSION 0x03 - -/* Return codes */ -#define CP210x_SUCCESS 0x00 -#define CP210x_DEVICE_NOT_FOUND 0xFF -#define CP210x_INVALID_HANDLE 0x01 -#define CP210x_INVALID_PARAMETER 0x02 -#define CP210x_DEVICE_IO_FAILED 0x03 -#define CP210x_FUNCTION_NOT_SUPPORTED 0x04 -#define CP210x_GLOBAL_DATA_ERROR 0x05 -#define CP210x_FILE_ERROR 0x06 -#define CP210x_COMMAND_FAILED 0x08 -#define CP210x_INVALID_ACCESS_TYPE 0x09 - -/* USB descriptor sizes */ -#define CP210x_MAX_DEVICE_STRLEN 256 -#define CP210x_MAX_PRODUCT_STRLEN 126 -#define CP210x_MAX_SERIAL_STRLEN 63 -#define CP210x_MAX_MAXPOWER 250 - -/* Used to pass variable sized buffers between user and kernel space (ioctls) */ -typedef struct { - char* buf; - size_t len; -} cp2101_buffer_t; - -/* Port config definitions */ -typedef struct { - uint16_t mode; /* Push-pull = 1, Open-drain = 0 */ - uint16_t lowPower; - uint16_t latch; /* Logic high = 1, Logic low = 0 */ -} cp2101_port_state_t; - -typedef struct { - cp2101_port_state_t reset; - cp2101_port_state_t suspend; - uint8_t enhancedFxn; -} cp2101_port_config_t; - -#define PORT_CONFIG_LEN 13 /* Because sizeof() will pad to full words */ +/* cp210x_get_partnum() return codes */ +#define CP210x_PART_UNKNOWN 0x00 +#define CP210x_PART_CP2101 0x01 +#define CP210x_PART_CP2102 0x02 +#define CP210x_PART_CP2103 0x03 + +/* Helper to make usb string size */ +#define USBSTRLEN(x) (x * 2 + 2) + +/* Populates usbstr with: (len) + (0x03) + unicode(str). Each char in str + * takes two bytes in unicode format. + * Returns the resulting length of the string in usbstr. + * This function can accept overlapping usbstr and str as long as the overlap + * does not cause data written to usbstr to overwrite data not yet read from + * str. + */ +static int make_usb_string(char *usbstr, size_t usblen, char *src, + size_t srclen) +{ + int len = 0; + + if (usbstr && usblen >= 2 && src && *src && srclen) { + char *p; + + if (usblen > 255) + usblen = 255; + + p = usbstr + 1; + *p++ = 0x03; + len = 2; + while (srclen && len < usblen) { + *p++ = *src++; + *p++ = 0; + len += 2; + srclen--; + } + *usbstr = (char)len; + } + return len; +} /* - * cp2101_buf_from_user - * Copy a buffer from user space, returning the number of bytes copied - * from ubuf.buf into kbuf. klen is the size of the buffer at kbuf. + * cp210x_usbstr_from_user + * Populate kbuf with a usb string derived from a user space variable. klen + * is the size of the buffer at kbuf. + * Returns the number of bytes used in kbuf. */ -size_t copy_buf_from_user(char *kbuf, unsigned long ubuf, size_t klen) +static size_t cp210x_usbstr_from_user(char *kbuf, unsigned long ubuf, size_t klen) { - cp2101_buffer_t t; + struct cp210x_buffer t; + char* str; + size_t slen; - if (!kbuf || !ubuf || !klen || - copy_from_user(&t, (cp2101_buffer_t *)ubuf, sizeof(t))) + if (!kbuf || !ubuf || !klen) return 0; - if (t.len < klen) - klen = t.len; - if (!t.buf || !t.len || copy_from_user(kbuf, t.buf, klen)) + if (copy_from_user(&t, (struct cp210x_buffer __user *)ubuf, sizeof(t))) return 0; - return klen; + if (!t.buf || !t.len || USBSTRLEN(t.len) > klen) + return 0; + slen = (klen - 2) / 2; + if (t.len < slen) + slen = t.len; + str = kbuf + klen - slen; + if (copy_from_user(str, (u8 __user *)t.buf, slen)) + return 0; + return make_usb_string(kbuf, klen, str, slen); +} + +/* cp210x_has_setmfg + * Returns 1 if the CP210X part includes firmware that allows setting the + * USB MFG descriptor, else 0. As of this writing, no CP210X firmware allows + * this. SiLabs has suggested this may change in future firmware versions or + * parts. + */ +static inline int cp210x_has_setmfg(void) +{ + return 0; } /* - * cp2101_ctlmsg + * cp210x_ctlmsg * A generic usb control message interface. * Returns the actual size of the data read or written within the message, 0 * if no data were read or written, or a negative value to indicate an error. */ -static int cp2101_ctlmsg(struct usb_serial_port* port, u8 request, - u8 requestype, u16 value, u16 index, void* data, u16 size) +static int cp210x_ctlmsg(struct usb_serial_port *port, u8 request, + u8 requestype, u16 value, u16 index, void *data, u16 size) { struct usb_device *dev = port->serial->dev; u8 *tbuf; @@ -317,113 +314,78 @@ static int cp2101_ctlmsg(struct usb_serial_port* port, u8 request, return ret; } -static int cp2101_reset(struct usb_serial_port *port) +static int cp210x_reset(struct usb_serial_port *port) { dbg("%s", __FUNCTION__); #if 1 - /* Is this better than usb_device_reset? It may be. Once a client issues + /* Is this better than usb_device_reset? It may be. Once a client issues * the reset ioctl, it must disconnect and reconnect, since the USB * connections are torn down. We also ignore the error return, since * the part resets and doesn't send one... */ - cp2101_ctlmsg(port, 0xff, 0x40, 0x0008, 0x00, 0, 0); + cp210x_ctlmsg(port, 0xff, 0x40, 0x0008, 0x00, NULL, 0); #else usb_reset_device(port->serial->dev); #endif return 0; } -static int cp2101_get_partnum(struct usb_serial_port *port) +static int cp210x_get_partnum(struct usb_serial_port *port) { - static u8 _partnum = 0; - int ret = CP210x_SUCCESS; - if (!_partnum) { + static u8 _partnum = CP210x_PART_UNKNOWN; + + if (_partnum == CP210x_PART_UNKNOWN) { u8 addr = port->serial->dev->actconfig->interface[0]-> cur_altsetting->endpoint[0].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - if (addr == 0x03 || addr == 0x02) /* The part is a cp2101 */ - _partnum = 0x01; + if (addr == 0x03 || addr == 0x02) + _partnum = CP210x_PART_CP2101; else if (addr == 0x01) { /* Must query part to determine part number */ - if (cp2101_ctlmsg(port, 0xff, 0xc0, 0x370b, 0x00, + if (cp210x_ctlmsg(port, 0xff, 0xc0, 0x370b, 0x00, &_partnum, 1) != 1) - ret = CP210x_DEVICE_IO_FAILED; - } else - ret = CP210x_DEVICE_IO_FAILED; + _partnum = CP210x_PART_UNKNOWN; + } } - dbg("%s - partnum %u err %d", __FUNCTION__, _partnum, ret); - return (ret == CP210x_SUCCESS) ? _partnum : 0; + dbg("%s - partnum %u", __FUNCTION__, _partnum); + return _partnum; } -inline int cp2101_setu16(struct usb_serial_port *port, int cmd, +static inline int cp210x_setu16(struct usb_serial_port *port, int cmd, unsigned int value) { - return cp2101_ctlmsg(port, 0xff, 0x40, 0x3700 | (cmd & 0xff), - value, 0, 0); -} - -/* Populates usbstr with: (len) + (0x03) + unicode(str). Each char in str - * takes up two bytes in unicode format, so the resulting len(usbstr) is - * 2 * len(str) + 2. - * Returns the resulting length of the string in usbstr. - * This function can accept overlapping usbstr and str as long as the overlap - * does not cause data written to usbstr to overwrite data not yet read from - * str. - */ -static int make_usb_string(char* usbstr, size_t usblen, char* src, - size_t srclen) -{ - int len = 0; - - if (usbstr && usblen >= 2 && src && *src && srclen) { - char* p; - - /* The usb string format uses first byte as length */ - if (usblen > 256) - usblen = 256; - - p = usbstr + 1; - *p++ = 0x03; - len = 2; - while (srclen && len < usblen) { - *p++ = *src++; - *p++ = 0; - len += 2; - srclen--; - } - *usbstr = (char)len; - } - return len; + return cp210x_ctlmsg(port, 0xff, 0x40, 0x3700 | (cmd & 0xff), + value, NULL, 0); } /* - * cp2101_setstr + * cp210x_setstr * * Set a USB string descriptor using proprietary cp210x control messages. * Return the number of characters actually written. */ -inline int cp2101_setstr(struct usb_serial_port *port, int cmd, char *usbstr) +static int cp210x_setstr(struct usb_serial_port *port, int cmd, char *usbstr) { unsigned len = usbstr[0]; - int ret = cp2101_ctlmsg(port, 0xff, 0x40, 0x3700 | (cmd & 0xff), 0, + int ret = cp210x_ctlmsg(port, 0xff, 0x40, 0x3700 | (cmd & 0xff), 0, usbstr, len); dbg("%s - cmd 0x%02x len %d ret %d", __FUNCTION__, cmd, len, ret); return ret; } /* Set all gpio simultaneously */ -static int cp2101_gpioset(struct usb_serial_port *port, u8 gpio) +static int cp210x_gpioset(struct usb_serial_port *port, u8 gpio) { dbg("%s - port %d, gpio = 0x%.2x", __FUNCTION__, port->number, gpio); - return cp2101_ctlmsg(port, 0xff, 0x40, 0x37e1, - ((uint16_t)gpio << 8) | GPIO_MASK, 0, 0); + return cp210x_ctlmsg(port, 0xff, 0x40, 0x37e1, + ((uint16_t)gpio << 8) | GPIO_MASK, NULL, 0); } /* Set select gpio bits */ -static int cp2101_gpiosetb(struct usb_serial_port *port, u8 set, u8 clear) +static int cp210x_gpiosetb(struct usb_serial_port *port, u8 set, u8 clear) { u16 gpio = 0; @@ -448,48 +410,49 @@ static int cp2101_gpiosetb(struct usb_serial_port *port, u8 set, u8 clear) dbg("%s - port %d, gpiob = 0x%.4x", __FUNCTION__, port->number, gpio); /* FIXME: how about REQTYPE_HOST_TO_DEVICE instead of 0x40? */ - return cp2101_ctlmsg(port, 0xff, 0x40, 0x37e1, gpio, 0, 0); + return cp210x_ctlmsg(port, 0xff, 0x40, 0x37e1, gpio, NULL, 0); } -static int cp2101_gpioget(struct usb_serial_port *port, u8* gpio) +static int cp210x_gpioget(struct usb_serial_port *port, u8 *gpio) { int ret; dbg("%s - port %d", __FUNCTION__, port->number); /* FIXME: how about REQTYPE_DEVICE_TO_HOST instead of 0xc0? */ - ret = cp2101_ctlmsg(port, 0xff, 0xc0, 0x00c2, 0, gpio, 1); + ret = cp210x_ctlmsg(port, 0xff, 0xc0, 0x00c2, 0, gpio, 1); dbg("%s - gpio = 0x%.2x (%d)", __FUNCTION__, *gpio, ret); return (ret == 1) ? 0 : -1; } -static int cp2101_portconfset(struct usb_serial_port *port, - cp2101_port_config_t* config) +static int cp210x_portconfset(struct usb_serial_port *port, + struct cp210x_port_config *config) { - cp2101_port_config_t lconfig; + struct cp210x_port_config lconfig; int ret; dbg("%s", __FUNCTION__); memcpy(&lconfig, config, sizeof(lconfig)); - /* apparently not implemented yet */ - lconfig.suspend.lowPower = 0; - lconfig.reset.lowPower = 0; - /* Words from cp2103 are MSB */ lconfig.reset.mode = cpu_to_be16(config->reset.mode); - /* lconfig.reset.lowPower = cpu_to_be16(config->reset.lowPower); */ lconfig.reset.latch = cpu_to_be16(config->reset.latch); lconfig.suspend.mode = cpu_to_be16(config->suspend.mode); - /* lconfig.suspend.lowPower = cpu_to_be16(config->suspend.lowPower); */ lconfig.suspend.latch = cpu_to_be16(config->suspend.latch); +#if 0 /* apparently not implemented by CP210X firmware */ + lconfig.reset.lowPower = cpu_to_be16(config->reset.lowPower); + lconfig.suspend.lowPower = cpu_to_be16(config->suspend.lowPower); +#else + lconfig.suspend.lowPower = 0; + lconfig.reset.lowPower = 0; +#endif - ret = cp2101_ctlmsg(port, 0xff, 0x40, 0x370c, 0, &lconfig, - PORT_CONFIG_LEN); - if (ret == PORT_CONFIG_LEN) + ret = cp210x_ctlmsg(port, 0xff, 0x40, 0x370c, 0, &lconfig, + sizeof(struct cp210x_port_config)); + if (ret == sizeof(struct cp210x_port_config)) return 0; else if (ret >= 0) return -1; @@ -497,16 +460,16 @@ static int cp2101_portconfset(struct usb_serial_port *port, return ret; } -static int cp2101_portconfget(struct usb_serial_port *port, - cp2101_port_config_t* config) +static int cp210x_portconfget(struct usb_serial_port *port, + struct cp210x_port_config *config) { int ret; dbg("%s", __FUNCTION__); - ret = cp2101_ctlmsg(port, 0xff, 0xc0, 0x370c, 0, config, - PORT_CONFIG_LEN); - if (ret == PORT_CONFIG_LEN) { + ret = cp210x_ctlmsg(port, 0xff, 0xc0, 0x370c, 0, config, + sizeof(struct cp210x_port_config)); + if (ret == sizeof(struct cp210x_port_config)) { /* Words from cp2103 are MSB */ config->reset.mode = be16_to_cpu(config->reset.mode); config->reset.lowPower = be16_to_cpu(config->reset.lowPower); @@ -529,13 +492,13 @@ static int cp2101_portconfget(struct usb_serial_port *port, } /* - * cp2101_get_config - * Reads from the CP2101 configuration registers + * cp210x_get_config + * Reads from the CP210x configuration registers * 'size' is specified in bytes. * 'data' is a pointer to a pre-allocated array of integers large * enough to hold 'size' bytes (with 4 bytes to each integer) */ -static int cp2101_get_config(struct usb_serial_port* port, u8 request, +static int cp210x_get_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; @@ -555,12 +518,12 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request, request++; /* Issue the request, attempting to read 'size' bytes */ - result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), + result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, 0, buf, size, 300); /* Convert data into an array of integers */ - for (i=0; iserial; @@ -603,12 +566,12 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request, buf[i] = cpu_to_le32(data[i]); if (size > 2) { - result = usb_control_msg (serial->dev, + result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, 0, buf, size, 300); } else { - result = usb_control_msg (serial->dev, + result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], 0, NULL, 0, 300); @@ -623,40 +586,35 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request, return -EPROTO; } - /* Single data value */ - result = usb_control_msg (serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, data[0], - 0, NULL, 0, 300); return 0; } /* - * cp2101_set_config_single - * Convenience function for calling cp2101_set_config on single data values + * cp210x_set_config_single + * Convenience function for calling cp210x_set_config on single data values * without requiring an integer pointer */ -static inline int cp2101_set_config_single(struct usb_serial_port* port, +static inline int cp210x_set_config_single(struct usb_serial_port *port, u8 request, unsigned int data) { - return cp2101_set_config(port, request, &data, 2); + return cp210x_set_config(port, request, &data, 2); } -static int cp2101_open (struct usb_serial_port *port, struct file *filp) +static int cp210x_open(struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; int result; dbg("%s - port %d", __FUNCTION__, port->number); - if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { + if (cp210x_set_config_single(port, CP2101_UART, UART_ENABLE)) { dev_err(&port->dev, "%s - Unable to enable UART\n", __FUNCTION__); return -EPROTO; } /* Start reading from the device */ - usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, @@ -671,15 +629,15 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) } /* Configure the termios structure */ - cp2101_get_termios(port); + cp210x_get_termios(port); /* Set the DTR and RTS pins low */ - cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); + cp210x_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); return 0; } -static void cp2101_cleanup (struct usb_serial_port *port) +static void cp210x_cleanup(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; @@ -694,7 +652,7 @@ static void cp2101_cleanup (struct usb_serial_port *port) } } -static void cp2101_close (struct usb_serial_port *port, struct file * filp) +static void cp210x_close(struct usb_serial_port *port, struct file *filp) { dbg("%s - port %d", __FUNCTION__, port->number); @@ -703,164 +661,156 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp) usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); - cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); + cp210x_set_config_single(port, CP2101_UART, UART_DISABLE); } -static int cp2101_ioctl(struct usb_serial_port *port, struct file *file, +static int cp210x_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) { dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd); switch (cmd) { - + case TIOCMGET: { - int result = cp2101_tiocmget(port, file); - if (copy_to_user(&arg, &result, sizeof(int))) - return -EFAULT; + int result = cp210x_tiocmget(port, file); + if (copy_to_user((int __user *)&arg, &result, sizeof(int))) + return -EFAULT; return 0; } break; case TIOCMSET: case TIOCMBIS: - case TIOCMBIC: { int val = 0; - if (copy_from_user(&val, &arg, sizeof(int))) + if (copy_from_user(&val, (int __user *)&arg, sizeof(int))) return -EFAULT; /* this looks wrong: TIOCMSET isn't going to work right */ - if (cp2101_tiocmset(port, file, cmd==TIOCMBIC ? 0 : val, + if (cp210x_tiocmset(port, file, cmd==TIOCMBIC ? 0 : val, cmd==TIOCMBIC ? val : 0)) return -EFAULT; return 0; } break; - case IOCTL_GPIOGET: - if (cp2101_get_partnum(port) == CP210x_CP2103_VERSION) { + case CP210x_IOCTL_GPIOGET: + if (cp210x_get_partnum(port) == CP210x_PART_CP2103) { u8 gpio = 0; - if (!cp2101_gpioget(port, &gpio) && !copy_to_user((u8*)arg, - &gpio, sizeof(gpio))) + if (!cp210x_gpioget(port, &gpio) && !copy_to_user( + (u8 __user *)arg, &gpio, sizeof(gpio))) return 0; } return -EFAULT; break; - case IOCTL_GPIOSET: - if (cp2101_get_partnum(port) == CP210x_CP2103_VERSION && - !cp2101_gpioset(port, arg)) + case CP210x_IOCTL_GPIOSET: + if (cp210x_get_partnum(port) == CP210x_PART_CP2103 && + !cp210x_gpioset(port, arg)) return 0; return -EFAULT; break; - case IOCTL_GPIOBIC: - case IOCTL_GPIOBIS: - if (cp2101_get_partnum(port) == CP210x_CP2103_VERSION && - !cp2101_gpiosetb(port, (cmd==IOCTL_GPIOBIC) ? 0 : arg, - (cmd==IOCTL_GPIOBIC) ? arg : 0)) + case CP210x_IOCTL_GPIOBIC: + case CP210x_IOCTL_GPIOBIS: + if (cp210x_get_partnum(port) == CP210x_PART_CP2103 && + !cp210x_gpiosetb(port, + (cmd==CP210x_IOCTL_GPIOBIC) ? 0 : arg, + (cmd==CP210x_IOCTL_GPIOBIC) ? arg : 0)) return 0; return -EFAULT; break; - case IOCTL_DEVICERESET: - return cp2101_reset(port); + case CP210x_IOCTL_DEVICERESET: + return cp210x_reset(port); break; - case IOCTL_PORTCONFGET: + case CP210x_IOCTL_PORTCONFGET: { - cp2101_port_config_t config; - if (!cp2101_portconfget(port, &config) && !copy_to_user( - (cp2101_port_config_t*)arg, &config, - sizeof(config))) + struct cp210x_port_config config; + if (!cp210x_portconfget(port, &config) && !copy_to_user( + (struct cp210x_port_config __user *)arg, + &config, sizeof(config))) return 0; } return -EFAULT; break; - case IOCTL_PORTCONFSET: + case CP210x_IOCTL_PORTCONFSET: { - cp2101_port_config_t config; - if (!copy_from_user(&config, (cp2101_port_config_t*)arg, + struct cp210x_port_config config; + if (!copy_from_user(&config, (struct cp210x_port_config __user *)arg, sizeof(config)) && - !cp2101_portconfset(port, &config)) + !cp210x_portconfset(port, &config)) return 0; return -EFAULT; } break; - case IOCTL_SETVID: + case CP210x_IOCTL_SETVID: { unsigned int vid; - if (!copy_from_user(&vid, (unsigned int *)arg, + if (!copy_from_user(&vid, (unsigned int __user *)arg, sizeof(unsigned int)) && - !cp2101_setu16(port, 0x01, vid)) + !cp210x_setu16(port, 0x01, vid)) return 0; return -EFAULT; } break; - case IOCTL_SETPID: + case CP210x_IOCTL_SETPID: { unsigned int pid; - if (!copy_from_user(&pid, (unsigned int *)arg, + if (!copy_from_user(&pid, (unsigned int __user *)arg, sizeof(unsigned int)) && - !cp2101_setu16(port, 0x02, pid)) + !cp210x_setu16(port, 0x02, pid)) return 0; return -EFAULT; } break; - case IOCTL_SETMFG: -#if 0 /* Silicon Labs apparently doesn't provide for setting of mfg desc */ - { - char usbstr[CP210x_MAX_MFG_STRLEN * 2 + 2]; - size_t len = copy_buf_from_user(usbstr + sizeof(usbstr) - - CP210x_MAX_MFG_STRLEN, arg, - CP210x_MAX_MFG_STRLEN); - len = make_usb_string(usbstr, sizeof(usbstr), str, len); - if (len && cp2101_setstr(port, 0x00, usbstr) == len) + case CP210x_IOCTL_SETMFG: + if (cp210x_has_setmfg()) { + char usbstr[USBSTRLEN(CP210x_MAX_MFG_STRLEN)]; + size_t len = cp210x_usbstr_from_user(usbstr, arg, + sizeof(usbstr)); + if (len && cp210x_setstr(port, 0x00, usbstr) == len) return 0; - return -EFAULT; } -#endif + return -EFAULT; break; - case IOCTL_SETPRODUCT: + case CP210x_IOCTL_SETPRODUCT: { - char usbstr[CP210x_MAX_PRODUCT_STRLEN * 2 + 2]; - char* str = usbstr + sizeof(usbstr) - CP210x_MAX_PRODUCT_STRLEN; - size_t len = copy_buf_from_user(str, arg, - CP210x_MAX_PRODUCT_STRLEN); - len = make_usb_string(usbstr, sizeof(usbstr), str, len); - if (len && cp2101_setstr(port, 0x03, usbstr) == len) + char usbstr[USBSTRLEN(CP210x_MAX_PRODUCT_STRLEN)]; + size_t len = cp210x_usbstr_from_user(usbstr, arg, + sizeof(usbstr)); + if (len && cp210x_setstr(port, 0x03, usbstr) == len) return 0; return -EFAULT; } break; - case IOCTL_SETSERIAL: + case CP210x_IOCTL_SETSERIAL: { - char usbstr[CP210x_MAX_SERIAL_STRLEN * 2 + 2]; - char* str = usbstr + sizeof(usbstr) - CP210x_MAX_SERIAL_STRLEN; - size_t len = copy_buf_from_user(str, arg, - CP210x_MAX_SERIAL_STRLEN); - len = make_usb_string(usbstr, sizeof(usbstr), str, len); - if (len && cp2101_setstr(port, 0x04, usbstr) == len) + char usbstr[USBSTRLEN(CP210x_MAX_SERIAL_STRLEN)]; + size_t len = cp210x_usbstr_from_user(usbstr, arg, + sizeof(usbstr)); + if (len && cp210x_setstr(port, 0x04, usbstr) == len) return 0; return -EFAULT; } break; - case IOCTL_SETDEVVER: + case CP210x_IOCTL_SETDEVVER: { unsigned int ver; - if (!copy_from_user(&ver, (unsigned int *)arg, + if (!copy_from_user(&ver, (unsigned int __user *)arg, sizeof(unsigned int)) && - !cp2101_setu16(port, 0x07, ver)) + !cp210x_setu16(port, 0x07, ver)) return 0; return -EFAULT; } @@ -875,12 +825,12 @@ static int cp2101_ioctl(struct usb_serial_port *port, struct file *file, } /* - * cp2101_get_termios + * cp210x_get_termios * Reads the baud rate, data bits, parity, stop bits and flow control mode * from the device, corrects any unsupported values, and configures the * termios structure to reflect the state of the device */ -static void cp2101_get_termios (struct usb_serial_port *port) +static void cp210x_get_termios(struct usb_serial_port *port) { unsigned int cflag, modem_ctl[4]; int baud; @@ -893,7 +843,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) return; } - cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); + cp210x_get_config(port, CP2101_BAUDRATE, &baud, 2); /* Convert to baudrate */ if (baud) baud = BAUD_RATE_GEN_FREQ / baud; @@ -903,7 +853,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) tty_encode_baud_rate(port->tty, baud, baud); cflag = port->tty->termios->c_cflag; - cp2101_get_config(port, CP2101_BITS, &bits, 2); + cp210x_get_config(port, CP2101_BITS, &bits, 2); cflag &= ~CSIZE; switch(bits & BITS_DATA_MASK) { case BITS_DATA_5: @@ -928,7 +878,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp210x_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown number of data bits, " @@ -936,7 +886,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp210x_set_config(port, CP2101_BITS, &bits, 2); break; } @@ -959,21 +909,21 @@ static void cp2101_get_termios (struct usb_serial_port *port) "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp210x_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_PARITY_SPACE: dbg("%s - parity = SPACE (not supported, " "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp210x_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown parity mode, " "disabling parity", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp210x_set_config(port, CP2101_BITS, &bits, 2); break; } @@ -986,7 +936,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - stop bits = 1.5 (not supported, " "using 1 stop bit)", __FUNCTION__); bits &= ~BITS_STOP_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp210x_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_STOP_2: dbg("%s - stop bits = 2", __FUNCTION__); @@ -996,11 +946,11 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - Unknown number of stop bits, " "using 1 stop bit", __FUNCTION__); bits &= ~BITS_STOP_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp210x_set_config(port, CP2101_BITS, &bits, 2); break; } - cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); + cp210x_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); if (modem_ctl[0] & 0x0008) { dbg("%s - flow control = CRTSCTS", __FUNCTION__); cflag |= CRTSCTS; @@ -1012,11 +962,11 @@ static void cp2101_get_termios (struct usb_serial_port *port) port->tty->termios->c_cflag = cflag; } -static void cp2101_set_termios (struct usb_serial_port *port, +static void cp210x_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; - int baud=0, bits; + int baud = 0, bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __FUNCTION__, port->number); @@ -1063,7 +1013,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, if (baud) { dbg("%s - Setting baud rate to %d baud", __FUNCTION__, baud); - if (cp2101_set_config_single(port, CP2101_BAUDRATE, + if (cp210x_set_config_single(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ / baud))) { dev_err(&port->dev, "Baud rate requested not " "supported by device\n"); @@ -1076,7 +1026,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - cp2101_get_config(port, CP2101_BITS, &bits, 2); + cp210x_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_DATA_MASK; switch (cflag & CSIZE) { case CS5: @@ -1106,13 +1056,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits |= BITS_DATA_8; break; } - if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) + if (cp210x_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of data bits requested " "not supported by device\n"); } if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { - cp2101_get_config(port, CP2101_BITS, &bits, 2); + cp210x_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & PARODD) { @@ -1123,13 +1073,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, dbg("%s - parity = EVEN", __FUNCTION__); } } - if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) + if (cp210x_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Parity mode not supported " "by device\n"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { - cp2101_get_config(port, CP2101_BITS, &bits, 2); + cp210x_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; @@ -1138,13 +1088,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits |= BITS_STOP_1; dbg("%s - stop bits = 1", __FUNCTION__); } - if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) + if (cp210x_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of stop bits requested " "not supported by device\n"); } if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { - cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); + cp210x_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __FUNCTION__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); @@ -1164,12 +1114,12 @@ static void cp2101_set_termios (struct usb_serial_port *port, dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", __FUNCTION__, modem_ctl[0], modem_ctl[1], modem_ctl[2], modem_ctl[3]); - cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); + cp210x_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); } } -static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, +static int cp210x_tiocmset(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear) { int control = 0; @@ -1195,17 +1145,17 @@ static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, dbg("%s - control = 0x%.4x", __FUNCTION__, control); - return cp2101_set_config(port, CP2101_CONTROL, &control, 2); + return cp210x_set_config(port, CP2101_CONTROL, &control, 2); } -static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) +static int cp210x_tiocmget(struct usb_serial_port *port, struct file *file) { int control, result; dbg("%s - port %d", __FUNCTION__, port->number); - cp2101_get_config(port, CP2101_CONTROL, &control, 1); + cp210x_get_config(port, CP2101_CONTROL, &control, 1); result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) |((control & CONTROL_RTS) ? TIOCM_RTS : 0) @@ -1219,7 +1169,7 @@ static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) return result; } -static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) +static void cp210x_break_ctl(struct usb_serial_port *port, int break_state) { int state; @@ -1230,40 +1180,40 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) state = BREAK_ON; dbg("%s - turning break %s", __FUNCTION__, state==BREAK_OFF ? "off" : "on"); - cp2101_set_config(port, CP2101_BREAK, &state, 2); + cp210x_set_config(port, CP2101_BREAK, &state, 2); } -static int cp2101_startup (struct usb_serial *serial) +static int cp210x_startup(struct usb_serial *serial) { /* CP2101 buffers behave strangely unless device is reset */ usb_reset_device(serial->dev); return 0; } -static void cp2101_shutdown (struct usb_serial *serial) +static void cp210x_shutdown(struct usb_serial *serial) { int i; dbg("%s", __FUNCTION__); /* Stop reads and writes on all ports */ - for (i=0; i < serial->num_ports; ++i) { - cp2101_cleanup(serial->port[i]); + for (i = 0; i < serial->num_ports; ++i) { + cp210x_cleanup(serial->port[i]); } } -static int __init cp2101_init (void) +static int __init cp210x_init(void) { int retval; - retval = usb_serial_register(&cp2101_device); + retval = usb_serial_register(&cp210x_device); if (retval) return retval; /* Failed to register */ - retval = usb_register(&cp2101_driver); + retval = usb_register(&cp210x_driver); if (retval) { /* Failed to register */ - usb_serial_deregister(&cp2101_device); + usb_serial_deregister(&cp210x_device); return retval; } @@ -1272,14 +1222,14 @@ static int __init cp2101_init (void) return 0; } -static void __exit cp2101_exit (void) +static void __exit cp210x_exit(void) { - usb_deregister (&cp2101_driver); - usb_serial_deregister (&cp2101_device); + usb_deregister(&cp210x_driver); + usb_serial_deregister(&cp210x_device); } -module_init(cp2101_init); -module_exit(cp2101_exit); +module_init(cp210x_init); +module_exit(cp210x_exit); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_VERSION(DRIVER_VERSION);