diff options
| -rw-r--r-- | drivers/char/hvc_console.c | 31 | ||||
| -rw-r--r-- | drivers/char/tty_buffer.c | 4 | ||||
| -rw-r--r-- | drivers/char/tty_port.c | 2 | ||||
| -rw-r--r-- | drivers/char/vt_ioctl.c | 39 | ||||
| -rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_cpm2.c | 4 | ||||
| -rw-r--r-- | drivers/usb/serial/console.c | 1 | ||||
| -rw-r--r-- | include/linux/tty.h | 10 | ||||
| -rw-r--r-- | include/linux/vt.h | 3 | 
8 files changed, 53 insertions, 41 deletions
| diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 465185fc0f52..ba55bba151b9 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)  	spin_lock_irqsave(&hp->lock, flags);  	/* Check and then increment for fast path open. */  	if (hp->count++ > 0) { +		tty_kref_get(tty);  		spin_unlock_irqrestore(&hp->lock, flags);  		hvc_kick();  		return 0; @@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)  	tty->driver_data = hp; -	hp->tty = tty; +	hp->tty = tty_kref_get(tty);  	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);  		hp->tty = NULL;  		spin_unlock_irqrestore(&hp->lock, flags); +		tty_kref_put(tty);  		tty->driver_data = NULL;  		kref_put(&hp->kref, destroy_hvc_struct);  		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;  	hp = tty->driver_data; +  	spin_lock_irqsave(&hp->lock, flags); +	tty_kref_get(tty);  	if (--hp->count == 0) {  		/* We are done with the tty pointer now. */  		hp->tty = NULL;  		spin_unlock_irqrestore(&hp->lock, flags); +		/* Put the ref obtained in hvc_open() */ +		tty_kref_put(tty); +  		if (hp->ops->notifier_del)  			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);  	} +	tty_kref_put(tty);  	kref_put(&hp->kref, destroy_hvc_struct);  } @@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty)  	spin_unlock_irqrestore(&hp->lock, flags);  	if (hp->ops->notifier_hangup) -			hp->ops->notifier_hangup(hp, hp->data); +		hp->ops->notifier_hangup(hp, hp->data);  	while(temp_open_count) {  		--temp_open_count; +		tty_kref_put(tty);  		kref_put(&hp->kref, destroy_hvc_struct);  	}  } @@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp)  	}  	/* No tty attached, just skip */ -	tty = hp->tty; +	tty = tty_kref_get(hp->tty);  	if (tty == NULL)  		goto bail; @@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp)  		tty_flip_buffer_push(tty);  	} +	if (tty) +		tty_kref_put(tty);  	return poll_mask;  } @@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp)  	struct tty_struct *tty;  	spin_lock_irqsave(&hp->lock, flags); -	tty = hp->tty; +	tty = tty_kref_get(hp->tty);  	if (hp->index < MAX_NR_HVC_CONSOLES)  		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  	 * 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.  	 */  	kref_put(&hp->kref, destroy_hvc_struct);  	/* -	 * This function call will auto chain call hvc_hangup.  The tty should -	 * always be valid at this time unless a simultaneous tty close already -	 * cleaned up the hvc_struct. +	 * This function call will auto chain call hvc_hangup.  	 */ -	if (tty) -		tty_hangup(tty); +	if (tty) { +		tty_vhangup(tty); +		tty_kref_put(tty); +	}  	return 0;  }  EXPORT_SYMBOL_GPL(hvc_remove); diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index af8d97715728..7ee52164d474 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c @@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,  {  	int copied = 0;  	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);  		struct tty_buffer *tb = tty->buf.tail;  		/* 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;  	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);  		struct tty_buffer *tb = tty->buf.tail;  		/* If there is no space then tb may be NULL */ diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index be492dd66437..a3bd1d0b66cf 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c @@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set);  static void tty_port_shutdown(struct tty_port *port)  {  	mutex_lock(&port->mutex); -	if (port->ops->shutdown && +	if (port->ops->shutdown && !port->console &&  		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))  			port->ops->shutdown(port);  	mutex_unlock(&port->mutex); diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 87778dcf8727..6aa10284104a 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,  			ret = -EFAULT;  			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;  			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  	 * 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  		 * 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.  	 */  	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  		 * tell us if the process has gone or something else @@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc)  		 */  		vc->vt_newvt = new_vc->vc_num;  		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 -				 * return. The process needs to send us a -				 * VT_RELDISP ioctl to complete the switch. -				 */ -				return; -		} else {  			/* -			 * The controlling process has died, so we revert back to -			 * normal operation. In this case, we'll also change back -			 * to KD_TEXT mode. I'm not sure if this is strictly correct -			 * but it saves the agony when the X server dies and the screen -			 * remains blanked due to KD_GRAPHICS! It would be nice to do -			 * this outside of VT_PROCESS but there is no single process -			 * to account for and tracking tty count may be undesirable. +			 * It worked. Mark the vt to switch to and +			 * return. The process needs to send us a +			 * VT_RELDISP ioctl to complete the switch.  			 */ -			reset_vc(vc); +			return;  		}  		/* -		 * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch... +		 * The controlling process has died, so we revert back to +		 * normal operation. In this case, we'll also change back +		 * to KD_TEXT mode. I'm not sure if this is strictly correct +		 * but it saves the agony when the X server dies and the screen +		 * remains blanked due to KD_GRAPHICS! It would be nice to do +		 * this outside of VT_PROCESS but there is no single process +		 * to account for and tracking tty count may be undesirable. +		 */ +		reset_vc(vc); + +		/* +		 * Fall through to normal (VT_AUTO) handling of the switch...  		 */  	} diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index a9802e76b5fa..722eac18f382 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -61,7 +61,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,  	void __iomem *pram;  	unsigned long offset;  	struct resource res; -	unsigned long len; +	resource_size_t len;  	/* Don't remap parameter RAM if it has already been initialized  	 * 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))  		return NULL; -	len = 1 + res.end - res.start; +	len = resource_size(&res);  	pram = ioremap(res.start, len);  	if (!pram)  		return NULL; diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index b22ac3258523..f347da2ef00a 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -181,6 +181,7 @@ static int usb_console_setup(struct console *co, char *options)  	/* The console is special in terms of closing the device so  	 * indicate this port is now acting as a system console. */  	port->console = 1; +	port->port.console = 1;  	mutex_unlock(&serial->disc_mutex);  	return retval; diff --git a/include/linux/tty.h b/include/linux/tty.h index 568369a86306..4409967db0c4 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -70,12 +70,13 @@ struct tty_buffer {  /*   * We default to dicing tty buffer allocations to this many characters - * in order to avoid multiple page allocations. We assume tty_buffer itself - * is under 256 bytes. See tty_buffer_find for the allocation logic this - * must match + * in order to avoid multiple page allocations. We know the size of + * tty_buffer itself but it must also be taken into account that the + * the buffer is 256 byte aligned. See tty_buffer_find for the allocation + * logic this must match   */ -#define TTY_BUFFER_PAGE		((PAGE_SIZE  - 256) / 2) +#define TTY_BUFFER_PAGE	(((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)  struct tty_bufhead { @@ -223,6 +224,7 @@ struct tty_port {  	wait_queue_head_t	close_wait;	/* Close waiters */  	wait_queue_head_t	delta_msr_wait;	/* Modem status change */  	unsigned long		flags;		/* TTY flags ASY_*/ +	unsigned char		console:1;	/* port is a console */  	struct mutex		mutex;		/* Locking */  	struct mutex		buf_mutex;	/* Buffer alloc lock */  	unsigned char		*xmit_buf;	/* Optional buffer */ diff --git a/include/linux/vt.h b/include/linux/vt.h index 778b7b2a47d4..d5dd0bc408fd 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h @@ -27,7 +27,7 @@ struct vt_mode {  #define VT_SETMODE	0x5602	/* set mode of active vt */  #define		VT_AUTO		0x00	/* auto vt switching */  #define		VT_PROCESS	0x01	/* process controls switching */ -#define		VT_PROCESS_AUTO 0x02	/* process is notified of switching */ +#define		VT_ACKACQ	0x02	/* acknowledge switch */  struct vt_stat {  	unsigned short v_active;	/* active vt */ @@ -38,7 +38,6 @@ struct vt_stat {  #define VT_SENDSIG	0x5604	/* signal to send to bitmask of vts */  #define VT_RELDISP	0x5605	/* release display */ -#define		VT_ACKACQ	0x02	/* acknowledge switch */  #define VT_ACTIVATE	0x5606	/* make vt active */  #define VT_WAITACTIVE	0x5607	/* wait for vt active */ | 
