Merge master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt
new file mode 100644
index 0000000..5f2b9c5
--- /dev/null
+++ b/Documentation/keys-request-key.txt
@@ -0,0 +1,161 @@
+			      ===================
+			      KEY REQUEST SERVICE
+			      ===================
+
+The key request service is part of the key retention service (refer to
+Documentation/keys.txt). This document explains more fully how that the
+requesting algorithm works.
+
+The process starts by either the kernel requesting a service by calling
+request_key():
+
+	struct key *request_key(const struct key_type *type,
+				const char *description,
+				const char *callout_string);
+
+Or by userspace invoking the request_key system call:
+
+	key_serial_t request_key(const char *type,
+				 const char *description,
+				 const char *callout_info,
+				 key_serial_t dest_keyring);
+
+The main difference between the two access points is that the in-kernel
+interface does not need to link the key to a keyring to prevent it from being
+immediately destroyed. The kernel interface returns a pointer directly to the
+key, and it's up to the caller to destroy the key.
+
+The userspace interface links the key to a keyring associated with the process
+to prevent the key from going away, and returns the serial number of the key to
+the caller.
+
+
+===========
+THE PROCESS
+===========
+
+A request proceeds in the following manner:
+
+ (1) Process A calls request_key() [the userspace syscall calls the kernel
+     interface].
+
+ (2) request_key() searches the process's subscribed keyrings to see if there's
+     a suitable key there. If there is, it returns the key. If there isn't, and
+     callout_info is not set, an error is returned. Otherwise the process
+     proceeds to the next step.
+
+ (3) request_key() sees that A doesn't have the desired key yet, so it creates
+     two things:
+
+     (a) An uninstantiated key U of requested type and description.
+
+     (b) An authorisation key V that refers to key U and notes that process A
+     	 is the context in which key U should be instantiated and secured, and
+     	 from which associated key requests may be satisfied.
+
+ (4) request_key() then forks and executes /sbin/request-key with a new session
+     keyring that contains a link to auth key V.
+
+ (5) /sbin/request-key execs an appropriate program to perform the actual
+     instantiation.
+
+ (6) The program may want to access another key from A's context (say a
+     Kerberos TGT key). It just requests the appropriate key, and the keyring
+     search notes that the session keyring has auth key V in its bottom level.
+
+     This will permit it to then search the keyrings of process A with the
+     UID, GID, groups and security info of process A as if it was process A,
+     and come up with key W.
+
+ (7) The program then does what it must to get the data with which to
+     instantiate key U, using key W as a reference (perhaps it contacts a
+     Kerberos server using the TGT) and then instantiates key U.
+
+ (8) Upon instantiating key U, auth key V is automatically revoked so that it
+     may not be used again.
+
+ (9) The program then exits 0 and request_key() deletes key V and returns key
+     U to the caller.
+
+This also extends further. If key W (step 5 above) didn't exist, key W would be
+created uninstantiated, another auth key (X) would be created [as per step 3]
+and another copy of /sbin/request-key spawned [as per step 4]; but the context
+specified by auth key X will still be process A, as it was in auth key V.
+
+This is because process A's keyrings can't simply be attached to
+/sbin/request-key at the appropriate places because (a) execve will discard two
+of them, and (b) it requires the same UID/GID/Groups all the way through.
+
+
+======================
+NEGATIVE INSTANTIATION
+======================
+
+Rather than instantiating a key, it is possible for the possessor of an
+authorisation key to negatively instantiate a key that's under construction.
+This is a short duration placeholder that causes any attempt at re-requesting
+the key whilst it exists to fail with error ENOKEY.
+
+This is provided to prevent excessive repeated spawning of /sbin/request-key
+processes for a key that will never be obtainable.
+
+Should the /sbin/request-key process exit anything other than 0 or die on a
+signal, the key under construction will be automatically negatively
+instantiated for a short amount of time.
+
+
+====================
+THE SEARCH ALGORITHM
+====================
+
+A search of any particular keyring proceeds in the following fashion:
+
+ (1) When the key management code searches for a key (keyring_search_aux) it
+     firstly calls key_permission(SEARCH) on the keyring it's starting with,
+     if this denies permission, it doesn't search further.
+
+ (2) It considers all the non-keyring keys within that keyring and, if any key
+     matches the criteria specified, calls key_permission(SEARCH) on it to see
+     if the key is allowed to be found. If it is, that key is returned; if
+     not, the search continues, and the error code is retained if of higher
+     priority than the one currently set.
+
+ (3) It then considers all the keyring-type keys in the keyring it's currently
+     searching. It calls key_permission(SEARCH) on each keyring, and if this
+     grants permission, it recurses, executing steps (2) and (3) on that
+     keyring.
+
+The process stops immediately a valid key is found with permission granted to
+use it. Any error from a previous match attempt is discarded and the key is
+returned.
+
+When search_process_keyrings() is invoked, it performs the following searches
+until one succeeds:
+
+ (1) If extant, the process's thread keyring is searched.
+
+ (2) If extant, the process's process keyring is searched.
+
+ (3) The process's session keyring is searched.
+
+ (4) If the process has a request_key() authorisation key in its session
+     keyring then:
+
+     (a) If extant, the calling process's thread keyring is searched.
+
+     (b) If extant, the calling process's process keyring is searched.
+
+     (c) The calling process's session keyring is searched.
+
+The moment one succeeds, all pending errors are discarded and the found key is
+returned.
+
+Only if all these fail does the whole thing fail with the highest priority
+error. Note that several errors may have come from LSM.
+
+The error priority is:
+
+	EKEYREVOKED > EKEYEXPIRED > ENOKEY
+
+EACCES/EPERM are only returned on a direct search of a specific keyring where
+the basal keyring does not grant Search permission.
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index b22e7c8..4afe03a 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -361,6 +361,8 @@
      /sbin/request-key will be invoked in an attempt to obtain a key. The
      callout_info string will be passed as an argument to the program.
 
+     See also Documentation/keys-request-key.txt.
+
 
 The keyctl syscall functions are:
 
@@ -533,8 +535,8 @@
 
  (*) Read the payload data from a key:
 
-	key_serial_t keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
-			    size_t buflen);
+	long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
+		    size_t buflen);
 
      This function attempts to read the payload data from the specified key
      into the buffer. The process must have read permission on the key to
@@ -555,9 +557,9 @@
 
  (*) Instantiate a partially constructed key.
 
-	key_serial_t keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
-			    const void *payload, size_t plen,
-			    key_serial_t keyring);
+	long keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
+		    const void *payload, size_t plen,
+		    key_serial_t keyring);
 
      If the kernel calls back to userspace to complete the instantiation of a
      key, userspace should use this call to supply data for the key before the
@@ -576,8 +578,8 @@
 
  (*) Negatively instantiate a partially constructed key.
 
-	key_serial_t keyctl(KEYCTL_NEGATE, key_serial_t key,
-			    unsigned timeout, key_serial_t keyring);
+	long keyctl(KEYCTL_NEGATE, key_serial_t key,
+		    unsigned timeout, key_serial_t keyring);
 
      If the kernel calls back to userspace to complete the instantiation of a
      key, userspace should use this call mark the key as negative before the
@@ -688,6 +690,8 @@
     If successful, the key will have been attached to the default keyring for
     implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
 
+    See also Documentation/keys-request-key.txt.
+
 
 (*) When it is no longer required, the key should be released using:
 
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 6537445..f7c51b8 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -21,6 +21,10 @@
 	bool
 	default y
 
+config GENERIC_IOMAP
+	bool
+	default y
+
 source "init/Kconfig"
 
 menu "General machine setup"
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index a698562..8a3aef1e 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -5,6 +5,7 @@
 CONFIG_UID16=y
 CONFIG_HIGHMEM=y
 CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index f685035dbd..11a8484 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -33,7 +33,7 @@
 	/* This is trivial with the new code... */
 	.globl		do_fpdis
 do_fpdis:
-	sethi		%hi(TSTATE_PEF), %g4					! IEU0
+	sethi		%hi(TSTATE_PEF), %g4
 	rdpr		%tstate, %g5
 	andcc		%g5, %g4, %g0
 	be,pt		%xcc, 1f
