diff options
-rw-r--r-- | drivers/usb/serial/digi_acceleport.c | 13 | ||||
-rw-r--r-- | drivers/usb/serial/oti6858.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/pl2303.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/ti_usb_3410_5052.c | 17 |
4 files changed, 19 insertions, 15 deletions
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index ae410c4678ea..5f9c6e46bee5 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -1405,19 +1405,19 @@ static void digi_close(struct usb_serial_port *port, struct file *filp) | |||
1405 | unsigned char buf[32]; | 1405 | unsigned char buf[32]; |
1406 | struct tty_struct *tty = port->tty; | 1406 | struct tty_struct *tty = port->tty; |
1407 | struct digi_port *priv = usb_get_serial_port_data(port); | 1407 | struct digi_port *priv = usb_get_serial_port_data(port); |
1408 | unsigned long flags = 0; | ||
1409 | 1408 | ||
1410 | dbg("digi_close: TOP: port=%d, open_count=%d", | 1409 | dbg("digi_close: TOP: port=%d, open_count=%d", |
1411 | priv->dp_port_num, port->open_count); | 1410 | priv->dp_port_num, port->open_count); |
1412 | 1411 | ||
1412 | mutex_lock(&port->serial->disc_mutex); | ||
1413 | /* if disconnected, just clear flags */ | 1413 | /* if disconnected, just clear flags */ |
1414 | if (!usb_get_intfdata(port->serial->interface)) | 1414 | if (port->serial->disconnected) |
1415 | goto exit; | 1415 | goto exit; |
1416 | 1416 | ||
1417 | /* do cleanup only after final close on this port */ | 1417 | /* do cleanup only after final close on this port */ |
1418 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 1418 | spin_lock_irq(&priv->dp_port_lock); |
1419 | priv->dp_in_close = 1; | 1419 | priv->dp_in_close = 1; |
1420 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | 1420 | spin_unlock_irq(&priv->dp_port_lock); |
1421 | 1421 | ||
1422 | /* tell line discipline to process only XON/XOFF */ | 1422 | /* tell line discipline to process only XON/XOFF */ |
1423 | tty->closing = 1; | 1423 | tty->closing = 1; |
@@ -1482,11 +1482,12 @@ static void digi_close(struct usb_serial_port *port, struct file *filp) | |||
1482 | } | 1482 | } |
1483 | tty->closing = 0; | 1483 | tty->closing = 0; |
1484 | exit: | 1484 | exit: |
1485 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 1485 | spin_lock_irq(&priv->dp_port_lock); |
1486 | priv->dp_write_urb_in_use = 0; | 1486 | priv->dp_write_urb_in_use = 0; |
1487 | priv->dp_in_close = 0; | 1487 | priv->dp_in_close = 0; |
1488 | wake_up_interruptible(&priv->dp_close_wait); | 1488 | wake_up_interruptible(&priv->dp_close_wait); |
1489 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | 1489 | spin_unlock_irq(&priv->dp_port_lock); |
1490 | mutex_unlock(&port->serial->disc_mutex); | ||
1490 | dbg("digi_close: done"); | 1491 | dbg("digi_close: done"); |
1491 | } | 1492 | } |
1492 | 1493 | ||
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index db725aaf7d19..a3847d6c946e 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -649,7 +649,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
649 | set_current_state(TASK_INTERRUPTIBLE); | 649 | set_current_state(TASK_INTERRUPTIBLE); |
650 | if (oti6858_buf_data_avail(priv->buf) == 0 | 650 | if (oti6858_buf_data_avail(priv->buf) == 0 |
651 | || timeout == 0 || signal_pending(current) | 651 | || timeout == 0 || signal_pending(current) |
652 | || !usb_get_intfdata(port->serial->interface)) /* disconnect */ | 652 | || port->serial->disconnected) |
653 | break; | 653 | break; |
654 | spin_unlock_irqrestore(&priv->lock, flags); | 654 | spin_unlock_irqrestore(&priv->lock, flags); |
655 | timeout = schedule_timeout(timeout); | 655 | timeout = schedule_timeout(timeout); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ac3d8765f482..ae3ec1a64008 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -667,7 +667,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp) | |||
667 | set_current_state(TASK_INTERRUPTIBLE); | 667 | set_current_state(TASK_INTERRUPTIBLE); |
668 | if (pl2303_buf_data_avail(priv->buf) == 0 || | 668 | if (pl2303_buf_data_avail(priv->buf) == 0 || |
669 | timeout == 0 || signal_pending(current) || | 669 | timeout == 0 || signal_pending(current) || |
670 | !usb_get_intfdata(port->serial->interface)) /* disconnect */ | 670 | port->serial->disconnected) |
671 | break; | 671 | break; |
672 | spin_unlock_irqrestore(&priv->lock, flags); | 672 | spin_unlock_irqrestore(&priv->lock, flags); |
673 | timeout = schedule_timeout(timeout); | 673 | timeout = schedule_timeout(timeout); |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 70f56c8aef99..b517f93352ec 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -1493,11 +1493,10 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1493 | struct ti_device *tdev = tport->tp_tdev; | 1493 | struct ti_device *tdev = tport->tp_tdev; |
1494 | struct usb_serial_port *port = tport->tp_port; | 1494 | struct usb_serial_port *port = tport->tp_port; |
1495 | wait_queue_t wait; | 1495 | wait_queue_t wait; |
1496 | unsigned long flags; | ||
1497 | 1496 | ||
1498 | dbg("%s - port %d", __FUNCTION__, port->number); | 1497 | dbg("%s - port %d", __FUNCTION__, port->number); |
1499 | 1498 | ||
1500 | spin_lock_irqsave(&tport->tp_lock, flags); | 1499 | spin_lock_irq(&tport->tp_lock); |
1501 | 1500 | ||
1502 | /* wait for data to drain from the buffer */ | 1501 | /* wait for data to drain from the buffer */ |
1503 | tdev->td_urb_error = 0; | 1502 | tdev->td_urb_error = 0; |
@@ -1508,11 +1507,11 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1508 | if (ti_buf_data_avail(tport->tp_write_buf) == 0 | 1507 | if (ti_buf_data_avail(tport->tp_write_buf) == 0 |
1509 | || timeout == 0 || signal_pending(current) | 1508 | || timeout == 0 || signal_pending(current) |
1510 | || tdev->td_urb_error | 1509 | || tdev->td_urb_error |
1511 | || !usb_get_intfdata(port->serial->interface)) /* disconnect */ | 1510 | || port->serial->disconnected) /* disconnect */ |
1512 | break; | 1511 | break; |
1513 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 1512 | spin_unlock_irq(&tport->tp_lock); |
1514 | timeout = schedule_timeout(timeout); | 1513 | timeout = schedule_timeout(timeout); |
1515 | spin_lock_irqsave(&tport->tp_lock, flags); | 1514 | spin_lock_irq(&tport->tp_lock); |
1516 | } | 1515 | } |
1517 | set_current_state(TASK_RUNNING); | 1516 | set_current_state(TASK_RUNNING); |
1518 | remove_wait_queue(&tport->tp_write_wait, &wait); | 1517 | remove_wait_queue(&tport->tp_write_wait, &wait); |
@@ -1521,19 +1520,23 @@ static void ti_drain(struct ti_port *tport, unsigned long timeout, int flush) | |||
1521 | if (flush) | 1520 | if (flush) |
1522 | ti_buf_clear(tport->tp_write_buf); | 1521 | ti_buf_clear(tport->tp_write_buf); |
1523 | 1522 | ||
1524 | spin_unlock_irqrestore(&tport->tp_lock, flags); | 1523 | spin_unlock_irq(&tport->tp_lock); |
1525 | 1524 | ||
1525 | mutex_lock(&port->serial->disc_mutex); | ||
1526 | /* wait for data to drain from the device */ | 1526 | /* wait for data to drain from the device */ |
1527 | /* wait for empty tx register, plus 20 ms */ | 1527 | /* wait for empty tx register, plus 20 ms */ |
1528 | timeout += jiffies; | 1528 | timeout += jiffies; |
1529 | tport->tp_lsr &= ~TI_LSR_TX_EMPTY; | 1529 | tport->tp_lsr &= ~TI_LSR_TX_EMPTY; |
1530 | while ((long)(jiffies - timeout) < 0 && !signal_pending(current) | 1530 | while ((long)(jiffies - timeout) < 0 && !signal_pending(current) |
1531 | && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error | 1531 | && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error |
1532 | && usb_get_intfdata(port->serial->interface)) { /* not disconnected */ | 1532 | && !port->serial->disconnected) { |
1533 | if (ti_get_lsr(tport)) | 1533 | if (ti_get_lsr(tport)) |
1534 | break; | 1534 | break; |
1535 | mutex_unlock(&port->serial->disc_mutex); | ||
1535 | msleep_interruptible(20); | 1536 | msleep_interruptible(20); |
1537 | mutex_lock(&port->serial->disc_mutex); | ||
1536 | } | 1538 | } |
1539 | mutex_unlock(&port->serial->disc_mutex); | ||
1537 | } | 1540 | } |
1538 | 1541 | ||
1539 | 1542 | ||