X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fserial%2Fcypress_m8.c;h=7212fbe3b6f28506b037475ed9be5bcae38f7d29;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=012e63e05806076b06a42dc1d3d592fa45fc0fce;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 012e63e05..7212fbe3b 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -98,10 +98,16 @@ static struct usb_device_id id_table_cyphidcomrs232 [] = { { } /* Terminating entry */ }; +static struct usb_device_id id_table_nokiaca42v2 [] = { + { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, + { } /* Terminating entry */ +}; + static struct usb_device_id id_table_combined [] = { { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, + { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, { } /* Terminating entry */ }; @@ -112,6 +118,7 @@ static struct usb_driver cypress_driver = { .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table_combined, + .no_dynamic_id = 1, }; struct cypress_private { @@ -148,6 +155,7 @@ struct cypress_buf { /* function prototypes for the Cypress USB to serial device */ static int cypress_earthmate_startup (struct usb_serial *serial); static int cypress_hidcom_startup (struct usb_serial *serial); +static int cypress_ca42v2_startup (struct usb_serial *serial); static void cypress_shutdown (struct usb_serial *serial); static int cypress_open (struct usb_serial_port *port, struct file *filp); static void cypress_close (struct usb_serial_port *port, struct file *filp); @@ -176,10 +184,12 @@ static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, u static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count); -static struct usb_serial_device_type cypress_earthmate_device = { - .owner = THIS_MODULE, - .name = "DeLorme Earthmate USB", - .short_name = "earthmate", +static struct usb_serial_driver cypress_earthmate_device = { + .driver = { + .owner = THIS_MODULE, + .name = "earthmate", + }, + .description = "DeLorme Earthmate USB", .id_table = id_table_earthmate, .num_interrupt_in = 1, .num_interrupt_out = 1, @@ -203,10 +213,12 @@ static struct usb_serial_device_type cypress_earthmate_device = { .write_int_callback = cypress_write_int_callback, }; -static struct usb_serial_device_type cypress_hidcom_device = { - .owner = THIS_MODULE, - .name = "HID->COM RS232 Adapter", - .short_name = "cyphidcom", +static struct usb_serial_driver cypress_hidcom_device = { + .driver = { + .owner = THIS_MODULE, + .name = "cyphidcom", + }, + .description = "HID->COM RS232 Adapter", .id_table = id_table_cyphidcomrs232, .num_interrupt_in = 1, .num_interrupt_out = 1, @@ -230,6 +242,34 @@ static struct usb_serial_device_type cypress_hidcom_device = { .write_int_callback = cypress_write_int_callback, }; +static struct usb_serial_driver cypress_ca42v2_device = { + .driver = { + .owner = THIS_MODULE, + .name = "nokiaca42v2", + }, + .description = "Nokia CA-42 V2 Adapter", + .id_table = id_table_nokiaca42v2, + .num_interrupt_in = 1, + .num_interrupt_out = 1, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, + .attach = cypress_ca42v2_startup, + .shutdown = cypress_shutdown, + .open = cypress_open, + .close = cypress_close, + .write = cypress_write, + .write_room = cypress_write_room, + .ioctl = cypress_ioctl, + .set_termios = cypress_set_termios, + .tiocmget = cypress_tiocmget, + .tiocmset = cypress_tiocmset, + .chars_in_buffer = cypress_chars_in_buffer, + .throttle = cypress_throttle, + .unthrottle = cypress_unthrottle, + .read_int_callback = cypress_read_int_callback, + .write_int_callback = cypress_write_int_callback, +}; /***************************************************************************** * Cypress serial helper functions @@ -281,6 +321,12 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m __FUNCTION__); new_baudrate = priv->baud_rate; } + } else if (priv->chiptype == CT_CA42V2) { + if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { + err("%s - failed setting baud rate, unsupported speed", + __FUNCTION__); + new_baudrate = priv->baud_rate; + } } else if (priv->chiptype == CT_GENERIC) { if ( (new_baudrate = mask_to_rate(baud_mask)) == -1) { err("%s - failed setting baud rate, unsupported speed", @@ -352,7 +398,7 @@ static int cypress_serial_control (struct usb_serial_port *port, unsigned baud_m } while (retval != 5 && retval != ENODEV); if (retval != 5) { - err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval); + err("%s - failed to retrieve serial line settings - %d", __FUNCTION__, retval); return retval; } else { spin_lock_irqsave(&priv->lock, flags); @@ -430,11 +476,10 @@ static int generic_startup (struct usb_serial *serial) dbg("%s - port %d", __FUNCTION__, serial->port[0]->number); - priv = kmalloc(sizeof (struct cypress_private), GFP_KERNEL); + priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL); if (!priv) return -ENOMEM; - memset(priv, 0x00, sizeof (struct cypress_private)); spin_lock_init(&priv->lock); priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE); if (priv->buf == NULL) { @@ -453,8 +498,8 @@ static int generic_startup (struct usb_serial *serial) priv->cbr_mask = B300; usb_set_serial_port_data(serial->port[0], priv); - return (0); -} + return 0; +} static int cypress_earthmate_startup (struct usb_serial *serial) @@ -464,14 +509,15 @@ static int cypress_earthmate_startup (struct usb_serial *serial) dbg("%s", __FUNCTION__); if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number); + dbg("%s - Failed setting up port %d", __FUNCTION__, + serial->port[0]->number); return 1; } priv = usb_get_serial_port_data(serial->port[0]); priv->chiptype = CT_EARTHMATE; - - return (0); + + return 0; } /* cypress_earthmate_startup */ @@ -482,17 +528,37 @@ static int cypress_hidcom_startup (struct usb_serial *serial) dbg("%s", __FUNCTION__); if (generic_startup(serial)) { - dbg("%s - Failed setting up port %d", __FUNCTION__, serial->port[0]->number); + dbg("%s - Failed setting up port %d", __FUNCTION__, + serial->port[0]->number); return 1; } priv = usb_get_serial_port_data(serial->port[0]); priv->chiptype = CT_CYPHIDCOM; - return (0); + return 0; } /* cypress_hidcom_startup */ +static int cypress_ca42v2_startup (struct usb_serial *serial) +{ + struct cypress_private *priv; + + dbg("%s", __FUNCTION__); + + if (generic_startup(serial)) { + dbg("%s - Failed setting up port %d", __FUNCTION__, + serial->port[0]->number); + return 1; + } + + priv = usb_get_serial_port_data(serial->port[0]); + priv->chiptype = CT_CA42V2; + + return 0; +} /* cypress_ca42v2_startup */ + + static void cypress_shutdown (struct usb_serial *serial) { struct cypress_private *priv; @@ -608,8 +674,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp) timeout = max((HZ*2560)/bps,HZ/10); else timeout = 2*HZ; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); + schedule_timeout_interruptible(timeout); dbg("%s - stopping urbs", __FUNCTION__); usb_kill_urb (port->interrupt_in_urb); @@ -909,7 +974,8 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi } /* cypress_ioctl */ -static void cypress_set_termios (struct usb_serial_port *port, struct termios *old_termios) +static void cypress_set_termios (struct usb_serial_port *port, + struct termios *old_termios) { struct cypress_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; @@ -918,7 +984,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o unsigned long flags; __u8 oldlines; int linechange = 0; - + dbg("%s - port %d", __FUNCTION__, port->number); tty = port->tty; @@ -931,10 +997,16 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o if (!priv->termios_initialized) { if (priv->chiptype == CT_EARTHMATE) { *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL; + tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | + CLOCAL; } else if (priv->chiptype == CT_CYPHIDCOM) { *(tty->termios) = tty_std_termios; - tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | + CLOCAL; + } else if (priv->chiptype == CT_CA42V2) { + *(tty->termios) = tty_std_termios; + tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | + CLOCAL; } priv->termios_initialized = 1; } @@ -946,12 +1018,15 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o /* check if there are new settings */ if (old_termios) { if ((cflag != old_termios->c_cflag) || - (RELEVANT_IFLAG(iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("%s - attempting to set new termios settings", __FUNCTION__); - /* should make a copy of this in case something goes wrong in the function, we can restore it */ + (RELEVANT_IFLAG(iflag) != + RELEVANT_IFLAG(old_termios->c_iflag))) { + dbg("%s - attempting to set new termios settings", + __FUNCTION__); + /* should make a copy of this in case something goes + * wrong in the function, we can restore it */ spin_lock_irqsave(&priv->lock, flags); priv->tmp_termios = *(tty->termios); - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); } else { dbg("%s - nothing to do, exiting", __FUNCTION__); return; @@ -962,21 +1037,34 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o /* set number of data bits, parity, stop bits */ /* when parity is disabled the parity type bit is ignored */ - stop_bits = cflag & CSTOPB ? 1 : 0; /* 1 means 2 stop bits, 0 means 1 stop bit */ - + /* 1 means 2 stop bits, 0 means 1 stop bit */ + stop_bits = cflag & CSTOPB ? 1 : 0; + if (cflag & PARENB) { parity_enable = 1; - parity_type = cflag & PARODD ? 1 : 0; /* 1 means odd parity, 0 means even parity */ + /* 1 means odd parity, 0 means even parity */ + parity_type = cflag & PARODD ? 1 : 0; } else parity_enable = parity_type = 0; if (cflag & CSIZE) { switch (cflag & CSIZE) { - case CS5: data_bits = 0; break; - case CS6: data_bits = 1; break; - case CS7: data_bits = 2; break; - case CS8: data_bits = 3; break; - default: err("%s - CSIZE was set, but not CS5-CS8", __FUNCTION__); data_bits = 3; + case CS5: + data_bits = 0; + break; + case CS6: + data_bits = 1; + break; + case CS7: + data_bits = 2; + break; + case CS8: + data_bits = 3; + break; + default: + err("%s - CSIZE was set, but not CS5-CS8", + __FUNCTION__); + data_bits = 3; } } else data_bits = 3; @@ -991,63 +1079,85 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o } else { baud_mask = (cflag & CBAUD); switch(baud_mask) { - case B300: dbg("%s - setting baud 300bps", __FUNCTION__); break; - case B600: dbg("%s - setting baud 600bps", __FUNCTION__); break; - case B1200: dbg("%s - setting baud 1200bps", __FUNCTION__); break; - case B2400: dbg("%s - setting baud 2400bps", __FUNCTION__); break; - case B4800: dbg("%s - setting baud 4800bps", __FUNCTION__); break; - case B9600: dbg("%s - setting baud 9600bps", __FUNCTION__); break; - case B19200: dbg("%s - setting baud 19200bps", __FUNCTION__); break; - case B38400: dbg("%s - setting baud 38400bps", __FUNCTION__); break; - case B57600: dbg("%s - setting baud 57600bps", __FUNCTION__); break; - case B115200: dbg("%s - setting baud 115200bps", __FUNCTION__); break; - default: dbg("%s - unknown masked baud rate", __FUNCTION__); + case B300: + dbg("%s - setting baud 300bps", __FUNCTION__); + break; + case B600: + dbg("%s - setting baud 600bps", __FUNCTION__); + break; + case B1200: + dbg("%s - setting baud 1200bps", __FUNCTION__); + break; + case B2400: + dbg("%s - setting baud 2400bps", __FUNCTION__); + break; + case B4800: + dbg("%s - setting baud 4800bps", __FUNCTION__); + break; + case B9600: + dbg("%s - setting baud 9600bps", __FUNCTION__); + break; + case B19200: + dbg("%s - setting baud 19200bps", __FUNCTION__); + break; + case B38400: + dbg("%s - setting baud 38400bps", __FUNCTION__); + break; + case B57600: + dbg("%s - setting baud 57600bps", __FUNCTION__); + break; + case B115200: + dbg("%s - setting baud 115200bps", __FUNCTION__); + break; + default: + dbg("%s - unknown masked baud rate", __FUNCTION__); } priv->line_control = (CONTROL_DTR | CONTROL_RTS); } spin_unlock_irqrestore(&priv->lock, flags); - - dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, %d data_bits (+5)", __FUNCTION__, - stop_bits, parity_enable, parity_type, data_bits); - cypress_serial_control(port, baud_mask, data_bits, stop_bits, parity_enable, - parity_type, 0, CYPRESS_SET_CONFIG); + dbg("%s - sending %d stop_bits, %d parity_enable, %d parity_type, " + "%d data_bits (+5)", __FUNCTION__, stop_bits, + parity_enable, parity_type, data_bits); - /* we perform a CYPRESS_GET_CONFIG so that the current settings are filled into the private structure - * this should confirm that all is working if it returns what we just set */ + cypress_serial_control(port, baud_mask, data_bits, stop_bits, + parity_enable, parity_type, 0, CYPRESS_SET_CONFIG); + + /* we perform a CYPRESS_GET_CONFIG so that the current settings are + * filled into the private structure this should confirm that all is + * working if it returns what we just set */ cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); - /* Here we can define custom tty settings for devices - * - * the main tty termios flag base comes from empeg.c - */ + /* Here we can define custom tty settings for devices; the main tty + * termios flag base comes from empeg.c */ - spin_lock_irqsave(&priv->lock, flags); + spin_lock_irqsave(&priv->lock, flags); if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) { - - dbg("Using custom termios settings for a baud rate of 4800bps."); + dbg("Using custom termios settings for a baud rate of " + "4800bps."); /* define custom termios settings for NMEA protocol */ tty->termios->c_iflag /* input modes - */ - &= ~(IGNBRK /* disable ignore break */ - | BRKINT /* disable break causes interrupt */ - | PARMRK /* disable mark parity errors */ - | ISTRIP /* disable clear high bit of input characters */ - | INLCR /* disable translate NL to CR */ - | IGNCR /* disable ignore CR */ - | ICRNL /* disable translate CR to NL */ - | IXON); /* disable enable XON/XOFF flow control */ - + &= ~(IGNBRK /* disable ignore break */ + | BRKINT /* disable break causes interrupt */ + | PARMRK /* disable mark parity errors */ + | ISTRIP /* disable clear high bit of input char */ + | INLCR /* disable translate NL to CR */ + | IGNCR /* disable ignore CR */ + | ICRNL /* disable translate CR to NL */ + | IXON); /* disable enable XON/XOFF flow control */ + tty->termios->c_oflag /* output modes */ - &= ~OPOST; /* disable postprocess output characters */ - - tty->termios->c_lflag /* line discipline modes */ - &= ~(ECHO /* disable echo input characters */ - | ECHONL /* disable echo new line */ - | ICANON /* disable erase, kill, werase, and rprnt special characters */ - | ISIG /* disable interrupt, quit, and suspend special characters */ - | IEXTEN); /* disable non-POSIX special characters */ + &= ~OPOST; /* disable postprocess output char */ + tty->termios->c_lflag /* line discipline modes */ + &= ~(ECHO /* disable echo input characters */ + | ECHONL /* disable echo new line */ + | ICANON /* disable erase, kill, werase, and rprnt + special characters */ + | ISIG /* disable interrupt, quit, and suspend + special characters */ + | IEXTEN); /* disable non-POSIX special characters */ } /* CT_CYPHIDCOM: Application should handle this for device */ linechange = (priv->line_control != oldlines); @@ -1060,7 +1170,7 @@ static void cypress_set_termios (struct usb_serial_port *port, struct termios *o } } /* cypress_set_termios */ - + /* returns amount of data still left in soft buffer */ static int cypress_chars_in_buffer(struct usb_serial_port *port) { @@ -1088,7 +1198,7 @@ static void cypress_throttle (struct usb_serial_port *port) spin_lock_irqsave(&priv->lock, flags); priv->rx_flags = THROTTLED; - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); } @@ -1110,7 +1220,8 @@ static void cypress_unthrottle (struct usb_serial_port *port) result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); if (result) - dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); + dev_err(&port->dev, "%s - failed submitting read urb, " + "error %d\n", __FUNCTION__, result); } } @@ -1122,7 +1233,7 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs) struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; unsigned long flags; - char tty_flag = TTY_NORMAL; + char tty_flag = TTY_NORMAL; int havedata = 0; int bytes = 0; int result; @@ -1131,7 +1242,8 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs) dbg("%s - port %d", __FUNCTION__, port->number); if (urb->status) { - dbg("%s - nonzero read status received: %d", __FUNCTION__, urb->status); + dbg("%s - nonzero read status received: %d", __FUNCTION__, + urb->status); return; } @@ -1155,51 +1267,55 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs) case 32: /* This is for the CY7C64013... */ priv->current_status = data[0] & 0xF8; - bytes = data[1]+2; - i=2; + bytes = data[1] + 2; + i = 2; if (bytes > 2) havedata = 1; break; case 8: /* This is for the CY7C63743... */ priv->current_status = data[0] & 0xF8; - bytes = (data[0] & 0x07)+1; - i=1; + bytes = (data[0] & 0x07) + 1; + i = 1; if (bytes > 1) havedata = 1; break; default: - dbg("%s - wrong packet size - received %d bytes", __FUNCTION__, urb->actual_length); + dbg("%s - wrong packet size - received %d bytes", + __FUNCTION__, urb->actual_length); spin_unlock_irqrestore(&priv->lock, flags); goto continue_read; } spin_unlock_irqrestore(&priv->lock, flags); - usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data); + usb_serial_debug_data (debug, &port->dev, __FUNCTION__, + urb->actual_length, data); spin_lock_irqsave(&priv->lock, flags); /* check to see if status has changed */ if (priv != NULL) { if (priv->current_status != priv->prev_status) { - priv->diff_status |= priv->current_status ^ priv->prev_status; + priv->diff_status |= priv->current_status ^ + priv->prev_status; wake_up_interruptible(&priv->delta_msr_wait); priv->prev_status = priv->current_status; } } - spin_unlock_irqrestore(&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); - /* hangup, as defined in acm.c... this might be a bad place for it though */ - if (tty && !(tty->termios->c_cflag & CLOCAL) && !(priv->current_status & UART_CD)) { + /* hangup, as defined in acm.c... this might be a bad place for it + * though */ + if (tty && !(tty->termios->c_cflag & CLOCAL) && + !(priv->current_status & UART_CD)) { dbg("%s - calling hangup", __FUNCTION__); tty_hangup(tty); goto continue_read; } - /* There is one error bit... I'm assuming it is a parity error indicator - * as the generic firmware will set this bit to 1 if a parity error occurs. - * I can not find reference to any other error events. - * - */ + /* There is one error bit... I'm assuming it is a parity error + * indicator as the generic firmware will set this bit to 1 if a + * parity error occurs. + * I can not find reference to any other error events. */ spin_lock_irqsave(&priv->lock, flags); if (priv->current_status & CYP_ERROR) { spin_unlock_irqrestore(&priv->lock, flags); @@ -1210,36 +1326,38 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs) /* process read if there is data other than line status */ if (tty && (bytes > i)) { + bytes = tty_buffer_request_room(tty, bytes); for (; i < bytes ; ++i) { - dbg("pushing byte number %d - %d - %c",i,data[i],data[i]); - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { - tty_flip_buffer_push(tty); - } + dbg("pushing byte number %d - %d - %c", i, data[i], + data[i]); tty_insert_flip_char(tty, data[i], tty_flag); } tty_flip_buffer_push(port->tty); } spin_lock_irqsave(&priv->lock, flags); - priv->bytes_in += bytes; /* control and status byte(s) are also counted */ + /* control and status byte(s) are also counted */ + priv->bytes_in += bytes; spin_unlock_irqrestore(&priv->lock, flags); continue_read: - - /* Continue trying to always read... unless the port has closed. */ + + /* Continue trying to always read... unless the port has closed. */ if (port->open_count > 0) { - usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, - usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress), - port->interrupt_in_urb->transfer_buffer, - port->interrupt_in_urb->transfer_buffer_length, - cypress_read_int_callback, port, - interval); - result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, + usb_rcvintpipe(port->serial->dev, + port->interrupt_in_endpointAddress), + port->interrupt_in_urb->transfer_buffer, + port->interrupt_in_urb->transfer_buffer_length, + cypress_read_int_callback, port, interval); + result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); + if (result) + dev_err(&urb->dev->dev, "%s - failed resubmitting " + "read urb, error %d\n", __FUNCTION__, + result); } - + return; } /* cypress_read_int_callback */ @@ -1487,6 +1605,9 @@ static int __init cypress_init(void) retval = usb_serial_register(&cypress_hidcom_device); if (retval) goto failed_hidcom_register; + retval = usb_serial_register(&cypress_ca42v2_device); + if (retval) + goto failed_ca42v2_register; retval = usb_register(&cypress_driver); if (retval) goto failed_usb_register; @@ -1495,6 +1616,8 @@ static int __init cypress_init(void) return 0; failed_usb_register: usb_deregister(&cypress_driver); +failed_ca42v2_register: + usb_serial_deregister(&cypress_ca42v2_device); failed_hidcom_register: usb_serial_deregister(&cypress_hidcom_device); failed_em_register: @@ -1511,6 +1634,7 @@ static void __exit cypress_exit (void) usb_deregister (&cypress_driver); usb_serial_deregister (&cypress_earthmate_device); usb_serial_deregister (&cypress_hidcom_device); + usb_serial_deregister (&cypress_ca42v2_device); }