@@ -50,18 +50,18 @@
 	add		%g0, %g0, %g0
 	ba,a,pt		%xcc, rtrap_clr_l6
 
-1:	ldub		[%g6 + TI_FPSAVED], %g5					! Load	Group
-	wr		%g0, FPRS_FEF, %fprs					! LSU	Group+4bubbles
-	andcc		%g5, FPRS_FEF, %g0					! IEU1	Group
-	be,a,pt		%icc, 1f						! CTI
-	 clr		%g7							! IEU0
-	ldx		[%g6 + TI_GSR], %g7					! Load	Group
-1:	andcc		%g5, FPRS_DL, %g0					! IEU1
-	bne,pn		%icc, 2f						! CTI
-	 fzero		%f0							! FPA
-	andcc		%g5, FPRS_DU, %g0					! IEU1  Group
-	bne,pn		%icc, 1f						! CTI
-	 fzero		%f2							! FPA
+1:	ldub		[%g6 + TI_FPSAVED], %g5
+	wr		%g0, FPRS_FEF, %fprs
+	andcc		%g5, FPRS_FEF, %g0
+	be,a,pt		%icc, 1f
+	 clr		%g7
+	ldx		[%g6 + TI_GSR], %g7
+1:	andcc		%g5, FPRS_DL, %g0
+	bne,pn		%icc, 2f
+	 fzero		%f0
+	andcc		%g5, FPRS_DU, %g0
+	bne,pn		%icc, 1f
+	 fzero		%f2
 	faddd		%f0, %f2, %f4
 	fmuld		%f0, %f2, %f6
 	faddd		%f0, %f2, %f8
@@ -104,8 +104,10 @@
 	add		%g6, TI_FPREGS + 0xc0, %g2
 	faddd		%f0, %f2, %f8
 	fmuld		%f0, %f2, %f10
-	ldda		[%g1] ASI_BLK_S, %f32	! grrr, where is ASI_BLK_NUCLEUS 8-(
+	membar		#Sync
+	ldda		[%g1] ASI_BLK_S, %f32
 	ldda		[%g2] ASI_BLK_S, %f48
+	membar		#Sync
 	faddd		%f0, %f2, %f12
 	fmuld		%f0, %f2, %f14
 	faddd		%f0, %f2, %f16
@@ -116,7 +118,6 @@
 	fmuld		%f0, %f2, %f26
 	faddd		%f0, %f2, %f28
 	fmuld		%f0, %f2, %f30
-	membar		#Sync
 	b,pt		%xcc, fpdis_exit
 	 nop
 2:	andcc		%g5, FPRS_DU, %g0
@@ -133,8 +134,10 @@
 	add		%g6, TI_FPREGS + 0x40, %g2
 	faddd		%f32, %f34, %f36
 	fmuld		%f32, %f34, %f38
-	ldda		[%g1] ASI_BLK_S, %f0	! grrr, where is ASI_BLK_NUCLEUS 8-(
+	membar		#Sync
+	ldda		[%g1] ASI_BLK_S, %f0
 	ldda		[%g2] ASI_BLK_S, %f16
+	membar		#Sync
 	faddd		%f32, %f34, %f40
 	fmuld		%f32, %f34, %f42
 	faddd		%f32, %f34, %f44
@@ -147,7 +150,6 @@
 	fmuld		%f32, %f34, %f58
 	faddd		%f32, %f34, %f60
 	fmuld		%f32, %f34, %f62
-	membar		#Sync
 	ba,pt		%xcc, fpdis_exit
 	 nop
 3:	mov		SECONDARY_CONTEXT, %g3
@@ -158,7 +160,8 @@
 	stxa		%g2, [%g3] ASI_DMMU
 	membar		#Sync
 	mov		0x40, %g2
-	ldda		[%g1] ASI_BLK_S, %f0		! grrr, where is ASI_BLK_NUCLEUS 8-(
+	membar		#Sync
+	ldda		[%g1] ASI_BLK_S, %f0
 	ldda		[%g1 + %g2] ASI_BLK_S, %f16
 	add		%g1, 0x80, %g1
 	ldda		[%g1] ASI_BLK_S, %f32
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 946cee0..9e8362e 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -17,6 +17,7 @@
 
 #include <asm/system.h>
 #include <asm/ebus.h>
+#include <asm/isa.h>
 #include <asm/auxio.h>
 
 #include <linux/unistd.h>
@@ -100,46 +101,83 @@
 	return 0;
 }
 
-static int __init has_button_interrupt(struct linux_ebus_device *edev)
+static int __init has_button_interrupt(unsigned int irq, int prom_node)
 {
-	if (edev->irqs[0] == PCI_IRQ_NONE)
+	if (irq == PCI_IRQ_NONE)
 		return 0;
-	if (!prom_node_has_property(edev->prom_node, "button"))
+	if (!prom_node_has_property(prom_node, "button"))
 		return 0;
 
 	return 1;
 }
 
-void __init power_init(void)
+static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
 {
 	struct linux_ebus *ebus;
 	struct linux_ebus_device *edev;
+
+	for_each_ebus(ebus) {
+		for_each_ebusdev(edev, ebus) {
+			if (!strcmp(edev->prom_name, "power")) {
+				*resp = &edev->resource[0];
+				*irq_p = edev->irqs[0];
+				*prom_node_p = edev->prom_node;
+				return 0;
+			}
+		}
+	}
+	return -ENODEV;
+}
+
+static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
+{
+	struct sparc_isa_bridge *isa_bus;
+	struct sparc_isa_device *isa_dev;
+
+	for_each_isa(isa_bus) {
+		for_each_isadev(isa_dev, isa_bus) {
+			if (!strcmp(isa_dev->prom_name, "power")) {
+				*resp = &isa_dev->resource;
+				*irq_p = isa_dev->irq;
+				*prom_node_p = isa_dev->prom_node;
+				return 0;
+			}
+		}
+	}
+	return -ENODEV;
+}
+
+void __init power_init(void)
+{
+	struct resource *res = NULL;
+	unsigned int irq;
+	int prom_node;
 	static int invoked;
 
 	if (invoked)
 		return;
 	invoked = 1;
 
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "power"))
-				goto found;
-		}
-	}
+	if (!power_probe_ebus(&res, &irq, &prom_node))
+		goto found;
+
+	if (!power_probe_isa(&res, &irq, &prom_node))
+		goto found;
+
 	return;
 
 found:
-	power_reg = ioremap(edev->resource[0].start, 0x4);
+	power_reg = ioremap(res->start, 0x4);
 	printk("power: Control reg at %p ... ", power_reg);
 	poweroff_method = machine_halt;  /* able to use the standard halt */
