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

Commit 8dba8f94 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6:
  tty_port,usb-console: Fix usb serial console open/close regression
  tty: cpm_uart: use resource_size()
  tty_buffer: Fix distinct type warning
  hvc_console: Fix race between hvc_close and hvc_remove
  uartlite: Fix build on sparc.
  tty: Take a 256 byte padding into account when buffering below sub-page units
  Revert "tty: Add a new VT mode which is like VT_PROCESS but doesn't require a VT_RELDISP ioctl call"
parents 2eb645e7 336cee42
Loading
Loading
Loading
Loading
+21 −10
Original line number Original line Diff line number Diff line
@@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
	spin_lock_irqsave(&hp->lock, flags);
	spin_lock_irqsave(&hp->lock, flags);
	/* Check and then increment for fast path open. */
	/* Check and then increment for fast path open. */
	if (hp->count++ > 0) {
	if (hp->count++ > 0) {
		tty_kref_get(tty);
		spin_unlock_irqrestore(&hp->lock, flags);
		spin_unlock_irqrestore(&hp->lock, flags);
		hvc_kick();
		hvc_kick();
		return 0;
		return 0;
@@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)


	tty->driver_data = hp;
	tty->driver_data = hp;


	hp->tty = tty;
	hp->tty = tty_kref_get(tty);


	spin_unlock_irqrestore(&hp->lock, flags);
	spin_unlock_irqrestore(&hp->lock, flags);


@@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
		spin_lock_irqsave(&hp->lock, flags);
		spin_lock_irqsave(&hp->lock, flags);
		hp->tty = NULL;
		hp->tty = NULL;
		spin_unlock_irqrestore(&hp->lock, flags);
		spin_unlock_irqrestore(&hp->lock, flags);
		tty_kref_put(tty);
		tty->driver_data = NULL;
		tty->driver_data = NULL;
		kref_put(&hp->kref, destroy_hvc_struct);
		kref_put(&hp->kref, destroy_hvc_struct);
		printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
		printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -363,13 +365,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
		return;
		return;


	hp = tty->driver_data;
	hp = tty->driver_data;

	spin_lock_irqsave(&hp->lock, flags);
	spin_lock_irqsave(&hp->lock, flags);
	tty_kref_get(tty);


	if (--hp->count == 0) {
	if (--hp->count == 0) {
		/* We are done with the tty pointer now. */
		/* We are done with the tty pointer now. */
		hp->tty = NULL;
		hp->tty = NULL;
		spin_unlock_irqrestore(&hp->lock, flags);
		spin_unlock_irqrestore(&hp->lock, flags);


		/* Put the ref obtained in hvc_open() */
		tty_kref_put(tty);

		if (hp->ops->notifier_del)
		if (hp->ops->notifier_del)
			hp->ops->notifier_del(hp, hp->data);
			hp->ops->notifier_del(hp, hp->data);


@@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
		spin_unlock_irqrestore(&hp->lock, flags);
		spin_unlock_irqrestore(&hp->lock, flags);
	}
	}


	tty_kref_put(tty);
	kref_put(&hp->kref, destroy_hvc_struct);
	kref_put(&hp->kref, destroy_hvc_struct);
}
}


@@ -428,6 +436,7 @@ static void hvc_hangup(struct tty_struct *tty)


	while(temp_open_count) {
	while(temp_open_count) {
		--temp_open_count;
		--temp_open_count;
		tty_kref_put(tty);
		kref_put(&hp->kref, destroy_hvc_struct);
		kref_put(&hp->kref, destroy_hvc_struct);
	}
	}
}
}
@@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp)
	}
	}


	/* No tty attached, just skip */
	/* No tty attached, just skip */
	tty = hp->tty;
	tty = tty_kref_get(hp->tty);
	if (tty == NULL)
	if (tty == NULL)
		goto bail;
		goto bail;


@@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp)


		tty_flip_buffer_push(tty);
		tty_flip_buffer_push(tty);
	}
	}
	if (tty)
		tty_kref_put(tty);


	return poll_mask;
	return poll_mask;
}
}
@@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp)
	struct tty_struct *tty;
	struct tty_struct *tty;


	spin_lock_irqsave(&hp->lock, flags);
	spin_lock_irqsave(&hp->lock, flags);
	tty = hp->tty;
	tty = tty_kref_get(hp->tty);


	if (hp->index < MAX_NR_HVC_CONSOLES)
	if (hp->index < MAX_NR_HVC_CONSOLES)
		vtermnos[hp->index] = -1;
		vtermnos[hp->index] = -1;
