Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d41861ca authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

tty: Replace ASYNC_INITIALIZED bit and update atomically



Replace ASYNC_INITIALIZED bit in the tty_port::flags field with
TTY_PORT_INITIALIZED bit in the tty_port::iflags field. Introduce helpers
tty_port_set_initialized() and tty_port_initialized() to abstract
atomic bit ops.

Note: the transforms for test_and_set_bit() and test_and_clear_bit()
are unnecessary as the state transitions are already mutually exclusive;
the tty lock prevents concurrent open/close/hangup.

Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 80f02d54
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -1272,7 +1272,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty)
	if (debug_level >= DEBUG_LEVEL_INFO)
	if (debug_level >= DEBUG_LEVEL_INFO)
		printk("%s(%d):startup(%s)\n", __FILE__, __LINE__, info->device_name);
		printk("%s(%d):startup(%s)\n", __FILE__, __LINE__, info->device_name);


	if (info->port.flags & ASYNC_INITIALIZED)
	if (tty_port_initialized(&info->port))
		return 0;
		return 0;


	if (!info->tx_buf) {
	if (!info->tx_buf) {
@@ -1311,7 +1311,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty)
	if (tty)
	if (tty)
		clear_bit(TTY_IO_ERROR, &tty->flags);
		clear_bit(TTY_IO_ERROR, &tty->flags);


	info->port.flags |= ASYNC_INITIALIZED;
	tty_port_set_initialized(&info->port, 1);


	return 0;
	return 0;
}
}
@@ -1322,7 +1322,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty)
{
{
	unsigned long flags;
	unsigned long flags;


	if (!(info->port.flags & ASYNC_INITIALIZED))
	if (!tty_port_initialized(&info->port))
		return;
		return;


	if (debug_level >= DEBUG_LEVEL_INFO)
	if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1361,7 +1361,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty)
	if (tty)
	if (tty)
		set_bit(TTY_IO_ERROR, &tty->flags);
		set_bit(TTY_IO_ERROR, &tty->flags);


	info->port.flags &= ~ASYNC_INITIALIZED;
	tty_port_set_initialized(&info->port, 0);
}
}


static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty)
static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty)
@@ -2338,7 +2338,7 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp)
	if (tty_port_close_start(port, tty, filp) == 0)
	if (tty_port_close_start(port, tty, filp) == 0)
		goto cleanup;
		goto cleanup;


	if (port->flags & ASYNC_INITIALIZED)
	if (tty_port_initialized(port))
		mgslpc_wait_until_sent(tty, info->timeout);
		mgslpc_wait_until_sent(tty, info->timeout);


	mgslpc_flush_buffer(tty);
	mgslpc_flush_buffer(tty);
@@ -2371,7 +2371,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout)
	if (mgslpc_paranoia_check(info, tty->name, "mgslpc_wait_until_sent"))
	if (mgslpc_paranoia_check(info, tty->name, "mgslpc_wait_until_sent"))
		return;
		return;


	if (!(info->port.flags & ASYNC_INITIALIZED))
	if (!tty_port_initialized(&info->port))
		goto exit;
		goto exit;


	orig_jiffies = jiffies;
	orig_jiffies = jiffies;
+2 −3
Original line number Original line Diff line number Diff line
@@ -629,8 +629,7 @@ static void ipoctal_hangup(struct tty_struct *tty)
	tty_port_hangup(&channel->tty_port);
	tty_port_hangup(&channel->tty_port);


	ipoctal_reset_channel(channel);
	ipoctal_reset_channel(channel);

	tty_port_set_initialized(&channel->tty_port, 0);
	clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
	wake_up_interruptible(&channel->tty_port.open_wait);
	wake_up_interruptible(&channel->tty_port.open_wait);
}
}


@@ -642,7 +641,7 @@ static void ipoctal_shutdown(struct tty_struct *tty)
		return;
		return;


	ipoctal_reset_channel(channel);
	ipoctal_reset_channel(channel);
	clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
	tty_port_set_initialized(&channel->tty_port, 0);
}
}