-	if (has_button_interrupt(edev)) {
+	if (has_button_interrupt(irq, prom_node)) {
 		if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
 			printk("Failed to start power daemon.\n");
 			return;
 		}
 		printk("powerd running.\n");
 
-		if (request_irq(edev->irqs[0],
+		if (request_irq(irq,
 				power_handler, SA_SHIRQ, "power", NULL) < 0)
 			printk("power: Error, cannot register IRQ handler.\n");
 	} else {
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index ecfb42a..090dcca 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -312,32 +312,33 @@
 		wr			%g1, FPRS_FEF, %fprs
 		ldx			[%o1 + %o5], %g1
 		add			%g6, TI_XFSR, %o1
-		membar			#StoreLoad | #LoadLoad
 		sll			%o0, 8, %o2
 		add			%g6, TI_FPREGS, %o3
 		brz,pn			%l6, 1f
 		 add			%g6, TI_FPREGS+0x40, %o4
 
+		membar			#Sync
 		ldda			[%o3 + %o2] ASI_BLK_P, %f0
 		ldda			[%o4 + %o2] ASI_BLK_P, %f16
+		membar			#Sync
 1:		andcc			%l2, FPRS_DU, %g0
 		be,pn			%icc, 1f
 		 wr			%g1, 0, %gsr
 		add			%o2, 0x80, %o2
+		membar			#Sync
 		ldda			[%o3 + %o2] ASI_BLK_P, %f32
 		ldda			[%o4 + %o2] ASI_BLK_P, %f48
-
 1:		membar			#Sync
 		ldx			[%o1 + %o5], %fsr
 2:		stb			%l5, [%g6 + TI_FPDEPTH]
 		ba,pt			%xcc, rt_continue
 		 nop
 5:		wr			%g0, FPRS_FEF, %fprs
-		membar			#StoreLoad | #LoadLoad
 		sll			%o0, 8, %o2
 
 		add			%g6, TI_FPREGS+0x80, %o3
 		add			%g6, TI_FPREGS+0xc0, %o4
+		membar			#Sync
 		ldda			[%o3 + %o2] ASI_BLK_P, %f32
 		ldda			[%o4 + %o2] ASI_BLK_P, %f48
 		membar			#Sync
diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S
index 4e18989..a0ded5c 100644
--- a/arch/sparc64/lib/VISsave.S
+++ b/arch/sparc64/lib/VISsave.S
@@ -59,15 +59,17 @@
 	be,pn		%icc, 9b
 	 add		%g6, TI_FPREGS, %g2
 	andcc		%o5, FPRS_DL, %g0
-	membar		#StoreStore | #LoadStore
 
 	be,pn		%icc, 4f
 	 add		%g6, TI_FPREGS+0x40, %g3
+	membar		#Sync
 	stda		%f0, [%g2 + %g1] ASI_BLK_P
 	stda		%f16, [%g3 + %g1] ASI_BLK_P
+	membar		#Sync
 	andcc		%o5, FPRS_DU, %g0
 	be,pn		%icc, 5f
 4:	 add		%g1, 128, %g1
+	membar		#Sync
 	stda		%f32, [%g2 + %g1] ASI_BLK_P
 
 	stda		%f48, [%g3 + %g1] ASI_BLK_P
@@ -87,7 +89,7 @@
 	sll		%g1, 5, %g1
 	add		%g6, TI_FPREGS+0xc0, %g3
 	wr		%g0, FPRS_FEF, %fprs
-	membar		#StoreStore | #LoadStore
+	membar		#Sync
 	stda		%f32, [%g2 + %g1] ASI_BLK_P
 	stda		%f48, [%g3 + %g1] ASI_BLK_P
 	membar		#Sync
@@ -128,8 +130,8 @@
 	be,pn		%icc, 4f
 	 add		%g6, TI_FPREGS, %g2
 
-	membar		#StoreStore | #LoadStore
 	add		%g6, TI_FPREGS+0x40, %g3
+	membar		#Sync
 	stda		%f0, [%g2 + %g1] ASI_BLK_P
 	stda		%f16, [%g3 + %g1] ASI_BLK_P
 	membar		#Sync
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 5a80adb..0b8e493 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -50,8 +50,8 @@
 #include <asm/io.h>		/* For inb/outb/... */
 
 /* Module and version information */
-#define WATCHDOG_VERSION "1.01"
-#define WATCHDOG_DATE "02 Sep 2005"
+#define WATCHDOG_VERSION "1.02"
+#define WATCHDOG_DATE "03 Sep 2005"
 #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
 #define WATCHDOG_NAME "pcwd_pci"
 #define PFX WATCHDOG_NAME ": "
@@ -70,19 +70,30 @@
  * These are the defines that describe the control status bits for the
  * PCI-PC Watchdog card.
  */
-#define WD_PCI_WTRP             0x01	/* Watchdog Trip status */
-#define WD_PCI_HRBT             0x02	/* Watchdog Heartbeat */
-#define WD_PCI_TTRP             0x04	/* Temperature Trip status */
+/* Port 1 : Control Status #1 */
+#define WD_PCI_WTRP		0x01	/* Watchdog Trip status */
+#define WD_PCI_HRBT		0x02	/* Watchdog Heartbeat */
+#define WD_PCI_TTRP		0x04	/* Temperature Trip status */
+#define WD_PCI_RL2A		0x08	/* Relay 2 Active */
+#define WD_PCI_RL1A		0x10	/* Relay 1 Active */
+#define WD_PCI_R2DS		0x40	/* Relay 2 Disable Temperature-trip/reset */
+#define WD_PCI_RLY2		0x80	/* Activate Relay 2 on the board */
+/* Port 2 : Control Status #2 */
+#define WD_PCI_WDIS		0x10	/* Watchdog Disable */
+#define WD_PCI_ENTP		0x20	/* Enable Temperature Trip Reset */
+#define WD_PCI_WRSP		0x40	/* Watchdog wrote response */
+#define WD_PCI_PCMD		0x80	/* PC has sent command */
 
 /* according to documentation max. time to process a command for the pci
  * watchdog card is 100 ms, so we give it 150 ms to do it's job */
 #define PCI_COMMAND_TIMEOUT	150
 
 /* Watchdog's internal commands */
-#define CMD_GET_STATUS			0x04
-#define CMD_GET_FIRMWARE_VERSION	0x08
-#define CMD_READ_WATCHDOG_TIMEOUT	0x18
-#define CMD_WRITE_WATCHDOG_TIMEOUT	0x19
+#define CMD_GET_STATUS				0x04
+#define CMD_GET_FIRMWARE_VERSION		0x08
+#define CMD_READ_WATCHDOG_TIMEOUT		0x18
+#define CMD_WRITE_WATCHDOG_TIMEOUT		0x19
+#define CMD_GET_CLEAR_RESET_COUNT		0x84
 
 /* We can only use 1 card due to the /dev/watchdog restriction */
 static int cards_found;
@@ -91,15 +102,22 @@
 static int temp_panic;
 static unsigned long is_active;
 static char expect_release;
-static struct {
-	int supports_temp;	/* Wether or not the card has a temperature device */
-	int boot_status;	/* The card's boot status */
-	unsigned long io_addr;	/* The cards I/O address */
-	spinlock_t io_lock;
-	struct pci_dev *pdev;
+static struct {				/* this is private data for each PCI-PC watchdog card */
+	int supports_temp;		/* Wether or not the card has a temperature device */
+	int boot_status;		/* The card's boot status */
+	unsigned long io_addr;		/* The cards I/O address */
+	spinlock_t io_lock;		/* the lock for io operations */
+	struct pci_dev *pdev;		/* the PCI-device */
 } pcipcwd_private;
 
 /* module parameters */
+#define QUIET	0	/* Default */
+#define VERBOSE	1	/* Verbose */
+#define DEBUG	2	/* print fancy stuff too */
+static int debug = QUIET;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
+
 #define WATCHDOG_HEARTBEAT 2	/* 2 sec default heartbeat */
 static int heartbeat = WATCHDOG_HEARTBEAT;
 module_param(heartbeat, int, 0);
@@ -117,6 +135,10 @@
 {
 	int got_response, count;
 
+	if (debug >= DEBUG)
+		printk(KERN_DEBUG PFX "sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x\n",
+		cmd, *msb, *lsb);
+
 	spin_lock(&pcipcwd_private.io_lock);
 	/* If a command requires data it should be written first.
 	 * Data for commands with 8 bits of data should be written to port 4.
@@ -131,10 +153,19 @@
 	/* wait till the pci card processed the command, signaled by
 	 * the WRSP bit in port 2 and give it a max. timeout of
 	 * PCI_COMMAND_TIMEOUT to process */
-	got_response = inb_p(pcipcwd_private.io_addr + 2) & 0x40;
+	got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
 	for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response); count++) {
 		mdelay(1);
-		got_response = inb_p(pcipcwd_private.io_addr + 2) & 0x40;
+		got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP;
+	}
+
+	if (debug >= DEBUG) {
+		if (got_response) {
+			printk(KERN_DEBUG PFX "time to process command was: %d ms\n",
+				count);
+		} else {
+			printk(KERN_DEBUG PFX "card did not respond on command!\n");
+		}
 	}
 
 	if (got_response) {
@@ -144,12 +175,66 @@
 
 		/* clear WRSP bit */
 		inb_p(pcipcwd_private.io_addr + 6);
+
+		if (debug >= DEBUG)
+			printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: msb=0x%02x lsb=0x%02x\n",
+				cmd, *msb, *lsb);
 	}
+
 	spin_unlock(&pcipcwd_private.io_lock);
 
 	return got_response;
 }
 
+static inline void pcipcwd_check_temperature_support(void)
+{
+	if (inb_p(pcipcwd_private.io_addr) != 0xF0)
+		pcipcwd_private.supports_temp = 1;
+}
+
+static int pcipcwd_get_option_switches(void)
+{
+	int option_switches;
+
+	option_switches = inb_p(pcipcwd_private.io_addr + 3);
+	return option_switches;
+}
+
+static void pcipcwd_show_card_info(void)
+{
+	int got_fw_rev, fw_rev_major, fw_rev_minor;
+	char fw_ver_str[20];		/* The cards firmware version */
+	int option_switches;
+
+	got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
+	if (got_fw_rev) {
+		sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
+	} else {
+		sprintf(fw_ver_str, "<card no answer>");
+	}
+
+	/* Get switch settings */
+	option_switches = pcipcwd_get_option_switches();
+
+	printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n",
+		(int) pcipcwd_private.io_addr, fw_ver_str,
+		(pcipcwd_private.supports_temp ? "with" : "without"));
+
+	printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
+		option_switches,
+		((option_switches & 0x10) ? "ON" : "OFF"),
+		((option_switches & 0x08) ? "ON" : "OFF"));
+
+	if (pcipcwd_private.boot_status & WDIOF_CARDRESET)
+		printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n");
+
+	if (pcipcwd_private.boot_status & WDIOF_OVERHEAT)
+		printk(KERN_INFO PFX "Card sensed a CPU Overheat\n");
+
+	if (pcipcwd_private.boot_status == 0)
+		printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
+}
+
 static int pcipcwd_start(void)
 {
 	int stat_reg;
@@ -161,11 +246,14 @@
 	stat_reg = inb_p(pcipcwd_private.io_addr + 2);
 	spin_unlock(&pcipcwd_private.io_lock);
 
-	if (stat_reg & 0x10) {
+	if (stat_reg & WD_PCI_WDIS) {
 		printk(KERN_ERR PFX "Card timer not enabled\n");
 		return -1;
 	}
 
+	if (debug >= VERBOSE)
+		printk(KERN_DEBUG PFX "Watchdog started\n");
+
 	return 0;
 }
 
@@ -183,18 +271,25 @@
 	stat_reg = inb_p(pcipcwd_private.io_addr + 2);
 	spin_unlock(&pcipcwd_private.io_lock);
 
-	if (!(stat_reg & 0x10)) {
+	if (!(stat_reg & WD_PCI_WDIS)) {
 		printk(KERN_ERR PFX "Card did not acknowledge disable attempt\n");
 		return -1;
 	}
 
+	if (debug >= VERBOSE)
+		printk(KERN_DEBUG PFX "Watchdog stopped\n");
+
 	return 0;
 }
 
 static int pcipcwd_keepalive(void)
 {
 	/* Re-trigger watchdog by writing to port 0 */
-	outb_p(0x42, pcipcwd_private.io_addr);
+	outb_p(0x42, pcipcwd_private.io_addr);	/* send out any data */
+
+	if (debug >= DEBUG)
+		printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
+
 	return 0;
 }
 
@@ -210,29 +305,64 @@
 	send_command(CMD_WRITE_WATCHDOG_TIMEOUT, &t_msb, &t_lsb);
 
 	heartbeat = t;
+	if (debug >= VERBOSE)
+		printk(KERN_DEBUG PFX "New heartbeat: %d\n",
+		       heartbeat);
+
 	return 0;
 }
 
 static int pcipcwd_get_status(int *status)
 {
-	int new_status;
+	int control_status;
 
 	*status=0;
-	new_status = inb_p(pcipcwd_private.io_addr + 1);
-	if (new_status & WD_PCI_WTRP)
+	control_status = inb_p(pcipcwd_private.io_addr + 1);
+	if (control_status & WD_PCI_WTRP)
 		*status |= WDIOF_CARDRESET;
-	if (new_status & WD_PCI_TTRP) {
+	if (control_status & WD_PCI_TTRP) {
 		*status |= WDIOF_OVERHEAT;
 		if (temp_panic)
 			panic(PFX "Temperature overheat trip!\n");
 	}
 
+	if (debug >= DEBUG)
+		printk(KERN_DEBUG PFX "Control Status #1: 0x%02x\n",
+		       control_status);
+
 	return 0;
 }
 
 static int pcipcwd_clear_status(void)
 {
-	outb_p(0x01, pcipcwd_private.io_addr + 1);
+	int control_status;
+	int msb;
+	int reset_counter;
+
+	if (debug >= VERBOSE)
+		printk(KERN_INFO PFX "clearing watchdog trip status & LED\n");
+
+	control_status = inb_p(pcipcwd_private.io_addr + 1);
+
+	if (debug >= DEBUG) {
+		printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status);
+		printk(KERN_DEBUG PFX "sending: 0x%02x\n",
+		       (control_status & WD_PCI_R2DS) | WD_PCI_WTRP);
+	}
+
+	/* clear trip status & LED and keep mode of relay 2 */
+	outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1);
+
+	/* clear reset counter */
+	msb=0;
+	reset_counter=0xff;
+	send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter);
+
+	if (debug >= DEBUG) {
+		printk(KERN_DEBUG PFX "reset count was: 0x%02x\n",
+		       reset_counter);
+	}
+
 	return 0;
 }
 
