diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/console.c | 13 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 9 | ||||
-rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/mct_u232.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/mos7840.c | 3 | ||||
-rw-r--r-- | drivers/usb/serial/sierra.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 26 |
7 files changed, 42 insertions, 14 deletions
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 5b95009d2fbb..19e24045b137 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -241,12 +241,25 @@ static void usb_console_write(struct console *co, | |||
241 | } | 241 | } |
242 | } | 242 | } |
243 | 243 | ||
244 | static struct tty_driver *usb_console_device(struct console *co, int *index) | ||
245 | { | ||
246 | struct tty_driver **p = (struct tty_driver **)co->data; | ||
247 | |||
248 | if (!*p) | ||
249 | return NULL; | ||
250 | |||
251 | *index = co->index; | ||
252 | return *p; | ||
253 | } | ||
254 | |||
244 | static struct console usbcons = { | 255 | static struct console usbcons = { |
245 | .name = "ttyUSB", | 256 | .name = "ttyUSB", |
246 | .write = usb_console_write, | 257 | .write = usb_console_write, |
258 | .device = usb_console_device, | ||
247 | .setup = usb_console_setup, | 259 | .setup = usb_console_setup, |
248 | .flags = CON_PRINTBUFFER, | 260 | .flags = CON_PRINTBUFFER, |
249 | .index = -1, | 261 | .index = -1, |
262 | .data = &usb_serial_tty_driver, | ||
250 | }; | 263 | }; |
251 | 264 | ||
252 | void usb_serial_console_disconnect(struct usb_serial *serial) | 265 | void usb_serial_console_disconnect(struct usb_serial *serial) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index fb6f2933b01b..ef6cfa5a447f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1054,6 +1054,8 @@ static int set_serial_info(struct tty_struct *tty, | |||
1054 | 1054 | ||
1055 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | 1055 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) |
1056 | return -EFAULT; | 1056 | return -EFAULT; |
1057 | |||
1058 | lock_kernel(); | ||
1057 | old_priv = *priv; | 1059 | old_priv = *priv; |
1058 | 1060 | ||
1059 | /* Do error checking and permission checking */ | 1061 | /* Do error checking and permission checking */ |
@@ -1069,8 +1071,10 @@ static int set_serial_info(struct tty_struct *tty, | |||
1069 | } | 1071 | } |
1070 | 1072 | ||
1071 | if ((new_serial.baud_base != priv->baud_base) && | 1073 | if ((new_serial.baud_base != priv->baud_base) && |
1072 | (new_serial.baud_base < 9600)) | 1074 | (new_serial.baud_base < 9600)) { |
1075 | unlock_kernel(); | ||
1073 | return -EINVAL; | 1076 | return -EINVAL; |
1077 | } | ||
1074 | 1078 | ||
1075 | /* Make the changes - these are privileged changes! */ | 1079 | /* Make the changes - these are privileged changes! */ |
1076 | 1080 | ||
@@ -1098,8 +1102,11 @@ check_and_exit: | |||
1098 | (priv->flags & ASYNC_SPD_MASK)) || | 1102 | (priv->flags & ASYNC_SPD_MASK)) || |
1099 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && | 1103 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && |
1100 | (old_priv.custom_divisor != priv->custom_divisor))) { | 1104 | (old_priv.custom_divisor != priv->custom_divisor))) { |
1105 | unlock_kernel(); | ||
1101 | change_speed(tty, port); | 1106 | change_speed(tty, port); |
1102 | } | 1107 | } |
1108 | else | ||
1109 | unlock_kernel(); | ||
1103 | return 0; | 1110 | return 0; |
1104 | 1111 | ||
1105 | } /* set_serial_info */ | 1112 | } /* set_serial_info */ |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index dc36a052766f..fcd9082f3e7f 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -878,6 +878,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) | |||
878 | 878 | ||
879 | dbg("%sstate=%d", __func__, break_state); | 879 | dbg("%sstate=%d", __func__, break_state); |
880 | 880 | ||
881 | /* LOCKING */ | ||
881 | if (break_state) | 882 | if (break_state) |
882 | lcr |= MCT_U232_SET_BREAK; | 883 | lcr |= MCT_U232_SET_BREAK; |
883 | 884 | ||
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 07710cf31d0d..82930a7d5093 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -721,10 +721,10 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) | |||
721 | 721 | ||
722 | spin_lock_irqsave(&priv->lock, flags); | 722 | spin_lock_irqsave(&priv->lock, flags); |
723 | lcr = priv->last_lcr; | 723 | lcr = priv->last_lcr; |
724 | spin_unlock_irqrestore(&priv->lock, flags); | ||
725 | 724 | ||
726 | if (break_state) | 725 | if (break_state) |
727 | lcr |= MCT_U232_SET_BREAK; | 726 | lcr |= MCT_U232_SET_BREAK; |
727 | spin_unlock_irqrestore(&priv->lock, flags); | ||
728 | 728 | ||
729 | mct_u232_set_line_ctrl(serial, lcr); | 729 | mct_u232_set_line_ctrl(serial, lcr); |
730 | } /* mct_u232_break_ctl */ | 730 | } /* mct_u232_break_ctl */ |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index fda4a6421c44..96a8c7713212 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1343,6 +1343,7 @@ static void mos7840_break(struct tty_struct *tty, int break_state) | |||
1343 | else | 1343 | else |
1344 | data = mos7840_port->shadowLCR & ~LCR_SET_BREAK; | 1344 | data = mos7840_port->shadowLCR & ~LCR_SET_BREAK; |
1345 | 1345 | ||
1346 | /* FIXME: no locking on shadowLCR anywhere in driver */ | ||
1346 | mos7840_port->shadowLCR = data; | 1347 | mos7840_port->shadowLCR = data; |
1347 | dbg("mcs7840_break mos7840_port->shadowLCR is %x\n", | 1348 | dbg("mcs7840_break mos7840_port->shadowLCR is %x\n", |
1348 | mos7840_port->shadowLCR); | 1349 | mos7840_port->shadowLCR); |
@@ -2214,10 +2215,12 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port, | |||
2214 | break; | 2215 | break; |
2215 | } | 2216 | } |
2216 | 2217 | ||
2218 | lock_kernel(); | ||
2217 | mos7840_port->shadowMCR = mcr; | 2219 | mos7840_port->shadowMCR = mcr; |
2218 | 2220 | ||
2219 | Data = mos7840_port->shadowMCR; | 2221 | Data = mos7840_port->shadowMCR; |
2220 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); | 2222 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); |
2223 | unlock_kernel(); | ||
2221 | if (status < 0) { | 2224 | if (status < 0) { |
2222 | dbg("setting MODEM_CONTROL_REGISTER Failed\n"); | 2225 | dbg("setting MODEM_CONTROL_REGISTER Failed\n"); |
2223 | return -1; | 2226 | return -1; |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 0f2b67244af6..d9bf9a5c20ec 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -442,7 +442,7 @@ static void sierra_indat_callback(struct urb *urb) | |||
442 | " endpoint %02x.", __func__, status, endpoint); | 442 | " endpoint %02x.", __func__, status, endpoint); |
443 | } else { | 443 | } else { |
444 | if (urb->actual_length) { | 444 | if (urb->actual_length) { |
445 | tty = tty_port_tty_get(&port->port); | 445 | tty = tty_port_tty_get(&port->port); |
446 | tty_buffer_request_room(tty, urb->actual_length); | 446 | tty_buffer_request_room(tty, urb->actual_length); |
447 | tty_insert_flip_string(tty, data, urb->actual_length); | 447 | tty_insert_flip_string(tty, data, urb->actual_length); |
448 | tty_flip_buffer_push(tty); | 448 | tty_flip_buffer_push(tty); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 794b5ffe4397..080ade223d53 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -269,15 +269,19 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
269 | return; | 269 | return; |
270 | } | 270 | } |
271 | 271 | ||
272 | --port->port.count; | 272 | if (port->port.count == 1) |
273 | if (port->port.count == 0) | ||
274 | /* only call the device specific close if this | 273 | /* only call the device specific close if this |
275 | * port is being closed by the last owner */ | 274 | * port is being closed by the last owner. Ensure we do |
275 | * this before we drop the port count. The call is protected | ||
276 | * by the port mutex | ||
277 | */ | ||
276 | port->serial->type->close(tty, port, filp); | 278 | port->serial->type->close(tty, port, filp); |
277 | 279 | ||
278 | if (port->port.count == (port->console? 1 : 0)) { | 280 | if (port->port.count == (port->console ? 2 : 1)) { |
279 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 281 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
280 | if (tty) { | 282 | if (tty) { |
283 | /* We must do this before we drop the port count to | ||
284 | zero. */ | ||
281 | if (tty->driver_data) | 285 | if (tty->driver_data) |
282 | tty->driver_data = NULL; | 286 | tty->driver_data = NULL; |
283 | tty_port_tty_set(&port->port, NULL); | 287 | tty_port_tty_set(&port->port, NULL); |
@@ -285,13 +289,14 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
285 | } | 289 | } |
286 | } | 290 | } |
287 | 291 | ||
288 | if (port->port.count == 0) { | 292 | if (port->port.count == 1) { |
289 | mutex_lock(&port->serial->disc_mutex); | 293 | mutex_lock(&port->serial->disc_mutex); |
290 | if (!port->serial->disconnected) | 294 | if (!port->serial->disconnected) |
291 | usb_autopm_put_interface(port->serial->interface); | 295 | usb_autopm_put_interface(port->serial->interface); |
292 | mutex_unlock(&port->serial->disc_mutex); | 296 | mutex_unlock(&port->serial->disc_mutex); |
293 | module_put(port->serial->type->driver.owner); | 297 | module_put(port->serial->type->driver.owner); |
294 | } | 298 | } |
299 | --port->port.count; | ||
295 | 300 | ||
296 | mutex_unlock(&port->mutex); | 301 | mutex_unlock(&port->mutex); |
297 | usb_serial_put(port->serial); | 302 | usb_serial_put(port->serial); |
@@ -334,6 +339,10 @@ static int serial_chars_in_buffer(struct tty_struct *tty) | |||
334 | dbg("%s = port %d", __func__, port->number); | 339 | dbg("%s = port %d", __func__, port->number); |
335 | 340 | ||
336 | WARN_ON(!port->port.count); | 341 | WARN_ON(!port->port.count); |
342 | /* if the device was unplugged then any remaining characters | ||
343 | fell out of the connector ;) */ | ||
344 | if (port->serial->disconnected) | ||
345 | return 0; | ||
337 | /* pass on to the driver specific version of this function */ | 346 | /* pass on to the driver specific version of this function */ |
338 | return port->serial->type->chars_in_buffer(tty); | 347 | return port->serial->type->chars_in_buffer(tty); |
339 | } | 348 | } |
@@ -373,9 +382,7 @@ static int serial_ioctl(struct tty_struct *tty, struct file *file, | |||
373 | /* pass on to the driver specific version of this function | 382 | /* pass on to the driver specific version of this function |
374 | if it is available */ | 383 | if it is available */ |
375 | if (port->serial->type->ioctl) { | 384 | if (port->serial->type->ioctl) { |
376 | lock_kernel(); | ||
377 | retval = port->serial->type->ioctl(tty, file, cmd, arg); | 385 | retval = port->serial->type->ioctl(tty, file, cmd, arg); |
378 | unlock_kernel(); | ||
379 | } else | 386 | } else |
380 | retval = -ENOIOCTLCMD; | 387 | retval = -ENOIOCTLCMD; |
381 | return retval; | 388 | return retval; |
@@ -404,11 +411,8 @@ static int serial_break(struct tty_struct *tty, int break_state) | |||
404 | WARN_ON(!port->port.count); | 411 | WARN_ON(!port->port.count); |
405 | /* pass on to the driver specific version of this function | 412 | /* pass on to the driver specific version of this function |
406 | if it is available */ | 413 | if it is available */ |
407 | if (port->serial->type->break_ctl) { | 414 | if (port->serial->type->break_ctl) |
408 | lock_kernel(); | ||
409 | port->serial->type->break_ctl(tty, break_state); | 415 | port->serial->type->break_ctl(tty, break_state); |
410 | unlock_kernel(); | ||
411 | } | ||
412 | return 0; | 416 | return 0; |
413 | } | 417 | } |
414 | 418 | ||