@@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp)
	/*
	/*
	 * We 'put' the instance that was grabbed when the kref instance
	 * We 'put' the instance that was grabbed when the kref instance
	 * was initialized using kref_init().  Let the last holder of this
	 * was initialized using kref_init().  Let the last holder of this
	 * kref cause it to be removed, which will probably be the tty_hangup
	 * kref cause it to be removed, which will probably be the tty_vhangup
	 * below.
	 * below.
	 */
	 */
	kref_put(&hp->kref, destroy_hvc_struct);
	kref_put(&hp->kref, destroy_hvc_struct);


	/*
	/*
	 * This function call will auto chain call hvc_hangup.  The tty should
	 * This function call will auto chain call hvc_hangup.
	 * always be valid at this time unless a simultaneous tty close already
	 * cleaned up the hvc_struct.
	 */
	 */
	if (tty)
	if (tty) {
		tty_hangup(tty);
		tty_vhangup(tty);
		tty_kref_put(tty);
	}
	return 0;
	return 0;
}
}
EXPORT_SYMBOL_GPL(hvc_remove);
EXPORT_SYMBOL_GPL(hvc_remove);
+2 −2
Original line number Original line Diff line number Diff line
@@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
{
{
	int copied = 0;
	int copied = 0;
	do {
	do {
		int goal = min(size - copied, TTY_BUFFER_PAGE);
		int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
		int space = tty_buffer_request_room(tty, goal);
		int space = tty_buffer_request_room(tty, goal);
		struct tty_buffer *tb = tty->buf.tail;
		struct tty_buffer *tb = tty->buf.tail;
		/* If there is no space then tb may be NULL */
		/* If there is no space then tb may be NULL */
@@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
{
{
	int copied = 0;
	int copied = 0;
	do {
	do {
		int goal = min(size - copied, TTY_BUFFER_PAGE);
		int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
		int space = tty_buffer_request_room(tty, goal);
		int space = tty_buffer_request_room(tty, goal);
		struct tty_buffer *tb = tty->buf.tail;
		struct tty_buffer *tb = tty->buf.tail;
		/* If there is no space then tb may be NULL */
		/* If there is no space then tb may be NULL */
+1 −1
Original line number Original line Diff line number Diff line
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set);
static void tty_port_shutdown(struct tty_port *port)
static void tty_port_shutdown(struct tty_port *port)
{
{
	mutex_lock(&port->mutex);
	mutex_lock(&port->mutex);
	if (port->ops->shutdown &&
	if (port->ops->shutdown && !port->console &&
		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
			port->ops->shutdown(port);
			port->ops->shutdown(port);
	mutex_unlock(&port->mutex);
	mutex_unlock(&port->mutex);
+19 −20
Original line number Original line Diff line number Diff line
@@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
			ret = -EFAULT;
			ret = -EFAULT;
			goto out;
			goto out;
		}
		}
		if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) {
		if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
			ret = -EINVAL;
			ret = -EINVAL;
			goto out;
			goto out;
		}
		}
@@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc)
	 * telling it that it has acquired. Also check if it has died and
	 * telling it that it has acquired. Also check if it has died and
	 * clean up (similar to logic employed in change_console())
	 * clean up (similar to logic employed in change_console())
	 */
	 */
	if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
	if (vc->vt_mode.mode == VT_PROCESS) {
		/*
		/*
		 * Send the signal as privileged - kill_pid() will
		 * Send the signal as privileged - kill_pid() will
		 * tell us if the process has gone or something else
		 * tell us if the process has gone or something else
@@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc)
	 * vt to auto control.
	 * vt to auto control.
	 */
	 */
	vc = vc_cons[fg_console].d;
	vc = vc_cons[fg_console].d;
	if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
	if (vc->vt_mode.mode == VT_PROCESS) {
		/*
		/*
		 * Send the signal as privileged - kill_pid() will
		 * Send the signal as privileged - kill_pid() will
		 * tell us if the process has gone or something else
		 * tell us if the process has gone or something else
@@ -1693,14 +1693,14 @@ void change_console(struct vc_data *new_vc)
		 */
		 */
		vc->vt_newvt = new_vc->vc_num;
		vc->vt_newvt = new_vc->vc_num;
		if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
		if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
			if(vc->vt_mode.mode == VT_PROCESS)
			/*
			/*
			 * It worked. Mark the vt to switch to and
			 * It worked. Mark the vt to switch to and
			 * return. The process needs to send us a
			 * return. The process needs to send us a
			 * VT_RELDISP ioctl to complete the switch.
			 * VT_RELDISP ioctl to complete the switch.
			 */
			 */
			return;
			return;
		} else {
		}

		/*
		/*
		 * The controlling process has died, so we revert back to
		 * The controlling process has died, so we revert back to
		 * normal operation. In this case, we'll also change back
		 * normal operation. In this case, we'll also change back
@@ -1711,10 +1711,9 @@ void change_console(struct vc_data *new_vc)
		 * to account for and tracking tty count may be undesirable.
		 * to account for and tracking tty count may be undesirable.
		 */
		 */
		reset_vc(vc);
		reset_vc(vc);
		}


		/*
		/*
		 * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch...
		 * Fall through to normal (VT_AUTO) handling of the switch...
		 */
		 */
	}
	}


+2 −2
Original line number Original line Diff line number Diff line
@@ -61,7 +61,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
	void __iomem *pram;
	void __iomem *pram;
	unsigned long offset;
	unsigned long offset;
	struct resource res;
	struct resource res;
	unsigned long len;
	resource_size_t len;


	/* Don't remap parameter RAM if it has already been initialized
	/* Don't remap parameter RAM if it has already been initialized
	 * during console setup.
	 * during console setup.
@@ -74,7 +74,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
	if (of_address_to_resource(np, 1, &res))
	if (of_address_to_resource(np, 1, &res))
		return NULL;
		return NULL;


	len = 1 + res.end - res.start;
	len = resource_size(&res);
	pram = ioremap(res.start, len);
	pram = ioremap(res.start, len);
	if (!pram)
	if (!pram)
		return NULL;
		return NULL;
Loading