Commit 78fbe864 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'usb-serial-4.19-rc1' of...

Merge tag 'usb-serial-4.19-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-next

Johan writes:

USB-serial updates for v4.19-rc1

Here are the USB-serial updates for 4.19-rc1, including:

 - gpio support for CP2102N devices
 - improved line-speed handling for cp210x
 - conversion to spin_lock_irqsave() in completion handlers
 - dropped kl5kusb105 support from the kl5kusb105 driver (sic!)

Included are also various lower-priority fixes and clean ups.

All but the final commit have been in linux-next, and with no reported
issues.
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parents 500f0716 c8acfe0a
...@@ -418,15 +418,6 @@ Current status: ...@@ -418,15 +418,6 @@ Current status:
why it is wise to cut down on the rate used is wise for large why it is wise to cut down on the rate used is wise for large
transfers until this is settled. transfers until this is settled.
Options supported:
If this driver is compiled as a module you can pass the following
options to it:
debug - extra verbose debugging info
(default: 0; nonzero enables)
use_lowlatency - use low_latency flag to speed up tty layer
when reading from the device.
(default: 0; nonzero enables)
See http://www.uuhaus.de/linux/palmconnect.html for up-to-date See http://www.uuhaus.de/linux/palmconnect.html for up-to-date
information on this driver. information on this driver.
......
...@@ -239,11 +239,14 @@ MODULE_DEVICE_TABLE(usb, id_table); ...@@ -239,11 +239,14 @@ MODULE_DEVICE_TABLE(usb, id_table);
struct cp210x_serial_private { struct cp210x_serial_private {
#ifdef CONFIG_GPIOLIB #ifdef CONFIG_GPIOLIB
struct gpio_chip gc; struct gpio_chip gc;
u8 config;
u8 gpio_mode;
bool gpio_registered; bool gpio_registered;
u8 gpio_pushpull;
u8 gpio_altfunc;
u8 gpio_input;
#endif #endif
u8 partnum; u8 partnum;
speed_t max_speed;
bool use_actual_rate;
}; };
struct cp210x_port_private { struct cp210x_port_private {
...@@ -356,6 +359,7 @@ static struct usb_serial_driver * const serial_drivers[] = { ...@@ -356,6 +359,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
#define CONTROL_WRITE_RTS 0x0200 #define CONTROL_WRITE_RTS 0x0200
/* CP210X_VENDOR_SPECIFIC values */ /* CP210X_VENDOR_SPECIFIC values */
#define CP210X_READ_2NCONFIG 0x000E
#define CP210X_READ_LATCH 0x00C2 #define CP210X_READ_LATCH 0x00C2
#define CP210X_GET_PARTNUM 0x370B #define CP210X_GET_PARTNUM 0x370B
#define CP210X_GET_PORTCONFIG 0x370C #define CP210X_GET_PORTCONFIG 0x370C
...@@ -369,6 +373,9 @@ static struct usb_serial_driver * const serial_drivers[] = { ...@@ -369,6 +373,9 @@ static struct usb_serial_driver * const serial_drivers[] = {
#define CP210X_PARTNUM_CP2104 0x04 #define CP210X_PARTNUM_CP2104 0x04
#define CP210X_PARTNUM_CP2105 0x05 #define CP210X_PARTNUM_CP2105 0x05
#define CP210X_PARTNUM_CP2108 0x08 #define CP210X_PARTNUM_CP2108 0x08
#define CP210X_PARTNUM_CP2102N_QFN28 0x20
#define CP210X_PARTNUM_CP2102N_QFN24 0x21
#define CP210X_PARTNUM_CP2102N_QFN20 0x22
#define CP210X_PARTNUM_UNKNOWN 0xFF #define CP210X_PARTNUM_UNKNOWN 0xFF
/* CP210X_GET_COMM_STATUS returns these 0x13 bytes */ /* CP210X_GET_COMM_STATUS returns these 0x13 bytes */
...@@ -462,6 +469,12 @@ struct cp210x_config { ...@@ -462,6 +469,12 @@ struct cp210x_config {
#define CP2105_GPIO1_RXLED_MODE BIT(1) #define CP2105_GPIO1_RXLED_MODE BIT(1)
#define CP2105_GPIO1_RS485_MODE BIT(2) #define CP2105_GPIO1_RS485_MODE BIT(2)
/* CP2102N configuration array indices */
#define CP210X_2NCONFIG_CONFIG_VERSION_IDX 2
#define CP210X_2NCONFIG_GPIO_MODE_IDX 581
#define CP210X_2NCONFIG_GPIO_RSTLATCH_IDX 587
#define CP210X_2NCONFIG_GPIO_CONTROL_IDX 600
/* CP210X_VENDOR_SPECIFIC, CP210X_WRITE_LATCH call writes these 0x2 bytes. */ /* CP210X_VENDOR_SPECIFIC, CP210X_WRITE_LATCH call writes these 0x2 bytes. */
struct cp210x_gpio_write { struct cp210x_gpio_write {
u8 mask; u8 mask;
...@@ -767,48 +780,6 @@ static int cp210x_get_line_ctl(struct usb_serial_port *port, u16 *ctl) ...@@ -767,48 +780,6 @@ static int cp210x_get_line_ctl(struct usb_serial_port *port, u16 *ctl)
return 0; return 0;
} }
/*
* cp210x_quantise_baudrate
* Quantises the baud rate as per AN205 Table 1
*/
static unsigned int cp210x_quantise_baudrate(unsigned int baud)
{
if (baud <= 300)
baud = 300;
else if (baud <= 600) baud = 600;
else if (baud <= 1200) baud = 1200;
else if (baud <= 1800) baud = 1800;
else if (baud <= 2400) baud = 2400;
else if (baud <= 4000) baud = 4000;
else if (baud <= 4803) baud = 4800;
else if (baud <= 7207) baud = 7200;
else if (baud <= 9612) baud = 9600;
else if (baud <= 14428) baud = 14400;
else if (baud <= 16062) baud = 16000;
else if (baud <= 19250) baud = 19200;
else if (baud <= 28912) baud = 28800;
else if (baud <= 38601) baud = 38400;
else if (baud <= 51558) baud = 51200;
else if (baud <= 56280) baud = 56000;
else if (baud <= 58053) baud = 57600;
else if (baud <= 64111) baud = 64000;
else if (baud <= 77608) baud = 76800;
else if (baud <= 117028) baud = 115200;
else if (baud <= 129347) baud = 128000;
else if (baud <= 156868) baud = 153600;
else if (baud <= 237832) baud = 230400;
else if (baud <= 254234) baud = 250000;
else if (baud <= 273066) baud = 256000;
else if (baud <= 491520) baud = 460800;
else if (baud <= 567138) baud = 500000;
else if (baud <= 670254) baud = 576000;
else if (baud < 1000000)
baud = 921600;
else if (baud > 2000000)
baud = 2000000;
return baud;
}
static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
int result; int result;
...@@ -1028,6 +999,75 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, ...@@ -1028,6 +999,75 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
*cflagp = cflag; *cflagp = cflag;
} }
struct cp210x_rate {
speed_t rate;
speed_t high;
};
static const struct cp210x_rate cp210x_an205_table1[] = {
{ 300, 300 },
{ 600, 600 },
{ 1200, 1200 },
{ 1800, 1800 },
{ 2400, 2400 },
{ 4000, 4000 },
{ 4800, 4803 },
{ 7200, 7207 },
{ 9600, 9612 },
{ 14400, 14428 },
{ 16000, 16062 },
{ 19200, 19250 },
{ 28800, 28912 },
{ 38400, 38601 },
{ 51200, 51558 },
{ 56000, 56280 },
{ 57600, 58053 },
{ 64000, 64111 },
{ 76800, 77608 },
{ 115200, 117028 },
{ 128000, 129347 },
{ 153600, 156868 },
{ 230400, 237832 },
{ 250000, 254234 },
{ 256000, 273066 },
{ 460800, 491520 },
{ 500000, 567138 },
{ 576000, 670254 },
{ 921600, UINT_MAX }
};
/*
* Quantises the baud rate as per AN205 Table 1
*/
static speed_t cp210x_get_an205_rate(speed_t baud)
{
int i;
for (i = 0; i < ARRAY_SIZE(cp210x_an205_table1); ++i) {
if (baud <= cp210x_an205_table1[i].high)
break;
}
return cp210x_an205_table1[i].rate;
}
static speed_t cp210x_get_actual_rate(struct usb_serial *serial, speed_t baud)
{
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
unsigned int prescale = 1;
unsigned int div;
baud = clamp(baud, 300u, priv->max_speed);
if (baud <= 365)
prescale = 4;
div = DIV_ROUND_CLOSEST(48000000, 2 * prescale * baud);
baud = 48000000 / (2 * prescale * div);
return baud;
}
/* /*
* CP2101 supports the following baud rates: * CP2101 supports the following baud rates:
* *
...@@ -1057,16 +1097,24 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, ...@@ -1057,16 +1097,24 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
static void cp210x_change_speed(struct tty_struct *tty, static void cp210x_change_speed(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios) struct usb_serial_port *port, struct ktermios *old_termios)
{ {
struct usb_serial *serial = port->serial;
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
u32 baud; u32 baud;
baud = tty->termios.c_ospeed; baud = tty->termios.c_ospeed;
/* This maps the requested rate to a rate valid on cp2102 or cp2103, /*
* or to an arbitrary rate in [1M,2M]. * This maps the requested rate to the actual rate, a valid rate on
* cp2102 or cp2103, or to an arbitrary rate in [1M, max_speed].
* *
* NOTE: B0 is not implemented. * NOTE: B0 is not implemented.
*/ */
baud = cp210x_quantise_baudrate(baud); if (priv->use_actual_rate)
baud = cp210x_get_actual_rate(serial, baud);
else if (baud < 1000000)
baud = cp210x_get_an205_rate(baud);
else if (baud > priv->max_speed)
baud = priv->max_speed;
dev_dbg(&port->dev, "%s - setting baud rate to %u\n", __func__, baud); dev_dbg(&port->dev, "%s - setting baud rate to %u\n", __func__, baud);
if (cp210x_write_u32_reg(port, CP210X_SET_BAUDRATE, baud)) { if (cp210x_write_u32_reg(port, CP210X_SET_BAUDRATE, baud)) {
...@@ -1288,17 +1336,8 @@ static int cp210x_gpio_request(struct gpio_chip *gc, unsigned int offset) ...@@ -1288,17 +1336,8 @@ static int cp210x_gpio_request(struct gpio_chip *gc, unsigned int offset)
struct usb_serial *serial = gpiochip_get_data(gc); struct usb_serial *serial = gpiochip_get_data(gc);
struct cp210x_serial_private *priv = usb_get_serial_data(serial); struct cp210x_serial_private *priv = usb_get_serial_data(serial);
switch (offset) { if (priv->gpio_altfunc & BIT(offset))
case 0:
if (priv->config & CP2105_GPIO0_TXLED_MODE)
return -ENODEV; return -ENODEV;
break;
case 1:
if (priv->config & (CP2105_GPIO1_RXLED_MODE |
CP2105_GPIO1_RS485_MODE))
return -ENODEV;
break;
}
return 0; return 0;
} }
...@@ -1306,10 +1345,15 @@ static int cp210x_gpio_request(struct gpio_chip *gc, unsigned int offset) ...@@ -1306,10 +1345,15 @@ static int cp210x_gpio_request(struct gpio_chip *gc, unsigned int offset)
static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio) static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{ {
struct usb_serial *serial = gpiochip_get_data(gc); struct usb_serial *serial = gpiochip_get_data(gc);
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
u8 req_type = REQTYPE_DEVICE_TO_HOST;
int result; int result;
u8 buf; u8 buf;
result = cp210x_read_vendor_block(serial, REQTYPE_INTERFACE_TO_HOST, if (priv->partnum == CP210X_PARTNUM_CP2105)
req_type = REQTYPE_INTERFACE_TO_HOST;
result = cp210x_read_vendor_block(serial, req_type,
CP210X_READ_LATCH, &buf, sizeof(buf)); CP210X_READ_LATCH, &buf, sizeof(buf));
if (result < 0) if (result < 0)
return result; return result;
...@@ -1320,7 +1364,9 @@ static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio) ...@@ -1320,7 +1364,9 @@ static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio)
static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value)
{ {
struct usb_serial *serial = gpiochip_get_data(gc); struct usb_serial *serial = gpiochip_get_data(gc);
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
struct cp210x_gpio_write buf; struct cp210x_gpio_write buf;
int result;
if (value == 1) if (value == 1)
buf.state = BIT(gpio); buf.state = BIT(gpio);
...@@ -1329,25 +1375,68 @@ static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) ...@@ -1329,25 +1375,68 @@ static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value)
buf.mask = BIT(gpio); buf.mask = BIT(gpio);
cp210x_write_vendor_block(serial, REQTYPE_HOST_TO_INTERFACE, if (priv->partnum == CP210X_PARTNUM_CP2105) {
CP210X_WRITE_LATCH, &buf, sizeof(buf)); result = cp210x_write_vendor_block(serial,
REQTYPE_HOST_TO_INTERFACE,
CP210X_WRITE_LATCH, &buf,
sizeof(buf));
} else {
u16 wIndex = buf.state << 8 | buf.mask;
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
CP210X_VENDOR_SPECIFIC,
REQTYPE_HOST_TO_DEVICE,
CP210X_WRITE_LATCH,
wIndex,
NULL, 0, USB_CTRL_SET_TIMEOUT);
}
if (result < 0) {
dev_err(&serial->interface->dev, "failed to set GPIO value: %d\n",
result);
}
} }
static int cp210x_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio) static int cp210x_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio)
{ {
/* Hardware does not support an input mode */ struct usb_serial *serial = gpiochip_get_data(gc);
return 0; struct cp210x_serial_private *priv = usb_get_serial_data(serial);
return priv->gpio_input & BIT(gpio);
} }
static int cp210x_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio) static int cp210x_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)
{ {
/* Hardware does not support an input mode */ struct usb_serial *serial = gpiochip_get_data(gc);
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
if (priv->partnum == CP210X_PARTNUM_CP2105) {
/* hardware does not support an input mode */
return -ENOTSUPP; return -ENOTSUPP;
}
/* push-pull pins cannot be changed to be inputs */
if (priv->gpio_pushpull & BIT(gpio))
return -EINVAL;
/* make sure to release pin if it is being driven low */
cp210x_gpio_set(gc, gpio, 1);
priv->gpio_input |= BIT(gpio);
return 0;
} }
static int cp210x_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio, static int cp210x_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio,
int value) int value)
{ {
struct usb_serial *serial = gpiochip_get_data(gc);
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
priv->gpio_input &= ~BIT(gpio);
cp210x_gpio_set(gc, gpio, value);
return 0; return 0;
} }
...@@ -1360,11 +1449,11 @@ static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio, ...@@ -1360,11 +1449,11 @@ static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio,
/* Succeed only if in correct mode (this can't be set at runtime) */ /* Succeed only if in correct mode (this can't be set at runtime) */
if ((param == PIN_CONFIG_DRIVE_PUSH_PULL) && if ((param == PIN_CONFIG_DRIVE_PUSH_PULL) &&
(priv->gpio_mode & BIT(gpio))) (priv->gpio_pushpull & BIT(gpio)))
return 0; return 0;
if ((param == PIN_CONFIG_DRIVE_OPEN_DRAIN) && if ((param == PIN_CONFIG_DRIVE_OPEN_DRAIN) &&
!(priv->gpio_mode & BIT(gpio))) !(priv->gpio_pushpull & BIT(gpio)))
return 0; return 0;
return -ENOTSUPP; return -ENOTSUPP;
...@@ -1377,12 +1466,13 @@ static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio, ...@@ -1377,12 +1466,13 @@ static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio,
* this driver that provide GPIO do so in a way that does not impact other * this driver that provide GPIO do so in a way that does not impact other
* signals and are thus expected to have very different initialisation. * signals and are thus expected to have very different initialisation.
*/ */
static int cp2105_shared_gpio_init(struct usb_serial *serial) static int cp2105_gpioconf_init(struct usb_serial *serial)
{ {
struct cp210x_serial_private *priv = usb_get_serial_data(serial); struct cp210x_serial_private *priv = usb_get_serial_data(serial);
struct cp210x_pin_mode mode; struct cp210x_pin_mode mode;
struct cp210x_config config; struct cp210x_config config;
u8 intf_num = cp210x_interface_num(serial); u8 intf_num = cp210x_interface_num(serial);
u8 iface_config;
int result; int result;
result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST,
...@@ -1399,20 +1489,26 @@ static int cp2105_shared_gpio_init(struct usb_serial *serial) ...@@ -1399,20 +1489,26 @@ static int cp2105_shared_gpio_init(struct usb_serial *serial)
/* 2 banks of GPIO - One for the pins taken from each serial port */ /* 2 banks of GPIO - One for the pins taken from each serial port */
if (intf_num == 0) { if (intf_num == 0) {
if (mode.eci == CP210X_PIN_MODE_MODEM) if (mode.eci == CP210X_PIN_MODE_MODEM) {
/* mark all GPIOs of this interface as reserved */
priv->gpio_altfunc = 0xff;
return 0; return 0;
}
priv->config = config.eci_cfg; iface_config = config.eci_cfg;
priv->gpio_mode = (u8)((le16_to_cpu(config.gpio_mode) & priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
CP210X_ECI_GPIO_MODE_MASK) >> CP210X_ECI_GPIO_MODE_MASK) >>
CP210X_ECI_GPIO_MODE_OFFSET); CP210X_ECI_GPIO_MODE_OFFSET);
priv->gc.ngpio = 2; priv->gc.ngpio = 2;
} else if (intf_num == 1) { } else if (intf_num == 1) {
if (mode.sci == CP210X_PIN_MODE_MODEM) if (mode.sci == CP210X_PIN_MODE_MODEM) {
/* mark all GPIOs of this interface as reserved */
priv->gpio_altfunc = 0xff;
return 0; return 0;
}
priv->config = config.sci_cfg; iface_config = config.sci_cfg;
priv->gpio_mode = (u8)((le16_to_cpu(config.gpio_mode) & priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
CP210X_SCI_GPIO_MODE_MASK) >> CP210X_SCI_GPIO_MODE_MASK) >>
CP210X_SCI_GPIO_MODE_OFFSET); CP210X_SCI_GPIO_MODE_OFFSET);
priv->gc.ngpio = 3; priv->gc.ngpio = 3;
...@@ -1420,6 +1516,125 @@ static int cp2105_shared_gpio_init(struct usb_serial *serial) ...@@ -1420,6 +1516,125 @@ static int cp2105_shared_gpio_init(struct usb_serial *serial)
return -ENODEV; return -ENODEV;
} }
/* mark all pins which are not in GPIO mode */
if (iface_config & CP2105_GPIO0_TXLED_MODE) /* GPIO 0 */
priv->gpio_altfunc |= BIT(0);
if (iface_config & (CP2105_GPIO1_RXLED_MODE | /* GPIO 1 */
CP2105_GPIO1_RS485_MODE))
priv->gpio_altfunc |= BIT(1);
/* driver implementation for CP2105 only supports outputs */
priv->gpio_input = 0;
return 0;
}
static int cp2102n_gpioconf_init(struct usb_serial *serial)
{
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
const u16 config_size = 0x02a6;
u8 gpio_rst_latch;
u8 config_version;
u8 gpio_pushpull;
u8 *config_buf;
u8 gpio_latch;
u8 gpio_ctrl;
int result;
u8 i;
/*
* Retrieve device configuration from the device.
* The array received contains all customization settings done at the
* factory/manufacturer. Format of the array is documented at the
* time of writing at:
* https://www.silabs.com/community/interface/knowledge-base.entry.html/2017/03/31/cp2102n_setconfig-xsfa
*/
config_buf = kmalloc(config_size, GFP_KERNEL);
if (!config_buf)
return -ENOMEM;
result = cp210x_read_vendor_block(serial,
REQTYPE_DEVICE_TO_HOST,
CP210X_READ_2NCONFIG,
config_buf,
config_size);
if (result < 0) {
kfree(config_buf);
return result;
}
config_version = config_buf[CP210X_2NCONFIG_CONFIG_VERSION_IDX];
gpio_pushpull = config_buf[CP210X_2NCONFIG_GPIO_MODE_IDX];
gpio_ctrl = config_buf[CP210X_2NCONFIG_GPIO_CONTROL_IDX];
gpio_rst_latch = config_buf[CP210X_2NCONFIG_GPIO_RSTLATCH_IDX];
kfree(config_buf);
/* Make sure this is a config format we understand. */
if (config_version != 0x01)
return -ENOTSUPP;
/*
* We only support 4 GPIOs even on the QFN28 package, because
* config locations of GPIOs 4-6 determined using reverse
* engineering revealed conflicting offsets with other
* documented functions. So we'll just play it safe for now.
*/
priv->gc.ngpio = 4;
/*
* Get default pin states after reset. Needed so we can determine
* the direction of an open-drain pin.
*/
gpio_latch = (gpio_rst_latch >> 3) & 0x0f;
/* 0 indicates open-drain mode, 1 is push-pull */
priv->gpio_pushpull = (gpio_pushpull >> 3) & 0x0f;
/* 0 indicates GPIO mode, 1 is alternate function */
priv->gpio_altfunc = (gpio_ctrl >> 2) & 0x0f;
/*
* The CP2102N does not strictly has input and output pin modes,
* it only knows open-drain and push-pull modes which is set at
* factory. An open-drain pin can function both as an
* input or an output. We emulate input mode for open-drain pins
* by making sure they are not driven low, and we do not allow
* push-pull pins to be set as an input.
*/
for (i = 0; i < priv->gc.ngpio; ++i) {
/*
* Set direction to "input" iff pin is open-drain and reset
* value is 1.
*/
if (!(priv->gpio_pushpull & BIT(i)) && (gpio_latch & BIT(i)))
priv->gpio_input |= BIT(i);
}
return 0;
}
static int cp210x_gpio_init(struct usb_serial *serial)
{
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
int result;
switch (priv->partnum) {
case CP210X_PARTNUM_CP2105:
result = cp2105_gpioconf_init(serial);
break;
case CP210X_PARTNUM_CP2102N_QFN28:
case CP210X_PARTNUM_CP2102N_QFN24:
case CP210X_PARTNUM_CP2102N_QFN20:
result = cp2102n_gpioconf_init(serial);
break;
default:
return 0;
}
if (result < 0)
return result;
priv->gc.label = "cp210x"; priv->gc.label = "cp210x";
priv->gc.request = cp210x_gpio_request; priv->gc.request = cp210x_gpio_request;
priv->gc.get_direction = cp210x_gpio_direction_get; priv->gc.get_direction = cp210x_gpio_direction_get;
...@@ -1452,7 +1667,7 @@ static void cp210x_gpio_remove(struct usb_serial *serial) ...@@ -1452,7 +1667,7 @@ static void cp210x_gpio_remove(struct usb_serial *serial)
#else #else
static int cp2105_shared_gpio_init(struct usb_serial *serial) static int cp210x_gpio_init(struct usb_serial *serial)
{ {
return 0; return 0;
} }
...@@ -1497,6 +1712,50 @@ static int cp210x_port_remove(struct usb_serial_port *port) ...@@ -1497,6 +1712,50 @@ static int cp210x_port_remove(struct usb_serial_port *port)
return 0; return 0;
} }
static void cp210x_init_max_speed(struct usb_serial *serial)
{
struct cp210x_serial_private *priv = usb_get_serial_data(serial);
bool use_actual_rate = false;
speed_t max;
switch (priv->partnum) {
case CP210X_PARTNUM_CP2101:
max = 921600;
break;
case CP210X_PARTNUM_CP2102:
case CP210X_PARTNUM_CP2103:
max = 1000000;
break;
case CP210X_PARTNUM_CP2104:
use_actual_rate = true;
max = 2000000;
break;
case CP210X_PARTNUM_CP2108:
max = 2000000;
break;
case CP210X_PARTNUM_CP2105:
if (cp210x_interface_num(serial) == 0) {
use_actual_rate = true;
max = 2000000; /* ECI */
} else {
max = 921600; /* SCI */
}
break;
case CP210X_PARTNUM_CP2102N_QFN28:
case CP210X_PARTNUM_CP2102N_QFN24:
case CP210X_PARTNUM_CP2102N_QFN20:
use_actual_rate = true;
max = 3000000;
break;
default:
max = 2000000;
break;
}
priv->max_speed = max;
priv->use_actual_rate = use_actual_rate;
}
static int cp210x_attach(struct usb_serial *serial) static int cp210x_attach(struct usb_serial *serial)
{ {
int result; int result;
...@@ -1517,12 +1776,12 @@ static int cp210x_attach(struct usb_serial *serial) ...@@ -1517,12 +1776,12 @@ static int cp210x_attach(struct usb_serial *serial)
usb_set_serial_data(serial, priv); usb_set_serial_data(serial, priv);
if (priv->partnum == CP210X_PARTNUM_CP2105) { cp210x_init_max_speed(serial);
result = cp2105_shared_gpio_init(serial);
result = cp210x_gpio_init(serial);
if (result < 0) { if (result < 0) {
dev_err(&serial->interface->dev, dev_err(&serial->interface->dev, "GPIO initialisation failed: %d\n",
"GPIO initialisation failed, continuing without GPIO support\n"); result);
}
} }
return 0; return 0;
......
...@@ -255,6 +255,7 @@ static void cyberjack_read_int_callback(struct urb *urb) ...@@ -255,6 +255,7 @@ static void cyberjack_read_int_callback(struct urb *urb)
struct device *dev = &port->dev; struct device *dev = &port->dev;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
int status = urb->status; int status = urb->status;
unsigned long flags;
int result; int result;
/* the urb might have been killed. */ /* the urb might have been killed. */
...@@ -270,13 +271,13 @@ static void cyberjack_read_int_callback(struct urb *urb) ...@@ -270,13 +271,13 @@ static void cyberjack_read_int_callback(struct urb *urb)
/* This is a announcement of coming bulk_ins. */ /* This is a announcement of coming bulk_ins. */
unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3; unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
spin_lock(&priv->lock); spin_lock_irqsave(&priv->lock, flags);
old_rdtodo = priv->rdtodo; old_rdtodo = priv->rdtodo;
if (old_rdtodo > SHRT_MAX - size) { if (old_rdtodo > SHRT_MAX - size) {
dev_dbg(dev, "To many bulk_in urbs to do.\n"); dev_dbg(dev, "To many bulk_in urbs to do.\n");
spin_unlock(&priv->lock); spin_unlock_irqrestore(&priv->lock, flags);
goto resubmit; goto resubmit;
} }
...@@ -285,7 +286,7 @@ static void cyberjack_read_int_callback(struct urb *urb) ...@@ -285,7 +286,7 @@ static void cyberjack_read_int_callback(struct urb *urb)
dev_dbg(dev, "%s - rdtodo: %d\n", __func__, priv->rdtodo); dev_dbg(dev, "%s - rdtodo: %d\n", __func__, priv->rdtodo);
spin_unlock(&priv->lock); spin_unlock_irqrestore(&priv->lock, flags);
if (!old_rdtodo) { if (!old_rdtodo) {
result = usb_submit_urb(port->read_urb, GFP_ATOMIC); result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
...@@ -309,6 +310,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb) ...@@ -309,6 +310,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
struct cyberjack_private *priv = usb_get_serial_port_data(port); struct cyberjack_private *priv = usb_get_serial_port_data(port);
struct device *dev = &port->dev; struct device *dev = &port->dev;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
unsigned long flags;
short todo; short todo;
int result; int result;
int status = urb->status; int status = urb->status;
...@@ -325,7 +327,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb) ...@@ -325,7 +327,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
tty_flip_buffer_push(&port->port); tty_flip_buffer_push(&port->port);
} }
spin_lock(&priv->lock); spin_lock_irqsave(&priv->lock, flags);
/* Reduce urbs to do by one. */ /* Reduce urbs to do by one. */
priv->rdtodo -= urb->actual_length; priv->rdtodo -= urb->actual_length;
...@@ -334,7 +336,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb) ...@@ -334,7 +336,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
priv->rdtodo = 0; priv->rdtodo = 0;
todo = priv->rdtodo; todo = priv->rdtodo;
spin_unlock(&priv->lock); spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(dev, "%s - rdtodo: %d\n", __func__, todo); dev_dbg(dev, "%s - rdtodo: %d\n", __func__, todo);
...@@ -354,6 +356,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb) ...@@ -354,6 +356,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
struct cyberjack_private *priv = usb_get_serial_port_data(port); struct cyberjack_private *priv = usb_get_serial_port_data(port);
struct device *dev = &port->dev; struct device *dev = &port->dev;
int status = urb->status; int status = urb->status;
unsigned long flags;
set_bit(0, &port->write_urbs_free); set_bit(0, &port->write_urbs_free);
if (status) { if (status) {
...@@ -362,7 +365,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb) ...@@ -362,7 +365,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
return; return;
} }
spin_lock(&priv->lock); spin_lock_irqsave(&priv->lock, flags);
/* only do something if we have more data to send */ /* only do something if we have more data to send */
if (priv->wrfilled) { if (priv->wrfilled) {
...@@ -406,7 +409,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb) ...@@ -406,7 +409,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
} }
exit: exit:
spin_unlock(&priv->lock); spin_unlock_irqrestore(&priv->lock, flags);
usb_serial_port_softint(port); usb_serial_port_softint(port);
} }
......
...@@ -984,6 +984,7 @@ static void digi_write_bulk_callback(struct urb *urb) ...@@ -984,6 +984,7 @@ static void digi_write_bulk_callback(struct urb *urb)
struct usb_serial *serial; struct usb_serial *serial;
struct digi_port *priv; struct digi_port *priv;
struct digi_serial *serial_priv; struct digi_serial *serial_priv;
unsigned long flags;
int ret = 0; int ret = 0;
int status = urb->status; int status = urb->status;
...@@ -1004,15 +1005,15 @@ static void digi_write_bulk_callback(struct urb *urb) ...@@ -1004,15 +1005,15 @@ static void digi_write_bulk_callback(struct urb *urb)
/* handle oob callback */ /* handle oob callback */
if (priv->dp_port_num == serial_priv->ds_oob_port_num) { if (priv->dp_port_num == serial_priv->ds_oob_port_num) {
dev_dbg(&port->dev, "digi_write_bulk_callback: oob callback\n"); dev_dbg(&port->dev, "digi_write_bulk_callback: oob callback\n");
spin_lock(&priv->dp_port_lock); spin_lock_irqsave(&priv->dp_port_lock, flags);
priv->dp_write_urb_in_use = 0; priv->dp_write_urb_in_use = 0;
wake_up_interruptible(&port->write_wait); wake_up_interruptible(&port->write_wait);
spin_unlock(&priv->dp_port_lock); spin_unlock_irqrestore(&priv->dp_port_lock, flags);
return; return;
} }
/* try to send any buffered data on this port */ /* try to send any buffered data on this port */
spin_lock(&priv->dp_port_lock); spin_lock_irqsave(&priv->dp_port_lock, flags);
priv->dp_write_urb_in_use = 0; priv->dp_write_urb_in_use = 0;
if (priv->dp_out_buf_len > 0) { if (priv->dp_out_buf_len > 0) {
*((unsigned char *)(port->write_urb->transfer_buffer)) *((unsigned char *)(port->write_urb->transfer_buffer))
...@@ -1035,7 +1036,7 @@ static void digi_write_bulk_callback(struct urb *urb) ...@@ -1035,7 +1036,7 @@ static void digi_write_bulk_callback(struct urb *urb)
/* lost the race in write_chan(). */ /* lost the race in write_chan(). */
schedule_work(&priv->dp_wakeup_work); schedule_work(&priv->dp_wakeup_work);
spin_unlock(&priv->dp_port_lock); spin_unlock_irqrestore(&priv->dp_port_lock, flags);
if (ret && ret != -EPERM) if (ret && ret != -EPERM)
dev_err_console(port, dev_err_console(port,
"%s: usb_submit_urb failed, ret=%d, port=%d\n", "%s: usb_submit_urb failed, ret=%d, port=%d\n",
...@@ -1381,11 +1382,12 @@ static int digi_read_inb_callback(struct urb *urb) ...@@ -1381,11 +1382,12 @@ static int digi_read_inb_callback(struct urb *urb)
struct usb_serial_port *port = urb->context; struct usb_serial_port *port = urb->context;
struct digi_port *priv = usb_get_serial_port_data(port); struct digi_port *priv = usb_get_serial_port_data(port);
unsigned char *buf = urb->transfer_buffer; unsigned char *buf = urb->transfer_buffer;
unsigned long flags;
int opcode; int opcode;
int len; int len;
int port_status; int port_status;
unsigned char *data; unsigned char *data;
int flag, throttled; int tty_flag, throttled;
/* short/multiple packet check */ /* short/multiple packet check */
if (urb->actual_length < 2) { if (urb->actual_length < 2) {
...@@ -1407,7 +1409,7 @@ static int digi_read_inb_callback(struct urb *urb) ...@@ -1407,7 +1409,7 @@ static int digi_read_inb_callback(struct urb *urb)
return -1; return -1;
} }
spin_lock(&priv->dp_port_lock); spin_lock_irqsave(&priv->dp_port_lock, flags);
/* check for throttle; if set, do not resubmit read urb */ /* check for throttle; if set, do not resubmit read urb */
/* indicate the read chain needs to be restarted on unthrottle */ /* indicate the read chain needs to be restarted on unthrottle */
...@@ -1421,7 +1423,7 @@ static int digi_read_inb_callback(struct urb *urb) ...@@ -1421,7 +1423,7 @@ static int digi_read_inb_callback(struct urb *urb)
data = &buf[3]; data = &buf[3];
/* get flag from port_status */ /* get flag from port_status */
flag = 0; tty_flag = 0;
/* overrun is special, not associated with a char */ /* overrun is special, not associated with a char */
if (port_status & DIGI_OVERRUN_ERROR) if (port_status & DIGI_OVERRUN_ERROR)
...@@ -1430,21 +1432,21 @@ static int digi_read_inb_callback(struct urb *urb) ...@@ -1430,21 +1432,21 @@ static int digi_read_inb_callback(struct urb *urb)
/* break takes precedence over parity, */ /* break takes precedence over parity, */
/* which takes precedence over framing errors */ /* which takes precedence over framing errors */
if (port_status & DIGI_BREAK_ERROR) if (port_status & DIGI_BREAK_ERROR)
flag = TTY_BREAK; tty_flag = TTY_BREAK;
else if (port_status & DIGI_PARITY_ERROR) else if (port_status & DIGI_PARITY_ERROR)
flag = TTY_PARITY; tty_flag = TTY_PARITY;
else if (port_status & DIGI_FRAMING_ERROR) else if (port_status & DIGI_FRAMING_ERROR)
flag = TTY_FRAME; tty_flag = TTY_FRAME;
/* data length is len-1 (one byte of len is port_status) */ /* data length is len-1 (one byte of len is port_status) */
--len; --len;
if (len > 0) { if (len > 0) {
tty_insert_flip_string_fixed_flag(&port->port, data, tty_insert_flip_string_fixed_flag(&port->port, data,
flag, len); tty_flag, len);
tty_flip_buffer_push(&port->port); tty_flip_buffer_push(&port->port);
} }
} }
spin_unlock(&priv->dp_port_lock); spin_unlock_irqrestore(&priv->dp_port_lock, flags);
if (opcode == DIGI_CMD_RECEIVE_DISABLE) if (opcode == DIGI_CMD_RECEIVE_DISABLE)
dev_dbg(&port->dev, "%s: got RECEIVE_DISABLE\n", __func__); dev_dbg(&port->dev, "%s: got RECEIVE_DISABLE\n", __func__);
...@@ -1474,6 +1476,7 @@ static int digi_read_oob_callback(struct urb *urb) ...@@ -1474,6 +1476,7 @@ static int digi_read_oob_callback(struct urb *urb)
struct digi_port *priv = usb_get_serial_port_data(port); struct digi_port *priv = usb_get_serial_port_data(port);
unsigned char *buf = urb->transfer_buffer; unsigned char *buf = urb->transfer_buffer;
int opcode, line, status, val; int opcode, line, status, val;
unsigned long flags;
int i; int i;
unsigned int rts; unsigned int rts;
...@@ -1506,7 +1509,7 @@ static int digi_read_oob_callback(struct urb *urb) ...@@ -1506,7 +1509,7 @@ static int digi_read_oob_callback(struct urb *urb)
rts = C_CRTSCTS(tty); rts = C_CRTSCTS(tty);
if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
spin_lock(&priv->dp_port_lock); spin_lock_irqsave(&priv->dp_port_lock, flags);
/* convert from digi flags to termiox flags */ /* convert from digi flags to termiox flags */
if (val & DIGI_READ_INPUT_SIGNALS_CTS) { if (val & DIGI_READ_INPUT_SIGNALS_CTS) {
priv->dp_modem_signals |= TIOCM_CTS; priv->dp_modem_signals |= TIOCM_CTS;
...@@ -1530,12 +1533,12 @@ static int digi_read_oob_callback(struct urb *urb) ...@@ -1530,12 +1533,12 @@ static int digi_read_oob_callback(struct urb *urb)
else else
priv->dp_modem_signals &= ~TIOCM_CD; priv->dp_modem_signals &= ~TIOCM_CD;
spin_unlock(&priv->dp_port_lock); spin_unlock_irqrestore(&priv->dp_port_lock, flags);
} else if (opcode == DIGI_CMD_TRANSMIT_IDLE) { } else if (opcode == DIGI_CMD_TRANSMIT_IDLE) {
spin_lock(&priv->dp_port_lock); spin_lock_irqsave(&priv->dp_port_lock, flags);
priv->dp_transmit_idle = 1; priv->dp_transmit_idle = 1;
wake_up_interruptible(&priv->dp_transmit_idle_wait); wake_up_interruptible(&priv->dp_transmit_idle_wait);
spin_unlock(&priv->dp_port_lock); spin_unlock_irqrestore(&priv->dp_port_lock, flags);
} else if (opcode == DIGI_CMD_IFLUSH_FIFO) { } else if (opcode == DIGI_CMD_IFLUSH_FIFO) {
wake_up_interruptible(&priv->dp_flush_wait); wake_up_interruptible(&priv->dp_flush_wait);
} }
......
...@@ -648,6 +648,7 @@ static void edge_interrupt_callback(struct urb *urb) ...@@ -648,6 +648,7 @@ static void edge_interrupt_callback(struct urb *urb)
struct usb_serial_port *port; struct usb_serial_port *port;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
int length = urb->actual_length; int length = urb->actual_length;
unsigned long flags;
int bytes_avail; int bytes_avail;
int position; int position;
int txCredits; int txCredits;
...@@ -679,7 +680,7 @@ static void edge_interrupt_callback(struct urb *urb) ...@@ -679,7 +680,7 @@ static void edge_interrupt_callback(struct urb *urb)
if (length > 1) { if (length > 1) {
bytes_avail = data[0] | (data[1] << 8); bytes_avail = data[0] | (data[1] << 8);
if (bytes_avail) { if (bytes_avail) {
spin_lock(&edge_serial->es_lock); spin_lock_irqsave(&edge_serial->es_lock, flags);
edge_serial->rxBytesAvail += bytes_avail; edge_serial->rxBytesAvail += bytes_avail;
dev_dbg(dev, dev_dbg(dev,
"%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d\n", "%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d\n",
...@@ -702,7 +703,8 @@ static void edge_interrupt_callback(struct urb *urb) ...@@ -702,7 +703,8 @@ static void edge_interrupt_callback(struct urb *urb)
edge_serial->read_in_progress = false; edge_serial->read_in_progress = false;
} }
} }
spin_unlock(&edge_serial->es_lock); spin_unlock_irqrestore(&edge_serial->es_lock,
flags);
} }
} }
/* grab the txcredits for the ports if available */ /* grab the txcredits for the ports if available */
...@@ -715,9 +717,11 @@ static void edge_interrupt_callback(struct urb *urb) ...@@ -715,9 +717,11 @@ static void edge_interrupt_callback(struct urb *urb)
port = edge_serial->serial->port[portNumber]; port = edge_serial->serial->port[portNumber];
edge_port = usb_get_serial_port_data(port); edge_port = usb_get_serial_port_data(port);
if (edge_port->open) { if (edge_port->open) {
spin_lock(&edge_port->ep_lock); spin_lock_irqsave(&edge_port->ep_lock,
flags);
edge_port->txCredits += txCredits; edge_port->txCredits += txCredits;
spin_unlock(&edge_port->ep_lock); spin_unlock_irqrestore(&edge_port->ep_lock,
flags);
dev_dbg(dev, "%s - txcredits for port%d = %d\n", dev_dbg(dev, "%s - txcredits for port%d = %d\n",
__func__, portNumber, __func__, portNumber,
edge_port->txCredits); edge_port->txCredits);
...@@ -758,6 +762,7 @@ static void edge_bulk_in_callback(struct urb *urb) ...@@ -758,6 +762,7 @@ static void edge_bulk_in_callback(struct urb *urb)
int retval; int retval;
__u16 raw_data_length; __u16 raw_data_length;
int status = urb->status; int status = urb->status;
unsigned long flags;
if (status) { if (status) {
dev_dbg(&urb->dev->dev, "%s - nonzero read bulk status received: %d\n", dev_dbg(&urb->dev->dev, "%s - nonzero read bulk status received: %d\n",
...@@ -777,7 +782,7 @@ static void edge_bulk_in_callback(struct urb *urb) ...@@ -777,7 +782,7 @@ static void edge_bulk_in_callback(struct urb *urb)
usb_serial_debug_data(dev, __func__, raw_data_length, data); usb_serial_debug_data(dev, __func__, raw_data_length, data);
spin_lock(&edge_serial->es_lock); spin_lock_irqsave(&edge_serial->es_lock, flags);
/* decrement our rxBytes available by the number that we just got */ /* decrement our rxBytes available by the number that we just got */
edge_serial->rxBytesAvail -= raw_data_length; edge_serial->rxBytesAvail -= raw_data_length;
...@@ -801,7 +806,7 @@ static void edge_bulk_in_callback(struct urb *urb) ...@@ -801,7 +806,7 @@ static void edge_bulk_in_callback(struct urb *urb)
edge_serial->read_in_progress = false; edge_serial->read_in_progress = false;
} }
spin_unlock(&edge_serial->es_lock); spin_unlock_irqrestore(&edge_serial->es_lock, flags);
} }
......
...@@ -1729,6 +1729,7 @@ static void edge_bulk_in_callback(struct urb *urb) ...@@ -1729,6 +1729,7 @@ static void edge_bulk_in_callback(struct urb *urb)
struct edgeport_port *edge_port = urb->context; struct edgeport_port *edge_port = urb->context;
struct device *dev = &edge_port->port->dev; struct device *dev = &edge_port->port->dev;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
unsigned long flags;
int retval = 0; int retval = 0;
int port_number; int port_number;
int status = urb->status; int status = urb->status;
...@@ -1780,13 +1781,13 @@ static void edge_bulk_in_callback(struct urb *urb) ...@@ -1780,13 +1781,13 @@ static void edge_bulk_in_callback(struct urb *urb)
exit: exit:
/* continue read unless stopped */ /* continue read unless stopped */
spin_lock(&edge_port->ep_lock); spin_lock_irqsave(&edge_port->ep_lock, flags);
if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING)
retval = usb_submit_urb(urb, GFP_ATOMIC); retval = usb_submit_urb(urb, GFP_ATOMIC);
else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING) else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING)
edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED; edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED;
spin_unlock(&edge_port->ep_lock); spin_unlock_irqrestore(&edge_port->ep_lock, flags);
if (retval) if (retval)
dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval); dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval);
} }
......
...@@ -132,7 +132,7 @@ irda_usb_find_class_desc(struct usb_serial *serial, unsigned int ifnum) ...@@ -132,7 +132,7 @@ irda_usb_find_class_desc(struct usb_serial *serial, unsigned int ifnum)
0, ifnum, desc, sizeof(*desc), 1000); 0, ifnum, desc, sizeof(*desc), 1000);
dev_dbg(&serial->dev->dev, "%s - ret=%d\n", __func__, ret); dev_dbg(&serial->dev->dev, "%s - ret=%d\n", __func__, ret);
if (ret < sizeof(*desc)) { if (ret < (int)sizeof(*desc)) {
dev_dbg(&serial->dev->dev, dev_dbg(&serial->dev->dev,
"%s - class descriptor read %s (%d)\n", __func__, "%s - class descriptor read %s (%d)\n", __func__,
(ret < 0) ? "failed" : "too short", ret); (ret < 0) ? "failed" : "too short", ret);
......
...@@ -58,7 +58,6 @@ struct iuu_private { ...@@ -58,7 +58,6 @@ struct iuu_private {
u8 *buf; /* used for initialize speed */ u8 *buf; /* used for initialize speed */
u8 len; u8 len;
int vcc; /* vcc (either 3 or 5 V) */ int vcc; /* vcc (either 3 or 5 V) */
u32 baud;
u32 boost; u32 boost;
u32 clk; u32 clk;
}; };
...@@ -963,9 +962,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -963,9 +962,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
struct iuu_private *priv = usb_get_serial_port_data(port); struct iuu_private *priv = usb_get_serial_port_data(port);
baud = tty->termios.c_ospeed; baud = tty->termios.c_ospeed;
tty->termios.c_ispeed = baud;
/* Re-encode speed */
tty_encode_baud_rate(tty, baud, baud);
dev_dbg(dev, "%s - baud %d\n", __func__, baud); dev_dbg(dev, "%s - baud %d\n", __func__, baud);
usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->write_urb->pipe);
...@@ -991,7 +987,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -991,7 +987,6 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
if (boost < 100) if (boost < 100)
boost = 100; boost = 100;
priv->boost = boost; priv->boost = boost;
priv->baud = baud;
switch (clockmode) { switch (clockmode) {
case 2: /* 3.680 Mhz */ case 2: /* 3.680 Mhz */
priv->clk = IUU_CLK_3680000; priv->clk = IUU_CLK_3680000;
......
...@@ -67,7 +67,6 @@ static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, ...@@ -67,7 +67,6 @@ static int klsi_105_prepare_write_buffer(struct usb_serial_port *port,
*/ */
static const struct usb_device_id id_table[] = { static const struct usb_device_id id_table[] = {
{ USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) }, { USB_DEVICE(PALMCONNECT_VID, PALMCONNECT_PID) },
{ USB_DEVICE(KLSI_VID, KLSI_KL5KUSB105D_PID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
#define PALMCONNECT_VID 0x0830 #define PALMCONNECT_VID 0x0830
#define PALMCONNECT_PID 0x0080 #define PALMCONNECT_PID 0x0080
#define KLSI_VID 0x05e9
#define KLSI_KL5KUSB105D_PID 0x00c0
/* Vendor commands: */ /* Vendor commands: */
......
...@@ -190,8 +190,10 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -190,8 +190,10 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
KOBIL_TIMEOUT KOBIL_TIMEOUT
); );
dev_dbg(dev, "%s - Send get_HW_version URB returns: %i\n", __func__, result); dev_dbg(dev, "%s - Send get_HW_version URB returns: %i\n", __func__, result);
if (result >= 3) {
dev_dbg(dev, "Hardware version: %i.%i.%i\n", transfer_buffer[0], dev_dbg(dev, "Hardware version: %i.%i.%i\n", transfer_buffer[0],
transfer_buffer[1], transfer_buffer[2]); transfer_buffer[1], transfer_buffer[2]);
}
/* get firmware version */ /* get firmware version */
result = usb_control_msg(port->serial->dev, result = usb_control_msg(port->serial->dev,
...@@ -205,8 +207,10 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -205,8 +207,10 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
KOBIL_TIMEOUT KOBIL_TIMEOUT
); );
dev_dbg(dev, "%s - Send get_FW_version URB returns: %i\n", __func__, result); dev_dbg(dev, "%s - Send get_FW_version URB returns: %i\n", __func__, result);
if (result >= 3) {
dev_dbg(dev, "Firmware version: %i.%i.%i\n", transfer_buffer[0], dev_dbg(dev, "Firmware version: %i.%i.%i\n", transfer_buffer[0],
transfer_buffer[1], transfer_buffer[2]); transfer_buffer[1], transfer_buffer[2]);
}
if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
...@@ -393,12 +397,20 @@ static int kobil_tiocmget(struct tty_struct *tty) ...@@ -393,12 +397,20 @@ static int kobil_tiocmget(struct tty_struct *tty)
transfer_buffer_length, transfer_buffer_length,
KOBIL_TIMEOUT); KOBIL_TIMEOUT);
dev_dbg(&port->dev, "%s - Send get_status_line_state URB returns: %i. Statusline: %02x\n", dev_dbg(&port->dev, "Send get_status_line_state URB returns: %i\n",
__func__, result, transfer_buffer[0]); result);
if (result < 1) {
if (result >= 0)
result = -EIO;
goto out_free;
}
dev_dbg(&port->dev, "Statusline: %02x\n", transfer_buffer[0]);
result = 0; result = 0;
if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0)
result = TIOCM_DSR; result = TIOCM_DSR;
out_free:
kfree(transfer_buffer); kfree(transfer_buffer);
return result; return result;
} }
......
...@@ -340,14 +340,15 @@ static void async_complete(struct urb *urb) ...@@ -340,14 +340,15 @@ static void async_complete(struct urb *urb)
{ {
struct urbtracker *urbtrack = urb->context; struct urbtracker *urbtrack = urb->context;
int status = urb->status; int status = urb->status;
unsigned long flags;
if (unlikely(status)) if (unlikely(status))
dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __func__, status); dev_dbg(&urb->dev->dev, "%s - nonzero urb status received: %d\n", __func__, status);
/* remove the urbtracker from the active_urbs list */ /* remove the urbtracker from the active_urbs list */
spin_lock(&urbtrack->mos_parport->listlock); spin_lock_irqsave(&urbtrack->mos_parport->listlock, flags);
list_del(&urbtrack->urblist_entry); list_del(&urbtrack->urblist_entry);
spin_unlock(&urbtrack->mos_parport->listlock); spin_unlock_irqrestore(&urbtrack->mos_parport->listlock, flags);
kref_put(&urbtrack->ref_count, destroy_urbtracker); kref_put(&urbtrack->ref_count, destroy_urbtracker);
} }
...@@ -1526,8 +1527,6 @@ static void change_port_settings(struct tty_struct *tty, ...@@ -1526,8 +1527,6 @@ static void change_port_settings(struct tty_struct *tty,
struct usb_serial *serial; struct usb_serial *serial;
int baud; int baud;
unsigned cflag; unsigned cflag;
unsigned iflag;
__u8 mask = 0xff;
__u8 lData; __u8 lData;
__u8 lParity; __u8 lParity;
__u8 lStop; __u8 lStop;
...@@ -1551,23 +1550,19 @@ static void change_port_settings(struct tty_struct *tty, ...@@ -1551,23 +1550,19 @@ static void change_port_settings(struct tty_struct *tty,
lParity = 0x00; /* No parity */ lParity = 0x00; /* No parity */
cflag = tty->termios.c_cflag; cflag = tty->termios.c_cflag;
iflag = tty->termios.c_iflag;
/* Change the number of bits */ /* Change the number of bits */
switch (cflag & CSIZE) { switch (cflag & CSIZE) {
case CS5: case CS5:
lData = UART_LCR_WLEN5; lData = UART_LCR_WLEN5;
mask = 0x1f;
break; break;
case CS6: case CS6:
lData = UART_LCR_WLEN6; lData = UART_LCR_WLEN6;
mask = 0x3f;
break; break;
case CS7: case CS7:
lData = UART_LCR_WLEN7; lData = UART_LCR_WLEN7;
mask = 0x7f;
break; break;
default: default:
case CS8: case CS8:
...@@ -1685,11 +1680,8 @@ static void mos7720_set_termios(struct tty_struct *tty, ...@@ -1685,11 +1680,8 @@ static void mos7720_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios) struct usb_serial_port *port, struct ktermios *old_termios)
{ {
int status; int status;
struct usb_serial *serial;
struct moschip_port *mos7720_port; struct moschip_port *mos7720_port;
serial = port->serial;
mos7720_port = usb_get_serial_port_data(port); mos7720_port = usb_get_serial_port_data(port);
if (mos7720_port == NULL) if (mos7720_port == NULL)
......
...@@ -805,18 +805,19 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) ...@@ -805,18 +805,19 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
struct moschip_port *mos7840_port; struct moschip_port *mos7840_port;
struct usb_serial_port *port; struct usb_serial_port *port;
int status = urb->status; int status = urb->status;
unsigned long flags;
int i; int i;
mos7840_port = urb->context; mos7840_port = urb->context;
port = mos7840_port->port; port = mos7840_port->port;
spin_lock(&mos7840_port->pool_lock); spin_lock_irqsave(&mos7840_port->pool_lock, flags);
for (i = 0; i < NUM_URBS; i++) { for (i = 0; i < NUM_URBS; i++) {
if (urb == mos7840_port->write_urb_pool[i]) { if (urb == mos7840_port->write_urb_pool[i]) {
mos7840_port->busy[i] = 0; mos7840_port->busy[i] = 0;
break; break;
} }
} }
spin_unlock(&mos7840_port->pool_lock); spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
if (status) { if (status) {
dev_dbg(&port->dev, "nonzero write bulk status received:%d\n", status); dev_dbg(&port->dev, "nonzero write bulk status received:%d\n", status);
......
...@@ -194,7 +194,7 @@ static inline int qt2_getregister(struct usb_device *dev, ...@@ -194,7 +194,7 @@ static inline int qt2_getregister(struct usb_device *dev,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg, QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), QT2_USB_TIMEOUT); uart, data, sizeof(*data), QT2_USB_TIMEOUT);
if (ret < sizeof(*data)) { if (ret < (int)sizeof(*data)) {
if (ret >= 0) if (ret >= 0)
ret = -EIO; ret = -EIO;
} }
...@@ -621,16 +621,17 @@ static void qt2_write_bulk_callback(struct urb *urb) ...@@ -621,16 +621,17 @@ static void qt2_write_bulk_callback(struct urb *urb)
{ {
struct usb_serial_port *port; struct usb_serial_port *port;
struct qt2_port_private *port_priv; struct qt2_port_private *port_priv;
unsigned long flags;
port = urb->context; port = urb->context;
port_priv = usb_get_serial_port_data(port); port_priv = usb_get_serial_port_data(port);
spin_lock(&port_priv->urb_lock); spin_lock_irqsave(&port_priv->urb_lock, flags);
port_priv->urb_in_use = false; port_priv->urb_in_use = false;
usb_serial_port_softint(port); usb_serial_port_softint(port);
spin_unlock(&port_priv->urb_lock); spin_unlock_irqrestore(&port_priv->urb_lock, flags);
} }
......
...@@ -409,6 +409,7 @@ static void sierra_outdat_callback(struct urb *urb) ...@@ -409,6 +409,7 @@ static void sierra_outdat_callback(struct urb *urb)
struct sierra_port_private *portdata = usb_get_serial_port_data(port); struct sierra_port_private *portdata = usb_get_serial_port_data(port);
struct sierra_intf_private *intfdata; struct sierra_intf_private *intfdata;
int status = urb->status; int status = urb->status;
unsigned long flags;
intfdata = usb_get_serial_data(port->serial); intfdata = usb_get_serial_data(port->serial);
...@@ -419,12 +420,12 @@ static void sierra_outdat_callback(struct urb *urb) ...@@ -419,12 +420,12 @@ static void sierra_outdat_callback(struct urb *urb)
dev_dbg(&port->dev, "%s - nonzero write bulk status " dev_dbg(&port->dev, "%s - nonzero write bulk status "
"received: %d\n", __func__, status); "received: %d\n", __func__, status);
spin_lock(&portdata->lock); spin_lock_irqsave(&portdata->lock, flags);
--portdata->outstanding_urbs; --portdata->outstanding_urbs;
spin_unlock(&portdata->lock); spin_unlock_irqrestore(&portdata->lock, flags);
spin_lock(&intfdata->susp_lock); spin_lock_irqsave(&intfdata->susp_lock, flags);
--intfdata->in_flight; --intfdata->in_flight;
spin_unlock(&intfdata->susp_lock); spin_unlock_irqrestore(&intfdata->susp_lock, flags);
usb_serial_port_softint(port); usb_serial_port_softint(port);
} }
...@@ -770,9 +771,9 @@ static void sierra_close(struct usb_serial_port *port) ...@@ -770,9 +771,9 @@ static void sierra_close(struct usb_serial_port *port)
kfree(urb->transfer_buffer); kfree(urb->transfer_buffer);
usb_free_urb(urb); usb_free_urb(urb);
usb_autopm_put_interface_async(serial->interface); usb_autopm_put_interface_async(serial->interface);
spin_lock(&portdata->lock); spin_lock_irq(&portdata->lock);
portdata->outstanding_urbs--; portdata->outstanding_urbs--;
spin_unlock(&portdata->lock); spin_unlock_irq(&portdata->lock);
} }
sierra_stop_rx_urbs(port); sierra_stop_rx_urbs(port);
......
...@@ -104,7 +104,7 @@ static inline int ssu100_getregister(struct usb_device *dev, ...@@ -104,7 +104,7 @@ static inline int ssu100_getregister(struct usb_device *dev,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0xc0, reg, QT_SET_GET_REGISTER, 0xc0, reg,
uart, data, sizeof(*data), 300); uart, data, sizeof(*data), 300);
if (ret < sizeof(*data)) { if (ret < (int)sizeof(*data)) {
if (ret >= 0) if (ret >= 0)
ret = -EIO; ret = -EIO;
} }
......
...@@ -35,6 +35,7 @@ static void symbol_int_callback(struct urb *urb) ...@@ -35,6 +35,7 @@ static void symbol_int_callback(struct urb *urb)
struct symbol_private *priv = usb_get_serial_port_data(port); struct symbol_private *priv = usb_get_serial_port_data(port);
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
int status = urb->status; int status = urb->status;
unsigned long flags;
int result; int result;
int data_length; int data_length;
...@@ -73,7 +74,7 @@ static void symbol_int_callback(struct urb *urb) ...@@ -73,7 +74,7 @@ static void symbol_int_callback(struct urb *urb)
} }
exit: exit:
spin_lock(&priv->lock); spin_lock_irqsave(&priv->lock, flags);
/* Continue trying to always read if we should */ /* Continue trying to always read if we should */
if (!priv->throttled) { if (!priv->throttled) {
...@@ -84,7 +85,7 @@ static void symbol_int_callback(struct urb *urb) ...@@ -84,7 +85,7 @@ static void symbol_int_callback(struct urb *urb)
__func__, result); __func__, result);
} else } else
priv->actually_throttled = true; priv->actually_throttled = true;
spin_unlock(&priv->lock); spin_unlock_irqrestore(&priv->lock, flags);
} }
static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port) static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port)
......
...@@ -1215,6 +1215,7 @@ static void ti_bulk_in_callback(struct urb *urb) ...@@ -1215,6 +1215,7 @@ static void ti_bulk_in_callback(struct urb *urb)
struct usb_serial_port *port = tport->tp_port; struct usb_serial_port *port = tport->tp_port;
struct device *dev = &urb->dev->dev; struct device *dev = &urb->dev->dev;
int status = urb->status; int status = urb->status;
unsigned long flags;
int retval = 0; int retval = 0;
switch (status) { switch (status) {
...@@ -1247,20 +1248,20 @@ static void ti_bulk_in_callback(struct urb *urb) ...@@ -1247,20 +1248,20 @@ static void ti_bulk_in_callback(struct urb *urb)
__func__); __func__);
else else
ti_recv(port, urb->transfer_buffer, urb->actual_length); ti_recv(port, urb->transfer_buffer, urb->actual_length);
spin_lock(&tport->tp_lock); spin_lock_irqsave(&tport->tp_lock, flags);
port->icount.rx += urb->actual_length; port->icount.rx += urb->actual_length;
spin_unlock(&tport->tp_lock); spin_unlock_irqrestore(&tport->tp_lock, flags);
} }
exit: exit:
/* continue to read unless stopping */ /* continue to read unless stopping */
spin_lock(&tport->tp_lock); spin_lock_irqsave(&tport->tp_lock, flags);
if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) if (tport->tp_read_urb_state == TI_READ_URB_RUNNING)
retval = usb_submit_urb(urb, GFP_ATOMIC); retval = usb_submit_urb(urb, GFP_ATOMIC);
else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING)
tport->tp_read_urb_state = TI_READ_URB_STOPPED; tport->tp_read_urb_state = TI_READ_URB_STOPPED;
spin_unlock(&tport->tp_lock); spin_unlock_irqrestore(&tport->tp_lock, flags);
if (retval) if (retval)
dev_err(dev, "%s - resubmit read urb failed, %d\n", dev_err(dev, "%s - resubmit read urb failed, %d\n",
__func__, retval); __func__, retval);
......
...@@ -326,6 +326,7 @@ static void usb_wwan_outdat_callback(struct urb *urb) ...@@ -326,6 +326,7 @@ static void usb_wwan_outdat_callback(struct urb *urb)
struct usb_serial_port *port; struct usb_serial_port *port;
struct usb_wwan_port_private *portdata; struct usb_wwan_port_private *portdata;
struct usb_wwan_intf_private *intfdata; struct usb_wwan_intf_private *intfdata;
unsigned long flags;
int i; int i;
port = urb->context; port = urb->context;
...@@ -334,9 +335,9 @@ static void usb_wwan_outdat_callback(struct urb *urb) ...@@ -334,9 +335,9 @@ static void usb_wwan_outdat_callback(struct urb *urb)
usb_serial_port_softint(port); usb_serial_port_softint(port);
usb_autopm_put_interface_async(port->serial->interface); usb_autopm_put_interface_async(port->serial->interface);
portdata = usb_get_serial_port_data(port); portdata = usb_get_serial_port_data(port);
spin_lock(&intfdata->susp_lock); spin_lock_irqsave(&intfdata->susp_lock, flags);
intfdata->in_flight--; intfdata->in_flight--;
spin_unlock(&intfdata->susp_lock); spin_unlock_irqrestore(&intfdata->susp_lock, flags);
for (i = 0; i < N_OUT_URB; ++i) { for (i = 0; i < N_OUT_URB; ++i) {
if (portdata->out_urbs[i] == urb) { if (portdata->out_urbs[i] == urb) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment