aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/hvc_console.c31
-rw-r--r--drivers/char/tty_buffer.c4
-rw-r--r--drivers/char/tty_port.c2
-rw-r--r--drivers/char/vt_ioctl.c39
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c4
-rw-r--r--drivers/usb/serial/console.c1
-rw-r--r--include/linux/tty.h10
-rw-r--r--include/linux/vt.h3
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)
312 spin_lock_irqsave(&hp->lock, flags); 312 spin_lock_irqsave(&hp->lock, flags);
313 /* Check and then increment for fast path open. */ 313 /* Check and then increment for fast path open. */
314 if (hp->count++ > 0) { 314 if (hp->count++ > 0) {
315 tty_kref_get(tty);
315 spin_unlock_irqrestore(&hp->lock, flags); 316 spin_unlock_irqrestore(&hp->lock, flags);
316 hvc_kick(); 317 hvc_kick();
317 return 0; 318 return 0;
@@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
319 320
320 tty->driver_data = hp; 321 tty->driver_data = hp;
321 322
322 hp->tty = tty; 323 hp->tty = tty_kref_get(tty);
323 324
324 spin_unlock_irqrestore(&hp->lock, flags); 325 spin_unlock_irqrestore(&hp->lock, flags);
325 326
@@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
336 spin_lock_irqsave(&hp->lock, flags); 337 spin_lock_irqsave(&hp->lock, flags);
337 hp->tty = NULL; 338 hp->tty = NULL;
338 spin_unlock_irqrestore(&hp->lock, flags); 339 spin_unlock_irqrestore(&hp->lock, flags);
340 tty_kref_put(tty);
339 tty->driver_data = NULL; 341 tty->driver_data = NULL;
340 kref_put(&hp->kref, destroy_hvc_struct); 342 kref_put(&hp->kref, destroy_hvc_struct);
341 printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); 343 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)
363 return; 365 return;
364 366
365 hp = tty->driver_data; 367 hp = tty->driver_data;
368
366 spin_lock_irqsave(&hp->lock, flags); 369 spin_lock_irqsave(&hp->lock, flags);
370 tty_kref_get(tty);
367 371
368 if (--hp->count == 0) { 372 if (--hp->count == 0) {
369 /* We are done with the tty pointer now. */ 373 /* We are done with the tty pointer now. */
370 hp->tty = NULL; 374 hp->tty = NULL;
371 spin_unlock_irqrestore(&hp->lock, flags); 375 spin_unlock_irqrestore(&hp->lock, flags);
372 376
377 /* Put the ref obtained in hvc_open() */
378 tty_kref_put(tty);
379
373 if (hp->ops->notifier_del) 380 if (hp->ops->notifier_del)
374 hp->ops->notifier_del(hp, hp->data); 381 hp->ops->notifier_del(hp, hp->data);
375 382
@@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
389 spin_unlock_irqrestore(&hp->lock, flags); 396 spin_unlock_irqrestore(&hp->lock, flags);
390 } 397 }
391 398
399 tty_kref_put(tty);
392 kref_put(&hp->kref, destroy_hvc_struct); 400 kref_put(&hp->kref, destroy_hvc_struct);
393} 401}
394 402
@@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty)
424 spin_unlock_irqrestore(&hp->lock, flags); 432 spin_unlock_irqrestore(&hp->lock, flags);
425 433
426 if (hp->ops->notifier_hangup) 434 if (hp->ops->notifier_hangup)
427 hp->ops->notifier_hangup(hp, hp->data); 435 hp->ops->notifier_hangup(hp, hp->data);
428 436
429 while(temp_open_count) { 437 while(temp_open_count) {
430 --temp_open_count; 438 --temp_open_count;
439 tty_kref_put(tty);
431 kref_put(&hp->kref, destroy_hvc_struct); 440 kref_put(&hp->kref, destroy_hvc_struct);
432 } 441 }
433} 442}
@@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp)
592 } 601 }
593 602
594 /* No tty attached, just skip */ 603 /* No tty attached, just skip */
595 tty = hp->tty; 604 tty = tty_kref_get(hp->tty);
596 if (tty == NULL) 605 if (tty == NULL)
597 goto bail; 606 goto bail;
598 607
@@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp)
672 681
673 tty_flip_buffer_push(tty); 682 tty_flip_buffer_push(tty);
674 } 683 }
684 if (tty)
685 tty_kref_put(tty);
675 686
676 return poll_mask; 687 return poll_mask;
677} 688}
@@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp)
807 struct tty_struct *tty; 818 struct tty_struct *tty;
808 819
809 spin_lock_irqsave(&hp->lock, flags); 820 spin_lock_irqsave(&hp->lock, flags);
810 tty = hp->tty; 821 tty = tty_kref_get(hp->tty);
811 822
812 if (hp->index < MAX_NR_HVC_CONSOLES) 823 if (hp->index < MAX_NR_HVC_CONSOLES)
813 vtermnos[hp->index] = -1; 824 vtermnos[hp->index] = -1;
@@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp)
819 /* 830 /*
820 * We 'put' the instance that was grabbed when the kref instance 831 * We 'put' the instance that was grabbed when the kref instance
821 * was initialized using kref_init(). Let the last holder of this 832 * was initialized using kref_init(). Let the last holder of this
822 * kref cause it to be removed, which will probably be the tty_hangup 833 * kref cause it to be removed, which will probably be the tty_vhangup
823 * below. 834 * below.
824 */ 835 */
825 kref_put(&hp->kref, destroy_hvc_struct); 836 kref_put(&hp->kref, destroy_hvc_struct);
826 837
827 /* 838 /*
828 * This function call will auto chain call hvc_hangup. The tty should 839 * This function call will auto chain call hvc_hangup.
829 * always be valid at this time unless a simultaneous tty close already
830 * cleaned up the hvc_struct.
831 */ 840 */
832 if (tty) 841 if (tty) {
833 tty_hangup(tty); 842 tty_vhangup(tty);
843 tty_kref_put(tty);
844 }
834 return 0; 845 return 0;
835} 846}
836EXPORT_SYMBOL_GPL(hvc_remove); 847EXPORT_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,
248{ 248{
249 int copied = 0; 249 int copied = 0;
250 do { 250 do {
251 int goal = min(size - copied, TTY_BUFFER_PAGE); 251 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
252 int space = tty_buffer_request_room(tty, goal); 252 int space = tty_buffer_request_room(tty, goal);
253 struct tty_buffer *tb = tty->buf.tail; 253 struct tty_buffer *tb = tty->buf.tail;
254 /* If there is no space then tb may be NULL */ 254 /* If there is no space then tb may be NULL */
@@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
285{ 285{
286 int copied = 0; 286 int copied = 0;
287 do { 287 do {
288 int goal = min(size - copied, TTY_BUFFER_PAGE); 288 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
289 int space = tty_buffer_request_room(tty, goal); 289 int space = tty_buffer_request_room(tty, goal);
290 struct tty_buffer *tb = tty->buf.tail; 290 struct tty_buffer *tb = tty->buf.tail;
291 /* If there is no space then tb may be NULL */ 291 /* 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);
119static void tty_port_shutdown(struct tty_port *port) 119static void tty_port_shutdown(struct tty_port *port)
120{ 120{
121 mutex_lock(&port->mutex); 121 mutex_lock(&port->mutex);
122 if (port->ops->shutdown && 122 if (port->ops->shutdown && !port->console &&
123 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) 123 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
124 port->ops->shutdown(port); 124 port->ops->shutdown(port);
125 mutex_unlock(&port->mutex); 125 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,
888 ret = -EFAULT; 888 ret = -EFAULT;
889 goto out; 889 goto out;
890 } 890 }
891 if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) { 891 if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
892 ret = -EINVAL; 892 ret = -EINVAL;
893 goto out; 893 goto out;
894 } 894 }
@@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc)
1622 * telling it that it has acquired. Also check if it has died and 1622 * telling it that it has acquired. Also check if it has died and
1623 * clean up (similar to logic employed in change_console()) 1623 * clean up (similar to logic employed in change_console())
1624 */ 1624 */
1625 if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { 1625 if (vc->vt_mode.mode == VT_PROCESS) {
1626 /* 1626 /*
1627 * Send the signal as privileged - kill_pid() will 1627 * Send the signal as privileged - kill_pid() will
1628 * tell us if the process has gone or something else 1628 * tell us if the process has gone or something else
@@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc)
1682 * vt to auto control. 1682 * vt to auto control.
1683 */ 1683 */
1684 vc = vc_cons[fg_console].d; 1684 vc = vc_cons[fg_console].d;
1685 if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { 1685 if (vc->vt_mode.mode == VT_PROCESS) {
1686 /* 1686 /*
1687 * Send the signal as privileged - kill_pid() will 1687 * Send the signal as privileged - kill_pid() will
1688 * tell us if the process has gone or something else 1688 * tell us if the process has gone or something else
@@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc)
1693 */ 1693 */
1694 vc->vt_newvt = new_vc->vc_num; 1694 vc->vt_newvt = new_vc->vc_num;
1695 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { 1695 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
1696 if(vc->vt_mode.mode == VT_PROCESS)
1697 /*
1698 * It worked. Mark the vt to switch to and
1699 * return. The process needs to send us a
1700 * VT_RELDISP ioctl to complete the switch.
1701 */
1702 return;
1703 } else {
1704 /* 1696 /*
1705 * The controlling process has died, so we revert back to 1697 * It worked. Mark the vt to switch to and
1706 * normal operation. In this case, we'll also change back 1698 * return. The process needs to send us a
1707 * to KD_TEXT mode. I'm not sure if this is strictly correct 1699 * VT_RELDISP ioctl to complete the switch.
1708 * but it saves the agony when the X server dies and the screen
1709 * remains blanked due to KD_GRAPHICS! It would be nice to do
1710 * this outside of VT_PROCESS but there is no single process
1711 * to account for and tracking tty count may be undesirable.
1712 */ 1700 */
1713 reset_vc(vc); 1701 return;
1714 } 1702 }
1715 1703
1716 /* 1704 /*
1717 * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch... 1705 * The controlling process has died, so we revert back to
1706 * normal operation. In this case, we'll also change back
1707 * to KD_TEXT mode. I'm not sure if this is strictly correct
1708 * but it saves the agony when the X server dies and the screen
1709 * remains blanked due to KD_GRAPHICS! It would be nice to do
1710 * this outside of VT_PROCESS but there is no single process
1711 * to account for and tracking tty count may be undesirable.
1712 */
1713 reset_vc(vc);
1714
1715 /*
1716 * Fall through to normal (VT_AUTO) handling of the switch...
1718 */ 1717 */
1719 } 1718 }
1720 1719
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,
61 void __iomem *pram; 61 void __iomem *pram;
62 unsigned long offset; 62 unsigned long offset;
63 struct resource res; 63 struct resource res;
64 unsigned long len; 64 resource_size_t len;
65 65
66 /* Don't remap parameter RAM if it has already been initialized 66 /* Don't remap parameter RAM if it has already been initialized
67 * during console setup. 67 * during console setup.
@@ -74,7 +74,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
74 if (of_address_to_resource(np, 1, &res)) 74 if (of_address_to_resource(np, 1, &res))
75 return NULL; 75 return NULL;
76 76
77 len = 1 + res.end - res.start; 77 len = resource_size(&res);
78 pram = ioremap(res.start, len); 78 pram = ioremap(res.start, len);
79 if (!pram) 79 if (!pram)
80 return NULL; 80 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)
181 /* The console is special in terms of closing the device so 181 /* The console is special in terms of closing the device so
182 * indicate this port is now acting as a system console. */ 182 * indicate this port is now acting as a system console. */
183 port->console = 1; 183 port->console = 1;
184 port->port.console = 1;
184 185
185 mutex_unlock(&serial->disc_mutex); 186 mutex_unlock(&serial->disc_mutex);
186 return retval; 187 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 {
70 70
71/* 71/*
72 * We default to dicing tty buffer allocations to this many characters 72 * We default to dicing tty buffer allocations to this many characters
73 * in order to avoid multiple page allocations. We assume tty_buffer itself 73 * in order to avoid multiple page allocations. We know the size of
74 * is under 256 bytes. See tty_buffer_find for the allocation logic this 74 * tty_buffer itself but it must also be taken into account that the
75 * must match 75 * the buffer is 256 byte aligned. See tty_buffer_find for the allocation
76 * logic this must match
76 */ 77 */
77 78
78#define TTY_BUFFER_PAGE ((PAGE_SIZE - 256) / 2) 79#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
79 80
80 81
81struct tty_bufhead { 82struct tty_bufhead {
@@ -223,6 +224,7 @@ struct tty_port {
223 wait_queue_head_t close_wait; /* Close waiters */ 224 wait_queue_head_t close_wait; /* Close waiters */
224 wait_queue_head_t delta_msr_wait; /* Modem status change */ 225 wait_queue_head_t delta_msr_wait; /* Modem status change */
225 unsigned long flags; /* TTY flags ASY_*/ 226 unsigned long flags; /* TTY flags ASY_*/
227 unsigned char console:1; /* port is a console */
226 struct mutex mutex; /* Locking */ 228 struct mutex mutex; /* Locking */
227 struct mutex buf_mutex; /* Buffer alloc lock */ 229 struct mutex buf_mutex; /* Buffer alloc lock */
228 unsigned char *xmit_buf; /* Optional buffer */ 230 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 {
27#define VT_SETMODE 0x5602 /* set mode of active vt */ 27#define VT_SETMODE 0x5602 /* set mode of active vt */
28#define VT_AUTO 0x00 /* auto vt switching */ 28#define VT_AUTO 0x00 /* auto vt switching */
29#define VT_PROCESS 0x01 /* process controls switching */ 29#define VT_PROCESS 0x01 /* process controls switching */
30#define VT_PROCESS_AUTO 0x02 /* process is notified of switching */ 30#define VT_ACKACQ 0x02 /* acknowledge switch */
31 31
32struct vt_stat { 32struct vt_stat {
33 unsigned short v_active; /* active vt */ 33 unsigned short v_active; /* active vt */
@@ -38,7 +38,6 @@ struct vt_stat {
38#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */ 38#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
39 39
40#define VT_RELDISP 0x5605 /* release display */ 40#define VT_RELDISP 0x5605 /* release display */
41#define VT_ACKACQ 0x02 /* acknowledge switch */
42 41
43#define VT_ACTIVATE 0x5606 /* make vt active */ 42#define VT_ACTIVATE 0x5606 /* make vt active */
44#define VT_WAITACTIVE 0x5607 /* wait for vt active */ 43#define VT_WAITACTIVE 0x5607 /* wait for vt active */