From: Guy Martin Date: Wed, 29 Dec 2004 00:14:11 +0000 (+0000) Subject: Removed hppa-dev-sources. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=e5c2ac12417009e858555040b71965a8c22e1583;p=gentoo.git Removed hppa-dev-sources. --- diff --git a/sys-kernel/hppa-dev-sources/ChangeLog b/sys-kernel/hppa-dev-sources/ChangeLog deleted file mode 100644 index 84bd54017fdf..000000000000 --- a/sys-kernel/hppa-dev-sources/ChangeLog +++ /dev/null @@ -1,155 +0,0 @@ -# ChangeLog for sys-kernel/hppa-dev-sources -# Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-dev-sources/ChangeLog,v 1.26 2004/12/09 13:56:35 gmsoft Exp $ - - 09 Dec 2004; Guy Martin files/CAN-2004-1074.patch: - Fixed patch of CAN-2004-1074 (#73896). - -*hppa-dev-sources-2.6.8.1_p11-r2 (08 Dec 2004) - - 08 Dec 2004; Guy Martin +files/AF_UNIX-security.patch, - +files/CAN-2004-0814-r1.patch, +files/CAN-2004-1074.patch, - +hppa-dev-sources-2.6.8.1_p11-r2.ebuild: - Security fixes (#68421, #72317, #72452). - -*hppa-dev-sources-2.6.8.1_p11-r1 (24 Nov 2004) - - 24 Nov 2004; Guy Martin +files/CAN-2004-0814.patch, - +files/CAN-2004-0883.patch, +files/binfmt_elf-loader-security.patch, - +files/ptmx-security.patch, +hppa-dev-sources-2.6.8.1_p11-r1.ebuild: - Various security fixes (#70681, #65877, #68421, #62524). - -*hppa-dev-sources-2.6.8.1_p11 (01 Oct 2004) - - 01 Oct 2004; Mike Frysinger - +hppa-dev-sources-2.6.8.1_p11.ebuild: - Version bump to fix strace bugs with 2.6.8.1-pa7. - -*hppa-dev-sources-2.6.8.1_p7 (31 Aug 2004) - - 31 Aug 2004; Guy Martin - +hppa-dev-sources-2.6.8.1_p7.ebuild: - Version bump. - -*hppa-dev-sources-2.6.8.1_p4 (17 Aug 2004) - - 17 Aug 2004; Guy Martin - +hppa-dev-sources-2.6.8.1_p4.ebuild: - Version bump. - -*hppa-dev-sources-2.6.7_p14-r1 (09 Aug 2004) - - 09 Aug 2004; Guy Martin +files/CAN-2004-0596.patch, - +files/firmware.c.patch, +files/security-proc-cmdline.patch, - +hppa-dev-sources-2.6.7_p14-r1.ebuild: - Added security fixes (see #57826, #59378 and #59905). Fix firmware.c. - -*hppa-dev-sources-2.6.7_p14 (24 Jul 2004) - - 24 Jul 2004; Mike Frysinger - +hppa-dev-sources-2.6.7_p14.ebuild: - Version bump. - -*hppa-dev-sources-2.6.7_p1-r2 (09 Jul 2004) - - 09 Jul 2004; Guy Martin - hppa-dev-sources-2.6.6_p4-r1.ebuild, hppa-dev-sources-2.6.7_p1-r1.ebuild, - hppa-dev-sources-2.6.7_p1-r2.ebuild, hppa-dev-sources-2.6.7_p1.ebuild, - files/CAN-2004-0497.patch: - CAN-2004-0497 fix. Removed old ebuild. - -*hppa-dev-sources-2.6.7_p1-r1 (03 Jul 2004) - - 03 Jul 2004; Guy Martin - hppa-dev-sources-2.6.7_p1-r1.ebuild, files/CAN-2004-0626-death_packet.patch: - CAN-2004-0626 fix (#55694). - -*hppa-dev-sources-2.6.7_p1 (23 Jun 2004) - - 23 Jun 2004; Guy Martin - hppa-dev-sources-2.6.7_p1.ebuild: - Version bump. ~hppa because of some ipv6 problems. - -*hppa-dev-sources-2.6.6_p4-r1 (22 Jun 2004) - - 22 Jun 2004; Guy Martin - hppa-dev-sources-2.6.5_p2.ebuild, hppa-dev-sources-2.6.5_p6.ebuild, - hppa-dev-sources-2.6.5_p8.ebuild, hppa-dev-sources-2.6.6_p4-r1.ebuild, - hppa-dev-sources-2.6.6_p4.ebuild, files/ncr53c8xx.diff: - Removed old versions. Added the ncr53c8xx patch. - -*hppa-dev-sources-2.6.6_p4-r1 (22 Jun 2004) - - 22 Jun 2004; Guy Martin - hppa-dev-sources-2.6.5_p2.ebuild, hppa-dev-sources-2.6.5_p6.ebuild, - hppa-dev-sources-2.6.5_p8.ebuild, hppa-dev-sources-2.6.6_p4-r1.ebuild, - hppa-dev-sources-2.6.6_p4.ebuild, files/ncr53c8xx.diff: - Removed old versions. Added the ncr53c8xx patch. - -*hppa-dev-sources-2.6.6_p4 (18 May 2004) - - 18 May 2004; Guy Martin - hppa-dev-sources-2.6.6_p4.ebuild: - Version bump. - -*hppa-dev-sources-2.6.5_p8 (20 Apr 2004) - - 20 Apr 2004; Guy Martin - hppa-dev-sources-2.6.5_p8.ebuild: - Version bump. Speedup fork() and exec(). - -*hppa-dev-sources-2.6.5_p6 (12 Apr 2004) - - 12 Apr 2004; Mike Frysinger - Version bump. - -*hppa-dev-sources-2.6.5_p2 (05 Apr 2004) - - 05 Apr 2004; Mike Frysinger - Version bump. - -*hppa-dev-sources-2.6.4_p2 (01 Apr 2004) - - 01 Apr 2004; Mike Frysinger - Version bump. - -*hppa-dev-sources-2.6.3_p0 (20 Feb 2004) - - 20 Feb 2004; Mike Frysinger - Version bump. - -*hppa-dev-sources-2.6.2_p3-r1 (18 Feb 2004) - - 18 Feb 2004; hppa-dev-sources-2.6.2_p3-r1.ebuild, - files/hppa-dev-sources-2.6.2_p3.munmap.patch: - Added the patch for the mremap/munmap vulnerability. Bug #42024. - -*hppa-dev-sources-2.6.2_p3 (05 Feb 2004) - - 05 Feb 02004; Guy Martin hppa-dev-sources-2.6.2_p3.ebuild : - Version bump. - -*hppa-dev-sources-2.6.1_p8 (21 Jan 2004) - - 21 Jan 2004; Mike Frysinger hppa-dev-sources-2.6.1_p8.ebuild : - Version bump. - -*hppa-dev-sources-2.6.1_p2 (14 Jan 2004) - - 14 Jan 2004; Guy Martin hppa-dev-sources-2.6.1_p2.ebuild : - Version bump. - -*hppa-dev-sources-2.6.1_p1 (12 Jan 2004) - - 12 Jan 2004; Guy Martin hppa-dev-sources-2.6.1_p1.ebuild : - Version bump. - -*hppa-dev-sources-2.6.0_p8 (09 Jan 2004) - - 09 Jan 2004; Guy Martin hppa-dev-sources-2.6.0_p8.ebuild : - Initial Import. - -*hppa-dev-sources-2.6.0_beta11-r4 (09 Jan 2004) - 09 Jan 2004; Guy Martin hppa-dev-sources-2.6.0_beta11-r4 : - Initial Import. - diff --git a/sys-kernel/hppa-dev-sources/Manifest b/sys-kernel/hppa-dev-sources/Manifest deleted file mode 100644 index 134325a6f146..000000000000 --- a/sys-kernel/hppa-dev-sources/Manifest +++ /dev/null @@ -1,27 +0,0 @@ -MD5 7adcd9be5a6894593ffe83d0d01e60d7 ChangeLog 5080 -MD5 ae5609d9bd55ed7d9792b7b86da4df6b hppa-dev-sources-2.6.7_p1-r2.ebuild 1180 -MD5 73864d24b030876a0f811d73fdbf556c hppa-dev-sources-2.6.7_p14-r1.ebuild 1449 -MD5 05bef7ac2c9a5cdf016c4be6f71d034b hppa-dev-sources-2.6.7_p14.ebuild 1176 -MD5 109cb26368a56cea9cf1d1210cb3e857 hppa-dev-sources-2.6.8.1_p11-r1.ebuild 1274 -MD5 f1b3ae515c1f32812ecbf25193148a90 metadata.xml 223 -MD5 e659a5ccd8cb4f1630eb94a992053474 hppa-dev-sources-2.6.8.1_p11.ebuild 1098 -MD5 db64518ef707a3ac3558971110dc3e7f hppa-dev-sources-2.6.8.1_p11-r2.ebuild 1361 -MD5 b6e38b41c8a79943df2ab2642149d06f files/CAN-2004-0497.patch 2214 -MD5 f0e12ba218f53c2694a91259bdc2fdc7 files/CAN-2004-0596.patch 494 -MD5 c91330cc5b4044b6f59696095c2dc0fb files/CAN-2004-0626-death_packet.patch 423 -MD5 ce5fc85224c09cf512dc725ee88945e4 files/digest-hppa-dev-sources-2.6.7_p1-r2 129 -MD5 2dfffb2597dfa71f526d15fdb55ce4f8 files/digest-hppa-dev-sources-2.6.7_p14 130 -MD5 2c3b568f5f12b140ab983b53543bca15 files/digest-hppa-dev-sources-2.6.7_p14-r1 206 -MD5 154a348c46bdd0a33b20d3bbfb5e2a3b files/CAN-2004-0814.patch 131240 -MD5 452e04a312368605e145428c35bd0e05 files/ptmx-security.patch 572 -MD5 8165de5e2ab6e0d3263ea35ce856fd1b files/CAN-2004-0883.patch 3309 -MD5 b36a855496ce31ee483358985b3a409c files/firmware.c.patch 3604 -MD5 c857b174f7e6a6b0ab2e26f9306ad0a0 files/ncr53c8xx.diff 3701 -MD5 222e890035f4ad3152f0c2a625a9ea67 files/security-proc-cmdline.patch 693 -MD5 00d36aabec0074afff01d252833fdcd0 files/digest-hppa-dev-sources-2.6.8.1_p11 133 -MD5 1ee8ba8362089c31fdd7d88b32eaf63e files/binfmt_elf-loader-security.patch 1938 -MD5 00d36aabec0074afff01d252833fdcd0 files/digest-hppa-dev-sources-2.6.8.1_p11-r1 133 -MD5 ef54ffd1bb8629f1a948afa9ff83d8a0 files/CAN-2004-0814-r1.patch 130187 -MD5 b0a1f80aff51d6601e8924329023b241 files/AF_UNIX-security.patch 515 -MD5 e5e5fab00c59854df1d816400a747728 files/CAN-2004-1074.patch 1878 -MD5 00d36aabec0074afff01d252833fdcd0 files/digest-hppa-dev-sources-2.6.8.1_p11-r2 133 diff --git a/sys-kernel/hppa-dev-sources/files/AF_UNIX-security.patch b/sys-kernel/hppa-dev-sources/files/AF_UNIX-security.patch deleted file mode 100644 index 6ced78404a2d..000000000000 --- a/sys-kernel/hppa-dev-sources/files/AF_UNIX-security.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- linux-2.4.27/net/unix/af_unix.c 2004-11-24 08:23:21 -08:00 -+++ linux-2.4.28/net/unix/af_unix.c 2004-11-24 08:23:21 -08:00 -@@ -1403,9 +1403,11 @@ - - msg->msg_namelen = 0; - -+ down(&sk->protinfo.af_unix.readsem); -+ - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) -- goto out; -+ goto out_unlock; - - wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); - -@@ -1449,6 +1451,8 @@ - - out_free: - skb_free_datagram(sk,skb); -+out_unlock: -+ up(&sk->protinfo.af_unix.readsem); - out: - return err; - } diff --git a/sys-kernel/hppa-dev-sources/files/CAN-2004-0497.patch b/sys-kernel/hppa-dev-sources/files/CAN-2004-0497.patch deleted file mode 100644 index 1e4ba6f7601a..000000000000 --- a/sys-kernel/hppa-dev-sources/files/CAN-2004-0497.patch +++ /dev/null @@ -1,75 +0,0 @@ -# This is a BitKeeper generated diff -Nru style patch. -# -# ChangeSet -# 2004/07/02 20:55:04-07:00 chrisw@osdl.org -# [PATCH] chown permission check fix for ATTR_GID -# -# SuSE discovered this problem with chown and ATTR_GID. Make sure user -# is authorized to change the group, CAN-2004-0497. -# -# fs/attr.c -# 2004/07/02 09:07:32-07:00 chrisw@osdl.org +2 -1 -# chown permission check fix for ATTR_GID -# -diff -Nru a/fs/attr.c b/fs/attr.c ---- a/fs/attr.c 2004-07-08 16:35:57 -07:00 -+++ b/fs/attr.c 2004-07-08 16:35:57 -07:00 -@@ -35,7 +35,8 @@ - - /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && -- (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid) && -+ (current->fsuid != inode->i_uid || -+ (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) && - !capable(CAP_CHOWN)) - goto error; - -# This is a BitKeeper generated diff -Nru style patch. -# -# ChangeSet -# 2004/07/02 18:48:26-07:00 chrisw@osdl.org -# [PATCH] check attr updates in /proc -# -# Any proc entry with default proc_file_inode_operations allow unauthorized -# attribute updates. This is very dangerous for proc entries that rely -# solely on file permissions for open/read/write. -# -# Signed-off-by: Chris Wright -# Signed-off-by: Linus Torvalds -# -# fs/proc/generic.c -# 2004/07/02 15:47:55-07:00 chrisw@osdl.org +14 -7 -# check attr updates in /proc -# -diff -Nru a/fs/proc/generic.c b/fs/proc/generic.c ---- a/fs/proc/generic.c 2004-07-08 17:03:20 -07:00 -+++ b/fs/proc/generic.c 2004-07-08 17:03:20 -07:00 -@@ -231,14 +231,21 @@ - static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) - { - struct inode *inode = dentry->d_inode; -- int error = inode_setattr(inode, iattr); -- if (!error) { -- struct proc_dir_entry *de = PDE(inode); -- de->uid = inode->i_uid; -- de->gid = inode->i_gid; -- de->mode = inode->i_mode; -- } -+ struct proc_dir_entry *de = PDE(inode); -+ int error; - -+ error = inode_change_ok(inode, iattr); -+ if (error) -+ goto out; -+ -+ error = inode_setattr(inode, iattr); -+ if (error) -+ goto out; -+ -+ de->uid = inode->i_uid; -+ de->gid = inode->i_gid; -+ de->mode = inode->i_mode; -+out: - return error; - } - diff --git a/sys-kernel/hppa-dev-sources/files/CAN-2004-0596.patch b/sys-kernel/hppa-dev-sources/files/CAN-2004-0596.patch deleted file mode 100644 index 8ea0f0488310..000000000000 --- a/sys-kernel/hppa-dev-sources/files/CAN-2004-0596.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- drivers/net/eql.c.ori 2004-07-22 12:46:56.103576048 +0200 -+++ drivers/net/eql.c 2004-07-22 12:46:59.068125368 +0200 -@@ -497,6 +497,8 @@ - slave_dev = dev_get_by_name(sc.slave_name); - - ret = -EINVAL; -+ if (!slave_dev) -+ return ret; - - spin_lock_bh(&eql->queue.lock); - if (eql_is_slave(slave_dev)) { -@@ -531,6 +533,8 @@ - slave_dev = dev_get_by_name(sc.slave_name); - - ret = -EINVAL; -+ if (!slave_dev) -+ return ret; - - spin_lock_bh(&eql->queue.lock); - if (eql_is_slave(slave_dev)) { diff --git a/sys-kernel/hppa-dev-sources/files/CAN-2004-0626-death_packet.patch b/sys-kernel/hppa-dev-sources/files/CAN-2004-0626-death_packet.patch deleted file mode 100644 index f6eafac10930..000000000000 --- a/sys-kernel/hppa-dev-sources/files/CAN-2004-0626-death_packet.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- net/ipv4/netfilter/ip_tables.c.orig 2004-06-30 18:19:22.957763360 -0400 -+++ net/ipv4/netfilter/ip_tables.c 2004-06-30 18:19:51.516421784 -0400 -@@ -1458,7 +1458,7 @@ tcp_find_option(u_int8_t option, - int *hotdrop) - { - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ -- char opt[60 - sizeof(struct tcphdr)]; -+ u_int8_t opt[60 - sizeof(struct tcphdr)]; - unsigned int i; - - duprintf("tcp_match: finding option\n"); diff --git a/sys-kernel/hppa-dev-sources/files/CAN-2004-0814-r1.patch b/sys-kernel/hppa-dev-sources/files/CAN-2004-0814-r1.patch deleted file mode 100644 index 496654d0365c..000000000000 --- a/sys-kernel/hppa-dev-sources/files/CAN-2004-0814-r1.patch +++ /dev/null @@ -1,4370 +0,0 @@ -diff -Naur linux-2.6.8.orig/Documentation/tty.txt linux-2.6.8/Documentation/tty.txt ---- linux-2.6.8.orig/Documentation/tty.txt 1969-12-31 16:00:00.000000000 -0800 -+++ linux-2.6.8/Documentation/tty.txt 2004-11-28 04:49:42.182497442 -0800 -@@ -0,0 +1,194 @@ -+ -+ The Lockronomicon -+ -+Your guide to the ancient and twisted locking policies of the tty layer and -+the warped logic behind them. Beware all ye who read on. -+ -+FIXME: still need to work out the full set of BKL assumptions and document -+them so they can eventually be killed off. -+ -+ -+Line Discipline -+--------------- -+ -+Line disciplines are registered with tty_register_ldisc() passing the -+discipline number and the ldisc structure. At the point of registration the -+discipline must be ready to use and it is possible it will get used before -+the call returns success. If the call returns an error then it won't get -+called. Do not re-use ldisc numbers as they are part of the userspace ABI -+and writing over an existing ldisc will cause demons to eat your computer. -+After the return the ldisc data has been copied so you may free your own -+copy of the structure. You must not re-register over the top of the line -+discipline even with the same data or your computer again will be eaten by -+demons. -+ -+In order to remove a line discipline call tty_register_ldisc passing NULL. -+In ancient times this always worked. In modern times the function will -+return -EBUSY if the ldisc is currently in use. Since the ldisc referencing -+code manages the module counts this should not usually be a concern. -+ -+Heed this warning: the reference count field of the registered copies of the -+tty_ldisc structure in the ldisc table counts the number of lines using this -+discipline. The reference count of the tty_ldisc structure within a tty -+counts the number of active users of the ldisc at this instant. In effect it -+counts the number of threads of execution within an ldisc method (plus those -+about to enter and exit although this detail matters not). -+ -+Line Discipline Methods -+----------------------- -+ -+TTY side interfaces: -+ -+close() - This is called on a terminal when the line -+ discipline is being unplugged. At the point of -+ execution no further users will enter the -+ ldisc code for this tty. Can sleep. -+ -+open() - Called when the line discipline is attached to -+ the terminal. No other call into the line -+ discipline for this tty will occur until it -+ completes successfully. Can sleep. -+ -+write() - A process is writing data from user space -+ through the line discipline. Multiple write calls -+ are serialized by the tty layer for the ldisc. May -+ sleep. -+ -+flush_buffer() - May be called at any point between open and close. -+ -+chars_in_buffer() - Report the number of bytes in the buffer. -+ -+set_termios() - Called on termios structure changes. The caller -+ passes the old termios data and the current data -+ is in the tty. Called under the termios lock so -+ may not sleep. Serialized against itself only. -+ -+read() - Move data from the line discipline to the user. -+ Multiple read calls may occur in parallel and the -+ ldisc must deal with serialization issues. May -+ sleep. -+ -+poll() - Check the status for the poll/select calls. Multiple -+ poll calls may occur in parallel. May sleep. -+ -+ioctl() - Called when an ioctl is handed to the tty layer -+ that might be for the ldisc. Multiple ioctl calls -+ may occur in parallel. May sleep. -+ -+Driver Side Interfaces: -+ -+receive_buf() - Hand buffers of bytes from the driver to the ldisc -+ for processing. Semantics currently rather -+ mysterious 8( -+ -+receive_room() - Can be called by the driver layer at any time when -+ the ldisc is opened. The ldisc must be able to -+ handle the reported amount of data at that instant. -+ Synchronization between active receive_buf and -+ receive_room calls is down to the driver not the -+ ldisc. Must not sleep. -+ -+write_wakeup() - May be called at any point between open and close. -+ The TTY_DO_WRITE_WAKEUP flag indicates if a call -+ is needed but always races versus calls. Thus the -+ ldisc must be careful about setting order and to -+ handle unexpected calls. Must not sleep. -+ -+ -+Locking -+ -+Callers to the line discipline functions from the tty layer are required to -+take line discipline locks. The same is true of calls from the driver side -+but not yet enforced. -+ -+Three calls are now provided -+ -+ ldisc = tty_ldisc_ref(tty); -+ -+takes a handle to the line discipline in the tty and returns it. If no ldisc -+is currently attached or the ldisc is being closed and re-opened at this -+point then NULL is returned. While this handle is held the ldisc will not -+change or go away. -+ -+ tty_ldisc_deref(ldisc) -+ -+Returns the ldisc reference and allows the ldisc to be closed. Returning the -+reference takes away your right to call the ldisc functions until you take -+a new reference. -+ -+ ldisc = tty_ldisc_ref_wait(tty); -+ -+Performs the same function as tty_ldisc_ref except that it will wait for an -+ldisc change to complete and then return a reference to the new ldisc. -+ -+While these functions are slightly slower than the old code they should have -+minimal impact as most receive logic uses the flip buffers and they only -+need to take a reference when they push bits up through the driver. -+ -+A caution: The ldisc->open(), ldisc->close() and driver->set_ldisc -+functions are called with the ldisc unavailable. Thus tty_ldisc_ref will -+fail in this situation if used within these functions. Ldisc and driver -+code calling its own functions must be careful in this case. -+ -+ -+Driver Interface -+---------------- -+ -+open() - Called when a device is opened. May sleep -+ -+close() - Called when a device is closed. At the point of -+ return from this call the driver must make no -+ further ldisc calls of any kind. May sleep -+ -+write() - Called to write bytes to the device. May not -+ sleep. May occur in parallel in special cases. -+ Because this includes panic paths drivers generally -+ shouldn't try and do clever locking here. -+ -+put_char() - Stuff a single character onto the queue. The -+ driver is guaranteed following up calls to -+ flush_chars. -+ -+flush_chars() - Ask the kernel to write put_char queue -+ -+write_room() - Return the number of characters tht can be stuffed -+ into the port buffers without overflow (or less). -+ The ldisc is responsible for being intelligent -+ about multi-threading of write_room/write calls -+ -+ioctl() - Called when an ioctl may be for the driver -+ -+set_termios() - Called on termios change, may get parallel calls, -+ may block for now (may change that) -+ -+set_ldisc() - Notifier for discipline change. At the point this -+ is done the discipline is not yet usable. Can now -+ sleep (I think) -+ -+throttle() - Called by the ldisc to ask the driver to do flow -+ control. Serialization including with unthrottle -+ is the job of the ldisc layer. -+ -+unthrottle() - Called by the ldisc to ask the driver to stop flow -+ control. -+ -+stop() - Ldisc notifier to the driver to stop output. As with -+ throttle the serializations with start() are down -+ to the ldisc layer. -+ -+start() - Ldisc notifier to the driver to start output. -+ -+hangup() - Ask the tty driver to cause a hangup initiated -+ from the host side. [Can sleep ??] -+ -+break_ctl() - Send RS232 break. Can sleep. Can get called in -+ parallel, driver must serialize (for now), and -+ with write calls. -+ -+wait_until_sent() - Wait for characters to exit the hardware queue -+ of the driver. Can sleep -+ -+send_xchar() - Send XON/XOFF and if possible jump the queue with -+ it in order to get fast flow control responses. -+ Cannot sleep ?? -+ -diff -Naur linux-2.6.8.orig/drivers/bluetooth/hci_ldisc.c linux-2.6.8/drivers/bluetooth/hci_ldisc.c ---- linux-2.6.8.orig/drivers/bluetooth/hci_ldisc.c 2004-08-13 22:37:38.000000000 -0700 -+++ linux-2.6.8/drivers/bluetooth/hci_ldisc.c 2004-11-28 04:49:42.192495818 -0800 -@@ -188,9 +188,7 @@ - } - - /* Flush any pending characters in the driver and discipline. */ -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ tty_ldisc_flush(tty); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - -@@ -280,7 +278,9 @@ - - spin_lock_init(&hu->rx_lock); - -- /* Flush any pending characters in the driver and line discipline */ -+ /* Flush any pending characters in the driver and line discipline. */ -+ /* FIXME: why is this needed. Note don't use ldisc_ref here as the -+ open path is before the ldisc is referencable */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - -diff -Naur linux-2.6.8.orig/drivers/char/amiserial.c linux-2.6.8/drivers/char/amiserial.c ---- linux-2.6.8.orig/drivers/char/amiserial.c 2004-08-13 22:38:10.000000000 -0700 -+++ linux-2.6.8/drivers/char/amiserial.c 2004-11-28 04:49:42.210492894 -0800 -@@ -557,9 +557,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -1023,9 +1021,7 @@ - info->xmit.head = info->xmit.tail = 0; - local_irq_restore(flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1564,8 +1560,8 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Naur linux-2.6.8.orig/drivers/char/cyclades.c linux-2.6.8/drivers/char/cyclades.c ---- linux-2.6.8.orig/drivers/char/cyclades.c 2004-08-13 22:36:32.000000000 -0700 -+++ linux-2.6.8/drivers/char/cyclades.c 2004-11-28 04:49:42.227490132 -0800 -@@ -970,10 +970,7 @@ - wake_up_interruptible(&info->delta_msr_wait); - } - if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { -- if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup){ -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - #ifdef Z_WAKE -@@ -2850,8 +2847,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - CY_LOCK(info, flags); - - tty->closing = 0; -@@ -4554,10 +4550,8 @@ - } - CY_UNLOCK(info, flags); - } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); - } /* cy_flush_buffer */ - - -diff -Naur linux-2.6.8.orig/drivers/char/epca.c linux-2.6.8/drivers/char/epca.c ---- linux-2.6.8.orig/drivers/char/epca.c 2004-08-13 22:37:14.000000000 -0700 -+++ linux-2.6.8/drivers/char/epca.c 2004-11-28 04:49:42.279481685 -0800 -@@ -551,9 +551,7 @@ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ tty_ldisc_flush(tty); - shutdown(ch); - tty->closing = 0; - ch->event = 0; -@@ -657,10 +655,7 @@ - cli(); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ tty_ldisc_flush(tty); - shutdown(ch); - - ch->tty = NULL; -@@ -1120,8 +1115,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - - } /* End pc_flush_buffer */ - -@@ -2262,9 +2256,7 @@ - { /* Begin if LOWWAIT */ - - ch->statusflags &= ~LOWWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - - } /* End if LOWWAIT */ -@@ -2281,9 +2273,7 @@ - { /* Begin if EMPTYWAIT */ - - ch->statusflags &= ~EMPTYWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - - wake_up_interruptible(&tty->write_wait); - -@@ -3136,6 +3126,7 @@ - } - else - { -+ /* ldisc lock already held in ioctl */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - } -diff -Naur linux-2.6.8.orig/drivers/char/esp.c linux-2.6.8/drivers/char/esp.c ---- linux-2.6.8.orig/drivers/char/esp.c 2004-08-13 22:36:11.000000000 -0700 -+++ linux-2.6.8/drivers/char/esp.c 2004-11-28 04:49:42.304477623 -0800 -@@ -762,10 +762,7 @@ - return; - - if (test_and_clear_bit(ESP_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1370,10 +1367,7 @@ - cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -2069,8 +2063,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = NULL; -diff -Naur linux-2.6.8.orig/drivers/char/generic_serial.c linux-2.6.8/drivers/char/generic_serial.c ---- linux-2.6.8.orig/drivers/char/generic_serial.c 2004-08-13 22:36:58.000000000 -0700 -+++ linux-2.6.8/drivers/char/generic_serial.c 2004-11-28 04:49:42.350470151 -0800 -@@ -436,9 +436,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - func_exit (); - } - -@@ -578,9 +576,7 @@ - if (!tty) return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - func_exit (); -@@ -694,8 +690,8 @@ - { - unsigned long flags; - struct gs_port *port; -- -- func_enter (); -+ -+ func_enter () - - if (!tty) return; - -@@ -760,8 +756,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - - port->event = 0; -diff -Naur linux-2.6.8.orig/drivers/char/hvc_console.c linux-2.6.8/drivers/char/hvc_console.c ---- linux-2.6.8.orig/drivers/char/hvc_console.c 2004-08-13 22:37:39.000000000 -0700 -+++ linux-2.6.8/drivers/char/hvc_console.c 2004-11-28 04:49:42.381465115 -0800 -@@ -248,10 +248,7 @@ - - if (hp->do_wakeup) { - hp->do_wakeup = 0; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Naur linux-2.6.8.orig/drivers/char/hvcs.c linux-2.6.8/drivers/char/hvcs.c ---- linux-2.6.8.orig/drivers/char/hvcs.c 2004-08-13 22:37:14.000000000 -0700 -+++ linux-2.6.8/drivers/char/hvcs.c 2004-11-28 04:49:42.385464465 -0800 -@@ -393,10 +393,7 @@ - * a non-existent tty. - */ - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - } -diff -Naur linux-2.6.8.orig/drivers/char/isicom.c linux-2.6.8/drivers/char/isicom.c ---- linux-2.6.8.orig/drivers/char/isicom.c 2004-08-13 22:36:12.000000000 -0700 -+++ linux-2.6.8/drivers/char/isicom.c 2004-11-28 04:49:42.424458129 -0800 -@@ -484,10 +484,8 @@ - - if (!tty) - return; -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -1119,8 +1117,8 @@ - isicom_shutdown_port(port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - port->tty = NULL; - if (port->blocked_open) { -@@ -1563,9 +1561,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - -diff -Naur linux-2.6.8.orig/drivers/char/moxa.c linux-2.6.8/drivers/char/moxa.c ---- linux-2.6.8.orig/drivers/char/moxa.c 2004-08-13 22:38:04.000000000 -0700 -+++ linux-2.6.8/drivers/char/moxa.c 2004-11-28 04:49:42.445454718 -0800 -@@ -618,8 +618,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - ch->event = 0; - ch->tty = NULL; -@@ -693,9 +693,7 @@ - if (ch == NULL) - return; - MoxaPortFlushData(ch->port, 1); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -954,9 +952,7 @@ - if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) { - if (!tp->stopped) { - ch->statusflags &= ~LOWWAIT; -- if ((tp->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tp->ldisc.write_wakeup) -- (tp->ldisc.write_wakeup) (tp); -+ tty_wakeup(tty); - wake_up_interruptible(&tp->write_wait); - } - } -@@ -1123,9 +1119,7 @@ - if (ch->tty && (ch->statusflags & EMPTYWAIT)) { - if (MoxaPortTxQueue(ch->port) == 0) { - ch->statusflags &= ~EMPTYWAIT; -- if ((ch->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- ch->tty->ldisc.write_wakeup) -- (ch->tty->ldisc.write_wakeup) (ch->tty); -+ tty_wakeup(tty); - wake_up_interruptible(&ch->tty->write_wait); - return; - } -diff -Naur linux-2.6.8.orig/drivers/char/mxser.c linux-2.6.8/drivers/char/mxser.c ---- linux-2.6.8.orig/drivers/char/mxser.c 2004-08-13 22:37:26.000000000 -0700 -+++ linux-2.6.8/drivers/char/mxser.c 2004-11-28 04:49:42.456452931 -0800 -@@ -678,9 +678,7 @@ - tty = info->tty; - if (tty) { - if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event)) { -@@ -817,8 +815,8 @@ - mxser_shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - info->event = 0; - info->tty = NULL; -@@ -976,9 +974,7 @@ - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - } - - static int mxser_ioctl(struct tty_struct *tty, struct file *file, -diff -Naur linux-2.6.8.orig/drivers/char/n_tty.c linux-2.6.8/drivers/char/n_tty.c ---- linux-2.6.8.orig/drivers/char/n_tty.c 2004-08-13 22:36:11.000000000 -0700 -+++ linux-2.6.8/drivers/char/n_tty.c 2004-11-28 04:49:42.469450819 -0800 -@@ -99,11 +99,18 @@ - spin_unlock_irqrestore(&tty->read_lock, flags); - } - --/* -- * Check whether to call the driver.unthrottle function. -- * We test the TTY_THROTTLED bit first so that it always -- * indicates the current state. -+/** -+ * check_unthrottle - allow new receive data -+ * @tty; tty device -+ * -+ * Check whether to call the driver.unthrottle function. -+ * We test the TTY_THROTTLED bit first so that it always -+ * indicates the current state. The decision about whether -+ * it is worth allowing more input has been taken by the caller. -+ * Can sleep, may be called under the atomic_read semaphore but -+ * this is not guaranteed. - */ -+ - static void check_unthrottle(struct tty_struct * tty) - { - if (tty->count && -@@ -112,10 +119,13 @@ - tty->driver->unthrottle(tty); - } - --/* -- * Reset the read buffer counters, clear the flags, -- * and make sure the driver is unthrottled. Called -- * from n_tty_open() and n_tty_flush_buffer(). -+/** -+ * reset_buffer_flags - reset buffer state -+ * @tty: terminal to reset -+ * -+ * Reset the read buffer counters, clear the flags, -+ * and make sure the driver is unthrottled. Called -+ * from n_tty_open() and n_tty_flush_buffer(). - */ - static void reset_buffer_flags(struct tty_struct *tty) - { -@@ -129,9 +139,19 @@ - check_unthrottle(tty); - } - --/* -- * Flush the input buffer -+/** -+ * n_tty_flush_buffer - clean input queue -+ * @tty: terminal device -+ * -+ * Flush the input buffer. Called when the line discipline is -+ * being closed, when the tty layer wants the buffer flushed (eg -+ * at hangup) or when the N_TTY line discipline internally has to -+ * clean the pending queue (for example some signals). -+ * -+ * FIXME: tty->ctrl_status is not spinlocked and relies on -+ * lock_kernel() still. - */ -+ - void n_tty_flush_buffer(struct tty_struct * tty) - { - /* clear everything and unthrottle the driver */ -@@ -146,9 +166,14 @@ - } - } - --/* -- * Return number of characters buffered to be delivered to user -+/** -+ * n_tty_chars_in_buffer - report available bytes -+ * @tty: tty device -+ * -+ * Report the number of characters buffered to be delivered to user -+ * at this instant in time. - */ -+ - ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) - { - unsigned long flags; -@@ -166,20 +191,47 @@ - return n; - } - -+/** -+ * is_utf8_continuation - utf8 multibyte check -+ * @c: byte to check -+ * -+ * Returns true if the utf8 character 'c' is a multibyte continuation -+ * character. We use this to correctly compute the on screen size -+ * of the character when printing -+ */ -+ - static inline int is_utf8_continuation(unsigned char c) - { - return (c & 0xc0) == 0x80; - } - -+/** -+ * is_continuation - multibyte check -+ * @c: byte to check -+ * -+ * Returns true if the utf8 character 'c' is a multibyte continuation -+ * character and the terminal is in unicode mode. -+ */ -+ - static inline int is_continuation(unsigned char c, struct tty_struct *tty) - { - return I_IUTF8(tty) && is_utf8_continuation(c); - } - --/* -- * Perform OPOST processing. Returns -1 when the output device is -- * full and the character must be retried. -+/** -+ * opost - output post processor -+ * @c: character (or partial unicode symbol) -+ * @tty: terminal device -+ * -+ * Perform OPOST processing. Returns -1 when the output device is -+ * full and the character must be retried. Note that Linux currently -+ * ignores TABDLY, CRDLY, VTDLY, FFDLY and NLDLY. They simply aren't -+ * relevant in the world today. If you ever need them, add them here. -+ * -+ * Called from both the receive and transmit sides and can be called -+ * re-entrantly. Relies on lock_kernel() still. - */ -+ - static int opost(unsigned char c, struct tty_struct *tty) - { - int space, spaces; -@@ -239,10 +291,20 @@ - return 0; - } - --/* -- * opost_block --- to speed up block console writes, among other -- * things. -+/** -+ * opost_block - block postprocess -+ * @tty: terminal device -+ * @inbuf: user buffer -+ * @nr: number of bytes -+ * -+ * This path is used to speed up block console writes, among other -+ * things when processing blocks of output data. It handles only -+ * the simple cases normally found and helps to generate blocks of -+ * symbols for the console driver and thus improve performance. -+ * -+ * Called from write_chan under the tty layer write lock. - */ -+ - static ssize_t opost_block(struct tty_struct * tty, - const unsigned char __user * inbuf, unsigned int nr) - { -@@ -304,13 +366,27 @@ - } - - -- -+/** -+ * put_char - write character to driver -+ * @c: character (or part of unicode symbol) -+ * @tty: terminal device -+ * -+ * Queue a byte to the driver layer for output -+ */ -+ - static inline void put_char(unsigned char c, struct tty_struct *tty) - { - tty->driver->put_char(tty, c); - } - --/* Must be called only when L_ECHO(tty) is true. */ -+/** -+ * echo_char - echo characters -+ * @c: unicode byte to echo -+ * @tty: terminal device -+ * -+ * Echo user input back onto the screen. This must be called only when -+ * L_ECHO(tty) is true. Called from the driver receive_buf path. -+ */ - - static void echo_char(unsigned char c, struct tty_struct *tty) - { -@@ -331,6 +407,16 @@ - } - } - -+/** -+ * eraser - handle erase function -+ * @c: character input -+ * @tty: terminal device -+ * -+ * Perform erase and neccessary output when an erase character is -+ * present in the stream from the driver layer. Handles the complexities -+ * of UTF-8 multibyte symbols. -+ */ -+ - static void eraser(unsigned char c, struct tty_struct *tty) - { - enum { ERASE, WERASE, KILL } kill_type; -@@ -463,6 +549,18 @@ - finish_erasing(tty); - } - -+/** -+ * isig - handle the ISIG optio -+ * @sig: signal -+ * @tty: terminal -+ * @flush: force flush -+ * -+ * Called when a signal is being sent due to terminal input. This -+ * may caus terminal flushing to take place according to the termios -+ * settings and character used. Called from the driver receive_buf -+ * path so serialized. -+ */ -+ - static inline void isig(int sig, struct tty_struct *tty, int flush) - { - if (tty->pgrp > 0) -@@ -474,6 +572,16 @@ - } - } - -+/** -+ * n_tty_receive_break - handle break -+ * @tty: terminal -+ * -+ * An RS232 break event has been hit in the incoming bitstream. This -+ * can cause a variety of events depending upon the termios settings. -+ * -+ * Called from the receive_buf path so single threaded. -+ */ -+ - static inline void n_tty_receive_break(struct tty_struct *tty) - { - if (I_IGNBRK(tty)) -@@ -490,19 +598,40 @@ - wake_up_interruptible(&tty->read_wait); - } - -+/** -+ * n_tty_receive_overrun - handle overrun reporting -+ * @tty: terminal -+ * -+ * Data arrived faster than we could process it. While the tty -+ * driver has flagged this the bits that were missed are gone -+ * forever. -+ * -+ * Called from the receive_buf path so single threaded. Does not -+ * need locking as num_overrun and overrun_time are function -+ * private. -+ */ -+ - static inline void n_tty_receive_overrun(struct tty_struct *tty) - { - char buf[64]; - - tty->num_overrun++; - if (time_before(tty->overrun_time, jiffies - HZ)) { -- printk("%s: %d input overrun(s)\n", tty_name(tty, buf), -+ printk(KERN_WARNING "%s: %d input overrun(s)\n", tty_name(tty, buf), - tty->num_overrun); - tty->overrun_time = jiffies; - tty->num_overrun = 0; - } - } - -+/** -+ * n_tty_receive_parity_error - error notifier -+ * @tty: terminal device -+ * @c: character -+ * -+ * Process a parity error and queue the right data to indicate -+ * the error case if neccessary. Locking as per n_tty_receive_buf. -+ */ - static inline void n_tty_receive_parity_error(struct tty_struct *tty, - unsigned char c) - { -@@ -520,6 +649,16 @@ - wake_up_interruptible(&tty->read_wait); - } - -+/** -+ * n_tty_receive_char - perform processing -+ * @tty: terminal device -+ * @c: character -+ * -+ * Process an individual character of input received from the driver. -+ * This is serialized with respect to itself by the rules for the -+ * driver above. -+ */ -+ - static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) - { - unsigned long flags; -@@ -711,6 +850,16 @@ - put_tty_queue(c, tty); - } - -+/** -+ * n_tty_receive_room - receive space -+ * @tty: terminal -+ * -+ * Called by the driver to find out how much data it is -+ * permitted to feed to the line discipline without any being lost -+ * and thus to manage flow control. Not serialized. Answers for the -+ * "instant". -+ */ -+ - static int n_tty_receive_room(struct tty_struct *tty) - { - int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; -@@ -729,10 +878,13 @@ - return 0; - } - --/* -- * Required for the ptys, serial driver etc. since processes -- * that attach themselves to the master and rely on ASYNC -- * IO must be woken up -+/** -+ * n_tty_write_wakeup - asynchronous I/O notifier -+ * @tty: tty device -+ * -+ * Required for the ptys, serial driver etc. since processes -+ * that attach themselves to the master and rely on ASYNC -+ * IO must be woken up - */ - - static void n_tty_write_wakeup(struct tty_struct *tty) -@@ -745,6 +897,19 @@ - return; - } - -+/** -+ * n_tty_receive_buf - data receive -+ * @tty: terminal device -+ * @cp: buffer -+ * @fp: flag buffer -+ * @count: characters -+ * -+ * Called by the terminal driver when a block of characters has -+ * been received. This function must be called from soft contexts -+ * not from interrupt context. The driver is responsible for making -+ * calls one at a time and in order (or using flush_to_ldisc) -+ */ -+ - static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) - { -@@ -828,6 +993,18 @@ - current->sighand->action[sig-1].sa.sa_handler == SIG_IGN); - } - -+/** -+ * n_tty_set_termios - termios data changed -+ * @tty: terminal -+ * @old: previous data -+ * -+ * Called by the tty layer when the user changes termios flags so -+ * that the line discipline can plan ahead. This function cannot sleep -+ * and is protected from re-entry by the tty layer. The user is -+ * guaranteed that this function will not be re-entered or in progress -+ * when the ldisc is closed. -+ */ -+ - static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) - { - if (!tty) -@@ -843,7 +1020,6 @@ - I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) || - I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) || - I_PARMRK(tty)) { -- local_irq_disable(); // FIXME: is this safe? - memset(tty->process_char_map, 0, 256/8); - - if (I_IGNCR(tty) || I_ICRNL(tty)) -@@ -879,7 +1055,6 @@ - set_bit(SUSP_CHAR(tty), tty->process_char_map); - } - clear_bit(__DISABLED_CHAR, tty->process_char_map); -- local_irq_enable(); // FIXME: is this safe? - tty->raw = 0; - tty->real_raw = 0; - } else { -@@ -893,6 +1068,16 @@ - } - } - -+/** -+ * n_tty_close - close the ldisc for this tty -+ * @tty: device -+ * -+ * Called from the terminal layer when this line discipline is -+ * being shut down, either because of a close or becsuse of a -+ * discipline change. The function will not be called while other -+ * ldisc methods are in progress. -+ */ -+ - static void n_tty_close(struct tty_struct *tty) - { - n_tty_flush_buffer(tty); -@@ -902,11 +1087,22 @@ - } - } - -+/** -+ * n_tty_open - open an ldisc -+ * @tty: terminal to open -+ * -+ * Called when this line discipline is being attached to the -+ * terminal device. Can sleep. Called serialized so that no -+ * other events will occur in parallel. No further open will occur -+ * until a close. -+ */ -+ - static int n_tty_open(struct tty_struct *tty) - { - if (!tty) - return -EINVAL; - -+ /* This one is ugly. Currently a malloc failure here can panic */ - if (!tty->read_buf) { - tty->read_buf = alloc_buf(); - if (!tty->read_buf) -@@ -932,14 +1128,23 @@ - return 0; - } - --/* -- * Helper function to speed up read_chan. It is only called when -- * ICANON is off; it copies characters straight from the tty queue to -- * user space directly. It can be profitably called twice; once to -- * drain the space from the tail pointer to the (physical) end of the -- * buffer, and once to drain the space from the (physical) beginning of -- * the buffer to head pointer. -+/** -+ * copy_from_read_buf - copy read data directly -+ * @tty: terminal device -+ * @b: user data -+ * @nr: size of data -+ * -+ * Helper function to speed up read_chan. It is only called when -+ * ICANON is off; it copies characters straight from the tty queue to -+ * user space directly. It can be profitably called twice; once to -+ * drain the space from the tail pointer to the (physical) end of the -+ * buffer, and once to drain the space from the (physical) beginning of -+ * the buffer to head pointer. -+ * -+ * Called under the tty->atomic_read sem and with TTY_DONT_FLIP set -+ * - */ -+ - static inline int copy_from_read_buf(struct tty_struct *tty, - unsigned char __user **b, - size_t *nr) -@@ -970,25 +1175,18 @@ - - extern ssize_t redirected_tty_write(struct file *,const char *,size_t,loff_t *); - --static ssize_t read_chan(struct tty_struct *tty, struct file *file, -- unsigned char __user *buf, size_t nr) -+/** -+ * job_control - check job control -+ * @tty: tty -+ * @file: file handle -+ * -+ * Perform job control management checks on this file/tty descriptor -+ * and if appropriate send any needed signals and return a negative -+ * error code if action should be taken. -+ */ -+ -+static int job_control(struct tty_struct *tty, struct file *file) - { -- unsigned char __user *b = buf; -- DECLARE_WAITQUEUE(wait, current); -- int c; -- int minimum, time; -- ssize_t retval = 0; -- ssize_t size; -- long timeout; -- unsigned long flags; -- --do_it_again: -- -- if (!tty->read_buf) { -- printk("n_tty_read_chan: called with read_buf == NULL?!?\n"); -- return -EIO; -- } -- - /* Job control check -- must be done at start and after - every sleep (POSIX.1 7.1.1.4). */ - /* NOTE: not yet done after every sleep pending a thorough -@@ -1006,7 +1204,48 @@ - return -ERESTARTSYS; - } - } -+ return 0; -+} -+ -+ -+/** -+ * read_chan - read function for tty -+ * @tty: tty device -+ * @file: file object -+ * @buf: userspace buffer pointer -+ * @nr: size of I/O -+ * -+ * Perform reads for the line discipline. We are guaranteed that the -+ * line discipline will not be closed under us but we may get multiple -+ * parallel readers and must handle this ourselves. We may also get -+ * a hangup. Always called in user context, may sleep. -+ * -+ * This code must be sure never to sleep through a hangup. -+ */ -+ -+static ssize_t read_chan(struct tty_struct *tty, struct file *file, -+ unsigned char __user *buf, size_t nr) -+{ -+ unsigned char __user *b = buf; -+ DECLARE_WAITQUEUE(wait, current); -+ int c; -+ int minimum, time; -+ ssize_t retval = 0; -+ ssize_t size; -+ long timeout; -+ unsigned long flags; -+ -+do_it_again: -+ -+ if (!tty->read_buf) { -+ printk("n_tty_read_chan: called with read_buf == NULL?!?\n"); -+ return -EIO; -+ } - -+ c = job_control(tty, file); -+ if(c < 0) -+ return c; -+ - minimum = time = 0; - timeout = MAX_SCHEDULE_TIMEOUT; - if (!tty->icanon) { -@@ -1028,6 +1267,9 @@ - } - } - -+ /* -+ * Internal serialization of reads. -+ */ - if (file->f_flags & O_NONBLOCK) { - if (down_trylock(&tty->atomic_read)) - return -EAGAIN; -@@ -1177,6 +1419,21 @@ - return retval; - } - -+/** -+ * write_chan - write function for tty -+ * @tty: tty device -+ * @file: file object -+ * @buf: userspace buffer pointer -+ * @nr: size of I/O -+ * -+ * Write function of the terminal device. This is serialized with -+ * respect to other write callers but not to termios changes, reads -+ * and other such events. We must be careful with N_TTY as the receive -+ * code will echo characters, thus calling driver write methods. -+ * -+ * This code must be sure never to sleep through a hangup. -+ */ -+ - static ssize_t write_chan(struct tty_struct * tty, struct file * file, - const unsigned char __user * buf, size_t nr) - { -@@ -1246,7 +1503,25 @@ - return (b - buf) ? b - buf : retval; - } - --/* Called without the kernel lock held - fine */ -+/** -+ * normal_poll - poll method for N_TTY -+ * @tty: terminal device -+ * @file: file accessing it -+ * @wait: poll table -+ * -+ * Called when the line discipline is asked to poll() for data or -+ * for special events. This code is not serialized with respect to -+ * other events save open/close. -+ * -+ * This code must be sure never to sleep through a hangup. -+ * Called without the kernel lock held - fine -+ * -+ * FIXME: if someone changes the VMIN or discipline settings for the -+ * terminal while another process is in poll() the poll does not -+ * recompute the new limits. Possibly set_termios should issue -+ * a read wakeup to fix this bug. -+ */ -+ - static unsigned int normal_poll(struct tty_struct * tty, struct file * file, poll_table *wait) - { - unsigned int mask = 0; -@@ -1287,6 +1562,7 @@ - n_tty_ioctl, /* ioctl */ - n_tty_set_termios, /* set_termios */ - normal_poll, /* poll */ -+ NULL, /* hangup */ - n_tty_receive_buf, /* receive_buf */ - n_tty_receive_room, /* receive_room */ - n_tty_write_wakeup /* write_wakeup */ -diff -Naur linux-2.6.8.orig/drivers/char/pcmcia/synclink_cs.c linux-2.6.8/drivers/char/pcmcia/synclink_cs.c ---- linux-2.6.8.orig/drivers/char/pcmcia/synclink_cs.c 2004-08-13 22:36:45.000000000 -0700 -+++ linux-2.6.8/drivers/char/pcmcia/synclink_cs.c 2004-11-28 04:49:42.509444321 -0800 -@@ -531,6 +531,40 @@ - return mgslpc_get_text_ptr; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_flush_buffer - flush line discipline receive buffers -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_flush_buffer(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+} -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - static dev_link_t *mgslpc_attach(void) - { - MGSLPC_INFO *info; -@@ -984,13 +1018,7 @@ - printk("bh_transmit() entry on %s\n", info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):calling ldisc.write_wakeup on %s\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -1875,11 +1903,9 @@ - info->tx_count = info->tx_put = info->tx_get = 0; - del_timer(&info->tx_timer); - spin_unlock_irqrestore(&info->lock,flags); -- -+ - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* Send a high-priority XON/XOFF character -@@ -2588,9 +2614,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ ldisc_flush_buffer(tty); - - shutdown(info); - -@@ -4059,11 +4084,7 @@ - } - else - #endif -- { -- /* Call the line discipline receive callback directly. */ -- if (tty && tty->ldisc.receive_buf) -- tty->ldisc.receive_buf(tty, buf->data, info->flag_buf, framesize); -- } -+ ldisc_receive_buf(tty, buf->data, info->flag_buf, framesize); - } - } - -diff -Naur linux-2.6.8.orig/drivers/char/pcxx.c linux-2.6.8/drivers/char/pcxx.c ---- linux-2.6.8.orig/drivers/char/pcxx.c 2004-08-13 22:37:15.000000000 -0700 -+++ linux-2.6.8/drivers/char/pcxx.c 2004-11-28 04:49:42.532440584 -0800 -@@ -538,28 +538,11 @@ - - if(tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if(tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - shutdown(info); - tty->closing = 0; - info->event = 0; - info->tty = NULL; --#ifndef MODULE --/* ldiscs[] is not available in a MODULE --** worth noting that while I'm not sure what this hunk of code is supposed --** to do, it is not present in the serial.c driver. Hmmm. If you know, --** please send me a note. brian@ilinx.com --** Don't know either what this is supposed to do christoph@lameter.com. --*/ -- if(tty->ldisc.num != ldiscs[N_TTY].num) { -- if(tty->ldisc.close) -- (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -- if(tty->ldisc.open) -- (tty->ldisc.open)(tty); -- } --#endif - if(info->blocked_open) { - if(info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -@@ -800,9 +783,7 @@ - memoff(ch); - restore_flags(flags); - -- wake_up_interruptible(&tty->write_wait); -- if((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - static void pcxe_flush_chars(struct tty_struct *tty) -@@ -1675,10 +1656,7 @@ - if (event & LOWTX_IND) { - if (ch->statusflags & LOWWAIT) { - ch->statusflags &= ~LOWWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1686,10 +1664,7 @@ - ch->statusflags &= ~TXBUSY; - if (ch->statusflags & EMPTYWAIT) { - ch->statusflags &= ~EMPTYWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - } -@@ -2165,8 +2140,7 @@ - tty_wait_until_sent(tty, 0); - } - else { -- if(tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - } - - /* Fall Thru */ -diff -Naur linux-2.6.8.orig/drivers/char/pty.c linux-2.6.8/drivers/char/pty.c ---- linux-2.6.8.orig/drivers/char/pty.c 2004-08-13 22:36:44.000000000 -0700 -+++ linux-2.6.8/drivers/char/pty.c 2004-11-28 04:49:42.546438310 -0800 -@@ -91,10 +91,7 @@ - if (!o_tty) - return; - -- if ((o_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- o_tty->ldisc.write_wakeup) -- (o_tty->ldisc.write_wakeup)(o_tty); -- wake_up_interruptible(&o_tty->write_wait); -+ tty_wakeup(o_tty); - set_bit(TTY_THROTTLED, &tty->flags); - } - -@@ -107,6 +104,10 @@ - * (2) avoid redundant copying for cases where count >> receive_room - * N.B. Calls from user space may now return an error code instead of - * a count. -+ * -+ * FIXME: Our pty_write method is called with our ldisc lock held but -+ * not our partners. We can't just take the other one blindly without -+ * risking deadlocks. There is also the small matter of TTY_DONT_FLIP - */ - static int pty_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -diff -Naur linux-2.6.8.orig/drivers/char/riscom8.c linux-2.6.8/drivers/char/riscom8.c ---- linux-2.6.8.orig/drivers/char/riscom8.c 2004-08-13 22:36:57.000000000 -0700 -+++ linux-2.6.8/drivers/char/riscom8.c 2004-11-28 04:49:42.562435711 -0800 -@@ -1127,8 +1127,8 @@ - rc_shutdown_port(bp, port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - port->event = 0; - port->tty = NULL; -@@ -1301,9 +1301,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - static int rc_tiocmget(struct tty_struct *tty, struct file *file) -@@ -1644,9 +1642,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -diff -Naur linux-2.6.8.orig/drivers/char/rocket.c linux-2.6.8/drivers/char/rocket.c ---- linux-2.6.8.orig/drivers/char/rocket.c 2004-08-13 22:37:26.000000000 -0700 -+++ linux-2.6.8/drivers/char/rocket.c 2004-11-28 04:49:42.577433274 -0800 -@@ -250,12 +250,16 @@ - CHANNEL_t * cp, unsigned int ChanStatus) - { - unsigned int CharNStat; -- int ToRecv, wRecv, space, count; -+ int ToRecv, wRecv, space = 0, count; - unsigned char *cbuf; - char *fbuf; -+ struct tty_ldisc *ld; -+ -+ ld = tty_ldisc_ref(tty); - - ToRecv = sGetRxCnt(cp); -- space = tty->ldisc.receive_room(tty); -+ if (ld) -+ space = ld->receive_room(tty); - if (space > 2 * TTY_FLIPBUF_SIZE) - space = 2 * TTY_FLIPBUF_SIZE; - cbuf = tty->flip.char_buf; -@@ -354,7 +358,8 @@ - count += ToRecv; - } - /* Push the data up to the tty layer */ -- tty->ldisc.receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); -+ ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); -+ tty_ldisc_deref(ld); - } - - /* -@@ -408,8 +413,7 @@ - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - - if (info->xmit_cnt < WAKEUP_CHARS) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - #ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -@@ -1022,7 +1026,7 @@ - unsigned long flags; - int timeout; - CHANNEL_t *cp; -- -+ - if (rocket_paranoia_check(info, "rp_close")) - return; - -@@ -1101,8 +1105,8 @@ - - if (TTY_DRIVER_FLUSH_BUFFER_EXISTS(tty)) - TTY_DRIVER_FLUSH_BUFFER(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - -@@ -1731,8 +1735,7 @@ - - end: - if (info->xmit_cnt < WAKEUP_CHARS) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - #ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -@@ -1806,8 +1809,7 @@ - #ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); - #endif -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - - cp = &info->channel; - sFlushTxFIFO(cp); -diff -Naur linux-2.6.8.orig/drivers/char/selection.c linux-2.6.8/drivers/char/selection.c ---- linux-2.6.8.orig/drivers/char/selection.c 2004-08-13 22:38:04.000000000 -0700 -+++ linux-2.6.8/drivers/char/selection.c 2004-11-28 04:49:42.584432137 -0800 -@@ -281,12 +281,15 @@ - { - struct vt_struct *vt = (struct vt_struct *) tty->driver_data; - int pasted = 0, count; -+ struct tty_ldisc *ld; - DECLARE_WAITQUEUE(wait, current); - - acquire_console_sem(); - poke_blanked_console(); - release_console_sem(); - -+ ld = tty_ldisc_ref_wait(tty); -+ - add_wait_queue(&vt->paste_wait, &wait); - while (sel_buffer && sel_buffer_lth > pasted) { - set_current_state(TASK_INTERRUPTIBLE); -@@ -301,6 +304,8 @@ - } - remove_wait_queue(&vt->paste_wait, &wait); - current->state = TASK_RUNNING; -+ -+ tty_ldisc_deref(ld); - return 0; - } - -diff -Naur linux-2.6.8.orig/drivers/char/ser_a2232.c linux-2.6.8/drivers/char/ser_a2232.c ---- linux-2.6.8.orig/drivers/char/ser_a2232.c 2004-08-13 22:36:33.000000000 -0700 -+++ linux-2.6.8/drivers/char/ser_a2232.c 2004-11-28 04:49:42.605428725 -0800 -@@ -599,10 +599,7 @@ - - /* WakeUp if output buffer runs low */ - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && port->gs.tty->ldisc.write_wakeup){ -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -- } -- wake_up_interruptible(&port->gs.tty->write_wait); -+ tty_wakeup(port->gs.tty); - } - } // if the port is used - } // for every port on the board -diff -Naur linux-2.6.8.orig/drivers/char/serial167.c linux-2.6.8/drivers/char/serial167.c ---- linux-2.6.8.orig/drivers/char/serial167.c 2004-08-13 22:36:56.000000000 -0700 -+++ linux-2.6.8/drivers/char/serial167.c 2004-11-28 04:49:42.611427751 -0800 -@@ -760,11 +760,7 @@ - wake_up_interruptible(&info->open_wait); - } - if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { -- if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup){ -- (tty->ldisc.write_wakeup)(tty); -- } -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } /* do_softint */ - -@@ -1343,10 +1339,7 @@ - local_irq_save(flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } /* cy_flush_buffer */ - - -@@ -1846,18 +1839,9 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - info->event = 0; - info->tty = 0; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -- if (tty->ldisc.close) -- (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -- if (tty->ldisc.open) -- (tty->ldisc.open)(tty); -- } - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -diff -Naur linux-2.6.8.orig/drivers/char/serial_tx3912.c linux-2.6.8/drivers/char/serial_tx3912.c ---- linux-2.6.8.orig/drivers/char/serial_tx3912.c 2004-08-13 22:36:58.000000000 -0700 -+++ linux-2.6.8/drivers/char/serial_tx3912.c 2004-11-28 04:49:42.621426126 -0800 -@@ -191,12 +191,9 @@ - } - - if (port->gs.xmit_cnt <= port->gs.wakeup_chars) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- port->gs.tty->ldisc.write_wakeup) -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -+ tty_wakeup(port->gs.tty); - rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", - port->gs.wakeup_chars); -- wake_up_interruptible(&port->gs.tty->write_wait); - } - } - -diff -Naur linux-2.6.8.orig/drivers/char/specialix.c linux-2.6.8/drivers/char/specialix.c ---- linux-2.6.8.orig/drivers/char/specialix.c 2004-08-13 22:37:40.000000000 -0700 -+++ linux-2.6.8/drivers/char/specialix.c 2004-11-28 04:49:42.625425476 -0800 -@@ -1468,8 +1468,7 @@ - sx_shutdown_port(bp, port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - port->event = 0; - port->tty = NULL; -@@ -1646,10 +1645,8 @@ - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - restore_flags(flags); - -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); - } - - -@@ -2052,12 +2049,8 @@ - if(!(tty = port->tty)) - return; - -- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) -+ tty_wakeup(tty); - } - - static struct tty_operations sx_ops = { -diff -Naur linux-2.6.8.orig/drivers/char/stallion.c linux-2.6.8/drivers/char/stallion.c ---- linux-2.6.8.orig/drivers/char/stallion.c 2004-08-13 22:37:37.000000000 -0700 -+++ linux-2.6.8/drivers/char/stallion.c 2004-11-28 04:49:42.657420278 -0800 -@@ -1197,8 +1197,7 @@ - portp->tx.tail = (char *) NULL; - } - set_bit(TTY_IO_ERROR, &tty->flags); -- if (tty->ldisc.flush_buffer) -- (tty->ldisc.flush_buffer)(tty); -+ tty_ldisc_flush(tty); - - tty->closing = 0; - portp->tty = (struct tty_struct *) NULL; -@@ -1809,10 +1808,7 @@ - return; - - stl_flush(portp); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /*****************************************************************************/ -@@ -2193,10 +2189,7 @@ - - lock_kernel(); - if (test_bit(ASYI_TXLOW, &portp->istate)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - if (test_bit(ASYI_DCDCHANGE, &portp->istate)) { - clear_bit(ASYI_DCDCHANGE, &portp->istate); -diff -Naur linux-2.6.8.orig/drivers/char/sx.c linux-2.6.8/drivers/char/sx.c ---- linux-2.6.8.orig/drivers/char/sx.c 2004-08-13 22:36:56.000000000 -0700 -+++ linux-2.6.8/drivers/char/sx.c 2004-11-28 04:49:42.661419628 -0800 -@@ -1046,12 +1046,9 @@ - } - - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- port->gs.tty->ldisc.write_wakeup) -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -+ tty_wakeup(port->gs.tty); - sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", - port->gs.wakeup_chars); -- wake_up_interruptible(&port->gs.tty->write_wait); - } - - clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks); -diff -Naur linux-2.6.8.orig/drivers/char/synclink.c linux-2.6.8/drivers/char/synclink.c ---- linux-2.6.8.orig/drivers/char/synclink.c 2004-08-13 22:36:46.000000000 -0700 -+++ linux-2.6.8/drivers/char/synclink.c 2004-11-28 04:49:42.677417029 -0800 -@@ -993,6 +993,29 @@ - return 0; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - /* mgsl_stop() throttle (stop) transmitter - * - * Arguments: tty pointer to tty info structure -@@ -1153,13 +1176,7 @@ - __FILE__,__LINE__,info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):calling ldisc.write_wakeup on %s\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -2415,11 +2432,8 @@ - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- --} /* end of mgsl_flush_buffer() */ -+ tty_wakeup(tty); -+} - - /* mgsl_send_xchar() - * -@@ -3253,9 +3267,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - - shutdown(info); - -@@ -6830,11 +6843,7 @@ - } - else - #endif -- { -- /* Call the line discipline receive callback directly. */ -- if ( tty && tty->ldisc.receive_buf ) -- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); -- } -+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ -@@ -7006,9 +7015,7 @@ - memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize); - info->icount.rxok++; - -- /* Call the line discipline receive callback directly. */ -- if ( tty && tty->ldisc.receive_buf ) -- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); -+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - - /* Free the buffers used by this frame. */ -diff -Naur linux-2.6.8.orig/drivers/char/synclinkmp.c linux-2.6.8/drivers/char/synclinkmp.c ---- linux-2.6.8.orig/drivers/char/synclinkmp.c 2004-08-13 22:36:32.000000000 -0700 -+++ linux-2.6.8/drivers/char/synclinkmp.c 2004-11-28 04:49:42.693414430 -0800 -@@ -722,6 +722,29 @@ - return 0; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - /* tty callbacks */ - - /* Called when a port is opened. Init and enable port. -@@ -869,8 +892,7 @@ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - - shutdown(info); - -@@ -1275,9 +1297,7 @@ - spin_unlock_irqrestore(&info->lock,flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* throttle (stop) transmitter -@@ -1941,13 +1961,7 @@ - __FILE__,__LINE__,info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):%s calling ldisc.write_wakeup\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -4869,15 +4883,8 @@ - } - else - #endif -- { -- if ( tty && tty->ldisc.receive_buf ) { -- /* Call the line discipline receive callback directly. */ -- tty->ldisc.receive_buf(tty, -- info->tmp_rx_buf, -- info->flag_buf, -- framesize); -- } -- } -+ ldisc_receive_buf(tty,info->tmp_rx_buf, -+ info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ -diff -Naur linux-2.6.8.orig/drivers/char/tty_io.c linux-2.6.8/drivers/char/tty_io.c ---- linux-2.6.8.orig/drivers/char/tty_io.c 2004-08-13 22:37:15.000000000 -0700 -+++ linux-2.6.8/drivers/char/tty_io.c 2004-11-28 04:49:42.733407931 -0800 -@@ -92,6 +92,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -120,11 +121,17 @@ - - EXPORT_SYMBOL(tty_std_termios); - -+/* This list gets poked at by procfs and various bits of boot up code. This -+ could do with some rationalisation such as pulling the tty proc function -+ into this file */ -+ - LIST_HEAD(tty_drivers); /* linked list of tty drivers */ --struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table */ - --/* Semaphore to protect creating and releasing a tty */ -+/* Semaphore to protect creating and releasing a tty. This is shared with -+ vt.c for deeply disgusting hack reasons */ - DECLARE_MUTEX(tty_sem); -+/* Lock for tty_termios changes - private to tty_io/tty_ioctl */ -+spinlock_t tty_termios_lock = SPIN_LOCK_UNLOCKED; - - #ifdef CONFIG_UNIX98_PTYS - extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ -@@ -223,65 +230,324 @@ - return 0; - } - -+/* -+ * This is probably overkill for real world processors but -+ * they are not on hot paths so a little discipline won't do -+ * any harm. -+ */ -+ -+static void tty_set_termios_ldisc(struct tty_struct *tty, int num) -+{ -+ unsigned long flags; -+ spin_lock_irqsave(&tty_termios_lock, flags); -+ tty->termios->c_line = num; -+ spin_unlock_irqrestore(&tty_termios_lock, flags); -+} -+ -+/* -+ * This guards the refcounted line discipline lists. The lock -+ * must be taken with irqs off because there are hangup path -+ * callers who will do ldisc lookups and cannot sleep. -+ */ -+ -+static spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED; -+static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); -+static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ -+ - int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) - { -+ unsigned long flags; -+ int ret = 0; -+ - if (disc < N_TTY || disc >= NR_LDISCS) - return -EINVAL; - -+ spin_lock_irqsave(&tty_ldisc_lock, flags); - if (new_ldisc) { -- ldiscs[disc] = *new_ldisc; -- ldiscs[disc].flags |= LDISC_FLAG_DEFINED; -- ldiscs[disc].num = disc; -- } else -- memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc)); -+ tty_ldiscs[disc] = *new_ldisc; -+ tty_ldiscs[disc].num = disc; -+ tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; -+ tty_ldiscs[disc].refcount = 0; -+ } else { -+ if(tty_ldiscs[disc].refcount) -+ ret = -EBUSY; -+ else -+ tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - -- return 0; -+ return ret; - } - - EXPORT_SYMBOL(tty_register_ldisc); - --/* Set the discipline of a tty line. */ -+struct tty_ldisc *tty_ldisc_get(int disc) -+{ -+ unsigned long flags; -+ struct tty_ldisc *ld; -+ -+ if (disc < N_TTY || disc >= NR_LDISCS) -+ return NULL; -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ -+ ld = &tty_ldiscs[disc]; -+ /* Check the entry is defined */ -+ if(ld->flags & LDISC_FLAG_DEFINED) -+ { -+ /* If the module is being unloaded we can't use it */ -+ if (!try_module_get(ld->owner)) -+ ld = NULL; -+ else /* lock it */ -+ ld->refcount++; -+ } -+ else -+ ld = NULL; -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ return ld; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_get); -+ -+void tty_ldisc_put(int disc) -+{ -+ struct tty_ldisc *ld; -+ unsigned long flags; -+ -+ if (disc < N_TTY || disc >= NR_LDISCS) -+ BUG(); -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ ld = &tty_ldiscs[disc]; -+ if(ld->refcount == 0) -+ BUG(); -+ ld->refcount --; -+ module_put(ld->owner); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_put); -+ -+void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) -+{ -+ tty->ldisc = *ld; -+ tty->ldisc.refcount = 0; -+} -+ -+/** -+ * tty_ldisc_try - internal helper -+ * @tty: the tty -+ * -+ * Make a single attempt to grab and bump the refcount on -+ * the tty ldisc. Return 0 on failure or 1 on success. This is -+ * used to implement both the waiting and non waiting versions -+ * of tty_ldisc_ref -+ */ -+ -+static int tty_ldisc_try(struct tty_struct *tty) -+{ -+ unsigned long flags; -+ struct tty_ldisc *ld; -+ int ret = 0; -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ ld = &tty->ldisc; -+ if(test_bit(TTY_LDISC, &tty->flags)) -+ { -+ ld->refcount++; -+ ret = 1; -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ return ret; -+} -+ -+/** -+ * tty_ldisc_ref_wait - wait for the tty ldisc -+ * @tty: tty device -+ * -+ * Dereference the line discipline for the terminal and take a -+ * reference to it. If the line discipline is in flux then -+ * wait patiently until it changes. -+ * -+ * Note: Must not be called from an IRQ/timer context. The caller -+ * must also be careful not to hold other locks that will deadlock -+ * against a discipline change, such as an existing ldisc reference -+ * (which we check for) -+ */ -+ -+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) -+{ -+ /* wait_event is a macro */ -+ wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); -+ if(tty->ldisc.refcount == 0) -+ printk(KERN_ERR "tty_ldisc_ref_wait\n"); -+ return &tty->ldisc; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); -+ -+/** -+ * tty_ldisc_ref - get the tty ldisc -+ * @tty: tty device -+ * -+ * Dereference the line discipline for the terminal and take a -+ * reference to it. If the line discipline is in flux then -+ * return NULL. Can be called from IRQ and timer functions. -+ */ -+ -+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) -+{ -+ if(tty_ldisc_try(tty)) -+ return &tty->ldisc; -+ return NULL; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_ref); -+ -+/** -+ * tty_ldisc_deref - free a tty ldisc reference -+ * @ld: reference to free up -+ * -+ * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May -+ * be called in IRQ context. -+ */ -+ -+void tty_ldisc_deref(struct tty_ldisc *ld) -+{ -+ unsigned long flags; -+ -+ if(ld == NULL) -+ BUG(); -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ if(ld->refcount == 0) -+ printk(KERN_ERR "tty_ldisc_deref: no references.\n"); -+ else -+ ld->refcount--; -+ if(ld->refcount == 0) -+ wake_up(&tty_ldisc_wait); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_deref); -+ -+/** -+ * tty_ldisc_enable - allow ldisc use -+ * @tty: terminal to activate ldisc on -+ * -+ * Set the TTY_LDISC flag when the line discipline can be called -+ * again. Do neccessary wakeups for existing sleepers. -+ * -+ * Note: nobody should set this bit except via this function. Clearing -+ * directly is allowed. -+ */ -+ -+static void tty_ldisc_enable(struct tty_struct *tty) -+{ -+ set_bit(TTY_LDISC, &tty->flags); -+ wake_up(&tty_ldisc_wait); -+} -+ -+/** -+ * tty_set_ldisc - set line discipline -+ * @tty: the terminal to set -+ * @ldisc: the line discipline -+ * -+ * Set the discipline of a tty line. Must be called from a process -+ * context. -+ */ -+ - static int tty_set_ldisc(struct tty_struct *tty, int ldisc) - { - int retval = 0; - struct tty_ldisc o_ldisc; - char buf[64]; -+ int work; -+ unsigned long flags; -+ struct tty_ldisc *ld; - - if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) - return -EINVAL; -+ -+restart: -+ -+ if (tty->ldisc.num == ldisc) -+ return 0; /* We are already in the desired discipline */ -+ -+ ld = tty_ldisc_get(ldisc); - /* Eduardo Blanco */ - /* Cyrus Durgin */ -- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) { -+ if (ld == NULL) { - request_module("tty-ldisc-%d", ldisc); -+ ld = tty_ldisc_get(ldisc); - } -- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) -+ if (ld == NULL) - return -EINVAL; - -- if (tty->ldisc.num == ldisc) -- return 0; /* We are already in the desired discipline */ -- -- if (!try_module_get(ldiscs[ldisc].owner)) -- return -EINVAL; -- - o_ldisc = tty->ldisc; - - tty_wait_until_sent(tty, 0); -+ -+ /* -+ * Make sure we don't change while someone holds a -+ * reference to the line discipline. The TTY_LDISC bit -+ * prevents anyone taking a reference once it is clear. -+ * We need the lock to avoid racing reference takers. -+ */ -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ if(tty->ldisc.refcount) -+ { -+ /* Free the new ldisc we grabbed. Must drop the lock -+ first. */ -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ tty_ldisc_put(ldisc); -+ /* -+ * There are several reasons we may be busy, including -+ * random momentary I/O traffic. We must therefore -+ * retry. We could distinguish between blocking ops -+ * and retries if we made tty_ldisc_wait() smarter. That -+ * is up for discussion. -+ */ -+ if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0) -+ return -ERESTARTSYS; -+ goto restart; -+ } -+ clear_bit(TTY_LDISC, &tty->flags); -+ clear_bit(TTY_DONT_FLIP, &tty->flags); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - -+ /* -+ * From this point on we know nobody has an ldisc -+ * usage reference, nor can they obtain one until -+ * we say so later on. -+ */ -+ -+ work = cancel_delayed_work(&tty->flip.work); -+ /* -+ * Wait for ->hangup_work and ->flip.work handlers to terminate -+ */ -+ -+ flush_scheduled_work(); - /* Shutdown the current discipline. */ - if (tty->ldisc.close) - (tty->ldisc.close)(tty); - - /* Now set up the new line discipline. */ -- tty->ldisc = ldiscs[ldisc]; -- tty->termios->c_line = ldisc; -+ tty_ldisc_assign(tty, ld); -+ tty_set_termios_ldisc(tty, ldisc); - if (tty->ldisc.open) - retval = (tty->ldisc.open)(tty); - if (retval < 0) { -- tty->ldisc = o_ldisc; -- tty->termios->c_line = tty->ldisc.num; -+ tty_ldisc_put(ldisc); -+ /* There is an outstanding reference here so this is safe */ -+ tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num)); -+ tty_set_termios_ldisc(tty, tty->ldisc.num); - if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) { -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -+ tty_ldisc_put(o_ldisc.num); -+ /* This driver is always present */ -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(tty, N_TTY); - if (tty->ldisc.open) { - int r = tty->ldisc.open(tty); - -@@ -291,12 +557,27 @@ - tty_name(tty, buf), r); - } - } -- } else { -- module_put(o_ldisc.owner); - } -+ /* At this point we hold a reference to the new ldisc and a -+ a reference to the old ldisc. If we ended up flipping back -+ to the existing ldisc we have two references to it */ - - if (tty->ldisc.num != o_ldisc.num && tty->driver->set_ldisc) - tty->driver->set_ldisc(tty); -+ -+ tty_ldisc_put(o_ldisc.num); -+ -+ /* -+ * Allow ldisc referencing to occur as soon as the driver -+ * ldisc callback completes. -+ */ -+ -+ tty_ldisc_enable(tty); -+ -+ /* Restart it in case no characters kick it off. Safe if -+ already running */ -+ if(work) -+ schedule_delayed_work(&tty->flip.work, 1); - return retval; - } - -@@ -399,6 +680,53 @@ - - static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED; - static struct file *redirect; -+ -+/** -+ * tty_wakeup - request more data -+ * @tty: terminal -+ * -+ * Internal and external helper for wakeups of tty. This function -+ * informs the line discipline if present that the driver is ready -+ * to receive more output data. -+ */ -+ -+void tty_wakeup(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld; -+ -+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { -+ ld = tty_ldisc_ref(tty); -+ if(ld) { -+ if(ld->write_wakeup) -+ ld->write_wakeup(tty); -+ tty_ldisc_deref(ld); -+ } -+ } -+ wake_up_interruptible(&tty->write_wait); -+} -+ -+EXPORT_SYMBOL_GPL(tty_wakeup); -+ -+/** -+ * tty_ldisc_flush - flush line discipline queue -+ * @tty: tty -+ * -+ * Flush the line discipline queue (if any) for this tty. If there -+ * is no line discipline active this is a no-op. -+ */ -+ -+void tty_ldisc_flush(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); -+ if(ld) { -+ if(ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_flush); -+ - /* - * This can be called by the "eventd" kernel thread. That is process synchronous, - * but doesn't hold any locks, so we need to make sure we have the appropriate -@@ -410,6 +738,7 @@ - struct file * cons_filp = NULL; - struct file *filp, *f = NULL; - struct task_struct *p; -+ struct tty_ldisc *ld; - struct pid *pid; - int closecount = 0, n; - -@@ -428,6 +757,7 @@ - - check_tty_count(tty, "do_tty_hangup"); - file_list_lock(); -+ /* This breaks for file handles being sent over AF_UNIX sockets ? */ - list_for_each_entry(filp, &tty->tty_files, f_list) { - if (filp->f_op->write == redirected_tty_write) - cons_filp = filp; -@@ -440,21 +770,25 @@ - file_list_unlock(); - - /* FIXME! What are the locking issues here? This may me overdoing things.. -- * this question is especially important now that we've removed the irqlock. */ -- { -- unsigned long flags; -+ * this question is especially important now that we've removed the irqlock. */ - -- local_irq_save(flags); // FIXME: is this safe? -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if(ld != NULL) /* We may have no line discipline at this point */ -+ { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- local_irq_restore(flags); // FIXME: is this safe? -+ ld->write_wakeup) -+ ld->write_wakeup(tty); -+ if (ld->hangup) -+ ld->hangup(tty); - } - -+ /* FIXME: Once we trust the LDISC code better we can wait here for -+ ldisc completion and fix the driver call race */ -+ - wake_up_interruptible(&tty->write_wait); - wake_up_interruptible(&tty->read_wait); - -@@ -463,22 +797,19 @@ - * N_TTY. - */ - if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) -+ { -+ unsigned long flags; -+ spin_lock_irqsave(&tty_termios_lock, flags); - *tty->termios = tty->driver->init_termios; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -- if (tty->ldisc.close) -- (tty->ldisc.close)(tty); -- module_put(tty->ldisc.owner); -- -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -- if (tty->ldisc.open) { -- int i = (tty->ldisc.open)(tty); -- if (i < 0) -- printk(KERN_ERR "do_tty_hangup: N_TTY open: " -- "error %d\n", -i); -- } -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - } - -+ /* Defer ldisc switch */ -+ /* tty_deferred_ldisc_switch(N_TTY); -+ -+ This should get done automatically when the port closes and -+ tty_release is called */ -+ - read_lock(&tasklist_lock); - if (tty->session > 0) { - struct list_head *l; -@@ -511,6 +842,17 @@ - tty->driver->close(tty, cons_filp); - } else if (tty->driver->hangup) - (tty->driver->hangup)(tty); -+ -+ /* We don't want to have driver/ldisc interactions beyond -+ the ones we did here. The driver layer expects no -+ calls after ->hangup() from the ldisc side. However we -+ can't yet guarantee all that */ -+ -+ set_bit(TTY_HUPPED, &tty->flags); -+ if (ld) { -+ tty_ldisc_enable(tty); -+ tty_ldisc_deref(ld); -+ } - unlock_kernel(); - if (f) - fput(f); -@@ -627,9 +969,9 @@ - } - if (tty->driver->start) - (tty->driver->start)(tty); -- if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ -+ /* If we have a running line discipline it may need kicking */ -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -641,6 +983,7 @@ - int i; - struct tty_struct * tty; - struct inode *inode; -+ struct tty_ldisc *ld; - - tty = (struct tty_struct *)file->private_data; - inode = file->f_dentry->d_inode; -@@ -649,11 +992,15 @@ - if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) - return -EIO; - -+ /* We want to wait for the line discipline to sort out in this -+ situation */ -+ ld = tty_ldisc_ref_wait(tty); - lock_kernel(); -- if (tty->ldisc.read) -- i = (tty->ldisc.read)(tty,file,buf,count); -+ if (ld->read) -+ i = (ld->read)(tty,file,buf,count); - else - i = -EIO; -+ tty_ldisc_deref(ld); - unlock_kernel(); - if (i > 0) - inode->i_atime = CURRENT_TIME; -@@ -715,16 +1062,23 @@ - { - struct tty_struct * tty; - struct inode *inode = file->f_dentry->d_inode; -- -+ ssize_t ret; -+ struct tty_ldisc *ld; -+ - tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode, "tty_write")) - return -EIO; - if (!tty || !tty->driver->write || (test_bit(TTY_IO_ERROR, &tty->flags))) - return -EIO; -- if (!tty->ldisc.write) -- return -EIO; -- return do_tty_write(tty->ldisc.write, tty, file, -+ -+ ld = tty_ldisc_ref_wait(tty); -+ if (!ld->write) -+ ret = -EIO; -+ else -+ ret = do_tty_write(ld->write, tty, file, - (const unsigned char __user *)buf, count); -+ tty_ldisc_deref(ld); -+ return ret; - } - - ssize_t redirected_tty_write(struct file * file, const char __user * buf, size_t count, -@@ -910,6 +1264,7 @@ - * If we fail here just call release_mem to clean up. No need - * to decrement the use counts, as release_mem doesn't care. - */ -+ - if (tty->ldisc.open) { - retval = (tty->ldisc.open)(tty); - if (retval) -@@ -922,7 +1277,9 @@ - (tty->ldisc.close)(tty); - goto release_mem_out; - } -+ tty_ldisc_enable(o_tty); - } -+ tty_ldisc_enable(tty); - goto success; - - /* -@@ -951,6 +1308,9 @@ - tty->count++; - tty->driver = driver; /* N.B. why do this every time?? */ - -+ /* FIXME */ -+ if(!test_bit(TTY_LDISC, &tty->flags)) -+ printk(KERN_ERR "init_dev but no ldisc\n"); - success: - *ret_tty = tty; - -@@ -1054,6 +1414,7 @@ - int devpts_master, devpts; - int idx; - char buf[64]; -+ unsigned long flags; - - tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "release_dev")) -@@ -1130,7 +1491,6 @@ - } - } - #endif -- - if (tty->driver->close) - tty->driver->close(tty, filp); - -@@ -1254,36 +1614,58 @@ - #ifdef TTY_DEBUG_HANGUP - printk(KERN_DEBUG "freeing tty structure..."); - #endif -- - /* - * Prevent flush_to_ldisc() from rescheduling the work for later. Then -- * kill any delayed work. -+ * kill any delayed work. As this is the final close it does not -+ * race with the set_ldisc code path. - */ -+ clear_bit(TTY_LDISC, &tty->flags); - clear_bit(TTY_DONT_FLIP, &tty->flags); - cancel_delayed_work(&tty->flip.work); - - /* - * Wait for ->hangup_work and ->flip.work handlers to terminate - */ -+ - flush_scheduled_work(); -- -+ -+ /* -+ * Wait for any short term users (we know they are just driver -+ * side waiters as the file is closing so user count on the file -+ * side is zero. -+ */ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ while(tty->ldisc.refcount) -+ { -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0); -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - /* - * Shutdown the current line discipline, and reset it to N_TTY. - * N.B. why reset ldisc when we're releasing the memory?? -+ * -+ * FIXME: this MUST get fixed for the new reflocking - */ - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -- module_put(tty->ldisc.owner); -+ tty_ldisc_put(tty->ldisc.num); - -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -+ /* -+ * Switch the line discipline back -+ */ -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(tty,N_TTY); - if (o_tty) { -+ /* FIXME: could o_tty be in setldisc here ? */ -+ clear_bit(TTY_LDISC, &o_tty->flags); - if (o_tty->ldisc.close) - (o_tty->ldisc.close)(o_tty); -- module_put(o_tty->ldisc.owner); -- o_tty->ldisc = ldiscs[N_TTY]; -+ tty_ldisc_put(o_tty->ldisc.num); -+ tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(o_tty,N_TTY); - } -- - /* - * The release_mem function takes care of the details of clearing - * the slots and preserving the termios structure. -@@ -1323,6 +1705,7 @@ - unsigned short saved_flags = filp->f_flags; - - nonseekable_open(inode, filp); -+ - retry_open: - noctty = filp->f_flags & O_NOCTTY; - index = -1; -@@ -1479,14 +1862,18 @@ - static unsigned int tty_poll(struct file * filp, poll_table * wait) - { - struct tty_struct * tty; -+ struct tty_ldisc *ld; -+ int ret = 0; - - tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_poll")) - return 0; -- -- if (tty->ldisc.poll) -- return (tty->ldisc.poll)(tty, filp, wait); -- return 0; -+ -+ ld = tty_ldisc_ref_wait(tty); -+ if (ld->poll) -+ ret = (ld->poll)(tty, filp, wait); -+ tty_ldisc_deref(ld); -+ return ret; - } - - static int tty_fasync(int fd, struct file * filp, int on) -@@ -1518,12 +1905,15 @@ - static int tiocsti(struct tty_struct *tty, char __user *p) - { - char ch, mbz = 0; -- -+ struct tty_ldisc *ld; -+ - if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) - return -EPERM; - if (get_user(ch, p)) - return -EFAULT; -- tty->ldisc.receive_buf(tty, &ch, &mbz, 1); -+ ld = tty_ldisc_ref_wait(tty); -+ ld->receive_buf(tty, &ch, &mbz, 1); -+ tty_ldisc_deref(ld); - return 0; - } - -@@ -1772,6 +2162,7 @@ - struct tty_struct *tty, *real_tty; - void __user *p = (void __user *)arg; - int retval; -+ struct tty_ldisc *ld; - - tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode, "tty_ioctl")) -@@ -1861,6 +2252,7 @@ - case TIOCGSID: - return tiocgsid(tty, real_tty, p); - case TIOCGETD: -+ /* FIXME: check this is ok */ - return put_user(tty->ldisc.num, (int __user *)p); - case TIOCSETD: - return tiocsetd(tty, p); -@@ -1899,16 +2291,19 @@ - return tty_tiocmset(tty, file, cmd, p); - } - if (tty->driver->ioctl) { -- int retval = (tty->driver->ioctl)(tty, file, cmd, arg); -+ retval = (tty->driver->ioctl)(tty, file, cmd, arg); - if (retval != -ENOIOCTLCMD) - return retval; - } -- if (tty->ldisc.ioctl) { -- int retval = (tty->ldisc.ioctl)(tty, file, cmd, arg); -- if (retval != -ENOIOCTLCMD) -- return retval; -+ ld = tty_ldisc_ref_wait(tty); -+ retval = -EINVAL; -+ if (ld->ioctl) { -+ retval = ld->ioctl(tty, file, cmd, arg); -+ if (retval == -ENOIOCTLCMD) -+ retval = -EINVAL; - } -- return -EINVAL; -+ tty_ldisc_deref(ld); -+ return retval; - } - - -@@ -1943,14 +2338,21 @@ - int session; - int i; - struct file *filp; -+ struct tty_ldisc *disc; - - if (!tty) - return; - session = tty->session; -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ /* We don't want an ldisc switch during this */ -+ disc = tty_ldisc_ref(tty); -+ if (disc && disc->flush_buffer) -+ disc->flush_buffer(tty); -+ tty_ldisc_deref(disc); -+ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -+ - read_lock(&tasklist_lock); - for_each_task_pid(session, PIDTYPE_SID, p, l, pid) { - if (p->signal->tty == tty || session > 0) { -@@ -2002,24 +2404,29 @@ - - /* - * This routine is called out of the software interrupt to flush data -- * from the flip buffer to the line discipline. -+ * from the flip buffer to the line discipline. - */ -+ - static void flush_to_ldisc(void *private_) - { - struct tty_struct *tty = (struct tty_struct *) private_; - unsigned char *cp; - char *fp; - int count; -- unsigned long flags; -+ unsigned long flags; -+ struct tty_ldisc *disc; -+ -+ disc = tty_ldisc_ref(tty); -+ if (disc == NULL) /* !TTY_LDISC */ -+ return; - - if (test_bit(TTY_DONT_FLIP, &tty->flags)) { - /* - * Do it after the next timer tick: - */ - schedule_delayed_work(&tty->flip.work, 1); -- return; -+ goto out; - } -- - spin_lock_irqsave(&tty->read_lock, flags); - if (tty->flip.buf_num) { - cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE; -@@ -2038,7 +2445,31 @@ - tty->flip.count = 0; - spin_unlock_irqrestore(&tty->read_lock, flags); - -- tty->ldisc.receive_buf(tty, cp, fp, count); -+ disc->receive_buf(tty, cp, fp, count); -+out: -+ tty_ldisc_deref(disc); -+} -+ -+/* -+ * Call the ldisc flush directly from a driver. This function may -+ * return an error and need retrying by the user. -+ */ -+ -+int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count) -+{ -+ int ret = 0; -+ struct tty_ldisc *disc; -+ -+ disc = tty_ldisc_ref(tty); -+ if(test_bit(TTY_DONT_FLIP, &tty->flags)) -+ ret = -EAGAIN; -+ else if(disc == NULL) -+ ret = -EIO; -+ else -+ disc->receive_buf(tty, cp, fp, count); -+ tty_ldisc_deref(disc); -+ return ret; -+ - } - - /* -@@ -2060,9 +2491,20 @@ - - static int n_baud_table = ARRAY_SIZE(baud_table); - -+/** -+ * tty_termios_baud_rate -+ * @termios: termios structure -+ * -+ * Convert termios baud rate data into a speed. This should be called -+ * with the termios lock held if this termios is a terminal termios -+ * structure. May change the termios data. -+ */ -+ - int tty_termios_baud_rate(struct termios *termios) - { -- unsigned int cbaud = termios->c_cflag & CBAUD; -+ unsigned int cbaud; -+ -+ cbaud = termios->c_cflag & CBAUD; - - if (cbaud & CBAUDEX) { - cbaud &= ~CBAUDEX; -@@ -2072,12 +2514,20 @@ - else - cbaud += 15; - } -- - return baud_table[cbaud]; - } - - EXPORT_SYMBOL(tty_termios_baud_rate); - -+/** -+ * tty_get_baud_rate - get tty bit rates -+ * @tty: tty to query -+ * -+ * Returns the baud rate as an integer for this terminal. The -+ * termios lock must be held by the caller and the terminal bit -+ * flags may be updated. -+ */ -+ - int tty_get_baud_rate(struct tty_struct *tty) - { - int baud = tty_termios_baud_rate(tty->termios); -@@ -2096,6 +2546,17 @@ - - EXPORT_SYMBOL(tty_get_baud_rate); - -+/** -+ * tty_flip_buffer_push - terminal -+ * @tty: tty to push -+ * -+ * Queue a push of the terminal flip buffers to the line discipline. This -+ * function must not be called from IRQ context if tty->low_latency is set. -+ * -+ * In the event of the queue being busy for flipping the work will be -+ * held off and retried later. -+ */ -+ - void tty_flip_buffer_push(struct tty_struct *tty) - { - if (tty->low_latency) -@@ -2113,7 +2574,7 @@ - { - memset(tty, 0, sizeof(struct tty_struct)); - tty->magic = TTY_MAGIC; -- tty->ldisc = ldiscs[N_TTY]; -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); - tty->pgrp = -1; - tty->flip.char_buf_ptr = tty->flip.char_buf; - tty->flip.flag_buf_ptr = tty->flip.flag_buf; -diff -Naur linux-2.6.8.orig/drivers/char/tty_ioctl.c linux-2.6.8/drivers/char/tty_ioctl.c ---- linux-2.6.8.orig/drivers/char/tty_ioctl.c 2004-08-13 22:38:10.000000000 -0700 -+++ linux-2.6.8/drivers/char/tty_ioctl.c 2004-11-28 04:49:54.591481233 -0800 -@@ -29,6 +29,8 @@ - - #undef DEBUG - -+extern spinlock_t tty_termios_lock; -+ - /* - * Internal flag options for termios setting behavior - */ -@@ -98,8 +100,18 @@ - { - int canon_change; - struct termios old_termios = *tty->termios; -+ struct tty_ldisc *ld; -+ unsigned long flags; -+ -+ /* -+ * Perform the actual termios internal changes under lock. -+ */ -+ -+ -+ /* FIXME: we need to decide on some locking/ordering semantics -+ for the set_termios notification eventually */ -+ spin_lock_irqsave(&tty_termios_lock, flags); - -- local_irq_disable(); // FIXME: is this safe? - *tty->termios = *new_termios; - unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); - canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; -@@ -109,12 +121,13 @@ - tty->canon_data = 0; - tty->erasing = 0; - } -- local_irq_enable(); // FIXME: is this safe? -+ -+ - if (canon_change && !L_ICANON(tty) && tty->read_cnt) - /* Get characters left over from canonical mode. */ - wake_up_interruptible(&tty->read_wait); - -- /* see if packet mode change of state */ -+ /* See if packet mode change of state. */ - - if (tty->link && tty->link->packet) { - int old_flow = ((old_termios.c_iflag & IXON) && -@@ -132,17 +145,23 @@ - wake_up_interruptible(&tty->link->read_wait); - } - } -- -+ - if (tty->driver->set_termios) - (*tty->driver->set_termios)(tty, &old_termios); - -- if (tty->ldisc.set_termios) -- (*tty->ldisc.set_termios)(tty, &old_termios); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->set_termios) -+ (ld->set_termios)(tty, &old_termios); -+ tty_ldisc_deref(ld); -+ } -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - } - - static int set_termios(struct tty_struct * tty, void __user *arg, int opt) - { - struct termios tmp_termios; -+ struct tty_ldisc *ld; - int retval = tty_check_change(tty); - - if (retval) -@@ -159,9 +178,14 @@ - return -EFAULT; - } - -- if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ ld = tty_ldisc_ref(tty); -+ -+ if (ld != NULL) { -+ if ((opt & TERMIOS_FLUSH) && ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+ - if (opt & TERMIOS_WAIT) { - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) -@@ -225,12 +249,16 @@ - static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) - { - struct sgttyb tmp; -+ unsigned long flags; - -+ spin_lock_irqsave(&tty_termios_lock, flags); - tmp.sg_ispeed = 0; - tmp.sg_ospeed = 0; - tmp.sg_erase = tty->termios->c_cc[VERASE]; - tmp.sg_kill = tty->termios->c_cc[VKILL]; - tmp.sg_flags = get_sgflags(tty); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); -+ - return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; - } - -@@ -265,16 +293,21 @@ - int retval; - struct sgttyb tmp; - struct termios termios; -+ unsigned long flags; - - retval = tty_check_change(tty); - if (retval) - return retval; -- termios = *tty->termios; -+ - if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) - return -EFAULT; -+ -+ spin_lock_irqsave(&tty_termios_lock, flags); -+ termios = *tty->termios; - termios.c_cc[VERASE] = tmp.sg_erase; - termios.c_cc[VKILL] = tmp.sg_kill; - set_sgflags(&termios, tmp.sg_flags); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - change_termios(tty, &termios); - return 0; - } -@@ -365,6 +398,8 @@ - struct tty_struct * real_tty; - void __user *p = (void __user *)arg; - int retval; -+ struct tty_ldisc *ld; -+ unsigned long flags; - - if (tty->driver->type == TTY_DRIVER_TYPE_PTY && - tty->driver->subtype == PTY_TYPE_MASTER) -@@ -443,22 +478,26 @@ - retval = tty_check_change(tty); - if (retval) - return retval; -+ -+ ld = tty_ldisc_ref(tty); - switch (arg) { - case TCIFLUSH: -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - break; - case TCIOFLUSH: -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - /* fall through */ - case TCOFLUSH: - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - break; - default: -+ tty_ldisc_deref(ld); - return -EINVAL; - } -+ tty_ldisc_deref(ld); - return 0; - case TIOCOUTQ: - return put_user(tty->driver->chars_in_buffer ? -@@ -504,9 +543,11 @@ - case TIOCSSOFTCAR: - if (get_user(arg, (unsigned int __user *) arg)) - return -EFAULT; -+ spin_lock_irqsave(&tty_termios_lock, flags); - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - return 0; - default: - return -ENOIOCTLCMD; -diff -Naur linux-2.6.8.orig/drivers/char/viocons.c linux-2.6.8/drivers/char/viocons.c ---- linux-2.6.8.orig/drivers/char/viocons.c 2004-08-13 22:36:10.000000000 -0700 -+++ linux-2.6.8/drivers/char/viocons.c 2004-11-28 04:49:42.767402408 -0800 -@@ -422,10 +422,7 @@ - pi->overflowMessage = 0; - - if (pi->tty) { -- if ((pi->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- (pi->tty->ldisc.write_wakeup)) -- (pi->tty->ldisc.write_wakeup)(pi->tty); -- wake_up_interruptible(&pi->tty->write_wait); -+ tty_wakeup(pi->tty); - } - } - -diff -Naur linux-2.6.8.orig/drivers/char/vme_scc.c linux-2.6.8/drivers/char/vme_scc.c ---- linux-2.6.8.orig/drivers/char/vme_scc.c 2004-08-13 22:36:11.000000000 -0700 -+++ linux-2.6.8/drivers/char/vme_scc.c 2004-11-28 04:49:42.779400459 -0800 -@@ -544,12 +544,8 @@ - SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); /* disable tx_int on next tx underrun? */ - port->gs.flags &= ~GS_TX_INTEN; - } -- if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- port->gs.tty->ldisc.write_wakeup) -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -- wake_up_interruptible(&port->gs.tty->write_wait); -- } -+ if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) -+ tty_wakeup(port->gs.tty); - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; -diff -Naur linux-2.6.8.orig/drivers/char/vt_ioctl.c linux-2.6.8/drivers/char/vt_ioctl.c ---- linux-2.6.8.orig/drivers/char/vt_ioctl.c 2004-08-13 22:37:26.000000000 -0700 -+++ linux-2.6.8/drivers/char/vt_ioctl.c 2004-11-28 04:49:42.785399484 -0800 -@@ -536,8 +536,7 @@ - default: - return -EINVAL; - } -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - return 0; - - case KDGKBMODE: -diff -Naur linux-2.6.8.orig/drivers/isdn/capi/capi.c linux-2.6.8/drivers/isdn/capi/capi.c ---- linux-2.6.8.orig/drivers/isdn/capi/capi.c 2004-08-13 22:38:04.000000000 -0700 -+++ linux-2.6.8/drivers/isdn/capi/capi.c 2004-11-28 04:49:42.797397535 -0800 -@@ -436,51 +436,62 @@ - struct sk_buff *nskb; - int datalen; - u16 errcode, datahandle; -- -+ struct tty_ldisc *ld; -+ - datalen = skb->len - CAPIMSG_LEN(skb->data); -- if (mp->tty) { -- if (mp->tty->ldisc.receive_buf == 0) { -- printk(KERN_ERR "capi: ldisc has no receive_buf function\n"); -- return -1; -- } -- if (mp->ttyinstop) { -+ if (mp->tty == NULL) -+ { -+#ifdef _DEBUG_DATAFLOW -+ printk(KERN_DEBUG "capi: currently no receiver\n"); -+#endif -+ return -1; -+ } -+ -+ ld = tty_ldisc_ref(mp->tty); -+ if (ld == NULL) -+ return -1; -+ if (ld->receive_buf == NULL) { - #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) -- printk(KERN_DEBUG "capi: recv tty throttled\n"); -+ printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n"); - #endif -- return -1; -- } -- if (mp->tty->ldisc.receive_room && -- mp->tty->ldisc.receive_room(mp->tty) < datalen) { -+ goto bad; -+ } -+ if (mp->ttyinstop) { - #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) -- printk(KERN_DEBUG "capi: no room in tty\n"); -+ printk(KERN_DEBUG "capi: recv tty throttled\n"); - #endif -- return -1; -- } -- if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) { -- printk(KERN_ERR "capi: gen_data_b3_resp failed\n"); -- return -1; -- } -- datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4); -- errcode = capi20_put_message(mp->ap, nskb); -- if (errcode != CAPI_NOERROR) { -- printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", -- errcode); -- kfree_skb(nskb); -- return -1; -- } -- (void)skb_pull(skb, CAPIMSG_LEN(skb->data)); --#ifdef _DEBUG_DATAFLOW -- printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", -- datahandle, skb->len); -+ goto bad; -+ } -+ if (ld->receive_room && -+ ld->receive_room(mp->tty) < datalen) { -+#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) -+ printk(KERN_DEBUG "capi: no room in tty\n"); - #endif -- mp->tty->ldisc.receive_buf(mp->tty, skb->data, NULL, skb->len); -- kfree_skb(skb); -- return 0; -- -+ goto bad; -+ } -+ if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) { -+ printk(KERN_ERR "capi: gen_data_b3_resp failed\n"); -+ goto bad; -+ } -+ datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4); -+ errcode = capi20_put_message(mp->ap, nskb); -+ if (errcode != CAPI_NOERROR) { -+ printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", -+ errcode); -+ kfree_skb(nskb); -+ goto bad; - } -+ (void)skb_pull(skb, CAPIMSG_LEN(skb->data)); - #ifdef _DEBUG_DATAFLOW -- printk(KERN_DEBUG "capi: currently no receiver\n"); -+ printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", -+ datahandle, skb->len); - #endif -+ ld->receive_buf(mp->tty, skb->data, NULL, skb->len); -+ kfree_skb(skb); -+ tty_ldisc_deref(ld); -+ return 0; -+bad: -+ tty_ldisc_deref(ld); - return -1; - } - -@@ -614,6 +625,7 @@ - - - if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) { -+ - datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2); - #ifdef _DEBUG_DATAFLOW - printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n", -@@ -633,10 +645,8 @@ - #endif - kfree_skb(skb); - (void)capiminor_del_ack(mp, datahandle); -- if (mp->tty) { -- if (mp->tty->ldisc.write_wakeup) -- mp->tty->ldisc.write_wakeup(mp->tty); -- } -+ if (mp->tty) -+ tty_wakeup(tty); - (void)handle_minor_send(mp); - - } else { -diff -Naur linux-2.6.8.orig/drivers/isdn/i4l/isdn_tty.c linux-2.6.8/drivers/isdn/i4l/isdn_tty.c ---- linux-2.6.8.orig/drivers/isdn/i4l/isdn_tty.c 2004-08-13 22:37:27.000000000 -0700 -+++ linux-2.6.8/drivers/isdn/i4l/isdn_tty.c 2004-11-28 04:49:42.814394773 -0800 -@@ -296,10 +296,7 @@ - info->send_outstanding++; - info->msr &= ~UART_MSR_CTS; - info->lsr &= ~UART_LSR_TEMT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - return; - } - if (slen < 0) { -@@ -1174,10 +1171,7 @@ - /* If DLE decoding results in zero-transmit, but - * c originally was non-zero, do a wakeup. - */ -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - info->msr |= UART_MSR_CTS; - info->lsr |= UART_LSR_TEMT; - } -@@ -1290,9 +1284,7 @@ - isdn_tty_cleanup_xmit(info); - info->xmit_count = 0; - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - } - - static void -@@ -1747,10 +1739,10 @@ - } - dev->modempoll--; - isdn_tty_shutdown(info); -+ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - info->tty = NULL; - info->ncarrier = 0; - tty->closing = 0; -@@ -2681,8 +2673,7 @@ - if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) { - return; - } -- if (info->tty->ldisc.flush_buffer) -- info->tty->ldisc.flush_buffer(info->tty); -+ tty_ldisc_flush(tty); - if ((info->flags & ISDN_ASYNC_CHECK_CD) && - (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) && - (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) { -diff -Naur linux-2.6.8.orig/drivers/macintosh/macserial.c linux-2.6.8/drivers/macintosh/macserial.c ---- linux-2.6.8.orig/drivers/macintosh/macserial.c 2004-08-13 22:38:08.000000000 -0700 -+++ linux-2.6.8/drivers/macintosh/macserial.c 2004-11-28 04:49:42.000000000 -0800 -@@ -713,12 +713,8 @@ - if (!tty) - return; - -- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) -+ tty_wakeup(tty); - } - - static int startup(struct mac_serial * info) -@@ -1564,10 +1560,7 @@ - spin_lock_irqsave(&info->lock, flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - spin_unlock_irqrestore(&info->lock, flags); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1994,8 +1987,7 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Naur linux-2.6.8.orig/drivers/net/hamradio/mkiss.c linux-2.6.8/drivers/net/hamradio/mkiss.c ---- linux-2.6.8.orig/drivers/net/hamradio/mkiss.c 2004-08-13 22:38:08.000000000 -0700 -+++ linux-2.6.8/drivers/net/hamradio/mkiss.c 2004-11-28 04:49:42.000000000 -0800 -@@ -602,8 +602,6 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); - - /* Restore default settings */ - ax->dev->type = ARPHRD_AX25; -diff -Naur linux-2.6.8.orig/drivers/net/irda/irtty-sir.c linux-2.6.8/drivers/net/irda/irtty-sir.c ---- linux-2.6.8.orig/drivers/net/irda/irtty-sir.c 2004-08-13 22:36:10.000000000 -0700 -+++ linux-2.6.8/drivers/net/irda/irtty-sir.c 2004-11-28 04:49:42.000000000 -0800 -@@ -509,13 +509,6 @@ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - --/* from old irtty - but what is it good for? -- * we _are_ the ldisc and we _don't_ implement flush_buffer! -- * -- * if (tty->ldisc.flush_buffer) -- * tty->ldisc.flush_buffer(tty); -- */ -- - /* apply mtt override */ - sir_tty_drv.qos_mtt_bits = qos_mtt_bits; - -diff -Naur linux-2.6.8.orig/drivers/net/ppp_async.c linux-2.6.8/drivers/net/ppp_async.c ---- linux-2.6.8.orig/drivers/net/ppp_async.c 2004-08-13 22:37:37.000000000 -0700 -+++ linux-2.6.8/drivers/net/ppp_async.c 2004-11-28 04:49:42.000000000 -0800 -@@ -122,6 +122,9 @@ - * frees the memory that ppp_asynctty_receive is using. The best - * way to fix this is to use a rwlock in the tty struct, but for now - * we use a single global rwlock for all ttys in ppp line discipline. -+ * -+ * FIXME: this is no longer true. The _close path for the ldisc is -+ * now guaranteed to be sane. - */ - static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; - -@@ -144,7 +147,8 @@ - } - - /* -- * Called when a tty is put into PPP line discipline. -+ * Called when a tty is put into PPP line discipline. Called in process -+ * context. - */ - static int - ppp_asynctty_open(struct tty_struct *tty) -@@ -255,6 +259,11 @@ - return -EAGAIN; - } - -+/* -+ * Called in process context only. May be re-entered by multiple -+ * ioctl calling threads. -+ */ -+ - static int - ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -@@ -716,7 +725,8 @@ - - /* - * Flush output from our internal buffers. -- * Called for the TCFLSH ioctl. -+ * Called for the TCFLSH ioctl. Can be entered in parallel -+ * but this is covered by the xmit_lock. - */ - static void - ppp_async_flush_output(struct asyncppp *ap) -@@ -816,7 +826,9 @@ - skb_trim(skb, 0); - } - --/* called when the tty driver has data for us. */ -+/* Called when the tty driver has data for us. Runs parallel with the -+ other ldisc functions but will not be re-entered */ -+ - static void - ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - char *flags, int count) -diff -Naur linux-2.6.8.orig/drivers/net/ppp_synctty.c linux-2.6.8/drivers/net/ppp_synctty.c ---- linux-2.6.8.orig/drivers/net/ppp_synctty.c 2004-08-13 22:36:56.000000000 -0700 -+++ linux-2.6.8/drivers/net/ppp_synctty.c 2004-11-28 04:49:42.000000000 -0800 -@@ -175,6 +175,8 @@ - * frees the memory that ppp_synctty_receive is using. The best - * way to fix this is to use a rwlock in the tty struct, but for now - * we use a single global rwlock for all ttys in ppp line discipline. -+ * -+ * FIXME: Fixed in tty_io nowdays. - */ - static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; - -diff -Naur linux-2.6.8.orig/drivers/net/slip.c linux-2.6.8/drivers/net/slip.c ---- linux-2.6.8.orig/drivers/net/slip.c 2004-08-13 22:38:10.000000000 -0700 -+++ linux-2.6.8/drivers/net/slip.c 2004-11-28 04:49:42.000000000 -0800 -@@ -672,7 +672,9 @@ - * Handle the 'receiver data ready' interrupt. - * This function is called by the 'tty_io' module in the kernel when - * a block of SLIP data has been received, which can now be decapsulated -- * and sent on to some IP layer for further processing. -+ * and sent on to some IP layer for further processing. This will not -+ * be re-entered while running but other ldisc functions may be called -+ * in parallel - */ - - static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) -@@ -841,9 +843,11 @@ - * SLIP line discipline is called for. Because we are - * sure the tty line exists, we only have to link it to - * a free SLIP channel... -+ * -+ * Called in process context serialized from other ldisc calls. - */ --static int --slip_open(struct tty_struct *tty) -+ -+static int slip_open(struct tty_struct *tty) - { - struct slip *sl; - int err; -@@ -876,11 +880,11 @@ - tty->disc_data = sl; - sl->line = tty_devnum(tty); - sl->pid = current->pid; -+ -+ /* FIXME: already done before we were called - seems this can go */ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ - if (!test_bit(SLF_INUSE, &sl->flags)) { - /* Perform the low-level SLIP initialization. */ - if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) -@@ -923,6 +927,9 @@ - } - - /* -+ -+ FIXME: 1,2 are fixed 3 was never true anyway. -+ - Let me to blame a bit. - 1. TTY module calls this funstion on soft interrupt. - 2. TTY module calls this function WITH MASKED INTERRUPTS! -@@ -941,9 +948,8 @@ - - /* - * Close down a SLIP channel. -- * This means flushing out any pending queues, and then restoring the -- * TTY line discipline to what it was before it got hooked to SLIP -- * (which usually is TTY again). -+ * This means flushing out any pending queues, and then returning. This -+ * call is serialized against other ldisc functions. - */ - static void - slip_close(struct tty_struct *tty) -diff -Naur linux-2.6.8.orig/drivers/net/wan/pc300_tty.c linux-2.6.8/drivers/net/wan/pc300_tty.c ---- linux-2.6.8.orig/drivers/net/wan/pc300_tty.c 2004-08-13 22:36:57.000000000 -0700 -+++ linux-2.6.8/drivers/net/wan/pc300_tty.c 2004-11-28 04:49:42.000000000 -0800 -@@ -634,14 +634,8 @@ - } - - CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name); -- -- wake_up_interruptible(&tty->write_wait); -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){ -- CPC_TTY_DBG("%s: call line disc. wake up\n",cpc_tty->name); -- tty->ldisc.write_wakeup(tty); -- } - -+ tty_wakeup(tty); - return; - } - -@@ -692,9 +686,11 @@ - st_cpc_tty_area *cpc_tty; - volatile st_cpc_rx_buf * buf; - char flags=0,flg_rx=1; -+ struct tty_ldisc *ld; - - if (cpc_tty_cnt == 0) return; - -+ - for (i=0; (i < 4) && flg_rx ; i++) { - flg_rx = 0; - port = (int) data; -@@ -702,11 +698,18 @@ - cpc_tty = &cpc_tty_area[port]; - - if ((buf=cpc_tty->buf_rx.first) != 0) { -- -- if (cpc_tty->tty && (cpc_tty->tty->ldisc.receive_buf)) { -- CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); -- cpc_tty->tty->ldisc.receive_buf(cpc_tty->tty, (char *)(buf->data), -- &flags, buf->size); -+ -+ if(cpc_tty->tty) -+ { -+ ld = tty_ldisc_ref(cpc_tty); -+ if(ld) -+ { -+ if (ld->receive_buf)) { -+ CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); -+ ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size); -+ } -+ tty_ldisc_deref(ld); -+ } - } - cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; - kfree((unsigned char *)buf); -@@ -910,13 +913,7 @@ - CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name); - return; - } -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){ -- CPC_TTY_DBG("%s:call line disc. wakeup\n",cpc_tty->name); -- tty->ldisc.write_wakeup (tty); -- } -- -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - /* -diff -Naur linux-2.6.8.orig/drivers/net/wan/sdla_chdlc.c linux-2.6.8/drivers/net/wan/sdla_chdlc.c ---- linux-2.6.8.orig/drivers/net/wan/sdla_chdlc.c 2004-08-13 22:36:58.000000000 -0700 -+++ linux-2.6.8/drivers/net/wan/sdla_chdlc.c 2004-11-28 04:49:42.000000000 -0800 -@@ -3628,11 +3628,7 @@ - if ((tty=card->tty)==NULL) - return; - -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup){ -- (tty->ldisc.write_wakeup)(tty); -- } -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - #if defined(SERIAL_HAVE_POLL_WAIT) - wake_up_interruptible(&tty->poll_wait); - #endif -@@ -3857,6 +3853,7 @@ - char fp=0; - struct tty_struct *tty; - int i; -+ struct tty_ldisc *ld; - - if (!card->tty_open){ - dbg_printk(KERN_INFO "%s: TTY not open during receive\n", -@@ -3944,8 +3941,11 @@ - len -= offset; - } - sdla_peek(&card->hw, addr, card->tty_rx+offset, len); -- if (tty->ldisc.receive_buf){ -- tty->ldisc.receive_buf(tty,card->tty_rx,&fp,olen); -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty,card->tty_rx,&fp,olen); -+ tty_ldisc_deref(ld); - }else{ - if (net_ratelimit()){ - printk(KERN_INFO -@@ -4252,14 +4252,10 @@ - if (!tty) - return; - -- wake_up_interruptible(&tty->write_wait); - #if defined(SERIAL_HAVE_POLL_WAIT) - wake_up_interruptible(&tty->poll_wait); - #endif -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- -+ tty_wakeup(tty); - return; - } - -diff -Naur linux-2.6.8.orig/drivers/net/wireless/strip.c linux-2.6.8/drivers/net/wireless/strip.c ---- linux-2.6.8.orig/drivers/net/wireless/strip.c 2004-08-13 22:37:26.000000000 -0700 -+++ linux-2.6.8/drivers/net/wireless/strip.c 2004-11-28 04:49:42.000000000 -0800 -@@ -2661,8 +2661,6 @@ - tty->disc_data = strip_info; - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); - - /* - * Restore default settings -diff -Naur linux-2.6.8.orig/drivers/s390/char/con3215.c linux-2.6.8/drivers/s390/char/con3215.c ---- linux-2.6.8.orig/drivers/s390/char/con3215.c 2004-08-13 22:37:26.000000000 -0700 -+++ linux-2.6.8/drivers/s390/char/con3215.c 2004-11-28 04:49:43.000000000 -0800 -@@ -366,10 +366,7 @@ - tty = raw->tty; - if (tty != NULL && - RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1055,10 +1052,7 @@ - - raw = (struct raw3215_info *) tty->driver_data; - raw3215_flush_buffer(raw); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -diff -Naur linux-2.6.8.orig/drivers/s390/char/sclp_tty.c linux-2.6.8/drivers/s390/char/sclp_tty.c ---- linux-2.6.8.orig/drivers/s390/char/sclp_tty.c 2004-08-13 22:38:11.000000000 -0700 -+++ linux-2.6.8/drivers/s390/char/sclp_tty.c 2004-11-28 04:49:43.000000000 -0800 -@@ -277,10 +277,7 @@ - wake_up(&sclp_tty_waitq); - /* check if the tty needs a wake up call */ - if (sclp_tty != NULL) { -- if ((sclp_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- sclp_tty->ldisc.write_wakeup) -- (sclp_tty->ldisc.write_wakeup)(sclp_tty); -- wake_up_interruptible(&sclp_tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Naur linux-2.6.8.orig/drivers/s390/char/sclp_vt220.c linux-2.6.8/drivers/s390/char/sclp_vt220.c ---- linux-2.6.8.orig/drivers/s390/char/sclp_vt220.c 2004-08-13 22:36:44.000000000 -0700 -+++ linux-2.6.8/drivers/s390/char/sclp_vt220.c 2004-11-28 04:49:43.000000000 -0800 -@@ -139,10 +139,7 @@ - wake_up(&sclp_vt220_waitq); - /* Check if the tty needs a wake up call */ - if (sclp_vt220_tty != NULL) { -- if ((sclp_vt220_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- (sclp_vt220_tty->ldisc.write_wakeup != NULL)) -- (sclp_vt220_tty->ldisc.write_wakeup)(sclp_vt220_tty); -- wake_up_interruptible(&sclp_vt220_tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Naur linux-2.6.8.orig/drivers/s390/net/ctctty.c linux-2.6.8/drivers/s390/net/ctctty.c ---- linux-2.6.8.orig/drivers/s390/net/ctctty.c 2004-08-13 22:37:14.000000000 -0700 -+++ linux-2.6.8/drivers/s390/net/ctctty.c 2004-11-28 04:49:43.000000000 -0800 -@@ -307,10 +307,7 @@ - - info->flags &= ~CTC_ASYNC_TX_LINESTAT; - if (tty) { -- if (wake && (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - return (skb_queue_empty(&info->tx_queue) ? 0 : 1); -@@ -589,9 +586,7 @@ - info->lsr |= UART_LSR_TEMT; - spin_unlock_irqrestore(&ctc_tty_lock, flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - ex: - DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__); - return; -@@ -1066,8 +1061,7 @@ - skb_queue_purge(&info->tx_queue); - info->lsr |= UART_LSR_TEMT; - } -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - info->tty = 0; - tty->closing = 0; - if (info->blocked_open) { -diff -Naur linux-2.6.8.orig/drivers/sbus/char/aurora.c linux-2.6.8/drivers/sbus/char/aurora.c ---- linux-2.6.8.orig/drivers/sbus/char/aurora.c 2004-08-13 22:36:17.000000000 -0700 -+++ linux-2.6.8/drivers/sbus/char/aurora.c 2004-11-28 04:49:43.000000000 -0800 -@@ -1531,8 +1531,7 @@ - aurora_shutdown_port(bp, port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - port->event = 0; - port->tty = 0; -@@ -1743,10 +1742,7 @@ - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - restore_flags(flags); - -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - #ifdef AURORA_DEBUG - printk("aurora_flush_buffer: end\n"); - #endif -@@ -2223,10 +2219,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - #ifdef AURORA_DEBUG - printk("do_softint: end\n"); -diff -Naur linux-2.6.8.orig/drivers/serial/68328serial.c linux-2.6.8/drivers/serial/68328serial.c ---- linux-2.6.8.orig/drivers/serial/68328serial.c 2004-08-13 22:38:08.000000000 -0700 -+++ linux-2.6.8/drivers/serial/68328serial.c 2004-11-28 04:49:43.000000000 -0800 -@@ -435,10 +435,7 @@ - return; - #if 0 - if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - #endif - } -@@ -858,10 +855,7 @@ - cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1185,11 +1179,13 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -+#warning "This is not and has never been valid so fix it" -+#if 0 - if (tty->ldisc.num != ldiscs[N_TTY].num) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -@@ -1198,6 +1194,7 @@ - if (tty->ldisc.open) - (tty->ldisc.open)(tty); - } -+#endif - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -diff -Naur linux-2.6.8.orig/drivers/serial/68360serial.c linux-2.6.8/drivers/serial/68360serial.c ---- linux-2.6.8.orig/drivers/serial/68360serial.c 2004-08-13 22:38:04.000000000 -0700 -+++ linux-2.6.8/drivers/serial/68360serial.c 2004-11-28 04:49:43.000000000 -0800 -@@ -700,12 +700,8 @@ - if (!tty) - return; - -- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) -+ tty_wakeup(tty); - } - - -@@ -1152,10 +1148,7 @@ - /* There is nothing to "flush", whatever we gave the CPM - * is on its way out. - */ -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - info->flags &= ~TX_WAKEUP; - } - -@@ -1716,8 +1709,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Naur linux-2.6.8.orig/drivers/serial/mcfserial.c linux-2.6.8/drivers/serial/mcfserial.c ---- linux-2.6.8.orig/drivers/serial/mcfserial.c 2004-08-13 22:36:56.000000000 -0700 -+++ linux-2.6.8/drivers/serial/mcfserial.c 2004-11-28 04:49:43.000000000 -0800 -@@ -424,11 +424,7 @@ - tty = info->tty; - if (!tty) - return; -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - -@@ -835,10 +831,7 @@ - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); - -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1232,11 +1225,12 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - info->event = 0; - info->tty = 0; -+#if 0 - if (tty->ldisc.num != ldiscs[N_TTY].num) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -@@ -1245,6 +1239,7 @@ - if (tty->ldisc.open) - (tty->ldisc.open)(tty); - } -+#endif - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -diff -Naur linux-2.6.8.orig/drivers/serial/serial_core.c linux-2.6.8/drivers/serial/serial_core.c ---- linux-2.6.8.orig/drivers/serial/serial_core.c 2004-08-13 22:36:32.000000000 -0700 -+++ linux-2.6.8/drivers/serial/serial_core.c 2004-11-28 04:49:43.000000000 -0800 -@@ -107,15 +107,7 @@ - static void uart_tasklet_action(unsigned long data) - { - struct uart_state *state = (struct uart_state *)data; -- struct tty_struct *tty; -- -- tty = state->info->tty; -- if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- tty->ldisc.write_wakeup(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ tty_wakeup(state->info->tty); - } - - static inline void -@@ -581,10 +573,7 @@ - spin_lock_irqsave(&port->lock, flags); - uart_circ_clear(&state->info->xmit); - spin_unlock_irqrestore(&port->lock, flags); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1216,7 +1205,7 @@ - { - struct uart_state *state = tty->driver_data; - struct uart_port *port; -- -+ - BUG_ON(!kernel_locked()); - - if (!state || !state->port) -@@ -1239,12 +1228,12 @@ - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ -- printk("uart_close: bad serial port count; tty->count is 1, " -+ printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { -- printk("rs_close: bad serial port count for %s: %d\n", -+ printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n", - tty->name, state->count); - state->count = 0; - } -@@ -1280,8 +1269,9 @@ - - uart_shutdown(state); - uart_flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - state->info->tty = NULL; - -diff -Naur linux-2.6.8.orig/drivers/tc/zs.c linux-2.6.8/drivers/tc/zs.c ---- linux-2.6.8.orig/drivers/tc/zs.c 2004-08-13 22:37:39.000000000 -0700 -+++ linux-2.6.8/drivers/tc/zs.c 2004-11-28 04:49:43.000000000 -0800 -@@ -683,10 +683,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1010,10 +1007,7 @@ - cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1407,8 +1401,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Naur linux-2.6.8.orig/drivers/usb/class/bluetty.c linux-2.6.8/drivers/usb/class/bluetty.c ---- linux-2.6.8.orig/drivers/usb/class/bluetty.c 2004-08-13 22:37:37.000000000 -0700 -+++ linux-2.6.8/drivers/usb/class/bluetty.c 2004-11-28 04:49:43.000000000 -0800 -@@ -992,17 +992,10 @@ - - dbg("%s", __FUNCTION__); - -- if (!bluetooth) { -+ if (!bluetooth) - return; -- } -- -- tty = bluetooth->tty; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- dbg("%s - write wakeup call.", __FUNCTION__); -- (tty->ldisc.write_wakeup)(tty); -- } - -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(&bluetooth->tty); - } - - -diff -Naur linux-2.6.8.orig/drivers/usb/class/cdc-acm.c linux-2.6.8/drivers/usb/class/cdc-acm.c ---- linux-2.6.8.orig/drivers/usb/class/cdc-acm.c 2004-08-13 22:37:15.000000000 -0700 -+++ linux-2.6.8/drivers/usb/class/cdc-acm.c 2004-11-28 04:49:43.000000000 -0800 -@@ -248,16 +248,11 @@ - static void acm_softint(void *private) - { - struct acm *acm = private; -- struct tty_struct *tty = acm->tty; - dbg("Entering acm_softint.\n"); - - if (!ACM_READY(acm)) - return; -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(acm->tty); - } - - /* -diff -Naur linux-2.6.8.orig/drivers/usb/serial/digi_acceleport.c linux-2.6.8/drivers/usb/serial/digi_acceleport.c ---- linux-2.6.8.orig/drivers/usb/serial/digi_acceleport.c 2004-08-13 22:36:57.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/digi_acceleport.c 2004-11-28 04:49:43.000000000 -0800 -@@ -624,14 +624,7 @@ - wake_up_interruptible( &port->write_wait ); - - /* wake up line discipline */ -- if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup ) -- (tty->ldisc.write_wakeup)(tty); -- -- /* wake up other tty processes */ -- wake_up_interruptible( &tty->write_wait ); -- /* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */ -- -+ tty_wakeup(tty); - } - - -@@ -1569,8 +1562,7 @@ - /* flush driver and line discipline buffers */ - if( tty->driver->flush_buffer ) - tty->driver->flush_buffer( tty ); -- if( tty->ldisc.flush_buffer ) -- tty->ldisc.flush_buffer( tty ); -+ tty_ldisc_flush(tty); - - if (port->serial->dev) { - /* wait for transmit idle */ -diff -Naur linux-2.6.8.orig/drivers/usb/serial/empeg.c linux-2.6.8/drivers/usb/serial/empeg.c ---- linux-2.6.8.orig/drivers/usb/serial/empeg.c 2004-08-13 22:38:08.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/empeg.c 2004-11-28 04:49:43.000000000 -0800 -@@ -516,7 +516,9 @@ - */ - port->tty->low_latency = 1; - -- /* Notify the tty driver that the termios have changed. */ -+ /* Notify the tty driver that the termios have changed. -+ FIXME: Why - the ldisc will do this anyway and NULL is not -+ a valid previous state */ - port->tty->ldisc.set_termios(port->tty, NULL); - - return; -diff -Naur linux-2.6.8.orig/drivers/usb/serial/io_edgeport.c linux-2.6.8/drivers/usb/serial/io_edgeport.c ---- linux-2.6.8.orig/drivers/usb/serial/io_edgeport.c 2004-08-13 22:36:14.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/io_edgeport.c 2004-11-28 04:49:43.000000000 -0800 -@@ -900,12 +900,7 @@ - - if (tty && edge_port->open) { - /* let the tty driver wakeup if it has a special write_wakeup function */ -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- (tty->ldisc.write_wakeup)(tty); -- } -- -- /* tell the tty driver that something has changed */ -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - // Release the Write URB -diff -Naur linux-2.6.8.orig/drivers/usb/serial/io_ti.c linux-2.6.8/drivers/usb/serial/io_ti.c ---- linux-2.6.8.orig/drivers/usb/serial/io_ti.c 2004-08-13 22:38:08.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/io_ti.c 2004-11-28 04:49:43.000000000 -0800 -@@ -1804,12 +1804,7 @@ - tty = port->tty; - if (tty) { - /* let the tty driver wakeup if it has a special write_wakeup function */ -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- (tty->ldisc.write_wakeup)(tty); -- } -- -- /* tell the tty driver that something has changed */ -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Naur linux-2.6.8.orig/drivers/usb/serial/ir-usb.c linux-2.6.8/drivers/usb/serial/ir-usb.c ---- linux-2.6.8.orig/drivers/usb/serial/ir-usb.c 2004-08-13 22:36:57.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/ir-usb.c 2004-11-28 04:49:43.000000000 -0800 -@@ -449,6 +449,10 @@ - */ - tty = port->tty; - -+ /* -+ * FIXME: must not do this in IRQ context, -+ * must honour TTY_DONT_FLIP -+ */ - tty->ldisc.receive_buf( - tty, - data+1, -diff -Naur linux-2.6.8.orig/drivers/usb/serial/keyspan_pda.c linux-2.6.8/drivers/usb/serial/keyspan_pda.c ---- linux-2.6.8.orig/drivers/usb/serial/keyspan_pda.c 2004-08-13 22:37:25.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/keyspan_pda.c 2004-11-28 04:49:43.000000000 -0800 -@@ -186,13 +186,7 @@ - wake_up_interruptible( &port->write_wait ); - - /* wake up line discipline */ -- if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup ) -- (tty->ldisc.write_wakeup)(tty); -- -- /* wake up other tty processes */ -- wake_up_interruptible( &tty->write_wait ); -- /* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */ -+ tty_wakeup(tty); - } - - static void keyspan_pda_request_unthrottle( struct usb_serial *serial ) -diff -Naur linux-2.6.8.orig/drivers/usb/serial/mct_u232.c linux-2.6.8/drivers/usb/serial/mct_u232.c ---- linux-2.6.8.orig/drivers/usb/serial/mct_u232.c 2004-08-13 22:37:25.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/mct_u232.c 2004-11-28 04:49:43.000000000 -0800 -@@ -579,11 +579,7 @@ - - if (write_blocking) { - wake_up_interruptible(&port->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- -+ tty_wakeup(tty); - } else { - /* from generic_write_bulk_callback */ - schedule_work(&port->work); -diff -Naur linux-2.6.8.orig/drivers/usb/serial/usb-serial.c linux-2.6.8/drivers/usb/serial/usb-serial.c ---- linux-2.6.8.orig/drivers/usb/serial/usb-serial.c 2004-08-13 22:38:11.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/usb-serial.c 2004-11-28 04:49:43.000000000 -0800 -@@ -755,12 +755,7 @@ - if (!tty) - return; - -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- dbg("%s - write wakeup call.", __FUNCTION__); -- (tty->ldisc.write_wakeup)(tty); -- } -- -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - static void destroy_serial(struct kref *kref) -diff -Naur linux-2.6.8.orig/drivers/usb/serial/whiteheat.c linux-2.6.8/drivers/usb/serial/whiteheat.c ---- linux-2.6.8.orig/drivers/usb/serial/whiteheat.c 2004-08-13 22:36:45.000000000 -0700 -+++ linux-2.6.8/drivers/usb/serial/whiteheat.c 2004-11-28 04:49:43.000000000 -0800 -@@ -668,8 +668,7 @@ - - if (port->tty->driver->flush_buffer) - port->tty->driver->flush_buffer(port->tty); -- if (port->tty->ldisc.flush_buffer) -- port->tty->ldisc.flush_buffer(port->tty); -+ tty_ldisc_flush(port->tty); - - firm_report_tx_done(port); - -diff -Naur linux-2.6.8.orig/fs/proc/proc_tty.c linux-2.6.8/fs/proc/proc_tty.c ---- linux-2.6.8.orig/fs/proc/proc_tty.c 2004-08-13 22:36:56.000000000 -0700 -+++ linux-2.6.8/fs/proc/proc_tty.c 2004-11-28 04:49:43.000000000 -0800 -@@ -15,9 +15,6 @@ - #include - #include - --extern struct tty_ldisc ldiscs[]; -- -- - static int tty_ldiscs_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -@@ -159,12 +156,15 @@ - int i; - int len = 0; - off_t begin = 0; -- -+ struct tty_ldisc *ld; -+ - for (i=0; i < NR_LDISCS; i++) { -- if (!(ldiscs[i].flags & LDISC_FLAG_DEFINED)) -+ ld = tty_ldisc_get(i); -+ if (ld == NULL) - continue; - len += sprintf(page+len, "%-10s %2d\n", -- ldiscs[i].name ? ldiscs[i].name : "???", i); -+ ld->name ? ld->name : "???", i); -+ tty_ldisc_put(i); - if (len+begin > off+count) - break; - if (len+begin < off) { -diff -Naur linux-2.6.8.orig/include/linux/tty.h linux-2.6.8/include/linux/tty.h ---- linux-2.6.8.orig/include/linux/tty.h 2004-08-13 22:36:58.000000000 -0700 -+++ linux-2.6.8/include/linux/tty.h 2004-11-28 04:49:43.000000000 -0800 -@@ -306,26 +306,27 @@ - * tty->write. Thus, you must use the inline functions set_bit() and - * clear_bit() to make things atomic. - */ --#define TTY_THROTTLED 0 --#define TTY_IO_ERROR 1 --#define TTY_OTHER_CLOSED 2 --#define TTY_EXCLUSIVE 3 --#define TTY_DEBUG 4 --#define TTY_DO_WRITE_WAKEUP 5 --#define TTY_PUSH 6 --#define TTY_CLOSING 7 --#define TTY_DONT_FLIP 8 --#define TTY_HW_COOK_OUT 14 --#define TTY_HW_COOK_IN 15 --#define TTY_PTY_LOCK 16 --#define TTY_NO_WRITE_SPLIT 17 -+#define TTY_THROTTLED 0 /* Call unthrottle() at threshold min */ -+#define TTY_IO_ERROR 1 /* Canse an I/O error (may be no ldisc too) */ -+#define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ -+#define TTY_EXCLUSIVE 3 /* Exclusive open mode */ -+#define TTY_DEBUG 4 /* Debugging */ -+#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ -+#define TTY_PUSH 6 /* n_tty private */ -+#define TTY_CLOSING 7 /* ->close() in progress */ -+#define TTY_DONT_FLIP 8 /* Defer buffer flip */ -+#define TTY_LDISC 9 /* Line discipline attached */ -+#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ -+#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ -+#define TTY_PTY_LOCK 16 /* pty private */ -+#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ -+#define TTY_HUPPED 18 /* Post driver->hangup() */ - - #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) - - extern void tty_write_flush(struct tty_struct *); - - extern struct termios tty_std_termios; --extern struct tty_ldisc ldiscs[]; - extern int fg_console, last_console, want_console; - - extern int kmsg_redirect; -@@ -362,6 +363,16 @@ - extern int tty_get_baud_rate(struct tty_struct *tty); - extern int tty_termios_baud_rate(struct termios *termios); - -+extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); -+extern void tty_ldisc_deref(struct tty_ldisc *); -+extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); -+ -+extern struct tty_ldisc *tty_ldisc_get(int); -+extern void tty_ldisc_put(int); -+ -+extern void tty_wakeup(struct tty_struct *tty); -+extern void tty_ldisc_flush(struct tty_struct *tty); -+ - struct semaphore; - extern struct semaphore tty_sem; - -diff -Naur linux-2.6.8.orig/include/linux/tty_ldisc.h linux-2.6.8/include/linux/tty_ldisc.h ---- linux-2.6.8.orig/include/linux/tty_ldisc.h 2004-08-13 22:38:09.000000000 -0700 -+++ linux-2.6.8/include/linux/tty_ldisc.h 2004-11-28 04:49:43.000000000 -0800 -@@ -95,6 +95,13 @@ - * that line discpline should try to send more characters to the - * low-level driver for transmission. If the line discpline does - * not have any more data to send, it can just return. -+ * -+ * int (*hangup)(struct tty_struct *) -+ * -+ * Called on a hangup. Tells the discipline that it should -+ * cease I/O to the tty driver. Can sleep. The driver should -+ * seek to perform this action quickly but should wait until -+ * any pending driver I/O is completed. - */ - - #include -@@ -122,6 +129,7 @@ - void (*set_termios)(struct tty_struct *tty, struct termios * old); - unsigned int (*poll)(struct tty_struct *, struct file *, - struct poll_table_struct *); -+ int (*hangup)(struct tty_struct *tty); - - /* - * The following routines are called from below. -@@ -132,6 +140,8 @@ - void (*write_wakeup)(struct tty_struct *); - - struct module *owner; -+ -+ int refcount; - }; - - #define TTY_LDISC_MAGIC 0x5403 diff --git a/sys-kernel/hppa-dev-sources/files/CAN-2004-0814.patch b/sys-kernel/hppa-dev-sources/files/CAN-2004-0814.patch deleted file mode 100644 index ec94a9f6db3a..000000000000 --- a/sys-kernel/hppa-dev-sources/files/CAN-2004-0814.patch +++ /dev/null @@ -1,4365 +0,0 @@ -diff -Nur linux-2.6.8.1/Documentation/tty.txt linux-2.6.8.1-plasmaroo/Documentation/tty.txt ---- linux-2.6.8.1/Documentation/tty.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/Documentation/tty.txt 2004-11-06 22:55:10.540666520 +0000 -@@ -0,0 +1,194 @@ -+ -+ The Lockronomicon -+ -+Your guide to the ancient and twisted locking policies of the tty layer and -+the warped logic behind them. Beware all ye who read on. -+ -+FIXME: still need to work out the full set of BKL assumptions and document -+them so they can eventually be killed off. -+ -+ -+Line Discipline -+--------------- -+ -+Line disciplines are registered with tty_register_ldisc() passing the -+discipline number and the ldisc structure. At the point of registration the -+discipline must be ready to use and it is possible it will get used before -+the call returns success. If the call returns an error then it won't get -+called. Do not re-use ldisc numbers as they are part of the userspace ABI -+and writing over an existing ldisc will cause demons to eat your computer. -+After the return the ldisc data has been copied so you may free your own -+copy of the structure. You must not re-register over the top of the line -+discipline even with the same data or your computer again will be eaten by -+demons. -+ -+In order to remove a line discipline call tty_register_ldisc passing NULL. -+In ancient times this always worked. In modern times the function will -+return -EBUSY if the ldisc is currently in use. Since the ldisc referencing -+code manages the module counts this should not usually be a concern. -+ -+Heed this warning: the reference count field of the registered copies of the -+tty_ldisc structure in the ldisc table counts the number of lines using this -+discipline. The reference count of the tty_ldisc structure within a tty -+counts the number of active users of the ldisc at this instant. In effect it -+counts the number of threads of execution within an ldisc method (plus those -+about to enter and exit although this detail matters not). -+ -+Line Discipline Methods -+----------------------- -+ -+TTY side interfaces: -+ -+close() - This is called on a terminal when the line -+ discipline is being unplugged. At the point of -+ execution no further users will enter the -+ ldisc code for this tty. Can sleep. -+ -+open() - Called when the line discipline is attached to -+ the terminal. No other call into the line -+ discipline for this tty will occur until it -+ completes successfully. Can sleep. -+ -+write() - A process is writing data from user space -+ through the line discipline. Multiple write calls -+ are serialized by the tty layer for the ldisc. May -+ sleep. -+ -+flush_buffer() - May be called at any point between open and close. -+ -+chars_in_buffer() - Report the number of bytes in the buffer. -+ -+set_termios() - Called on termios structure changes. The caller -+ passes the old termios data and the current data -+ is in the tty. Called under the termios lock so -+ may not sleep. Serialized against itself only. -+ -+read() - Move data from the line discipline to the user. -+ Multiple read calls may occur in parallel and the -+ ldisc must deal with serialization issues. May -+ sleep. -+ -+poll() - Check the status for the poll/select calls. Multiple -+ poll calls may occur in parallel. May sleep. -+ -+ioctl() - Called when an ioctl is handed to the tty layer -+ that might be for the ldisc. Multiple ioctl calls -+ may occur in parallel. May sleep. -+ -+Driver Side Interfaces: -+ -+receive_buf() - Hand buffers of bytes from the driver to the ldisc -+ for processing. Semantics currently rather -+ mysterious 8( -+ -+receive_room() - Can be called by the driver layer at any time when -+ the ldisc is opened. The ldisc must be able to -+ handle the reported amount of data at that instant. -+ Synchronization between active receive_buf and -+ receive_room calls is down to the driver not the -+ ldisc. Must not sleep. -+ -+write_wakeup() - May be called at any point between open and close. -+ The TTY_DO_WRITE_WAKEUP flag indicates if a call -+ is needed but always races versus calls. Thus the -+ ldisc must be careful about setting order and to -+ handle unexpected calls. Must not sleep. -+ -+ -+Locking -+ -+Callers to the line discipline functions from the tty layer are required to -+take line discipline locks. The same is true of calls from the driver side -+but not yet enforced. -+ -+Three calls are now provided -+ -+ ldisc = tty_ldisc_ref(tty); -+ -+takes a handle to the line discipline in the tty and returns it. If no ldisc -+is currently attached or the ldisc is being closed and re-opened at this -+point then NULL is returned. While this handle is held the ldisc will not -+change or go away. -+ -+ tty_ldisc_deref(ldisc) -+ -+Returns the ldisc reference and allows the ldisc to be closed. Returning the -+reference takes away your right to call the ldisc functions until you take -+a new reference. -+ -+ ldisc = tty_ldisc_ref_wait(tty); -+ -+Performs the same function as tty_ldisc_ref except that it will wait for an -+ldisc change to complete and then return a reference to the new ldisc. -+ -+While these functions are slightly slower than the old code they should have -+minimal impact as most receive logic uses the flip buffers and they only -+need to take a reference when they push bits up through the driver. -+ -+A caution: The ldisc->open(), ldisc->close() and driver->set_ldisc -+functions are called with the ldisc unavailable. Thus tty_ldisc_ref will -+fail in this situation if used within these functions. Ldisc and driver -+code calling its own functions must be careful in this case. -+ -+ -+Driver Interface -+---------------- -+ -+open() - Called when a device is opened. May sleep -+ -+close() - Called when a device is closed. At the point of -+ return from this call the driver must make no -+ further ldisc calls of any kind. May sleep -+ -+write() - Called to write bytes to the device. May not -+ sleep. May occur in parallel in special cases. -+ Because this includes panic paths drivers generally -+ shouldn't try and do clever locking here. -+ -+put_char() - Stuff a single character onto the queue. The -+ driver is guaranteed following up calls to -+ flush_chars. -+ -+flush_chars() - Ask the kernel to write put_char queue -+ -+write_room() - Return the number of characters tht can be stuffed -+ into the port buffers without overflow (or less). -+ The ldisc is responsible for being intelligent -+ about multi-threading of write_room/write calls -+ -+ioctl() - Called when an ioctl may be for the driver -+ -+set_termios() - Called on termios change, may get parallel calls, -+ may block for now (may change that) -+ -+set_ldisc() - Notifier for discipline change. At the point this -+ is done the discipline is not yet usable. Can now -+ sleep (I think) -+ -+throttle() - Called by the ldisc to ask the driver to do flow -+ control. Serialization including with unthrottle -+ is the job of the ldisc layer. -+ -+unthrottle() - Called by the ldisc to ask the driver to stop flow -+ control. -+ -+stop() - Ldisc notifier to the driver to stop output. As with -+ throttle the serializations with start() are down -+ to the ldisc layer. -+ -+start() - Ldisc notifier to the driver to start output. -+ -+hangup() - Ask the tty driver to cause a hangup initiated -+ from the host side. [Can sleep ??] -+ -+break_ctl() - Send RS232 break. Can sleep. Can get called in -+ parallel, driver must serialize (for now), and -+ with write calls. -+ -+wait_until_sent() - Wait for characters to exit the hardware queue -+ of the driver. Can sleep -+ -+send_xchar() - Send XON/XOFF and if possible jump the queue with -+ it in order to get fast flow control responses. -+ Cannot sleep ?? -+ -diff -Nur linux-2.6.8.1/drivers/bluetooth/hci_ldisc.c linux-2.6.8.1-plasmaroo/drivers/bluetooth/hci_ldisc.c ---- linux-2.6.8.1/drivers/bluetooth/hci_ldisc.c 2004-08-14 11:55:48.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/bluetooth/hci_ldisc.c 2004-11-06 22:55:10.555664240 +0000 -@@ -188,9 +188,7 @@ - } - - /* Flush any pending characters in the driver and discipline. */ -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ tty_ldisc_flush(tty); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - -@@ -280,7 +278,9 @@ - - spin_lock_init(&hu->rx_lock); - -- /* Flush any pending characters in the driver and line discipline */ -+ /* Flush any pending characters in the driver and line discipline. */ -+ /* FIXME: why is this needed. Note don't use ldisc_ref here as the -+ open path is before the ldisc is referencable */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - -diff -Nur linux-2.6.8.1/drivers/char/amiserial.c linux-2.6.8.1-plasmaroo/drivers/char/amiserial.c ---- linux-2.6.8.1/drivers/char/amiserial.c 2004-08-14 11:56:24.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/amiserial.c 2004-11-06 22:55:10.582660136 +0000 -@@ -557,9 +557,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -1023,9 +1021,7 @@ - info->xmit.head = info->xmit.tail = 0; - local_irq_restore(flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1564,8 +1560,8 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Nur linux-2.6.8.1/drivers/char/cyclades.c linux-2.6.8.1-plasmaroo/drivers/char/cyclades.c ---- linux-2.6.8.1/drivers/char/cyclades.c 2004-08-14 11:54:51.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/cyclades.c 2004-11-06 22:55:10.593658464 +0000 -@@ -970,10 +970,7 @@ - wake_up_interruptible(&info->delta_msr_wait); - } - if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { -- if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup){ -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - #ifdef Z_WAKE -@@ -2850,8 +2847,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - CY_LOCK(info, flags); - - tty->closing = 0; -@@ -4554,10 +4550,8 @@ - } - CY_UNLOCK(info, flags); - } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); - } /* cy_flush_buffer */ - - -diff -Nur linux-2.6.8.1/drivers/char/epca.c linux-2.6.8.1-plasmaroo/drivers/char/epca.c ---- linux-2.6.8.1/drivers/char/epca.c 2004-08-14 11:55:33.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/epca.c 2004-11-06 22:55:10.608656184 +0000 -@@ -551,9 +551,7 @@ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ tty_ldisc_flush(tty); - shutdown(ch); - tty->closing = 0; - ch->event = 0; -@@ -657,10 +655,7 @@ - cli(); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ tty_ldisc_flush(tty); - shutdown(ch); - - ch->tty = NULL; -@@ -1120,8 +1115,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - - } /* End pc_flush_buffer */ - -@@ -2262,9 +2256,7 @@ - { /* Begin if LOWWAIT */ - - ch->statusflags &= ~LOWWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - - } /* End if LOWWAIT */ -@@ -2281,9 +2273,7 @@ - { /* Begin if EMPTYWAIT */ - - ch->statusflags &= ~EMPTYWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - - wake_up_interruptible(&tty->write_wait); - -@@ -3136,6 +3126,7 @@ - } - else - { -+ /* ldisc lock already held in ioctl */ - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - } -diff -Nur linux-2.6.8.1/drivers/char/esp.c linux-2.6.8.1-plasmaroo/drivers/char/esp.c ---- linux-2.6.8.1/drivers/char/esp.c 2004-08-14 11:54:46.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/esp.c 2004-11-06 22:55:10.625653600 +0000 -@@ -762,10 +762,7 @@ - return; - - if (test_and_clear_bit(ESP_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1370,10 +1367,7 @@ - cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -2069,8 +2063,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = NULL; -diff -Nur linux-2.6.8.1/drivers/char/generic_serial.c linux-2.6.8.1-plasmaroo/drivers/char/generic_serial.c ---- linux-2.6.8.1/drivers/char/generic_serial.c 2004-08-14 11:55:32.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/generic_serial.c 2004-11-06 22:55:10.630652840 +0000 -@@ -436,9 +436,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - func_exit (); - } - -@@ -578,9 +576,7 @@ - if (!tty) return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - func_exit (); -@@ -694,8 +690,8 @@ - { - unsigned long flags; - struct gs_port *port; -- -- func_enter (); -+ -+ func_enter () - - if (!tty) return; - -@@ -760,8 +756,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - - port->event = 0; -diff -Nur linux-2.6.8.1/drivers/char/hvc_console.c linux-2.6.8.1-plasmaroo/drivers/char/hvc_console.c ---- linux-2.6.8.1/drivers/char/hvc_console.c 2004-08-14 11:56:00.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/hvc_console.c 2004-11-06 22:56:30.270545736 +0000 -@@ -248,10 +248,7 @@ - - if (hp->do_wakeup) { - hp->do_wakeup = 0; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Nur linux-2.6.8.1/drivers/char/hvcs.c linux-2.6.8.1-plasmaroo/drivers/char/hvcs.c ---- linux-2.6.8.1/drivers/char/hvcs.c 2004-08-14 11:55:33.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/hvcs.c 2004-11-06 22:55:10.652649496 +0000 -@@ -393,10 +393,7 @@ - * a non-existent tty. - */ - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - } -diff -Nur linux-2.6.8.1/drivers/char/isicom.c linux-2.6.8.1-plasmaroo/drivers/char/isicom.c ---- linux-2.6.8.1/drivers/char/isicom.c 2004-08-14 11:54:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/isicom.c 2004-11-06 22:55:10.655649040 +0000 -@@ -484,10 +484,8 @@ - - if (!tty) - return; -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -1119,8 +1117,8 @@ - isicom_shutdown_port(port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - port->tty = NULL; - if (port->blocked_open) { -@@ -1563,9 +1561,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - -diff -Nur linux-2.6.8.1/drivers/char/moxa.c linux-2.6.8.1-plasmaroo/drivers/char/moxa.c ---- linux-2.6.8.1/drivers/char/moxa.c 2004-08-14 11:56:22.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/moxa.c 2004-11-06 22:55:10.660648280 +0000 -@@ -618,8 +618,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - ch->event = 0; - ch->tty = NULL; -@@ -693,9 +693,7 @@ - if (ch == NULL) - return; - MoxaPortFlushData(ch->port, 1); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -954,9 +952,7 @@ - if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) { - if (!tp->stopped) { - ch->statusflags &= ~LOWWAIT; -- if ((tp->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tp->ldisc.write_wakeup) -- (tp->ldisc.write_wakeup) (tp); -+ tty_wakeup(tty); - wake_up_interruptible(&tp->write_wait); - } - } -@@ -1123,9 +1119,7 @@ - if (ch->tty && (ch->statusflags & EMPTYWAIT)) { - if (MoxaPortTxQueue(ch->port) == 0) { - ch->statusflags &= ~EMPTYWAIT; -- if ((ch->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- ch->tty->ldisc.write_wakeup) -- (ch->tty->ldisc.write_wakeup) (ch->tty); -+ tty_wakeup(tty); - wake_up_interruptible(&ch->tty->write_wait); - return; - } -diff -Nur linux-2.6.8.1/drivers/char/mxser.c linux-2.6.8.1-plasmaroo/drivers/char/mxser.c ---- linux-2.6.8.1/drivers/char/mxser.c 2004-08-14 11:55:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/mxser.c 2004-11-06 22:55:10.670646760 +0000 -@@ -678,9 +678,7 @@ - tty = info->tty; - if (tty) { - if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event)) { -@@ -817,8 +815,8 @@ - mxser_shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - info->event = 0; - info->tty = NULL; -@@ -976,9 +974,7 @@ - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - } - - static int mxser_ioctl(struct tty_struct *tty, struct file *file, -diff -Nur linux-2.6.8.1/drivers/char/n_tty.c linux-2.6.8.1-plasmaroo/drivers/char/n_tty.c ---- linux-2.6.8.1/drivers/char/n_tty.c 2004-08-14 11:54:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/n_tty.c 2004-11-06 22:55:10.684644632 +0000 -@@ -99,11 +99,18 @@ - spin_unlock_irqrestore(&tty->read_lock, flags); - } - --/* -- * Check whether to call the driver.unthrottle function. -- * We test the TTY_THROTTLED bit first so that it always -- * indicates the current state. -+/** -+ * check_unthrottle - allow new receive data -+ * @tty; tty device -+ * -+ * Check whether to call the driver.unthrottle function. -+ * We test the TTY_THROTTLED bit first so that it always -+ * indicates the current state. The decision about whether -+ * it is worth allowing more input has been taken by the caller. -+ * Can sleep, may be called under the atomic_read semaphore but -+ * this is not guaranteed. - */ -+ - static void check_unthrottle(struct tty_struct * tty) - { - if (tty->count && -@@ -112,10 +119,13 @@ - tty->driver->unthrottle(tty); - } - --/* -- * Reset the read buffer counters, clear the flags, -- * and make sure the driver is unthrottled. Called -- * from n_tty_open() and n_tty_flush_buffer(). -+/** -+ * reset_buffer_flags - reset buffer state -+ * @tty: terminal to reset -+ * -+ * Reset the read buffer counters, clear the flags, -+ * and make sure the driver is unthrottled. Called -+ * from n_tty_open() and n_tty_flush_buffer(). - */ - static void reset_buffer_flags(struct tty_struct *tty) - { -@@ -129,9 +139,19 @@ - check_unthrottle(tty); - } - --/* -- * Flush the input buffer -+/** -+ * n_tty_flush_buffer - clean input queue -+ * @tty: terminal device -+ * -+ * Flush the input buffer. Called when the line discipline is -+ * being closed, when the tty layer wants the buffer flushed (eg -+ * at hangup) or when the N_TTY line discipline internally has to -+ * clean the pending queue (for example some signals). -+ * -+ * FIXME: tty->ctrl_status is not spinlocked and relies on -+ * lock_kernel() still. - */ -+ - void n_tty_flush_buffer(struct tty_struct * tty) - { - /* clear everything and unthrottle the driver */ -@@ -146,9 +166,14 @@ - } - } - --/* -- * Return number of characters buffered to be delivered to user -+/** -+ * n_tty_chars_in_buffer - report available bytes -+ * @tty: tty device -+ * -+ * Report the number of characters buffered to be delivered to user -+ * at this instant in time. - */ -+ - ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) - { - unsigned long flags; -@@ -166,20 +191,47 @@ - return n; - } - -+/** -+ * is_utf8_continuation - utf8 multibyte check -+ * @c: byte to check -+ * -+ * Returns true if the utf8 character 'c' is a multibyte continuation -+ * character. We use this to correctly compute the on screen size -+ * of the character when printing -+ */ -+ - static inline int is_utf8_continuation(unsigned char c) - { - return (c & 0xc0) == 0x80; - } - -+/** -+ * is_continuation - multibyte check -+ * @c: byte to check -+ * -+ * Returns true if the utf8 character 'c' is a multibyte continuation -+ * character and the terminal is in unicode mode. -+ */ -+ - static inline int is_continuation(unsigned char c, struct tty_struct *tty) - { - return I_IUTF8(tty) && is_utf8_continuation(c); - } - --/* -- * Perform OPOST processing. Returns -1 when the output device is -- * full and the character must be retried. -+/** -+ * opost - output post processor -+ * @c: character (or partial unicode symbol) -+ * @tty: terminal device -+ * -+ * Perform OPOST processing. Returns -1 when the output device is -+ * full and the character must be retried. Note that Linux currently -+ * ignores TABDLY, CRDLY, VTDLY, FFDLY and NLDLY. They simply aren't -+ * relevant in the world today. If you ever need them, add them here. -+ * -+ * Called from both the receive and transmit sides and can be called -+ * re-entrantly. Relies on lock_kernel() still. - */ -+ - static int opost(unsigned char c, struct tty_struct *tty) - { - int space, spaces; -@@ -239,10 +291,20 @@ - return 0; - } - --/* -- * opost_block --- to speed up block console writes, among other -- * things. -+/** -+ * opost_block - block postprocess -+ * @tty: terminal device -+ * @inbuf: user buffer -+ * @nr: number of bytes -+ * -+ * This path is used to speed up block console writes, among other -+ * things when processing blocks of output data. It handles only -+ * the simple cases normally found and helps to generate blocks of -+ * symbols for the console driver and thus improve performance. -+ * -+ * Called from write_chan under the tty layer write lock. - */ -+ - static ssize_t opost_block(struct tty_struct * tty, - const unsigned char __user * inbuf, unsigned int nr) - { -@@ -304,13 +366,27 @@ - } - - -- -+/** -+ * put_char - write character to driver -+ * @c: character (or part of unicode symbol) -+ * @tty: terminal device -+ * -+ * Queue a byte to the driver layer for output -+ */ -+ - static inline void put_char(unsigned char c, struct tty_struct *tty) - { - tty->driver->put_char(tty, c); - } - --/* Must be called only when L_ECHO(tty) is true. */ -+/** -+ * echo_char - echo characters -+ * @c: unicode byte to echo -+ * @tty: terminal device -+ * -+ * Echo user input back onto the screen. This must be called only when -+ * L_ECHO(tty) is true. Called from the driver receive_buf path. -+ */ - - static void echo_char(unsigned char c, struct tty_struct *tty) - { -@@ -331,6 +407,16 @@ - } - } - -+/** -+ * eraser - handle erase function -+ * @c: character input -+ * @tty: terminal device -+ * -+ * Perform erase and neccessary output when an erase character is -+ * present in the stream from the driver layer. Handles the complexities -+ * of UTF-8 multibyte symbols. -+ */ -+ - static void eraser(unsigned char c, struct tty_struct *tty) - { - enum { ERASE, WERASE, KILL } kill_type; -@@ -463,6 +549,18 @@ - finish_erasing(tty); - } - -+/** -+ * isig - handle the ISIG optio -+ * @sig: signal -+ * @tty: terminal -+ * @flush: force flush -+ * -+ * Called when a signal is being sent due to terminal input. This -+ * may caus terminal flushing to take place according to the termios -+ * settings and character used. Called from the driver receive_buf -+ * path so serialized. -+ */ -+ - static inline void isig(int sig, struct tty_struct *tty, int flush) - { - if (tty->pgrp > 0) -@@ -474,6 +572,16 @@ - } - } - -+/** -+ * n_tty_receive_break - handle break -+ * @tty: terminal -+ * -+ * An RS232 break event has been hit in the incoming bitstream. This -+ * can cause a variety of events depending upon the termios settings. -+ * -+ * Called from the receive_buf path so single threaded. -+ */ -+ - static inline void n_tty_receive_break(struct tty_struct *tty) - { - if (I_IGNBRK(tty)) -@@ -490,19 +598,40 @@ - wake_up_interruptible(&tty->read_wait); - } - -+/** -+ * n_tty_receive_overrun - handle overrun reporting -+ * @tty: terminal -+ * -+ * Data arrived faster than we could process it. While the tty -+ * driver has flagged this the bits that were missed are gone -+ * forever. -+ * -+ * Called from the receive_buf path so single threaded. Does not -+ * need locking as num_overrun and overrun_time are function -+ * private. -+ */ -+ - static inline void n_tty_receive_overrun(struct tty_struct *tty) - { - char buf[64]; - - tty->num_overrun++; - if (time_before(tty->overrun_time, jiffies - HZ)) { -- printk("%s: %d input overrun(s)\n", tty_name(tty, buf), -+ printk(KERN_WARNING "%s: %d input overrun(s)\n", tty_name(tty, buf), - tty->num_overrun); - tty->overrun_time = jiffies; - tty->num_overrun = 0; - } - } - -+/** -+ * n_tty_receive_parity_error - error notifier -+ * @tty: terminal device -+ * @c: character -+ * -+ * Process a parity error and queue the right data to indicate -+ * the error case if neccessary. Locking as per n_tty_receive_buf. -+ */ - static inline void n_tty_receive_parity_error(struct tty_struct *tty, - unsigned char c) - { -@@ -520,6 +649,16 @@ - wake_up_interruptible(&tty->read_wait); - } - -+/** -+ * n_tty_receive_char - perform processing -+ * @tty: terminal device -+ * @c: character -+ * -+ * Process an individual character of input received from the driver. -+ * This is serialized with respect to itself by the rules for the -+ * driver above. -+ */ -+ - static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) - { - unsigned long flags; -@@ -711,6 +850,16 @@ - put_tty_queue(c, tty); - } - -+/** -+ * n_tty_receive_room - receive space -+ * @tty: terminal -+ * -+ * Called by the driver to find out how much data it is -+ * permitted to feed to the line discipline without any being lost -+ * and thus to manage flow control. Not serialized. Answers for the -+ * "instant". -+ */ -+ - static int n_tty_receive_room(struct tty_struct *tty) - { - int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; -@@ -729,10 +878,13 @@ - return 0; - } - --/* -- * Required for the ptys, serial driver etc. since processes -- * that attach themselves to the master and rely on ASYNC -- * IO must be woken up -+/** -+ * n_tty_write_wakeup - asynchronous I/O notifier -+ * @tty: tty device -+ * -+ * Required for the ptys, serial driver etc. since processes -+ * that attach themselves to the master and rely on ASYNC -+ * IO must be woken up - */ - - static void n_tty_write_wakeup(struct tty_struct *tty) -@@ -745,6 +897,19 @@ - return; - } - -+/** -+ * n_tty_receive_buf - data receive -+ * @tty: terminal device -+ * @cp: buffer -+ * @fp: flag buffer -+ * @count: characters -+ * -+ * Called by the terminal driver when a block of characters has -+ * been received. This function must be called from soft contexts -+ * not from interrupt context. The driver is responsible for making -+ * calls one at a time and in order (or using flush_to_ldisc) -+ */ -+ - static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) - { -@@ -828,6 +993,18 @@ - current->sighand->action[sig-1].sa.sa_handler == SIG_IGN); - } - -+/** -+ * n_tty_set_termios - termios data changed -+ * @tty: terminal -+ * @old: previous data -+ * -+ * Called by the tty layer when the user changes termios flags so -+ * that the line discipline can plan ahead. This function cannot sleep -+ * and is protected from re-entry by the tty layer. The user is -+ * guaranteed that this function will not be re-entered or in progress -+ * when the ldisc is closed. -+ */ -+ - static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) - { - if (!tty) -@@ -843,7 +1020,6 @@ - I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) || - I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) || - I_PARMRK(tty)) { -- local_irq_disable(); // FIXME: is this safe? - memset(tty->process_char_map, 0, 256/8); - - if (I_IGNCR(tty) || I_ICRNL(tty)) -@@ -879,7 +1055,6 @@ - set_bit(SUSP_CHAR(tty), tty->process_char_map); - } - clear_bit(__DISABLED_CHAR, tty->process_char_map); -- local_irq_enable(); // FIXME: is this safe? - tty->raw = 0; - tty->real_raw = 0; - } else { -@@ -893,6 +1068,16 @@ - } - } - -+/** -+ * n_tty_close - close the ldisc for this tty -+ * @tty: device -+ * -+ * Called from the terminal layer when this line discipline is -+ * being shut down, either because of a close or becsuse of a -+ * discipline change. The function will not be called while other -+ * ldisc methods are in progress. -+ */ -+ - static void n_tty_close(struct tty_struct *tty) - { - n_tty_flush_buffer(tty); -@@ -902,11 +1087,22 @@ - } - } - -+/** -+ * n_tty_open - open an ldisc -+ * @tty: terminal to open -+ * -+ * Called when this line discipline is being attached to the -+ * terminal device. Can sleep. Called serialized so that no -+ * other events will occur in parallel. No further open will occur -+ * until a close. -+ */ -+ - static int n_tty_open(struct tty_struct *tty) - { - if (!tty) - return -EINVAL; - -+ /* This one is ugly. Currently a malloc failure here can panic */ - if (!tty->read_buf) { - tty->read_buf = alloc_buf(); - if (!tty->read_buf) -@@ -932,14 +1128,23 @@ - return 0; - } - --/* -- * Helper function to speed up read_chan. It is only called when -- * ICANON is off; it copies characters straight from the tty queue to -- * user space directly. It can be profitably called twice; once to -- * drain the space from the tail pointer to the (physical) end of the -- * buffer, and once to drain the space from the (physical) beginning of -- * the buffer to head pointer. -+/** -+ * copy_from_read_buf - copy read data directly -+ * @tty: terminal device -+ * @b: user data -+ * @nr: size of data -+ * -+ * Helper function to speed up read_chan. It is only called when -+ * ICANON is off; it copies characters straight from the tty queue to -+ * user space directly. It can be profitably called twice; once to -+ * drain the space from the tail pointer to the (physical) end of the -+ * buffer, and once to drain the space from the (physical) beginning of -+ * the buffer to head pointer. -+ * -+ * Called under the tty->atomic_read sem and with TTY_DONT_FLIP set -+ * - */ -+ - static inline int copy_from_read_buf(struct tty_struct *tty, - unsigned char __user **b, - size_t *nr) -@@ -970,25 +1175,18 @@ - - extern ssize_t redirected_tty_write(struct file *,const char *,size_t,loff_t *); - --static ssize_t read_chan(struct tty_struct *tty, struct file *file, -- unsigned char __user *buf, size_t nr) -+/** -+ * job_control - check job control -+ * @tty: tty -+ * @file: file handle -+ * -+ * Perform job control management checks on this file/tty descriptor -+ * and if appropriate send any needed signals and return a negative -+ * error code if action should be taken. -+ */ -+ -+static int job_control(struct tty_struct *tty, struct file *file) - { -- unsigned char __user *b = buf; -- DECLARE_WAITQUEUE(wait, current); -- int c; -- int minimum, time; -- ssize_t retval = 0; -- ssize_t size; -- long timeout; -- unsigned long flags; -- --do_it_again: -- -- if (!tty->read_buf) { -- printk("n_tty_read_chan: called with read_buf == NULL?!?\n"); -- return -EIO; -- } -- - /* Job control check -- must be done at start and after - every sleep (POSIX.1 7.1.1.4). */ - /* NOTE: not yet done after every sleep pending a thorough -@@ -1006,7 +1204,48 @@ - return -ERESTARTSYS; - } - } -+ return 0; -+} -+ -+ -+/** -+ * read_chan - read function for tty -+ * @tty: tty device -+ * @file: file object -+ * @buf: userspace buffer pointer -+ * @nr: size of I/O -+ * -+ * Perform reads for the line discipline. We are guaranteed that the -+ * line discipline will not be closed under us but we may get multiple -+ * parallel readers and must handle this ourselves. We may also get -+ * a hangup. Always called in user context, may sleep. -+ * -+ * This code must be sure never to sleep through a hangup. -+ */ -+ -+static ssize_t read_chan(struct tty_struct *tty, struct file *file, -+ unsigned char __user *buf, size_t nr) -+{ -+ unsigned char __user *b = buf; -+ DECLARE_WAITQUEUE(wait, current); -+ int c; -+ int minimum, time; -+ ssize_t retval = 0; -+ ssize_t size; -+ long timeout; -+ unsigned long flags; -+ -+do_it_again: -+ -+ if (!tty->read_buf) { -+ printk("n_tty_read_chan: called with read_buf == NULL?!?\n"); -+ return -EIO; -+ } - -+ c = job_control(tty, file); -+ if(c < 0) -+ return c; -+ - minimum = time = 0; - timeout = MAX_SCHEDULE_TIMEOUT; - if (!tty->icanon) { -@@ -1028,6 +1267,9 @@ - } - } - -+ /* -+ * Internal serialization of reads. -+ */ - if (file->f_flags & O_NONBLOCK) { - if (down_trylock(&tty->atomic_read)) - return -EAGAIN; -@@ -1177,6 +1419,21 @@ - return retval; - } - -+/** -+ * write_chan - write function for tty -+ * @tty: tty device -+ * @file: file object -+ * @buf: userspace buffer pointer -+ * @nr: size of I/O -+ * -+ * Write function of the terminal device. This is serialized with -+ * respect to other write callers but not to termios changes, reads -+ * and other such events. We must be careful with N_TTY as the receive -+ * code will echo characters, thus calling driver write methods. -+ * -+ * This code must be sure never to sleep through a hangup. -+ */ -+ - static ssize_t write_chan(struct tty_struct * tty, struct file * file, - const unsigned char __user * buf, size_t nr) - { -@@ -1246,7 +1503,25 @@ - return (b - buf) ? b - buf : retval; - } - --/* Called without the kernel lock held - fine */ -+/** -+ * normal_poll - poll method for N_TTY -+ * @tty: terminal device -+ * @file: file accessing it -+ * @wait: poll table -+ * -+ * Called when the line discipline is asked to poll() for data or -+ * for special events. This code is not serialized with respect to -+ * other events save open/close. -+ * -+ * This code must be sure never to sleep through a hangup. -+ * Called without the kernel lock held - fine -+ * -+ * FIXME: if someone changes the VMIN or discipline settings for the -+ * terminal while another process is in poll() the poll does not -+ * recompute the new limits. Possibly set_termios should issue -+ * a read wakeup to fix this bug. -+ */ -+ - static unsigned int normal_poll(struct tty_struct * tty, struct file * file, poll_table *wait) - { - unsigned int mask = 0; -@@ -1287,6 +1562,7 @@ - n_tty_ioctl, /* ioctl */ - n_tty_set_termios, /* set_termios */ - normal_poll, /* poll */ -+ NULL, /* hangup */ - n_tty_receive_buf, /* receive_buf */ - n_tty_receive_room, /* receive_room */ - n_tty_write_wakeup /* write_wakeup */ -diff -Nur linux-2.6.8.1/drivers/char/pcmcia/synclink_cs.c linux-2.6.8.1-plasmaroo/drivers/char/pcmcia/synclink_cs.c ---- linux-2.6.8.1/drivers/char/pcmcia/synclink_cs.c 2004-08-14 11:55:10.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/pcmcia/synclink_cs.c 2004-11-06 22:55:10.696642808 +0000 -@@ -531,6 +531,40 @@ - return mgslpc_get_text_ptr; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_flush_buffer - flush line discipline receive buffers -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_flush_buffer(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+} -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - static dev_link_t *mgslpc_attach(void) - { - MGSLPC_INFO *info; -@@ -984,13 +1018,7 @@ - printk("bh_transmit() entry on %s\n", info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):calling ldisc.write_wakeup on %s\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -1875,11 +1903,9 @@ - info->tx_count = info->tx_put = info->tx_get = 0; - del_timer(&info->tx_timer); - spin_unlock_irqrestore(&info->lock,flags); -- -+ - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* Send a high-priority XON/XOFF character -@@ -2588,9 +2614,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ ldisc_flush_buffer(tty); - - shutdown(info); - -@@ -4059,11 +4084,7 @@ - } - else - #endif -- { -- /* Call the line discipline receive callback directly. */ -- if (tty && tty->ldisc.receive_buf) -- tty->ldisc.receive_buf(tty, buf->data, info->flag_buf, framesize); -- } -+ ldisc_receive_buf(tty, buf->data, info->flag_buf, framesize); - } - } - -diff -Nur linux-2.6.8.1/drivers/char/pcxx.c linux-2.6.8.1-plasmaroo/drivers/char/pcxx.c ---- linux-2.6.8.1/drivers/char/pcxx.c 2004-08-14 11:55:34.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/pcxx.c 2004-11-06 22:55:10.705641440 +0000 -@@ -538,28 +538,11 @@ - - if(tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if(tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - shutdown(info); - tty->closing = 0; - info->event = 0; - info->tty = NULL; --#ifndef MODULE --/* ldiscs[] is not available in a MODULE --** worth noting that while I'm not sure what this hunk of code is supposed --** to do, it is not present in the serial.c driver. Hmmm. If you know, --** please send me a note. brian@ilinx.com --** Don't know either what this is supposed to do christoph@lameter.com. --*/ -- if(tty->ldisc.num != ldiscs[N_TTY].num) { -- if(tty->ldisc.close) -- (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -- if(tty->ldisc.open) -- (tty->ldisc.open)(tty); -- } --#endif - if(info->blocked_open) { - if(info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -@@ -800,9 +783,7 @@ - memoff(ch); - restore_flags(flags); - -- wake_up_interruptible(&tty->write_wait); -- if((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - static void pcxe_flush_chars(struct tty_struct *tty) -@@ -1675,10 +1656,7 @@ - if (event & LOWTX_IND) { - if (ch->statusflags & LOWWAIT) { - ch->statusflags &= ~LOWWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1686,10 +1664,7 @@ - ch->statusflags &= ~TXBUSY; - if (ch->statusflags & EMPTYWAIT) { - ch->statusflags &= ~EMPTYWAIT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - } -@@ -2165,8 +2140,7 @@ - tty_wait_until_sent(tty, 0); - } - else { -- if(tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - } - - /* Fall Thru */ -diff -Nur linux-2.6.8.1/drivers/char/pty.c linux-2.6.8.1-plasmaroo/drivers/char/pty.c ---- linux-2.6.8.1/drivers/char/pty.c 2004-08-14 11:55:10.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/pty.c 2004-11-06 22:55:10.707641136 +0000 -@@ -91,10 +91,7 @@ - if (!o_tty) - return; - -- if ((o_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- o_tty->ldisc.write_wakeup) -- (o_tty->ldisc.write_wakeup)(o_tty); -- wake_up_interruptible(&o_tty->write_wait); -+ tty_wakeup(o_tty); - set_bit(TTY_THROTTLED, &tty->flags); - } - -@@ -107,6 +104,10 @@ - * (2) avoid redundant copying for cases where count >> receive_room - * N.B. Calls from user space may now return an error code instead of - * a count. -+ * -+ * FIXME: Our pty_write method is called with our ldisc lock held but -+ * not our partners. We can't just take the other one blindly without -+ * risking deadlocks. There is also the small matter of TTY_DONT_FLIP - */ - static int pty_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -diff -Nur linux-2.6.8.1/drivers/char/riscom8.c linux-2.6.8.1-plasmaroo/drivers/char/riscom8.c ---- linux-2.6.8.1/drivers/char/riscom8.c 2004-08-14 11:55:31.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/riscom8.c 2004-11-06 22:55:10.723638704 +0000 -@@ -1127,8 +1127,8 @@ - rc_shutdown_port(bp, port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - port->event = 0; - port->tty = NULL; -@@ -1301,9 +1301,7 @@ - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - static int rc_tiocmget(struct tty_struct *tty, struct file *file) -@@ -1644,9 +1642,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -diff -Nur linux-2.6.8.1/drivers/char/rocket.c linux-2.6.8.1-plasmaroo/drivers/char/rocket.c ---- linux-2.6.8.1/drivers/char/rocket.c 2004-08-14 11:55:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/rocket.c 2004-11-06 22:55:10.736636728 +0000 -@@ -250,12 +250,16 @@ - CHANNEL_t * cp, unsigned int ChanStatus) - { - unsigned int CharNStat; -- int ToRecv, wRecv, space, count; -+ int ToRecv, wRecv, space = 0, count; - unsigned char *cbuf; - char *fbuf; -+ struct tty_ldisc *ld; -+ -+ ld = tty_ldisc_ref(tty); - - ToRecv = sGetRxCnt(cp); -- space = tty->ldisc.receive_room(tty); -+ if (ld) -+ space = ld->receive_room(tty); - if (space > 2 * TTY_FLIPBUF_SIZE) - space = 2 * TTY_FLIPBUF_SIZE; - cbuf = tty->flip.char_buf; -@@ -354,7 +358,8 @@ - count += ToRecv; - } - /* Push the data up to the tty layer */ -- tty->ldisc.receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); -+ ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); -+ tty_ldisc_deref(ld); - } - - /* -@@ -408,8 +413,7 @@ - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - - if (info->xmit_cnt < WAKEUP_CHARS) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - #ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -@@ -1022,7 +1026,7 @@ - unsigned long flags; - int timeout; - CHANNEL_t *cp; -- -+ - if (rocket_paranoia_check(info, "rp_close")) - return; - -@@ -1101,8 +1105,8 @@ - - if (TTY_DRIVER_FLUSH_BUFFER_EXISTS(tty)) - TTY_DRIVER_FLUSH_BUFFER(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - -@@ -1731,8 +1735,7 @@ - - end: - if (info->xmit_cnt < WAKEUP_CHARS) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - #ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -@@ -1806,8 +1809,7 @@ - #ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); - #endif -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - - cp = &info->channel; - sFlushTxFIFO(cp); -diff -Nur linux-2.6.8.1/drivers/char/selection.c linux-2.6.8.1-plasmaroo/drivers/char/selection.c ---- linux-2.6.8.1/drivers/char/selection.c 2004-08-14 11:56:22.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/selection.c 2004-11-06 22:55:10.747635056 +0000 -@@ -281,12 +281,15 @@ - { - struct vt_struct *vt = (struct vt_struct *) tty->driver_data; - int pasted = 0, count; -+ struct tty_ldisc *ld; - DECLARE_WAITQUEUE(wait, current); - - acquire_console_sem(); - poke_blanked_console(); - release_console_sem(); - -+ ld = tty_ldisc_ref_wait(tty); -+ - add_wait_queue(&vt->paste_wait, &wait); - while (sel_buffer && sel_buffer_lth > pasted) { - set_current_state(TASK_INTERRUPTIBLE); -@@ -301,6 +304,8 @@ - } - remove_wait_queue(&vt->paste_wait, &wait); - current->state = TASK_RUNNING; -+ -+ tty_ldisc_deref(ld); - return 0; - } - -diff -Nur linux-2.6.8.1/drivers/char/ser_a2232.c linux-2.6.8.1-plasmaroo/drivers/char/ser_a2232.c ---- linux-2.6.8.1/drivers/char/ser_a2232.c 2004-08-14 11:55:09.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/ser_a2232.c 2004-11-06 22:55:10.748634904 +0000 -@@ -599,10 +599,7 @@ - - /* WakeUp if output buffer runs low */ - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && port->gs.tty->ldisc.write_wakeup){ -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -- } -- wake_up_interruptible(&port->gs.tty->write_wait); -+ tty_wakeup(port->gs.tty); - } - } // if the port is used - } // for every port on the board -diff -Nur linux-2.6.8.1/drivers/char/serial167.c linux-2.6.8.1-plasmaroo/drivers/char/serial167.c ---- linux-2.6.8.1/drivers/char/serial167.c 2004-08-14 11:55:20.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/serial167.c 2004-11-06 22:55:10.756633688 +0000 -@@ -760,11 +760,7 @@ - wake_up_interruptible(&info->open_wait); - } - if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { -- if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup){ -- (tty->ldisc.write_wakeup)(tty); -- } -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } /* do_softint */ - -@@ -1343,10 +1339,7 @@ - local_irq_save(flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } /* cy_flush_buffer */ - - -@@ -1846,18 +1839,9 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - info->event = 0; - info->tty = 0; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -- if (tty->ldisc.close) -- (tty->ldisc.close)(tty); -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -- if (tty->ldisc.open) -- (tty->ldisc.open)(tty); -- } - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -diff -Nur linux-2.6.8.1/drivers/char/serial_tx3912.c linux-2.6.8.1-plasmaroo/drivers/char/serial_tx3912.c ---- linux-2.6.8.1/drivers/char/serial_tx3912.c 2004-08-14 11:55:33.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/serial_tx3912.c 2004-11-06 22:55:10.758633384 +0000 -@@ -191,12 +191,9 @@ - } - - if (port->gs.xmit_cnt <= port->gs.wakeup_chars) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- port->gs.tty->ldisc.write_wakeup) -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -+ tty_wakeup(port->gs.tty); - rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", - port->gs.wakeup_chars); -- wake_up_interruptible(&port->gs.tty->write_wait); - } - } - -diff -Nur linux-2.6.8.1/drivers/char/specialix.c linux-2.6.8.1-plasmaroo/drivers/char/specialix.c ---- linux-2.6.8.1/drivers/char/specialix.c 2004-08-14 11:56:09.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/specialix.c 2004-11-06 22:55:10.762632776 +0000 -@@ -1468,8 +1468,7 @@ - sx_shutdown_port(bp, port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - port->event = 0; - port->tty = NULL; -@@ -1646,10 +1645,8 @@ - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - restore_flags(flags); - -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); - } - - -@@ -2052,12 +2049,8 @@ - if(!(tty = port->tty)) - return; - -- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) -+ tty_wakeup(tty); - } - - static struct tty_operations sx_ops = { -diff -Nur linux-2.6.8.1/drivers/char/stallion.c linux-2.6.8.1-plasmaroo/drivers/char/stallion.c ---- linux-2.6.8.1/drivers/char/stallion.c 2004-08-14 11:55:48.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/stallion.c 2004-11-06 22:55:10.774630952 +0000 -@@ -1197,8 +1197,7 @@ - portp->tx.tail = (char *) NULL; - } - set_bit(TTY_IO_ERROR, &tty->flags); -- if (tty->ldisc.flush_buffer) -- (tty->ldisc.flush_buffer)(tty); -+ tty_ldisc_flush(tty); - - tty->closing = 0; - portp->tty = (struct tty_struct *) NULL; -@@ -1809,10 +1808,7 @@ - return; - - stl_flush(portp); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /*****************************************************************************/ -@@ -2193,10 +2189,7 @@ - - lock_kernel(); - if (test_bit(ASYI_TXLOW, &portp->istate)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - if (test_bit(ASYI_DCDCHANGE, &portp->istate)) { - clear_bit(ASYI_DCDCHANGE, &portp->istate); -diff -Nur linux-2.6.8.1/drivers/char/sx.c linux-2.6.8.1-plasmaroo/drivers/char/sx.c ---- linux-2.6.8.1/drivers/char/sx.c 2004-08-14 11:55:19.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/sx.c 2004-11-06 22:55:10.777630496 +0000 -@@ -1046,12 +1046,9 @@ - } - - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- port->gs.tty->ldisc.write_wakeup) -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -+ tty_wakeup(port->gs.tty); - sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", - port->gs.wakeup_chars); -- wake_up_interruptible(&port->gs.tty->write_wait); - } - - clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks); -diff -Nur linux-2.6.8.1/drivers/char/synclink.c linux-2.6.8.1-plasmaroo/drivers/char/synclink.c ---- linux-2.6.8.1/drivers/char/synclink.c 2004-08-14 11:55:10.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/synclink.c 2004-11-06 22:55:10.794627912 +0000 -@@ -993,6 +993,29 @@ - return 0; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - /* mgsl_stop() throttle (stop) transmitter - * - * Arguments: tty pointer to tty info structure -@@ -1153,13 +1176,7 @@ - __FILE__,__LINE__,info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):calling ldisc.write_wakeup on %s\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -2415,11 +2432,8 @@ - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- --} /* end of mgsl_flush_buffer() */ -+ tty_wakeup(tty); -+} - - /* mgsl_send_xchar() - * -@@ -3253,9 +3267,8 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - - shutdown(info); - -@@ -6830,11 +6843,7 @@ - } - else - #endif -- { -- /* Call the line discipline receive callback directly. */ -- if ( tty && tty->ldisc.receive_buf ) -- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); -- } -+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ -@@ -7006,9 +7015,7 @@ - memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize); - info->icount.rxok++; - -- /* Call the line discipline receive callback directly. */ -- if ( tty && tty->ldisc.receive_buf ) -- tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); -+ ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - - /* Free the buffers used by this frame. */ -diff -Nur linux-2.6.8.1/drivers/char/synclinkmp.c linux-2.6.8.1-plasmaroo/drivers/char/synclinkmp.c ---- linux-2.6.8.1/drivers/char/synclinkmp.c 2004-08-14 11:54:51.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/synclinkmp.c 2004-11-06 22:55:10.802626696 +0000 -@@ -722,6 +722,29 @@ - return 0; - } - -+/** -+ * line discipline callback wrappers -+ * -+ * The wrappers maintain line discipline references -+ * while calling into the line discipline. -+ * -+ * ldisc_receive_buf - pass receive data to line discipline -+ */ -+ -+static void ldisc_receive_buf(struct tty_struct *tty, -+ const __u8 *data, char *flags, int count) -+{ -+ struct tty_ldisc *ld; -+ if (!tty) -+ return; -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty, data, flags, count); -+ tty_ldisc_deref(ld); -+ } -+} -+ - /* tty callbacks */ - - /* Called when a port is opened. Init and enable port. -@@ -869,8 +892,7 @@ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - - shutdown(info); - -@@ -1275,9 +1297,7 @@ - spin_unlock_irqrestore(&info->lock,flags); - - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* throttle (stop) transmitter -@@ -1941,13 +1961,7 @@ - __FILE__,__LINE__,info->device_name); - - if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) { -- if ( debug_level >= DEBUG_LEVEL_BH ) -- printk( "%s(%d):%s calling ldisc.write_wakeup\n", -- __FILE__,__LINE__,info->device_name); -- (tty->ldisc.write_wakeup)(tty); -- } -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - } -@@ -4869,15 +4883,8 @@ - } - else - #endif -- { -- if ( tty && tty->ldisc.receive_buf ) { -- /* Call the line discipline receive callback directly. */ -- tty->ldisc.receive_buf(tty, -- info->tmp_rx_buf, -- info->flag_buf, -- framesize); -- } -- } -+ ldisc_receive_buf(tty,info->tmp_rx_buf, -+ info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ -diff -Nur linux-2.6.8.1/drivers/char/tty_io.c linux-2.6.8.1-plasmaroo/drivers/char/tty_io.c ---- linux-2.6.8.1/drivers/char/tty_io.c 2004-08-14 11:55:34.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/tty_io.c 2004-11-06 22:57:19.465067032 +0000 -@@ -92,6 +92,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -120,11 +121,17 @@ - - EXPORT_SYMBOL(tty_std_termios); - -+/* This list gets poked at by procfs and various bits of boot up code. This -+ could do with some rationalisation such as pulling the tty proc function -+ into this file */ -+ - LIST_HEAD(tty_drivers); /* linked list of tty drivers */ --struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table */ - --/* Semaphore to protect creating and releasing a tty */ -+/* Semaphore to protect creating and releasing a tty. This is shared with -+ vt.c for deeply disgusting hack reasons */ - DECLARE_MUTEX(tty_sem); -+/* Lock for tty_termios changes - private to tty_io/tty_ioctl */ -+spinlock_t tty_termios_lock = SPIN_LOCK_UNLOCKED; - - #ifdef CONFIG_UNIX98_PTYS - extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ -@@ -223,65 +230,324 @@ - return 0; - } - -+/* -+ * This is probably overkill for real world processors but -+ * they are not on hot paths so a little discipline won't do -+ * any harm. -+ */ -+ -+static void tty_set_termios_ldisc(struct tty_struct *tty, int num) -+{ -+ unsigned long flags; -+ spin_lock_irqsave(&tty_termios_lock, flags); -+ tty->termios->c_line = num; -+ spin_unlock_irqrestore(&tty_termios_lock, flags); -+} -+ -+/* -+ * This guards the refcounted line discipline lists. The lock -+ * must be taken with irqs off because there are hangup path -+ * callers who will do ldisc lookups and cannot sleep. -+ */ -+ -+static spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED; -+static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); -+static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ -+ - int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) - { -+ unsigned long flags; -+ int ret = 0; -+ - if (disc < N_TTY || disc >= NR_LDISCS) - return -EINVAL; - -+ spin_lock_irqsave(&tty_ldisc_lock, flags); - if (new_ldisc) { -- ldiscs[disc] = *new_ldisc; -- ldiscs[disc].flags |= LDISC_FLAG_DEFINED; -- ldiscs[disc].num = disc; -- } else -- memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc)); -+ tty_ldiscs[disc] = *new_ldisc; -+ tty_ldiscs[disc].num = disc; -+ tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; -+ tty_ldiscs[disc].refcount = 0; -+ } else { -+ if(tty_ldiscs[disc].refcount) -+ ret = -EBUSY; -+ else -+ tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - -- return 0; -+ return ret; - } - - EXPORT_SYMBOL(tty_register_ldisc); - --/* Set the discipline of a tty line. */ -+struct tty_ldisc *tty_ldisc_get(int disc) -+{ -+ unsigned long flags; -+ struct tty_ldisc *ld; -+ -+ if (disc < N_TTY || disc >= NR_LDISCS) -+ return NULL; -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ -+ ld = &tty_ldiscs[disc]; -+ /* Check the entry is defined */ -+ if(ld->flags & LDISC_FLAG_DEFINED) -+ { -+ /* If the module is being unloaded we can't use it */ -+ if (!try_module_get(ld->owner)) -+ ld = NULL; -+ else /* lock it */ -+ ld->refcount++; -+ } -+ else -+ ld = NULL; -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ return ld; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_get); -+ -+void tty_ldisc_put(int disc) -+{ -+ struct tty_ldisc *ld; -+ unsigned long flags; -+ -+ if (disc < N_TTY || disc >= NR_LDISCS) -+ BUG(); -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ ld = &tty_ldiscs[disc]; -+ if(ld->refcount == 0) -+ BUG(); -+ ld->refcount --; -+ module_put(ld->owner); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_put); -+ -+void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) -+{ -+ tty->ldisc = *ld; -+ tty->ldisc.refcount = 0; -+} -+ -+/** -+ * tty_ldisc_try - internal helper -+ * @tty: the tty -+ * -+ * Make a single attempt to grab and bump the refcount on -+ * the tty ldisc. Return 0 on failure or 1 on success. This is -+ * used to implement both the waiting and non waiting versions -+ * of tty_ldisc_ref -+ */ -+ -+static int tty_ldisc_try(struct tty_struct *tty) -+{ -+ unsigned long flags; -+ struct tty_ldisc *ld; -+ int ret = 0; -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ ld = &tty->ldisc; -+ if(test_bit(TTY_LDISC, &tty->flags)) -+ { -+ ld->refcount++; -+ ret = 1; -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ return ret; -+} -+ -+/** -+ * tty_ldisc_ref_wait - wait for the tty ldisc -+ * @tty: tty device -+ * -+ * Dereference the line discipline for the terminal and take a -+ * reference to it. If the line discipline is in flux then -+ * wait patiently until it changes. -+ * -+ * Note: Must not be called from an IRQ/timer context. The caller -+ * must also be careful not to hold other locks that will deadlock -+ * against a discipline change, such as an existing ldisc reference -+ * (which we check for) -+ */ -+ -+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) -+{ -+ /* wait_event is a macro */ -+ wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); -+ if(tty->ldisc.refcount == 0) -+ printk(KERN_ERR "tty_ldisc_ref_wait\n"); -+ return &tty->ldisc; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); -+ -+/** -+ * tty_ldisc_ref - get the tty ldisc -+ * @tty: tty device -+ * -+ * Dereference the line discipline for the terminal and take a -+ * reference to it. If the line discipline is in flux then -+ * return NULL. Can be called from IRQ and timer functions. -+ */ -+ -+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) -+{ -+ if(tty_ldisc_try(tty)) -+ return &tty->ldisc; -+ return NULL; -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_ref); -+ -+/** -+ * tty_ldisc_deref - free a tty ldisc reference -+ * @ld: reference to free up -+ * -+ * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May -+ * be called in IRQ context. -+ */ -+ -+void tty_ldisc_deref(struct tty_ldisc *ld) -+{ -+ unsigned long flags; -+ -+ if(ld == NULL) -+ BUG(); -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ if(ld->refcount == 0) -+ printk(KERN_ERR "tty_ldisc_deref: no references.\n"); -+ else -+ ld->refcount--; -+ if(ld->refcount == 0) -+ wake_up(&tty_ldisc_wait); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_deref); -+ -+/** -+ * tty_ldisc_enable - allow ldisc use -+ * @tty: terminal to activate ldisc on -+ * -+ * Set the TTY_LDISC flag when the line discipline can be called -+ * again. Do neccessary wakeups for existing sleepers. -+ * -+ * Note: nobody should set this bit except via this function. Clearing -+ * directly is allowed. -+ */ -+ -+static void tty_ldisc_enable(struct tty_struct *tty) -+{ -+ set_bit(TTY_LDISC, &tty->flags); -+ wake_up(&tty_ldisc_wait); -+} -+ -+/** -+ * tty_set_ldisc - set line discipline -+ * @tty: the terminal to set -+ * @ldisc: the line discipline -+ * -+ * Set the discipline of a tty line. Must be called from a process -+ * context. -+ */ -+ - static int tty_set_ldisc(struct tty_struct *tty, int ldisc) - { - int retval = 0; - struct tty_ldisc o_ldisc; - char buf[64]; -+ int work; -+ unsigned long flags; -+ struct tty_ldisc *ld; - - if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) - return -EINVAL; -+ -+restart: -+ -+ if (tty->ldisc.num == ldisc) -+ return 0; /* We are already in the desired discipline */ -+ -+ ld = tty_ldisc_get(ldisc); - /* Eduardo Blanco */ - /* Cyrus Durgin */ -- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) { -+ if (ld == NULL) { - request_module("tty-ldisc-%d", ldisc); -+ ld = tty_ldisc_get(ldisc); - } -- if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) -+ if (ld == NULL) - return -EINVAL; - -- if (tty->ldisc.num == ldisc) -- return 0; /* We are already in the desired discipline */ -- -- if (!try_module_get(ldiscs[ldisc].owner)) -- return -EINVAL; -- - o_ldisc = tty->ldisc; - - tty_wait_until_sent(tty, 0); -+ -+ /* -+ * Make sure we don't change while someone holds a -+ * reference to the line discipline. The TTY_LDISC bit -+ * prevents anyone taking a reference once it is clear. -+ * We need the lock to avoid racing reference takers. -+ */ -+ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ if(tty->ldisc.refcount) -+ { -+ /* Free the new ldisc we grabbed. Must drop the lock -+ first. */ -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ tty_ldisc_put(ldisc); -+ /* -+ * There are several reasons we may be busy, including -+ * random momentary I/O traffic. We must therefore -+ * retry. We could distinguish between blocking ops -+ * and retries if we made tty_ldisc_wait() smarter. That -+ * is up for discussion. -+ */ -+ if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0) -+ return -ERESTARTSYS; -+ goto restart; -+ } -+ clear_bit(TTY_LDISC, &tty->flags); -+ clear_bit(TTY_DONT_FLIP, &tty->flags); -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - -+ /* -+ * From this point on we know nobody has an ldisc -+ * usage reference, nor can they obtain one until -+ * we say so later on. -+ */ -+ -+ work = cancel_delayed_work(&tty->flip.work); -+ /* -+ * Wait for ->hangup_work and ->flip.work handlers to terminate -+ */ -+ -+ flush_scheduled_work(); - /* Shutdown the current discipline. */ - if (tty->ldisc.close) - (tty->ldisc.close)(tty); - - /* Now set up the new line discipline. */ -- tty->ldisc = ldiscs[ldisc]; -- tty->termios->c_line = ldisc; -+ tty_ldisc_assign(tty, ld); -+ tty_set_termios_ldisc(tty, ldisc); - if (tty->ldisc.open) - retval = (tty->ldisc.open)(tty); - if (retval < 0) { -- tty->ldisc = o_ldisc; -- tty->termios->c_line = tty->ldisc.num; -+ tty_ldisc_put(ldisc); -+ /* There is an outstanding reference here so this is safe */ -+ tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num)); -+ tty_set_termios_ldisc(tty, tty->ldisc.num); - if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) { -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -+ tty_ldisc_put(o_ldisc.num); -+ /* This driver is always present */ -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(tty, N_TTY); - if (tty->ldisc.open) { - int r = tty->ldisc.open(tty); - -@@ -291,12 +557,27 @@ - tty_name(tty, buf), r); - } - } -- } else { -- module_put(o_ldisc.owner); - } -+ /* At this point we hold a reference to the new ldisc and a -+ a reference to the old ldisc. If we ended up flipping back -+ to the existing ldisc we have two references to it */ - - if (tty->ldisc.num != o_ldisc.num && tty->driver->set_ldisc) - tty->driver->set_ldisc(tty); -+ -+ tty_ldisc_put(o_ldisc.num); -+ -+ /* -+ * Allow ldisc referencing to occur as soon as the driver -+ * ldisc callback completes. -+ */ -+ -+ tty_ldisc_enable(tty); -+ -+ /* Restart it in case no characters kick it off. Safe if -+ already running */ -+ if(work) -+ schedule_delayed_work(&tty->flip.work, 1); - return retval; - } - -@@ -399,6 +680,53 @@ - - static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED; - static struct file *redirect; -+ -+/** -+ * tty_wakeup - request more data -+ * @tty: terminal -+ * -+ * Internal and external helper for wakeups of tty. This function -+ * informs the line discipline if present that the driver is ready -+ * to receive more output data. -+ */ -+ -+void tty_wakeup(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld; -+ -+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { -+ ld = tty_ldisc_ref(tty); -+ if(ld) { -+ if(ld->write_wakeup) -+ ld->write_wakeup(tty); -+ tty_ldisc_deref(ld); -+ } -+ } -+ wake_up_interruptible(&tty->write_wait); -+} -+ -+EXPORT_SYMBOL_GPL(tty_wakeup); -+ -+/** -+ * tty_ldisc_flush - flush line discipline queue -+ * @tty: tty -+ * -+ * Flush the line discipline queue (if any) for this tty. If there -+ * is no line discipline active this is a no-op. -+ */ -+ -+void tty_ldisc_flush(struct tty_struct *tty) -+{ -+ struct tty_ldisc *ld = tty_ldisc_ref(tty); -+ if(ld) { -+ if(ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+} -+ -+EXPORT_SYMBOL_GPL(tty_ldisc_flush); -+ - /* - * This can be called by the "eventd" kernel thread. That is process synchronous, - * but doesn't hold any locks, so we need to make sure we have the appropriate -@@ -410,6 +738,7 @@ - struct file * cons_filp = NULL; - struct file *filp, *f = NULL; - struct task_struct *p; -+ struct tty_ldisc *ld; - struct pid *pid; - int closecount = 0, n; - -@@ -428,6 +757,7 @@ - - check_tty_count(tty, "do_tty_hangup"); - file_list_lock(); -+ /* This breaks for file handles being sent over AF_UNIX sockets ? */ - list_for_each_entry(filp, &tty->tty_files, f_list) { - if (filp->f_op->write == redirected_tty_write) - cons_filp = filp; -@@ -440,21 +770,25 @@ - file_list_unlock(); - - /* FIXME! What are the locking issues here? This may me overdoing things.. -- * this question is especially important now that we've removed the irqlock. */ -- { -- unsigned long flags; -+ * this question is especially important now that we've removed the irqlock. */ - -- local_irq_save(flags); // FIXME: is this safe? -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ ld = tty_ldisc_ref(tty); -+ if(ld != NULL) /* We may have no line discipline at this point */ -+ { -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- local_irq_restore(flags); // FIXME: is this safe? -+ ld->write_wakeup) -+ ld->write_wakeup(tty); -+ if (ld->hangup) -+ ld->hangup(tty); - } - -+ /* FIXME: Once we trust the LDISC code better we can wait here for -+ ldisc completion and fix the driver call race */ -+ - wake_up_interruptible(&tty->write_wait); - wake_up_interruptible(&tty->read_wait); - -@@ -463,22 +797,19 @@ - * N_TTY. - */ - if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) -+ { -+ unsigned long flags; -+ spin_lock_irqsave(&tty_termios_lock, flags); - *tty->termios = tty->driver->init_termios; -- if (tty->ldisc.num != ldiscs[N_TTY].num) { -- if (tty->ldisc.close) -- (tty->ldisc.close)(tty); -- module_put(tty->ldisc.owner); -- -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -- if (tty->ldisc.open) { -- int i = (tty->ldisc.open)(tty); -- if (i < 0) -- printk(KERN_ERR "do_tty_hangup: N_TTY open: " -- "error %d\n", -i); -- } -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - } - -+ /* Defer ldisc switch */ -+ /* tty_deferred_ldisc_switch(N_TTY); -+ -+ This should get done automatically when the port closes and -+ tty_release is called */ -+ - read_lock(&tasklist_lock); - if (tty->session > 0) { - struct list_head *l; -@@ -511,6 +842,17 @@ - tty->driver->close(tty, cons_filp); - } else if (tty->driver->hangup) - (tty->driver->hangup)(tty); -+ -+ /* We don't want to have driver/ldisc interactions beyond -+ the ones we did here. The driver layer expects no -+ calls after ->hangup() from the ldisc side. However we -+ can't yet guarantee all that */ -+ -+ set_bit(TTY_HUPPED, &tty->flags); -+ if (ld) { -+ tty_ldisc_enable(tty); -+ tty_ldisc_deref(ld); -+ } - unlock_kernel(); - if (f) - fput(f); -@@ -627,9 +969,9 @@ - } - if (tty->driver->start) - (tty->driver->start)(tty); -- if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ -+ /* If we have a running line discipline it may need kicking */ -+ tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } - -@@ -641,6 +983,7 @@ - int i; - struct tty_struct * tty; - struct inode *inode; -+ struct tty_ldisc *ld; - - tty = (struct tty_struct *)file->private_data; - inode = file->f_dentry->d_inode; -@@ -649,11 +992,15 @@ - if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) - return -EIO; - -+ /* We want to wait for the line discipline to sort out in this -+ situation */ -+ ld = tty_ldisc_ref_wait(tty); - lock_kernel(); -- if (tty->ldisc.read) -- i = (tty->ldisc.read)(tty,file,buf,count); -+ if (ld->read) -+ i = (ld->read)(tty,file,buf,count); - else - i = -EIO; -+ tty_ldisc_deref(ld); - unlock_kernel(); - if (i > 0) - inode->i_atime = CURRENT_TIME; -@@ -715,16 +1062,23 @@ - { - struct tty_struct * tty; - struct inode *inode = file->f_dentry->d_inode; -- -+ ssize_t ret; -+ struct tty_ldisc *ld; -+ - tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode, "tty_write")) - return -EIO; - if (!tty || !tty->driver->write || (test_bit(TTY_IO_ERROR, &tty->flags))) - return -EIO; -- if (!tty->ldisc.write) -- return -EIO; -- return do_tty_write(tty->ldisc.write, tty, file, -+ -+ ld = tty_ldisc_ref_wait(tty); -+ if (!ld->write) -+ ret = -EIO; -+ else -+ ret = do_tty_write(ld->write, tty, file, - (const unsigned char __user *)buf, count); -+ tty_ldisc_deref(ld); -+ return ret; - } - - ssize_t redirected_tty_write(struct file * file, const char __user * buf, size_t count, -@@ -910,6 +1264,7 @@ - * If we fail here just call release_mem to clean up. No need - * to decrement the use counts, as release_mem doesn't care. - */ -+ - if (tty->ldisc.open) { - retval = (tty->ldisc.open)(tty); - if (retval) -@@ -922,7 +1277,9 @@ - (tty->ldisc.close)(tty); - goto release_mem_out; - } -+ tty_ldisc_enable(o_tty); - } -+ tty_ldisc_enable(tty); - goto success; - - /* -@@ -951,6 +1308,9 @@ - tty->count++; - tty->driver = driver; /* N.B. why do this every time?? */ - -+ /* FIXME */ -+ if(!test_bit(TTY_LDISC, &tty->flags)) -+ printk(KERN_ERR "init_dev but no ldisc\n"); - success: - *ret_tty = tty; - -@@ -1054,6 +1414,7 @@ - int devpts_master, devpts; - int idx; - char buf[64]; -+ unsigned long flags; - - tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "release_dev")) -@@ -1130,7 +1491,6 @@ - } - } - #endif -- - if (tty->driver->close) - tty->driver->close(tty, filp); - -@@ -1254,36 +1614,58 @@ - #ifdef TTY_DEBUG_HANGUP - printk(KERN_DEBUG "freeing tty structure..."); - #endif -- - /* - * Prevent flush_to_ldisc() from rescheduling the work for later. Then -- * kill any delayed work. -+ * kill any delayed work. As this is the final close it does not -+ * race with the set_ldisc code path. - */ -+ clear_bit(TTY_LDISC, &tty->flags); - clear_bit(TTY_DONT_FLIP, &tty->flags); - cancel_delayed_work(&tty->flip.work); - - /* - * Wait for ->hangup_work and ->flip.work handlers to terminate - */ -+ - flush_scheduled_work(); -- -+ -+ /* -+ * Wait for any short term users (we know they are just driver -+ * side waiters as the file is closing so user count on the file -+ * side is zero. -+ */ -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ while(tty->ldisc.refcount) -+ { -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); -+ wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0); -+ spin_lock_irqsave(&tty_ldisc_lock, flags); -+ } -+ spin_unlock_irqrestore(&tty_ldisc_lock, flags); - /* - * Shutdown the current line discipline, and reset it to N_TTY. - * N.B. why reset ldisc when we're releasing the memory?? -+ * -+ * FIXME: this MUST get fixed for the new reflocking - */ - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -- module_put(tty->ldisc.owner); -+ tty_ldisc_put(tty->ldisc.num); - -- tty->ldisc = ldiscs[N_TTY]; -- tty->termios->c_line = N_TTY; -+ /* -+ * Switch the line discipline back -+ */ -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(tty,N_TTY); - if (o_tty) { -+ /* FIXME: could o_tty be in setldisc here ? */ -+ clear_bit(TTY_LDISC, &o_tty->flags); - if (o_tty->ldisc.close) - (o_tty->ldisc.close)(o_tty); -- module_put(o_tty->ldisc.owner); -- o_tty->ldisc = ldiscs[N_TTY]; -+ tty_ldisc_put(o_tty->ldisc.num); -+ tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY)); -+ tty_set_termios_ldisc(o_tty,N_TTY); - } -- - /* - * The release_mem function takes care of the details of clearing - * the slots and preserving the termios structure. -@@ -1323,6 +1705,7 @@ - unsigned short saved_flags = filp->f_flags; - - nonseekable_open(inode, filp); -+ - retry_open: - noctty = filp->f_flags & O_NOCTTY; - index = -1; -@@ -1479,14 +1862,18 @@ - static unsigned int tty_poll(struct file * filp, poll_table * wait) - { - struct tty_struct * tty; -+ struct tty_ldisc *ld; -+ int ret = 0; - - tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_poll")) - return 0; -- -- if (tty->ldisc.poll) -- return (tty->ldisc.poll)(tty, filp, wait); -- return 0; -+ -+ ld = tty_ldisc_ref_wait(tty); -+ if (ld->poll) -+ ret = (ld->poll)(tty, filp, wait); -+ tty_ldisc_deref(ld); -+ return ret; - } - - static int tty_fasync(int fd, struct file * filp, int on) -@@ -1518,12 +1905,15 @@ - static int tiocsti(struct tty_struct *tty, char __user *p) - { - char ch, mbz = 0; -- -+ struct tty_ldisc *ld; -+ - if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) - return -EPERM; - if (get_user(ch, p)) - return -EFAULT; -- tty->ldisc.receive_buf(tty, &ch, &mbz, 1); -+ ld = tty_ldisc_ref_wait(tty); -+ ld->receive_buf(tty, &ch, &mbz, 1); -+ tty_ldisc_deref(ld); - return 0; - } - -@@ -1772,6 +2162,7 @@ - struct tty_struct *tty, *real_tty; - void __user *p = (void __user *)arg; - int retval; -+ struct tty_ldisc *ld; - - tty = (struct tty_struct *)file->private_data; - if (tty_paranoia_check(tty, inode, "tty_ioctl")) -@@ -1861,6 +2252,7 @@ - case TIOCGSID: - return tiocgsid(tty, real_tty, p); - case TIOCGETD: -+ /* FIXME: check this is ok */ - return put_user(tty->ldisc.num, (int __user *)p); - case TIOCSETD: - return tiocsetd(tty, p); -@@ -1899,16 +2291,19 @@ - return tty_tiocmset(tty, file, cmd, p); - } - if (tty->driver->ioctl) { -- int retval = (tty->driver->ioctl)(tty, file, cmd, arg); -+ retval = (tty->driver->ioctl)(tty, file, cmd, arg); - if (retval != -ENOIOCTLCMD) - return retval; - } -- if (tty->ldisc.ioctl) { -- int retval = (tty->ldisc.ioctl)(tty, file, cmd, arg); -- if (retval != -ENOIOCTLCMD) -- return retval; -+ ld = tty_ldisc_ref_wait(tty); -+ retval = -EINVAL; -+ if (ld->ioctl) { -+ retval = ld->ioctl(tty, file, cmd, arg); -+ if (retval == -ENOIOCTLCMD) -+ retval = -EINVAL; - } -- return -EINVAL; -+ tty_ldisc_deref(ld); -+ return retval; - } - - -@@ -1943,14 +2338,21 @@ - int session; - int i; - struct file *filp; -+ struct tty_ldisc *disc; - - if (!tty) - return; - session = tty->session; -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ /* We don't want an ldisc switch during this */ -+ disc = tty_ldisc_ref(tty); -+ if (disc && disc->flush_buffer) -+ disc->flush_buffer(tty); -+ tty_ldisc_deref(disc); -+ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -+ - read_lock(&tasklist_lock); - for_each_task_pid(session, PIDTYPE_SID, p, l, pid) { - if (p->signal->tty == tty || session > 0) { -@@ -2002,24 +2404,29 @@ - - /* - * This routine is called out of the software interrupt to flush data -- * from the flip buffer to the line discipline. -+ * from the flip buffer to the line discipline. - */ -+ - static void flush_to_ldisc(void *private_) - { - struct tty_struct *tty = (struct tty_struct *) private_; - unsigned char *cp; - char *fp; - int count; -- unsigned long flags; -+ unsigned long flags; -+ struct tty_ldisc *disc; -+ -+ disc = tty_ldisc_ref(tty); -+ if (disc == NULL) /* !TTY_LDISC */ -+ return; - - if (test_bit(TTY_DONT_FLIP, &tty->flags)) { - /* - * Do it after the next timer tick: - */ - schedule_delayed_work(&tty->flip.work, 1); -- return; -+ goto out; - } -- - spin_lock_irqsave(&tty->read_lock, flags); - if (tty->flip.buf_num) { - cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE; -@@ -2038,7 +2445,31 @@ - tty->flip.count = 0; - spin_unlock_irqrestore(&tty->read_lock, flags); - -- tty->ldisc.receive_buf(tty, cp, fp, count); -+ disc->receive_buf(tty, cp, fp, count); -+out: -+ tty_ldisc_deref(disc); -+} -+ -+/* -+ * Call the ldisc flush directly from a driver. This function may -+ * return an error and need retrying by the user. -+ */ -+ -+int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count) -+{ -+ int ret = 0; -+ struct tty_ldisc *disc; -+ -+ disc = tty_ldisc_ref(tty); -+ if(test_bit(TTY_DONT_FLIP, &tty->flags)) -+ ret = -EAGAIN; -+ else if(disc == NULL) -+ ret = -EIO; -+ else -+ disc->receive_buf(tty, cp, fp, count); -+ tty_ldisc_deref(disc); -+ return ret; -+ - } - - /* -@@ -2060,9 +2491,20 @@ - - static int n_baud_table = ARRAY_SIZE(baud_table); - -+/** -+ * tty_termios_baud_rate -+ * @termios: termios structure -+ * -+ * Convert termios baud rate data into a speed. This should be called -+ * with the termios lock held if this termios is a terminal termios -+ * structure. May change the termios data. -+ */ -+ - int tty_termios_baud_rate(struct termios *termios) - { -- unsigned int cbaud = termios->c_cflag & CBAUD; -+ unsigned int cbaud; -+ -+ cbaud = termios->c_cflag & CBAUD; - - if (cbaud & CBAUDEX) { - cbaud &= ~CBAUDEX; -@@ -2072,12 +2514,20 @@ - else - cbaud += 15; - } -- - return baud_table[cbaud]; - } - - EXPORT_SYMBOL(tty_termios_baud_rate); - -+/** -+ * tty_get_baud_rate - get tty bit rates -+ * @tty: tty to query -+ * -+ * Returns the baud rate as an integer for this terminal. The -+ * termios lock must be held by the caller and the terminal bit -+ * flags may be updated. -+ */ -+ - int tty_get_baud_rate(struct tty_struct *tty) - { - int baud = tty_termios_baud_rate(tty->termios); -@@ -2096,6 +2546,17 @@ - - EXPORT_SYMBOL(tty_get_baud_rate); - -+/** -+ * tty_flip_buffer_push - terminal -+ * @tty: tty to push -+ * -+ * Queue a push of the terminal flip buffers to the line discipline. This -+ * function must not be called from IRQ context if tty->low_latency is set. -+ * -+ * In the event of the queue being busy for flipping the work will be -+ * held off and retried later. -+ */ -+ - void tty_flip_buffer_push(struct tty_struct *tty) - { - if (tty->low_latency) -@@ -2113,7 +2574,7 @@ - { - memset(tty, 0, sizeof(struct tty_struct)); - tty->magic = TTY_MAGIC; -- tty->ldisc = ldiscs[N_TTY]; -+ tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); - tty->pgrp = -1; - tty->flip.char_buf_ptr = tty->flip.char_buf; - tty->flip.flag_buf_ptr = tty->flip.flag_buf; -diff -Nur linux-2.6.8.1/drivers/char/tty_ioctl.c linux-2.6.8.1-plasmaroo/drivers/char/tty_ioctl.c ---- linux-2.6.8.1/drivers/char/tty_ioctl.c 2004-08-14 11:56:24.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/tty_ioctl.c 2004-11-06 22:55:10.853618944 +0000 -@@ -29,6 +29,8 @@ - - #undef DEBUG - -+extern spinlock_t tty_termios_lock; -+ - /* - * Internal flag options for termios setting behavior - */ -@@ -98,8 +100,18 @@ - { - int canon_change; - struct termios old_termios = *tty->termios; -+ struct tty_ldisc *ld; -+ unsigned long flags; -+ -+ /* -+ * Perform the actual termios internal changes under lock. -+ */ -+ -+ -+ /* FIXME: we need to decide on some locking/ordering semantics -+ for the set_termios notification eventually */ -+ spin_lock_irqsave(&tty_termios_lock, flags); - -- local_irq_disable(); // FIXME: is this safe? - *tty->termios = *new_termios; - unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); - canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; -@@ -109,12 +121,13 @@ - tty->canon_data = 0; - tty->erasing = 0; - } -- local_irq_enable(); // FIXME: is this safe? -+ -+ - if (canon_change && !L_ICANON(tty) && tty->read_cnt) - /* Get characters left over from canonical mode. */ - wake_up_interruptible(&tty->read_wait); - -- /* see if packet mode change of state */ -+ /* See if packet mode change of state. */ - - if (tty->link && tty->link->packet) { - int old_flow = ((old_termios.c_iflag & IXON) && -@@ -132,17 +145,23 @@ - wake_up_interruptible(&tty->link->read_wait); - } - } -- -+ - if (tty->driver->set_termios) - (*tty->driver->set_termios)(tty, &old_termios); - -- if (tty->ldisc.set_termios) -- (*tty->ldisc.set_termios)(tty, &old_termios); -+ ld = tty_ldisc_ref(tty); -+ if (ld != NULL) { -+ if (ld->set_termios) -+ (ld->set_termios)(tty, &old_termios); -+ tty_ldisc_deref(ld); -+ } -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - } - - static int set_termios(struct tty_struct * tty, void __user *arg, int opt) - { - struct termios tmp_termios; -+ struct tty_ldisc *ld; - int retval = tty_check_change(tty); - - if (retval) -@@ -159,9 +178,14 @@ - return -EFAULT; - } - -- if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ ld = tty_ldisc_ref(tty); -+ -+ if (ld != NULL) { -+ if ((opt & TERMIOS_FLUSH) && ld->flush_buffer) -+ ld->flush_buffer(tty); -+ tty_ldisc_deref(ld); -+ } -+ - if (opt & TERMIOS_WAIT) { - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) -@@ -225,12 +249,16 @@ - static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) - { - struct sgttyb tmp; -+ unsigned long flags; - -+ spin_lock_irqsave(&tty_termios_lock, flags); - tmp.sg_ispeed = 0; - tmp.sg_ospeed = 0; - tmp.sg_erase = tty->termios->c_cc[VERASE]; - tmp.sg_kill = tty->termios->c_cc[VKILL]; - tmp.sg_flags = get_sgflags(tty); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); -+ - return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; - } - -@@ -269,12 +297,16 @@ - retval = tty_check_change(tty); - if (retval) - return retval; -- termios = *tty->termios; -+ - if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) - return -EFAULT; -+ -+ spin_lock_irqsave(&tty_termios_lock, flags); -+ termios = *tty->termios; - termios.c_cc[VERASE] = tmp.sg_erase; - termios.c_cc[VKILL] = tmp.sg_kill; - set_sgflags(&termios, tmp.sg_flags); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - change_termios(tty, &termios); - return 0; - } -@@ -365,6 +397,8 @@ - struct tty_struct * real_tty; - void __user *p = (void __user *)arg; - int retval; -+ struct tty_ldisc *ld; -+ unsigned long flags; - - if (tty->driver->type == TTY_DRIVER_TYPE_PTY && - tty->driver->subtype == PTY_TYPE_MASTER) -@@ -443,22 +477,26 @@ - retval = tty_check_change(tty); - if (retval) - return retval; -+ -+ ld = tty_ldisc_ref(tty); - switch (arg) { - case TCIFLUSH: -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - break; - case TCIOFLUSH: -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ if (ld->flush_buffer) -+ ld->flush_buffer(tty); - /* fall through */ - case TCOFLUSH: - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - break; - default: -+ tty_ldisc_deref(ld); - return -EINVAL; - } -+ tty_ldisc_deref(ld); - return 0; - case TIOCOUTQ: - return put_user(tty->driver->chars_in_buffer ? -@@ -504,9 +542,11 @@ - case TIOCSSOFTCAR: - if (get_user(arg, (unsigned int __user *) arg)) - return -EFAULT; -+ spin_lock_irqsave(&tty_termios_lock, flags); - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); -+ spin_unlock_irqrestore(&tty_termios_lock, flags); - return 0; - default: - return -ENOIOCTLCMD; -diff -Nur linux-2.6.8.1/drivers/char/viocons.c linux-2.6.8.1-plasmaroo/drivers/char/viocons.c ---- linux-2.6.8.1/drivers/char/viocons.c 2004-08-14 11:54:46.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/viocons.c 2004-11-06 22:55:10.855618640 +0000 -@@ -422,10 +422,7 @@ - pi->overflowMessage = 0; - - if (pi->tty) { -- if ((pi->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- (pi->tty->ldisc.write_wakeup)) -- (pi->tty->ldisc.write_wakeup)(pi->tty); -- wake_up_interruptible(&pi->tty->write_wait); -+ tty_wakeup(pi->tty); - } - } - -diff -Nur linux-2.6.8.1/drivers/char/vme_scc.c linux-2.6.8.1-plasmaroo/drivers/char/vme_scc.c ---- linux-2.6.8.1/drivers/char/vme_scc.c 2004-08-14 11:54:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/vme_scc.c 2004-11-06 22:55:10.856618488 +0000 -@@ -544,12 +544,8 @@ - SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); /* disable tx_int on next tx underrun? */ - port->gs.flags &= ~GS_TX_INTEN; - } -- if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) { -- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- port->gs.tty->ldisc.write_wakeup) -- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); -- wake_up_interruptible(&port->gs.tty->write_wait); -- } -+ if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) -+ tty_wakeup(port->gs.tty); - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; -diff -Nur linux-2.6.8.1/drivers/char/vt_ioctl.c linux-2.6.8.1-plasmaroo/drivers/char/vt_ioctl.c ---- linux-2.6.8.1/drivers/char/vt_ioctl.c 2004-08-14 11:55:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/char/vt_ioctl.c 2004-11-06 22:55:10.858618184 +0000 -@@ -536,8 +536,7 @@ - default: - return -EINVAL; - } -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - return 0; - - case KDGKBMODE: -diff -Nur linux-2.6.8.1/drivers/isdn/capi/capi.c linux-2.6.8.1-plasmaroo/drivers/isdn/capi/capi.c ---- linux-2.6.8.1/drivers/isdn/capi/capi.c 2004-08-14 11:56:22.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/isdn/capi/capi.c 2004-11-06 22:55:10.885614080 +0000 -@@ -436,51 +436,62 @@ - struct sk_buff *nskb; - int datalen; - u16 errcode, datahandle; -- -+ struct tty_ldisc *ld; -+ - datalen = skb->len - CAPIMSG_LEN(skb->data); -- if (mp->tty) { -- if (mp->tty->ldisc.receive_buf == 0) { -- printk(KERN_ERR "capi: ldisc has no receive_buf function\n"); -- return -1; -- } -- if (mp->ttyinstop) { -+ if (mp->tty == NULL) -+ { -+#ifdef _DEBUG_DATAFLOW -+ printk(KERN_DEBUG "capi: currently no receiver\n"); -+#endif -+ return -1; -+ } -+ -+ ld = tty_ldisc_ref(mp->tty); -+ if (ld == NULL) -+ return -1; -+ if (ld->receive_buf == NULL) { - #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) -- printk(KERN_DEBUG "capi: recv tty throttled\n"); -+ printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n"); - #endif -- return -1; -- } -- if (mp->tty->ldisc.receive_room && -- mp->tty->ldisc.receive_room(mp->tty) < datalen) { -+ goto bad; -+ } -+ if (mp->ttyinstop) { - #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) -- printk(KERN_DEBUG "capi: no room in tty\n"); -+ printk(KERN_DEBUG "capi: recv tty throttled\n"); - #endif -- return -1; -- } -- if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) { -- printk(KERN_ERR "capi: gen_data_b3_resp failed\n"); -- return -1; -- } -- datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4); -- errcode = capi20_put_message(mp->ap, nskb); -- if (errcode != CAPI_NOERROR) { -- printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", -- errcode); -- kfree_skb(nskb); -- return -1; -- } -- (void)skb_pull(skb, CAPIMSG_LEN(skb->data)); --#ifdef _DEBUG_DATAFLOW -- printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", -- datahandle, skb->len); -+ goto bad; -+ } -+ if (ld->receive_room && -+ ld->receive_room(mp->tty) < datalen) { -+#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) -+ printk(KERN_DEBUG "capi: no room in tty\n"); - #endif -- mp->tty->ldisc.receive_buf(mp->tty, skb->data, NULL, skb->len); -- kfree_skb(skb); -- return 0; -- -+ goto bad; -+ } -+ if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) { -+ printk(KERN_ERR "capi: gen_data_b3_resp failed\n"); -+ goto bad; -+ } -+ datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4); -+ errcode = capi20_put_message(mp->ap, nskb); -+ if (errcode != CAPI_NOERROR) { -+ printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", -+ errcode); -+ kfree_skb(nskb); -+ goto bad; - } -+ (void)skb_pull(skb, CAPIMSG_LEN(skb->data)); - #ifdef _DEBUG_DATAFLOW -- printk(KERN_DEBUG "capi: currently no receiver\n"); -+ printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", -+ datahandle, skb->len); - #endif -+ ld->receive_buf(mp->tty, skb->data, NULL, skb->len); -+ kfree_skb(skb); -+ tty_ldisc_deref(ld); -+ return 0; -+bad: -+ tty_ldisc_deref(ld); - return -1; - } - -@@ -614,6 +625,7 @@ - - - if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) { -+ - datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2); - #ifdef _DEBUG_DATAFLOW - printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n", -@@ -633,10 +645,8 @@ - #endif - kfree_skb(skb); - (void)capiminor_del_ack(mp, datahandle); -- if (mp->tty) { -- if (mp->tty->ldisc.write_wakeup) -- mp->tty->ldisc.write_wakeup(mp->tty); -- } -+ if (mp->tty) -+ tty_wakeup(tty); - (void)handle_minor_send(mp); - - } else { -diff -Nur linux-2.6.8.1/drivers/isdn/i4l/isdn_tty.c linux-2.6.8.1-plasmaroo/drivers/isdn/i4l/isdn_tty.c ---- linux-2.6.8.1/drivers/isdn/i4l/isdn_tty.c 2004-08-14 11:55:48.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/isdn/i4l/isdn_tty.c 2004-11-06 22:55:10.900611800 +0000 -@@ -296,10 +296,7 @@ - info->send_outstanding++; - info->msr &= ~UART_MSR_CTS; - info->lsr &= ~UART_LSR_TEMT; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - return; - } - if (slen < 0) { -@@ -1174,10 +1171,7 @@ - /* If DLE decoding results in zero-transmit, but - * c originally was non-zero, do a wakeup. - */ -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - info->msr |= UART_MSR_CTS; - info->lsr |= UART_LSR_TEMT; - } -@@ -1290,9 +1284,7 @@ - isdn_tty_cleanup_xmit(info); - info->xmit_count = 0; - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - } - - static void -@@ -1747,10 +1739,10 @@ - } - dev->modempoll--; - isdn_tty_shutdown(info); -+ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - info->tty = NULL; - info->ncarrier = 0; - tty->closing = 0; -@@ -2681,8 +2673,7 @@ - if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) { - return; - } -- if (info->tty->ldisc.flush_buffer) -- info->tty->ldisc.flush_buffer(info->tty); -+ tty_ldisc_flush(tty); - if ((info->flags & ISDN_ASYNC_CHECK_CD) && - (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) && - (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) { -diff -Nur linux-2.6.8.1/drivers/macintosh/macserial.c linux-2.6.8.1-plasmaroo/drivers/macintosh/macserial.c ---- linux-2.6.8.1/drivers/macintosh/macserial.c 2004-08-14 11:56:23.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/macintosh/macserial.c 2004-11-06 22:55:10.910610280 +0000 -@@ -713,12 +713,8 @@ - if (!tty) - return; - -- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) -+ tty_wakeup(tty); - } - - static int startup(struct mac_serial * info) -@@ -1564,10 +1560,7 @@ - spin_lock_irqsave(&info->lock, flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - spin_unlock_irqrestore(&info->lock, flags); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1994,8 +1987,7 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Nur linux-2.6.8.1/drivers/net/hamradio/mkiss.c linux-2.6.8.1-plasmaroo/drivers/net/hamradio/mkiss.c ---- linux-2.6.8.1/drivers/net/hamradio/mkiss.c 2004-08-14 11:56:23.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/hamradio/mkiss.c 2004-11-06 22:55:10.931607088 +0000 -@@ -602,8 +602,6 @@ - - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); - - /* Restore default settings */ - ax->dev->type = ARPHRD_AX25; -diff -Nur linux-2.6.8.1/drivers/net/irda/irtty-sir.c linux-2.6.8.1-plasmaroo/drivers/net/irda/irtty-sir.c ---- linux-2.6.8.1/drivers/net/irda/irtty-sir.c 2004-08-14 11:54:46.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/irda/irtty-sir.c 2004-11-06 22:55:10.944605112 +0000 -@@ -509,13 +509,6 @@ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - --/* from old irtty - but what is it good for? -- * we _are_ the ldisc and we _don't_ implement flush_buffer! -- * -- * if (tty->ldisc.flush_buffer) -- * tty->ldisc.flush_buffer(tty); -- */ -- - /* apply mtt override */ - sir_tty_drv.qos_mtt_bits = qos_mtt_bits; - -diff -Nur linux-2.6.8.1/drivers/net/ppp_async.c linux-2.6.8.1-plasmaroo/drivers/net/ppp_async.c ---- linux-2.6.8.1/drivers/net/ppp_async.c 2004-08-14 11:55:48.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/ppp_async.c 2004-11-06 22:55:10.957603136 +0000 -@@ -122,6 +122,9 @@ - * frees the memory that ppp_asynctty_receive is using. The best - * way to fix this is to use a rwlock in the tty struct, but for now - * we use a single global rwlock for all ttys in ppp line discipline. -+ * -+ * FIXME: this is no longer true. The _close path for the ldisc is -+ * now guaranteed to be sane. - */ - static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; - -@@ -144,7 +147,8 @@ - } - - /* -- * Called when a tty is put into PPP line discipline. -+ * Called when a tty is put into PPP line discipline. Called in process -+ * context. - */ - static int - ppp_asynctty_open(struct tty_struct *tty) -@@ -255,6 +259,11 @@ - return -EAGAIN; - } - -+/* -+ * Called in process context only. May be re-entered by multiple -+ * ioctl calling threads. -+ */ -+ - static int - ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -@@ -716,7 +725,8 @@ - - /* - * Flush output from our internal buffers. -- * Called for the TCFLSH ioctl. -+ * Called for the TCFLSH ioctl. Can be entered in parallel -+ * but this is covered by the xmit_lock. - */ - static void - ppp_async_flush_output(struct asyncppp *ap) -@@ -816,7 +826,9 @@ - skb_trim(skb, 0); - } - --/* called when the tty driver has data for us. */ -+/* Called when the tty driver has data for us. Runs parallel with the -+ other ldisc functions but will not be re-entered */ -+ - static void - ppp_async_input(struct asyncppp *ap, const unsigned char *buf, - char *flags, int count) -diff -Nur linux-2.6.8.1/drivers/net/ppp_synctty.c linux-2.6.8.1-plasmaroo/drivers/net/ppp_synctty.c ---- linux-2.6.8.1/drivers/net/ppp_synctty.c 2004-08-14 11:55:20.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/ppp_synctty.c 2004-11-06 22:55:10.963602224 +0000 -@@ -175,6 +175,8 @@ - * frees the memory that ppp_synctty_receive is using. The best - * way to fix this is to use a rwlock in the tty struct, but for now - * we use a single global rwlock for all ttys in ppp line discipline. -+ * -+ * FIXME: Fixed in tty_io nowdays. - */ - static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; - -diff -Nur linux-2.6.8.1/drivers/net/slip.c linux-2.6.8.1-plasmaroo/drivers/net/slip.c ---- linux-2.6.8.1/drivers/net/slip.c 2004-08-14 11:56:24.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/slip.c 2004-11-06 22:55:10.969601312 +0000 -@@ -672,7 +672,9 @@ - * Handle the 'receiver data ready' interrupt. - * This function is called by the 'tty_io' module in the kernel when - * a block of SLIP data has been received, which can now be decapsulated -- * and sent on to some IP layer for further processing. -+ * and sent on to some IP layer for further processing. This will not -+ * be re-entered while running but other ldisc functions may be called -+ * in parallel - */ - - static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) -@@ -841,9 +843,11 @@ - * SLIP line discipline is called for. Because we are - * sure the tty line exists, we only have to link it to - * a free SLIP channel... -+ * -+ * Called in process context serialized from other ldisc calls. - */ --static int --slip_open(struct tty_struct *tty) -+ -+static int slip_open(struct tty_struct *tty) - { - struct slip *sl; - int err; -@@ -876,11 +880,11 @@ - tty->disc_data = sl; - sl->line = tty_devnum(tty); - sl->pid = current->pid; -+ -+ /* FIXME: already done before we were called - seems this can go */ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -- -+ - if (!test_bit(SLF_INUSE, &sl->flags)) { - /* Perform the low-level SLIP initialization. */ - if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) -@@ -923,6 +927,9 @@ - } - - /* -+ -+ FIXME: 1,2 are fixed 3 was never true anyway. -+ - Let me to blame a bit. - 1. TTY module calls this funstion on soft interrupt. - 2. TTY module calls this function WITH MASKED INTERRUPTS! -@@ -941,9 +948,8 @@ - - /* - * Close down a SLIP channel. -- * This means flushing out any pending queues, and then restoring the -- * TTY line discipline to what it was before it got hooked to SLIP -- * (which usually is TTY again). -+ * This means flushing out any pending queues, and then returning. This -+ * call is serialized against other ldisc functions. - */ - static void - slip_close(struct tty_struct *tty) -diff -Nur linux-2.6.8.1/drivers/net/wan/pc300_tty.c linux-2.6.8.1-plasmaroo/drivers/net/wan/pc300_tty.c ---- linux-2.6.8.1/drivers/net/wan/pc300_tty.c 2004-08-14 11:55:20.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/wan/pc300_tty.c 2004-11-06 22:55:11.003596144 +0000 -@@ -634,14 +634,8 @@ - } - - CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name); -- -- wake_up_interruptible(&tty->write_wait); -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){ -- CPC_TTY_DBG("%s: call line disc. wake up\n",cpc_tty->name); -- tty->ldisc.write_wakeup(tty); -- } - -+ tty_wakeup(tty); - return; - } - -@@ -692,9 +686,11 @@ - st_cpc_tty_area *cpc_tty; - volatile st_cpc_rx_buf * buf; - char flags=0,flg_rx=1; -+ struct tty_ldisc *ld; - - if (cpc_tty_cnt == 0) return; - -+ - for (i=0; (i < 4) && flg_rx ; i++) { - flg_rx = 0; - port = (int) data; -@@ -702,11 +698,18 @@ - cpc_tty = &cpc_tty_area[port]; - - if ((buf=cpc_tty->buf_rx.first) != 0) { -- -- if (cpc_tty->tty && (cpc_tty->tty->ldisc.receive_buf)) { -- CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); -- cpc_tty->tty->ldisc.receive_buf(cpc_tty->tty, (char *)(buf->data), -- &flags, buf->size); -+ -+ if(cpc_tty->tty) -+ { -+ ld = tty_ldisc_ref(cpc_tty); -+ if(ld) -+ { -+ if (ld->receive_buf)) { -+ CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); -+ ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size); -+ } -+ tty_ldisc_deref(ld); -+ } - } - cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; - kfree((unsigned char *)buf); -@@ -910,13 +913,7 @@ - CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name); - return; - } -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){ -- CPC_TTY_DBG("%s:call line disc. wakeup\n",cpc_tty->name); -- tty->ldisc.write_wakeup (tty); -- } -- -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - /* -diff -Nur linux-2.6.8.1/drivers/net/wan/sdla_chdlc.c linux-2.6.8.1-plasmaroo/drivers/net/wan/sdla_chdlc.c ---- linux-2.6.8.1/drivers/net/wan/sdla_chdlc.c 2004-08-14 11:55:32.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/wan/sdla_chdlc.c 2004-11-06 22:55:11.017594016 +0000 -@@ -3628,11 +3628,7 @@ - if ((tty=card->tty)==NULL) - return; - -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup){ -- (tty->ldisc.write_wakeup)(tty); -- } -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - #if defined(SERIAL_HAVE_POLL_WAIT) - wake_up_interruptible(&tty->poll_wait); - #endif -@@ -3857,6 +3853,7 @@ - char fp=0; - struct tty_struct *tty; - int i; -+ struct tty_ldisc *ld; - - if (!card->tty_open){ - dbg_printk(KERN_INFO "%s: TTY not open during receive\n", -@@ -3944,8 +3941,11 @@ - len -= offset; - } - sdla_peek(&card->hw, addr, card->tty_rx+offset, len); -- if (tty->ldisc.receive_buf){ -- tty->ldisc.receive_buf(tty,card->tty_rx,&fp,olen); -+ ld = tty_ldisc_ref(tty); -+ if (ld) { -+ if (ld->receive_buf) -+ ld->receive_buf(tty,card->tty_rx,&fp,olen); -+ tty_ldisc_deref(ld); - }else{ - if (net_ratelimit()){ - printk(KERN_INFO -@@ -4252,14 +4252,10 @@ - if (!tty) - return; - -- wake_up_interruptible(&tty->write_wait); - #if defined(SERIAL_HAVE_POLL_WAIT) - wake_up_interruptible(&tty->poll_wait); - #endif -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- -+ tty_wakeup(tty); - return; - } - -diff -Nur linux-2.6.8.1/drivers/net/wireless/strip.c linux-2.6.8.1-plasmaroo/drivers/net/wireless/strip.c ---- linux-2.6.8.1/drivers/net/wireless/strip.c 2004-08-14 11:55:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/net/wireless/strip.c 2004-11-06 22:55:11.026592648 +0000 -@@ -2661,8 +2661,6 @@ - tty->disc_data = strip_info; - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); - - /* - * Restore default settings -diff -Nur linux-2.6.8.1/drivers/s390/char/con3215.c linux-2.6.8.1-plasmaroo/drivers/s390/char/con3215.c ---- linux-2.6.8.1/drivers/s390/char/con3215.c 2004-08-14 11:55:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/s390/char/con3215.c 2004-11-06 22:55:11.039590672 +0000 -@@ -366,10 +366,7 @@ - tty = raw->tty; - if (tty != NULL && - RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1055,10 +1052,7 @@ - - raw = (struct raw3215_info *) tty->driver_data; - raw3215_flush_buffer(raw); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -diff -Nur linux-2.6.8.1/drivers/s390/char/sclp_tty.c linux-2.6.8.1-plasmaroo/drivers/s390/char/sclp_tty.c ---- linux-2.6.8.1/drivers/s390/char/sclp_tty.c 2004-08-14 11:56:25.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/s390/char/sclp_tty.c 2004-11-06 22:55:11.048589304 +0000 -@@ -277,10 +277,7 @@ - wake_up(&sclp_tty_waitq); - /* check if the tty needs a wake up call */ - if (sclp_tty != NULL) { -- if ((sclp_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- sclp_tty->ldisc.write_wakeup) -- (sclp_tty->ldisc.write_wakeup)(sclp_tty); -- wake_up_interruptible(&sclp_tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Nur linux-2.6.8.1/drivers/s390/char/sclp_vt220.c linux-2.6.8.1-plasmaroo/drivers/s390/char/sclp_vt220.c ---- linux-2.6.8.1/drivers/s390/char/sclp_vt220.c 2004-08-14 11:55:10.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/s390/char/sclp_vt220.c 2004-11-06 22:55:11.050589000 +0000 -@@ -139,10 +139,7 @@ - wake_up(&sclp_vt220_waitq); - /* Check if the tty needs a wake up call */ - if (sclp_vt220_tty != NULL) { -- if ((sclp_vt220_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- (sclp_vt220_tty->ldisc.write_wakeup != NULL)) -- (sclp_vt220_tty->ldisc.write_wakeup)(sclp_vt220_tty); -- wake_up_interruptible(&sclp_vt220_tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Nur linux-2.6.8.1/drivers/s390/net/ctctty.c linux-2.6.8.1-plasmaroo/drivers/s390/net/ctctty.c ---- linux-2.6.8.1/drivers/s390/net/ctctty.c 2004-08-14 11:55:33.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/s390/net/ctctty.c 2004-11-06 22:55:11.064586872 +0000 -@@ -307,10 +307,7 @@ - - info->flags &= ~CTC_ASYNC_TX_LINESTAT; - if (tty) { -- if (wake && (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - return (skb_queue_empty(&info->tx_queue) ? 0 : 1); -@@ -589,9 +586,7 @@ - info->lsr |= UART_LSR_TEMT; - spin_unlock_irqrestore(&ctc_tty_lock, flags); - wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup) (tty); -+ tty_wakeup(tty); - ex: - DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__); - return; -@@ -1066,8 +1061,7 @@ - skb_queue_purge(&info->tx_queue); - info->lsr |= UART_LSR_TEMT; - } -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - info->tty = 0; - tty->closing = 0; - if (info->blocked_open) { -diff -Nur linux-2.6.8.1/drivers/sbus/char/aurora.c linux-2.6.8.1-plasmaroo/drivers/sbus/char/aurora.c ---- linux-2.6.8.1/drivers/sbus/char/aurora.c 2004-08-14 11:54:50.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/sbus/char/aurora.c 2004-11-06 22:55:11.101581248 +0000 -@@ -1531,8 +1531,7 @@ - aurora_shutdown_port(bp, port); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - port->event = 0; - port->tty = 0; -@@ -1743,10 +1742,7 @@ - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - restore_flags(flags); - -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - #ifdef AURORA_DEBUG - printk("aurora_flush_buffer: end\n"); - #endif -@@ -2223,10 +2219,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - #ifdef AURORA_DEBUG - printk("do_softint: end\n"); -diff -Nur linux-2.6.8.1/drivers/serial/68328serial.c linux-2.6.8.1-plasmaroo/drivers/serial/68328serial.c ---- linux-2.6.8.1/drivers/serial/68328serial.c 2004-08-14 11:56:23.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/serial/68328serial.c 2004-11-06 22:55:11.109580032 +0000 -@@ -435,10 +435,7 @@ - return; - #if 0 - if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - #endif - } -@@ -858,10 +855,7 @@ - cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1185,11 +1179,13 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -+#warning "This is not and has never been valid so fix it" -+#if 0 - if (tty->ldisc.num != ldiscs[N_TTY].num) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -@@ -1198,6 +1194,7 @@ - if (tty->ldisc.open) - (tty->ldisc.open)(tty); - } -+#endif - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -diff -Nur linux-2.6.8.1/drivers/serial/68360serial.c linux-2.6.8.1-plasmaroo/drivers/serial/68360serial.c ---- linux-2.6.8.1/drivers/serial/68360serial.c 2004-08-14 11:56:23.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/serial/68360serial.c 2004-11-06 22:55:11.116578968 +0000 -@@ -700,12 +700,8 @@ - if (!tty) - return; - -- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) -+ tty_wakeup(tty); - } - - -@@ -1152,10 +1148,7 @@ - /* There is nothing to "flush", whatever we gave the CPM - * is on its way out. - */ -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - info->flags &= ~TX_WAKEUP; - } - -@@ -1716,8 +1709,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Nur linux-2.6.8.1/drivers/serial/mcfserial.c linux-2.6.8.1-plasmaroo/drivers/serial/mcfserial.c ---- linux-2.6.8.1/drivers/serial/mcfserial.c 2004-08-14 11:55:20.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/serial/mcfserial.c 2004-11-06 22:55:11.126577448 +0000 -@@ -424,11 +424,7 @@ - tty = info->tty; - if (!tty) - return; -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - -@@ -835,10 +831,7 @@ - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); - -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1232,11 +1225,12 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - info->event = 0; - info->tty = 0; -+#if 0 - if (tty->ldisc.num != ldiscs[N_TTY].num) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); -@@ -1245,6 +1239,7 @@ - if (tty->ldisc.open) - (tty->ldisc.open)(tty); - } -+#endif - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; -diff -Nur linux-2.6.8.1/drivers/serial/serial_core.c linux-2.6.8.1-plasmaroo/drivers/serial/serial_core.c ---- linux-2.6.8.1/drivers/serial/serial_core.c 2004-08-14 11:54:51.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/serial/serial_core.c 2004-11-06 22:55:11.131576688 +0000 -@@ -107,15 +107,7 @@ - static void uart_tasklet_action(unsigned long data) - { - struct uart_state *state = (struct uart_state *)data; -- struct tty_struct *tty; -- -- tty = state->info->tty; -- if (tty) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- tty->ldisc.write_wakeup(tty); -- wake_up_interruptible(&tty->write_wait); -- } -+ tty_wakeup(state->info->tty); - } - - static inline void -@@ -581,10 +573,7 @@ - spin_lock_irqsave(&port->lock, flags); - uart_circ_clear(&state->info->xmit); - spin_unlock_irqrestore(&port->lock, flags); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1216,7 +1205,7 @@ - { - struct uart_state *state = tty->driver_data; - struct uart_port *port; -- -+ - BUG_ON(!kernel_locked()); - - if (!state || !state->port) -@@ -1239,12 +1228,12 @@ - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ -- printk("uart_close: bad serial port count; tty->count is 1, " -+ printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { -- printk("rs_close: bad serial port count for %s: %d\n", -+ printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n", - tty->name, state->count); - state->count = 0; - } -@@ -1280,8 +1269,9 @@ - - uart_shutdown(state); - uart_flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ -+ tty_ldisc_flush(tty); -+ - tty->closing = 0; - state->info->tty = NULL; - -diff -Nur linux-2.6.8.1/drivers/tc/zs.c linux-2.6.8.1-plasmaroo/drivers/tc/zs.c ---- linux-2.6.8.1/drivers/tc/zs.c 2004-08-14 11:56:00.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/tc/zs.c 2004-11-06 22:55:11.138575624 +0000 -@@ -683,10 +683,7 @@ - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -@@ -1010,10 +1007,7 @@ - cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); -- wake_up_interruptible(&tty->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -+ tty_wakeup(tty); - } - - /* -@@ -1407,8 +1401,7 @@ - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); -- if (tty->ldisc.flush_buffer) -- tty->ldisc.flush_buffer(tty); -+ tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; -diff -Nur linux-2.6.8.1/drivers/usb/class/bluetty.c linux-2.6.8.1-plasmaroo/drivers/usb/class/bluetty.c ---- linux-2.6.8.1/drivers/usb/class/bluetty.c 2004-08-14 11:55:48.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/class/bluetty.c 2004-11-06 22:55:11.145574560 +0000 -@@ -992,17 +992,10 @@ - - dbg("%s", __FUNCTION__); - -- if (!bluetooth) { -+ if (!bluetooth) - return; -- } -- -- tty = bluetooth->tty; -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- dbg("%s - write wakeup call.", __FUNCTION__); -- (tty->ldisc.write_wakeup)(tty); -- } - -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(&bluetooth->tty); - } - - -diff -Nur linux-2.6.8.1/drivers/usb/class/cdc-acm.c linux-2.6.8.1-plasmaroo/drivers/usb/class/cdc-acm.c ---- linux-2.6.8.1/drivers/usb/class/cdc-acm.c 2004-08-14 11:55:35.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/class/cdc-acm.c 2004-11-06 22:55:11.146574408 +0000 -@@ -248,16 +248,11 @@ - static void acm_softint(void *private) - { - struct acm *acm = private; -- struct tty_struct *tty = acm->tty; - dbg("Entering acm_softint.\n"); - - if (!ACM_READY(acm)) - return; -- -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(acm->tty); - } - - /* -diff -Nur linux-2.6.8.1/drivers/usb/serial/digi_acceleport.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/digi_acceleport.c ---- linux-2.6.8.1/drivers/usb/serial/digi_acceleport.c 2004-08-14 11:55:31.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/digi_acceleport.c 2004-11-06 22:55:11.152573496 +0000 -@@ -624,14 +624,7 @@ - wake_up_interruptible( &port->write_wait ); - - /* wake up line discipline */ -- if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup ) -- (tty->ldisc.write_wakeup)(tty); -- -- /* wake up other tty processes */ -- wake_up_interruptible( &tty->write_wait ); -- /* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */ -- -+ tty_wakeup(tty); - } - - -@@ -1569,8 +1562,7 @@ - /* flush driver and line discipline buffers */ - if( tty->driver->flush_buffer ) - tty->driver->flush_buffer( tty ); -- if( tty->ldisc.flush_buffer ) -- tty->ldisc.flush_buffer( tty ); -+ tty_ldisc_flush(tty); - - if (port->serial->dev) { - /* wait for transmit idle */ -diff -Nur linux-2.6.8.1/drivers/usb/serial/empeg.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/empeg.c ---- linux-2.6.8.1/drivers/usb/serial/empeg.c 2004-08-14 11:56:23.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/empeg.c 2004-11-06 22:55:11.155573040 +0000 -@@ -516,7 +516,9 @@ - */ - port->tty->low_latency = 1; - -- /* Notify the tty driver that the termios have changed. */ -+ /* Notify the tty driver that the termios have changed. -+ FIXME: Why - the ldisc will do this anyway and NULL is not -+ a valid previous state */ - port->tty->ldisc.set_termios(port->tty, NULL); - - return; -diff -Nur linux-2.6.8.1/drivers/usb/serial/io_edgeport.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/io_edgeport.c ---- linux-2.6.8.1/drivers/usb/serial/io_edgeport.c 2004-08-14 11:54:48.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/io_edgeport.c 2004-11-06 22:55:11.169570912 +0000 -@@ -900,12 +900,7 @@ - - if (tty && edge_port->open) { - /* let the tty driver wakeup if it has a special write_wakeup function */ -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- (tty->ldisc.write_wakeup)(tty); -- } -- -- /* tell the tty driver that something has changed */ -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - // Release the Write URB -diff -Nur linux-2.6.8.1/drivers/usb/serial/io_ti.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/io_ti.c ---- linux-2.6.8.1/drivers/usb/serial/io_ti.c 2004-08-14 11:56:23.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/io_ti.c 2004-11-06 22:55:11.178569544 +0000 -@@ -1804,12 +1804,7 @@ - tty = port->tty; - if (tty) { - /* let the tty driver wakeup if it has a special write_wakeup function */ -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- (tty->ldisc.write_wakeup)(tty); -- } -- -- /* tell the tty driver that something has changed */ -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - } - -diff -Nur linux-2.6.8.1/drivers/usb/serial/ir-usb.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/ir-usb.c ---- linux-2.6.8.1/drivers/usb/serial/ir-usb.c 2004-08-14 11:55:31.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/ir-usb.c 2004-11-06 22:55:11.188568024 +0000 -@@ -449,6 +449,10 @@ - */ - tty = port->tty; - -+ /* -+ * FIXME: must not do this in IRQ context, -+ * must honour TTY_DONT_FLIP -+ */ - tty->ldisc.receive_buf( - tty, - data+1, -diff -Nur linux-2.6.8.1/drivers/usb/serial/keyspan_pda.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/keyspan_pda.c ---- linux-2.6.8.1/drivers/usb/serial/keyspan_pda.c 2004-08-14 11:55:35.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/keyspan_pda.c 2004-11-06 22:55:11.189567872 +0000 -@@ -186,13 +186,7 @@ - wake_up_interruptible( &port->write_wait ); - - /* wake up line discipline */ -- if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) -- && tty->ldisc.write_wakeup ) -- (tty->ldisc.write_wakeup)(tty); -- -- /* wake up other tty processes */ -- wake_up_interruptible( &tty->write_wait ); -- /* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */ -+ tty_wakeup(tty); - } - - static void keyspan_pda_request_unthrottle( struct usb_serial *serial ) -diff -Nur linux-2.6.8.1/drivers/usb/serial/mct_u232.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/mct_u232.c ---- linux-2.6.8.1/drivers/usb/serial/mct_u232.c 2004-08-14 11:55:47.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/mct_u232.c 2004-11-06 22:55:11.195566960 +0000 -@@ -579,11 +579,7 @@ - - if (write_blocking) { - wake_up_interruptible(&port->write_wait); -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && -- tty->ldisc.write_wakeup) -- (tty->ldisc.write_wakeup)(tty); -- wake_up_interruptible(&tty->write_wait); -- -+ tty_wakeup(tty); - } else { - /* from generic_write_bulk_callback */ - schedule_work(&port->work); -diff -Nur linux-2.6.8.1/drivers/usb/serial/usb-serial.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/usb-serial.c ---- linux-2.6.8.1/drivers/usb/serial/usb-serial.c 2004-08-14 11:56:26.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/usb-serial.c 2004-11-06 22:55:11.209564832 +0000 -@@ -755,12 +755,7 @@ - if (!tty) - return; - -- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { -- dbg("%s - write wakeup call.", __FUNCTION__); -- (tty->ldisc.write_wakeup)(tty); -- } -- -- wake_up_interruptible(&tty->write_wait); -+ tty_wakeup(tty); - } - - static void destroy_serial(struct kref *kref) -diff -Nur linux-2.6.8.1/drivers/usb/serial/whiteheat.c linux-2.6.8.1-plasmaroo/drivers/usb/serial/whiteheat.c ---- linux-2.6.8.1/drivers/usb/serial/whiteheat.c 2004-08-14 11:55:10.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/drivers/usb/serial/whiteheat.c 2004-11-06 22:55:11.217563616 +0000 -@@ -668,8 +668,7 @@ - - if (port->tty->driver->flush_buffer) - port->tty->driver->flush_buffer(port->tty); -- if (port->tty->ldisc.flush_buffer) -- port->tty->ldisc.flush_buffer(port->tty); -+ tty_ldisc_flush(port->tty); - - firm_report_tx_done(port); - -diff -Nur linux-2.6.8.1/fs/proc/proc_tty.c linux-2.6.8.1-plasmaroo/fs/proc/proc_tty.c ---- linux-2.6.8.1/fs/proc/proc_tty.c 2004-08-14 11:55:10.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/fs/proc/proc_tty.c 2004-11-06 22:55:11.236560728 +0000 -@@ -15,9 +15,6 @@ - #include - #include - --extern struct tty_ldisc ldiscs[]; -- -- - static int tty_ldiscs_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -@@ -159,12 +156,15 @@ - int i; - int len = 0; - off_t begin = 0; -- -+ struct tty_ldisc *ld; -+ - for (i=0; i < NR_LDISCS; i++) { -- if (!(ldiscs[i].flags & LDISC_FLAG_DEFINED)) -+ ld = tty_ldisc_get(i); -+ if (ld == NULL) - continue; - len += sprintf(page+len, "%-10s %2d\n", -- ldiscs[i].name ? ldiscs[i].name : "???", i); -+ ld->name ? ld->name : "???", i); -+ tty_ldisc_put(i); - if (len+begin > off+count) - break; - if (len+begin < off) { -diff -Nur linux-2.6.8.1/include/linux/tty.h linux-2.6.8.1-plasmaroo/include/linux/tty.h ---- linux-2.6.8.1/include/linux/tty.h 2004-08-14 11:55:32.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/include/linux/tty.h 2004-11-06 22:55:11.237560576 +0000 -@@ -306,26 +306,27 @@ - * tty->write. Thus, you must use the inline functions set_bit() and - * clear_bit() to make things atomic. - */ --#define TTY_THROTTLED 0 --#define TTY_IO_ERROR 1 --#define TTY_OTHER_CLOSED 2 --#define TTY_EXCLUSIVE 3 --#define TTY_DEBUG 4 --#define TTY_DO_WRITE_WAKEUP 5 --#define TTY_PUSH 6 --#define TTY_CLOSING 7 --#define TTY_DONT_FLIP 8 --#define TTY_HW_COOK_OUT 14 --#define TTY_HW_COOK_IN 15 --#define TTY_PTY_LOCK 16 --#define TTY_NO_WRITE_SPLIT 17 -+#define TTY_THROTTLED 0 /* Call unthrottle() at threshold min */ -+#define TTY_IO_ERROR 1 /* Canse an I/O error (may be no ldisc too) */ -+#define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */ -+#define TTY_EXCLUSIVE 3 /* Exclusive open mode */ -+#define TTY_DEBUG 4 /* Debugging */ -+#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ -+#define TTY_PUSH 6 /* n_tty private */ -+#define TTY_CLOSING 7 /* ->close() in progress */ -+#define TTY_DONT_FLIP 8 /* Defer buffer flip */ -+#define TTY_LDISC 9 /* Line discipline attached */ -+#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ -+#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ -+#define TTY_PTY_LOCK 16 /* pty private */ -+#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ -+#define TTY_HUPPED 18 /* Post driver->hangup() */ - - #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) - - extern void tty_write_flush(struct tty_struct *); - - extern struct termios tty_std_termios; --extern struct tty_ldisc ldiscs[]; - extern int fg_console, last_console, want_console; - - extern int kmsg_redirect; -@@ -362,6 +363,16 @@ - extern int tty_get_baud_rate(struct tty_struct *tty); - extern int tty_termios_baud_rate(struct termios *termios); - -+extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); -+extern void tty_ldisc_deref(struct tty_ldisc *); -+extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); -+ -+extern struct tty_ldisc *tty_ldisc_get(int); -+extern void tty_ldisc_put(int); -+ -+extern void tty_wakeup(struct tty_struct *tty); -+extern void tty_ldisc_flush(struct tty_struct *tty); -+ - struct semaphore; - extern struct semaphore tty_sem; - -diff -Nur linux-2.6.8.1/include/linux/tty_ldisc.h linux-2.6.8.1-plasmaroo/include/linux/tty_ldisc.h ---- linux-2.6.8.1/include/linux/tty_ldisc.h 2004-08-14 11:56:23.000000000 +0100 -+++ linux-2.6.8.1-plasmaroo/include/linux/tty_ldisc.h 2004-11-06 22:55:11.238560424 +0000 -@@ -95,6 +95,13 @@ - * that line discpline should try to send more characters to the - * low-level driver for transmission. If the line discpline does - * not have any more data to send, it can just return. -+ * -+ * int (*hangup)(struct tty_struct *) -+ * -+ * Called on a hangup. Tells the discipline that it should -+ * cease I/O to the tty driver. Can sleep. The driver should -+ * seek to perform this action quickly but should wait until -+ * any pending driver I/O is completed. - */ - - #include -@@ -122,6 +129,7 @@ - void (*set_termios)(struct tty_struct *tty, struct termios * old); - unsigned int (*poll)(struct tty_struct *, struct file *, - struct poll_table_struct *); -+ int (*hangup)(struct tty_struct *tty); - - /* - * The following routines are called from below. -@@ -132,6 +140,8 @@ - void (*write_wakeup)(struct tty_struct *); - - struct module *owner; -+ -+ int refcount; - }; - - #define TTY_LDISC_MAGIC 0x5403 diff --git a/sys-kernel/hppa-dev-sources/files/CAN-2004-0883.patch b/sys-kernel/hppa-dev-sources/files/CAN-2004-0883.patch deleted file mode 100644 index 99401cf93a0e..000000000000 --- a/sys-kernel/hppa-dev-sources/files/CAN-2004-0883.patch +++ /dev/null @@ -1,93 +0,0 @@ -diff -urN linux-2.6.8.1/fs/smbfs/proc.c linux-2.6.8.1.plasmaroo/fs/smbfs/proc.c ---- linux-2.6.8.1/fs/smbfs/proc.c 2004-08-24 17:15:57.000000000 +1000 -+++ linux-2.6.8.1.plasmaroo/fs/smbfs/proc.c 2004-11-06 11:27:20.000000000 +1100 -@@ -1427,9 +1427,9 @@ - * So we must first calculate the amount of padding used by the server. - */ - data_off -= hdrlen; -- if (data_off > SMB_READX_MAX_PAD) { -- PARANOIA("offset is larger than max pad!\n"); -- PARANOIA("%d > %d\n", data_off, SMB_READX_MAX_PAD); -+ if (data_off > SMB_READX_MAX_PAD || data_off < 0) { -+ PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n"); -+ PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off); - req->rq_rlen = req->rq_bufsize + 1; - return; - } -diff -urN linux-2.6.8.1/fs/smbfs/request.c linux-2.6.8.1.plasmaroo/fs/smbfs/request.c ---- linux-2.6.8.1/fs/smbfs/request.c 2004-11-06 11:27:51.000000000 +1100 -+++ linux-2.6.8.1.plasmaroo/fs/smbfs/request.c 2004-11-06 11:27:20.000000000 +1100 -@@ -588,6 +588,10 @@ - data_count = WVAL(inbuf, smb_drcnt); - - /* Modify offset for the split header/buffer we use */ -+ if (data_offset < hdrlen) -+ goto out_bad_data; -+ if (parm_offset < hdrlen) -+ goto out_bad_parm; - data_offset -= hdrlen; - parm_offset -= hdrlen; - -@@ -607,6 +611,10 @@ - req->rq_lparm = parm_count; - req->rq_data = req->rq_buffer + data_offset; - req->rq_parm = req->rq_buffer + parm_offset; -+ if (parm_offset + parm_count > req->rq_rlen) -+ goto out_bad_parm; -+ if (data_offset + data_count > req->rq_rlen) -+ goto out_bad_data; - return 0; - } - -@@ -634,6 +642,7 @@ - req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS); - if (!req->rq_trans2buffer) - goto out_no_mem; -+ memset(req->rq_trans2buffer, 0, buf_len); - - req->rq_parm = req->rq_trans2buffer; - req->rq_data = req->rq_trans2buffer + parm_tot; -@@ -643,8 +652,12 @@ - - if (parm_disp + parm_count > req->rq_total_parm) - goto out_bad_parm; -+ if (parm_offset + parm_count > req->rq_rlen) -+ goto out_bad_parm; - if (data_disp + data_count > req->rq_total_data) - goto out_bad_data; -+ if (data_offset + data_count > req->rq_rlen) -+ goto out_bad_data; - - inbuf = req->rq_buffer; - memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count); -@@ -657,8 +670,11 @@ - * Check whether we've received all of the data. Note that - * we use the packet totals -- total lengths might shrink! - */ -- if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) -+ if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) { -+ req->rq_ldata = data_tot; -+ req->rq_lparm = parm_tot; - return 0; -+ } - return 1; - - out_too_long: -@@ -676,13 +692,13 @@ - req->rq_errno = -EIO; - goto out; - out_bad_parm: -- printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n", -- parm_disp, parm_count, parm_tot); -+ printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d, ofs=%d\n", -+ parm_disp, parm_count, parm_tot, parm_offset); - req->rq_errno = -EIO; - goto out; - out_bad_data: -- printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n", -- data_disp, data_count, data_tot); -+ printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d, ofs=%d\n", -+ data_disp, data_count, data_tot, data_offset); - req->rq_errno = -EIO; - out: - return req->rq_errno; diff --git a/sys-kernel/hppa-dev-sources/files/CAN-2004-1074.patch b/sys-kernel/hppa-dev-sources/files/CAN-2004-1074.patch deleted file mode 100644 index 4c2b5c9c0102..000000000000 --- a/sys-kernel/hppa-dev-sources/files/CAN-2004-1074.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff -uNr linux-2.6.8.1-pa11-r2.orig/fs/binfmt_aout.c linux-2.6.8.1-pa11-r2/fs/binfmt_aout.c ---- linux-2.6.8.1-pa11-r2.orig/fs/binfmt_aout.c 2004-12-09 14:43:33.191733360 +0100 -+++ linux-2.6.8.1-pa11-r2/fs/binfmt_aout.c 2004-12-09 14:48:40.065081520 +0100 -@@ -43,13 +43,18 @@ - .min_coredump = PAGE_SIZE - }; - --static void set_brk(unsigned long start, unsigned long end) -+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) -+ -+static int set_brk(unsigned long start, unsigned long end) - { - start = PAGE_ALIGN(start); - end = PAGE_ALIGN(end); -- if (end <= start) -- return; -- do_brk(start, end - start); -+ if (end > start) { -+ unsigned long addr = do_brk(start, end - start); -+ if (BAD_ADDR(addr)) -+ return addr; -+ } -+ return 0; - } - - /* -@@ -413,7 +418,12 @@ - beyond_if: - set_binfmt(&aout_format); - -- set_brk(current->mm->start_brk, current->mm->brk); -+ -+ retval = set_brk(current->mm->start_brk, current->mm->brk); -+ if (retval < 0) { -+ send_sig(SIGKILL, current, 0); -+ return retval; -+ } - - retval = setup_arg_pages(bprm, EXSTACK_DEFAULT); - if (retval < 0) { -diff -uNr linux-2.6.8.1-pa11-r2.orig/fs/exec.c linux-2.6.8.1-pa11-r2/fs/exec.c ---- linux-2.6.8.1-pa11-r2.orig/fs/exec.c 2004-12-09 14:43:33.247724848 +0100 -+++ linux-2.6.8.1-pa11-r2/fs/exec.c 2004-12-09 14:46:24.696660648 +0100 -@@ -412,6 +412,7 @@ - - down_write(&mm->mmap_sem); - { -+ struct vm_area_struct *vma; - mpnt->vm_mm = mm; - #ifdef CONFIG_STACK_GROWSUP - mpnt->vm_start = stack_base; -@@ -432,6 +433,12 @@ - mpnt->vm_flags = VM_STACK_FLAGS; - mpnt->vm_flags |= mm->def_flags; - mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7]; -+ vma = find_vma(mm, mpnt->vm_start); -+ if (vma) { -+ up_write(&mm->mmap_sem); -+ kmem_cache_free(vm_area_cachep, mpnt); -+ return -ENOMEM; -+ } - insert_vm_struct(mm, mpnt); - mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; - } diff --git a/sys-kernel/hppa-dev-sources/files/binfmt_elf-loader-security.patch b/sys-kernel/hppa-dev-sources/files/binfmt_elf-loader-security.patch deleted file mode 100644 index 9ca23675f25d..000000000000 --- a/sys-kernel/hppa-dev-sources/files/binfmt_elf-loader-security.patch +++ /dev/null @@ -1,72 +0,0 @@ ---- linux-2.6.7-uc0-r8/fs/binfmt_elf.c 2004-11-12 11:50:08 -08:00 -+++ linux-2.6.7-uc0-r8-plasmaroo/fs/binfmt_elf.c 2004-11-12 11:50:08 -08:00 -@@ -335,9 +335,12 @@ - goto out; - - retval = kernel_read(interpreter,interp_elf_ex->e_phoff,(char *)elf_phdata,size); -- error = retval; -- if (retval < 0) -+ error = -EIO; -+ if (retval != size) { -+ if (retval < 0) -+ error = retval; - goto out_close; -+ } - - eppnt = elf_phdata; - for (i=0; ie_phnum; i++, eppnt++) { -@@ -532,8 +535,11 @@ - goto out; - - retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *) elf_phdata, size); -- if (retval < 0) -+ if (retval != size) { -+ if (retval >= 0) -+ retval = -EIO; - goto out_free_ph; -+ } - - files = current->files; /* Refcounted so ok */ - retval = unshare_files(); -@@ -580,8 +586,14 @@ - retval = kernel_read(bprm->file, elf_ppnt->p_offset, - elf_interpreter, - elf_ppnt->p_filesz); -- if (retval < 0) -+ if (retval != elf_ppnt->p_filesz) { -+ if (retval >= 0) -+ retval = -EIO; - goto out_free_interp; -+ } -+ /* make sure path is NULL terminated */ -+ elf_interpreter[elf_ppnt->p_filesz - 1] = '\0'; -+ - /* If the program interpreter is one of these two, - * then assume an iBCS2 image. Otherwise assume - * a native linux image. -@@ -616,8 +628,11 @@ - if (IS_ERR(interpreter)) - goto out_free_interp; - retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); -- if (retval < 0) -+ if (retval != BINPRM_BUF_SIZE) { -+ if (retval >= 0) -+ retval = -EIO; - goto out_free_dentry; -+ } - - /* Get the exec headers */ - loc->interp_ex = *((struct exec *) bprm->buf); -@@ -776,8 +791,10 @@ - } - - error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); -- if (BAD_ADDR(error)) -- continue; -+ if (BAD_ADDR(error)) { -+ send_sig(SIGKILL, current, 0); -+ goto out_free_dentry; -+ } - - if (!load_addr_set) { - load_addr_set = 1; diff --git a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p1-r2 b/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p1-r2 deleted file mode 100644 index 7e748cdf493c..000000000000 --- a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p1-r2 +++ /dev/null @@ -1,2 +0,0 @@ -MD5 a74671ea68b0e3c609e8785ed8497c14 linux-2.6.7.tar.bz2 35092228 -MD5 c9354bcf2a81d22a23d6c0c1725717a1 patch-2.6.7-pa1.gz 125457 diff --git a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14 b/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14 deleted file mode 100644 index 538c50fffb72..000000000000 --- a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14 +++ /dev/null @@ -1,2 +0,0 @@ -MD5 a74671ea68b0e3c609e8785ed8497c14 linux-2.6.7.tar.bz2 35092228 -MD5 d25a37371b5e4c89d4013a17986dc8a8 patch-2.6.7-pa14.gz 151607 diff --git a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14-r1 b/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14-r1 deleted file mode 100644 index eae74def394b..000000000000 --- a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14-r1 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 a74671ea68b0e3c609e8785ed8497c14 linux-2.6.7.tar.bz2 35092228 -MD5 d25a37371b5e4c89d4013a17986dc8a8 patch-2.6.7-pa14.gz 151607 -MD5 52996b643afbd6ed9ba38b9483c2cac3 linux-2.6.7-CAN-2004-0415.patch 112612 diff --git a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11 b/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11 deleted file mode 100644 index 4571cc199906..000000000000 --- a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11 +++ /dev/null @@ -1,2 +0,0 @@ -MD5 9517ca999e822b898fbdc7e72796b1aa linux-2.6.8.1.tar.bz2 35628066 -MD5 7d2bce70b2d231234bef64dbebb33385 patch-2.6.8.1-pa11.gz 89416 diff --git a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r1 b/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r1 deleted file mode 100644 index 4571cc199906..000000000000 --- a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r1 +++ /dev/null @@ -1,2 +0,0 @@ -MD5 9517ca999e822b898fbdc7e72796b1aa linux-2.6.8.1.tar.bz2 35628066 -MD5 7d2bce70b2d231234bef64dbebb33385 patch-2.6.8.1-pa11.gz 89416 diff --git a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r2 b/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r2 deleted file mode 100644 index 4571cc199906..000000000000 --- a/sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r2 +++ /dev/null @@ -1,2 +0,0 @@ -MD5 9517ca999e822b898fbdc7e72796b1aa linux-2.6.8.1.tar.bz2 35628066 -MD5 7d2bce70b2d231234bef64dbebb33385 patch-2.6.8.1-pa11.gz 89416 diff --git a/sys-kernel/hppa-dev-sources/files/firmware.c.patch b/sys-kernel/hppa-dev-sources/files/firmware.c.patch deleted file mode 100644 index 861afed7b4a3..000000000000 --- a/sys-kernel/hppa-dev-sources/files/firmware.c.patch +++ /dev/null @@ -1,96 +0,0 @@ -diff -urN --exclude-from=/tmp/dont11503.12372 ../.#prev/linux-2.6/arch/parisc/kernel/firmware.c linux-2.6/arch/parisc/kernel/firmware.c ---- ../.#prev/linux-2.6/arch/parisc/kernel/firmware.c Sun Aug 8 21:22:53 2004 -+++ linux-2.6/arch/parisc/kernel/firmware.c Sun Aug 8 21:20:08 2004 -@@ -237,11 +237,11 @@ - #ifdef __LP64__ - int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) - { -+ int retval = 0; -+ - if (!is_pdc_pat()) - return -1; - -- int retval = 0; -- - spin_lock_irq(&pdc_lock); - retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data)); - spin_unlock_irq(&pdc_lock); -@@ -1276,29 +1276,29 @@ - long real64_call(unsigned long fn, ...) - { - va_list args; -- extern struct wide_stack real_stack; -+ extern struct wide_stack real64_stack __attribute__ ((alias ("real_stack"))); - extern unsigned long real64_call_asm(unsigned long *, - unsigned long *, - unsigned long); - - va_start(args, fn); -- real_stack.arg0 = va_arg(args, unsigned long); -- real_stack.arg1 = va_arg(args, unsigned long); -- real_stack.arg2 = va_arg(args, unsigned long); -- real_stack.arg3 = va_arg(args, unsigned long); -- real_stack.arg4 = va_arg(args, unsigned long); -- real_stack.arg5 = va_arg(args, unsigned long); -- real_stack.arg6 = va_arg(args, unsigned long); -- real_stack.arg7 = va_arg(args, unsigned long); -- real_stack.arg8 = va_arg(args, unsigned long); -- real_stack.arg9 = va_arg(args, unsigned long); -- real_stack.arg10 = va_arg(args, unsigned long); -- real_stack.arg11 = va_arg(args, unsigned long); -- real_stack.arg12 = va_arg(args, unsigned long); -- real_stack.arg13 = va_arg(args, unsigned long); -+ real64_stack.arg0 = va_arg(args, unsigned long); -+ real64_stack.arg1 = va_arg(args, unsigned long); -+ real64_stack.arg2 = va_arg(args, unsigned long); -+ real64_stack.arg3 = va_arg(args, unsigned long); -+ real64_stack.arg4 = va_arg(args, unsigned long); -+ real64_stack.arg5 = va_arg(args, unsigned long); -+ real64_stack.arg6 = va_arg(args, unsigned long); -+ real64_stack.arg7 = va_arg(args, unsigned long); -+ real64_stack.arg8 = va_arg(args, unsigned long); -+ real64_stack.arg9 = va_arg(args, unsigned long); -+ real64_stack.arg10 = va_arg(args, unsigned long); -+ real64_stack.arg11 = va_arg(args, unsigned long); -+ real64_stack.arg12 = va_arg(args, unsigned long); -+ real64_stack.arg13 = va_arg(args, unsigned long); - va_end(args); - -- return real64_call_asm(&real_stack.sp, &real_stack.arg0, fn); -+ return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn); - } - - #endif /* __LP64__ */ -diff -urN --exclude-from=/tmp/dont11503.12372 ../.#prev/linux-2.6/arch/parisc/kernel/real2.S linux-2.6/arch/parisc/kernel/real2.S ---- ../.#prev/linux-2.6/arch/parisc/kernel/real2.S Sun May 23 18:02:45 2004 -+++ linux-2.6/arch/parisc/kernel/real2.S Sun Aug 8 21:20:08 2004 -@@ -12,8 +12,12 @@ - - .section .bss - .export real_stack -+ .export real32_stack -+ .export real64_stack - .align 64 - real_stack: -+real32_stack: -+real64_stack: - .block 8192 - - #ifdef __LP64__ -diff -urN --exclude-from=/tmp/dont11503.12372 ../.#prev/linux-2.6/arch/parisc/kernel/sys_parisc32.c linux-2.6/arch/parisc/kernel/sys_parisc32.c ---- ../.#prev/linux-2.6/arch/parisc/kernel/sys_parisc32.c Sun Aug 8 21:22:53 2004 -+++ linux-2.6/arch/parisc/kernel/sys_parisc32.c Sun Aug 8 21:20:08 2004 -@@ -205,10 +205,11 @@ - - asmlinkage long sys32_time(compat_time_t *tloc) - { -- struct timeval tv; -+ struct timeval tv; -+ compat_time_t now32; - - do_gettimeofday(&tv); -- compat_time_t now32 = tv.tv_sec; -+ now32 = tv.tv_sec; - - if (tloc) - if (put_user(now32, tloc)) diff --git a/sys-kernel/hppa-dev-sources/files/ncr53c8xx.diff b/sys-kernel/hppa-dev-sources/files/ncr53c8xx.diff deleted file mode 100644 index 564afdee9a46..000000000000 --- a/sys-kernel/hppa-dev-sources/files/ncr53c8xx.diff +++ /dev/null @@ -1,137 +0,0 @@ ---- linux-2.6.7-pa1-wrk/drivers/scsi/ncr53c8xx.h.orig 2004-06-18 20:30:09.000000000 +0200 -+++ linux-2.6.7-pa1-wrk/drivers/scsi/ncr53c8xx.h 2004-06-18 21:15:45.703972000 +0200 -@@ -48,6 +48,18 @@ - - #include "sym53c8xx_defs.h" - -+/* -+ Build a scatter/gather entry. -+ see sym53c8xx_2/sym_hipd.h for more detailed sym_build_sge() -+ implementation ;) -+ */ -+ -+#define ncr_build_sge(np, data, badd, len) \ -+do { \ -+ (data)->addr = cpu_to_scr(badd); \ -+ (data)->size = cpu_to_scr(len); \ -+} while (0) -+ - /*========================================================== - ** - ** Structures used by the detection routine to transmit ---- linux-2.6.7-pa1-wrk/drivers/scsi/ncr53c8xx.c.orig 2004-05-30 01:28:20.000000000 +0200 -+++ linux-2.6.7-pa1-wrk/drivers/scsi/ncr53c8xx.c 2004-06-18 21:53:34.803972000 +0200 -@@ -91,7 +91,7 @@ - */ - - /* Name and version of the driver */ --#define SCSI_NCR_DRIVER_NAME "ncr53c8xx-3.4.3e" -+#define SCSI_NCR_DRIVER_NAME "ncr53c8xx-3.4.3f" - - #define SCSI_NCR_DEBUG_FLAGS (0) - -@@ -839,7 +839,7 @@ - struct scr_tblmove smsg ; - struct scr_tblmove cmd ; - struct scr_tblmove sense ; -- struct scr_tblmove data [MAX_SCATTER]; -+ struct scr_tblmove data[MAX_SCATTER]; - }; - - -@@ -3845,7 +3845,7 @@ - - direction = scsi_data_direction(cmd); - if (direction != SCSI_DATA_NONE) { -- segments = ncr_scatter (np, cp, cp->cmd); -+ segments = ncr_scatter(np, cp, cp->cmd); - if (segments < 0) { - ncr_free_ccb(np, cp); - return(DID_ERROR); -@@ -7575,44 +7575,57 @@ - ** sizes to the data segment array. - */ - --static int ncr_scatter(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd) -+static int ncr_scatter_no_sglist(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd) - { -- struct scr_tblmove *data; -- int segment = 0; -- int use_sg = (int) cmd->use_sg; -+ struct scr_tblmove *data = &cp->phys.data[MAX_SCATTER - 1]; -+ int segment; - -- data = cp->phys.data; -- cp->data_len = 0; -+ cp->data_len = cmd->request_bufflen; - -- if (!use_sg) { -- if (cmd->request_bufflen) { -- u_long baddr = map_scsi_single_data(np, cmd); -- -- data = &data[MAX_SCATTER - 1]; -- data[0].addr = cpu_to_scr(baddr); -- data[0].size = cpu_to_scr(cmd->request_bufflen); -- cp->data_len = cmd->request_bufflen; -+ if (cmd->request_bufflen) { -+ dma_addr_t baddr = map_scsi_single_data(np, cmd); -+ if (baddr) { -+ ncr_build_sge(np, data, baddr, cmd->request_bufflen); - segment = 1; -+ } else { -+ segment = -2; - } -+ } else { -+ segment = 0; - } -- else if (use_sg <= MAX_SCATTER) { -+ -+ return segment; -+} -+ -+static int ncr_scatter(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd) -+{ -+ int segment = 0; -+ int use_sg = (int) cmd->use_sg; -+ -+ cp->data_len = 0; -+ -+ if (!use_sg) -+ segment = ncr_scatter_no_sglist(np, cp, cmd); -+ else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) { - struct scatterlist *scatter = (struct scatterlist *)cmd->buffer; -+ struct scr_tblmove *data; -+ -+ if (use_sg > MAX_SCATTER) { -+ unmap_scsi_data(np, cmd); -+ return -1; -+ } -+ -+ data = &cp->phys.data[MAX_SCATTER - use_sg]; - -- use_sg = map_scsi_sg_data(np, cmd); -- data = &data[MAX_SCATTER - use_sg]; -+ for (segment = 0; segment < use_sg; segment++) { -+ dma_addr_t baddr = sg_dma_address(&scatter[segment]); -+ unsigned int len = sg_dma_len(&scatter[segment]); - -- while (segment < use_sg) { -- u_long baddr = scsi_sg_dma_address(&scatter[segment]); -- unsigned int len = scsi_sg_dma_len(&scatter[segment]); -- -- data[segment].addr = cpu_to_scr(baddr); -- data[segment].size = cpu_to_scr(len); -- cp->data_len += len; -- ++segment; -+ ncr_build_sge(np, &data[segment], baddr, len); -+ cp->data_len += len; - } -- } -- else { -- return -1; -+ } else { -+ segment = -2; - } - - return segment; - diff --git a/sys-kernel/hppa-dev-sources/files/ptmx-security.patch b/sys-kernel/hppa-dev-sources/files/ptmx-security.patch deleted file mode 100644 index 2312a2bf5e3b..000000000000 --- a/sys-kernel/hppa-dev-sources/files/ptmx-security.patch +++ /dev/null @@ -1,21 +0,0 @@ -Index: linux-2.6.5/fs/devpts/inode.c -=================================================================== ---- linux-2.6.5.orig/fs/devpts/inode.c -+++ linux-2.6.5/fs/devpts/inode.c -@@ -178,9 +178,13 @@ struct tty_struct *devpts_get_tty(int nu - { - struct dentry *dentry = get_node(number); - struct tty_struct *tty; -- -- tty = (IS_ERR(dentry) || !dentry->d_inode) ? NULL : -- dentry->d_inode->u.generic_ip; -+ -+ tty = NULL; -+ if (!IS_ERR(dentry)) { -+ if (dentry->d_inode) -+ tty = dentry->d_inode->u.generic_ip; -+ dput(dentry); -+ } - - up(&devpts_root->d_inode->i_sem); - diff --git a/sys-kernel/hppa-dev-sources/files/security-proc-cmdline.patch b/sys-kernel/hppa-dev-sources/files/security-proc-cmdline.patch deleted file mode 100644 index bb80884c394e..000000000000 --- a/sys-kernel/hppa-dev-sources/files/security-proc-cmdline.patch +++ /dev/null @@ -1,24 +0,0 @@ - -From: Roger Luethi - -If you win the race with a starting process, you can read its environment. - -Signed-off-by: Andrew Morton ---- - - 25-akpm/fs/proc/base.c | 2 ++ - 1 files changed, 2 insertions(+) - -diff -puN fs/proc/base.c~proc_pid_cmdline-race-fix fs/proc/base.c ---- 25/fs/proc/base.c~proc_pid_cmdline-race-fix 2004-08-05 11:28:21.915442360 -0700 -+++ 25-akpm/fs/proc/base.c 2004-08-05 11:28:21.919441752 -0700 -@@ -340,6 +340,8 @@ static int proc_pid_cmdline(struct task_ - struct mm_struct *mm = get_task_mm(task); - if (!mm) - goto out; -+ if (!mm->arg_end) -+ goto out; /* Shh! No looking before we're done */ - - len = mm->arg_end - mm->arg_start; - -_ diff --git a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p1-r2.ebuild b/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p1-r2.ebuild deleted file mode 100644 index 7a62fe080487..000000000000 --- a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p1-r2.ebuild +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 1999-2004 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p1-r2.ebuild,v 1.2 2004/07/15 03:50:25 agriffis Exp $ -#OKV=original kernel version, KV=patched kernel version. They can be the same. - -ETYPE="sources" -inherit kernel-2 eutils -OKV="${PV/_p*/}" -PATCH_LEVEL="${PV/${OKV}_p/}" -EXTRAVERSION="-pa${PATCH_LEVEL}" -[ ! "${PR}" = "r0" ] && EXTRAVERSION="${EXTRAVERSION}-${PR}" -KV=${OKV}${EXTRAVERSION} -S=${WORKDIR}/linux-${KV} - - -DESCRIPTION="Full sources for the Linux kernel with patch for hppa" -SRC_URI="mirror://kernel/linux/kernel/v2.6/linux-${OKV}.tar.bz2 http://ftp.parisc-linux.org/cvs/linux-2.6/patch-${OKV}-pa${PATCH_LEVEL}.gz" -HOMEPAGE="http://www.kernel.org/ http://www.gentoo.org/ http://parisc-linux.org" -KEYWORDS="hppa -*" -IUSE="" -SLOT="${KV}" - - -src_unpack() { - unpack linux-${OKV}.tar.bz2 - mv ${WORKDIR}/linux-${OKV} ${WORKDIR}/linux-${KV} - cd ${S} - - epatch ${DISTDIR}/patch-${OKV}-pa${PATCH_LEVEL}.gz - epatch ${FILESDIR}/ncr53c8xx.diff - epatch ${FILESDIR}/CAN-2004-0626-death_packet.patch - epatch ${FILESDIR}/CAN-2004-0497.patch - -} diff --git a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14-r1.ebuild b/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14-r1.ebuild deleted file mode 100644 index bda6d2a709e8..000000000000 --- a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14-r1.ebuild +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 1999-2004 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14-r1.ebuild,v 1.1 2004/08/09 23:32:52 gmsoft Exp $ -#OKV=original kernel version, KV=patched kernel version. They can be the same. - -ETYPE="sources" -inherit kernel-2 eutils -OKV="${PV/_p*/}" -PATCH_LEVEL="${PV/${OKV}_p/}" -EXTRAVERSION="-pa${PATCH_LEVEL}" -[ ! "${PR}" = "r0" ] && EXTRAVERSION="${EXTRAVERSION}-${PR}" -KV=${OKV}${EXTRAVERSION} -S=${WORKDIR}/linux-${KV} - - -DESCRIPTION="Full sources for the Linux kernel with patch for hppa" -SRC_URI="mirror://kernel/linux/kernel/v2.6/linux-${OKV}.tar.bz2 http://ftp.parisc-linux.org/cvs/linux-2.6/patch-${OKV}-pa${PATCH_LEVEL}.gz http://dev.gentoo.org/~plasmaroo/patches/kernel/misc/security/linux-2.6.7-CAN-2004-0415.patch" -HOMEPAGE="http://www.kernel.org/ http://www.gentoo.org/ http://parisc-linux.org" -KEYWORDS="hppa -*" -IUSE="" -SLOT="${KV}" - - -src_unpack() { - unpack linux-${OKV}.tar.bz2 - mv ${WORKDIR}/linux-${OKV} ${WORKDIR}/linux-${KV} - cd ${S} - - epatch ${DISTDIR}/patch-${OKV}-pa${PATCH_LEVEL}.gz - epatch ${FILESDIR}/ncr53c8xx.diff - epatch ${FILESDIR}/firmware.c.patch - epatch ${DISTDIR}/linux-2.6.7-CAN-2004-0415.patch - epatch ${FILESDIR}/CAN-2004-0626-death_packet.patch - epatch ${FILESDIR}/CAN-2004-0497.patch - epatch ${FILESDIR}/CAN-2004-0596.patch - epatch ${FILESDIR}/security-proc-cmdline.patch - -} diff --git a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14.ebuild b/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14.ebuild deleted file mode 100644 index 447c8c1609d0..000000000000 --- a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14.ebuild +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 1999-2004 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14.ebuild,v 1.1 2004/07/24 07:08:29 vapier Exp $ -#OKV=original kernel version, KV=patched kernel version. They can be the same. - -ETYPE="sources" -inherit kernel-2 eutils -OKV="${PV/_p*/}" -PATCH_LEVEL="${PV/${OKV}_p/}" -EXTRAVERSION="-pa${PATCH_LEVEL}" -[ ! "${PR}" = "r0" ] && EXTRAVERSION="${EXTRAVERSION}-${PR}" -KV=${OKV}${EXTRAVERSION} -S=${WORKDIR}/linux-${KV} - - -DESCRIPTION="Full sources for the Linux kernel with patch for hppa" -SRC_URI="mirror://kernel/linux/kernel/v2.6/linux-${OKV}.tar.bz2 http://ftp.parisc-linux.org/cvs/linux-2.6/patch-${OKV}-pa${PATCH_LEVEL}.gz" -HOMEPAGE="http://www.kernel.org/ http://www.gentoo.org/ http://parisc-linux.org" -KEYWORDS="hppa -*" -IUSE="" -SLOT="${KV}" - - -src_unpack() { - unpack linux-${OKV}.tar.bz2 - mv ${WORKDIR}/linux-${OKV} ${WORKDIR}/linux-${KV} - cd ${S} - - epatch ${DISTDIR}/patch-${OKV}-pa${PATCH_LEVEL}.gz - epatch ${FILESDIR}/ncr53c8xx.diff - epatch ${FILESDIR}/CAN-2004-0626-death_packet.patch - epatch ${FILESDIR}/CAN-2004-0497.patch - -} diff --git a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r1.ebuild b/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r1.ebuild deleted file mode 100644 index e5bee9809ecb..000000000000 --- a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r1.ebuild +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 1999-2004 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r1.ebuild,v 1.1 2004/11/24 17:35:47 gmsoft Exp $ -#OKV=original kernel version, KV=patched kernel version. They can be the same. - -ETYPE="sources" -inherit kernel-2 eutils -OKV="${PV/_p*/}" -PATCH_LEVEL="${PV/${OKV}_p/}" -EXTRAVERSION="-pa${PATCH_LEVEL}" -[ ! "${PR}" = "r0" ] && EXTRAVERSION="${EXTRAVERSION}-${PR}" -KV=${OKV}${EXTRAVERSION} -S=${WORKDIR}/linux-${KV} - - -DESCRIPTION="Full sources for the Linux kernel with patch for hppa" -SRC_URI="mirror://kernel/linux/kernel/v2.6/linux-${OKV}.tar.bz2 http://ftp.parisc-linux.org/cvs/linux-2.6/patch-${OKV}-pa${PATCH_LEVEL}.gz" -HOMEPAGE="http://www.kernel.org/ http://www.gentoo.org/ http://parisc-linux.org" -KEYWORDS="hppa -*" -IUSE="" -SLOT="${KV}" - - -src_unpack() { - unpack linux-${OKV}.tar.bz2 - mv ${WORKDIR}/linux-${OKV} ${WORKDIR}/linux-${KV} - cd ${S} - - epatch ${DISTDIR}/patch-${OKV}-pa${PATCH_LEVEL}.gz - epatch ${FILESDIR}/security-proc-cmdline.patch - epatch ${FILESDIR}/binfmt_elf-loader-security.patch - epatch ${FILESDIR}/CAN-2004-0883.patch - epatch ${FILESDIR}/ptmx-security.patch - epatch ${FILESDIR}/CAN-2004-0814.patch - -} diff --git a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r2.ebuild b/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r2.ebuild deleted file mode 100644 index 1f397bb58eba..000000000000 --- a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r2.ebuild +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 1999-2004 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r2.ebuild,v 1.1 2004/12/08 17:10:46 gmsoft Exp $ -#OKV=original kernel version, KV=patched kernel version. They can be the same. - -ETYPE="sources" -inherit kernel-2 eutils -OKV="${PV/_p*/}" -PATCH_LEVEL="${PV/${OKV}_p/}" -EXTRAVERSION="-pa${PATCH_LEVEL}" -[ ! "${PR}" = "r0" ] && EXTRAVERSION="${EXTRAVERSION}-${PR}" -KV=${OKV}${EXTRAVERSION} -S=${WORKDIR}/linux-${KV} - - -DESCRIPTION="Full sources for the Linux kernel with patch for hppa" -SRC_URI="mirror://kernel/linux/kernel/v2.6/linux-${OKV}.tar.bz2 http://ftp.parisc-linux.org/cvs/linux-2.6/patch-${OKV}-pa${PATCH_LEVEL}.gz" -HOMEPAGE="http://www.kernel.org/ http://www.gentoo.org/ http://parisc-linux.org" -KEYWORDS="hppa -*" -IUSE="" -SLOT="${KV}" - - -src_unpack() { - unpack linux-${OKV}.tar.bz2 - mv ${WORKDIR}/linux-${OKV} ${WORKDIR}/linux-${KV} - cd ${S} - - epatch ${DISTDIR}/patch-${OKV}-pa${PATCH_LEVEL}.gz - epatch ${FILESDIR}/security-proc-cmdline.patch - epatch ${FILESDIR}/binfmt_elf-loader-security.patch - epatch ${FILESDIR}/CAN-2004-0883.patch - epatch ${FILESDIR}/ptmx-security.patch - epatch ${FILESDIR}/CAN-2004-0814-r1.patch - epatch ${FILESDIR}/AF_UNIX-security.patch - epatch ${FILESDIR}/CAN-2004-1074.patch - - -} diff --git a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11.ebuild b/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11.ebuild deleted file mode 100644 index 47106a669d11..000000000000 --- a/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11.ebuild +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 1999-2004 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11.ebuild,v 1.1 2004/10/01 22:07:20 vapier Exp $ -#OKV=original kernel version, KV=patched kernel version. They can be the same. - -ETYPE="sources" -inherit kernel-2 eutils -OKV="${PV/_p*/}" -PATCH_LEVEL="${PV/${OKV}_p/}" -EXTRAVERSION="-pa${PATCH_LEVEL}" -[ ! "${PR}" = "r0" ] && EXTRAVERSION="${EXTRAVERSION}-${PR}" -KV=${OKV}${EXTRAVERSION} -S=${WORKDIR}/linux-${KV} - - -DESCRIPTION="Full sources for the Linux kernel with patch for hppa" -SRC_URI="mirror://kernel/linux/kernel/v2.6/linux-${OKV}.tar.bz2 http://ftp.parisc-linux.org/cvs/linux-2.6/patch-${OKV}-pa${PATCH_LEVEL}.gz" -HOMEPAGE="http://www.kernel.org/ http://www.gentoo.org/ http://parisc-linux.org" -KEYWORDS="hppa -*" -IUSE="" -SLOT="${KV}" - - -src_unpack() { - unpack linux-${OKV}.tar.bz2 - mv ${WORKDIR}/linux-${OKV} ${WORKDIR}/linux-${KV} - cd ${S} - - epatch ${DISTDIR}/patch-${OKV}-pa${PATCH_LEVEL}.gz - epatch ${FILESDIR}/security-proc-cmdline.patch - -} diff --git a/sys-kernel/hppa-dev-sources/metadata.xml b/sys-kernel/hppa-dev-sources/metadata.xml deleted file mode 100644 index 899166bc36e0..000000000000 --- a/sys-kernel/hppa-dev-sources/metadata.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - -hppa-kernel - -2.6 kernels for hppa. - -