diff options
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
| -rw-r--r-- | drivers/usb/serial/cypress_m8.c | 119 |
1 files changed, 35 insertions, 84 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index ed51bc48eea6..e29569d65991 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -7,7 +7,7 @@ * Copyright (C) 2003,2004 * Neil Whelchel (koyama@firstlight.net) * - * See Documentation/usb/usb-serial.txt for more information on using this + * See Documentation/usb/usb-serial.rst for more information on using this * driver * * See http://geocities.com/i0xox0i for information on this driver and the @@ -36,7 +36,7 @@ #include <linux/kfifo.h> #include <linux/delay.h> #include <linux/uaccess.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "cypress_m8.h" @@ -59,6 +59,7 @@ static const struct usb_device_id id_table_earthmate[] = { static const struct usb_device_id id_table_cyphidcomrs232[] = { { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, + { USB_DEVICE(VENDOR_ID_SAI, PRODUCT_ID_CYPHIDCOM) }, { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, { } /* Terminating entry */ @@ -73,6 +74,7 @@ static const 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_SAI, PRODUCT_ID_CYPHIDCOM) }, { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, @@ -98,7 +100,6 @@ struct cypress_private { int write_urb_interval; /* interval to use for write urb */ int read_urb_interval; /* interval to use for read urb */ int comm_is_ok; /* true if communication is (still) ok */ - int termios_initialized; __u8 line_control; /* holds dtr / rts value */ __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ __u8 current_config; /* stores the current configuration byte */ @@ -107,31 +108,29 @@ struct cypress_private { int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ int baud_rate; /* stores current baud rate in integer form */ - int isthrottled; /* if throttled, discard reads */ char prev_status; /* used for TIOCMIWAIT */ - /* we pass a pointer to this as the argument sent to - cypress_set_termios old_termios */ - struct ktermios tmp_termios; /* stores the old termios settings */ }; /* function prototypes for the Cypress USB to serial device */ static int cypress_earthmate_port_probe(struct usb_serial_port *port); static int cypress_hidcom_port_probe(struct usb_serial_port *port); static int cypress_ca42v2_port_probe(struct usb_serial_port *port); -static int cypress_port_remove(struct usb_serial_port *port); +static void cypress_port_remove(struct usb_serial_port *port); static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); static void cypress_close(struct usb_serial_port *port); static void cypress_dtr_rts(struct usb_serial_port *port, int on); static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static void cypress_send(struct usb_serial_port *port); -static int cypress_write_room(struct tty_struct *tty); +static unsigned int cypress_write_room(struct tty_struct *tty); +static void cypress_earthmate_init_termios(struct tty_struct *tty); static void cypress_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old); + struct usb_serial_port *port, + const struct ktermios *old_termios); static int cypress_tiocmget(struct tty_struct *tty); static int cypress_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int cypress_chars_in_buffer(struct tty_struct *tty); +static unsigned int cypress_chars_in_buffer(struct tty_struct *tty); static void cypress_throttle(struct tty_struct *tty); static void cypress_unthrottle(struct tty_struct *tty); static void cypress_set_dead(struct usb_serial_port *port); @@ -140,7 +139,6 @@ static void cypress_write_int_callback(struct urb *urb); static struct usb_serial_driver cypress_earthmate_device = { .driver = { - .owner = THIS_MODULE, .name = "earthmate", }, .description = "DeLorme Earthmate USB", @@ -153,6 +151,7 @@ static struct usb_serial_driver cypress_earthmate_device = { .dtr_rts = cypress_dtr_rts, .write = cypress_write, .write_room = cypress_write_room, + .init_termios = cypress_earthmate_init_termios, .set_termios = cypress_set_termios, .tiocmget = cypress_tiocmget, .tiocmset = cypress_tiocmset, @@ -166,7 +165,6 @@ static struct usb_serial_driver cypress_earthmate_device = { static struct usb_serial_driver cypress_hidcom_device = { .driver = { - .owner = THIS_MODULE, .name = "cyphidcom", }, .description = "HID->COM RS232 Adapter", @@ -192,7 +190,6 @@ static struct usb_serial_driver cypress_hidcom_device = { static struct usb_serial_driver cypress_ca42v2_device = { .driver = { - .owner = THIS_MODULE, .name = "nokiaca42v2", }, .description = "Nokia CA-42 V2 Adapter", @@ -257,7 +254,7 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) /* * Mike Isely <isely@pobox.com> 2-Feb-2008: The * Cypress app note that describes this mechanism - * states the the low-speed part can't handle more + * states that the low-speed part can't handle more * than 800 bytes/sec, in which case 4800 baud is the * safest speed for a part like that. */ @@ -327,7 +324,7 @@ static int cypress_serial_control(struct tty_struct *tty, /* fill the feature_buffer with new configuration */ put_unaligned_le32(new_baudrate, feature_buffer); - feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ + feature_buffer[4] |= data_bits - 5; /* assign data bits in 2 bit space ( max 3 ) */ /* 1 bit gap */ feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */ feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */ @@ -467,7 +464,6 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) priv->cmd_ctrl = 0; priv->line_control = 0; - priv->termios_initialized = 0; priv->rx_flags = 0; /* Default packet format setting is determined by packet size. Anything with a size larger then 9 must have a separate @@ -566,7 +562,7 @@ static int cypress_ca42v2_port_probe(struct usb_serial_port *port) return 0; } -static int cypress_port_remove(struct usb_serial_port *port) +static void cypress_port_remove(struct usb_serial_port *port) { struct cypress_private *priv; @@ -574,8 +570,6 @@ static int cypress_port_remove(struct usb_serial_port *port) kfifo_free(&priv->write_fifo); kfree(priv); - - return 0; } static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -604,7 +598,7 @@ static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) cypress_send(port); if (tty) - cypress_set_termios(tty, port, &priv->tmp_termios); + cypress_set_termios(tty, port, NULL); /* setup the port and start reading from the device */ usb_fill_int_urb(port->interrupt_in_urb, serial->dev, @@ -793,18 +787,18 @@ send: /* returns how much space is available in the soft buffer */ -static int cypress_write_room(struct tty_struct *tty) +static unsigned int cypress_write_room(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct cypress_private *priv = usb_get_serial_port_data(port); - int room = 0; + unsigned int room; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); room = kfifo_avail(&priv->write_fifo); spin_unlock_irqrestore(&priv->lock, flags); - dev_dbg(&port->dev, "%s - returns %d\n", __func__, room); + dev_dbg(&port->dev, "%s - returns %u\n", __func__, room); return room; } @@ -857,8 +851,14 @@ static int cypress_tiocmset(struct tty_struct *tty, return cypress_write(tty, port, NULL, 0); } +static void cypress_earthmate_init_termios(struct tty_struct *tty) +{ + tty_encode_baud_rate(tty, 4800, 4800); +} + static void cypress_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) + struct usb_serial_port *port, + const struct ktermios *old_termios) { struct cypress_private *priv = usb_get_serial_port_data(port); struct device *dev = &port->dev; @@ -868,45 +868,11 @@ static void cypress_set_termios(struct tty_struct *tty, __u8 oldlines; int linechange = 0; - spin_lock_irqsave(&priv->lock, flags); - /* We can't clean this one up as we don't know the device type - early enough */ - 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_ispeed = 4800; - tty->termios.c_ospeed = 4800; - } else if (priv->chiptype == CT_CYPHIDCOM) { - tty->termios = tty_std_termios; - tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | - CLOCAL; - tty->termios.c_ispeed = 9600; - tty->termios.c_ospeed = 9600; - } else if (priv->chiptype == CT_CA42V2) { - tty->termios = tty_std_termios; - tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | - CLOCAL; - tty->termios.c_ispeed = 9600; - tty->termios.c_ospeed = 9600; - } - priv->termios_initialized = 1; - } - spin_unlock_irqrestore(&priv->lock, flags); - /* Unsupported features need clearing */ tty->termios.c_cflag &= ~(CMSPAR|CRTSCTS); cflag = tty->termios.c_cflag; - /* check if there are new settings */ - if (old_termios) { - spin_lock_irqsave(&priv->lock, flags); - priv->tmp_termios = tty->termios; - spin_unlock_irqrestore(&priv->lock, flags); - } - /* set number of data bits, parity, stop bits */ /* when parity is disabled the parity type bit is ignored */ @@ -920,23 +886,8 @@ static void cypress_set_termios(struct tty_struct *tty, } else parity_enable = parity_type = 0; - 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: - dev_err(dev, "%s - CSIZE was set, but not CS5-CS8\n", __func__); - data_bits = 3; - } + data_bits = tty_get_char_size(cflag); + spin_lock_irqsave(&priv->lock, flags); oldlines = priv->line_control; if ((cflag & CBAUD) == B0) { @@ -1003,18 +954,18 @@ static void cypress_set_termios(struct tty_struct *tty, /* returns amount of data still left in soft buffer */ -static int cypress_chars_in_buffer(struct tty_struct *tty) +static unsigned int cypress_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct cypress_private *priv = usb_get_serial_port_data(port); - int chars = 0; + unsigned int chars; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); chars = kfifo_len(&priv->write_fifo); spin_unlock_irqrestore(&priv->lock, flags); - dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); + dev_dbg(&port->dev, "%s - returns %u\n", __func__, chars); return chars; } @@ -1079,7 +1030,7 @@ static void cypress_read_int_callback(struct urb *urb) return; case -EPIPE: /* Can't call usb_clear_halt while in_interrupt */ - /* FALLS THROUGH */ + fallthrough; default: /* something ugly is going on... */ dev_err(dev, "%s - unexpected nonzero read status received: %d\n", @@ -1228,7 +1179,7 @@ static void cypress_write_int_callback(struct urb *urb) return; case -EPIPE: /* Cannot call usb_clear_halt while in_interrupt */ - /* FALLTHROUGH */ + fallthrough; default: dev_err(dev, "%s - unexpected nonzero write status received: %d\n", __func__, status); @@ -1247,9 +1198,9 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -module_param(stats, bool, S_IRUGO | S_IWUSR); +module_param(stats, bool, 0644); MODULE_PARM_DESC(stats, "Enable statistics or not"); -module_param(interval, int, S_IRUGO | S_IWUSR); +module_param(interval, int, 0644); MODULE_PARM_DESC(interval, "Overrides interrupt interval"); -module_param(unstable_bauds, bool, S_IRUGO | S_IWUSR); +module_param(unstable_bauds, bool, 0644); MODULE_PARM_DESC(unstable_bauds, "Allow unstable baud rates"); |