static void ipoctal_cleanup(struct tty_struct *tty)
static void ipoctal_cleanup(struct tty_struct *tty)
+5 −5
Original line number Original line Diff line number Diff line
@@ -1049,7 +1049,7 @@ isdn_tty_change_speed(modem_info *info)
static int
static int
isdn_tty_startup(modem_info *info)
isdn_tty_startup(modem_info *info)
{
{
	if (info->port.flags & ASYNC_INITIALIZED)
	if (tty_port_initialized(&info->port))
		return 0;
		return 0;
	isdn_lock_drivers();
	isdn_lock_drivers();
#ifdef ISDN_DEBUG_MODEM_OPEN
#ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1066,7 +1066,7 @@ isdn_tty_startup(modem_info *info)
	 */
	 */
	isdn_tty_change_speed(info);
	isdn_tty_change_speed(info);


	info->port.flags |= ASYNC_INITIALIZED;
	tty_port_set_initialized(&info->port, 1);
	info->msr |= (UART_MSR_DSR | UART_MSR_CTS);
	info->msr |= (UART_MSR_DSR | UART_MSR_CTS);
	info->send_outstanding = 0;
	info->send_outstanding = 0;
	return 0;
	return 0;
@@ -1079,7 +1079,7 @@ isdn_tty_startup(modem_info *info)
static void
static void
isdn_tty_shutdown(modem_info *info)
isdn_tty_shutdown(modem_info *info)
{
{
	if (!(info->port.flags & ASYNC_INITIALIZED))
	if (!tty_port_initialized(&info->port))
		return;
		return;
#ifdef ISDN_DEBUG_MODEM_OPEN
#ifdef ISDN_DEBUG_MODEM_OPEN
	printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line);
	printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line);
@@ -1099,7 +1099,7 @@ isdn_tty_shutdown(modem_info *info)
	if (info->port.tty)
	if (info->port.tty)
		set_bit(TTY_IO_ERROR, &info->port.tty->flags);
		set_bit(TTY_IO_ERROR, &info->port.tty->flags);


	info->port.flags &= ~ASYNC_INITIALIZED;
	tty_port_set_initialized(&info->port, 0);
}
}