@@ -242,11 +372,18 @@
 	if (!pcipcwd_private.supports_temp)
 		return -ENODEV;
 
+	*temperature = inb_p(pcipcwd_private.io_addr);
+
 	/*
 	 * Convert celsius to fahrenheit, since this was
 	 * the decided 'standard' for this return value.
 	 */
-	*temperature = ((inb_p(pcipcwd_private.io_addr)) * 9 / 5) + 32;
+	*temperature = (*temperature * 9 / 5) + 32;
+
+	if (debug >= DEBUG) {
+		printk(KERN_DEBUG PFX "temperature is: %d F\n",
+		       *temperature);
+	}
 
 	return 0;
 }
@@ -256,7 +393,7 @@
  */
 
 static ssize_t pcipcwd_write(struct file *file, const char __user *data,
-			      size_t len, loff_t *ppos)
+			     size_t len, loff_t *ppos)
 {
 	/* See if we got the magic character 'V' and reload the timer */
 	if (len) {
@@ -381,8 +518,11 @@
 static int pcipcwd_open(struct inode *inode, struct file *file)
 {
 	/* /dev/watchdog can only be opened once */
-	if (test_and_set_bit(0, &is_active))
+	if (test_and_set_bit(0, &is_active)) {
+		if (debug >= VERBOSE)
+			printk(KERN_ERR PFX "Attempt to open already opened device.\n");
 		return -EBUSY;
+	}
 
 	/* Activate */
 	pcipcwd_start();
@@ -492,19 +632,10 @@
  *	Init & exit routines
  */
 
-static inline void check_temperature_support(void)
-{
-	if (inb_p(pcipcwd_private.io_addr) != 0xF0)
-		pcipcwd_private.supports_temp = 1;
-}
-
 static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
 		const struct pci_device_id *ent)
 {
 	int ret = -EIO;
-	int got_fw_rev, fw_rev_major, fw_rev_minor;
-	char fw_ver_str[20];
-	char option_switches;
 
 	cards_found++;
 	if (cards_found == 1)
@@ -546,36 +677,10 @@
 	pcipcwd_stop();
 
 	/* Check whether or not the card supports the temperature device */
-	check_temperature_support();
+	pcipcwd_check_temperature_support();
 
-	/* Get the Firmware Version */
-	got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
-	if (got_fw_rev) {
-		sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
-	} else {
-		sprintf(fw_ver_str, "<card no answer>");
-	}
-
-	/* Get switch settings */
-	option_switches = inb_p(pcipcwd_private.io_addr + 3);
-
-	printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n",
-		(int) pcipcwd_private.io_addr, fw_ver_str,
-		(pcipcwd_private.supports_temp ? "with" : "without"));
-
-	printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n",
-		option_switches,
-		((option_switches & 0x10) ? "ON" : "OFF"),
-		((option_switches & 0x08) ? "ON" : "OFF"));
-
-	if (pcipcwd_private.boot_status & WDIOF_CARDRESET)
-		printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n");
-
-	if (pcipcwd_private.boot_status & WDIOF_OVERHEAT)
-		printk(KERN_INFO PFX "Card sensed a CPU Overheat\n");
-
-	if (pcipcwd_private.boot_status == 0)
-		printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
+	/* Show info about the card itself */
+	pcipcwd_show_card_info();
 
 	/* Check that the heartbeat value is within it's range ; if not reset to the default */
 	if (pcipcwd_set_heartbeat(heartbeat)) {
@@ -656,7 +761,7 @@
 
 static int __init pcipcwd_init_module(void)
 {
-	spin_lock_init (&pcipcwd_private.io_lock);
+	spin_lock_init(&pcipcwd_private.io_lock);
 
 	return pci_register_driver(&pcipcwd_driver);
 }
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index da0b404..539b5cd 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -873,6 +873,7 @@
  * Some fixup code to make everybody happy (TM).
  */
 
+#ifdef CONFIG_CARDBUS
 /**
  * set/clear various test bits:
  * Defaults to clear the bit.
@@ -927,7 +928,6 @@
 	config_writeb(socket, ENE_TEST_C9, test_c9);
 }
 
-
 static int ene_override(struct yenta_socket *socket)
 {
 	/* install tune_bridge() function */
@@ -935,6 +935,9 @@
 
 	return ti1250_override(socket);
 }
+#else
+#  define ene_override ti1250_override
+#endif
 
 #endif /* _LINUX_TI113X_H */
 
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 7808a01..b76a5a9 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -288,6 +288,9 @@
 	all->par.physbase = sdev->reg_addrs[2].phys_addr;
 
 	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	all->info.var.red.length = 8;
+	all->info.var.green.length = 8;
+	all->info.var.blue.length = 8;
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
 				       all->info.var.xres);
