|
@@ -675,12 +675,14 @@ static int open(struct tty_struct *tty, struct file *filp)
|
|
|
goto cleanup;
|
|
|
}
|
|
|
|
|
|
+ mutex_lock(&info->port.mutex);
|
|
|
info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
|
|
|
|
|
|
spin_lock_irqsave(&info->netlock, flags);
|
|
|
if (info->netcount) {
|
|
|
retval = -EBUSY;
|
|
|
spin_unlock_irqrestore(&info->netlock, flags);
|
|
|
+ mutex_unlock(&info->port.mutex);
|
|
|
goto cleanup;
|
|
|
}
|
|
|
info->port.count++;
|
|
@@ -692,7 +694,7 @@ static int open(struct tty_struct *tty, struct file *filp)
|
|
|
if (retval < 0)
|
|
|
goto cleanup;
|
|
|
}
|
|
|
-
|
|
|
+ mutex_unlock(&info->port.mutex);
|
|
|
retval = block_til_ready(tty, filp, info);
|
|
|
if (retval) {
|
|
|
DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval));
|
|
@@ -724,12 +726,14 @@ static void close(struct tty_struct *tty, struct file *filp)
|
|
|
if (tty_port_close_start(&info->port, tty, filp) == 0)
|
|
|
goto cleanup;
|
|
|
|
|
|
+ mutex_lock(&info->port.mutex);
|
|
|
if (info->port.flags & ASYNC_INITIALIZED)
|
|
|
wait_until_sent(tty, info->timeout);
|
|
|
flush_buffer(tty);
|
|
|
tty_ldisc_flush(tty);
|
|
|
|
|
|
shutdown(info);
|
|
|
+ mutex_unlock(&info->port.mutex);
|
|
|
|
|
|
tty_port_close_end(&info->port, tty);
|
|
|
info->port.tty = NULL;
|
|
@@ -740,17 +744,23 @@ cleanup:
|
|
|
static void hangup(struct tty_struct *tty)
|
|
|
{
|
|
|
struct slgt_info *info = tty->driver_data;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
if (sanity_check(info, tty->name, "hangup"))
|
|
|
return;
|
|
|
DBGINFO(("%s hangup\n", info->device_name));
|
|
|
|
|
|
flush_buffer(tty);
|
|
|
+
|
|
|
+ mutex_lock(&info->port.mutex);
|
|
|
shutdown(info);
|
|
|
|
|
|
+ spin_lock_irqsave(&info->port.lock, flags);
|
|
|
info->port.count = 0;
|
|
|
info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
|
|
|
info->port.tty = NULL;
|
|
|
+ spin_unlock_irqrestore(&info->port.lock, flags);
|
|
|
+ mutex_unlock(&info->port.mutex);
|
|
|
|
|
|
wake_up_interruptible(&info->port.open_wait);
|
|
|
}
|