/* isdn_tty_write() is the main send-routine. It is called from the upper
/* isdn_tty_write() is the main send-routine. It is called from the upper
@@ -1577,7 +1577,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
	 * interrupt driver to stop checking the data ready bit in the
	 * interrupt driver to stop checking the data ready bit in the
	 * line status register.
	 * line status register.
	 */
	 */
	if (port->flags & ASYNC_INITIALIZED) {
	if (tty_port_initialized(port)) {
		tty_wait_until_sent(tty, 3000);	/* 30 seconds timeout */
		tty_wait_until_sent(tty, 3000);	/* 30 seconds timeout */
		/*
		/*
		 * Before we drop DTR, make sure the UART transmitter
		 * Before we drop DTR, make sure the UART transmitter
+5 −7
Original line number Original line Diff line number Diff line
@@ -311,8 +311,7 @@ static void raw3215_timeout(unsigned long __data)
 */
 */
static inline void raw3215_try_io(struct raw3215_info *raw)
static inline void raw3215_try_io(struct raw3215_info *raw)
{
{
	if (!(raw->port.flags & ASYNC_INITIALIZED) ||
	if (!tty_port_initialized(&raw->port) || tty_port_suspended(&raw->port))
	    tty_port_suspended(&raw->port))
		return;
		return;
	if (raw->queued_read != NULL)
	if (raw->queued_read != NULL)
		raw3215_start_io(raw);
		raw3215_start_io(raw);
@@ -616,10 +615,10 @@ static int raw3215_startup(struct raw3215_info *raw)
{
{
	unsigned long flags;
	unsigned long flags;


	if (raw->port.flags & ASYNC_INITIALIZED)
	if (tty_port_initialized(&raw->port))
		return 0;
		return 0;
	raw->line_pos = 0;
	raw->line_pos = 0;
	raw->port.flags |= ASYNC_INITIALIZED;
	tty_port_set_initialized(&raw->port, 1);
	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
	raw3215_try_io(raw);
	raw3215_try_io(raw);
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -635,8 +634,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
	DECLARE_WAITQUEUE(wait, current);
	DECLARE_WAITQUEUE(wait, current);
	unsigned long flags;
	unsigned long flags;


	if (!(raw->port.flags & ASYNC_INITIALIZED) ||
	if (!tty_port_initialized(&raw->port) || (raw->flags & RAW3215_FIXED))
	    (raw->flags & RAW3215_FIXED))
		return;
		return;
	/* Wait for outstanding requests, then free irq */
	/* Wait for outstanding requests, then free irq */
	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
@@ -650,7 +648,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
		spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
		spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
		remove_wait_queue(&raw->empty_wait, &wait);
		remove_wait_queue(&raw->empty_wait, &wait);
		set_current_state(TASK_RUNNING);
		set_current_state(TASK_RUNNING);
		raw->port.flags &= ~ASYNC_INITIALIZED;
		tty_port_set_initialized(&raw->port, 1);
	}
	}
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
}
+7 −7
Original line number Original line Diff line number Diff line
@@ -525,7 +525,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info)


	local_irq_save(flags);
	local_irq_save(flags);


	if (port->flags & ASYNC_INITIALIZED) {
	if (tty_port_initialized(port)) {
		free_page(page);
		free_page(page);
		goto errout;
		goto errout;
	}
	}
@@ -586,7 +586,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info)
	 */
	 */
	change_speed(tty, info, NULL);
	change_speed(tty, info, NULL);


	port->flags |= ASYNC_INITIALIZED;
	tty_port_set_initialized(port, 1);
	local_irq_restore(flags);
	local_irq_restore(flags);
	return 0;
	return 0;


@@ -604,7 +604,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info)
	unsigned long	flags;
	unsigned long	flags;
	struct serial_state *state;
	struct serial_state *state;


	if (!(info->tport.flags & ASYNC_INITIALIZED))
	if (!tty_port_initialized(&info->tport))
		return;
		return;


	state = info;
	state = info;
@@ -645,7 +645,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info)


	set_bit(TTY_IO_ERROR, &tty->flags);
	set_bit(TTY_IO_ERROR, &tty->flags);


	info->tport.flags &= ~ASYNC_INITIALIZED;
	tty_port_set_initialized(&info->tport, 0);
	local_irq_restore(flags);
	local_irq_restore(flags);
}
}


@@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
	port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
	port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;


check_and_exit:
check_and_exit:
	if (port->flags & ASYNC_INITIALIZED) {
	if (tty_port_initialized(port)) {
		if (change_spd) {
		if (change_spd) {
			if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
			if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
				tty->alt_speed = 57600;
				tty->alt_speed = 57600;
@@ -1390,7 +1390,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
	 * line status register.
	 * line status register.
	 */
	 */
	state->read_status_mask &= ~UART_LSR_DR;
	state->read_status_mask &= ~UART_LSR_DR;
	if (port->flags & ASYNC_INITIALIZED) {
	if (tty_port_initialized(port)) {
	        /* disable receive interrupts */
	        /* disable receive interrupts */
	        custom.intena = IF_RBF;
	        custom.intena = IF_RBF;
		mb();
		mb();
@@ -1538,7 +1538,7 @@ static inline void line_info(struct seq_file *m, int line,


	local_irq_save(flags);
	local_irq_save(flags);
	status = ciab.pra;
	status = ciab.pra;
	control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status;
	control = tty_port_initialized(&state->tport) ? state->MCR : status;
	local_irq_restore(flags);
	local_irq_restore(flags);


	stat_buf[0] = 0;
	stat_buf[0] = 0;
Loading