@@ -323,6 +326,7 @@
 		kfree(all);
 		return;
 	}
+	fb_set_cmap(&all->info.cmap, &all->info);
 
 	list_add(&all->list, &p9100_list);
 
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index f1fd849..aca9b34 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -76,6 +76,13 @@
 					/* set interface ESI */
 #define ATM_SETESIF	_IOW('a',ATMIOC_ITF+13,struct atmif_sioc)
 					/* force interface ESI */
+#define ATM_ADDLECSADDR	_IOW('a', ATMIOC_ITF+14, struct atmif_sioc)
+					/* register a LECS address */
+#define ATM_DELLECSADDR	_IOW('a', ATMIOC_ITF+15, struct atmif_sioc)
+					/* unregister a LECS address */
+#define ATM_GETLECSADDR	_IOW('a', ATMIOC_ITF+16, struct atmif_sioc)
+					/* retrieve LECS address(es) */
+
 #define ATM_GETSTAT	_IOW('a',ATMIOC_SARCOM+0,struct atmif_sioc)
 					/* get AAL layer statistics */
 #define ATM_GETSTATZ	_IOW('a',ATMIOC_SARCOM+1,struct atmif_sioc)
@@ -328,6 +335,8 @@
 	struct list_head entry;		/* next address */
 };
 
+enum atm_addr_type_t { ATM_ADDR_LOCAL, ATM_ADDR_LECS };
+
 struct atm_dev {
 	const struct atmdev_ops *ops;	/* device operations; NULL if unused */
 	const struct atmphy_ops *phy;	/* PHY operations, may be undefined */
@@ -338,6 +347,7 @@
 	void		*phy_data;	/* private PHY date */
 	unsigned long	flags;		/* device flags (ATM_DF_*) */
 	struct list_head local;		/* local ATM addresses */
+	struct list_head lecs;		/* LECS ATM addresses learned via ILMI */
 	unsigned char	esi[ESI_LEN];	/* ESI ("MAC" addr) */
 	struct atm_cirange ci_range;	/* VPI/VCI range */
 	struct k_atm_dev_stats stats;	/* statistics */
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
index 918c34a..7a2e332 100644
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -38,97 +38,16 @@
 	struct key	*keys[0];
 };
 
-
 /*
  * check to see whether permission is granted to use a key in the desired way
  */
