aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/mct_u232.c17
-rw-r--r--drivers/usb/serial/option.c5
-rw-r--r--drivers/usb/serial/sierra.c5
-rw-r--r--drivers/usb/serial/visor.c22
-rw-r--r--drivers/usb/serial/whiteheat.c7
5 files changed, 35 insertions, 21 deletions
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 88b2074867c5..fc1cea4aba13 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -487,21 +487,22 @@ error:
487static void mct_u232_close (struct usb_serial_port *port, struct file *filp) 487static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
488{ 488{
489 unsigned int c_cflag; 489 unsigned int c_cflag;
490 unsigned long flags;
491 unsigned int control_state; 490 unsigned int control_state;
492 struct mct_u232_private *priv = usb_get_serial_port_data(port); 491 struct mct_u232_private *priv = usb_get_serial_port_data(port);
493 dbg("%s port %d", __FUNCTION__, port->number); 492 dbg("%s port %d", __FUNCTION__, port->number);
494 493
495 if (port->tty) { 494 if (port->tty) {
496 c_cflag = port->tty->termios->c_cflag; 495 c_cflag = port->tty->termios->c_cflag;
497 if (c_cflag & HUPCL) { 496 mutex_lock(&port->serial->disc_mutex);
498 /* drop DTR and RTS */ 497 if (c_cflag & HUPCL && !port->serial->disconnected) {
499 spin_lock_irqsave(&priv->lock, flags); 498 /* drop DTR and RTS */
500 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); 499 spin_lock_irq(&priv->lock);
501 control_state = priv->control_state; 500 priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
502 spin_unlock_irqrestore(&priv->lock, flags); 501 control_state = priv->control_state;
503 mct_u232_set_modem_ctrl(port->serial, control_state); 502 spin_unlock_irq(&priv->lock);
503 mct_u232_set_modem_ctrl(port->serial, control_state);
504 } 504 }
505 mutex_unlock(&port->serial->disc_mutex);
505 } 506 }
506 507
507 508
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index bbbe1b962008..5e8bf1bc1e50 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -641,7 +641,10 @@ static void option_close(struct usb_serial_port *port, struct file *filp)
641 portdata->dtr_state = 0; 641 portdata->dtr_state = 0;
642 642
643 if (serial->dev) { 643 if (serial->dev) {
644 option_send_setup(port); 644 mutex_lock(&serial->disc_mutex);
645 if (!serial->disconnected)
646 option_send_setup(port);
647 mutex_unlock(&serial->disc_mutex);
645 648
646 /* Stop reading/writing urbs */ 649 /* Stop reading/writing urbs */
647 for (i = 0; i < N_IN_URB; i++) 650 for (i = 0; i < N_IN_URB; i++)
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 953bdf8827d2..4c925e3e8a63 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -597,7 +597,10 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
597 portdata->dtr_state = 0; 597 portdata->dtr_state = 0;
598 598
599 if (serial->dev) { 599 if (serial->dev) {
600 sierra_send_setup(port); 600 mutex_lock(&serial->disc_mutex);
601 if (!serial->disconnected)
602 sierra_send_setup(port);
603 mutex_unlock(&serial->disc_mutex);
601 604
602 /* Stop reading/writing urbs */ 605 /* Stop reading/writing urbs */
603 for (i = 0; i < N_IN_URB; i++) 606 for (i = 0; i < N_IN_URB; i++)
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 7ee087fed913..c2347995c786 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -349,16 +349,20 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
349 usb_kill_urb(port->read_urb); 349 usb_kill_urb(port->read_urb);
350 usb_kill_urb(port->interrupt_in_urb); 350 usb_kill_urb(port->interrupt_in_urb);
351 351
352 /* Try to send shutdown message, if the device is gone, this will just fail. */ 352 mutex_lock(&port->serial->disc_mutex);
353 transfer_buffer = kmalloc (0x12, GFP_KERNEL); 353 if (!port->serial->disconnected) {
354 if (transfer_buffer) { 354 /* Try to send shutdown message, unless the device is gone */
355 usb_control_msg (port->serial->dev, 355 transfer_buffer = kmalloc (0x12, GFP_KERNEL);
356 usb_rcvctrlpipe(port->serial->dev, 0), 356 if (transfer_buffer) {
357 VISOR_CLOSE_NOTIFICATION, 0xc2, 357 usb_control_msg (port->serial->dev,
358 0x0000, 0x0000, 358 usb_rcvctrlpipe(port->serial->dev, 0),
359 transfer_buffer, 0x12, 300); 359 VISOR_CLOSE_NOTIFICATION, 0xc2,
360 kfree (transfer_buffer); 360 0x0000, 0x0000,
361 transfer_buffer, 0x12, 300);
362 kfree (transfer_buffer);
363 }
361 } 364 }
365 mutex_lock(&port->serial->disc_mutex);
362 366
363 if (stats) 367 if (stats)
364 dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n", 368 dev_info(&port->dev, "Bytes In = %d Bytes Out = %d\n",
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index f5033d482eee..38726ef3132b 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -658,11 +658,14 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
658 struct list_head *tmp2; 658 struct list_head *tmp2;
659 659
660 dbg("%s - port %d", __FUNCTION__, port->number); 660 dbg("%s - port %d", __FUNCTION__, port->number);
661 661
662 mutex_lock(&port->serial->disc_mutex);
662 /* filp is NULL when called from usb_serial_disconnect */ 663 /* filp is NULL when called from usb_serial_disconnect */
663 if (filp && (tty_hung_up_p(filp))) { 664 if ((filp && (tty_hung_up_p(filp))) || port->serial->disconnected) {
665 mutex_unlock(&port->serial->disc_mutex);
664 return; 666 return;
665 } 667 }
668 mutex_unlock(&port->serial->disc_mutex);
666 669
667 port->tty->closing = 1; 670 port->tty->closing = 1;
668 671