aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:54:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:47 -0400
commitf34d7a5b7010b82fe97da95496b9971435530062 (patch)
tree87e2abec1e33ed4fe5e63ee2fd000bc2ad745e57 /drivers/serial
parent251b8dd7eee30fda089a1dc088abf4fc9a0dee9c (diff)
tty: The big operations rework
- Operations are now a shared const function block as with most other Linux objects - Introduce wrappers for some optional functions to get consistent behaviour - Wrap put_char which used to be patched by the tty layer - Document which functions are needed/optional - Make put_char report success/fail - Cache the driver->ops pointer in the tty as tty->ops - Remove various surplus lock calls we no longer need - Remove proc_write method as noted by Alexey Dobriyan - Introduce some missing sanity checks where certain driver/ldisc combinations would oops as they didn't check needed methods were present [akpm@linux-foundation.org: fix fs/compat_ioctl.c build] [akpm@linux-foundation.org: fix isicom] [akpm@linux-foundation.org: fix arch/ia64/hp/sim/simserial.c build] [akpm@linux-foundation.org: fix kgdb] Signed-off-by: Alan Cox <alan@redhat.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/kgdboc.c6
-rw-r--r--drivers/serial/serial_core.c38
2 files changed, 30 insertions, 14 deletions
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 9cf03327386a..eadc1ab6bbce 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -96,12 +96,14 @@ static void cleanup_kgdboc(void)
96 96
97static int kgdboc_get_char(void) 97static int kgdboc_get_char(void)
98{ 98{
99 return kgdb_tty_driver->poll_get_char(kgdb_tty_driver, kgdb_tty_line); 99 return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver,
100 kgdb_tty_line);
100} 101}
101 102
102static void kgdboc_put_char(u8 chr) 103static void kgdboc_put_char(u8 chr)
103{ 104{
104 kgdb_tty_driver->poll_put_char(kgdb_tty_driver, kgdb_tty_line, chr); 105 kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver,
106 kgdb_tty_line, chr);
105} 107}
106 108
107static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) 109static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 6c7a5cf76582..1e2b9d826f69 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -532,15 +532,25 @@ uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
532static int uart_write_room(struct tty_struct *tty) 532static int uart_write_room(struct tty_struct *tty)
533{ 533{
534 struct uart_state *state = tty->driver_data; 534 struct uart_state *state = tty->driver_data;
535 unsigned long flags;
536 int ret;
535 537
536 return uart_circ_chars_free(&state->info->xmit); 538 spin_lock_irqsave(&state->port->lock, flags);
539 ret = uart_circ_chars_free(&state->info->xmit);
540 spin_unlock_irqrestore(&state->port->lock, flags);
541 return ret;
537} 542}
538 543
539static int uart_chars_in_buffer(struct tty_struct *tty) 544static int uart_chars_in_buffer(struct tty_struct *tty)
540{ 545{
541 struct uart_state *state = tty->driver_data; 546 struct uart_state *state = tty->driver_data;
547 unsigned long flags;
548 int ret;
542 549
543 return uart_circ_chars_pending(&state->info->xmit); 550 spin_lock_irqsave(&state->port->lock, flags);
551 ret = uart_circ_chars_pending(&state->info->xmit);
552 spin_unlock_irqrestore(&state->port->lock, flags);
553 return ret;
544} 554}
545 555
546static void uart_flush_buffer(struct tty_struct *tty) 556static void uart_flush_buffer(struct tty_struct *tty)
@@ -622,6 +632,11 @@ static int uart_get_info(struct uart_state *state,
622 struct serial_struct tmp; 632 struct serial_struct tmp;
623 633
624 memset(&tmp, 0, sizeof(tmp)); 634 memset(&tmp, 0, sizeof(tmp));
635
636 /* Ensure the state we copy is consistent and no hardware changes
637 occur as we go */
638 mutex_lock(&state->mutex);
639
625 tmp.type = port->type; 640 tmp.type = port->type;
626 tmp.line = port->line; 641 tmp.line = port->line;
627 tmp.port = port->iobase; 642 tmp.port = port->iobase;
@@ -641,6 +656,8 @@ static int uart_get_info(struct uart_state *state,
641 tmp.iomem_reg_shift = port->regshift; 656 tmp.iomem_reg_shift = port->regshift;
642 tmp.iomem_base = (void *)(unsigned long)port->mapbase; 657 tmp.iomem_base = (void *)(unsigned long)port->mapbase;
643 658
659 mutex_unlock(&state->mutex);
660
644 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 661 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
645 return -EFAULT; 662 return -EFAULT;
646 return 0; 663 return 0;
@@ -918,14 +935,12 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
918 struct uart_state *state = tty->driver_data; 935 struct uart_state *state = tty->driver_data;
919 struct uart_port *port = state->port; 936 struct uart_port *port = state->port;
920 937
921 lock_kernel();
922 mutex_lock(&state->mutex); 938 mutex_lock(&state->mutex);
923 939
924 if (port->type != PORT_UNKNOWN) 940 if (port->type != PORT_UNKNOWN)
925 port->ops->break_ctl(port, break_state); 941 port->ops->break_ctl(port, break_state);
926 942
927 mutex_unlock(&state->mutex); 943 mutex_unlock(&state->mutex);
928 unlock_kernel();
929} 944}
930 945
931static int uart_do_autoconfig(struct uart_state *state) 946static int uart_do_autoconfig(struct uart_state *state)
@@ -1074,7 +1089,6 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
1074 int ret = -ENOIOCTLCMD; 1089 int ret = -ENOIOCTLCMD;
1075 1090
1076 1091
1077 lock_kernel();
1078 /* 1092 /*
1079 * These ioctls don't rely on the hardware to be present. 1093 * These ioctls don't rely on the hardware to be present.
1080 */ 1094 */
@@ -1144,10 +1158,9 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
1144 break; 1158 break;
1145 } 1159 }
1146 } 1160 }
1147 out_up: 1161out_up:
1148 mutex_unlock(&state->mutex); 1162 mutex_unlock(&state->mutex);
1149 out: 1163out:
1150 unlock_kernel();
1151 return ret; 1164 return ret;
1152} 1165}
1153 1166
@@ -1173,7 +1186,6 @@ static void uart_set_termios(struct tty_struct *tty,
1173 return; 1186 return;
1174 } 1187 }
1175 1188
1176 lock_kernel();
1177 uart_change_speed(state, old_termios); 1189 uart_change_speed(state, old_termios);
1178 1190
1179 /* Handle transition to B0 status */ 1191 /* Handle transition to B0 status */
@@ -1206,7 +1218,6 @@ static void uart_set_termios(struct tty_struct *tty,
1206 } 1218 }
1207 spin_unlock_irqrestore(&state->port->lock, flags); 1219 spin_unlock_irqrestore(&state->port->lock, flags);
1208 } 1220 }
1209 unlock_kernel();
1210#if 0 1221#if 0
1211 /* 1222 /*
1212 * No need to wake up processes in open wait, since they 1223 * No need to wake up processes in open wait, since they
@@ -1322,11 +1333,11 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
1322 struct uart_port *port = state->port; 1333 struct uart_port *port = state->port;
1323 unsigned long char_time, expire; 1334 unsigned long char_time, expire;
1324 1335
1325 BUG_ON(!kernel_locked());
1326
1327 if (port->type == PORT_UNKNOWN || port->fifosize == 0) 1336 if (port->type == PORT_UNKNOWN || port->fifosize == 0)
1328 return; 1337 return;
1329 1338
1339 lock_kernel();
1340
1330 /* 1341 /*
1331 * Set the check interval to be 1/5 of the estimated time to 1342 * Set the check interval to be 1/5 of the estimated time to
1332 * send a single character, and make it at least 1. The check 1343 * send a single character, and make it at least 1. The check
@@ -1372,6 +1383,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
1372 break; 1383 break;
1373 } 1384 }
1374 set_current_state(TASK_RUNNING); /* might not be needed */ 1385 set_current_state(TASK_RUNNING); /* might not be needed */
1386 unlock_kernel();
1375} 1387}
1376 1388
1377/* 1389/*
@@ -2085,7 +2097,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
2085 int ret; 2097 int ret;
2086 2098
2087 uart_change_pm(state, 0); 2099 uart_change_pm(state, 0);
2100 spin_lock_irq(&port->lock);
2088 ops->set_mctrl(port, 0); 2101 ops->set_mctrl(port, 0);
2102 spin_unlock_irq(&port->lock);
2089 ret = ops->startup(port); 2103 ret = ops->startup(port);
2090 if (ret == 0) { 2104 if (ret == 0) {
2091 uart_change_speed(state, NULL); 2105 uart_change_speed(state, NULL);