+extern int key_task_permission(const key_ref_t key_ref,
+			       struct task_struct *context,
+			       key_perm_t perm);
+
 static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
 {
-	struct key *key = key_ref_to_ptr(key_ref);
-	key_perm_t kperm;
-
-	if (is_key_possessed(key_ref))
-		kperm = key->perm >> 24;
-	else if (key->uid == current->fsuid)
-		kperm = key->perm >> 16;
-	else if (key->gid != -1 &&
-		 key->perm & KEY_GRP_ALL &&
-		 in_group_p(key->gid)
-		 )
-		kperm = key->perm >> 8;
-	else
-		kperm = key->perm;
-
-	kperm = kperm & perm & KEY_ALL;
-
-	return kperm == perm;
-}
-
-/*
- * check to see whether permission is granted to use a key in at least one of
- * the desired ways
- */
-static inline int key_any_permission(const key_ref_t key_ref, key_perm_t perm)
-{
-	struct key *key = key_ref_to_ptr(key_ref);
-	key_perm_t kperm;
-
-	if (is_key_possessed(key_ref))
-		kperm = key->perm >> 24;
-	else if (key->uid == current->fsuid)
-		kperm = key->perm >> 16;
-	else if (key->gid != -1 &&
-		 key->perm & KEY_GRP_ALL &&
-		 in_group_p(key->gid)
-		 )
-		kperm = key->perm >> 8;
-	else
-		kperm = key->perm;
-
-	kperm = kperm & perm & KEY_ALL;
-
-	return kperm != 0;
-}
-
-static inline int key_task_groups_search(struct task_struct *tsk, gid_t gid)
-{
-	int ret;
-
-	task_lock(tsk);
-	ret = groups_search(tsk->group_info, gid);
-	task_unlock(tsk);
-	return ret;
-}
-
-static inline int key_task_permission(const key_ref_t key_ref,
-				      struct task_struct *context,
-				      key_perm_t perm)
-{
-	struct key *key = key_ref_to_ptr(key_ref);
-	key_perm_t kperm;
-
-	if (is_key_possessed(key_ref)) {
-		kperm = key->perm >> 24;
-	}
-	else if (key->uid == context->fsuid) {
-		kperm = key->perm >> 16;
-	}
-	else if (key->gid != -1 &&
-		 key->perm & KEY_GRP_ALL && (
-			 key->gid == context->fsgid ||
-			 key_task_groups_search(context, key->gid)
-			 )
-		 ) {
-		kperm = key->perm >> 8;
-	}
-	else {
-		kperm = key->perm;
-	}
-
-	kperm = kperm & perm & KEY_ALL;
-
-	return kperm == perm;
-
+	return key_task_permission(key_ref, current, perm);
 }
 
 extern key_ref_t lookup_user_key(struct task_struct *context,
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index f6328ae..1c5f19f 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -103,16 +103,20 @@
 #define SCTP_SOCKOPT_BINDX_REM	SCTP_SOCKOPT_BINDX_REM
 	SCTP_SOCKOPT_PEELOFF, 	/* peel off association. */
 #define SCTP_SOCKOPT_PEELOFF	SCTP_SOCKOPT_PEELOFF
-	SCTP_GET_PEER_ADDRS_NUM, 	/* Get number of peer addresss. */
-#define SCTP_GET_PEER_ADDRS_NUM	SCTP_GET_PEER_ADDRS_NUM
-	SCTP_GET_PEER_ADDRS, 	/* Get all peer addresss. */
-#define SCTP_GET_PEER_ADDRS	SCTP_GET_PEER_ADDRS
-	SCTP_GET_LOCAL_ADDRS_NUM, 	/* Get number of local addresss. */
-#define SCTP_GET_LOCAL_ADDRS_NUM	SCTP_GET_LOCAL_ADDRS_NUM
-	SCTP_GET_LOCAL_ADDRS, 	/* Get all local addresss. */
-#define SCTP_GET_LOCAL_ADDRS	SCTP_GET_LOCAL_ADDRS
+	SCTP_GET_PEER_ADDRS_NUM_OLD, 	/* Get number of peer addresss. */
+#define SCTP_GET_PEER_ADDRS_NUM_OLD	SCTP_GET_PEER_ADDRS_NUM_OLD
+	SCTP_GET_PEER_ADDRS_OLD, 	/* Get all peer addresss. */
+#define SCTP_GET_PEER_ADDRS_OLD	SCTP_GET_PEER_ADDRS_OLD
+	SCTP_GET_LOCAL_ADDRS_NUM_OLD, 	/* Get number of local addresss. */
+#define SCTP_GET_LOCAL_ADDRS_NUM_OLD	SCTP_GET_LOCAL_ADDRS_NUM_OLD
+	SCTP_GET_LOCAL_ADDRS_OLD, 	/* Get all local addresss. */
+#define SCTP_GET_LOCAL_ADDRS_OLD	SCTP_GET_LOCAL_ADDRS_OLD
 	SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
 #define SCTP_SOCKOPT_CONNECTX	SCTP_SOCKOPT_CONNECTX
+	SCTP_GET_PEER_ADDRS, 	/* Get all peer addresss. */
+#define SCTP_GET_PEER_ADDRS	SCTP_GET_PEER_ADDRS
+	SCTP_GET_LOCAL_ADDRS, 	/* Get all local addresss. */
+#define SCTP_GET_LOCAL_ADDRS	SCTP_GET_LOCAL_ADDRS
 };
 
 /*
@@ -239,7 +243,7 @@
 	int spc_state;
 	int spc_error;
 	sctp_assoc_t spc_assoc_id;
-};
+} __attribute__((packed, aligned(4)));
 
 /*
  *    spc_state:  32 bits (signed integer)
@@ -464,7 +468,7 @@
 struct sctp_setpeerprim {
 	sctp_assoc_t            sspp_assoc_id;
 	struct sockaddr_storage sspp_addr;
-};
+} __attribute__((packed, aligned(4)));
 
 /*
  * 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
@@ -477,7 +481,7 @@
 struct sctp_prim {
 	sctp_assoc_t            ssp_assoc_id;
 	struct sockaddr_storage ssp_addr;
-};
+} __attribute__((packed, aligned(4)));
 
 /*
  * 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER)
@@ -504,7 +508,7 @@
 	struct sockaddr_storage	spp_address;
 	__u32			spp_hbinterval;
 	__u16			spp_pathmaxrxt;
-};
+} __attribute__((packed, aligned(4)));
 
 /*
  * 7.2.2 Peer Address Information
@@ -523,7 +527,7 @@
 	__u32			spinfo_srtt;
 	__u32			spinfo_rto;
 	__u32			spinfo_mtu;
-};
+} __attribute__((packed, aligned(4)));
 
 /* Peer addresses's state. */
 enum sctp_spinfo_state {
@@ -559,11 +563,16 @@
  * SCTP_GET_LOCAL_ADDRS socket options used internally to implement
  * sctp_getpaddrs() and sctp_getladdrs() API. 
  */
-struct sctp_getaddrs {
+struct sctp_getaddrs_old {
 	sctp_assoc_t            assoc_id;
 	int			addr_num;
 	struct sockaddr		__user *addrs;
 };
+struct sctp_getaddrs {
+	sctp_assoc_t		assoc_id; /*input*/
+	__u32			addr_num; /*output*/
+	__u8			addrs[0]; /*output, variable size*/
+};
 
 /* These are bit fields for msghdr->msg_flags.  See section 5.1.  */
 /* On user space Linux, these live in <bits/socket.h> as an enum.  */
diff --git a/kernel/signal.c b/kernel/signal.c
index 619b027..c135f5a 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -578,7 +578,8 @@
  		 * is to alert stop-signal processing code when another
  		 * processor has come along and cleared the flag.
  		 */
- 		tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
+ 		if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT))
+ 			tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
  	}
 	if ( signr &&
 	     ((info->si_code & __SI_MASK) == __SI_TIMER) &&
diff --git a/net/atm/addr.c b/net/atm/addr.c
index a30d0bf..3060fd0 100644
--- a/net/atm/addr.c
+++ b/net/atm/addr.c
@@ -44,31 +44,43 @@
 	sigd_enq(NULL, as_itf_notify, NULL, &pvc, NULL);
 }
 
-void atm_reset_addr(struct atm_dev *dev)
+void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t atype)
 {
 	unsigned long flags;
 	struct atm_dev_addr *this, *p;
+	struct list_head *head;
 
 	spin_lock_irqsave(&dev->lock, flags);
-	list_for_each_entry_safe(this, p, &dev->local, entry) {
+	if (atype == ATM_ADDR_LECS)
+		head = &dev->lecs;
+	else
+		head = &dev->local;
+	list_for_each_entry_safe(this, p, head, entry) {
 		list_del(&this->entry);
 		kfree(this);
 	}
 	spin_unlock_irqrestore(&dev->lock, flags);
-	notify_sigd(dev);
+	if (head == &dev->local)
+		notify_sigd(dev);
 }
 
-int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
+int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+		 enum atm_addr_type_t atype)
 {
 	unsigned long flags;
 	struct atm_dev_addr *this;
+	struct list_head *head;
 	int error;
 
 	error = check_addr(addr);
 	if (error)
 		return error;
 	spin_lock_irqsave(&dev->lock, flags);
-	list_for_each_entry(this, &dev->local, entry) {
+	if (atype == ATM_ADDR_LECS)
+		head = &dev->lecs;
+	else
+		head = &dev->local;
+	list_for_each_entry(this, head, entry) {
 		if (identical(&this->addr, addr)) {
 			spin_unlock_irqrestore(&dev->lock, flags);
 			return -EEXIST;
@@ -80,28 +92,36 @@
 		return -ENOMEM;
 	}
 	this->addr = *addr;
-	list_add(&this->entry, &dev->local);
+	list_add(&this->entry, head);
 	spin_unlock_irqrestore(&dev->lock, flags);
-	notify_sigd(dev);
+	if (head == &dev->local)
+		notify_sigd(dev);
 	return 0;
 }
 
-int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
+int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+		 enum atm_addr_type_t atype)
 {
 	unsigned long flags;
 	struct atm_dev_addr *this;
+	struct list_head *head;
 	int error;
 
 	error = check_addr(addr);
 	if (error)
 		return error;
 	spin_lock_irqsave(&dev->lock, flags);
-	list_for_each_entry(this, &dev->local, entry) {
+	if (atype == ATM_ADDR_LECS)
+		head = &dev->lecs;
+	else
+		head = &dev->local;
+	list_for_each_entry(this, head, entry) {
 		if (identical(&this->addr, addr)) {
 			list_del(&this->entry);
 			spin_unlock_irqrestore(&dev->lock, flags);
 			kfree(this);
-			notify_sigd(dev);
+			if (head == &dev->local)
+				notify_sigd(dev);
 			return 0;
 		}
 	}
@@ -110,22 +130,27 @@
 }
 
 int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user * buf,
-		 size_t size)
+		 size_t size, enum atm_addr_type_t atype)
 {
 	unsigned long flags;
 	struct atm_dev_addr *this;
+	struct list_head *head;
 	int total = 0, error;
 	struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
 
 	spin_lock_irqsave(&dev->lock, flags);
-	list_for_each_entry(this, &dev->local, entry)
+	if (atype == ATM_ADDR_LECS)
+		head = &dev->lecs;
+	else
+		head = &dev->local;
+	list_for_each_entry(this, head, entry)
 	    total += sizeof(struct sockaddr_atmsvc);
 	tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
 	if (!tmp_buf) {
 		spin_unlock_irqrestore(&dev->lock, flags);
 		return -ENOMEM;
 	}
-	list_for_each_entry(this, &dev->local, entry)
+	list_for_each_entry(this, head, entry)
 	    memcpy(tmp_bufp++, &this->addr, sizeof(struct sockaddr_atmsvc));
 	spin_unlock_irqrestore(&dev->lock, flags);
 	error = total > size ? -E2BIG : total;
diff --git a/net/atm/addr.h b/net/atm/addr.h
index 3099d21..f39433a 100644
--- a/net/atm/addr.h
+++ b/net/atm/addr.h
@@ -9,10 +9,12 @@
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 
-
-void atm_reset_addr(struct atm_dev *dev);
-int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,size_t size);
+void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t type);
+int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+		 enum atm_addr_type_t type);
+int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
+		 enum atm_addr_type_t type);
+int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user *buf,
+		 size_t size, enum atm_addr_type_t type);
 
 #endif
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 289956c..72f3f7b 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -220,7 +220,7 @@
 		/* netif_stop_queue(dev); */
 		dev_kfree_skb(skb);
 		read_unlock(&devs_lock);
