diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-04-30 03:53:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:45 -0400 |
commit | 978e595f88a1fba5869aa42a4af4fba36f33ecac (patch) | |
tree | 60848f49949c5b7b518621ee36cdc6d500244539 /drivers | |
parent | ac0e4b7d319bf284bb64bc7e1c051417386b34a4 (diff) |
tty/serial: lay the foundations for the next set of reworks
- Stop drivers calling their own flush method indirectly, it obfuscates code
and it will change soon anyway
- A few more lock_kernel paths temporarily needed in some driver internal
waiting code
- Remove private put_char method that does a write call for one char - we
have that anyway
- Most but not yet all of the termios copy under lock fixing (some has other
dependencies to follow)
- Note a few locking bugs in drivers found in the process
- Kill remaining [ab]users of TIOCG/SSOFTCAR in the driver, these must go to
fix the termios locking
Signed-off-by: Alan Cox <alan@redhat.com>
Cc: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/amiserial.c | 6 | ||||
-rw-r--r-- | drivers/char/cyclades.c | 76 | ||||
-rw-r--r-- | drivers/char/epca.c | 13 | ||||
-rw-r--r-- | drivers/char/esp.c | 3 | ||||
-rw-r--r-- | drivers/char/generic_serial.c | 3 | ||||
-rw-r--r-- | drivers/char/isicom.c | 35 | ||||
-rw-r--r-- | drivers/char/moxa.c | 2 | ||||
-rw-r--r-- | drivers/char/mxser.c | 47 | ||||
-rw-r--r-- | drivers/char/nozomi.c | 13 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 16 | ||||
-rw-r--r-- | drivers/char/riscom8.c | 38 | ||||
-rw-r--r-- | drivers/char/rocket.c | 2 | ||||
-rw-r--r-- | drivers/char/serial167.c | 3 | ||||
-rw-r--r-- | drivers/char/specialix.c | 46 | ||||
-rw-r--r-- | drivers/char/stallion.c | 2 | ||||
-rw-r--r-- | drivers/char/synclink.c | 7 | ||||
-rw-r--r-- | drivers/char/synclink_gt.c | 6 | ||||
-rw-r--r-- | drivers/char/synclinkmp.c | 8 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 2 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 14 | ||||
-rw-r--r-- | drivers/isdn/i4l/isdn_tty.c | 4 | ||||
-rw-r--r-- | drivers/serial/68328serial.c | 18 | ||||
-rw-r--r-- | drivers/serial/68360serial.c | 17 | ||||
-rw-r--r-- | drivers/serial/crisv10.c | 23 | ||||
-rw-r--r-- | drivers/serial/mcfserial.c | 18 | ||||
-rw-r--r-- | drivers/serial/netx-serial.c | 1 |
26 files changed, 189 insertions, 234 deletions
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 8ab75a43231b..a5f3956a5971 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1505,8 +1505,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1505 | rs_wait_until_sent(tty, info->timeout); | 1505 | rs_wait_until_sent(tty, info->timeout); |
1506 | } | 1506 | } |
1507 | shutdown(info); | 1507 | shutdown(info); |
1508 | if (tty->driver->flush_buffer) | 1508 | rs_flush_buffer(tty); |
1509 | tty->driver->flush_buffer(tty); | ||
1510 | 1509 | ||
1511 | tty_ldisc_flush(tty); | 1510 | tty_ldisc_flush(tty); |
1512 | tty->closing = 0; | 1511 | tty->closing = 0; |
@@ -1539,6 +1538,8 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1539 | return; /* Just in case.... */ | 1538 | return; /* Just in case.... */ |
1540 | 1539 | ||
1541 | orig_jiffies = jiffies; | 1540 | orig_jiffies = jiffies; |
1541 | |||
1542 | lock_kernel(); | ||
1542 | /* | 1543 | /* |
1543 | * Set the check interval to be 1/5 of the estimated time to | 1544 | * Set the check interval to be 1/5 of the estimated time to |
1544 | * send a single character, and make it at least 1. The check | 1545 | * send a single character, and make it at least 1. The check |
@@ -1579,6 +1580,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1579 | break; | 1580 | break; |
1580 | } | 1581 | } |
1581 | __set_current_state(TASK_RUNNING); | 1582 | __set_current_state(TASK_RUNNING); |
1583 | unlock_kernel(); | ||
1582 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1584 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1583 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1585 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1584 | #endif | 1586 | #endif |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index e61939d3331d..571e4fab5bfa 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -2522,6 +2522,7 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2522 | return; /* Just in case.... */ | 2522 | return; /* Just in case.... */ |
2523 | 2523 | ||
2524 | orig_jiffies = jiffies; | 2524 | orig_jiffies = jiffies; |
2525 | lock_kernel(); | ||
2525 | /* | 2526 | /* |
2526 | * Set the check interval to be 1/5 of the estimated time to | 2527 | * Set the check interval to be 1/5 of the estimated time to |
2527 | * send a single character, and make it at least 1. The check | 2528 | * send a single character, and make it at least 1. The check |
@@ -2573,11 +2574,47 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2573 | } | 2574 | } |
2574 | /* Run one more char cycle */ | 2575 | /* Run one more char cycle */ |
2575 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); | 2576 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); |
2577 | unlock_kernel(); | ||
2576 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2578 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2577 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); | 2579 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); |
2578 | #endif | 2580 | #endif |
2579 | } | 2581 | } |
2580 | 2582 | ||
2583 | static void cy_flush_buffer(struct tty_struct *tty) | ||
2584 | { | ||
2585 | struct cyclades_port *info = tty->driver_data; | ||
2586 | struct cyclades_card *card; | ||
2587 | int channel, retval; | ||
2588 | unsigned long flags; | ||
2589 | |||
2590 | #ifdef CY_DEBUG_IO | ||
2591 | printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); | ||
2592 | #endif | ||
2593 | |||
2594 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) | ||
2595 | return; | ||
2596 | |||
2597 | card = info->card; | ||
2598 | channel = info->line - card->first_line; | ||
2599 | |||
2600 | spin_lock_irqsave(&card->card_lock, flags); | ||
2601 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
2602 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
2603 | |||
2604 | if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board | ||
2605 | buffers as well */ | ||
2606 | spin_lock_irqsave(&card->card_lock, flags); | ||
2607 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); | ||
2608 | if (retval != 0) { | ||
2609 | printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " | ||
2610 | "was %x\n", info->line, retval); | ||
2611 | } | ||
2612 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
2613 | } | ||
2614 | tty_wakeup(tty); | ||
2615 | } /* cy_flush_buffer */ | ||
2616 | |||
2617 | |||
2581 | /* | 2618 | /* |
2582 | * This routine is called when a particular tty device is closed. | 2619 | * This routine is called when a particular tty device is closed. |
2583 | */ | 2620 | */ |
@@ -2689,8 +2726,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2689 | 2726 | ||
2690 | spin_unlock_irqrestore(&card->card_lock, flags); | 2727 | spin_unlock_irqrestore(&card->card_lock, flags); |
2691 | shutdown(info); | 2728 | shutdown(info); |
2692 | if (tty->driver->flush_buffer) | 2729 | cy_flush_buffer(tty); |
2693 | tty->driver->flush_buffer(tty); | ||
2694 | tty_ldisc_flush(tty); | 2730 | tty_ldisc_flush(tty); |
2695 | spin_lock_irqsave(&card->card_lock, flags); | 2731 | spin_lock_irqsave(&card->card_lock, flags); |
2696 | 2732 | ||
@@ -2881,6 +2917,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
2881 | int char_count; | 2917 | int char_count; |
2882 | __u32 tx_put, tx_get, tx_bufsize; | 2918 | __u32 tx_put, tx_get, tx_bufsize; |
2883 | 2919 | ||
2920 | lock_kernel(); | ||
2884 | firm_id = card->base_addr + ID_ADDRESS; | 2921 | firm_id = card->base_addr + ID_ADDRESS; |
2885 | zfw_ctrl = card->base_addr + | 2922 | zfw_ctrl = card->base_addr + |
2886 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2923 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
@@ -2898,6 +2935,7 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
2898 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", | 2935 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", |
2899 | info->line, info->xmit_cnt + char_count); | 2936 | info->line, info->xmit_cnt + char_count); |
2900 | #endif | 2937 | #endif |
2938 | unlock_kernel(); | ||
2901 | return info->xmit_cnt + char_count; | 2939 | return info->xmit_cnt + char_count; |
2902 | } | 2940 | } |
2903 | #endif /* Z_EXT_CHARS_IN_BUFFER */ | 2941 | #endif /* Z_EXT_CHARS_IN_BUFFER */ |
@@ -4271,40 +4309,6 @@ static void cy_start(struct tty_struct *tty) | |||
4271 | } | 4309 | } |
4272 | } /* cy_start */ | 4310 | } /* cy_start */ |
4273 | 4311 | ||
4274 | static void cy_flush_buffer(struct tty_struct *tty) | ||
4275 | { | ||
4276 | struct cyclades_port *info = tty->driver_data; | ||
4277 | struct cyclades_card *card; | ||
4278 | int channel, retval; | ||
4279 | unsigned long flags; | ||
4280 | |||
4281 | #ifdef CY_DEBUG_IO | ||
4282 | printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); | ||
4283 | #endif | ||
4284 | |||
4285 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) | ||
4286 | return; | ||
4287 | |||
4288 | card = info->card; | ||
4289 | channel = info->line - card->first_line; | ||
4290 | |||
4291 | spin_lock_irqsave(&card->card_lock, flags); | ||
4292 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
4293 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
4294 | |||
4295 | if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board | ||
4296 | buffers as well */ | ||
4297 | spin_lock_irqsave(&card->card_lock, flags); | ||
4298 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); | ||
4299 | if (retval != 0) { | ||
4300 | printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " | ||
4301 | "was %x\n", info->line, retval); | ||
4302 | } | ||
4303 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
4304 | } | ||
4305 | tty_wakeup(tty); | ||
4306 | } /* cy_flush_buffer */ | ||
4307 | |||
4308 | /* | 4312 | /* |
4309 | * cy_hangup() --- called by tty_hangup() when a hangup is signaled. | 4313 | * cy_hangup() --- called by tty_hangup() when a hangup is signaled. |
4310 | */ | 4314 | */ |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 37d4dca5a5d4..39c6a36e395b 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -157,7 +157,6 @@ static void epca_error(int, char *); | |||
157 | static void pc_close(struct tty_struct *, struct file *); | 157 | static void pc_close(struct tty_struct *, struct file *); |
158 | static void shutdown(struct channel *); | 158 | static void shutdown(struct channel *); |
159 | static void pc_hangup(struct tty_struct *); | 159 | static void pc_hangup(struct tty_struct *); |
160 | static void pc_put_char(struct tty_struct *, unsigned char); | ||
161 | static int pc_write_room(struct tty_struct *); | 160 | static int pc_write_room(struct tty_struct *); |
162 | static int pc_chars_in_buffer(struct tty_struct *); | 161 | static int pc_chars_in_buffer(struct tty_struct *); |
163 | static void pc_flush_buffer(struct tty_struct *); | 162 | static void pc_flush_buffer(struct tty_struct *); |
@@ -459,8 +458,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp) | |||
459 | setup_empty_event(tty, ch); | 458 | setup_empty_event(tty, ch); |
460 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ | 459 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ |
461 | } | 460 | } |
462 | if (tty->driver->flush_buffer) | 461 | pc_flush_buffer(tty); |
463 | tty->driver->flush_buffer(tty); | ||
464 | 462 | ||
465 | tty_ldisc_flush(tty); | 463 | tty_ldisc_flush(tty); |
466 | shutdown(ch); | 464 | shutdown(ch); |
@@ -532,8 +530,7 @@ static void pc_hangup(struct tty_struct *tty) | |||
532 | if ((ch = verifyChannel(tty)) != NULL) { | 530 | if ((ch = verifyChannel(tty)) != NULL) { |
533 | unsigned long flags; | 531 | unsigned long flags; |
534 | 532 | ||
535 | if (tty->driver->flush_buffer) | 533 | pc_flush_buffer(tty); |
536 | tty->driver->flush_buffer(tty); | ||
537 | tty_ldisc_flush(tty); | 534 | tty_ldisc_flush(tty); |
538 | shutdown(ch); | 535 | shutdown(ch); |
539 | 536 | ||
@@ -645,11 +642,6 @@ static int pc_write(struct tty_struct *tty, | |||
645 | return amountCopied; | 642 | return amountCopied; |
646 | } | 643 | } |
647 | 644 | ||
648 | static void pc_put_char(struct tty_struct *tty, unsigned char c) | ||
649 | { | ||
650 | pc_write(tty, &c, 1); | ||
651 | } | ||
652 | |||
653 | static int pc_write_room(struct tty_struct *tty) | 645 | static int pc_write_room(struct tty_struct *tty) |
654 | { | 646 | { |
655 | int remain; | 647 | int remain; |
@@ -1035,7 +1027,6 @@ static const struct tty_operations pc_ops = { | |||
1035 | .flush_buffer = pc_flush_buffer, | 1027 | .flush_buffer = pc_flush_buffer, |
1036 | .chars_in_buffer = pc_chars_in_buffer, | 1028 | .chars_in_buffer = pc_chars_in_buffer, |
1037 | .flush_chars = pc_flush_chars, | 1029 | .flush_chars = pc_flush_chars, |
1038 | .put_char = pc_put_char, | ||
1039 | .ioctl = pc_ioctl, | 1030 | .ioctl = pc_ioctl, |
1040 | .set_termios = pc_set_termios, | 1031 | .set_termios = pc_set_termios, |
1041 | .stop = pc_stop, | 1032 | .stop = pc_stop, |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 662e9cfdcc96..b1f92db31331 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -1994,8 +1994,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1994 | rs_wait_until_sent(tty, info->timeout); | 1994 | rs_wait_until_sent(tty, info->timeout); |
1995 | } | 1995 | } |
1996 | shutdown(info); | 1996 | shutdown(info); |
1997 | if (tty->driver->flush_buffer) | 1997 | rs_flush_buffer(tty); |
1998 | tty->driver->flush_buffer(tty); | ||
1999 | tty_ldisc_flush(tty); | 1998 | tty_ldisc_flush(tty); |
2000 | tty->closing = 0; | 1999 | tty->closing = 0; |
2001 | info->tty = NULL; | 2000 | info->tty = NULL; |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 7ed7da1d99cf..f6610f28d657 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c | |||
@@ -586,8 +586,7 @@ void gs_close(struct tty_struct * tty, struct file * filp) | |||
586 | 586 | ||
587 | port->flags &= ~GS_ACTIVE; | 587 | port->flags &= ~GS_ACTIVE; |
588 | 588 | ||
589 | if (tty->driver->flush_buffer) | 589 | gs_flush_buffer(tty); |
590 | tty->driver->flush_buffer(tty); | ||
591 | 590 | ||
592 | tty_ldisc_flush(tty); | 591 | tty_ldisc_flush(tty); |
593 | tty->closing = 0; | 592 | tty->closing = 0; |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index a69e4bb91ad4..6812fda20953 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1012,6 +1012,22 @@ static void isicom_shutdown_port(struct isi_port *port) | |||
1012 | } | 1012 | } |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | static void isicom_flush_buffer(struct tty_struct *tty) | ||
1016 | { | ||
1017 | struct isi_port *port = tty->driver_data; | ||
1018 | struct isi_board *card = port->card; | ||
1019 | unsigned long flags; | ||
1020 | |||
1021 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) | ||
1022 | return; | ||
1023 | |||
1024 | spin_lock_irqsave(&card->card_lock, flags); | ||
1025 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1026 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1027 | |||
1028 | tty_wakeup(tty); | ||
1029 | } | ||
1030 | |||
1015 | static void isicom_close(struct tty_struct *tty, struct file *filp) | 1031 | static void isicom_close(struct tty_struct *tty, struct file *filp) |
1016 | { | 1032 | { |
1017 | struct isi_port *port = tty->driver_data; | 1033 | struct isi_port *port = tty->driver_data; |
@@ -1065,8 +1081,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
1065 | isicom_shutdown_port(port); | 1081 | isicom_shutdown_port(port); |
1066 | spin_unlock_irqrestore(&card->card_lock, flags); | 1082 | spin_unlock_irqrestore(&card->card_lock, flags); |
1067 | 1083 | ||
1068 | if (tty->driver->flush_buffer) | 1084 | isicom_flush_buffer(tty); |
1069 | tty->driver->flush_buffer(tty); | ||
1070 | tty_ldisc_flush(tty); | 1085 | tty_ldisc_flush(tty); |
1071 | 1086 | ||
1072 | spin_lock_irqsave(&card->card_lock, flags); | 1087 | spin_lock_irqsave(&card->card_lock, flags); |
@@ -1447,22 +1462,6 @@ static void isicom_hangup(struct tty_struct *tty) | |||
1447 | wake_up_interruptible(&port->open_wait); | 1462 | wake_up_interruptible(&port->open_wait); |
1448 | } | 1463 | } |
1449 | 1464 | ||
1450 | /* flush_buffer et all */ | ||
1451 | static void isicom_flush_buffer(struct tty_struct *tty) | ||
1452 | { | ||
1453 | struct isi_port *port = tty->driver_data; | ||
1454 | struct isi_board *card = port->card; | ||
1455 | unsigned long flags; | ||
1456 | |||
1457 | if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) | ||
1458 | return; | ||
1459 | |||
1460 | spin_lock_irqsave(&card->card_lock, flags); | ||
1461 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1462 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1463 | |||
1464 | tty_wakeup(tty); | ||
1465 | } | ||
1466 | 1465 | ||
1467 | /* | 1466 | /* |
1468 | * Driver init and deinit functions | 1467 | * Driver init and deinit functions |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 1ab9517c24c5..585fac179ec6 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -1280,6 +1280,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) | |||
1280 | */ | 1280 | */ |
1281 | if (ch == NULL) | 1281 | if (ch == NULL) |
1282 | return 0; | 1282 | return 0; |
1283 | lock_kernel(); | ||
1283 | chars = MoxaPortTxQueue(ch); | 1284 | chars = MoxaPortTxQueue(ch); |
1284 | if (chars) { | 1285 | if (chars) { |
1285 | /* | 1286 | /* |
@@ -1289,6 +1290,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) | |||
1289 | if (!(ch->statusflags & EMPTYWAIT)) | 1290 | if (!(ch->statusflags & EMPTYWAIT)) |
1290 | moxa_setup_empty_event(tty); | 1291 | moxa_setup_empty_event(tty); |
1291 | } | 1292 | } |
1293 | unlock_kernel(); | ||
1292 | return chars; | 1294 | return chars; |
1293 | } | 1295 | } |
1294 | 1296 | ||
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 00cf09aa11fc..28f63566ab8a 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -927,6 +927,27 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
927 | return 0; | 927 | return 0; |
928 | } | 928 | } |
929 | 929 | ||
930 | static void mxser_flush_buffer(struct tty_struct *tty) | ||
931 | { | ||
932 | struct mxser_port *info = tty->driver_data; | ||
933 | char fcr; | ||
934 | unsigned long flags; | ||
935 | |||
936 | |||
937 | spin_lock_irqsave(&info->slock, flags); | ||
938 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
939 | |||
940 | fcr = inb(info->ioaddr + UART_FCR); | ||
941 | outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), | ||
942 | info->ioaddr + UART_FCR); | ||
943 | outb(fcr, info->ioaddr + UART_FCR); | ||
944 | |||
945 | spin_unlock_irqrestore(&info->slock, flags); | ||
946 | |||
947 | tty_wakeup(tty); | ||
948 | } | ||
949 | |||
950 | |||
930 | /* | 951 | /* |
931 | * This routine is called when the serial port gets closed. First, we | 952 | * This routine is called when the serial port gets closed. First, we |
932 | * wait for the last remaining data to be sent. Then, we unlink its | 953 | * wait for the last remaining data to be sent. Then, we unlink its |
@@ -1013,9 +1034,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1013 | } | 1034 | } |
1014 | mxser_shutdown(info); | 1035 | mxser_shutdown(info); |
1015 | 1036 | ||
1016 | if (tty->driver->flush_buffer) | 1037 | mxser_flush_buffer(tty); |
1017 | tty->driver->flush_buffer(tty); | ||
1018 | |||
1019 | tty_ldisc_flush(tty); | 1038 | tty_ldisc_flush(tty); |
1020 | 1039 | ||
1021 | tty->closing = 0; | 1040 | tty->closing = 0; |
@@ -1142,26 +1161,6 @@ static int mxser_chars_in_buffer(struct tty_struct *tty) | |||
1142 | return info->xmit_cnt; | 1161 | return info->xmit_cnt; |
1143 | } | 1162 | } |
1144 | 1163 | ||
1145 | static void mxser_flush_buffer(struct tty_struct *tty) | ||
1146 | { | ||
1147 | struct mxser_port *info = tty->driver_data; | ||
1148 | char fcr; | ||
1149 | unsigned long flags; | ||
1150 | |||
1151 | |||
1152 | spin_lock_irqsave(&info->slock, flags); | ||
1153 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
1154 | |||
1155 | fcr = inb(info->ioaddr + UART_FCR); | ||
1156 | outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), | ||
1157 | info->ioaddr + UART_FCR); | ||
1158 | outb(fcr, info->ioaddr + UART_FCR); | ||
1159 | |||
1160 | spin_unlock_irqrestore(&info->slock, flags); | ||
1161 | |||
1162 | tty_wakeup(tty); | ||
1163 | } | ||
1164 | |||
1165 | /* | 1164 | /* |
1166 | * ------------------------------------------------------------ | 1165 | * ------------------------------------------------------------ |
1167 | * friends of mxser_ioctl() | 1166 | * friends of mxser_ioctl() |
@@ -1992,6 +1991,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1992 | timeout, char_time); | 1991 | timeout, char_time); |
1993 | printk("jiff=%lu...", jiffies); | 1992 | printk("jiff=%lu...", jiffies); |
1994 | #endif | 1993 | #endif |
1994 | lock_kernel(); | ||
1995 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { | 1995 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { |
1996 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1996 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1997 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); | 1997 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); |
@@ -2003,6 +2003,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2003 | break; | 2003 | break; |
2004 | } | 2004 | } |
2005 | set_current_state(TASK_RUNNING); | 2005 | set_current_state(TASK_RUNNING); |
2006 | unlock_kernel(); | ||
2006 | 2007 | ||
2007 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 2008 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
2008 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 2009 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 6a6843a0a674..b55c933d5585 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -1724,6 +1724,8 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file) | |||
1724 | const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; | 1724 | const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; |
1725 | const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; | 1725 | const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; |
1726 | 1726 | ||
1727 | /* Note: these could change under us but it is not clear this | ||
1728 | matters if so */ | ||
1727 | return (ctrl_ul->RTS ? TIOCM_RTS : 0) | | 1729 | return (ctrl_ul->RTS ? TIOCM_RTS : 0) | |
1728 | (ctrl_ul->DTR ? TIOCM_DTR : 0) | | 1730 | (ctrl_ul->DTR ? TIOCM_DTR : 0) | |
1729 | (ctrl_dl->DCD ? TIOCM_CAR : 0) | | 1731 | (ctrl_dl->DCD ? TIOCM_CAR : 0) | |
@@ -1849,16 +1851,6 @@ static void ntty_throttle(struct tty_struct *tty) | |||
1849 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | 1851 | spin_unlock_irqrestore(&dc->spin_mutex, flags); |
1850 | } | 1852 | } |
1851 | 1853 | ||
1852 | /* just to discard single character writes */ | ||
1853 | static void ntty_put_char(struct tty_struct *tty, unsigned char c) | ||
1854 | { | ||
1855 | /* | ||
1856 | * card does not react correct when we write single chars | ||
1857 | * to the card, so we discard them | ||
1858 | */ | ||
1859 | DBG2("PUT CHAR Function: %c", c); | ||
1860 | } | ||
1861 | |||
1862 | /* Returns number of chars in buffer, called by tty layer */ | 1854 | /* Returns number of chars in buffer, called by tty layer */ |
1863 | static s32 ntty_chars_in_buffer(struct tty_struct *tty) | 1855 | static s32 ntty_chars_in_buffer(struct tty_struct *tty) |
1864 | { | 1856 | { |
@@ -1892,7 +1884,6 @@ static const struct tty_operations tty_ops = { | |||
1892 | .unthrottle = ntty_unthrottle, | 1884 | .unthrottle = ntty_unthrottle, |
1893 | .throttle = ntty_throttle, | 1885 | .throttle = ntty_throttle, |
1894 | .chars_in_buffer = ntty_chars_in_buffer, | 1886 | .chars_in_buffer = ntty_chars_in_buffer, |
1895 | .put_char = ntty_put_char, | ||
1896 | .tiocmget = ntty_tiocmget, | 1887 | .tiocmget = ntty_tiocmget, |
1897 | .tiocmset = ntty_tiocmset, | 1888 | .tiocmset = ntty_tiocmset, |
1898 | }; | 1889 | }; |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 583356426dfb..45d8eb5de69f 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -503,20 +503,9 @@ static void* mgslpc_get_text_ptr(void) | |||
503 | * The wrappers maintain line discipline references | 503 | * The wrappers maintain line discipline references |
504 | * while calling into the line discipline. | 504 | * while calling into the line discipline. |
505 | * | 505 | * |
506 | * ldisc_flush_buffer - flush line discipline receive buffers | ||
507 | * ldisc_receive_buf - pass receive data to line discipline | 506 | * ldisc_receive_buf - pass receive data to line discipline |
508 | */ | 507 | */ |
509 | 508 | ||
510 | static void ldisc_flush_buffer(struct tty_struct *tty) | ||
511 | { | ||
512 | struct tty_ldisc *ld = tty_ldisc_ref(tty); | ||
513 | if (ld) { | ||
514 | if (ld->flush_buffer) | ||
515 | ld->flush_buffer(tty); | ||
516 | tty_ldisc_deref(ld); | ||
517 | } | ||
518 | } | ||
519 | |||
520 | static void ldisc_receive_buf(struct tty_struct *tty, | 509 | static void ldisc_receive_buf(struct tty_struct *tty, |
521 | const __u8 *data, char *flags, int count) | 510 | const __u8 *data, char *flags, int count) |
522 | { | 511 | { |
@@ -2467,10 +2456,9 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp) | |||
2467 | if (info->flags & ASYNC_INITIALIZED) | 2456 | if (info->flags & ASYNC_INITIALIZED) |
2468 | mgslpc_wait_until_sent(tty, info->timeout); | 2457 | mgslpc_wait_until_sent(tty, info->timeout); |
2469 | 2458 | ||
2470 | if (tty->driver->flush_buffer) | 2459 | mgslpc_flush_buffer(tty); |
2471 | tty->driver->flush_buffer(tty); | ||
2472 | 2460 | ||
2473 | ldisc_flush_buffer(tty); | 2461 | tty_ldisc_flush(tty); |
2474 | 2462 | ||
2475 | shutdown(info); | 2463 | shutdown(info); |
2476 | 2464 | ||
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index b56e0e04cb4a..a82c2a2d5e6c 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -1015,6 +1015,24 @@ static int rc_open(struct tty_struct * tty, struct file * filp) | |||
1015 | return 0; | 1015 | return 0; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | static void rc_flush_buffer(struct tty_struct *tty) | ||
1019 | { | ||
1020 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | ||
1021 | unsigned long flags; | ||
1022 | |||
1023 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) | ||
1024 | return; | ||
1025 | |||
1026 | spin_lock_irqsave(&riscom_lock, flags); | ||
1027 | |||
1028 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1029 | |||
1030 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1031 | |||
1032 | tty_wakeup(tty); | ||
1033 | } | ||
1034 | |||
1035 | |||
1018 | static void rc_close(struct tty_struct * tty, struct file * filp) | 1036 | static void rc_close(struct tty_struct * tty, struct file * filp) |
1019 | { | 1037 | { |
1020 | struct riscom_port *port = (struct riscom_port *) tty->driver_data; | 1038 | struct riscom_port *port = (struct riscom_port *) tty->driver_data; |
@@ -1078,8 +1096,7 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1078 | } | 1096 | } |
1079 | } | 1097 | } |
1080 | rc_shutdown_port(bp, port); | 1098 | rc_shutdown_port(bp, port); |
1081 | if (tty->driver->flush_buffer) | 1099 | rc_flush_buffer(tty); |
1082 | tty->driver->flush_buffer(tty); | ||
1083 | tty_ldisc_flush(tty); | 1100 | tty_ldisc_flush(tty); |
1084 | 1101 | ||
1085 | tty->closing = 0; | 1102 | tty->closing = 0; |
@@ -1213,23 +1230,6 @@ static int rc_chars_in_buffer(struct tty_struct *tty) | |||
1213 | return port->xmit_cnt; | 1230 | return port->xmit_cnt; |
1214 | } | 1231 | } |
1215 | 1232 | ||
1216 | static void rc_flush_buffer(struct tty_struct *tty) | ||
1217 | { | ||
1218 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | ||
1219 | unsigned long flags; | ||
1220 | |||
1221 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) | ||
1222 | return; | ||
1223 | |||
1224 | spin_lock_irqsave(&riscom_lock, flags); | ||
1225 | |||
1226 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1227 | |||
1228 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1229 | |||
1230 | tty_wakeup(tty); | ||
1231 | } | ||
1232 | |||
1233 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) | 1233 | static int rc_tiocmget(struct tty_struct *tty, struct file *file) |
1234 | { | 1234 | { |
1235 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1235 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 32fe8dca24b6..00cfb6c7fd46 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -1585,6 +1585,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1585 | jiffies); | 1585 | jiffies); |
1586 | printk(KERN_INFO "cps=%d...\n", info->cps); | 1586 | printk(KERN_INFO "cps=%d...\n", info->cps); |
1587 | #endif | 1587 | #endif |
1588 | lock_kernel(); | ||
1588 | while (1) { | 1589 | while (1) { |
1589 | txcnt = sGetTxCnt(cp); | 1590 | txcnt = sGetTxCnt(cp); |
1590 | if (!txcnt) { | 1591 | if (!txcnt) { |
@@ -1612,6 +1613,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1612 | break; | 1613 | break; |
1613 | } | 1614 | } |
1614 | __set_current_state(TASK_RUNNING); | 1615 | __set_current_state(TASK_RUNNING); |
1616 | unlock_kernel(); | ||
1615 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT | 1617 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT |
1616 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); | 1618 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); |
1617 | #endif | 1619 | #endif |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index f62fb9360c3f..62d6f2e0fd18 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1674,8 +1674,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
1674 | if (info->flags & ASYNC_INITIALIZED) | 1674 | if (info->flags & ASYNC_INITIALIZED) |
1675 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ | 1675 | tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ |
1676 | shutdown(info); | 1676 | shutdown(info); |
1677 | if (tty->driver->flush_buffer) | 1677 | cy_flush_buffer(tty); |
1678 | tty->driver->flush_buffer(tty); | ||
1679 | tty_ldisc_flush(tty); | 1678 | tty_ldisc_flush(tty); |
1680 | info->tty = NULL; | 1679 | info->tty = NULL; |
1681 | if (info->blocked_open) { | 1680 | if (info->blocked_open) { |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 9f9a4bdc1b0e..075ad924dd04 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -1504,6 +1504,27 @@ static int sx_open(struct tty_struct * tty, struct file * filp) | |||
1504 | return 0; | 1504 | return 0; |
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | static void sx_flush_buffer(struct tty_struct *tty) | ||
1508 | { | ||
1509 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | ||
1510 | unsigned long flags; | ||
1511 | struct specialix_board * bp; | ||
1512 | |||
1513 | func_enter(); | ||
1514 | |||
1515 | if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { | ||
1516 | func_exit(); | ||
1517 | return; | ||
1518 | } | ||
1519 | |||
1520 | bp = port_Board(port); | ||
1521 | spin_lock_irqsave(&port->lock, flags); | ||
1522 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1523 | spin_unlock_irqrestore(&port->lock, flags); | ||
1524 | tty_wakeup(tty); | ||
1525 | |||
1526 | func_exit(); | ||
1527 | } | ||
1507 | 1528 | ||
1508 | static void sx_close(struct tty_struct * tty, struct file * filp) | 1529 | static void sx_close(struct tty_struct * tty, struct file * filp) |
1509 | { | 1530 | { |
@@ -1597,8 +1618,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1597 | } | 1618 | } |
1598 | 1619 | ||
1599 | sx_shutdown_port(bp, port); | 1620 | sx_shutdown_port(bp, port); |
1600 | if (tty->driver->flush_buffer) | 1621 | sx_flush_buffer(tty); |
1601 | tty->driver->flush_buffer(tty); | ||
1602 | tty_ldisc_flush(tty); | 1622 | tty_ldisc_flush(tty); |
1603 | spin_lock_irqsave(&port->lock, flags); | 1623 | spin_lock_irqsave(&port->lock, flags); |
1604 | tty->closing = 0; | 1624 | tty->closing = 0; |
@@ -1770,28 +1790,6 @@ static int sx_chars_in_buffer(struct tty_struct *tty) | |||
1770 | } | 1790 | } |
1771 | 1791 | ||
1772 | 1792 | ||
1773 | static void sx_flush_buffer(struct tty_struct *tty) | ||
1774 | { | ||
1775 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | ||
1776 | unsigned long flags; | ||
1777 | struct specialix_board * bp; | ||
1778 | |||
1779 | func_enter(); | ||
1780 | |||
1781 | if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { | ||
1782 | func_exit(); | ||
1783 | return; | ||
1784 | } | ||
1785 | |||
1786 | bp = port_Board(port); | ||
1787 | spin_lock_irqsave(&port->lock, flags); | ||
1788 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | ||
1789 | spin_unlock_irqrestore(&port->lock, flags); | ||
1790 | tty_wakeup(tty); | ||
1791 | |||
1792 | func_exit(); | ||
1793 | } | ||
1794 | |||
1795 | 1793 | ||
1796 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) | 1794 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) |
1797 | { | 1795 | { |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 983244ab1362..d17be10c5d21 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -875,6 +875,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
875 | timeout = HZ; | 875 | timeout = HZ; |
876 | tend = jiffies + timeout; | 876 | tend = jiffies + timeout; |
877 | 877 | ||
878 | lock_kernel(); | ||
878 | while (stl_datastate(portp)) { | 879 | while (stl_datastate(portp)) { |
879 | if (signal_pending(current)) | 880 | if (signal_pending(current)) |
880 | break; | 881 | break; |
@@ -882,6 +883,7 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
882 | if (time_after_eq(jiffies, tend)) | 883 | if (time_after_eq(jiffies, tend)) |
883 | break; | 884 | break; |
884 | } | 885 | } |
886 | unlock_kernel(); | ||
885 | } | 887 | } |
886 | 888 | ||
887 | /*****************************************************************************/ | 889 | /*****************************************************************************/ |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 1c9c440f59ce..dbbd998ae103 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -3157,8 +3157,7 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp) | |||
3157 | if (info->flags & ASYNC_INITIALIZED) | 3157 | if (info->flags & ASYNC_INITIALIZED) |
3158 | mgsl_wait_until_sent(tty, info->timeout); | 3158 | mgsl_wait_until_sent(tty, info->timeout); |
3159 | 3159 | ||
3160 | if (tty->driver->flush_buffer) | 3160 | mgsl_flush_buffer(tty); |
3161 | tty->driver->flush_buffer(tty); | ||
3162 | 3161 | ||
3163 | tty_ldisc_flush(tty); | 3162 | tty_ldisc_flush(tty); |
3164 | 3163 | ||
@@ -3221,7 +3220,8 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3221 | * interval should also be less than the timeout. | 3220 | * interval should also be less than the timeout. |
3222 | * Note: use tight timings here to satisfy the NIST-PCTS. | 3221 | * Note: use tight timings here to satisfy the NIST-PCTS. |
3223 | */ | 3222 | */ |
3224 | 3223 | ||
3224 | lock_kernel(); | ||
3225 | if ( info->params.data_rate ) { | 3225 | if ( info->params.data_rate ) { |
3226 | char_time = info->timeout/(32 * 5); | 3226 | char_time = info->timeout/(32 * 5); |
3227 | if (!char_time) | 3227 | if (!char_time) |
@@ -3251,6 +3251,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3251 | break; | 3251 | break; |
3252 | } | 3252 | } |
3253 | } | 3253 | } |
3254 | unlock_kernel(); | ||
3254 | 3255 | ||
3255 | exit: | 3256 | exit: |
3256 | if (debug_level >= DEBUG_LEVEL_INFO) | 3257 | if (debug_level >= DEBUG_LEVEL_INFO) |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 6473ae023466..1a11717b1adc 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -771,8 +771,7 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
771 | 771 | ||
772 | if (info->flags & ASYNC_INITIALIZED) | 772 | if (info->flags & ASYNC_INITIALIZED) |
773 | wait_until_sent(tty, info->timeout); | 773 | wait_until_sent(tty, info->timeout); |
774 | if (tty->driver->flush_buffer) | 774 | flush_buffer(tty); |
775 | tty->driver->flush_buffer(tty); | ||
776 | tty_ldisc_flush(tty); | 775 | tty_ldisc_flush(tty); |
777 | 776 | ||
778 | shutdown(info); | 777 | shutdown(info); |
@@ -967,6 +966,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
967 | * Note: use tight timings here to satisfy the NIST-PCTS. | 966 | * Note: use tight timings here to satisfy the NIST-PCTS. |
968 | */ | 967 | */ |
969 | 968 | ||
969 | lock_kernel(); | ||
970 | |||
970 | if (info->params.data_rate) { | 971 | if (info->params.data_rate) { |
971 | char_time = info->timeout/(32 * 5); | 972 | char_time = info->timeout/(32 * 5); |
972 | if (!char_time) | 973 | if (!char_time) |
@@ -984,6 +985,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
984 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 985 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
985 | break; | 986 | break; |
986 | } | 987 | } |
988 | unlock_kernel(); | ||
987 | 989 | ||
988 | exit: | 990 | exit: |
989 | DBGINFO(("%s wait_until_sent exit\n", info->device_name)); | 991 | DBGINFO(("%s wait_until_sent exit\n", info->device_name)); |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index b716a73a236f..2f1988c48ee3 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -862,8 +862,7 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
862 | if (info->flags & ASYNC_INITIALIZED) | 862 | if (info->flags & ASYNC_INITIALIZED) |
863 | wait_until_sent(tty, info->timeout); | 863 | wait_until_sent(tty, info->timeout); |
864 | 864 | ||
865 | if (tty->driver->flush_buffer) | 865 | flush_buffer(tty); |
866 | tty->driver->flush_buffer(tty); | ||
867 | 866 | ||
868 | tty_ldisc_flush(tty); | 867 | tty_ldisc_flush(tty); |
869 | 868 | ||
@@ -1119,6 +1118,8 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1119 | if (sanity_check(info, tty->name, "wait_until_sent")) | 1118 | if (sanity_check(info, tty->name, "wait_until_sent")) |
1120 | return; | 1119 | return; |
1121 | 1120 | ||
1121 | lock_kernel(); | ||
1122 | |||
1122 | if (!(info->flags & ASYNC_INITIALIZED)) | 1123 | if (!(info->flags & ASYNC_INITIALIZED)) |
1123 | goto exit; | 1124 | goto exit; |
1124 | 1125 | ||
@@ -1161,6 +1162,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1161 | } | 1162 | } |
1162 | 1163 | ||
1163 | exit: | 1164 | exit: |
1165 | unlock_kernel(); | ||
1164 | if (debug_level >= DEBUG_LEVEL_INFO) | 1166 | if (debug_level >= DEBUG_LEVEL_INFO) |
1165 | printk("%s(%d):%s wait_until_sent() exit\n", | 1167 | printk("%s(%d):%s wait_until_sent() exit\n", |
1166 | __FILE__,__LINE__, info->device_name ); | 1168 | __FILE__,__LINE__, info->device_name ); |
@@ -1176,6 +1178,7 @@ static int write_room(struct tty_struct *tty) | |||
1176 | if (sanity_check(info, tty->name, "write_room")) | 1178 | if (sanity_check(info, tty->name, "write_room")) |
1177 | return 0; | 1179 | return 0; |
1178 | 1180 | ||
1181 | lock_kernel(); | ||
1179 | if (info->params.mode == MGSL_MODE_HDLC) { | 1182 | if (info->params.mode == MGSL_MODE_HDLC) { |
1180 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; | 1183 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; |
1181 | } else { | 1184 | } else { |
@@ -1183,6 +1186,7 @@ static int write_room(struct tty_struct *tty) | |||
1183 | if (ret < 0) | 1186 | if (ret < 0) |
1184 | ret = 0; | 1187 | ret = 0; |
1185 | } | 1188 | } |
1189 | unlock_kernel(); | ||
1186 | 1190 | ||
1187 | if (debug_level >= DEBUG_LEVEL_INFO) | 1191 | if (debug_level >= DEBUG_LEVEL_INFO) |
1188 | printk("%s(%d):%s write_room()=%d\n", | 1192 | printk("%s(%d):%s write_room()=%d\n", |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 35c7d2eb8b28..b1692afd797e 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1204,7 +1204,7 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver); | |||
1204 | * not in the foreground, send a SIGTTOU. If the signal is blocked or | 1204 | * not in the foreground, send a SIGTTOU. If the signal is blocked or |
1205 | * ignored, go ahead and perform the operation. (POSIX 7.2) | 1205 | * ignored, go ahead and perform the operation. (POSIX 7.2) |
1206 | * | 1206 | * |
1207 | * Locking: ctrl_lock - FIXME: review this | 1207 | * Locking: ctrl_lock |
1208 | */ | 1208 | */ |
1209 | 1209 | ||
1210 | int tty_check_change(struct tty_struct *tty) | 1210 | int tty_check_change(struct tty_struct *tty) |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index d769e43f73fb..8c4bf3e48d5b 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -396,7 +396,7 @@ EXPORT_SYMBOL(tty_termios_hw_change); | |||
396 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | 396 | static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) |
397 | { | 397 | { |
398 | int canon_change; | 398 | int canon_change; |
399 | struct ktermios old_termios = *tty->termios; | 399 | struct ktermios old_termios; |
400 | struct tty_ldisc *ld; | 400 | struct tty_ldisc *ld; |
401 | unsigned long flags; | 401 | unsigned long flags; |
402 | 402 | ||
@@ -408,7 +408,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
408 | /* FIXME: we need to decide on some locking/ordering semantics | 408 | /* FIXME: we need to decide on some locking/ordering semantics |
409 | for the set_termios notification eventually */ | 409 | for the set_termios notification eventually */ |
410 | mutex_lock(&tty->termios_mutex); | 410 | mutex_lock(&tty->termios_mutex); |
411 | 411 | old_termios = *tty->termios; | |
412 | *tty->termios = *new_termios; | 412 | *tty->termios = *new_termios; |
413 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); | 413 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); |
414 | canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; | 414 | canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; |
@@ -480,7 +480,9 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
480 | if (retval) | 480 | if (retval) |
481 | return retval; | 481 | return retval; |
482 | 482 | ||
483 | mutex_lock(&tty->termios_mutex); | ||
483 | memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); | 484 | memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); |
485 | mutex_unlock(&tty->termios_mutex); | ||
484 | 486 | ||
485 | if (opt & TERMIOS_TERMIO) { | 487 | if (opt & TERMIOS_TERMIO) { |
486 | if (user_termio_to_kernel_termios(&tmp_termios, | 488 | if (user_termio_to_kernel_termios(&tmp_termios, |
@@ -666,12 +668,14 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
666 | { | 668 | { |
667 | struct tchars tmp; | 669 | struct tchars tmp; |
668 | 670 | ||
671 | mutex_lock(&tty->termios_mutex); | ||
669 | tmp.t_intrc = tty->termios->c_cc[VINTR]; | 672 | tmp.t_intrc = tty->termios->c_cc[VINTR]; |
670 | tmp.t_quitc = tty->termios->c_cc[VQUIT]; | 673 | tmp.t_quitc = tty->termios->c_cc[VQUIT]; |
671 | tmp.t_startc = tty->termios->c_cc[VSTART]; | 674 | tmp.t_startc = tty->termios->c_cc[VSTART]; |
672 | tmp.t_stopc = tty->termios->c_cc[VSTOP]; | 675 | tmp.t_stopc = tty->termios->c_cc[VSTOP]; |
673 | tmp.t_eofc = tty->termios->c_cc[VEOF]; | 676 | tmp.t_eofc = tty->termios->c_cc[VEOF]; |
674 | tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ | 677 | tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ |
678 | mutex_unlock(&tty->termios_mutex); | ||
675 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 679 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
676 | } | 680 | } |
677 | 681 | ||
@@ -681,12 +685,14 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
681 | 685 | ||
682 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) | 686 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) |
683 | return -EFAULT; | 687 | return -EFAULT; |
688 | mutex_lock(&tty->termios_mutex); | ||
684 | tty->termios->c_cc[VINTR] = tmp.t_intrc; | 689 | tty->termios->c_cc[VINTR] = tmp.t_intrc; |
685 | tty->termios->c_cc[VQUIT] = tmp.t_quitc; | 690 | tty->termios->c_cc[VQUIT] = tmp.t_quitc; |
686 | tty->termios->c_cc[VSTART] = tmp.t_startc; | 691 | tty->termios->c_cc[VSTART] = tmp.t_startc; |
687 | tty->termios->c_cc[VSTOP] = tmp.t_stopc; | 692 | tty->termios->c_cc[VSTOP] = tmp.t_stopc; |
688 | tty->termios->c_cc[VEOF] = tmp.t_eofc; | 693 | tty->termios->c_cc[VEOF] = tmp.t_eofc; |
689 | tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ | 694 | tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ |
695 | mutex_unlock(&tty->termios_mutex); | ||
690 | return 0; | 696 | return 0; |
691 | } | 697 | } |
692 | #endif | 698 | #endif |
@@ -696,6 +702,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
696 | { | 702 | { |
697 | struct ltchars tmp; | 703 | struct ltchars tmp; |
698 | 704 | ||
705 | mutex_lock(&tty->termios_mutex); | ||
699 | tmp.t_suspc = tty->termios->c_cc[VSUSP]; | 706 | tmp.t_suspc = tty->termios->c_cc[VSUSP]; |
700 | /* what is dsuspc anyway? */ | 707 | /* what is dsuspc anyway? */ |
701 | tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; | 708 | tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; |
@@ -704,6 +711,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
704 | tmp.t_flushc = tty->termios->c_cc[VEOL2]; | 711 | tmp.t_flushc = tty->termios->c_cc[VEOL2]; |
705 | tmp.t_werasc = tty->termios->c_cc[VWERASE]; | 712 | tmp.t_werasc = tty->termios->c_cc[VWERASE]; |
706 | tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; | 713 | tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; |
714 | mutex_unlock(&tty->termios_mutex); | ||
707 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 715 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
708 | } | 716 | } |
709 | 717 | ||
@@ -714,6 +722,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
714 | if (copy_from_user(&tmp, ltchars, sizeof(tmp))) | 722 | if (copy_from_user(&tmp, ltchars, sizeof(tmp))) |
715 | return -EFAULT; | 723 | return -EFAULT; |
716 | 724 | ||
725 | mutex_lock(&tty->termios_mutex); | ||
717 | tty->termios->c_cc[VSUSP] = tmp.t_suspc; | 726 | tty->termios->c_cc[VSUSP] = tmp.t_suspc; |
718 | /* what is dsuspc anyway? */ | 727 | /* what is dsuspc anyway? */ |
719 | tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; | 728 | tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; |
@@ -722,6 +731,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
722 | tty->termios->c_cc[VEOL2] = tmp.t_flushc; | 731 | tty->termios->c_cc[VEOL2] = tmp.t_flushc; |
723 | tty->termios->c_cc[VWERASE] = tmp.t_werasc; | 732 | tty->termios->c_cc[VWERASE] = tmp.t_werasc; |
724 | tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; | 733 | tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; |
734 | mutex_unlock(&tty->termios_mutex); | ||
725 | return 0; | 735 | return 0; |
726 | } | 736 | } |
727 | #endif | 737 | #endif |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index a033f53209d5..1a2222cbb805 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1708,9 +1708,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) | |||
1708 | } | 1708 | } |
1709 | dev->modempoll--; | 1709 | dev->modempoll--; |
1710 | isdn_tty_shutdown(info); | 1710 | isdn_tty_shutdown(info); |
1711 | 1711 | isdn_tty_flush_buffer(tty); | |
1712 | if (tty->driver->flush_buffer) | ||
1713 | tty->driver->flush_buffer(tty); | ||
1714 | tty_ldisc_flush(tty); | 1712 | tty_ldisc_flush(tty); |
1715 | info->tty = NULL; | 1713 | info->tty = NULL; |
1716 | info->ncarrier = 0; | 1714 | info->ncarrier = 0; |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 2b8a410e0959..5ce3e57bff0b 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -1017,18 +1017,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1017 | tty_wait_until_sent(tty, 0); | 1017 | tty_wait_until_sent(tty, 0); |
1018 | send_break(info, arg ? arg*(100) : 250); | 1018 | send_break(info, arg ? arg*(100) : 250); |
1019 | return 0; | 1019 | return 0; |
1020 | case TIOCGSOFTCAR: | ||
1021 | error = put_user(C_CLOCAL(tty) ? 1 : 0, | ||
1022 | (unsigned long *) arg); | ||
1023 | if (error) | ||
1024 | return error; | ||
1025 | return 0; | ||
1026 | case TIOCSSOFTCAR: | ||
1027 | get_user(arg, (unsigned long *) arg); | ||
1028 | tty->termios->c_cflag = | ||
1029 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
1030 | (arg ? CLOCAL : 0)); | ||
1031 | return 0; | ||
1032 | case TIOCGSERIAL: | 1020 | case TIOCGSERIAL: |
1033 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1021 | if (access_ok(VERIFY_WRITE, (void *) arg, |
1034 | sizeof(struct serial_struct))) | 1022 | sizeof(struct serial_struct))) |
@@ -1061,9 +1049,6 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1061 | { | 1049 | { |
1062 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | 1050 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; |
1063 | 1051 | ||
1064 | if (tty->termios->c_cflag == old_termios->c_cflag) | ||
1065 | return; | ||
1066 | |||
1067 | change_speed(info); | 1052 | change_speed(info); |
1068 | 1053 | ||
1069 | if ((old_termios->c_cflag & CRTSCTS) && | 1054 | if ((old_termios->c_cflag & CRTSCTS) && |
@@ -1140,8 +1125,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1140 | uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); | 1125 | uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); |
1141 | 1126 | ||
1142 | shutdown(info); | 1127 | shutdown(info); |
1143 | if (tty->driver->flush_buffer) | 1128 | rs_flush_buffer(tty); |
1144 | tty->driver->flush_buffer(tty); | ||
1145 | 1129 | ||
1146 | tty_ldisc_flush(tty); | 1130 | tty_ldisc_flush(tty); |
1147 | tty->closing = 0; | 1131 | tty->closing = 0; |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 6f540107d0bb..f4f737bfa0a7 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
@@ -1436,18 +1436,6 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file, | |||
1436 | return retval; | 1436 | return retval; |
1437 | end_break(info); | 1437 | end_break(info); |
1438 | return 0; | 1438 | return 0; |
1439 | case TIOCGSOFTCAR: | ||
1440 | /* return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); */ | ||
1441 | put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg); | ||
1442 | return 0; | ||
1443 | case TIOCSSOFTCAR: | ||
1444 | error = get_user(arg, (unsigned int *) arg); | ||
1445 | if (error) | ||
1446 | return error; | ||
1447 | tty->termios->c_cflag = | ||
1448 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
1449 | (arg ? CLOCAL : 0)); | ||
1450 | return 0; | ||
1451 | #ifdef maybe | 1439 | #ifdef maybe |
1452 | case TIOCSERGETLSR: /* Get line status register */ | 1440 | case TIOCSERGETLSR: /* Get line status register */ |
1453 | return get_lsr_info(info, (unsigned int *) arg); | 1441 | return get_lsr_info(info, (unsigned int *) arg); |
@@ -1665,8 +1653,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp) | |||
1665 | rs_360_wait_until_sent(tty, info->timeout); | 1653 | rs_360_wait_until_sent(tty, info->timeout); |
1666 | } | 1654 | } |
1667 | shutdown(info); | 1655 | shutdown(info); |
1668 | if (tty->driver->flush_buffer) | 1656 | rs_360_flush_buffer(tty); |
1669 | tty->driver->flush_buffer(tty); | ||
1670 | tty_ldisc_flush(tty); | 1657 | tty_ldisc_flush(tty); |
1671 | tty->closing = 0; | 1658 | tty->closing = 0; |
1672 | info->event = 0; | 1659 | info->event = 0; |
@@ -1717,6 +1704,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1717 | printk("jiff=%lu...", jiffies); | 1704 | printk("jiff=%lu...", jiffies); |
1718 | #endif | 1705 | #endif |
1719 | 1706 | ||
1707 | lock_kernel(); | ||
1720 | /* We go through the loop at least once because we can't tell | 1708 | /* We go through the loop at least once because we can't tell |
1721 | * exactly when the last character exits the shifter. There can | 1709 | * exactly when the last character exits the shifter. There can |
1722 | * be at least two characters waiting to be sent after the buffers | 1710 | * be at least two characters waiting to be sent after the buffers |
@@ -1745,6 +1733,7 @@ static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1745 | bdp--; | 1733 | bdp--; |
1746 | } while (bdp->status & BD_SC_READY); | 1734 | } while (bdp->status & BD_SC_READY); |
1747 | current->state = TASK_RUNNING; | 1735 | current->state = TASK_RUNNING; |
1736 | unlock_kernel(); | ||
1748 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1737 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1749 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1738 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1750 | #endif | 1739 | #endif |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 88e7c1d5b919..8b9af73c1d59 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -3581,8 +3581,9 @@ rs_tiocmset(struct tty_struct *tty, struct file *file, | |||
3581 | unsigned int set, unsigned int clear) | 3581 | unsigned int set, unsigned int clear) |
3582 | { | 3582 | { |
3583 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3583 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3584 | unsigned long flags; | ||
3584 | 3585 | ||
3585 | lock_kernel(); | 3586 | local_irq_save(flags); |
3586 | 3587 | ||
3587 | if (clear & TIOCM_RTS) | 3588 | if (clear & TIOCM_RTS) |
3588 | e100_rts(info, 0); | 3589 | e100_rts(info, 0); |
@@ -3604,7 +3605,7 @@ rs_tiocmset(struct tty_struct *tty, struct file *file, | |||
3604 | if (set & TIOCM_CD) | 3605 | if (set & TIOCM_CD) |
3605 | e100_cd_out(info, 1); | 3606 | e100_cd_out(info, 1); |
3606 | 3607 | ||
3607 | unlock_kernel(); | 3608 | local_irq_restore(flags); |
3608 | return 0; | 3609 | return 0; |
3609 | } | 3610 | } |
3610 | 3611 | ||
@@ -3613,8 +3614,10 @@ rs_tiocmget(struct tty_struct *tty, struct file *file) | |||
3613 | { | 3614 | { |
3614 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3615 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3615 | unsigned int result; | 3616 | unsigned int result; |
3617 | unsigned long flags; | ||
3618 | |||
3619 | local_irq_save(flags); | ||
3616 | 3620 | ||
3617 | lock_kernel(); | ||
3618 | result = | 3621 | result = |
3619 | (!E100_RTS_GET(info) ? TIOCM_RTS : 0) | 3622 | (!E100_RTS_GET(info) ? TIOCM_RTS : 0) |
3620 | | (!E100_DTR_GET(info) ? TIOCM_DTR : 0) | 3623 | | (!E100_DTR_GET(info) ? TIOCM_DTR : 0) |
@@ -3623,7 +3626,7 @@ rs_tiocmget(struct tty_struct *tty, struct file *file) | |||
3623 | | (!E100_CD_GET(info) ? TIOCM_CAR : 0) | 3626 | | (!E100_CD_GET(info) ? TIOCM_CAR : 0) |
3624 | | (!E100_CTS_GET(info) ? TIOCM_CTS : 0); | 3627 | | (!E100_CTS_GET(info) ? TIOCM_CTS : 0); |
3625 | 3628 | ||
3626 | unlock_kernel(); | 3629 | local_irq_restore(flags); |
3627 | 3630 | ||
3628 | #ifdef SERIAL_DEBUG_IO | 3631 | #ifdef SERIAL_DEBUG_IO |
3629 | printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n", | 3632 | printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n", |
@@ -3702,10 +3705,6 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
3702 | { | 3705 | { |
3703 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3706 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3704 | 3707 | ||
3705 | if (tty->termios->c_cflag == old_termios->c_cflag && | ||
3706 | tty->termios->c_iflag == old_termios->c_iflag) | ||
3707 | return; | ||
3708 | |||
3709 | change_speed(info); | 3708 | change_speed(info); |
3710 | 3709 | ||
3711 | /* Handle turning off CRTSCTS */ | 3710 | /* Handle turning off CRTSCTS */ |
@@ -3808,10 +3807,8 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3808 | #endif | 3807 | #endif |
3809 | 3808 | ||
3810 | shutdown(info); | 3809 | shutdown(info); |
3811 | if (tty->driver->flush_buffer) | 3810 | rs_flush_buffer(tty); |
3812 | tty->driver->flush_buffer(tty); | 3811 | tty_ldisc_flush_buffer(tty); |
3813 | if (tty->ldisc.flush_buffer) | ||
3814 | tty->ldisc.flush_buffer(tty); | ||
3815 | tty->closing = 0; | 3812 | tty->closing = 0; |
3816 | info->event = 0; | 3813 | info->event = 0; |
3817 | info->tty = 0; | 3814 | info->tty = 0; |
@@ -3885,6 +3882,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3885 | * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO | 3882 | * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO |
3886 | * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) | 3883 | * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k) |
3887 | */ | 3884 | */ |
3885 | lock_kernel(); | ||
3888 | orig_jiffies = jiffies; | 3886 | orig_jiffies = jiffies; |
3889 | while (info->xmit.head != info->xmit.tail || /* More in send queue */ | 3887 | while (info->xmit.head != info->xmit.tail || /* More in send queue */ |
3890 | (*info->ostatusadr & 0x007f) || /* more in FIFO */ | 3888 | (*info->ostatusadr & 0x007f) || /* more in FIFO */ |
@@ -3901,6 +3899,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3901 | curr_time_usec - info->last_tx_active_usec; | 3899 | curr_time_usec - info->last_tx_active_usec; |
3902 | } | 3900 | } |
3903 | set_current_state(TASK_RUNNING); | 3901 | set_current_state(TASK_RUNNING); |
3902 | unlock_kernel(); | ||
3904 | } | 3903 | } |
3905 | 3904 | ||
3906 | /* | 3905 | /* |
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index ddd3aa50d4ad..aafa1704e1ab 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
@@ -1072,18 +1072,6 @@ static int mcfrs_ioctl(struct tty_struct *tty, struct file * file, | |||
1072 | tty_wait_until_sent(tty, 0); | 1072 | tty_wait_until_sent(tty, 0); |
1073 | send_break(info, arg ? arg*(HZ/10) : HZ/4); | 1073 | send_break(info, arg ? arg*(HZ/10) : HZ/4); |
1074 | return 0; | 1074 | return 0; |
1075 | case TIOCGSOFTCAR: | ||
1076 | error = put_user(C_CLOCAL(tty) ? 1 : 0, | ||
1077 | (unsigned long *) arg); | ||
1078 | if (error) | ||
1079 | return error; | ||
1080 | return 0; | ||
1081 | case TIOCSSOFTCAR: | ||
1082 | get_user(arg, (unsigned long *) arg); | ||
1083 | tty->termios->c_cflag = | ||
1084 | ((tty->termios->c_cflag & ~CLOCAL) | | ||
1085 | (arg ? CLOCAL : 0)); | ||
1086 | return 0; | ||
1087 | case TIOCGSERIAL: | 1075 | case TIOCGSERIAL: |
1088 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1076 | if (access_ok(VERIFY_WRITE, (void *) arg, |
1089 | sizeof(struct serial_struct))) | 1077 | sizeof(struct serial_struct))) |
@@ -1222,8 +1210,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp) | |||
1222 | } else | 1210 | } else |
1223 | #endif | 1211 | #endif |
1224 | shutdown(info); | 1212 | shutdown(info); |
1225 | if (tty->driver->flush_buffer) | 1213 | mcfrs_flush_buffer(tty); |
1226 | tty->driver->flush_buffer(tty); | ||
1227 | tty_ldisc_flush(tty); | 1214 | tty_ldisc_flush(tty); |
1228 | 1215 | ||
1229 | tty->closing = 0; | 1216 | tty->closing = 0; |
@@ -1276,6 +1263,8 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1276 | * Note: we have to use pretty tight timings here to satisfy | 1263 | * Note: we have to use pretty tight timings here to satisfy |
1277 | * the NIST-PCTS. | 1264 | * the NIST-PCTS. |
1278 | */ | 1265 | */ |
1266 | lock_kernel(); | ||
1267 | |||
1279 | fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud; | 1268 | fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud; |
1280 | char_time = fifo_time / 5; | 1269 | char_time = fifo_time / 5; |
1281 | if (char_time == 0) | 1270 | if (char_time == 0) |
@@ -1312,6 +1301,7 @@ mcfrs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1312 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 1301 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
1313 | break; | 1302 | break; |
1314 | } | 1303 | } |
1304 | unlock_kernel(); | ||
1315 | #else | 1305 | #else |
1316 | /* | 1306 | /* |
1317 | * For the other coldfire models, assume all data has been sent | 1307 | * For the other coldfire models, assume all data has been sent |
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c index 3123ffeac8ad..81ac9bb4f39b 100644 --- a/drivers/serial/netx-serial.c +++ b/drivers/serial/netx-serial.c | |||
@@ -287,6 +287,7 @@ static void netx_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
287 | { | 287 | { |
288 | unsigned int val; | 288 | unsigned int val; |
289 | 289 | ||
290 | /* FIXME: Locking needed ? */ | ||
290 | if (mctrl & TIOCM_RTS) { | 291 | if (mctrl & TIOCM_RTS) { |
291 | val = readl(port->membase + UART_RTS_CR); | 292 | val = readl(port->membase + UART_RTS_CR); |
292 | writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR); | 293 | writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR); |