aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-20 01:16:58 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-20 01:16:58 -0500
commit497992917edf03994088ec8757b8262e1d9f568a (patch)
tree7e82975f98d3d3c9f80e10c981601db23eef5bd1 /drivers/serial
parent7e732bfc5570b8f9bb5f155cf36e94b2e7d6bf6a (diff)
parent386d1d50c8eef254653b1015fde06622ef38ba76 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/sn_console.c129
1 files changed, 58 insertions, 71 deletions
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 5468e5a767e2..43e67d6c29d4 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -6,7 +6,7 @@
6 * driver for that. 6 * driver for that.
7 * 7 *
8 * 8 *
9 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. 9 * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved.
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify it 11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of version 2 of the GNU General Public License 12 * under the terms of version 2 of the GNU General Public License
@@ -829,8 +829,8 @@ static int __init sn_sal_module_init(void)
829 misc.name = DEVICE_NAME_DYNAMIC; 829 misc.name = DEVICE_NAME_DYNAMIC;
830 retval = misc_register(&misc); 830 retval = misc_register(&misc);
831 if (retval != 0) { 831 if (retval != 0) {
832 printk 832 printk(KERN_WARNING "Failed to register console "
833 ("Failed to register console device using misc_register.\n"); 833 "device using misc_register.\n");
834 return -ENODEV; 834 return -ENODEV;
835 } 835 }
836 sal_console_uart.major = MISC_MAJOR; 836 sal_console_uart.major = MISC_MAJOR;
@@ -942,88 +942,75 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
942{ 942{
943 unsigned long flags = 0; 943 unsigned long flags = 0;
944 struct sn_cons_port *port = &sal_console_port; 944 struct sn_cons_port *port = &sal_console_port;
945#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
946 static int stole_lock = 0; 945 static int stole_lock = 0;
947#endif
948 946
949 BUG_ON(!port->sc_is_asynch); 947 BUG_ON(!port->sc_is_asynch);
950 948
951 /* We can't look at the xmit buffer if we're not registered with serial core 949 /* We can't look at the xmit buffer if we're not registered with serial core
952 * yet. So only do the fancy recovery after registering 950 * yet. So only do the fancy recovery after registering
953 */ 951 */
954 if (port->sc_port.info) { 952 if (!port->sc_port.info) {
955 953 /* Not yet registered with serial core - simple case */
956 /* somebody really wants this output, might be an 954 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
957 * oops, kdb, panic, etc. make sure they get it. */ 955 return;
958#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) 956 }
959 if (spin_is_locked(&port->sc_port.lock)) {
960 int lhead = port->sc_port.info->xmit.head;
961 int ltail = port->sc_port.info->xmit.tail;
962 int counter, got_lock = 0;
963 957
964 /* 958 /* somebody really wants this output, might be an
965 * We attempt to determine if someone has died with the 959 * oops, kdb, panic, etc. make sure they get it. */
966 * lock. We wait ~20 secs after the head and tail ptrs 960 if (spin_is_locked(&port->sc_port.lock)) {
967 * stop moving and assume the lock holder is not functional 961 int lhead = port->sc_port.info->xmit.head;
968 * and plow ahead. If the lock is freed within the time out 962 int ltail = port->sc_port.info->xmit.tail;
969 * period we re-get the lock and go ahead normally. We also 963 int counter, got_lock = 0;
970 * remember if we have plowed ahead so that we don't have 964
971 * to wait out the time out period again - the asumption 965 /*
972 * is that we will time out again. 966 * We attempt to determine if someone has died with the
973 */ 967 * lock. We wait ~20 secs after the head and tail ptrs
968 * stop moving and assume the lock holder is not functional
969 * and plow ahead. If the lock is freed within the time out
970 * period we re-get the lock and go ahead normally. We also
971 * remember if we have plowed ahead so that we don't have
972 * to wait out the time out period again - the asumption
973 * is that we will time out again.
974 */
974 975
975 for (counter = 0; counter < 150; mdelay(125), counter++) { 976 for (counter = 0; counter < 150; mdelay(125), counter++) {
976 if (!spin_is_locked(&port->sc_port.lock) 977 if (!spin_is_locked(&port->sc_port.lock)
977 || stole_lock) { 978 || stole_lock) {
978 if (!stole_lock) { 979 if (!stole_lock) {
979 spin_lock_irqsave(&port-> 980 spin_lock_irqsave(&port->sc_port.lock,
980 sc_port.lock, 981 flags);
981 flags); 982 got_lock = 1;
982 got_lock = 1;
983 }
984 break;
985 } else {
986 /* still locked */
987 if ((lhead !=
988 port->sc_port.info->xmit.head)
989 || (ltail !=
990 port->sc_port.info->xmit.
991 tail)) {
992 lhead =
993 port->sc_port.info->xmit.
994 head;
995 ltail =
996 port->sc_port.info->xmit.
997 tail;
998 counter = 0;
999 }
1000 } 983 }
1001 } 984 break;
1002 /* flush anything in the serial core xmit buffer, raw */
1003 sn_transmit_chars(port, 1);
1004 if (got_lock) {
1005 spin_unlock_irqrestore(&port->sc_port.lock,
1006 flags);
1007 stole_lock = 0;
1008 } else { 985 } else {
1009 /* fell thru */ 986 /* still locked */
1010 stole_lock = 1; 987 if ((lhead != port->sc_port.info->xmit.head)
988 || (ltail !=
989 port->sc_port.info->xmit.tail)) {
990 lhead =
991 port->sc_port.info->xmit.head;
992 ltail =
993 port->sc_port.info->xmit.tail;
994 counter = 0;
995 }
1011 } 996 }
1012 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); 997 }
1013 } else { 998 /* flush anything in the serial core xmit buffer, raw */
1014 stole_lock = 0; 999 sn_transmit_chars(port, 1);
1015#endif 1000 if (got_lock) {
1016 spin_lock_irqsave(&port->sc_port.lock, flags);
1017 sn_transmit_chars(port, 1);
1018 spin_unlock_irqrestore(&port->sc_port.lock, flags); 1001 spin_unlock_irqrestore(&port->sc_port.lock, flags);
1019 1002 stole_lock = 0;
1020 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); 1003 } else {
1021#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) 1004 /* fell thru */
1005 stole_lock = 1;
1022 } 1006 }
1023#endif 1007 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
1024 } 1008 } else {
1025 else { 1009 stole_lock = 0;
1026 /* Not yet registered with serial core - simple case */ 1010 spin_lock_irqsave(&port->sc_port.lock, flags);
1011 sn_transmit_chars(port, 1);
1012 spin_unlock_irqrestore(&port->sc_port.lock, flags);
1013
1027 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); 1014 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
1028 } 1015 }
1029} 1016}