-		return -EUNATCH;
+		return 0;
 	}
 	if (!br2684_xmit_vcc(skb, brdev, brvcc)) {
 		/*
diff --git a/net/atm/resources.c b/net/atm/resources.c
index a57a926..415d261 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -40,6 +40,7 @@
 	dev->link_rate = ATM_OC3_PCR;
 	spin_lock_init(&dev->lock);
 	INIT_LIST_HEAD(&dev->local);
+	INIT_LIST_HEAD(&dev->lecs);
 
 	return dev;
 }
@@ -320,10 +321,12 @@
 				error = -EPERM;
 				goto done;
 			}
-			atm_reset_addr(dev);
+			atm_reset_addr(dev, ATM_ADDR_LOCAL);
 			break;
 		case ATM_ADDADDR:
 		case ATM_DELADDR:
+		case ATM_ADDLECSADDR:
+		case ATM_DELLECSADDR:
 			if (!capable(CAP_NET_ADMIN)) {
 				error = -EPERM;
 				goto done;
@@ -335,14 +338,21 @@
 					error = -EFAULT;
 					goto done;
 				}
-				if (cmd == ATM_ADDADDR)
-					error = atm_add_addr(dev, &addr);
+				if (cmd == ATM_ADDADDR || cmd == ATM_ADDLECSADDR)
+					error = atm_add_addr(dev, &addr,
+							     (cmd == ATM_ADDADDR ?
+							      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
 				else
-					error = atm_del_addr(dev, &addr);
+					error = atm_del_addr(dev, &addr,
+							     (cmd == ATM_DELADDR ?
+							      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
 				goto done;
 			}
 		case ATM_GETADDR:
-			error = atm_get_addr(dev, buf, len);
+		case ATM_GETLECSADDR:
+			error = atm_get_addr(dev, buf, len,
+					     (cmd == ATM_GETADDR ?
+					      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
 			if (error < 0)
 				goto done;
 			size = error;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 91ec8c9..02e068d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3159,8 +3159,9 @@
 	return 0;
 }
 
-static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
-					  char __user *optval, int __user *optlen)
+static int sctp_getsockopt_peer_addrs_num_old(struct sock *sk, int len,
+					      char __user *optval,
+					      int __user *optlen)
 {
 	sctp_assoc_t id;
 	struct sctp_association *asoc;
@@ -3185,23 +3186,28 @@
 	return cnt;
 }
 
-static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
-				      char __user *optval, int __user *optlen)
+/* 
+ * Old API for getting list of peer addresses. Does not work for 32-bit
+ * programs running on a 64-bit kernel
+ */
+static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len,
+					  char __user *optval,
+					  int __user *optlen)
 {
 	struct sctp_association *asoc;
 	struct list_head *pos;
 	int cnt = 0;
-	struct sctp_getaddrs getaddrs;
+	struct sctp_getaddrs_old getaddrs;
 	struct sctp_transport *from;
 	void __user *to;
 	union sctp_addr temp;
 	struct sctp_sock *sp = sctp_sk(sk);
 	int addrlen;
 
-	if (len != sizeof(struct sctp_getaddrs))
+	if (len != sizeof(struct sctp_getaddrs_old))
 		return -EINVAL;
 
-	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old)))
 		return -EFAULT;
 
 	if (getaddrs.addr_num <= 0) return -EINVAL;
@@ -3225,15 +3231,69 @@
 		if (cnt >= getaddrs.addr_num) break;
 	}
 	getaddrs.addr_num = cnt;
-	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
+	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old)))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
-						char __user *optval,
-						int __user *optlen)
+static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
+				      char __user *optval, int __user *optlen)
+{
+	struct sctp_association *asoc;
+	struct list_head *pos;
+	int cnt = 0;
+	struct sctp_getaddrs getaddrs;
+	struct sctp_transport *from;
+	void __user *to;
+	union sctp_addr temp;
+	struct sctp_sock *sp = sctp_sk(sk);
+	int addrlen;
+	size_t space_left;
+	int bytes_copied;
+
+	if (len < sizeof(struct sctp_getaddrs))
+		return -EINVAL;
+
+	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+		return -EFAULT;
+
+	/* For UDP-style sockets, id specifies the association to query.  */
+	asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
+	if (!asoc)
+		return -EINVAL;
+
+	to = optval + offsetof(struct sctp_getaddrs,addrs);
+	space_left = len - sizeof(struct sctp_getaddrs) - 
+			offsetof(struct sctp_getaddrs,addrs);
+
+	list_for_each(pos, &asoc->peer.transport_addr_list) {
+		from = list_entry(pos, struct sctp_transport, transports);
+		memcpy(&temp, &from->ipaddr, sizeof(temp));
+		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+		addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
+		if(space_left < addrlen)
+			return -ENOMEM;
+		temp.v4.sin_port = htons(temp.v4.sin_port);
+		if (copy_to_user(to, &temp, addrlen))
+			return -EFAULT;
+		to += addrlen;
+		cnt++;
+		space_left -= addrlen;
+	}
+
+	if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num))
+		return -EFAULT;
+	bytes_copied = ((char __user *)to) - optval;
+	if (put_user(bytes_copied, optlen))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
+					       char __user *optval,
+					       int __user *optlen)
 {
 	sctp_assoc_t id;
 	struct sctp_bind_addr *bp;
@@ -3306,8 +3366,8 @@
 /* Helper function that copies local addresses to user and returns the number
  * of addresses copied.
  */
-static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, int max_addrs,
-				    void __user *to)
+static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs,
+					void __user *to)
 {
 	struct list_head *pos;
 	struct sctp_sockaddr_entry *addr;
@@ -3341,14 +3401,54 @@
 	return cnt;
 }
 
-static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
-				       char __user *optval, int __user *optlen)
+static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
+				    void * __user *to, size_t space_left)
+{
+	struct list_head *pos;
+	struct sctp_sockaddr_entry *addr;
+	unsigned long flags;
+	union sctp_addr temp;
+	int cnt = 0;
+	int addrlen;
+
+	sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+	list_for_each(pos, &sctp_local_addr_list) {
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+		if ((PF_INET == sk->sk_family) && 
+		    (AF_INET6 == addr->a.sa.sa_family))
+			continue;
+		memcpy(&temp, &addr->a, sizeof(temp));
+		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+								&temp);
+		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+		if(space_left<addrlen)
+			return -ENOMEM;
+		temp.v4.sin_port = htons(port);
+		if (copy_to_user(*to, &temp, addrlen)) {
+			sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+						    flags);
+			return -EFAULT;
+		}
+		*to += addrlen;
+		cnt ++;
+		space_left -= addrlen;
+	}
+	sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
+
+	return cnt;
+}
+
+/* Old API for getting list of local addresses. Does not work for 32-bit
+ * programs running on a 64-bit kernel
+ */
+static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
+					   char __user *optval, int __user *optlen)
 {
 	struct sctp_bind_addr *bp;
 	struct sctp_association *asoc;
 	struct list_head *pos;
 	int cnt = 0;
-	struct sctp_getaddrs getaddrs;
+	struct sctp_getaddrs_old getaddrs;
 	struct sctp_sockaddr_entry *addr;
 	void __user *to;
 	union sctp_addr temp;
@@ -3357,10 +3457,10 @@
 	rwlock_t *addr_lock;
 	int err = 0;
 
-	if (len != sizeof(struct sctp_getaddrs))
+	if (len != sizeof(struct sctp_getaddrs_old))
 		return -EINVAL;
 
-	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old)))
 		return -EFAULT;
 
 	if (getaddrs.addr_num <= 0) return -EINVAL;
