Removed hppa-dev-sources.
authorGuy Martin <gmsoft@gentoo.org>
Wed, 29 Dec 2004 00:14:11 +0000 (00:14 +0000)
committerGuy Martin <gmsoft@gentoo.org>
Wed, 29 Dec 2004 00:14:11 +0000 (00:14 +0000)
28 files changed:
sys-kernel/hppa-dev-sources/ChangeLog [deleted file]
sys-kernel/hppa-dev-sources/Manifest [deleted file]
sys-kernel/hppa-dev-sources/files/AF_UNIX-security.patch [deleted file]
sys-kernel/hppa-dev-sources/files/CAN-2004-0497.patch [deleted file]
sys-kernel/hppa-dev-sources/files/CAN-2004-0596.patch [deleted file]
sys-kernel/hppa-dev-sources/files/CAN-2004-0626-death_packet.patch [deleted file]
sys-kernel/hppa-dev-sources/files/CAN-2004-0814-r1.patch [deleted file]
sys-kernel/hppa-dev-sources/files/CAN-2004-0814.patch [deleted file]
sys-kernel/hppa-dev-sources/files/CAN-2004-0883.patch [deleted file]
sys-kernel/hppa-dev-sources/files/CAN-2004-1074.patch [deleted file]
sys-kernel/hppa-dev-sources/files/binfmt_elf-loader-security.patch [deleted file]
sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p1-r2 [deleted file]
sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14 [deleted file]
sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.7_p14-r1 [deleted file]
sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11 [deleted file]
sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r1 [deleted file]
sys-kernel/hppa-dev-sources/files/digest-hppa-dev-sources-2.6.8.1_p11-r2 [deleted file]
sys-kernel/hppa-dev-sources/files/firmware.c.patch [deleted file]
sys-kernel/hppa-dev-sources/files/ncr53c8xx.diff [deleted file]
sys-kernel/hppa-dev-sources/files/ptmx-security.patch [deleted file]
sys-kernel/hppa-dev-sources/files/security-proc-cmdline.patch [deleted file]
sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p1-r2.ebuild [deleted file]
sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14-r1.ebuild [deleted file]
sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.7_p14.ebuild [deleted file]
sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r1.ebuild [deleted file]
sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11-r2.ebuild [deleted file]
sys-kernel/hppa-dev-sources/hppa-dev-sources-2.6.8.1_p11.ebuild [deleted file]
sys-kernel/hppa-dev-sources/metadata.xml [deleted file]

diff --git a/sys-kernel/hppa-dev-sources/ChangeLog b/sys-kernel/hppa-dev-sources/ChangeLog
deleted file mode 100644 (file)
index 84bd540..0000000
+++ /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 <gmsoft@gentoo.org> 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 <gmsoft@gentoo.org> +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 <gmsoft@gentoo.org> +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 <vapier@gentoo.org>
-  +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 <gmsoft@gentoo.org>
-  +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 <gmsoft@gentoo.org>
-  +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 <gmsoft@gentoo.org> +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 <vapier@gentoo.org>
-  +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 <gmsoft@gentoo.org>
-  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 <gmsoft@gentoo.org>
-  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 <gmsoft@gentoo.org>
-  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 <gmsoft@gentoo.org>
-  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 <gmsoft@gentoo.org>
-  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 <gmsoft@gentoo.org>
-  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 <gmsoft@gentoo.org>
-  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 <vapier@gentoo.org>
-  Version bump.
-
-*hppa-dev-sources-2.6.5_p2 (05 Apr 2004)
-
-  05 Apr 2004; Mike Frysinger <vapier@gentoo.org>
-  Version bump.
-
-*hppa-dev-sources-2.6.4_p2 (01 Apr 2004)
-
-  01 Apr 2004; Mike Frysinger <vapier@gentoo.org>
-  Version bump.
-
-*hppa-dev-sources-2.6.3_p0 (20 Feb 2004)
-
-  20 Feb 2004; Mike Frysinger <vapier@gentoo.org> 
-  Version bump.
-
-*hppa-dev-sources-2.6.2_p3-r1 (18 Feb 2004)
-
-  18 Feb 2004; <plasmaroo@gentoo.org> 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 <gmsoft@gentoo.org> 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 <vapier@gentoo.org> 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 <gmsoft@gentoo.org> 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 <gmsoft@gentoo.org> 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 <gmsoft@gentoo.org> 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 <gmsoft@gentoo.org> 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 (file)
index 134325a..0000000
+++ /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 (file)
index 6ced784..0000000
+++ /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 (file)
index 1e4ba6f..0000000
+++ /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 <chrisw@osdl.org>
-#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-# 
-# 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 (file)
index 8ea0f04..0000000
+++ /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 (file)
index f6eafac..0000000
+++ /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 (file)
index 496654d..0000000
+++ /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 <linux/smp_lock.h>
- #include <linux/device.h>
- #include <linux/idr.h>
-+#include <linux/wait.h>
- 
- #include <asm/uaccess.h>
- #include <asm/system.h>
-@@ -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 <ejbs@cs.cs.com.uy> */
-       /* Cyrus Durgin <cider@speakeasy.org> */
--      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 <linux/seq_file.h>
- #include <asm/bitops.h>
- 
--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 <linux/fs.h>
-@@ -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 (file)
index ec94a9f..0000000
+++ /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 <linux/smp_lock.h>
- #include <linux/device.h>
- #include <linux/idr.h>
-+#include <linux/wait.h>
- 
- #include <asm/uaccess.h>
- #include <asm/system.h>
-@@ -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 <ejbs@cs.cs.com.uy> */
-       /* Cyrus Durgin <cider@speakeasy.org> */
--      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 <linux/seq_file.h>
- #include <asm/bitops.h>
- 
--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 <linux/fs.h>
-@@ -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 (file)
index 99401cf..0000000
+++ /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 (file)
index 4c2b5c9..0000000
+++ /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 (file)
index 9ca2367..0000000
+++ /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; i<interp_elf_ex->e_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 (file)
index 7e748cd..0000000
+++ /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 (file)
index 538c50f..0000000
+++ /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 (file)
index eae74de..0000000
+++ /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 (file)
index 4571cc1..0000000
+++ /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 (file)
index 4571cc1..0000000
+++ /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 (file)
index 4571cc1..0000000
+++ /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 (file)
index 861afed..0000000
+++ /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 (file)
index 564afde..0000000
+++ /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 (file)
index 2312a2b..0000000
+++ /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 (file)
index bb80884..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-From: Roger Luethi <rl@hellgate.ch>
-
-If you win the race with a starting process, you can read its environment.
-
-Signed-off-by: Andrew Morton <akpm@osdl.org>
----
-
- 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 (file)
index 7a62fe0..0000000
+++ /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 (file)
index bda6d2a..0000000
+++ /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 (file)
index 447c8c1..0000000
+++ /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 (file)
index e5bee98..0000000
+++ /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 (file)
index 1f397bb..0000000
+++ /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 (file)
index 47106a6..0000000
+++ /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 (file)
index 899166b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
-<pkgmetadata>
-<herd>hppa-kernel</herd>
-<longdescription>
-2.6 kernels for hppa.
-</longdescription>
-</pkgmetadata>