@@ -3392,8 +3492,9 @@
 		addr = list_entry(bp->address_list.next,
 				  struct sctp_sockaddr_entry, list);
 		if (sctp_is_any(&addr->a)) {
-			cnt = sctp_copy_laddrs_to_user(sk, bp->port,
-						       getaddrs.addr_num, to);
+			cnt = sctp_copy_laddrs_to_user_old(sk, bp->port,
+							   getaddrs.addr_num,
+							   to);
 			if (cnt < 0) {
 				err = cnt;
 				goto unlock;
@@ -3419,7 +3520,7 @@
 
 copy_getaddrs:
 	getaddrs.addr_num = cnt;
-	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
+	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old)))
 		err = -EFAULT;
 
 unlock:
@@ -3427,6 +3528,99 @@
 	return err;
 }
 
+static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+				       char __user *optval, int __user *optlen)
+{
+	struct sctp_bind_addr *bp;
+	struct sctp_association *asoc;
+	struct list_head *pos;
+	int cnt = 0;
+	struct sctp_getaddrs getaddrs;
+	struct sctp_sockaddr_entry *addr;
+	void __user *to;
+	union sctp_addr temp;
+	struct sctp_sock *sp = sctp_sk(sk);
+	int addrlen;
+	rwlock_t *addr_lock;
+	int err = 0;
+	size_t space_left;
+	int bytes_copied;
+
+	if (len <= sizeof(struct sctp_getaddrs))
+		return -EINVAL;
+
+	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+		return -EFAULT;
+
+	/*
+	 *  For UDP-style sockets, id specifies the association to query.
+	 *  If the id field is set to the value '0' then the locally bound
+	 *  addresses are returned without regard to any particular
+	 *  association.
+	 */
+	if (0 == getaddrs.assoc_id) {
+		bp = &sctp_sk(sk)->ep->base.bind_addr;
+		addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
+	} else {
+		asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
+		if (!asoc)
+			return -EINVAL;
+		bp = &asoc->base.bind_addr;
+		addr_lock = &asoc->base.addr_lock;
+	}
+
+	to = optval + offsetof(struct sctp_getaddrs,addrs);
+	space_left = len - sizeof(struct sctp_getaddrs) -
+			 offsetof(struct sctp_getaddrs,addrs);
+
+	sctp_read_lock(addr_lock);
+
+	/* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
+	 * addresses from the global local address list.
+	 */
+	if (sctp_list_single_entry(&bp->address_list)) {
+		addr = list_entry(bp->address_list.next,
+				  struct sctp_sockaddr_entry, list);
+		if (sctp_is_any(&addr->a)) {
+			cnt = sctp_copy_laddrs_to_user(sk, bp->port,
+						       &to, space_left);
+			if (cnt < 0) {
+				err = cnt;
+				goto unlock;
+			}
+			goto copy_getaddrs;		
+		}
+	}
+
+	list_for_each(pos, &bp->address_list) {
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+		memcpy(&temp, &addr->a, sizeof(temp));
+		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
+		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+		if(space_left < addrlen)
+			return -ENOMEM; /*fixme: right error?*/
+		temp.v4.sin_port = htons(temp.v4.sin_port);
+		if (copy_to_user(to, &temp, addrlen)) {
+			err = -EFAULT;
+			goto unlock;
+		}
+		to += addrlen;
+		cnt ++;
+		space_left -= addrlen;
+	}
+
+copy_getaddrs:
+	if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num))
+		return -EFAULT;
+	bytes_copied = ((char __user *)to) - optval;
+	if (put_user(bytes_copied, optlen))
+		return -EFAULT;
+
+unlock:
+	sctp_read_unlock(addr_lock);
+	return err;
+}
+
 /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
  *
  * Requests that the local SCTP stack use the enclosed peer address as
@@ -3807,12 +4001,20 @@
 	case SCTP_INITMSG:
 		retval = sctp_getsockopt_initmsg(sk, len, optval, optlen);
 		break;
-	case SCTP_GET_PEER_ADDRS_NUM:
-		retval = sctp_getsockopt_peer_addrs_num(sk, len, optval,
+	case SCTP_GET_PEER_ADDRS_NUM_OLD:
+		retval = sctp_getsockopt_peer_addrs_num_old(sk, len, optval,
+							    optlen);
+		break;
+	case SCTP_GET_LOCAL_ADDRS_NUM_OLD:
+		retval = sctp_getsockopt_local_addrs_num_old(sk, len, optval,
+							     optlen);
+		break;
+	case SCTP_GET_PEER_ADDRS_OLD:
+		retval = sctp_getsockopt_peer_addrs_old(sk, len, optval,
 							optlen);
 		break;
-	case SCTP_GET_LOCAL_ADDRS_NUM:
-		retval = sctp_getsockopt_local_addrs_num(sk, len, optval,
+	case SCTP_GET_LOCAL_ADDRS_OLD:
+		retval = sctp_getsockopt_local_addrs_old(sk, len, optval,
 							 optlen);
 		break;
 	case SCTP_GET_PEER_ADDRS:
diff --git a/security/keys/Makefile b/security/keys/Makefile
index c392d75..5145adf 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -6,6 +6,7 @@
 	key.o \
 	keyring.o \
 	keyctl.o \
+	permission.o \
 	process_keys.o \
 	request_key.o \
 	request_key_auth.o \
diff --git a/security/keys/permission.c b/security/keys/permission.c
new file mode 100644
index 0000000..03db073
--- /dev/null
+++ b/security/keys/permission.c
@@ -0,0 +1,70 @@
+/* permission.c: key permission determination
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include "internal.h"
+
+/*****************************************************************************/
+/*
+ * check to see whether permission is granted to use a key in the desired way,
+ * but permit the security modules to override
+ */
+int key_task_permission(const key_ref_t key_ref,
+			struct task_struct *context,
+			key_perm_t perm)
+{
+	struct key *key;
+	key_perm_t kperm;
+	int ret;
+
+	key = key_ref_to_ptr(key_ref);
+
+	/* use the second 8-bits of permissions for keys the caller owns */
+	if (key->uid == context->fsuid) {
+		kperm = key->perm >> 16;
+		goto use_these_perms;
+	}
+
+	/* use the third 8-bits of permissions for keys the caller has a group
+	 * membership in common with */
+	if (key->gid != -1 && key->perm & KEY_GRP_ALL) {
+		if (key->gid == context->fsgid) {
+			kperm = key->perm >> 8;
+			goto use_these_perms;
+		}
+
+		task_lock(context);
+		ret = groups_search(context->group_info, key->gid);
+		task_unlock(context);
+
+		if (ret) {
+			kperm = key->perm >> 8;
+			goto use_these_perms;
+		}
+	}
+
+	/* otherwise use the least-significant 8-bits */
+	kperm = key->perm;
+
+use_these_perms:
+	/* use the top 8-bits of permissions for keys the caller possesses
+	 * - possessor permissions are additive with other permissions
+	 */
+	if (is_key_possessed(key_ref))
+		kperm |= key->perm >> 24;
+
+	kperm = kperm & perm & KEY_ALL;
+
+	return kperm == perm;
+
+} /* end key_task_permission() */
+
+EXPORT_SYMBOL(key_task_permission);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index e6dd366..5cc4bba 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -7,6 +7,8 @@
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/keys-request-key.txt
  */
 
 #include <linux/module.h>
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 1ecd3d3..a8e4069 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -7,6 +7,8 @@
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/keys-request-key.txt
  */
 
 #include <linux/module.h>
@@ -96,6 +98,7 @@
 	kenter("{%d}", key->serial);
 
 	key_put(rka->target_key);
+	kfree(rka);
 
 } /* end request_key_auth_destroy() */