rpms/kernel/FC-3 linux-2.6-ide-tune-locking.patch, NONE, 1.1 linux-2.6.11-acpi-thinkpad-c2c3.patch, NONE, 1.1 linux-2.6.11-atkbd-dell-multimedia.patch, NONE, 1.1 linux-2.6.11-cpufreq-add-suspend.patch, NONE, 1.1 linux-2.6.11-dentry-size.patch, NONE, 1.1 linux-2.6.11-execshield-vdso.patch, NONE, 1.1 linux-2.6.11-execshield.patch, NONE, 1.1 linux-2.6.11-firedire-slab-corruptor.patch, NONE, 1.1 linux-2.6.11-i2c-config.patch, NONE, 1.1 linux-2.6.11-isdn-icn-nodev.patch, NONE, 1.1 linux-2.6.11-kallsyms-extra-text.patch, NONE, 1.1 linux-2.6.11-libata-promise-pata-on-sata.patch, NONE, 1.1 linux-2.6.11-mac-mini-sound.patch, NONE, 1.1 linux-2.6.11-module-licenses.patch, NONE, 1.1 linux-2.6.11-parport-sysctl-perms.patch, NONE, 1.1 linux-2.6.11-pmac-ide-sleep.patch, NONE, 1.1 linux-2.6.11-pmac-volume-save.patch, NONE, 1.1 linux-2.6.11-ppc32-750-erratum-fix.patch, NONE, 1.1 linux-2.6.11-ppc32-pbook-clock-spreading.patch, NONE, 1.1 linux-2.6.11-ppc32-pmac-sleep-fix.patch, NONE, 1.1 linux-2.6.11-radeon-backlight.patch, ! NONE, 1.1 linux-2.6.11-random-ehci-patch.patch, NONE, 1.1 linux-2.6.11-serial-tickle-nmi.patch, NONE, 1.1 linux-2.6.11-serport-oops-fix.patch, NONE, 1.1 linux-2.6.11-slab-backtrace.patch, NONE, 1.1 linux-2.6.11-taint-check.patch, NONE, 1.1 linux-2.6.11-via-irq-quirk.patch, NONE, 1.1 linux-2.6.12-audit-git.patch, NONE, 1.1 linux-2.6.12-audit-merge.patch, NONE, 1.1 linux-2.6.12-cpufreq-update.patch, NONE, 1.1 linux-2.6.12-detect-softlockups.patch, NONE, 1.1 linux-2.6.12-firedire-init-breakage.patch, NONE, 1.1 linux-2.6.12-input-kill-stupid-messages.patch, NONE, 1.1 linux-2.6.12-ipmi-sysfs.patch, NONE, 1.1 linux-2.6.12-kobject-ordering.patch, NONE, 1.1 linux-2.6.12-missing-exports.patch, NONE, 1.1 linux-2.6.12-net-atm-lanai-nodev-rmmod.patch, NONE, 1.1 linux-2.6.12-net-conntrack-bridge-fix.patch, NONE, 1.1 linux-2.6.12-net-e1000-update.patch, NONE, 1.1 linux-2.6.12-net-make-orinoco-suck-less.patch, NONE, 1.1 linux-2.6.12-net-sundance-ip100A.patch, NONE, 1.1 linux-2.6.12-net-tulip-double-spinunlock.patch, NONE, 1.1 linu! x-2.6.12-nmi.patch,NONE,1.1 linux-2.6.12-ns558-nodev-rmmod.pat! ch,NONE,

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Jul 13 04:16:31 UTC 2005


Author: davej

Update of /cvs/dist/rpms/kernel/FC-3
In directory cvs.devel.redhat.com:/tmp/cvs-serv21541

Modified Files:
	.cvsignore Makefile Makefile.config branch kernel-2.6.spec 
	sources upstream 
Added Files:
	linux-2.6-ide-tune-locking.patch 
	linux-2.6.11-acpi-thinkpad-c2c3.patch 
	linux-2.6.11-atkbd-dell-multimedia.patch 
	linux-2.6.11-cpufreq-add-suspend.patch 
	linux-2.6.11-dentry-size.patch 
	linux-2.6.11-execshield-vdso.patch 
	linux-2.6.11-execshield.patch 
	linux-2.6.11-firedire-slab-corruptor.patch 
	linux-2.6.11-i2c-config.patch 
	linux-2.6.11-isdn-icn-nodev.patch 
	linux-2.6.11-kallsyms-extra-text.patch 
	linux-2.6.11-libata-promise-pata-on-sata.patch 
	linux-2.6.11-mac-mini-sound.patch 
	linux-2.6.11-module-licenses.patch 
	linux-2.6.11-parport-sysctl-perms.patch 
	linux-2.6.11-pmac-ide-sleep.patch 
	linux-2.6.11-pmac-volume-save.patch 
	linux-2.6.11-ppc32-750-erratum-fix.patch 
	linux-2.6.11-ppc32-pbook-clock-spreading.patch 
	linux-2.6.11-ppc32-pmac-sleep-fix.patch 
	linux-2.6.11-radeon-backlight.patch 
	linux-2.6.11-random-ehci-patch.patch 
	linux-2.6.11-serial-tickle-nmi.patch 
	linux-2.6.11-serport-oops-fix.patch 
	linux-2.6.11-slab-backtrace.patch 
	linux-2.6.11-taint-check.patch 
	linux-2.6.11-via-irq-quirk.patch linux-2.6.12-audit-git.patch 
	linux-2.6.12-audit-merge.patch 
	linux-2.6.12-cpufreq-update.patch 
	linux-2.6.12-detect-softlockups.patch 
	linux-2.6.12-firedire-init-breakage.patch 
	linux-2.6.12-input-kill-stupid-messages.patch 
	linux-2.6.12-ipmi-sysfs.patch 
	linux-2.6.12-kobject-ordering.patch 
	linux-2.6.12-missing-exports.patch 
	linux-2.6.12-net-atm-lanai-nodev-rmmod.patch 
	linux-2.6.12-net-conntrack-bridge-fix.patch 
	linux-2.6.12-net-e1000-update.patch 
	linux-2.6.12-net-make-orinoco-suck-less.patch 
	linux-2.6.12-net-sundance-ip100A.patch 
	linux-2.6.12-net-tulip-double-spinunlock.patch 
	linux-2.6.12-nmi.patch linux-2.6.12-ns558-nodev-rmmod.patch 
	linux-2.6.12-pwc-warning.patch 
	linux-2.6.12-rc3-ehci-misc-updates.patch 
	linux-2.6.12-rc4-audit-git.patch 
	linux-2.6.12-sata-sil-extra-id.patch 
	linux-2.6.12-scsi-blacklist.patch 
	linux-2.6.12-scsicam-geom-fix.patch 
	linux-2.6.12-speedtouch-resync.patch 
	linux-2.6.12-usb-old_scheme_first.patch 
	linux-2.6.12-vm-singlebiterror.patch linux-2.6.12.tar.bz2.sign 
	linux-2.6.12rc-ac-ide-fixes.patch 
	linux-2.6.12rc-ppc32-clockspreading-fix.patch 
	patch-2.6.12.2.bz2.sign 
Removed Files:
	linux-2.6.10-ac11-firewire-fixes.patch 
	linux-2.6.10-scsi-blacklist.patch 
	linux-2.6.10-usb-use_both_schemes.patch 
	linux-2.6.11-exec-shield.patch linux-2.6.11-ide-acfixes.patch 
	linux-2.6.11-net-conntrack-checksum-unnecessary.patch 
	linux-2.6.11-net-conntrack-leak.patch linux-2.6.11-pwc.patch 
	linux-2.6.11-scsi-aacraid-openoops.patch 
	linux-2.6.11-scsi-gfp-fix.patch 
	linux-2.6.11-scsi-queue-lock.patch 
	linux-2.6.11-scsi-st_ioctl-CAP_ADMIN.patch 
	linux-2.6.11-usb-aggressive-init-retry.patch 
	linux-2.6.11-x86_64-badpmd-debug.patch 
	linux-2.6.11-x86_64-more-debug.patch 
	linux-2.6.11-x86_64-pmdpud-race.patch 
	linux-2.6.11.tar.bz2.sign linux-2.6.12-devmem.patch 
	linux-2.6.9-ide-cd-early-EOF.patch 
	linux-2.6.9-net-airo-nullptr.patch 
	linux-2.6.9-s390-qeth_hipersocket-fix.patch 
	linux-2.6.9-sha1.patch patch-2.6.11.11.bz2.sign 
	patch-2.6.11.12.bz2.sign patch-2.6.11.9.bz2.sign 
Log Message:
sync from scratch/
(2.6.12 rebasE)


linux-2.6-ide-tune-locking.patch:
 piix.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-ide-tune-locking.patch ---
--- linux-2.6.12/drivers/ide/pci/piix.c~	2005-07-11 10:23:24.637181320 +0100
+++ linux-2.6.12/drivers/ide/pci/piix.c	2005-07-11 10:23:24.637181320 +0100
@@ -203,6 +203,8 @@
 	}
 }
 
+static spinlock_t tune_lock = SPIN_LOCK_UNLOCKED;
+
 /**
  *	piix_tune_drive		-	tune a drive attached to a PIIX
  *	@drive: drive to tune
@@ -229,7 +231,12 @@
 			    { 2, 3 }, };
 
 	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-	spin_lock_irqsave(&ide_lock, flags);
+	
+	/* Master v slave is synchronized above us but the slave register is
+	   shared by the two hwifs so the corner case of two slave timeouts in
+	   parallel must be locked */
+	   
+	spin_lock_irqsave(&tune_lock, flags);
 	pci_read_config_word(dev, master_port, &master_data);
 	if (is_slave) {
 		master_data = master_data | 0x4000;
@@ -249,7 +256,7 @@
 	pci_write_config_word(dev, master_port, master_data);
 	if (is_slave)
 		pci_write_config_byte(dev, slave_port, slave_data);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&tune_lock, flags);
 }
 
 /**

linux-2.6.11-acpi-thinkpad-c2c3.patch:
 processor_idle.c |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+)

--- NEW FILE linux-2.6.11-acpi-thinkpad-c2c3.patch ---

The patch titled

     ] acpi: Disable C2/C3 for _all_ IBM R40e Laptops (Bug #3549)

has been added to the -mm tree.  Its filename is

     acpi-disable-c2-c3-for-_all_-ibm-r40e-laptops-bug-3549.patch

Patches currently in -mm which might be from Thomas.Roesner at digital-trauma.de are

acpi-disable-c2-c3-for-_all_-ibm-r40e-laptops-bug-3549.patch



From: Thomas Roesner <Thomas.Roesner at digital-trauma.de>

This adds all known BIOS versions of IBM R40e Laptops to the C2/C3
processor state blacklist and thus prevents them from crashing.  Fixes Bug
#3549.

Implementation is probably overly verbose, but DMI_MATCH seems to give us
no choice.

Signed-off-by: Thomas Roesner <kernel-bugs at digital-trauma.de>
Cc: "Brown, Len" <len.brown at intel.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
---

 drivers/acpi/processor_idle.c |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+)

diff -puN drivers/acpi/processor_idle.c~acpi-disable-c2-c3-for-_all_-ibm-r40e-laptops-bug-3549 drivers/acpi/processor_idle.c
--- 25/drivers/acpi/processor_idle.c~acpi-disable-c2-c3-for-_all_-ibm-r40e-laptops-bug-3549	Mon Jun 27 13:40:24 2005
+++ 25-akpm/drivers/acpi/processor_idle.c	Mon Jun 27 13:41:08 2005
@@ -99,7 +99,46 @@ static int no_c2c3(struct dmi_system_id 
 static struct dmi_system_id __initdata processor_power_dmi_table[] = {
 	{ no_c2c3, "IBM ThinkPad R40e", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET32WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }},
+	{ no_c2c3, "IBM ThinkPad R40e", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }},
 	{ no_c2c3, "Medion 41700", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }},


linux-2.6.11-atkbd-dell-multimedia.patch:
 atkbd.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6.11-atkbd-dell-multimedia.patch ---

bz 126148

--- linux-2.6.11/drivers/input/keyboard/atkbd.c~	2005-04-16 12:45:00.000000000 -0400
+++ linux-2.6.11/drivers/input/keyboard/atkbd.c	2005-04-16 12:46:28.000000000 -0400
@@ -90,13 +90,13 @@ static unsigned char atkbd_set2_keycode[
 	 82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
 
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
-	173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
+	217,100,255,  0, 97,165,196,  0,156,  0,  0,  0,  0,  0,197,125,
+	173,114,  0,113,  0,  0,198,126,128,  0,  0,140,  0,  0,  0,127,
 	159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
 	157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
 	226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
 	  0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
-	110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
+	110,111,108,112,106,103,195,119,  0,118,109,  0, 99,104,119,  0,
 
 	  0,  0,  0, 65, 99,
 #endif

linux-2.6.11-cpufreq-add-suspend.patch:
 drivers/cpufreq/cpufreq.c |  131 +++++++++++++++++++++++++++++++++++++---------
 include/linux/cpufreq.h   |    5 +
 2 files changed, 111 insertions(+), 25 deletions(-)

--- NEW FILE linux-2.6.11-cpufreq-add-suspend.patch ---
Index: linux-work/drivers/cpufreq/cpufreq.c
===================================================================
--- linux-work.orig/drivers/cpufreq/cpufreq.c	2005-03-30 09:42:18.000000000 +1000
+++ linux-work/drivers/cpufreq/cpufreq.c	2005-03-30 09:47:22.000000000 +1000
@@ -223,7 +223,7 @@
 	}
 	if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) ||
 	    (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
-	    (val == CPUFREQ_RESUMECHANGE)) {
+	    (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
 		loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
 		dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new);
 	}
@@ -866,16 +866,96 @@
 
 
 /**
+ *	cpufreq_suspend - let the low level driver prepare for suspend
+ */
+
+static int cpufreq_suspend(struct sys_device * sysdev, u32 state)
+{
+	int cpu = sysdev->id;
+	unsigned int ret = 0;
+	unsigned int cur_freq = 0;
+	struct cpufreq_policy *cpu_policy;
+
+	dprintk("resuming cpu %u\n", cpu);
+
+	if (!cpu_online(cpu))
+		return 0;
+
+	/* we may be lax here as interrupts are off. Nonetheless
+	 * we need to grab the correct cpu policy, as to check
+	 * whether we really run on this CPU.
+	 */
+
+	cpu_policy = cpufreq_cpu_get(cpu);
+	if (!cpu_policy)
+		return -EINVAL;
+
+	/* only handle each CPU group once */
+	if (unlikely(cpu_policy->cpu != cpu)) {
+		cpufreq_cpu_put(cpu_policy);
+		return 0;
+	}
+
+	if (cpufreq_driver->suspend) {
+		ret = cpufreq_driver->suspend(cpu_policy, state);
+		if (ret) {
+			printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
+					"step on CPU %u\n", cpu_policy->cpu);
+			cpufreq_cpu_put(cpu_policy);
+			return ret;
+		}
+	}
+
+
+	if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)
+		goto out;
+
+	if (cpufreq_driver->get)
+		cur_freq = cpufreq_driver->get(cpu_policy->cpu);
+
+	if (!cur_freq || !cpu_policy->cur) {
+		printk(KERN_ERR "cpufreq: suspend failed to assert current "
+		       "frequency is what timing core thinks it is.\n");
+		goto out;
+	}
+
+	if (unlikely(cur_freq != cpu_policy->cur)) {
+		struct cpufreq_freqs freqs;
+
+		if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
+			printk(KERN_DEBUG "Warning: CPU frequency is %u, "
+			       "cpufreq assumed %u kHz.\n",
+			       cur_freq, cpu_policy->cur);
+
+		freqs.cpu = cpu;
+		freqs.old = cpu_policy->cur;
+		freqs.new = cur_freq;
+
+		notifier_call_chain(&cpufreq_transition_notifier_list,
+				    CPUFREQ_SUSPENDCHANGE, &freqs);
+		adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
+
+		cpu_policy->cur = cur_freq;
+	}
+
+ out:
+	cpufreq_cpu_put(cpu_policy);
+	return 0;
+}
+
+/**
  *	cpufreq_resume -  restore proper CPU frequency handling after resume
  *
  *	1.) resume CPUfreq hardware support (cpufreq_driver->resume())
  *	2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync
- *	3.) schedule call cpufreq_update_policy() ASAP as interrupts are restored.
+ *	3.) schedule call cpufreq_update_policy() ASAP as interrupts are
+ *	    restored.
  */
 static int cpufreq_resume(struct sys_device * sysdev)
 {
 	int cpu = sysdev->id;
 	unsigned int ret = 0;
+	unsigned int cur_freq = 0;
 	struct cpufreq_policy *cpu_policy;
 
 	dprintk("resuming cpu %u\n", cpu);
@@ -908,32 +988,34 @@
 		}
 	}
 
-	if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
-		unsigned int cur_freq = 0;
-
-		if (cpufreq_driver->get)
-			cur_freq = cpufreq_driver->get(cpu_policy->cpu);
-
-		if (!cur_freq || !cpu_policy->cur) {
-			printk(KERN_ERR "cpufreq: resume failed to assert current frequency is what timing core thinks it is.\n");
-			goto out;
-		}
-
-		if (unlikely(cur_freq != cpu_policy->cur)) {
-			struct cpufreq_freqs freqs;
+	if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)
+		goto out;
 
-			printk(KERN_WARNING "Warning: CPU frequency is %u, "
-			       "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur);
+	if (cpufreq_driver->get)
+		cur_freq = cpufreq_driver->get(cpu_policy->cpu);
 
-			freqs.cpu = cpu;
-			freqs.old = cpu_policy->cur;
-			freqs.new = cur_freq;
+	if (!cur_freq || !cpu_policy->cur) {
+		printk(KERN_ERR "cpufreq: resume failed to assert current "
+		       "frequency is what timing core thinks it is.\n");
+		goto out;
+	}
 
-			notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs);
-			adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
+	if (unlikely(cur_freq != cpu_policy->cur)) {
+		struct cpufreq_freqs freqs;
 
-			cpu_policy->cur = cur_freq;
-		}
+		if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
+			printk(KERN_DEBUG "Warning: CPU frequency is %u, "
+			       "cpufreq assumed %u kHz.\n",
+			       cur_freq, cpu_policy->cur);
+
+		freqs.cpu = cpu;
+		freqs.old = cpu_policy->cur;
+		freqs.new = cur_freq;
+
+		notifier_call_chain(&cpufreq_transition_notifier_list,
+				    CPUFREQ_RESUMECHANGE, &freqs);
+		adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
+		cpu_policy->cur = cur_freq;
 	}
 
 out:
@@ -945,6 +1027,7 @@
 static struct sysdev_driver cpufreq_sysdev_driver = {
 	.add		= cpufreq_add_dev,
 	.remove		= cpufreq_remove_dev,
+	.suspend	= cpufreq_suspend,
 	.resume		= cpufreq_resume,
 };
 
Index: linux-work/include/linux/cpufreq.h
===================================================================
--- linux-work.orig/include/linux/cpufreq.h	2005-03-30 09:42:18.000000000 +1000
+++ linux-work/include/linux/cpufreq.h	2005-03-30 09:46:25.000000000 +1000
@@ -103,6 +103,7 @@
 #define CPUFREQ_PRECHANGE	(0)
 #define CPUFREQ_POSTCHANGE	(1)
 #define CPUFREQ_RESUMECHANGE	(8)
+#define CPUFREQ_SUSPENDCHANGE	(9)
 
 struct cpufreq_freqs {
 	unsigned int cpu;	/* cpu nr */
@@ -200,6 +201,7 @@
 
 	/* optional */
 	int	(*exit)		(struct cpufreq_policy *policy);
+	int	(*suspend)	(struct cpufreq_policy *policy, u32 state);
 	int	(*resume)	(struct cpufreq_policy *policy);
 	struct freq_attr	**attr;
 };
@@ -211,7 +213,8 @@
 #define CPUFREQ_CONST_LOOPS 	0x02	/* loops_per_jiffy or other kernel
 					 * "constants" aren't affected by
 					 * frequency transitions */
-
+#define CPUFREQ_PM_NO_WARN	0x04	/* don't warn on suspend/resume speed
+					 * mismatches */
 
 int cpufreq_register_driver(struct cpufreq_driver *driver_data);
 int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);

linux-2.6.11-dentry-size.patch:
 dcache.h |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.11-dentry-size.patch ---
--- linux-2.6.11/include/linux/dcache.h~	2005-04-20 00:59:37.000000000 -0400
+++ linux-2.6.11/include/linux/dcache.h	2005-04-20 01:01:46.000000000 -0400
@@ -78,7 +78,13 @@ full_name_hash(const unsigned char *name
 
 struct dcookie_struct;
 
-#define DNAME_INLINE_LEN_MIN 36
+#ifdef CONFIG_64BIT
+/* Total dentry size=256 bytes */
+#define DNAME_INLINE_LEN_MIN 60
+#else
+/* Total dentry size=128 bytes */
+#define DNAME_INLINE_LEN_MIN 16
+#endif
 
 struct dentry {
 	atomic_t d_count;

linux-2.6.11-execshield-vdso.patch:
 linux-2.6.11/arch/i386/kernel/sysenter.c  |   73 ++++++++++++++++++------------
 linux-2.6.11/fs/binfmt_elf.c              |   17 ++----
 linux-2.6.11/include/asm-i386/elf.h       |    7 ++
 linux-2.6.11/include/asm-i386/page.h      |    5 ++
 linux-2.6.11/include/linux/mm.h           |    5 ++
 linux-2.6.11/mm/mmap.c                    |   39 ++++++++++++++++
 linux-2.6.8/arch/i386/kernel/cpu/common.c |    6 ++
 7 files changed, 113 insertions(+), 39 deletions(-)

--- NEW FILE linux-2.6.11-execshield-vdso.patch ---
--- linux-2.6.8/arch/i386/kernel/cpu/common.c~	2004-10-12 17:21:42.945526432 -0400
+++ linux-2.6.8/arch/i386/kernel/cpu/common.c	2004-10-12 17:24:30.941987088 -0400
@@ -384,6 +377,12 @@ void __init identify_cpu(struct cpuinfo_
 	if (disable_pse)
 		clear_bit(X86_FEATURE_PSE, c->x86_capability);
 
+	/* hack: disable SEP for non-NX cpus; SEP breaks Execshield. */
+	#ifdef CONFIG_HIGHMEM64G
+	if (!test_bit(X86_FEATURE_NX, c->x86_capability)) 
+	#endif
+		clear_bit(X86_FEATURE_SEP, c->x86_capability);
+
 	/* If the model name is still unset, do table lookup. */
 	if ( !c->x86_model_id[0] ) {
 		char *p;
--- linux-2.6.11/arch/i386/kernel/sysenter.c
+++ linux-2.6.11/arch/i386/kernel/sysenter.c
@@ -48,13 +48,6 @@ static int __init sysenter_setup(void)
 {
 	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
 
-	/*
-	 * We keep this page mapped readonly, even though the executable
-	 * portion is randomized into a userspace vma - so that we dont
-	 * have to fix up the data within the VDSO page every time we
-	 * exec().
-	 */
-	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_KERNEL_RO);
 	sysenter_page = virt_to_page(page);
 
 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
@@ -76,37 +69,61 @@ __initcall(sysenter_setup);
 
 extern void SYSENTER_RETURN_OFFSET;
 
-unsigned int vdso_enabled = 0;
+unsigned int vdso_enabled = 1;
 
-void map_vsyscall(void)
+/*
+ * This is called from binfmt_elf, we create the special vma for the
+ * vDSO and insert it into the mm struct tree.
+ */
+int arch_setup_additional_pages(struct linux_binprm *bprm,
+				int executable_stack)
 {
 	struct thread_info *ti = current_thread_info();
-	struct vm_area_struct *vma;
-	unsigned long addr;
+	unsigned long addr, len;
+	int err;
 
-	if (unlikely(!vdso_enabled)) {
-		current->mm->context.vdso = NULL;
-		return;
-	}
+	current->mm->context.vdso = NULL;
+	if (unlikely(!vdso_enabled) || unlikely(!sysenter_page))
+		return 0;
 
 	/*
 	 * Map the vDSO (it will be randomized):
 	 */
 	down_write(&current->mm->mmap_sem);
-	addr = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
-	current->mm->context.vdso = (void *)addr;
-	ti->sysenter_return = (void *)addr + (long)&SYSENTER_RETURN_OFFSET;
-	if (addr != -1) {
-		vma = find_vma(current->mm, addr);
-		if (vma) {
-			pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
-			get_page(sysenter_page);
-			install_page(current->mm, vma, addr,
-					sysenter_page, vma->vm_page_prot);
-			
-		}
+	len = PAGE_SIZE > ELF_EXEC_PAGESIZE ? PAGE_SIZE : ELF_EXEC_PAGESIZE;
+	addr = get_unmapped_area_prot(NULL, 0, len, 0,
+				      MAP_PRIVATE, PROT_READ | PROT_EXEC);
+	if (unlikely(addr & ~PAGE_MASK)) {
+		up_write(&current->mm->mmap_sem);
+		return addr;
+	}
+	get_page(sysenter_page);
+	err = install_special_mapping(current->mm, addr, len,
+				      VM_DONTEXPAND | VM_READ | VM_EXEC |
+				      VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+				      PAGE_READONLY_EXEC,
+				      &sysenter_page, 1);
+	if (likely(err == 0)) {
+		current->mm->context.vdso = (void *)addr;
+		ti->sysenter_return = &SYSENTER_RETURN_OFFSET + addr;
 	}
 	up_write(&current->mm->mmap_sem);
+	return err;
+}
+
+int in_gate_area_no_task(unsigned long addr)
+{
+	return 0;
+}
+
+int in_gate_area(struct task_struct *task, unsigned long addr)
+{
+	return 0;
+}
+
+struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
+{
+	return NULL;
 }
 
 static int __init vdso_setup(char *str)
--- linux-2.6.11/fs/binfmt_elf.c
+++ linux-2.6.11/fs/binfmt_elf.c
@@ -1016,14 +1016,6 @@ static int load_elf_binary(struct linux_
 	}
 #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
 
-	/*
-	 * Map the vsyscall trampoline. This address is then passed via
-	 * AT_SYSINFO.
-	 */
-#ifdef __HAVE_ARCH_VSYSCALL
-	map_vsyscall();
-#endif
-
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
 	create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT),
@@ -1223,6 +1215,9 @@ static int maydump(struct vm_area_struct
 	if (vma->vm_flags & (VM_IO | VM_RESERVED))
 		return 0;
 
+	if (vma->vm_flags & VM_DONTEXPAND) /* Kludge for vDSO.  */
+		return 1;
+
 	/* Dump shared memory only if mapped from an anonymous file.  */
 	if (vma->vm_flags & VM_SHARED)
 		return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
--- linux-2.6.11/include/asm-i386/elf.h
+++ linux-2.6.11/include/asm-i386/elf.h
@@ -152,6 +152,12 @@ do {									\
 	}								\
 } while (0)
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+				       int executable_stack);
+
+#if 0	/* Disabled for exec-shield, where a normal vma holds the vDSO.  */
 /*
  * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
  * extra segments containing the vsyscall DSO contents.  Dumping its
@@ -195,8 +201,9 @@ do {									      \
 				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
 	}								      \
 } while (0)
+#endif
 
 #endif
 
 #define __HAVE_ARCH_RANDOMIZE_BRK
 extern void randomize_brk(unsigned long old_brk);
--- linux-2.6.11/include/asm-i386/page.h
+++ linux-2.6.11/include/asm-i386/page.h
@@ -150,6 +150,11 @@ extern int devmem_is_allowed(unsigned lo
 	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
 		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+/*
+ * Under exec-shield we don't use the generic fixmap gate area.
+ * The vDSO ("gate area") has a normal vma found the normal ways.
+ */
+#define __HAVE_ARCH_GATE_AREA	1
 
 
 #endif /* __KERNEL__ */
--- linux-2.6.11/include/linux/mm.h
+++ linux-2.6.11/include/linux/mm.h
@@ -737,6 +737,11 @@ static inline unsigned long get_unmapped
 	return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0);	
 }
 
+extern int install_special_mapping(struct mm_struct *mm,
+				   unsigned long addr, unsigned long len,
+				   unsigned long vm_flags, pgprot_t pgprot,
+				   struct page **pages, unsigned int npages);
+
 extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 	unsigned long len, unsigned long prot,
 	unsigned long flag, unsigned long pgoff);
--- linux-2.6.11/mm/mmap.c
+++ linux-2.6.11/mm/mmap.c
@@ -2171,3 +2171,42 @@ struct vm_area_struct *copy_vma(struct v
 	}
 	return new_vma;
 }
+
+/*
+ * Insert a new vma covering the given region, with the given flags and
+ * protections.  Pre-install the mappings to zero or more leading pages
+ * in the region.  Note, this does put_page on pages[0..npages-1] in all
+ * cases, even on error return.
+ */
+int install_special_mapping(struct mm_struct *mm,
+			    unsigned long addr, unsigned long len,
+			    unsigned long vm_flags, pgprot_t pgprot,
+			    struct page **pages, unsigned int npages)
+{
+	struct vm_area_struct *vma;
+	int err = -ENOMEM;
+
+	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (unlikely(vma == NULL))
+		goto out;
+	memset(vma, 0, sizeof(*vma));
+
+	vma->vm_mm = mm;
+	vma->vm_start = addr;
+	vma->vm_end = addr + len;
+
+	vma->vm_flags = vm_flags;
+	vma->vm_page_prot = pgprot;
+
+	insert_vm_struct(mm, vma);
+	mm->total_vm += len >> PAGE_SHIFT;
+
+	for (err = 0; npages > 0 && !err; --npages, ++pages, addr += PAGE_SIZE)
+		err = install_page(mm, vma, addr, *pages, vma->vm_page_prot);
+
+ out:
+	for (; npages > 0; --npages, ++pages)
+		put_page(*pages);
+
+	return err;
+}


--- linux-2.6.11/fs/binfmt_elf.c.~1~	2005-04-26 17:42:01.532000183 -0700
+++ linux-2.6.11/fs/binfmt_elf.c	2005-04-26 17:55:58.566821547 -0700
@@ -1001,8 +1001,6 @@ static int load_elf_binary(struct linux_
 		elf_entry = loc->elf_ex.e_entry;
 	}
 
-	kfree(elf_phdata);
-
 	if (interpreter_type != INTERPRETER_AOUT)
 		sys_close(elf_exec_fileno);
 
@@ -1010,10 +1010,12 @@ static int load_elf_binary(struct linux_
 	retval = arch_setup_additional_pages(bprm, executable_stack);
 	if (retval < 0) {
 		send_sig(SIGKILL, current, 0);
-		goto out;
+		goto out_free_fh;
 	}
 #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
 
+	kfree(elf_phdata);
+
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
 	create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT),
--- linux-2.6.11/arch/i386/kernel/sysenter.c~	2005-05-25 19:25:10.000000000 -0400
+++ linux-2.6.11/arch/i386/kernel/sysenter.c	2005-05-25 19:25:41.000000000 -0400
@@ -51,7 +51,7 @@ static int __init sysenter_setup(void)
 
 	sysenter_page = virt_to_page(page);
 
-	if (!boot_cpu_has(X86_FEATURE_SEP)) {
+	if (1 || (!boot_cpu_has(X86_FEATURE_SEP))) {
 		memcpy(page,
 		       &vsyscall_int80_start,
 		       &vsyscall_int80_end - &vsyscall_int80_start);

linux-2.6.11-execshield.patch:
 2/mm/mmap.c                                    |    2 
 linux-2.6.11/arch/i386/kernel/traps.c          |  111 ++++++++++++++++-------
 linux-2.6.11/arch/x86_64/mm/fault.c            |    4 
 linux-2.6.11/include/asm-x86_64/processor.h    |    8 +
 linux-810/arch/i386/kernel/asm-offsets.c       |    1 
 linux-810/arch/i386/kernel/entry.S             |    8 +
 linux-810/arch/i386/kernel/process.c           |   59 ++++++++++++
 linux-810/arch/i386/kernel/signal.c            |    4 
 linux-810/arch/i386/kernel/smp.c               |    3 
 linux-810/arch/i386/kernel/sysenter.c          |   55 +++++++++++
 linux-810/arch/i386/kernel/traps.c             |   48 +++++++++-
 linux-810/arch/i386/kernel/vsyscall-sysenter.S |    6 -
 linux-810/arch/i386/kernel/vsyscall.lds.S      |    4 
 linux-810/arch/i386/mm/init.c                  |    6 +
 linux-810/arch/i386/mm/mmap.c                  |    6 -
 linux-810/arch/ia64/ia32/binfmt_elf32.c        |    2 
 linux-810/arch/x86_64/ia32/ia32_binfmt.c       |    2 
 linux-810/arch/x86_64/kernel/process.c         |    7 -
 linux-810/arch/x86_64/mm/Makefile              |    2 
 linux-810/arch/x86_64/mm/mmap.c                |   95 +++++++++++++++++++
 linux-810/drivers/char/random.c                |    7 +
 linux-810/fs/binfmt_elf.c                      |  120 ++++++++++++++++++++-----
 linux-810/fs/proc/array.c                      |    8 +
 linux-810/fs/proc/base.c                       |    4 
 linux-810/fs/proc/task_mmu.c                   |   25 ++++-
 linux-810/include/asm-i386/desc.h              |   14 ++
 linux-810/include/asm-i386/elf.h               |   42 +++++---
 linux-810/include/asm-i386/mmu.h               |    6 +
 linux-810/include/asm-i386/pgalloc.h           |    1 
 linux-810/include/asm-i386/processor.h         |    8 +
 linux-810/include/asm-i386/thread_info.h       |    1 
 linux-810/include/asm-ia64/pgalloc.h           |    4 
 linux-810/include/asm-ppc/pgalloc.h            |    5 +
 linux-810/include/asm-ppc64/pgalloc.h          |    5 +
 linux-810/include/asm-s390/pgalloc.h           |    4 
 linux-810/include/asm-sparc/pgalloc.h          |    4 
 linux-810/include/asm-sparc64/pgalloc.h        |    4 
 linux-810/include/asm-x86_64/pgalloc.h         |    7 +
 linux-810/include/linux/mm.h                   |    9 +
 linux-810/include/linux/resource.h             |    5 -
 linux-810/include/linux/sched.h                |    9 +
 linux-810/include/linux/sysctl.h               |    3 
 linux-810/kernel/signal.c                      |   38 +++++++
 linux-810/kernel/sysctl.c                      |   39 ++++++++
 linux-810/mm/fremap.c                          |   10 +-
 linux-810/mm/mmap.c                            |  105 ++++++++++++++++++++-
 linux-810/mm/mprotect.c                        |    5 -
 linux-810/mm/mremap.c                          |    4 
 48 files changed, 804 insertions(+), 125 deletions(-)

--- NEW FILE linux-2.6.11-execshield.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/asm-offsets.c linux-810/arch/i386/kernel/asm-offsets.c
--- linux-801/arch/i386/kernel/asm-offsets.c
+++ linux-810/arch/i386/kernel/asm-offsets.c
@@ -53,6 +53,7 @@ void foo(void)
 	OFFSET(TI_preempt_count, thread_info, preempt_count);
 	OFFSET(TI_addr_limit, thread_info, addr_limit);
 	OFFSET(TI_restart_block, thread_info, restart_block);
+	OFFSET(TI_sysenter_return, thread_info, sysenter_return);
 	BLANK();
 
 	OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/entry.S linux-810/arch/i386/kernel/entry.S
--- linux-801/arch/i386/kernel/entry.S
+++ linux-810/arch/i386/kernel/entry.S
@@ -201,8 +201,12 @@ sysenter_past_esp:
 	pushl %ebp
 	pushfl
 	pushl $(__USER_CS)
-	pushl $SYSENTER_RETURN
-
+	/*
+	 * Push current_thread_info()->sysenter_return to the stack.
+	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
+	 * pushed above; +8 corresponds to copy_thread's esp0 setting.
+	 */
+	pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
 /*
  * Load the potential sixth argument from user stack.
  * Careful about security.
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/process.c linux-810/arch/i386/kernel/process.c
--- linux-801/arch/i386/kernel/process.c
+++ linux-810/arch/i386/kernel/process.c
@@ -582,6 +582,8 @@ struct task_struct fastcall * __switch_t
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
 	__unlazy_fpu(prev_p);
+	if (next_p->mm)
+		load_user_cs_desc(cpu, next_p->mm);
 
 	/*
 	 * Reload esp0, LDT and the page table pointer:
@@ -835,3 +837,60 @@ unsigned long arch_align_stack(unsigned 
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
+{
+	if (limit > mm->context.exec_limit) {
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
+{
+	struct vm_area_struct *vma;
+	unsigned long limit = PAGE_SIZE;
+
+	if (old_end == mm->context.exec_limit) {
+		for (vma = mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_flush_exec_range(struct mm_struct *mm)
+{
+	mm->context.exec_limit = 0;
+	set_user_cs(&mm->context.user_cs, 0);
+}
+
+/*
+ * Generate random brk address between 128MB and 196MB. (if the layout
+ * allows it.)
+ */
+void randomize_brk(unsigned long old_brk)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = 0x08000000;
+	if (current->mm->brk >= range_start)
+		range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = new_brk;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/signal.c linux-810/arch/i386/kernel/signal.c
--- linux-801/arch/i386/kernel/signal.c
+++ linux-810/arch/i386/kernel/signal.c
@@ -380,7 +380,7 @@ static void setup_frame(int sig, struct 
 			goto give_sigsegv;
 	}
 
-	restorer = &__kernel_sigreturn;
+	restorer = current->mm->context.vdso + (long)&__kernel_sigreturn;
 	if (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 
@@ -475,7 +475,7 @@ static void setup_rt_frame(int sig, stru
 		goto give_sigsegv;
 
 	/* Set up to return from userspace.  */
-	restorer = &__kernel_rt_sigreturn;
+	restorer = current->mm->context.vdso + (long)&__kernel_rt_sigreturn;
 	if (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 	err |= __put_user(restorer, &frame->pretcode);
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/smp.c linux-810/arch/i386/kernel/smp.c
--- linux-801/arch/i386/kernel/smp.c
+++ linux-810/arch/i386/kernel/smp.c
@@ -22,6 +22,7 @@
 
 #include <asm/mtrr.h>
 #include <asm/tlbflush.h>
+#include <asm/desc.h>
 #include <mach_apic.h>
 
 /*
@@ -313,6 +314,8 @@ fastcall void smp_invalidate_interrupt(s
 	unsigned long cpu;
 
 	cpu = get_cpu();
+	if (current->active_mm)
+		load_user_cs_desc(cpu, current->active_mm);
 
 	if (!cpu_isset(cpu, flush_cpumask))
 		goto out;
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/sysenter.c linux-810/arch/i386/kernel/sysenter.c
--- linux-801/arch/i386/kernel/sysenter.c
+++ linux-810/arch/i386/kernel/sysenter.c
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/elf.h>
+#include <linux/mman.h>
 
 #include <asm/cpufeature.h>
 #include <asm/msr.h>
@@ -41,11 +42,20 @@ void enable_sep_cpu(void *info)
 extern const char vsyscall_int80_start, vsyscall_int80_end;
 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
 
+struct page *sysenter_page;
+
 static int __init sysenter_setup(void)
 {
 	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
 
-	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
+	/*
+	 * We keep this page mapped readonly, even though the executable
+	 * portion is randomized into a userspace vma - so that we dont
+	 * have to fix up the data within the VDSO page every time we
+	 * exec().
+	 */
+	__set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_KERNEL_RO);
+	sysenter_page = virt_to_page(page);
 
 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
 		memcpy(page,
@@ -63,3 +73,46 @@ static int __init sysenter_setup(void)
 }
 
 __initcall(sysenter_setup);
+
+extern void SYSENTER_RETURN_OFFSET;
+
+unsigned int vdso_enabled = 0;
+
+void map_vsyscall(void)
+{
+	struct thread_info *ti = current_thread_info();
+	struct vm_area_struct *vma;
+	unsigned long addr;
+
+	if (unlikely(!vdso_enabled)) {
+		current->mm->context.vdso = NULL;
+		return;
+	}
+
+	/*
+	 * Map the vDSO (it will be randomized):
+	 */
+	down_write(&current->mm->mmap_sem);
+	addr = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
+	current->mm->context.vdso = (void *)addr;
+	ti->sysenter_return = (void *)addr + (long)&SYSENTER_RETURN_OFFSET;
+	if (addr != -1) {
+		vma = find_vma(current->mm, addr);
+		if (vma) {
+			pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+			get_page(sysenter_page);
+			install_page(current->mm, vma, addr,
+					sysenter_page, vma->vm_page_prot);
+			
+		}
+	}
+	up_write(&current->mm->mmap_sem);
+}
+
+static int __init vdso_setup(char *str)
+{
+        vdso_enabled = simple_strtoul(str, NULL, 0);
+        return 1;
+}
+__setup("vdso=", vdso_setup);
+
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/traps.c linux-810/arch/i386/kernel/traps.c
--- linux-801/arch/i386/kernel/traps.c
+++ linux-810/arch/i386/kernel/traps.c
@@ -452,6 +452,10 @@ DO_ERROR(11, SIGBUS,  "segment not prese
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
 
+/*
+ * the original non-exec stack patch was written by
+ * Solar Designer <solar at openwall.com>. Thanks!
+ */
 fastcall void do_general_protection(struct pt_regs * regs, long error_code)
 {
 	int cpu = get_cpu();
@@ -482,7 +486,6 @@ fastcall void do_general_protection(stru
 		put_cpu();
 		return;
 	}
-	put_cpu();
 
 	if (regs->eflags & VM_MASK)
 		goto gp_in_vm86;
@@ -490,17 +493,60 @@ fastcall void do_general_protection(stru
 	if (!(regs->xcs & 3))
 		goto gp_in_kernel;
 
+	/*
+	 * lazy-check for CS validity on exec-shield binaries:
+	 */
+	if (current->mm) {
+		struct desc_struct *desc1, *desc2;
+		struct vm_area_struct *vma;
+		unsigned long limit = PAGE_SIZE;
+		
+		spin_lock(&current->mm->page_table_lock);
+		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+		spin_unlock(&current->mm->page_table_lock);
+
+		current->mm->context.exec_limit = limit;
+		set_user_cs(&current->mm->context.user_cs, limit);
+
+		desc1 = &current->mm->context.user_cs;
+		desc2 = per_cpu(cpu_gdt_table, cpu) + GDT_ENTRY_DEFAULT_USER_CS;
+
+		/*
+		 * The CS was not in sync - reload it and retry the
+		 * instruction. If the instruction still faults then
+		 * we wont hit this branch next time around.
+		 */
+		if (desc1->a != desc2->a || desc1->b != desc2->b) {
+			if (print_fatal_signals >= 2) {
+				printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+				printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
+			}
+			load_user_cs_desc(cpu, current->mm);
+			put_cpu();
+			return;
+		}
+	}
+	put_cpu();
+	if (print_fatal_signals) {
+		printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+		printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
+	}
+
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
 	force_sig(SIGSEGV, current);
 	return;
 
 gp_in_vm86:
+	put_cpu();
 	local_irq_enable();
 	handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
 	return;
 
 gp_in_kernel:
+	put_cpu();
 	if (!fixup_exception(regs)) {
 		if (notify_die(DIE_GPF, "general protection fault", regs,
 				error_code, 13, SIGSEGV) == NOTIFY_STOP)
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/vsyscall.lds.S linux-810/arch/i386/kernel/vsyscall.lds.S
--- linux-801/arch/i386/kernel/vsyscall.lds.S
+++ linux-810/arch/i386/kernel/vsyscall.lds.S
@@ -7,7 +7,7 @@
 
 SECTIONS
 {
-  . = VSYSCALL_BASE + SIZEOF_HEADERS;
+  . = SIZEOF_HEADERS;
 
   .hash           : { *(.hash) }		:text
   .dynsym         : { *(.dynsym) }
@@ -20,7 +20,7 @@ SECTIONS
      For the layouts to match, we need to skip more than enough
      space for the dynamic symbol table et al.  If this amount
      is insufficient, ld -shared will barf.  Just increase it here.  */
-  . = VSYSCALL_BASE + 0x400;
+  . = 0x400;
 
   .text           : { *(.text) }		:text =0x90909090
 
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/kernel/vsyscall-sysenter.S linux-810/arch/i386/kernel/vsyscall-sysenter.S
--- linux-801/arch/i386/kernel/vsyscall-sysenter.S
+++ linux-810/arch/i386/kernel/vsyscall-sysenter.S
@@ -24,11 +24,11 @@ __kernel_vsyscall:
 	/* 7: align return point with nop's to make disassembly easier */
 	.space 7,0x90
 
-	/* 14: System call restart point is here! (SYSENTER_RETURN - 2) */
+	/* 14: System call restart point is here! (SYSENTER_RETURN_OFFSET-2) */
 	jmp .Lenter_kernel
 	/* 16: System call normal return point is here! */
-	.globl SYSENTER_RETURN	/* Symbol used by entry.S.  */
-SYSENTER_RETURN:
+	.globl SYSENTER_RETURN_OFFSET	/* Symbol used by sysenter.c  */
+SYSENTER_RETURN_OFFSET:
 	pop %ebp
 .Lpop_ebp:
 	pop %edx
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/mm/init.c linux-810/arch/i386/mm/init.c
--- linux-801/arch/i386/mm/init.c
+++ linux-810/arch/i386/mm/init.c
@@ -400,7 +400,7 @@ u64 __supported_pte_mask = ~_PAGE_NX;
  * Control non executable mappings.
  *
  * on      Enable
- * off     Disable
+ * off     Disable (disables exec-shield too)
  */
 void __init noexec_setup(const char *str)
 {
@@ -410,6 +410,7 @@ void __init noexec_setup(const char *str
 	} else if (!strncmp(str,"off",3)) {
 		disable_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
+		exec_shield = 0;
 	}
 }
 
@@ -474,7 +475,10 @@ void __init paging_init(void)
 	set_nx();
 	if (nx_enabled)
 		printk("NX (Execute Disable) protection: active\n");
+	else
 #endif
+	if (exec_shield)
+		printk("Using x86 segment limits to approximate NX protection\n");
 
 	pagetable_init();
 
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/i386/mm/mmap.c linux-810/arch/i386/mm/mmap.c
--- linux-801/arch/i386/mm/mmap.c
+++ linux-810/arch/i386/mm/mmap.c
@@ -62,15 +62,17 @@ void arch_pick_mmap_layout(struct mm_str
 	 * Fall back to the standard layout if the personality
 	 * bit is set, or if the expected stack growth is unlimited:
 	 */
-	if (sysctl_legacy_va_layout ||
+	if ((exec_shield != 2) && (sysctl_legacy_va_layout ||
 			(current->personality & ADDR_COMPAT_LAYOUT) ||
-			current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
+			current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = arch_get_unmapped_area;
 		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base(mm);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		if (!(current->personality & READ_IMPLIES_EXEC))
+			mm->get_unmapped_exec_area = arch_get_unmapped_exec_area;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/ia64/ia32/binfmt_elf32.c linux-810/arch/ia64/ia32/binfmt_elf32.c
--- linux-801/arch/ia64/ia32/binfmt_elf32.c
+++ linux-810/arch/ia64/ia32/binfmt_elf32.c
@@ -272,7 +272,7 @@ elf32_set_personality (void)
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
 {
 	unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
 
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/x86_64/ia32/ia32_binfmt.c linux-810/arch/x86_64/ia32/ia32_binfmt.c
--- linux-801/arch/x86_64/ia32/ia32_binfmt.c
+++ linux-810/arch/x86_64/ia32/ia32_binfmt.c
@@ -395,7 +395,7 @@ int setup_arg_pages(struct linux_binprm 
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
 {
 	unsigned long map_addr;
 	struct task_struct *me = current; 
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/x86_64/kernel/process.c linux-810/arch/x86_64/kernel/process.c
--- linux-801/arch/x86_64/kernel/process.c
+++ linux-810/arch/x86_64/kernel/process.c
@@ -750,10 +750,3 @@ int dump_task_regs(struct task_struct *t
  
 	return 1;
 }
-
-unsigned long arch_align_stack(unsigned long sp)
-{
-	if (randomize_va_space)
-		sp -= get_random_int() % 8192;
-	return sp & ~0xf;
-}
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/x86_64/mm/Makefile linux-810/arch/x86_64/mm/Makefile
--- linux-801/arch/x86_64/mm/Makefile
+++ linux-810/arch/x86_64/mm/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the linux x86_64-specific parts of the memory manager.
 #
 
-obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
+obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o mmap.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_DISCONTIGMEM) += numa.o
 obj-$(CONFIG_K8_NUMA) += k8topology.o
diff -urNp --exclude-from=/home/davej/.exclude linux-801/arch/x86_64/mm/mmap.c linux-810/arch/x86_64/mm/mmap.c
--- linux-801/arch/x86_64/mm/mmap.c
+++ linux-810/arch/x86_64/mm/mmap.c
@@ -0,0 +1,95 @@
+/*
+ *  linux/arch/x86-64/mm/mmap.c
+ *
+ *  flexible mmap layout support
+ *
+ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * Started by Ingo Molnar <mingo at elte.hu>
+ */
+
+#include <linux/personality.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+
+/*
+ * Top of mmap area (just below the process stack).
+ *
+ * Leave an at least ~128 MB hole.
+ */
+#define MIN_GAP (128*1024*1024)
+#define MAX_GAP (TASK_SIZE/6*5)
+
+static inline unsigned long mmap_base(void)
+{
+	unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+
+	if (gap < MIN_GAP)
+		gap = MIN_GAP;
+	else if (gap > MAX_GAP)
+		gap = MAX_GAP;
+
+	return TASK_SIZE - (gap & PAGE_MASK);
+}
+
+static inline int mmap_is_legacy(void)
+{
+	/*
+	 * Force standard allocation for 64 bit programs.
+	 */
+	if (!test_thread_flag(TIF_IA32))
+		return 1;
+		
+	if (current->personality & ADDR_COMPAT_LAYOUT) 
+		return 1;
+	
+	if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
+		return 1;
+		
+	return sysctl_legacy_va_layout;
+}
+
+/*
+ * This function, called very early during the creation of a new
+ * process VM image, sets up which VM layout function to use:
+ */
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+	/*
+	 * Fall back to the standard layout if the personality
+	 * bit is set, or if the expected stack growth is unlimited:
+	 */
+	if (mmap_is_legacy()) {
+		mm->mmap_base = TASK_UNMAPPED_BASE;
+		mm->get_unmapped_area = arch_get_unmapped_area;
+		mm->unmap_area = arch_unmap_area;
+	} else {
+		mm->mmap_base = mmap_base();
+		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		mm->unmap_area = arch_unmap_area_topdown;
+	}
+}
+
+unsigned long arch_align_stack(unsigned long sp)
+{
+	if (current->flags & PF_RANDOMIZE)
+		sp -= get_random_int() % 8192;
+	return sp & ~0xf;
+}
+
diff -urNp --exclude-from=/home/davej/.exclude linux-801/drivers/char/random.c linux-810/drivers/char/random.c
--- linux-801/drivers/char/random.c
+++ linux-810/drivers/char/random.c
@@ -1600,13 +1600,18 @@ EXPORT_SYMBOL(secure_tcpv6_port_ephemera
  */
 unsigned int get_random_int(void)
 {
+	unsigned int val = 0;
+
+#ifdef CONFIG_X86_HAS_TSC
+	rdtscl(val);
+#endif
 	/*
 	 * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
 	 * every second, from the entropy pool (and thus creates a limited
 	 * drain on it), and uses halfMD4Transform within the second. We
 	 * also mix it with jiffies and the PID:
 	 */
-	return secure_ip_id(current->pid + jiffies);
+	return secure_ip_id(current->pid + jiffies + (int)val);
 }
 
 /*
diff -urNp --exclude-from=/home/davej/.exclude linux-801/fs/binfmt_elf.c linux-810/fs/binfmt_elf.c
--- linux-801/fs/binfmt_elf.c
+++ linux-810/fs/binfmt_elf.c
@@ -47,7 +47,7 @@
 
 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
 static int load_elf_library(struct file*);
-static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
+static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long);
 extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
 
 #ifndef elf_addr_t
@@ -285,20 +285,59 @@ create_elf_tables(struct linux_binprm *b
 #ifndef elf_map
 
 static unsigned long elf_map(struct file *filep, unsigned long addr,
-			struct elf_phdr *eppnt, int prot, int type)
+			     struct elf_phdr *eppnt, int prot, int type,
+			     unsigned long total_size)
 {
 	unsigned long map_addr;
+	unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
+	unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
+
+	addr = ELF_PAGESTART(addr);
+	size = ELF_PAGEALIGN(size);
 
 	down_write(&current->mm->mmap_sem);
-	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
-			   eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
-			   eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
+
+	/*
+	 * total_size is the size of the ELF (interpreter) image.
+	 * The _first_ mmap needs to know the full size, otherwise
+	 * randomization might put this image into an overlapping
+	 * position with the ELF binary image. (since size < total_size)
+	 * So we first map the 'big' image - and unmap the remainder at
+	 * the end. (which unmap is needed for ELF images with holes.)
+	 */
+	if (total_size) {
+		total_size = ELF_PAGEALIGN(total_size);
+		map_addr = do_mmap(filep, addr, total_size, prot, type, off);
+		if (!BAD_ADDR(map_addr))
+			do_munmap(current->mm, map_addr+size, total_size-size);
+	} else
+		map_addr = do_mmap(filep, addr, size, prot, type, off);
+		
 	up_write(&current->mm->mmap_sem);
-	return(map_addr);
+
+	return map_addr;
 }
 
 #endif /* !elf_map */
 
+static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
+{
+	int i, first_idx = -1, last_idx = -1;
+
+	for (i = 0; i < nr; i++)
+		if (cmds[i].p_type == PT_LOAD) {
+			last_idx = i;
+			if (first_idx == -1)
+				first_idx = i;
+		}
+
+	if (first_idx == -1)
+		return 0;
+
+	return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
+				ELF_PAGESTART(cmds[first_idx].p_vaddr);
+}
+
 /* This is much more generalized than the library routine read function,
    so we keep this separate.  Technically the library read function
    is only provided so that we can read a.out libraries that have
@@ -306,7 +345,8 @@ static unsigned long elf_map(struct file
 
 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
 				     struct file * interpreter,
-				     unsigned long *interp_load_addr)
+				     unsigned long *interp_load_addr,
+				     unsigned long no_base)
 {
 	struct elf_phdr *elf_phdata;
 	struct elf_phdr *eppnt;
@@ -314,6 +354,7 @@ static unsigned long load_elf_interp(str
 	int load_addr_set = 0;
 	unsigned long last_bss = 0, elf_bss = 0;
 	unsigned long error = ~0UL;
+	unsigned long total_size;
 	int retval, i, size;
 
 	/* First of all, some simple consistency checks */
@@ -352,6 +393,10 @@ static unsigned long load_elf_interp(str
 		goto out_close;
 	}
 
+	total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
+	if (!total_size)
+		goto out_close;
+
 	eppnt = elf_phdata;
 	for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
 	  if (eppnt->p_type == PT_LOAD) {
@@ -366,8 +411,11 @@ static unsigned long load_elf_interp(str
 	    vaddr = eppnt->p_vaddr;
 	    if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
 	    	elf_type |= MAP_FIXED;
+	    else if (no_base && interp_elf_ex->e_type == ET_DYN)
+		load_addr = -vaddr;
 
-	    map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
+	    map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type, total_size);
+	    total_size = 0;
 	    error = map_addr;
 	    if (BAD_ADDR(map_addr))
 	    	goto out_close;
@@ -527,7 +575,7 @@ static int load_elf_binary(struct linux_
 	unsigned long reloc_func_desc = 0;
 	char passed_fileno[6];
 	struct files_struct *files;
-	int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT;
+	int have_pt_gnu_stack, executable_stack;
 	unsigned long def_flags = 0;
 	struct {
 		struct elfhdr elf_ex;
@@ -683,6 +731,8 @@ static int load_elf_binary(struct linux_
 	}
 
 	elf_ppnt = elf_phdata;
+	executable_stack = EXSTACK_DEFAULT;
+
 	for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
 		if (elf_ppnt->p_type == PT_GNU_STACK) {
 			if (elf_ppnt->p_flags & PF_X)
@@ -693,6 +743,11 @@ static int load_elf_binary(struct linux_
 		}
 	have_pt_gnu_stack = (i < loc->elf_ex.e_phnum);
 
+	if (current->personality == PER_LINUX && exec_shield == 2) {
+		executable_stack = EXSTACK_DISABLE_X;
+		current->flags |= PF_RANDOMIZE;
+	}
+
 	/* Some simple consistency checks for the interpreter */
 	if (elf_interpreter) {
 		interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
@@ -746,6 +801,15 @@ static int load_elf_binary(struct linux_
 	if (retval)
 		goto out_free_dentry;
 
+#ifdef __i386__
+	/*
+	 * Turn off the CS limit completely if exec-shield disabled or
+	 * NX active:
+	 */
+	if (!exec_shield || executable_stack != EXSTACK_DISABLE_X || nx_enabled)
+		arch_add_exec_range(current->mm, -1);
+#endif
+
 	/* Discard our unneeded old files struct */
 	if (files) {
 		steal_locks(files);
@@ -764,7 +828,8 @@ static int load_elf_binary(struct linux_
 	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
 	   may depend on the personality.  */
 	SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
-	if (elf_read_implies_exec(loc->elf_ex, executable_stack))
+	if (exec_shield != 2 &&
+			elf_read_implies_exec(loc->elf_ex, executable_stack))
 		current->personality |= READ_IMPLIES_EXEC;
 
 	if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
@@ -792,10 +857,10 @@ static int load_elf_binary(struct linux_
 
 	current->mm->start_stack = bprm->p;
 
+
 	/* Now we do a little grungy work by mmaping the ELF image into
-	   the correct location in memory.  At this point, we assume that
-	   the image should be loaded at fixed address, not at a variable
-	   address. */
+	   the correct location in memory.
+	 */
 
 	for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
 		int elf_prot = 0, elf_flags;
@@ -839,16 +904,16 @@ static int load_elf_binary(struct linux_
 		elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
 
 		vaddr = elf_ppnt->p_vaddr;
-		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
+		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set)
 			elf_flags |= MAP_FIXED;
-		} else if (loc->elf_ex.e_type == ET_DYN) {
-			/* Try and get dynamic programs out of the way of the default mmap
-			   base, as well as whatever program they might try to exec.  This
-			   is because the brk will follow the loader, and is not movable.  */
+		else if (loc->elf_ex.e_type == ET_DYN)
+#ifdef __i386__
+			load_bias = 0;
+#else
 			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-		}
+#endif
 
-		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
+		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags, 0);
 		if (BAD_ADDR(error)) {
 			send_sig(SIGKILL, current, 0);
 			goto out_free_dentry;
@@ -925,7 +990,8 @@ static int load_elf_binary(struct linux_
 		else
 			elf_entry = load_elf_interp(&loc->interp_elf_ex,
 						    interpreter,
-						    &interp_load_addr);
+						    &interp_load_addr,
+						    load_bias);
 		if (BAD_ADDR(elf_entry)) {
 			printk(KERN_ERR "Unable to load interpreter %.128s\n",
 				elf_interpreter);
@@ -949,6 +1015,14 @@ static int load_elf_binary(struct linux_
 
 	set_binfmt(&elf_format);
 
+	/*
+	 * Map the vsyscall trampoline. This address is then passed via
+	 * AT_SYSINFO.
+	 */
+#ifdef __HAVE_ARCH_VSYSCALL
+	map_vsyscall();
+#endif
+
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
 	create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT),
@@ -962,6 +1036,10 @@ static int load_elf_binary(struct linux_
 	current->mm->end_data = end_data;
 	current->mm->start_stack = bprm->p;
 
+#ifdef __HAVE_ARCH_RANDOMIZE_BRK
+	if (current->flags & PF_RANDOMIZE)
+		randomize_brk(elf_brk);
+#endif
 	if (current->personality & MMAP_PAGE_ZERO) {
 		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
 		   and some applications "depend" upon this behavior.
diff -urNp --exclude-from=/home/davej/.exclude linux-801/fs/proc/array.c linux-810/fs/proc/array.c
--- linux-801/fs/proc/array.c
+++ linux-810/fs/proc/array.c
@@ -385,8 +385,12 @@ static int do_task_stat(struct task_stru
 	ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
 	read_unlock(&tasklist_lock);
 
-	if (!whole || num_threads<2)
-		wchan = get_wchan(task);
+	if (!whole || num_threads<2) {
+		wchan = 0;
+		if (current->uid == task->uid || current->euid == task->uid ||
+				capable(CAP_SYS_NICE))
+			wchan = get_wchan(task);
+	}
 	if (!whole) {
 		min_flt = task->min_flt;
 		maj_flt = task->maj_flt;
diff -urNp --exclude-from=/home/davej/.exclude linux-801/fs/proc/base.c linux-810/fs/proc/base.c
--- linux-801/fs/proc/base.c
+++ linux-810/fs/proc/base.c
@@ -143,7 +143,7 @@ static struct pid_entry tgid_base_stuff[
 	E(PROC_TGID_CMDLINE,   "cmdline", S_IFREG|S_IRUGO),
 	E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
 	E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
+	E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUSR),
 	E(PROC_TGID_MEM,       "mem",     S_IFREG|S_IRUSR|S_IWUSR),
 #ifdef CONFIG_SECCOMP
 	E(PROC_TGID_SECCOMP,   "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
@@ -179,7 +179,7 @@ static struct pid_entry tid_base_stuff[]
 	E(PROC_TID_CMDLINE,    "cmdline", S_IFREG|S_IRUGO),
 	E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
 	E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
-	E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
+	E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUSR),
 	E(PROC_TID_MEM,        "mem",     S_IFREG|S_IRUSR|S_IWUSR),
 #ifdef CONFIG_SECCOMP
 	E(PROC_TID_SECCOMP,    "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
diff -urNp --exclude-from=/home/davej/.exclude linux-801/fs/proc/task_mmu.c linux-810/fs/proc/task_mmu.c
--- linux-801/fs/proc/task_mmu.c
+++ linux-810/fs/proc/task_mmu.c
@@ -21,13 +21,23 @@ char *task_mem(struct mm_struct *mm, cha
 		"VmStk:\t%8lu kB\n"
 		"VmExe:\t%8lu kB\n"
 		"VmLib:\t%8lu kB\n"
-		"VmPTE:\t%8lu kB\n",
+		"VmPTE:\t%8lu kB\n"
+		"StaBrk:\t%08lx kB\n"
+		"Brk:\t%08lx kB\n"
+		"StaStk:\t%08lx kB\n"
+		,
 		(mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
 		mm->locked_vm << (PAGE_SHIFT-10),
 		get_mm_counter(mm, rss) << (PAGE_SHIFT-10),
 		data << (PAGE_SHIFT-10),
 		mm->stack_vm << (PAGE_SHIFT-10), text, lib,
-		(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
+		(PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
+		mm->start_brk, mm->brk, mm->start_stack);
+#if __i386__
+	if (!nx_enabled)
+		buffer += sprintf(buffer,
+				"ExecLim:\t%08lx\n", mm->context.exec_limit);
+#endif
 	return buffer;
 }
 
@@ -107,7 +117,13 @@ static int show_map(struct seq_file *m, 
 			map->vm_end,
 			flags & VM_READ ? 'r' : '-',
 			flags & VM_WRITE ? 'w' : '-',
-			flags & VM_EXEC ? 'x' : '-',
+			(flags & VM_EXEC
+#ifdef __i386__
+				|| (!nx_enabled &&
+				(map->vm_start < task->mm->context.exec_limit))
+#endif
+			)
+				? 'x' : '-',
 			flags & VM_MAYSHARE ? 's' : 'p',
 			map->vm_pgoff << PAGE_SHIFT,
 			MAJOR(dev), MINOR(dev), ino, &len);
@@ -121,8 +137,7 @@ static int show_map(struct seq_file *m, 
 		seq_path(m, file->f_vfsmnt, file->f_dentry, "");
 	} else {
 		if (mm) {
-			if (map->vm_start <= mm->start_brk &&
-						map->vm_end >= mm->brk) {
+			if (map->vm_end == mm->brk) {
 				pad_len_spaces(m, len);
 				seq_puts(m, "[heap]");
 			} else {
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-i386/desc.h linux-810/include/asm-i386/desc.h
--- linux-801/include/asm-i386/desc.h
+++ linux-810/include/asm-i386/desc.h
@@ -135,6 +135,20 @@ static inline unsigned long get_desc_bas
 	return base;
 }
 
+static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
+{
+	limit = (limit - 1) / PAGE_SIZE;
+	desc->a = limit & 0xffff;
+	desc->b = (limit & 0xf0000) | 0x00c0fb00;
+}
+
+#define load_user_cs_desc(cpu, mm) \
+    	per_cpu(cpu_gdt_table, (cpu))[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs
+
+extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_flush_exec_range(struct mm_struct *mm);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-i386/elf.h linux-810/include/asm-i386/elf.h
--- linux-801/include/asm-i386/elf.h
+++ linux-810/include/asm-i386/elf.h
@@ -9,6 +9,7 @@
 #include <asm/user.h>
 #include <asm/processor.h>
 #include <asm/system.h>		/* for savesegment */
+#include <asm/desc.h>
 
 #include <linux/utsname.h>
 
@@ -133,15 +134,22 @@ extern int dump_task_extended_fpu (struc
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
 
-#define VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
-#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
-#define VSYSCALL_ENTRY	((unsigned long) &__kernel_vsyscall)
 extern void __kernel_vsyscall;
+#define VSYSCALL_BASE	((unsigned long)current->mm->context.vdso)
+#define VSYSCALL_EHDR	((const struct elfhdr *) VSYSCALL_BASE)
+#define VSYSCALL_OFFSET	((unsigned long) &__kernel_vsyscall)
+#define VSYSCALL_ENTRY	(VSYSCALL_BASE + VSYSCALL_OFFSET)
 
-#define ARCH_DLINFO						\
-do {								\
-		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);	\
-		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);	\
+/* kernel-internal fixmap address: */
+#define __VSYSCALL_BASE	(__fix_to_virt(FIX_VSYSCALL))
+#define __VSYSCALL_EHDR	((const struct elfhdr *) __VSYSCALL_BASE)
+
+#define ARCH_DLINFO							\
+do {									\
+	if (VSYSCALL_BASE) {						\
+		NEW_AUX_ENT(AT_SYSINFO,	VSYSCALL_ENTRY);		\
+		NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);		\
+	}								\
 } while (0)
 
 /*
@@ -152,15 +160,15 @@ do {								\
  * Dumping its extra ELF program headers includes all the other information
  * a debugger needs to easily find how the vsyscall DSO was being used.
  */
-#define ELF_CORE_EXTRA_PHDRS		(VSYSCALL_EHDR->e_phnum)
+#define ELF_CORE_EXTRA_PHDRS		(__VSYSCALL_EHDR->e_phnum)
 #define ELF_CORE_WRITE_EXTRA_PHDRS					      \
 do {									      \
 	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+		(const struct elf_phdr *) (__VSYSCALL_BASE		      \
+					   + __VSYSCALL_EHDR->e_phoff);	      \
 	int i;								      \
 	Elf32_Off ofs = 0;						      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+	for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {		      \
 		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
 		if (phdr.p_type == PT_LOAD) {				      \
 			BUG_ON(ofs != 0);				      \
@@ -178,10 +186,10 @@ do {									      \
 #define ELF_CORE_WRITE_EXTRA_DATA					      \
 do {									      \
 	const struct elf_phdr *const vsyscall_phdrs =			      \
-		(const struct elf_phdr *) (VSYSCALL_BASE		      \
-					   + VSYSCALL_EHDR->e_phoff);	      \
+		(const struct elf_phdr *) (__VSYSCALL_BASE		      \
+					   + __VSYSCALL_EHDR->e_phoff);	      \
 	int i;								      \
-	for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {			      \
+	for (i = 0; i < __VSYSCALL_EHDR->e_phnum; ++i) {		      \
 		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
 			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
 				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
@@ -190,4 +198,10 @@ do {									      \
 
 #endif
 
+#define __HAVE_ARCH_RANDOMIZE_BRK
+extern void randomize_brk(unsigned long old_brk);
+
+#define __HAVE_ARCH_VSYSCALL
+extern void map_vsyscall(void);
+
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-i386/mmu.h linux-810/include/asm-i386/mmu.h
--- linux-801/include/asm-i386/mmu.h
+++ linux-810/include/asm-i386/mmu.h
@@ -7,11 +7,17 @@
  * we put the segment information here.
  *
  * cpu_vm_mask is used to optimize ldt flushing.
+ *
+ * exec_limit is used to track the range PROT_EXEC
+ * mappings span.
  */
 typedef struct { 
 	int size;
 	struct semaphore sem;
 	void *ldt;
+	struct desc_struct user_cs;
+	unsigned long exec_limit;
+	void *vdso;
 } mm_context_t;
 
 #endif
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-i386/pgalloc.h linux-810/include/asm-i386/pgalloc.h
--- linux-801/include/asm-i386/pgalloc.h
+++ linux-810/include/asm-i386/pgalloc.h
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <asm/processor.h>
 #include <asm/fixmap.h>
+#include <asm/desc.h>
 #include <linux/threads.h>
 #include <linux/mm.h>		/* for struct page */
 
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-i386/processor.h linux-810/include/asm-i386/processor.h
--- linux-801/include/asm-i386/processor.h
+++ linux-810/include/asm-i386/processor.h
@@ -303,7 +303,10 @@ extern int bootloader_type;
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
+#define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE/3)
+
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
@@ -485,6 +488,9 @@ static inline void load_esp0(struct tss_
 	regs->xcs = __USER_CS;					\
 	regs->eip = new_eip;					\
 	regs->esp = new_esp;					\
+	preempt_disable();					\
+	load_user_cs_desc(smp_processor_id(), current->mm);	\
+	preempt_enable();					\
 } while (0)
 
 /* Forward declaration, a strange C thing */
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-i386/thread_info.h linux-810/include/asm-i386/thread_info.h
--- linux-801/include/asm-i386/thread_info.h
+++ linux-810/include/asm-i386/thread_info.h
@@ -38,6 +38,7 @@ struct thread_info {
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
 						*/
+	void			*sysenter_return;
 	struct restart_block    restart_block;
 
 	unsigned long           previous_esp;   /* ESP of the previous stack in case
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-ia64/pgalloc.h linux-810/include/asm-ia64/pgalloc.h
--- linux-801/include/asm-ia64/pgalloc.h
+++ linux-810/include/asm-ia64/pgalloc.h
@@ -23,6 +23,10 @@
 #include <asm/mmu_context.h>
 #include <asm/processor.h>
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 /*
  * Very stupidly, we used to get new pgd's and pmd's, init their contents
  * to point to the NULL versions of the next level page table, later on
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-ppc/pgalloc.h linux-810/include/asm-ppc/pgalloc.h
--- linux-801/include/asm-ppc/pgalloc.h
+++ linux-810/include/asm-ppc/pgalloc.h
@@ -40,5 +40,10 @@ extern void pte_free(struct page *pte);
 
 #define check_pgt_cache()	do { } while (0)
 
+#define arch_add_exec_range(mm, limit)         do { ; } while (0)
+#define arch_flush_exec_range(mm)              do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)      do { ; } while (0)
+
+
 #endif /* _PPC_PGALLOC_H */
 #endif /* __KERNEL__ */
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-ppc64/pgalloc.h linux-810/include/asm-ppc64/pgalloc.h
--- linux-801/include/asm-ppc64/pgalloc.h
+++ linux-810/include/asm-ppc64/pgalloc.h
@@ -11,6 +11,11 @@
 
 extern kmem_cache_t *zero_cache;
 
+/* Dummy functions since we don't support execshield on ppc */
+#define arch_add_exec_range(mm, limit) do { ; } while (0)
+#define arch_flush_exec_range(mm)      do { ; } while (0)
+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
+
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-s390/pgalloc.h linux-810/include/asm-s390/pgalloc.h
--- linux-801/include/asm-s390/pgalloc.h
+++ linux-810/include/asm-s390/pgalloc.h
@@ -19,6 +19,10 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 
+#define arch_add_exec_range(mm, limit) do { ; } while (0)
+#define arch_flush_exec_range(mm)      do { ; } while (0)
+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
+
 #define check_pgt_cache()	do {} while (0)
 
 extern void diag10(unsigned long addr);
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-sparc/pgalloc.h linux-810/include/asm-sparc/pgalloc.h
--- linux-801/include/asm-sparc/pgalloc.h
+++ linux-810/include/asm-sparc/pgalloc.h
@@ -66,4 +66,8 @@ BTFIXUPDEF_CALL(void, pte_free, struct p
 #define pte_free(pte)		BTFIXUP_CALL(pte_free)(pte)
 #define __pte_free_tlb(tlb, pte)	pte_free(pte)
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 #endif /* _SPARC_PGALLOC_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-sparc64/pgalloc.h linux-810/include/asm-sparc64/pgalloc.h
--- linux-801/include/asm-sparc64/pgalloc.h
+++ linux-810/include/asm-sparc64/pgalloc.h
@@ -250,4 +250,8 @@ static inline void pte_free(struct page 
 #define pgd_free(pgd)		free_pgd_fast(pgd)
 #define pgd_alloc(mm)		get_pgd_fast()
 
+#define arch_add_exec_range(mm, limit)		do { ; } while (0)
+#define arch_flush_exec_range(mm)		do { ; } while (0)
+#define arch_remove_exec_range(mm, limit)	do { ; } while (0)
+
 #endif /* _SPARC64_PGALLOC_H */
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/asm-x86_64/pgalloc.h linux-810/include/asm-x86_64/pgalloc.h
--- linux-801/include/asm-x86_64/pgalloc.h
+++ linux-810/include/asm-x86_64/pgalloc.h
@@ -7,6 +7,13 @@
 #include <linux/threads.h>
 #include <linux/mm.h>
 
+#define arch_add_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+#define arch_flush_exec_range(mm) \
+		do { (void)(mm); } while (0)
+#define arch_remove_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+
 #define pmd_populate_kernel(mm, pmd, pte) \
 		set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
 #define pud_populate(mm, pud, pmd) \
--- linux-2.6.11/include/asm-x86_64/processor.h~	2005-05-18 14:02:29.000000000 -0400
+++ linux-2.6.11/include/asm-x86_64/processor.h	2005-05-18 14:03:14.000000000 -0400
@@ -160,7 +160,13 @@ static inline void clear_in_cr4 (unsigne
 /*
  * User space process size. 47bits minus one guard page.
  */
-#define TASK_SIZE	(0x800000000000UL - 4096)
+#define TASK_SIZE_64	(0x800000000000UL - 4096)
+#define TASK_SIZE	(test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE_64)
+
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
+
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/linux/mm.h linux-810/include/linux/mm.h
--- linux-801/include/linux/mm.h
+++ linux-810/include/linux/mm.h
@@ -728,7 +728,14 @@ extern struct vm_area_struct *copy_vma(s
 	unsigned long addr, unsigned long len, pgoff_t pgoff);
 extern void exit_mmap(struct mm_struct *);
 
-extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+extern unsigned long get_unmapped_area_prot(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, int);
+
+
+static inline unsigned long get_unmapped_area(struct file * file, unsigned long addr, 
+		unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	return get_unmapped_area_prot(file, addr, len, pgoff, flags, 0);	
+}
 
 extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
 	unsigned long len, unsigned long prot,
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/linux/resource.h linux-810/include/linux/resource.h
--- linux-801/include/linux/resource.h
+++ linux-810/include/linux/resource.h
@@ -52,8 +52,11 @@ struct rlimit {
 /*
  * Limit the stack by to some sane default: root can always
  * increase this limit if needed..  8MB seems reasonable.
+ *
+ * (2MB more to cover randomization effects.)
  */
-#define _STK_LIM	(8*1024*1024)
+#define _STK_LIM	(10*1024*1024)
+#define EXEC_STACK_BIAS	(2*1024*1024)
 
 /*
  * GPG wants 32kB of mlocked memory, to make sure pass phrases
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/linux/sched.h linux-810/include/linux/sched.h
--- linux-801/include/linux/sched.h
+++ linux-810/include/linux/sched.h
@@ -36,6 +36,8 @@
 #include <linux/seccomp.h>
 
 struct exec_domain;
+extern int exec_shield;
+extern int print_fatal_signals;
 
 /*
  * cloning flags:
@@ -197,6 +199,10 @@ extern int sysctl_max_map_count;
 extern unsigned long
 arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
 		       unsigned long, unsigned long);
+
+extern unsigned long
+arch_get_unmapped_exec_area(struct file *, unsigned long, unsigned long,
+		       unsigned long, unsigned long);
 extern unsigned long
 arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
@@ -212,6 +218,9 @@ struct mm_struct {
 	unsigned long (*get_unmapped_area) (struct file *filp,
 				unsigned long addr, unsigned long len,
 				unsigned long pgoff, unsigned long flags);
+	unsigned long (*get_unmapped_exec_area) (struct file *filp,
+				unsigned long addr, unsigned long len,
+				unsigned long pgoff, unsigned long flags);
 	void (*unmap_area) (struct vm_area_struct *area);
 	unsigned long mmap_base;		/* base of mmap area */
 	unsigned long free_area_cache;		/* first hole */
diff -urNp --exclude-from=/home/davej/.exclude linux-801/include/linux/sysctl.h linux-810/include/linux/sysctl.h
--- linux-801/include/linux/sysctl.h
+++ linux-810/include/linux/sysctl.h
@@ -84,6 +84,9 @@ enum
 
 	KERN_CAP_BSET=14,	/* int: capability bounding set */
 	KERN_PANIC=15,		/* int: panic timeout */
+	KERN_EXEC_SHIELD=1000,	/* int: exec-shield enabled (0/1/2) */
+	KERN_PRINT_FATAL=1001,	/* int: print fatal signals (0/1/2) */
+	KERN_VDSO=1002,		/* int: VDSO enabled (0/1) */
 	KERN_REALROOTDEV=16,	/* real root device to mount after initrd */
 
 	KERN_SPARC_REBOOT=21,	/* reboot command on Sparc */
diff -urNp --exclude-from=/home/davej/.exclude linux-801/kernel/signal.c linux-810/kernel/signal.c
--- linux-801/kernel/signal.c
+++ linux-810/kernel/signal.c
@@ -1193,6 +1193,37 @@ kill_proc_info(int sig, struct siginfo *
 	return error;
 }
 
+int print_fatal_signals = 0;
+
+static void print_fatal_signal(struct pt_regs *regs, int signr)
+{
+	printk("%s/%d: potentially unexpected fatal signal %d.\n",
+		current->comm, current->pid, signr);
+		
+#ifdef __i386__
+	printk("code at %08lx: ", regs->eip);
+	{
+		int i;
+		for (i = 0; i < 16; i++) {
+			unsigned char insn;
+
+			__get_user(insn, (unsigned char *)(regs->eip + i));
+			printk("%02x ", insn);
+		}
+	}
+#endif	
+	printk("\n");
+	show_regs(regs);
+}
+
+static int __init setup_print_fatal_signals(char *str)
+{
+	get_option (&str, &print_fatal_signals);
+
+	return 1;
+}
+
+__setup("print-fatal-signals=", setup_print_fatal_signals);
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1845,6 +1876,11 @@ relock:
 		if (!signr)
 			break; /* will return 0 */
 
+		if ((signr == SIGSEGV) && print_fatal_signals) {
+			spin_unlock_irq(&current->sighand->siglock);
+			print_fatal_signal(regs, signr);
+			spin_lock_irq(&current->sighand->siglock);
+		}
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
 			ptrace_signal_deliver(regs, cookie);
 
@@ -1940,6 +1976,8 @@ relock:
 		 * Anything else is fatal, maybe with a core dump.
 		 */
 		current->flags |= PF_SIGNALED;
+		if (print_fatal_signals)
+			print_fatal_signal(regs, signr);
 		if (sig_kernel_coredump(signr)) {
 			/*
 			 * If it was able to dump core, this kills all
diff -urNp --exclude-from=/home/davej/.exclude linux-801/kernel/sysctl.c linux-810/kernel/sysctl.c
--- linux-801/kernel/sysctl.c
+++ linux-810/kernel/sysctl.c
@@ -72,6 +72,19 @@ extern int proc_unknown_nmi_panic(ctl_ta
 				  void __user *, size_t *, loff_t *);
 #endif
 
+extern unsigned int vdso_enabled;
+
+int exec_shield = 1;
+
+static int __init setup_exec_shield(char *str)
+{
+        get_option (&str, &exec_shield);
+
+        return 1;
+}
+
+__setup("exec-shield=", setup_exec_shield);
+
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
@@ -275,6 +288,32 @@ static ctl_table kern_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 	{
+		.ctl_name	= KERN_EXEC_SHIELD,
+		.procname	= "exec-shield",
+		.data		= &exec_shield,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= KERN_PRINT_FATAL,
+		.procname	= "print-fatal-signals",
+		.data		= &print_fatal_signals,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#if __i386__
+	{
+		.ctl_name	= KERN_VDSO,
+		.procname	= "vdso",
+		.data		= &vdso_enabled,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#endif
+	{
 		.ctl_name	= KERN_CORE_USES_PID,
 		.procname	= "core_uses_pid",
 		.data		= &core_uses_pid,
diff -urNp --exclude-from=/home/davej/.exclude linux-801/mm/fremap.c linux-810/mm/fremap.c
--- linux-801/mm/fremap.c
+++ linux-810/mm/fremap.c
@@ -85,10 +85,12 @@ int install_page(struct mm_struct *mm, s
 	 * caller about it.
 	 */
 	err = -EINVAL;
-	inode = vma->vm_file->f_mapping->host;
-	size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	if (!page->mapping || page->index >= size)
-		goto err_unlock;
+	if (vma->vm_file) {
+		inode = vma->vm_file->f_mapping->host;
+		size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+		if (!page->mapping || page->index >= size)
+			goto err_unlock;
+	}
 
 	zap_pte(mm, vma, addr, pte);
 
diff -urNp --exclude-from=/home/davej/.exclude linux-801/mm/mmap.c linux-810/mm/mmap.c
--- linux-801/mm/mmap.c
+++ linux-810/mm/mmap.c
@@ -24,6 +24,7 @@
 #include <linux/mount.h>
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
+#include <linux/random.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -334,6 +335,8 @@ static inline void
 __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
 		struct vm_area_struct *prev, struct rb_node *rb_parent)
 {
+	if (vma->vm_flags & VM_EXEC)
+		arch_add_exec_range(mm, vma->vm_end);
 	if (prev) {
 		vma->vm_next = prev->vm_next;
 		prev->vm_next = vma;
@@ -438,6 +441,8 @@ __vma_unlink(struct mm_struct *mm, struc
 	rb_erase(&vma->vm_rb, &mm->mm_rb);
 	if (mm->mmap_cache == vma)
 		mm->mmap_cache = prev;
+	if (vma->vm_flags & VM_EXEC)
+		arch_remove_exec_range(mm, vma->vm_end);
 }
 
 /*
@@ -743,6 +748,8 @@ struct vm_area_struct *vma_merge(struct 
 		} else					/* cases 2, 5, 7 */
 			vma_adjust(prev, prev->vm_start,
 				end, prev->vm_pgoff, NULL);
+		if (prev->vm_flags & VM_EXEC)
+			arch_add_exec_range(mm, prev->vm_end);
 		return prev;
 	}
 
@@ -914,7 +921,7 @@ unsigned long do_mmap_pgoff(struct file 
 	/* Obtain the address to map to. we verify (or select) it and ensure
 	 * that it represents a valid section of the address space.
 	 */
-	addr = get_unmapped_area(file, addr, len, pgoff, flags);
+	addr = get_unmapped_area_prot(file, addr, len, pgoff, flags, prot & PROT_EXEC);
 	if (addr & ~PAGE_MASK)
 		return addr;
 
@@ -1293,9 +1300,10 @@ void arch_unmap_area_topdown(struct vm_a
 		area->vm_mm->free_area_cache = area->vm_mm->mmap_base;
 }
 
+
 unsigned long
-get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
-		unsigned long pgoff, unsigned long flags)
+get_unmapped_area_prot(struct file *file, unsigned long addr, unsigned long len,
+		unsigned long pgoff, unsigned long flags, int exec)
 {
 	if (flags & MAP_FIXED) {
 		unsigned long ret;
@@ -1315,7 +1315,11 @@ get_unmapped_area_prot(struct file *file
 	if (!(flags & MAP_FIXED)) {
 		unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
 
-		get_area = current->mm->get_unmapped_area;
+		if (exec && current->mm->get_unmapped_exec_area)
+			get_area = current->mm->get_unmapped_exec_area;
+		else
+			get_area = current->mm->get_unmapped_area;
+
 		if (file && file->f_op && file->f_op->get_unmapped_area)
 			get_area = file->f_op->get_unmapped_area;
 		addr = get_area(file, addr, len, pgoff, flags);
@@ -1350,7 +1350,71 @@ get_unmapped_area_prot(struct file *file
 	return addr;
 }
 
-EXPORT_SYMBOL(get_unmapped_area);
+EXPORT_SYMBOL(get_unmapped_area_prot);
+
+#define SHLIB_BASE             0x00111000
+
+unsigned long arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
+		unsigned long len0, unsigned long pgoff, unsigned long flags)
+{
+	unsigned long addr = addr0, len = len0;
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long tmp;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	if (!addr && !(flags & MAP_FIXED))
+		addr = randomize_range(SHLIB_BASE, 0x01000000, len);
+
+	if (addr) {
+		addr = PAGE_ALIGN(addr);
+		vma = find_vma(mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start)) {
+			return addr;
+		}
+	}
+
+	addr = SHLIB_BASE;
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+
+		if (!vma || addr + len <= vma->vm_start) {
+			/*
+			 * Must not let a PROT_EXEC mapping get into the
+			 * brk area:
+			 */
+			if (addr + len > mm->brk)
+				goto failed;
+
+			/*
+			 * Up until the brk area we randomize addresses
+			 * as much as possible:
+			 */
+			if (addr >= 0x01000000) {
+				tmp = randomize_range(0x01000000, mm->brk, len);
+				vma = find_vma(mm, tmp);
+				if (TASK_SIZE - len >= tmp &&
+				    (!vma || tmp + len <= vma->vm_start))
+					return tmp;
+			}
+			/*
+			 * Ok, randomization didnt work out - return
+			 * the result of the linear search:
+			 */
+			return addr;
+		}
+		addr = vma->vm_end;
+	}
+
+failed:
+	return current->mm->get_unmapped_area(filp, addr0, len0, pgoff, flags);
+}
+
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
@@ -1405,6 +1483,14 @@ out:
 	return prev ? prev->vm_next : vma;
 }
 
+static int over_stack_limit(unsigned long sz)
+{
+	if (sz < EXEC_STACK_BIAS)
+		return 0;
+	return (sz - EXEC_STACK_BIAS) >
+			current->signal->rlim[RLIMIT_STACK].rlim_cur;
+}
+
 /*
  * Verify that the stack growth is acceptable and
  * update accounting. This is shared with both the
@@ -1420,7 +1506,7 @@ static int acct_stack_growth(struct vm_a
 		return -ENOMEM;
 
 	/* Stack limit test */
-	if (size > rlim[RLIMIT_STACK].rlim_cur)
+	if (over_stack_limit(size))
 		return -ENOMEM;
 
 	/* mlock limit tests */
@@ -1760,10 +1846,14 @@ int split_vma(struct mm_struct * mm, str
 	if (new->vm_ops && new->vm_ops->open)
 		new->vm_ops->open(new);
 
-	if (new_below)
+	if (new_below) {
+		unsigned long old_end = vma->vm_end;
+
 		vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
 			((addr - new->vm_start) >> PAGE_SHIFT), new);
-	else
+		if (vma->vm_flags & VM_EXEC)
+			arch_remove_exec_range(mm, old_end);
+	} else
 		vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
 
 	return 0;
@@ -1981,6 +2071,7 @@ void exit_mmap(struct mm_struct *mm)
 	mm->rss = 0;
 	mm->total_vm = 0;
 	mm->locked_vm = 0;
+	arch_flush_exec_range(mm);
 
 	spin_unlock(&mm->page_table_lock);
 
diff -urNp --exclude-from=/home/davej/.exclude linux-801/mm/mprotect.c linux-810/mm/mprotect.c
--- linux-801/mm/mprotect.c
+++ linux-810/mm/mprotect.c
@@ -22,6 +22,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
@@ -105,7 +106,7 @@ mprotect_fixup(struct vm_area_struct *vm
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long oldflags = vma->vm_flags;
 	long nrpages = (end - start) >> PAGE_SHIFT;
-	unsigned long charged = 0;
+	unsigned long charged = 0, old_end = vma->vm_end;
 	pgprot_t newprot;
 	pgoff_t pgoff;
 	int error;
@@ -166,6 +167,8 @@ success:
 	 */
 	vma->vm_flags = newflags;
 	vma->vm_page_prot = newprot;
+	if (oldflags & VM_EXEC)
+		arch_remove_exec_range(current->mm, old_end);
 	change_protection(vma, start, end, newprot);
 	__vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
 	__vm_stat_account(mm, newflags, vma->vm_file, nrpages);
diff -urNp --exclude-from=/home/davej/.exclude linux-801/mm/mremap.c linux-810/mm/mremap.c
--- linux-801/mm/mremap.c
+++ linux-810/mm/mremap.c
@@ -398,8 +398,8 @@ unsigned long do_mremap(unsigned long ad
 			if (vma->vm_flags & VM_MAYSHARE)
 				map_flags |= MAP_SHARED;
 
-			new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
-						vma->vm_pgoff, map_flags);
+			new_addr = get_unmapped_area_prot(vma->vm_file, 0, new_len, 
+				vma->vm_pgoff, map_flags, vma->vm_flags & VM_EXEC);
 			ret = new_addr;
 			if (new_addr & ~PAGE_MASK)
 				goto out;
--- linux-2.6.11/arch/x86_64/mm/fault.c
+++ linux-2.6.11/arch/x86_64/mm/fault.c
@@ -74,7 +74,7 @@ static noinline int is_prefetch(struct p
 	instr = (unsigned char *)convert_rip_to_linear(current, regs);
 	max_instr = instr + 15;
 
-	if ((regs->cs & 3) != 0 && instr >= (unsigned char *)TASK_SIZE)
+	if ((regs->cs & 3) != 0 && instr >= (unsigned char *)TASK_SIZE_64)
 		return 0;
 
 	while (scan_more && instr < max_instr) { 
@@ -350,7 +350,7 @@ asmlinkage void do_page_fault(struct pt_
 	 * (error_code & 4) == 0, and that the fault was not a
 	 * protection error (error_code & 1) == 0.
 	 */
-	if (unlikely(address >= TASK_SIZE)) {
+	if (unlikely(address >= TASK_SIZE_64)) {
 		if (!(error_code & 5) &&
 		      ((address >= VMALLOC_START && address < VMALLOC_END) ||
 		       (address >= MODULES_VADDR && address < MODULES_END))) {
--- linux-2.6.11/arch/i386/kernel/traps.c.~1~
+++ linux-2.6.11/arch/i386/kernel/traps.c
@@ -457,17 +457,89 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", inv
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
-DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+
 
 /*
+ * lazy-check for CS validity on exec-shield binaries:
+ *
  * the original non-exec stack patch was written by
  * Solar Designer <solar at openwall.com>. Thanks!
  */
+static int
+check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code)
+{
+	struct desc_struct *desc1, *desc2;
+	struct vm_area_struct *vma;
+	unsigned long limit;
+
+	if (current->mm == NULL)
+		return 0;
+
+	limit = -1UL;
+	if (current->mm->context.exec_limit != -1UL) {
+		limit = PAGE_SIZE;
+		spin_lock(&current->mm->page_table_lock);
+		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+		spin_unlock(&current->mm->page_table_lock);
+		if (limit >= TASK_SIZE)
+			limit = -1UL;
+		current->mm->context.exec_limit = limit;
+	}
+	set_user_cs(&current->mm->context.user_cs, limit);
+
+	desc1 = &current->mm->context.user_cs;
+	desc2 = per_cpu(cpu_gdt_table, cpu) + GDT_ENTRY_DEFAULT_USER_CS;
+
+	if (desc1->a != desc2->a || desc1->b != desc2->b) {
+		/*
+		 * The CS was not in sync - reload it and retry the
+		 * instruction. If the instruction still faults then
+		 * we won't hit this branch next time around.
+		 */
+		if (print_fatal_signals >= 2) {
+			printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+			printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
+		}
+		load_user_cs_desc(cpu, current->mm);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * The fixup code for errors in iret jumps to here (iret_exc).  It loses
+ * the original trap number and error code.  The bogus trap 32 and error
+ * code 0 are what the vanilla kernel delivers via:
+ * DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+ *
+ * In case of a general protection fault in the iret instruction, we
+ * need to check for a lazy CS update for exec-shield.
+ */
+fastcall void do_iret_error(struct pt_regs *regs, long error_code)
+{
+	int ok = check_lazy_exec_limit(get_cpu(), regs, error_code);
+	put_cpu();
+	if (!ok && notify_die(DIE_TRAP, "iret exception", regs,
+			      error_code, 32, SIGSEGV) != NOTIFY_STOP) {
+		siginfo_t info;
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		info.si_code = ILL_BADSTK;
+		info.si_addr = 0;
+		do_trap(32, SIGSEGV, "iret exception", 0, regs, error_code,
+			&info);
+	}
+}
+
 fastcall void do_general_protection(struct pt_regs * regs, long error_code)
 {
 	int cpu = get_cpu();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
 	struct thread_struct *thread = &current->thread;
+	int ok;
 
 	/*
 	 * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
@@ -500,42 +572,13 @@ fastcall void do_general_protection(stru
 	if (!(regs->xcs & 3))
 		goto gp_in_kernel;
 
-	/*
-	 * lazy-check for CS validity on exec-shield binaries:
-	 */
-	if (current->mm) {
-		struct desc_struct *desc1, *desc2;
-		struct vm_area_struct *vma;
-		unsigned long limit = PAGE_SIZE;
-		
-		spin_lock(&current->mm->page_table_lock);
-		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
-			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
-				limit = vma->vm_end;
-		spin_unlock(&current->mm->page_table_lock);
+	ok = check_lazy_exec_limit(cpu, regs, error_code);
 
-		current->mm->context.exec_limit = limit;
-		set_user_cs(&current->mm->context.user_cs, limit);
+	put_cpu();
 
-		desc1 = &current->mm->context.user_cs;
-		desc2 = per_cpu(cpu_gdt_table, cpu) + GDT_ENTRY_DEFAULT_USER_CS;
+	if (ok)
+		return;
 
-		/*
-		 * The CS was not in sync - reload it and retry the
-		 * instruction. If the instruction still faults then
-		 * we wont hit this branch next time around.
-		 */
-		if (desc1->a != desc2->a || desc1->b != desc2->b) {
-			if (print_fatal_signals >= 2) {
-				printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
-				printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
-			}
-			load_user_cs_desc(cpu, current->mm);
-			put_cpu();
-			return;
-		}
-	}
-	put_cpu();
 	if (print_fatal_signals) {
 		printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
 		printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
--- 1/mm/mmap.c.orig
+++ 2/mm/mmap.c
@@ -1303,7 +1303,7 @@ unsigned long arch_get_unmapped_exec_are
 			 * as much as possible:
 			 */
 			if (addr >= 0x01000000) {
-				tmp = randomize_range(0x01000000, mm->brk, len);
+				tmp = randomize_range(0x01000000, PAGE_ALIGN(max(mm->start_brk, 0x08000000)), len);
 				vma = find_vma(mm, tmp);
 				if (TASK_SIZE - len >= tmp &&
 				    (!vma || tmp + len <= vma->vm_start))


linux-2.6.11-firedire-slab-corruptor.patch:
 sbp2.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.11-firedire-slab-corruptor.patch ---
--- 1/drivers/ieee1394/sbp2.c~	2005-05-29 14:00:06.000000000 -0300
+++ 2/drivers/ieee1394/sbp2.c	2005-05-29 20:04:07.000000000 -0300
@@ -745,7 +745,8 @@
 	list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids);
 
 	/* Register our host with the SCSI stack. */
-	scsi_host = scsi_host_alloc(&scsi_driver_template, 0);
+	scsi_host = scsi_host_alloc(&scsi_driver_template,
+				    sizeof (unsigned long));
 	if (!scsi_host) {
 		SBP2_ERR("failed to register scsi host");
 		goto failed_alloc;

linux-2.6.11-i2c-config.patch:
 Kconfig |   30 +++++++++++++++---------------
 1 files changed, 15 insertions(+), 15 deletions(-)

--- NEW FILE linux-2.6.11-i2c-config.patch ---
--- linux-2.6.11/drivers/i2c/busses/Kconfig~	2005-04-16 01:05:36.000000000 -0400
+++ linux-2.6.11/drivers/i2c/busses/Kconfig	2005-04-16 01:06:09.000000000 -0400
@@ -376,7 +376,7 @@ config SCx200_I2C_SDA
 
 config SCx200_ACB
 	tristate "NatSemi SCx200 ACCESS.bus"
-	depends on I2C && PCI
+	depends on SCx200 && PCI
 	help
 	  Enable the use of the ACCESS.bus controllers of a SCx200 processor.
 
--- linux-2.6.11/drivers/i2c/busses/Kconfig~	2005-04-16 01:07:57.000000000 -0400
+++ linux-2.6.11/drivers/i2c/busses/Kconfig	2005-04-16 01:11:10.000000000 -0400
@@ -7,7 +7,7 @@ menu "I2C Hardware Bus support"
 
 config I2C_ALI1535
 	tristate "ALI 1535"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on X86 && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the SMB
 	  Host controller on Acer Labs Inc. (ALI) M1535 South Bridges.  The SMB
@@ -19,7 +19,7 @@ config I2C_ALI1535
 
 config I2C_ALI1563
 	tristate "ALI 1563"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on X86 && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the SMB
 	  Host controller on Acer Labs Inc. (ALI) M1563 South Bridges.  The SMB
@@ -31,7 +31,7 @@ config I2C_ALI1563
 
 config I2C_ALI15X3
 	tristate "ALI 15x3"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on (X86 || MIPS) && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the
 	  Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
@@ -41,7 +41,7 @@ config I2C_ALI15X3
 
 config I2C_AMD756
 	tristate "AMD 756/766/768/8111 and nVidia nForce"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on (X86 || PPC64 || ALPHA )&& I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the AMD
 	  756/766/768 mainboard I2C interfaces.  The driver also includes
@@ -53,7 +53,7 @@ config I2C_AMD756
 
 config I2C_AMD756_S4882
 	tristate "SMBus multiplexing on the Tyan S4882"
-	depends on I2C_AMD756 && EXPERIMENTAL
+	depends on X86 && I2C_AMD756 && EXPERIMENTAL
 	help
 	  Enabling this option will add specific SMBus support for the Tyan
 	  S4882 motherboard.  On this 4-CPU board, the SMBus is multiplexed
@@ -66,7 +66,7 @@ config I2C_AMD756_S4882
 
 config I2C_AMD8111
 	tristate "AMD 8111"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on (X86 || PPC64) && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the
 	  second (SMBus 2.0) AMD 8111 mainboard I2C interface.
@@ -109,7 +109,7 @@ config I2C_HYDRA
 
 config I2C_I801
 	tristate "Intel 82801 (ICH)"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on X86 && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  801 family of mainboard I2C interfaces.  Specifically, the following
@@ -129,7 +129,7 @@ config I2C_I801
 
 config I2C_I810
 	tristate "Intel 810/815"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on X86 && I2C && PCI && EXPERIMENTAL
 	select I2C_ALGOBIT
 	help
 	  If you say yes to this option, support will be included for the Intel
@@ -145,7 +145,7 @@ config I2C_I810
 
 config I2C_PIIX4
 	tristate "Intel PIIX4"
-	depends on I2C && PCI
+	depends on (X86 || PPC || PPC64 || MIPS || MIPS64) && I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  PIIX4 family of mainboard I2C interfaces.  Specifically, the following
@@ -437,7 +437,7 @@ config I2C_STUB
 
 config I2C_VIA
 	tristate "VIA 82C586B"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on (X86 || PPC) && I2C && PCI && EXPERIMENTAL
 	select I2C_ALGOBIT
 	help
 	  If you say yes to this option, support will be included for the VIA
@@ -448,7 +448,7 @@ config I2C_VIA
 
 config I2C_VIAPRO
 	tristate "VIA 82C596/82C686/823x"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on (X86 || PPC) && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the VIA
 	  82C596/82C686/823x I2C interfaces.  Specifically, the following 
--- linux-2.6.11/drivers/i2c/busses/Kconfig~	2005-04-16 01:16:48.000000000 -0400
+++ linux-2.6.11/drivers/i2c/busses/Kconfig	2005-04-16 01:17:11.000000000 -0400
@@ -387,7 +387,7 @@ config SCx200_ACB
 
 config I2C_SIS5595
 	tristate "SiS 5595"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on X86 && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS5595 SMBus (a subset of I2C) interface.
@@ -397,7 +397,7 @@ config I2C_SIS5595
 
 config I2C_SIS630
 	tristate "SiS 630/730"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on X86 && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS630 and SiS730 SMBus (a subset of I2C) interface.
@@ -407,7 +407,7 @@ config I2C_SIS630
 
 config I2C_SIS96X
 	tristate "SiS 96x"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on X86 && I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the SiS
 	  96x SMBus (a subset of I2C) interfaces.  Specifically, the following

linux-2.6.11-isdn-icn-nodev.patch:
 icn.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6.11-isdn-icn-nodev.patch ---
--- linux-2.6.11/drivers/isdn/icn/icn.c~	2005-04-18 19:33:47.000000000 -0400
+++ linux-2.6.11/drivers/isdn/icn/icn.c	2005-04-18 19:34:16.000000000 -0400
@@ -1670,8 +1670,8 @@ static void __exit icn_exit(void)
 			for (i = 0; i < ICN_BCH; i++)
 				icn_free_queue(card, i);
 		}
-		card = card->next;
 		spin_unlock_irqrestore(&card->lock, flags);
+		card = card->next;
 	}
 	card = cards;
 	cards = NULL;

linux-2.6.11-kallsyms-extra-text.patch:
 arch/ppc/kernel/vmlinux.lds.S  |    2 ++
 include/asm-generic/sections.h |    2 ++
 kernel/kallsyms.c              |   10 +++++++++-
 scripts/kallsyms.c             |   20 +++++++++++++-------
 4 files changed, 26 insertions(+), 8 deletions(-)

--- NEW FILE linux-2.6.11-kallsyms-extra-text.patch ---
The PPC32 kernel puts platform-specific functions into separate sections
so that unneeded parts of it can be freed when we've booted and actually
worked out what we're running on today. 

This makes kallsyms ignore those functions, because they're not between
_[se]text or _[se]inittext. Rather than teaching kallsyms about the
various pmac/chrp/etc sections, this patch adds '_[se]extratext' markers
for kallsyms.

Signed-off-by: David Woodhouse <dwmw2 at infradead.org> 

--- linux-2.6.11/arch/ppc/kernel/vmlinux.lds.S~	2005-05-01 10:43:10.000000000 +0100
+++ linux-2.6.11/arch/ppc/kernel/vmlinux.lds.S	2005-05-02 08:06:52.000000000 +0100
@@ -147,6 +147,7 @@ SECTIONS
   __init_end = .;
 
   . = ALIGN(4096);
+  _sextratext = .;
   __pmac_begin = .;
   .pmac.text : { *(.pmac.text) }
   .pmac.data : { *(.pmac.data) }
@@ -173,6 +174,7 @@ SECTIONS
   .openfirmware.data : { *(.openfirmware.data) }
   . = ALIGN(4096);
   __openfirmware_end = .;
+  _eextratext = .;
 
   __bss_start = .;
   .bss :
--- linux-2.6.11/include/asm-generic/sections.h~	2005-03-02 07:37:31.000000000 +0000
+++ linux-2.6.11/include/asm-generic/sections.h	2005-05-02 08:43:04.000000000 +0100
@@ -8,6 +8,8 @@ extern char _data[], _sdata[], _edata[];
 extern char __bss_start[], __bss_stop[];
 extern char __init_begin[], __init_end[];
 extern char _sinittext[], _einittext[];
+extern char _sextratext[] __attribute__((weak));
+extern char _eextratext[] __attribute__((weak));
 extern char _end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
--- linux-2.6.11/scripts/kallsyms.c~	2005-03-02 07:38:33.000000000 +0000
+++ linux-2.6.11/scripts/kallsyms.c	2005-05-02 08:09:11.000000000 +0100
@@ -67,7 +67,7 @@ struct sym_entry {
 
 static struct sym_entry *table;
 static int size, cnt;
-static unsigned long long _stext, _etext, _sinittext, _einittext;
+static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
 static int all_symbols = 0;
 
 struct token {
@@ -132,6 +132,10 @@ read_symbol(FILE *in, struct sym_entry *
 		_sinittext = s->addr;
 	else if (strcmp(str, "_einittext") == 0)
 		_einittext = s->addr;
+	else if (strcmp(str, "_sextratext") == 0)
+		_sextratext = s->addr;
+	else if (strcmp(str, "_eextratext") == 0)
+		_eextratext = s->addr;
 	else if (toupper(s->type) == 'A')
 	{
 		/* Keep these useful absolute symbols */
@@ -182,16 +186,18 @@ symbol_valid(struct sym_entry *s)
 	 * and inittext sections are discarded */
 	if (!all_symbols) {
 		if ((s->addr < _stext || s->addr > _etext)
-		    && (s->addr < _sinittext || s->addr > _einittext))
+		    && (s->addr < _sinittext || s->addr > _einittext) 
+		    && (s->addr < _sextratext || s->addr > _eextratext))
 			return 0;
 		/* Corner case.  Discard any symbols with the same value as
-		 * _etext or _einittext, they can move between pass 1 and 2
-		 * when the kallsyms data is added.  If these symbols move then
-		 * they may get dropped in pass 2, which breaks the kallsyms
-		 * rules.
+		 * _etext _einittext or _eextratext; they can move between pass 
+		 * 1 and 2 when the kallsyms data is added.  If these symbols 
+		 * move then they may get dropped in pass 2, which breaks the
+		 * kallsyms rules.
 		 */
 		if ((s->addr == _etext && strcmp(s->sym + 1, "_etext")) ||
-		    (s->addr == _einittext && strcmp(s->sym + 1, "_einittext")))
+		    (s->addr == _einittext && strcmp(s->sym + 1, "_einittext")) ||
+		    (s->addr == _eextratext && strcmp(s->sym + 1, "_eextratext")))
 			return 0;
 	}
 
--- linux-2.6.11/kernel/kallsyms.c~	2005-05-01 10:37:45.000000000 +0100
+++ linux-2.6.11/kernel/kallsyms.c	2005-05-02 08:42:59.000000000 +0100
@@ -46,6 +46,14 @@ static inline int is_kernel_inittext(uns
 	return 0;
 }
 
+static inline int is_kernel_extratext(unsigned long addr)
+{
+	if (addr >= (unsigned long)_sextratext
+	    && addr <= (unsigned long)_eextratext)
+		return 1;
+	return 0;
+}
+
 static inline int is_kernel_text(unsigned long addr)
 {
 	if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)
@@ -169,7 +177,7 @@ const char *kallsyms_lookup(unsigned lon
 	namebuf[0] = 0;
 
 	if ((all_var && is_kernel(addr)) ||
-	    (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr)))) {
+	    (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) || is_kernel_extratext(addr)))) {
 		unsigned long symbol_end=0;
 
 		/* do a binary search on the sorted kallsyms_addresses array */


-- 
dwmw2

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6.11-libata-promise-pata-on-sata.patch:
 drivers/scsi/libata-core.c  |    1 
 drivers/scsi/sata_promise.c |   56 +++++++++++++++++++++++++++++++++++++++++---
 include/linux/libata.h      |    1 
 3 files changed, 55 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6.11-libata-promise-pata-on-sata.patch ---

This will update the following files:

 drivers/scsi/libata-core.c   |    1 ++
 drivers/scsi/libata.h        |    2 
 drivers/scsi/sata_promise.c  |   56 +++

through these ChangeSets:

<erikbenada:yahoo.ca>:
  o [libata sata_promise] support PATA ports on SATA controllers

diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c	2004-11-14 22:37:46 -05:00
+++ b/drivers/scsi/libata-core.c	2004-11-14 22:37:46 -05:00
@@ -3181,6 +3211,7 @@
 	ap->mwdma_mask = ent->mwdma_mask;
 	ap->udma_mask = ent->udma_mask;
 	ap->flags |= ent->host_flags;
+	ap->flags |= ent->port_flags[port_no];
 	ap->ops = ent->port_ops;
 	ap->cbl = ATA_CBL_NONE;
 	ap->active_tag = ATA_TAG_POISON;
diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
--- a/drivers/scsi/sata_promise.c	2004-11-14 22:37:46 -05:00
+++ b/drivers/scsi/sata_promise.c	2004-11-14 22:37:46 -05:00
@@ -79,6 +79,8 @@
 static int pdc_port_start(struct ata_port *ap);
 static void pdc_port_stop(struct ata_port *ap);
 static void pdc_phy_reset(struct ata_port *ap);
+static void pdc_pata_phy_reset(struct ata_port *ap);
+static void pdc_pata_cbl_detect(struct ata_port *ap);
 static void pdc_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
 static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
@@ -127,7 +129,7 @@
 	/* board_2037x */
 	{
 		.sht		= &pdc_ata_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+		.host_flags	= /* ATA_FLAG_SATA | */ ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
@@ -244,7 +246,35 @@
 static void pdc_phy_reset(struct ata_port *ap)
 {
 	pdc_reset_port(ap);
-	sata_phy_reset(ap);
+	if (ap->flags & ATA_FLAG_SATA)
+		sata_phy_reset(ap);
+	else
+		pdc_pata_phy_reset(ap);
+}
+
+static void pdc_pata_cbl_detect(struct ata_port *ap)
+{
+	u8 tmp;
+	void *mmio = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
+
+	tmp = readb(mmio);
+	
+	if (tmp & 0x01)
+	{
+		ap->cbl = ATA_CBL_PATA40;
+		ap->udma_mask &= ATA_UDMA_MASK_40C;
+	}
+	else
+		ap->cbl = ATA_CBL_PATA80;
+}
+		
+static void pdc_pata_phy_reset(struct ata_port *ap)
+{
+	pdc_pata_cbl_detect(ap);
+
+	ata_port_probe(ap);
+	
+	ata_bus_reset(ap);
 }
 
 static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
@@ -547,6 +577,7 @@
 	void *mmio_base;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
 	int rc;
+	u8 tmp;
 
 	if (!printed_version++)
 		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
@@ -605,6 +636,9 @@
 	probe_ent->port[0].scr_addr = base + 0x400;
 	probe_ent->port[1].scr_addr = base + 0x500;
 
+	probe_ent->port_flags[0] = ATA_FLAG_SATA;
+	probe_ent->port_flags[1] = ATA_FLAG_SATA;
+	
 	/* notice 4-port boards */
 	switch (board_idx) {
 	case board_20319:
@@ -615,9 +649,25 @@
 
 		probe_ent->port[2].scr_addr = base + 0x600;
 		probe_ent->port[3].scr_addr = base + 0x700;
+	
+		probe_ent->port_flags[2] = ATA_FLAG_SATA;
+		probe_ent->port_flags[3] = ATA_FLAG_SATA;
 		break;
 	case board_2037x:
-       		probe_ent->n_ports = 2;
+		/* Some boards have also PATA port */
+		tmp = readb(mmio_base + PDC_FLASH_CTL+1);
+		if (!(tmp & 0x80))
+		{
+			probe_ent->n_ports = 3;
+			
+			pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
+
+			probe_ent->port_flags[2] = ATA_FLAG_SLAVE_POSS;
+			
+			printk(KERN_INFO DRV_NAME " PATA port found\n");
+		}
+		else
+       			probe_ent->n_ports = 2;
 		break;
 	default:
 		BUG();
diff -Nru a/include/linux/libata.h b/include/linux/libata.h
--- a/include/linux/libata.h	2004-11-14 22:37:46 -05:00
+++ b/include/linux/libata.h	2004-11-14 22:37:46 -05:00
@@ -204,6 +204,7 @@
 	unsigned long		irq;
 	unsigned int		irq_flags;
 	unsigned long		host_flags;
+	unsigned long		port_flags[ATA_MAX_PORTS];
 	void __iomem		*mmio_base;
 	void			*private_data;
 };

linux-2.6.11-mac-mini-sound.patch:
 Makefile   |    2 
 pmac.c     |    8 +
 pmac.h     |    4 
 powermac.c |    7 +
 toonie.c   |  380 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 398 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6.11-mac-mini-sound.patch ---
>From linuxppc-dev-bounces at ozlabs.org Thu Apr 14 03:16:03 2005
Return-path: <linuxppc-dev-bounces at ozlabs.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Thu, 14 Apr 2005 03:16:03 +0100
Received: from [2002:d592:9a28::1] (helo=pentafluge.infradead.org) by
	baythorne.infradead.org with esmtps (Exim 4.43 #1 (Red Hat Linux)) id
	1DLttj-0007Ma-1b for dwmw2 at baythorne.infradead.org; Thu, 14 Apr 2005
	03:16:03 +0100
Received: from ozlabs.org ([203.10.76.45]) by pentafluge.infradead.org with
	esmtps (Exim 4.43 #1 (Red Hat Linux)) id 1DLttF-0005uw-Es for
	dwmw2 at infradead.org; Thu, 14 Apr 2005 03:16:02 +0100
Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix)
	with ESMTP id 8313867B6F; Thu, 14 Apr 2005 12:15:27 +1000 (EST)
X-Original-To: linuxppc-dev at ozlabs.org
Delivered-To: linuxppc-dev at ozlabs.org
Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using
	TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not
	present a certificate) by ozlabs.org (Postfix) with ESMTP id 905C267B39 for
	<linuxppc-dev at ozlabs.org>; Thu, 14 Apr 2005 12:15:25 +1000 (EST)
Received: from gaston (localhost [127.0.0.1]) by gate.crashing.org
	(8.12.8/8.12.8) with ESMTP id j3E2AagJ031501; Wed, 13 Apr 2005 21:10:37
	-0500
From: Benjamin Herrenschmidt <benh at kernel.crashing.org>
To: Andrew Morton <akpm at osdl.org>
Content-Type: text/plain
Date: Thu, 14 Apr 2005 12:14:37 +1000
Message-Id: <1113444877.5515.44.camel at gaston>
Mime-Version: 1.0
X-Mailer: Evolution 2.0.4 
Cc: linuxppc-dev list <linuxppc-dev at ozlabs.org>, "debian-powerpc at lists.debian.org" <debian-powerpc at lists.debian.org>, alsa-devel at lists.sourceforge.net
Subject: [PATCH] ppc32: add sound support for Mac Mini
X-BeenThere: linuxppc-dev at ozlabs.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>
List-Unsubscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev at ozlabs.org>
List-Help: <mailto:linuxppc-dev-request at ozlabs.org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=subscribe>
Sender: linuxppc-dev-bounces at ozlabs.org
Errors-To: linuxppc-dev-bounces at ozlabs.org
X-Spam-Score: 1.8 (+)
X-Spam-Report: SpamAssassin version 2.63 on pentafluge.infradead.org
	summary: Content analysis details:   (1.8 points, 5.0 required) pts rule
	name              description ---- ----------------------
	-------------------------------------------------- 1.8 DOMAIN_BODY         
	  BODY: Domain registration spam body
X-Evolution-Source: imap://dwmw2@pentafluge.infradead.org/
Content-Transfer-Encoding: 8bit

Hi !

This patch applies on top of my previous g5 related sound patches and
adds support for the Mac Mini to the PowerMac Alsa driver.

However, I haven't found any kind of HW support for volume control on
this machine. If it exist, it's well hidden. That means that you
probably want to make sure you use software with the ability to do soft
volume control, or use Alsa 0.9 pre-release with the softvol plugin.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>

Index: linux-work/sound/ppc/toonie.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-work/sound/ppc/toonie.c	2005-04-14 12:13:17.000000000 +1000
@@ -0,0 +1,380 @@
+/*
+ * Mac Mini "toonie" mixer control
+ *
+ * Copyright (c) 2005 by Benjamin Herrenschmidt <benh at kernel.crashing.org>
+ *
+ *   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.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <linux/kmod.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <sound/core.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include "pmac.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+struct pmac_gpio {
+	unsigned int addr;
+	u8 active_val;
+	u8 inactive_val;
+	u8 active_state;
+};
+
+struct pmac_toonie
+{
+	struct pmac_gpio	hp_detect_gpio;
+	struct pmac_gpio	hp_mute_gpio;
+	struct pmac_gpio	amp_mute_gpio;
+	int			hp_detect_irq;
+	int			auto_mute_notify;
+	struct work_struct	detect_work;
+};
+
+
+/*
+ * gpio access
+ */
+#define do_gpio_write(gp, val) \
+	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
+#define do_gpio_read(gp) \
+	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
+#define tumbler_gpio_free(gp) /* NOP */
+
+static void write_audio_gpio(struct pmac_gpio *gp, int active)
+{
+	if (! gp->addr)
+		return;
+	active = active ? gp->active_val : gp->inactive_val;
+	do_gpio_write(gp, active);
+	DBG("(I) gpio %x write %d\n", gp->addr, active);
+}
+
+static int check_audio_gpio(struct pmac_gpio *gp)
+{
+	int ret;
+
+	if (! gp->addr)
+		return 0;
+
+	ret = do_gpio_read(gp);
+
+	return (ret & 0xd) == (gp->active_val & 0xd);
+}
+
+static int read_audio_gpio(struct pmac_gpio *gp)
+{
+	int ret;
+	if (! gp->addr)
+		return 0;
+	ret = ((do_gpio_read(gp) & 0x02) !=0);
+	return ret == gp->active_state;
+}
+
+
+enum { TOONIE_MUTE_HP, TOONIE_MUTE_AMP };
+
+static int toonie_get_mute_switch(snd_kcontrol_t *kcontrol,
+				  snd_ctl_elem_value_t *ucontrol)
+{
+	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_toonie *mix = chip->mixer_data;
+	struct pmac_gpio *gp;
+
+	if (mix == NULL)
+		return -ENODEV;
+	switch(kcontrol->private_value) {
+	case TOONIE_MUTE_HP:
+		gp = &mix->hp_mute_gpio;
+		break;
+	case TOONIE_MUTE_AMP:
+		gp = &mix->amp_mute_gpio;
+		break;
+	default:
+		return -EINVAL;;
+	}
+	ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
+	return 0;
+}
+
+static int toonie_put_mute_switch(snd_kcontrol_t *kcontrol,
+				   snd_ctl_elem_value_t *ucontrol)
+{
+	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_toonie *mix = chip->mixer_data;
+	struct pmac_gpio *gp;
+	int val;
+
+	if (chip->update_automute && chip->auto_mute)
+		return 0; /* don't touch in the auto-mute mode */
+
+	if (mix == NULL)
+		return -ENODEV;
+
+	switch(kcontrol->private_value) {
+	case TOONIE_MUTE_HP:
+		gp = &mix->hp_mute_gpio;
+		break;
+	case TOONIE_MUTE_AMP:
+		gp = &mix->amp_mute_gpio;
+		break;
+	default:
+		return -EINVAL;;
+	}
+	val = ! check_audio_gpio(gp);
+	if (val != ucontrol->value.integer.value[0]) {
+		write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
+		return 1;
+	}
+	return 0;
+}
+
+static snd_kcontrol_new_t toonie_hp_sw __initdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Headphone Playback Switch",
+	.info = snd_pmac_boolean_mono_info,
+	.get = toonie_get_mute_switch,
+	.put = toonie_put_mute_switch,
+	.private_value = TOONIE_MUTE_HP,
+};
+static snd_kcontrol_new_t toonie_speaker_sw __initdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "PC Speaker Playback Switch",
+	.info = snd_pmac_boolean_mono_info,
+	.get = toonie_get_mute_switch,
+	.put = toonie_put_mute_switch,
+	.private_value = TOONIE_MUTE_AMP,
+};
+
+/*
+ * auto-mute stuffs
+ */
+static int toonie_detect_headphone(pmac_t *chip)
+{
+	struct pmac_toonie *mix = chip->mixer_data;
+	int detect = 0;
+
+	if (mix->hp_detect_gpio.addr)
+		detect |= read_audio_gpio(&mix->hp_detect_gpio);
+	return detect;
+}
+
+static void toonie_check_mute(pmac_t *chip, struct pmac_gpio *gp, int val,
+			      int do_notify, snd_kcontrol_t *sw)
+{
+	if (check_audio_gpio(gp) != val) {
+		write_audio_gpio(gp, val);
+		if (do_notify)
+			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+				       &sw->id);
+	}
+}
+
+static void toonie_detect_handler(void *self)
+{
+	pmac_t *chip = (pmac_t*) self;
+	struct pmac_toonie *mix;
+	int headphone;
+
+	if (!chip)
+		return;
+
+	mix = chip->mixer_data;
+	snd_assert(mix, return);
+
+	headphone = toonie_detect_headphone(chip);
+
+	DBG("headphone: %d, lineout: %d\n", headphone, lineout);
+
+	if (headphone) {
+		/* unmute headphone/lineout & mute speaker */
+		toonie_check_mute(chip, &mix->hp_mute_gpio, 0,
+				  mix->auto_mute_notify, chip->master_sw_ctl);
+		toonie_check_mute(chip, &mix->amp_mute_gpio, 1,
+				  mix->auto_mute_notify, chip->speaker_sw_ctl);
+	} else {
+		/* unmute speaker, mute others */
+		toonie_check_mute(chip, &mix->amp_mute_gpio, 0,
+				  mix->auto_mute_notify, chip->speaker_sw_ctl);
+		toonie_check_mute(chip, &mix->hp_mute_gpio, 1,
+				  mix->auto_mute_notify, chip->master_sw_ctl);
+	}
+	if (mix->auto_mute_notify) {
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+				       &chip->hp_detect_ctl->id);
+	}
+}
+
+static void toonie_update_automute(pmac_t *chip, int do_notify)
+{
+	if (chip->auto_mute) {
+		struct pmac_toonie *mix;
+		mix = chip->mixer_data;
+		snd_assert(mix, return);
+		mix->auto_mute_notify = do_notify;
+		schedule_work(&mix->detect_work);
+	}
+}
+
+/* interrupt - headphone plug changed */
+static irqreturn_t toonie_hp_intr(int irq, void *devid, struct pt_regs *regs)
+{
+	pmac_t *chip = devid;
+
+	if (chip->update_automute && chip->initialized) {
+		chip->update_automute(chip, 1);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
+/* look for audio gpio device */
+static int find_audio_gpio(const char *name, const char *platform,
+			   struct pmac_gpio *gp)
+{
+	struct device_node *np;
+  	u32 *base, addr;
+
+	if (! (np = find_devices("gpio")))
+		return -ENODEV;
+  
+	for (np = np->child; np; np = np->sibling) {
+		char *property = get_property(np, "audio-gpio", NULL);
+		if (property && strcmp(property, name) == 0)
+			break;
+		if (device_is_compatible(np, name))
+			break;
+	}
+	if (np == NULL)
+		return -ENODEV;
+
+	base = (u32 *)get_property(np, "AAPL,address", NULL);
+	if (! base) {
+		base = (u32 *)get_property(np, "reg", NULL);
+		if (!base) {
+			DBG("(E) cannot find address for device %s !\n", device);
+			snd_printd("cannot find address for device %s\n", device);
+			return -ENODEV;
+		}
+		addr = *base;
+		if (addr < 0x50)
+			addr += 0x50;
+	} else
+		addr = *base;
+
+	gp->addr = addr & 0x0000ffff;
+
+	/* Try to find the active state, default to 0 ! */
+	base = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
+	if (base) {
+		gp->active_state = *base;
+		gp->active_val = (*base) ? 0x5 : 0x4;
+		gp->inactive_val = (*base) ? 0x4 : 0x5;
+	} else {
+		u32 *prop = NULL;
+		gp->active_state = 0;
+		gp->active_val = 0x4;
+		gp->inactive_val = 0x5;
+		/* Here are some crude hacks to extract the GPIO polarity and
+		 * open collector informations out of the do-platform script
+		 * as we don't yet have an interpreter for these things
+		 */
+		if (platform)
+			prop = (u32 *)get_property(np, platform, NULL);
+		if (prop) {
+			if (prop[3] == 0x9 && prop[4] == 0x9) {
+				gp->active_val = 0xd;
+				gp->inactive_val = 0xc;
+			}
+			if (prop[3] == 0x1 && prop[4] == 0x1) {
+				gp->active_val = 0x5;
+				gp->inactive_val = 0x4;
+			}
+		}
+	}
+
+	DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
+	    device, gp->addr, gp->active_state);
+
+	return (np->n_intrs > 0) ? np->intrs[0].line : 0;
+}
+
+static void toonie_cleanup(pmac_t *chip)
+{
+	struct pmac_toonie *mix = chip->mixer_data;
+	if (! mix)
+		return;
+	if (mix->hp_detect_irq >= 0)
+		free_irq(mix->hp_detect_irq, chip);
+	kfree(mix);
+	chip->mixer_data = NULL;
+}
+
+int snd_pmac_toonie_init(pmac_t *chip)
+{
+	struct pmac_toonie *mix;
+
+	mix = kmalloc(sizeof(*mix), GFP_KERNEL);
+	if (! mix)
+		return -ENOMEM;
+
+	chip->mixer_data = mix;
+	chip->mixer_free = toonie_cleanup;
+
+	find_audio_gpio("headphone-mute", NULL, &mix->hp_mute_gpio);
+	find_audio_gpio("amp-mute", NULL, &mix->amp_mute_gpio);
+	mix->hp_detect_irq = find_audio_gpio("headphone-detect",
+					     NULL, &mix->hp_detect_gpio);
+
+	strcpy(chip->card->mixername, "PowerMac Toonie");
+
+	chip->master_sw_ctl = snd_ctl_new1(&toonie_hp_sw, chip);
+	snd_ctl_add(chip->card, chip->master_sw_ctl);
+
+	chip->speaker_sw_ctl = snd_ctl_new1(&toonie_speaker_sw, chip);
+	snd_ctl_add(chip->card, chip->speaker_sw_ctl);
+
+	INIT_WORK(&mix->detect_work, toonie_detect_handler, (void *)chip);
+
+	if (mix->hp_detect_irq >= 0) {
+		snd_pmac_add_automute(chip);
+
+		chip->detect_headphone = toonie_detect_headphone;
+		chip->update_automute = toonie_update_automute;
+		toonie_update_automute(chip, 0);
+
+		if (request_irq(mix->hp_detect_irq, toonie_hp_intr, 0,
+				"Sound Headphone Detection", chip) < 0)
+			mix->hp_detect_irq = -1;
+	}
+
+	return 0;
+}
+
Index: linux-work/sound/ppc/Makefile
===================================================================
--- linux-work.orig/sound/ppc/Makefile	2005-03-15 12:00:38.000000000 +1100
+++ linux-work/sound/ppc/Makefile	2005-04-14 11:15:38.000000000 +1000
@@ -3,7 +3,7 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex at suse.cz>
 #
 
-snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
+snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o toonie.o keywest.o beep.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
Index: linux-work/sound/ppc/pmac.c
===================================================================
--- linux-work.orig/sound/ppc/pmac.c	2005-04-12 18:07:50.000000000 +1000
+++ linux-work/sound/ppc/pmac.c	2005-04-14 11:16:33.000000000 +1000
@@ -986,7 +986,13 @@
 			chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
 			chip->model = PMAC_SNAPPER;
 			chip->can_byte_swap = 0; /* FIXME: check this */
-			chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
+			chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */
+			break;
+		case 0x3a:
+			chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
+			chip->model = PMAC_TOONIE;
+			chip->can_byte_swap = 0; /* FIXME: check this */
+			chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */
 			break;
 		}
 	}
Index: linux-work/sound/ppc/pmac.h
===================================================================
--- linux-work.orig/sound/ppc/pmac.h	2005-04-12 18:07:50.000000000 +1000
+++ linux-work/sound/ppc/pmac.h	2005-04-14 11:19:06.000000000 +1000
@@ -94,7 +94,8 @@
  */
 
 enum snd_pmac_model {
-	PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER, PMAC_SNAPPER
+	PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER,
+	PMAC_SNAPPER, PMAC_TOONIE
 };
 
 struct snd_pmac {
@@ -191,6 +192,7 @@
 int snd_pmac_daca_init(pmac_t *chip);
 int snd_pmac_tumbler_init(pmac_t *chip);
 int snd_pmac_tumbler_post_init(void);
+int snd_pmac_toonie_init(pmac_t *chip);
 
 /* i2c functions */
 typedef struct snd_pmac_keywest {
Index: linux-work/sound/ppc/powermac.c
===================================================================
--- linux-work.orig/sound/ppc/powermac.c	2005-03-15 12:00:38.000000000 +1100
+++ linux-work/sound/ppc/powermac.c	2005-04-14 11:18:49.000000000 +1000
@@ -95,6 +95,13 @@
 		if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0)
 			goto __error;
 		break;
+	case PMAC_TOONIE:
+		strcpy(card->driver, "PMac Toonie");
+		strcpy(card->shortname, "PowerMac Toonie");
+		strcpy(card->longname, card->shortname);
+		if ((err = snd_pmac_toonie_init(chip)) < 0)
+			goto __error;
+		break;
 	case PMAC_AWACS:
 	case PMAC_SCREAMER:
 		name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS";


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6.11-module-licenses.patch:
 macmodes.c |    2 ++
 1 files changed, 2 insertions(+)

--- NEW FILE linux-2.6.11-module-licenses.patch ---
--- linux-2.6.11/drivers/video/macmodes.c~	2005-04-18 19:25:30.000000000 -0400
+++ linux-2.6.11/drivers/video/macmodes.c	2005-04-18 19:25:44.000000000 -0400
@@ -387,3 +387,5 @@ int __init mac_find_mode(struct fb_var_s
 }
 EXPORT_SYMBOL(mac_find_mode);
 
+MODULE_LICENSE("GPL");
+

linux-2.6.11-parport-sysctl-perms.patch:
 procfs.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

--- NEW FILE linux-2.6.11-parport-sysctl-perms.patch ---
--- linux-2.6.11/drivers/parport/procfs.c~	2005-04-25 12:17:30.000000000 -0400
+++ linux-2.6.11/drivers/parport/procfs.c	2005-04-25 12:20:35.000000000 -0400
@@ -286,19 +286,19 @@ static const struct parport_sysctl_table
 		PARPORT_DEVICES_ROOT_DIR,
 #ifdef CONFIG_PARPORT_1284
 		{ DEV_PARPORT_AUTOPROBE, "autoprobe",
-		  NULL, 0, 0444, NULL,
+		  NULL, 0, 0200, NULL,
 		  &do_autoprobe },
 		{ DEV_PARPORT_AUTOPROBE + 1, "autoprobe0",
-		 NULL, 0, 0444, NULL,
+		 NULL, 0, 0200, NULL,
 		 &do_autoprobe },
 		{ DEV_PARPORT_AUTOPROBE + 2, "autoprobe1",
-		  NULL, 0, 0444, NULL,
+		  NULL, 0, 0200, NULL,
 		  &do_autoprobe },
 		{ DEV_PARPORT_AUTOPROBE + 3, "autoprobe2",
-		  NULL, 0, 0444, NULL,
+		  NULL, 0, 0200, NULL,
 		  &do_autoprobe },
 		{ DEV_PARPORT_AUTOPROBE + 4, "autoprobe3",
-		  NULL, 0, 0444, NULL,
+		  NULL, 0, 0200, NULL,
 		  &do_autoprobe },
 #endif /* IEEE 1284 support */
 		{0}
@@ -326,7 +326,7 @@ parport_device_sysctl_template = {
 	NULL,
 	{
 		{ DEV_PARPORT_DEVICE_TIMESLICE, "timeslice",
-		  NULL, sizeof(int), 0644, NULL,
+		  NULL, sizeof(int), 0200, NULL,
 		  &proc_doulongvec_ms_jiffies_minmax, NULL, NULL,
 		  (void*) &parport_min_timeslice_value,
 		  (void*) &parport_max_timeslice_value },

linux-2.6.11-pmac-ide-sleep.patch:
 pmac.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.11-pmac-ide-sleep.patch ---
>From linuxppc-dev-bounces at ozlabs.org Wed Apr 13 05:41:09 2005
Return-path: <linuxppc-dev-bounces at ozlabs.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Wed, 13 Apr 2005 05:41:09 +0100
Received: from [2002:d592:9a28::1] (helo=pentafluge.infradead.org) by
	baythorne.infradead.org with esmtps (Exim 4.43 #1 (Red Hat Linux)) id
	1DLZgb-0004eA-0a for dwmw2 at baythorne.infradead.org; Wed, 13 Apr 2005
	05:41:09 +0100
Received: from ozlabs.org ([203.10.76.45]) by pentafluge.infradead.org with
	esmtps (Exim 4.43 #1 (Red Hat Linux)) id 1DLZgW-0007qu-IF for
	dwmw2 at infradead.org; Wed, 13 Apr 2005 05:41:08 +0100
Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix)
	with ESMTP id 8AA7D67B58; Wed, 13 Apr 2005 14:40:59 +1000 (EST)
X-Original-To: linuxppc-dev at ozlabs.org
Delivered-To: linuxppc-dev at ozlabs.org
Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using
	TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not
	present a certificate) by ozlabs.org (Postfix) with ESMTP id C250567B56 for
	<linuxppc-dev at ozlabs.org>; Wed, 13 Apr 2005 14:40:57 +1000 (EST)
Received: from gaston (localhost [127.0.0.1]) by gate.crashing.org
	(8.12.8/8.12.8) with ESMTP id j3D4aMgJ011111; Tue, 12 Apr 2005 23:36:23
	-0500
From: Benjamin Herrenschmidt <benh at kernel.crashing.org>
To: Andrew Morton <akpm at osdl.org>
Content-Type: text/plain
Date: Wed, 13 Apr 2005 14:40:38 +1000
Message-Id: <1113367238.5515.5.camel at gaston>
Mime-Version: 1.0
X-Mailer: Evolution 2.0.4 
Cc: linuxppc-dev list <linuxppc-dev at ozlabs.org>, "debian-powerpc at lists.debian.org" <debian-powerpc at lists.debian.org>
Subject: [PATCH] ppc32: Fix IDE related crash on wakeup
X-BeenThere: linuxppc-dev at ozlabs.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>
List-Unsubscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev at ozlabs.org>
List-Help: <mailto:linuxppc-dev-request at ozlabs.org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=subscribe>
Sender: linuxppc-dev-bounces at ozlabs.org
Errors-To: linuxppc-dev-bounces at ozlabs.org
X-Spam-Score: 0.0 (/)
X-Evolution-Source: imap://dwmw2@pentafluge.infradead.org/
Content-Transfer-Encoding: 8bit

Hi !

I noticed an occasional crash on wakeup from sleep on my powerbook
(strangly never happened before, probably timing related) that appears
to be due to a dangling interrupt while the chip is put to sleep and
beeing reset on wakeup.

This patch fixes is by disabling the irq in the ide pmac driver while
asleep and only re-enable it after the chip has been fully reset. This
is safe to do so as the interrupt of these apple IDE cells is never
shared.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>

Index: linux-work/drivers/ide/ppc/pmac.c
===================================================================
--- linux-work.orig/drivers/ide/ppc/pmac.c	2005-04-13 10:53:39.000000000 +1000
+++ linux-work/drivers/ide/ppc/pmac.c	2005-04-13 14:17:41.000000000 +1000
@@ -1204,6 +1204,8 @@
 	}
 #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
 
+	disable_irq(pmif->irq);
+
 	/* The media bay will handle itself just fine */
 	if (pmif->mediabay)
 		return 0;
@@ -1236,7 +1238,6 @@
 		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);
 		msleep(10);
 		ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0);
-		msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
 
 		/* Kauai has it different */
 		if (pmif->kauai_fcr) {
@@ -1244,11 +1245,15 @@
 			fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE;
 			writel(fcr, pmif->kauai_fcr);
 		}
+
+		msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
 	}
 
 	/* Sanitize drive timings */
 	sanitize_timings(pmif);
 
+	enable_irq(pmif->irq);
+
 	return 0;
 }
 


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6.11-pmac-volume-save.patch:
 tumbler.c |    5 +++++
 1 files changed, 5 insertions(+)

--- NEW FILE linux-2.6.11-pmac-volume-save.patch ---
>From linuxppc-dev-bounces at ozlabs.org Thu Apr 21 19:04:31 2005
Return-path: <linuxppc-dev-bounces at ozlabs.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Thu, 21 Apr 2005 19:04:31 +0100
Received: from [2002:d592:9a28::1] (helo=pentafluge.infradead.org) by
	baythorne.infradead.org with esmtps (Exim 4.43 #1 (Red Hat Linux)) id
	1DOg2R-0006oh-IM for dwmw2 at baythorne.infradead.org; Thu, 21 Apr 2005
	19:04:31 +0100
Received: from ozlabs.org ([203.10.76.45]) by pentafluge.infradead.org with
	esmtps (Exim 4.43 #1 (Red Hat Linux)) id 1DOg2P-00075e-4R for
	dwmw2 at infradead.org; Thu, 21 Apr 2005 19:04:30 +0100
Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix)
	with ESMTP id A9CEF67A6F; Fri, 22 Apr 2005 04:04:23 +1000 (EST)
X-Original-To: linuxppc-dev at ozlabs.org
Delivered-To: linuxppc-dev at ozlabs.org
Received: from paperstreet.colino.net (colino.net [213.41.131.56]) (using
	TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (Client did not
	present a certificate) by ozlabs.org (Postfix) with ESMTP id F2F4E67A2E for
	<linuxppc-dev at ozlabs.org>; Fri, 22 Apr 2005 04:04:21 +1000 (EST)
Received: by paperstreet.colino.net (Postfix, from userid 1015) id
	1F710101DB; Thu, 21 Apr 2005 20:04:12 +0200 (CEST)
Received: from jack.colino.net (jack.colino.net [192.168.0.11]) by
	paperstreet.colino.net (Postfix) with ESMTP id 9A606101D9; Thu, 21 Apr 2005
	20:04:09 +0200 (CEST)
Date: Thu, 21 Apr 2005 20:04:08 +0200
From: Colin Leroy <colin at colino.net>
To: "debian-powerpc at lists.debian.org" <debian-powerpc at lists.debian.org>, linuxppc-dev at ozlabs.org, Benjamin Herrenschmidt <benh at kernel.crashing.org>
Message-ID: <20050421200408.5361a5b3 at jack.colino.net>
X-Mailer: Sylpheed-Claws 1.9.6cvs36 (GTK+ 2.6.4; powerpc-unknown-linux-gnu)
X-Face:
	Fy:*XpRna1/tz}cJ at O'0^:qYs:8b[Rg`*8,+o^[fI?<%5LeB,Xz8ZJK[r7V0hBs8G)*&C+XA0qHoR=LoTohe at 7X5K$A- at cN6n~~J/]+{[)E4h'lK$13WQf$.R+Pi;
	E09tk&{t|; ~dakRD%CLHrk6m!?gA,5|Sb=fJ=>[9#n1Bu8?VngkVM4{'^'V_qgdA.8yn3)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
X-Spam-Checker-Version: SpamAssassin 2.64 (2004-01-11) on 
	paperstreet.colino.net
X-Spam-Level: 
X-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL autolearn=no
	version=2.64
Cc: Takashi Iwai <tiwai at suse.de>, Andrew Morton <akpm at osdl.org>
Subject: [PATCH 2.6.12-rc3] pmac: save master volume on sleep
X-BeenThere: linuxppc-dev at ozlabs.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>
List-Unsubscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev at ozlabs.org>
List-Help: <mailto:linuxppc-dev-request at ozlabs.org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=subscribe>
Sender: linuxppc-dev-bounces at ozlabs.org
Errors-To: linuxppc-dev-bounces at ozlabs.org
X-Spam-Score: 0.0 (/)
X-Evolution-Source: imap://dwmw2@pentafluge.infradead.org/
Content-Transfer-Encoding: 8bit

Hi,

Ben's patch that shutdowns master switch and restores it after
resume ("pmac: Improve sleep code of tumbler driver") isn't enough here
on an iBook (snapper chip).

The master switch is correctly saved and restored, but somehow
tumbler_put_master_volume() gets called just after
tumbler_set_master_volume() and sets mix->master_vol[*] to 0. So, on
resuming, the master switch is reenabled, but the volume is set to 0.

Here's a patch that also saves and restores master_vol.
Thanks,

Signed-off-by: Colin Leroy <colin at colino.net>
--- a/sound/ppc/tumbler.c	2005-04-21 19:56:06.000000000 +0200
+++ b/sound/ppc/tumbler.c	2005-04-21 19:55:43.000000000 +0200
@@ -99,6 +99,7 @@
 	pmac_gpio_t hp_detect;
 	int headphone_irq;
 	int lineout_irq;
+	unsigned int save_master_vol[2];
 	unsigned int master_vol[2];
 	unsigned int save_master_switch[2];
 	unsigned int master_switch[2];
@@ -1128,6 +1129,8 @@
 		disable_irq(mix->lineout_irq);
 	mix->save_master_switch[0] = mix->master_switch[0];
 	mix->save_master_switch[1] = mix->master_switch[1];
+	mix->save_master_vol[0] = mix->master_vol[0];
+	mix->save_master_vol[1] = mix->master_vol[1];
 	mix->master_switch[0] = mix->master_switch[1] = 0;
 
 	tumbler_set_master_volume(mix);
@@ -1156,6 +1159,8 @@
 	mix->acs &= ~1;
 	mix->master_switch[0] = mix->save_master_switch[0];
 	mix->master_switch[1] = mix->save_master_switch[1];
+	mix->master_vol[0] = mix->save_master_vol[0];
+	mix->master_vol[1] = mix->save_master_vol[1];
 	tumbler_reset_audio(chip);
 	if (mix->i2c.client && mix->i2c.init_client) {
 		if (mix->i2c.init_client(&mix->i2c) < 0)
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6.11-ppc32-750-erratum-fix.patch:
 kernel/cpu_setup_6xx.S |   44 +++++++++++++++++++++++++++++++++++++-------
 platforms/pmac_sleep.S |    4 ++++
 2 files changed, 41 insertions(+), 7 deletions(-)

--- NEW FILE linux-2.6.11-ppc32-750-erratum-fix.patch ---
>From linuxppc-dev-bounces at ozlabs.org Tue Apr  5 07:06:22 2005
Return-path: <linuxppc-dev-bounces at ozlabs.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Tue, 05 Apr 2005 07:06:22 +0100
Received: from [2002:d592:9a28::1] (helo=pentafluge.infradead.org) by
	baythorne.infradead.org with esmtps (Exim 4.43 #1 (Red Hat Linux)) id
	1DIhCf-0004AK-SH for dwmw2 at baythorne.infradead.org; Tue, 05 Apr 2005
	07:06:22 +0100
Received: from ozlabs.org ([203.10.76.45]) by pentafluge.infradead.org with
	esmtp (Exim 4.43 #1 (Red Hat Linux)) id 1DIhCJ-0006Zs-9H for
	dwmw2 at infradead.org; Tue, 05 Apr 2005 07:06:04 +0100
Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix)
	with ESMTP id 0F70567A6C; Tue,  5 Apr 2005 16:06:13 +1000 (EST)
X-Original-To: linuxppc-dev at ozlabs.org
Delivered-To: linuxppc-dev at ozlabs.org
Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using
	TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not
	present a certificate) by ozlabs.org (Postfix) with ESMTP id 0E3EC67A46 for
	<linuxppc-dev at ozlabs.org>; Tue,  5 Apr 2005 16:06:10 +1000 (EST)
Received: from gaston (localhost [127.0.0.1]) by gate.crashing.org
	(8.12.8/8.12.8) with ESMTP id j3562BgJ027513; Tue, 5 Apr 2005 01:02:12 -0500
From: Benjamin Herrenschmidt <benh at kernel.crashing.org>
To: Andrew Morton <akpm at osdl.org>
Content-Type: text/plain
Date: Tue, 05 Apr 2005 16:05:54 +1000
Message-Id: <1112681154.9517.7.camel at gaston>
Mime-Version: 1.0
X-Mailer: Evolution 2.0.4 
Cc: linuxppc-dev list <linuxppc-dev at ozlabs.org>
Subject: [PATCH] Update ppc32-fix-errata-for-some-g3-cpus.patch
X-BeenThere: linuxppc-dev at ozlabs.org
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>
List-Unsubscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev at ozlabs.org>
List-Help: <mailto:linuxppc-dev-request at ozlabs.org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=subscribe>
Sender: linuxppc-dev-bounces at ozlabs.org
Errors-To: linuxppc-dev-bounces at ozlabs.org
X-Spam-Score: 0.0 (/)
X-Evolution-Source: imap://dwmw2@pentafluge.infradead.org/
Content-Transfer-Encoding: 8bit

Hi Andrew !

The previous version of ppc32-fix-errata-for-some-g3-cpus.patch had an
issue that would crash some G4 CPUs on boot. This is fixed in this new
version, please replace the old one and send to linus asap (it's now
been tested on enough CPUs).

---

Some G3 CPUs can crash in funny way if a store from an FPU register
instruction is executed on a register that has never been initialized
since power on. This patch fixes it by making sure all FP registers have
been properly initialized at kernel boot and when waking from sleep. It
also makes the code that decides wether HID0_BTIC and HID0_DPM are
allowed on a given CPU smarter (it can actually _clear_ them now if they
are not allowed instead of just setting them when they are allowed in
case the firmware got them wrong)

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>


Index: linux-work/arch/ppc/kernel/cpu_setup_6xx.S
===================================================================
--- linux-work.orig/arch/ppc/kernel/cpu_setup_6xx.S	2005-03-15 11:56:39.000000000 +1100
+++ linux-work/arch/ppc/kernel/cpu_setup_6xx.S	2005-04-05 15:57:49.000000000 +1000
@@ -30,12 +30,14 @@
 	blr
 _GLOBAL(__setup_cpu_750)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	mtlr	r4
 	blr
 _GLOBAL(__setup_cpu_750cx)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750cx
@@ -43,6 +45,7 @@
 	blr
 _GLOBAL(__setup_cpu_750fx)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750fx
@@ -50,6 +53,7 @@
 	blr
 _GLOBAL(__setup_cpu_7400)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_7400_workarounds
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
@@ -57,6 +61,7 @@
 	blr
 _GLOBAL(__setup_cpu_7410)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_7410_workarounds
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
@@ -80,7 +85,7 @@
 	bne	1f			/* don't invalidate the D-cache */
 	ori	r8,r8,HID0_DCI		/* unless it wasn't enabled */
 1:	sync
-	mtspr	SPRN_HID0,r8			/* enable and invalidate caches */
+	mtspr	SPRN_HID0,r8		/* enable and invalidate caches */
 	sync
 	mtspr	SPRN_HID0,r11		/* enable caches */
 	sync
@@ -151,10 +156,14 @@
  */
 setup_750_7400_hid0:
 	mfspr	r11,SPRN_HID0
-	ori	r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
+	ori	r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC	
+	oris	r11,r11,HID0_DPM at h
 BEGIN_FTR_SECTION
-	oris	r11,r11,HID0_DPM at h	/* enable dynamic power mgmt */
-END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
+	xori	r11,r11,HID0_BTIC
+END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
+BEGIN_FTR_SECTION
+	xoris	r11,r11,HID0_DPM at h	/* disable dynamic power mgmt */
+END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
 	li	r3,HID0_SPD
 	andc	r11,r11,r3		/* clear SPD: enable speculative */
  	li	r3,0
@@ -218,13 +227,15 @@
 
 	/* All of the bits we have to set.....
 	 */
-	ori	r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_LRSTK | HID0_BTIC
+	ori	r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
+	ori	r11,r11,HID0_LRSTK | HID0_BTIC
+	oris	r11,r11,HID0_DPM at h
 BEGIN_FTR_SECTION
 	xori	r11,r11,HID0_BTIC
 END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
 BEGIN_FTR_SECTION
-	oris	r11,r11,HID0_DPM at h	/* enable dynamic power mgmt */
-END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
+	xoris	r11,r11,HID0_DPM at h	/* disable dynamic power mgmt */
+END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
 
 	/* All of the bits we have to clear....
 	 */
@@ -248,6 +259,25 @@
 	isync
 	blr
 
+/*
+ * Initialize the FPU registers. This is needed to work around an errata
+ * in some 750 cpus where using a not yet initialized FPU register after
+ * power on reset may hang the CPU
+ */
+_GLOBAL(__init_fpu_registers)
+	mfmsr	r10
+	ori	r11,r10,MSR_FP
+	mtmsr	r11
+	isync	
+	addis	r9,r3,empty_zero_page at ha
+	addi	r9,r9,empty_zero_page at l
+	REST_32FPRS(0,r9)
+	sync
+	mtmsr	r10
+	isync
+	blr
+		
+	
 /* Definitions for the table use to save CPU states */
 #define CS_HID0		0
 #define CS_HID1		4
Index: linux-work/arch/ppc/platforms/pmac_sleep.S
===================================================================
--- linux-work.orig/arch/ppc/platforms/pmac_sleep.S	2005-03-15 11:56:42.000000000 +1100
+++ linux-work/arch/ppc/platforms/pmac_sleep.S	2005-04-05 14:29:25.000000000 +1000
@@ -267,6 +267,10 @@
 	/* Restore various CPU config stuffs */
 	bl	__restore_cpu_setup
 
+	/* Make sure all FPRs have been initialized */
+	bl	reloc_offset
+	bl	__init_fpu_registers
+	
 	/* Invalidate & enable L1 cache, we don't care about
 	 * whatever the ROM may have tried to write to memory
 	 */


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6.11-ppc32-pbook-clock-spreading.patch:
 pmac_feature.c |  214 ++++++++++++++++++++++++++++++---------------------------
 1 files changed, 114 insertions(+), 100 deletions(-)

--- NEW FILE linux-2.6.11-ppc32-pbook-clock-spreading.patch ---
Index: linux-work/arch/ppc/platforms/pmac_feature.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/pmac_feature.c	2005-04-12 18:07:50.000000000 +1000
+++ linux-work/arch/ppc/platforms/pmac_feature.c	2005-04-22 17:07:30.000000000 +1000
@@ -1590,6 +1590,112 @@
 	mdelay(10);
 }
 
+
+static void __pmac pmac_tweak_clock_spreading(struct macio_chip* macio, int enable)
+{
+	/* Hack for doing clock spreading on some machines PowerBooks and
+	 * iBooks. This implements the "platform-do-clockspreading" OF
+	 * property as decoded manually on various models. For safety, we also
+	 * check the product ID in the device-tree in cases we'll whack the i2c
+	 * chip to make reasonably sure we won't set wrong values in there
+	 *
+	 * Of course, ultimately, we have to implement a real parser for
+	 * the platform-do-* stuff...
+	 */
+
+	if (macio->type == macio_intrepid) {
+		if (enable)
+			UN_OUT(UNI_N_CLOCK_SPREADING, 2);
+		else
+			UN_OUT(UNI_N_CLOCK_SPREADING, 0);
+		mdelay(40);
+	}
+
+	while (machine_is_compatible("PowerBook5,2") ||
+	       machine_is_compatible("PowerBook5,3") ||
+	       machine_is_compatible("PowerBook6,2") ||
+	       machine_is_compatible("PowerBook6,3")) {
+		struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
+		struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
+		u8 buffer[9];
+		u32 *productID;
+		int i, rc, changed = 0;
+		
+		if (dt == NULL)
+			break;
+		productID = (u32 *)get_property(dt, "pid#", NULL);
+		if (productID == NULL)
+			break;
+		while(ui2c) {
+			struct device_node *p = of_get_parent(ui2c);
+			if (p && !strcmp(p->name, "uni-n"))
+				break;
+			ui2c = of_find_node_by_type(ui2c, "i2c");
+		}
+		if (ui2c == NULL)
+			break;
+		DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
+		rc = pmac_low_i2c_open(ui2c, 1);
+		if (rc != 0)
+			break;
+		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+		DBG("read result: %d,", rc);
+		if (rc != 0) {
+			pmac_low_i2c_close(ui2c);
+			break;
+		}
+		for (i=0; i<9; i++)
+			DBG(" %02x", buffer[i]);
+		DBG("\n");
+		
+		switch(*productID) {
+		case 0x1182:	/* AlBook 12" rev 2 */
+		case 0x1183:	/* iBook G4 12" */
+			buffer[0] = (buffer[0] & 0x8f) | 0x70;
+			buffer[2] = (buffer[2] & 0x7f) | 0x00;
+			buffer[5] = (buffer[5] & 0x80) | 0x31;
+			buffer[6] = (buffer[6] & 0x40) | 0xb0;
+			buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
+			buffer[8] = (buffer[8] & 0x00) | 0x30;
+			changed = 1;
+			break;
+		case 0x3142:	/* AlBook 15" (ATI M10) */
+		case 0x3143:	/* AlBook 17" (ATI M10) */
+			buffer[0] = (buffer[0] & 0xaf) | 0x50;
+			buffer[2] = (buffer[2] & 0x7f) | 0x00;
+			buffer[5] = (buffer[5] & 0x80) | 0x31;
+			buffer[6] = (buffer[6] & 0x40) | 0xb0;
+			buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
+			buffer[8] = (buffer[8] & 0x00) | 0x30;
+			changed = 1;
+			break;
+		default:
+			DBG("i2c-hwclock: Machine model not handled\n");
+			break;
+		}
+		if (!changed) {
+			pmac_low_i2c_close(ui2c);
+			break;
+		}
+		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
+		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
+		DBG("write result: %d,", rc);
+		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+		DBG("read result: %d,", rc);
+		if (rc != 0) {
+			pmac_low_i2c_close(ui2c);
+			break;
+		}
+		for (i=0; i<9; i++)
+			DBG(" %02x", buffer[i]);
+		pmac_low_i2c_close(ui2c);
+		break;
+	}
+}
+
+
 static int __pmac
 core99_sleep(void)
 {
@@ -1601,11 +1707,8 @@
 	    macio->type != macio_intrepid)
 		return -ENODEV;
 
-	/* The device-tree contains that in the hwclock node */
-	if (macio->type == macio_intrepid) {
-		UN_OUT(UNI_N_CLOCK_SPREADING, 0);
-		mdelay(40);
-	}
+	/* Disable clock spreading */
+	pmac_tweak_clock_spreading(macio, 0);
 
 	/* We power off the wireless slot in case it was not done
 	 * by the driver. We don't power it on automatically however
@@ -1749,11 +1852,8 @@
 	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
 	udelay(100);
 
-	/* Restore clock spreading */
-	if (macio->type == macio_intrepid) {
-		UN_OUT(UNI_N_CLOCK_SPREADING, 2);
-		mdelay(40);
-	}
+	/* Enable clock spreading */
+	pmac_tweak_clock_spreading(macio, 1);
 
 	return 0;
 }
@@ -2718,97 +2818,11 @@
 		MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
 	}
 
-	/* Hack for bumping clock speed on the new PowerBooks and the
-	 * iBook G4. This implements the "platform-do-clockspreading" OF
-	 * property. For safety, we also check the product ID in the
-	 * device-tree to make reasonably sure we won't set wrong values
-	 * in the clock chip.
-	 *
-	 * Of course, ultimately, we have to implement a real parser for
-	 * the platform-do-* stuff...
+	/* Some machine models need the clock chip to be properly setup for
+	 * clock spreading now. This should be a platform function but we
+	 * don't do these at the moment
 	 */
-	while (machine_is_compatible("PowerBook5,2") ||
-	       machine_is_compatible("PowerBook5,3") ||
-	       machine_is_compatible("PowerBook6,2") ||
-	       machine_is_compatible("PowerBook6,3")) {
-		struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
-		struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
-		u8 buffer[9];
-		u32 *productID;
-		int i, rc, changed = 0;
-		
-		if (dt == NULL)
-			break;
-		productID = (u32 *)get_property(dt, "pid#", NULL);
-		if (productID == NULL)
-			break;
-		while(ui2c) {
-			struct device_node *p = of_get_parent(ui2c);
-			if (p && !strcmp(p->name, "uni-n"))
-				break;
-			ui2c = of_find_node_by_type(ui2c, "i2c");
-		}
-		if (ui2c == NULL)
-			break;
-		DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
-		rc = pmac_low_i2c_open(ui2c, 1);
-		if (rc != 0)
-			break;
-		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
-		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
-		DBG("read result: %d,", rc);
-		if (rc != 0) {
-			pmac_low_i2c_close(ui2c);
-			break;
-		}
-		for (i=0; i<9; i++)
-			DBG(" %02x", buffer[i]);
-		DBG("\n");
-		
-		switch(*productID) {
-		case 0x1182:	/* AlBook 12" rev 2 */
-		case 0x1183:	/* iBook G4 12" */
-			buffer[0] = (buffer[0] & 0x8f) | 0x70;
-			buffer[2] = (buffer[2] & 0x7f) | 0x00;
-			buffer[5] = (buffer[5] & 0x80) | 0x31;
-			buffer[6] = (buffer[6] & 0x40) | 0xb0;
-			buffer[7] = (buffer[7] & 0x00) | 0xc0;
-			buffer[8] = (buffer[8] & 0x00) | 0x30;
-			changed = 1;
-			break;
-		case 0x3142:	/* AlBook 15" (ATI M10) */
-		case 0x3143:	/* AlBook 17" (ATI M10) */
-			buffer[0] = (buffer[0] & 0xaf) | 0x50;
-			buffer[2] = (buffer[2] & 0x7f) | 0x00;
-			buffer[5] = (buffer[5] & 0x80) | 0x31;
-			buffer[6] = (buffer[6] & 0x40) | 0xb0;
-			buffer[7] = (buffer[7] & 0x00) | 0xd0;
-			buffer[8] = (buffer[8] & 0x00) | 0x30;
-			changed = 1;
-			break;
-		default:
-			DBG("i2c-hwclock: Machine model not handled\n");
-			break;
-		}
-		if (!changed) {
-			pmac_low_i2c_close(ui2c);
-			break;
-		}
-		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
-		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
-		DBG("write result: %d,", rc);
-		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
-		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
-		DBG("read result: %d,", rc);
-		if (rc != 0) {
-			pmac_low_i2c_close(ui2c);
-			break;
-		}
-		for (i=0; i<9; i++)
-			DBG(" %02x", buffer[i]);
-		pmac_low_i2c_close(ui2c);
-		break;
-	}
+	pmac_tweak_clock_spreading(&macio_chips[0], 1);
 
 #endif /* CONFIG_POWER4 */
 

linux-2.6.11-ppc32-pmac-sleep-fix.patch:
 pmac_cache.S |   56 +++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 43 insertions(+), 13 deletions(-)

--- NEW FILE linux-2.6.11-ppc32-pmac-sleep-fix.patch ---
We are experiencing a problem when flushing the CPU caches before sleep
on some laptop models using the 750FX CPU rev 1.X. While I haven't been
able to figure out a proper explanation for what's going on, I do have a
workaround that seem to work reliably and allows those machine to sleep
and wakeup properly again. This should be applied for 2.6.12. I'll
re-update that code if/when I ever find exactly what is happening with
those CPU revisions.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>

Index: linux-work/arch/ppc/platforms/pmac_cache.S
===================================================================
--- linux-work.orig/arch/ppc/platforms/pmac_cache.S	2005-04-24 11:37:38.000000000 +1000
+++ linux-work/arch/ppc/platforms/pmac_cache.S	2005-04-24 12:00:46.000000000 +1000
@@ -64,27 +64,39 @@
 	mtspr	SPRN_HID0,r4		/* Disable DPM */
 	sync
 
-	/* disp-flush L1 */
-	li	r4,0x4000
-	mtctr	r4
+	/* Disp-flush L1. We have a weird problem here that I never
+	 * totally figured out. On 750FX, using the ROM for the flush
+	 * results in a non-working flush. We use that workaround for
+	 * now until I finally understand what's going on. --BenH
+	 */
+
+	/* ROM base by default */
 	lis	r4,0xfff0
-1:	lwzx	r0,r0,r4
+	mfpvr	r3
+	srwi	r3,r3,16
+	cmplwi	cr0,r3,0x7000
+	bne+	1f
+	/* RAM base on 750FX */
+	li	r4,0
+1:	li	r4,0x4000
+	mtctr	r4
+1:	lwz	r0,0(r4)
 	addi	r4,r4,32
 	bdnz	1b
 	sync
 	isync
 
-	/* disable / invalidate / enable L1 data */
+	/* Disable / invalidate / enable L1 data */
 	mfspr	r3,SPRN_HID0
-	rlwinm	r0,r0,0,~HID0_DCE
+	rlwinm	r3,r3,0,~(HID0_DCE | HID0_ICE)
 	mtspr	SPRN_HID0,r3
 	sync
 	isync
-	ori	r3,r3,HID0_DCE|HID0_DCI
+	ori	r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
 	sync
 	isync
 	mtspr	SPRN_HID0,r3
-	xori	r3,r3,HID0_DCI
+	xori	r3,r3,(HID0_DCI|HID0_ICFI)
 	mtspr	SPRN_HID0,r3
 	sync
 
@@ -110,11 +122,20 @@
 	lis	r4,2
 	mtctr	r4
 	lis	r4,0xfff0
-1:	lwzx	r0,r0,r4
+1:	lwz	r0,0(r4)
+	addi	r4,r4,32
+	bdnz	1b
+	sync
+	isync
+	lis	r4,2
+	mtctr	r4
+	lis	r4,0xfff0
+1:	dcbf	0,r4
 	addi	r4,r4,32
 	bdnz	1b
 	sync
 	isync
+
 	/* now disable L2 */
 	rlwinm	r5,r5,0,~L2CR_L2E
 	b	2f
@@ -135,6 +156,13 @@
 	mtspr	SPRN_L2CR,r4
 	sync
 	isync
+
+	/* Wait for the invalidation to complete */
+1:	mfspr	r3,SPRN_L2CR
+	rlwinm.	r0,r3,0,31,31
+	bne	1b
+
+	/* Clear L2I */
 	xoris	r4,r4,L2CR_L2I at h
 	sync
 	mtspr	SPRN_L2CR,r4
@@ -142,16 +170,18 @@
 
 	/* now disable the L1 data cache */
 	mfspr	r0,SPRN_HID0
-	rlwinm	r0,r0,0,~HID0_DCE
+	rlwinm	r0,r0,0,~(HID0_DCE|HID0_ICE)
 	mtspr	SPRN_HID0,r0
 	sync
 	isync
 
 	/* Restore HID0[DPM] to whatever it was before */
 	sync
-	mtspr	SPRN_HID0,r8
+	mfspr	r0,SPRN_HID0
+	rlwimi	r0,r8,0,11,11		/* Turn back HID0[DPM] */
+	mtspr	SPRN_HID0,r0
 	sync
-
+
 	/* restore DR and EE */
 	sync
 	mtmsr	r11
@@ -201,7 +231,7 @@
         mtctr   r4
  	li      r4,0
 1:
-        lwzx    r0,r0,r4
+        lwz     r0,0(r4)
         addi    r4,r4,32                /* Go to start of next cache line */
         bdnz    1b
         isync


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6.11-radeon-backlight.patch:
 radeon_base.c |   11 ++
 radeon_pm.c   |  283 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 293 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.11-radeon-backlight.patch ---
--- linux-2.6.11-rc4-tank/drivers/video/aty/radeon_pm.c.tppm	2005-02-20 20:09:02.000000000 +0200
+++ linux-2.6.11-rc4-tank/drivers/video/aty/radeon_pm.c	2005-02-20 21:35:27.000000000 +0200
@@ -25,8 +25,258 @@
 #include <asm/pmac_feature.h>
 #endif
 
+/* For detecting supported PC laptops */
+#ifdef CONFIG_X86
+#include <linux/dmi.h>
+#endif
+
 #include "ati_ids.h"
 
+#ifdef CONFIG_X86
+/* This array holds a list of supported PC laptops.
+ * Currently only few IBM models are tested.
+ * If you want to experiment, use dmidecode to find out
+ * vendor and product codes for Your laptop.
+ */
+static struct dmi_system_id __devinitdata radeonfb_dmi_table[] = {
+	{
+		/* Reported by George Avrunin <avrunin at math.umass.edu> */
+		.ident = "IBM ThinkPad T40 (2372-9CU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23729CU"),
+		},
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad R40 (2722-B3G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2722B3G"),
+		},
+	},
+	{
+		/* Reported by Klaus Kurzmann <mok at fluxnetz.de> */
+		.ident = "IBM ThinkPad T40 (2373-25G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237325G"),
+		},
+	},
+	{
+		/* Reported by Antti Andreimann <Antti.Andreimann at mail.ee> */
+		.ident = "IBM ThinkPad T41 (2373-2FG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23732FG"),
+		},
+	},
+	{
+		/* Reported by Antti P Miettinen <apm at brigitte.dna.fi> */
+		.ident = "IBM ThinkPad T40 (2373-4G2)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23734G2"),
+	      },
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T40 (2373-92G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237392G"),
+	      },
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T40 (2373-8CG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23738CG"),
+		},
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T40 (2373-94U)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237394U"),
+		},
+	},
+	{
+		/* Reported by Manuel Carro <mcarro at fi.upm.es> */
+		.ident = "IBM ThinkPad T40 (2373-94G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237394G"),
+		},
+	},
+	{
+		/* Reported by Peter Jones <pjones at redhat.com> */
+		.ident = "IBM ThinkPad T41 (2373-9FU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23739FU"),
+		},
+	},
+	{
+		/* Reported by Ajay Ramaswamy <ajay at ramaswamy.net> */
+		.ident = "IBM ThinkPad T41 (2373-9HU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23739HU"),
+	      },
+	},
+	{
+		/* Reported by Peter Jones <pjones at redhat.com> */
+		.ident = "IBM ThinkPad T40 (2373-BU7)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373BU7"),
+		},
+	},
+	{
+		/* Reported by Jerome Poggi <Jerome.Poggi at hsc.fr> */
+		.ident = "IBM ThinkPad T42 (2373-FWG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373FWG"),
+		},
+	},
+	{
+		/* Reported by Juerg Billeter <j at bitron.ch> */
+		.ident = "IBM ThinkPad T40p (2373-G1G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373G1G"),
+		},
+	},
+	{
+		/* Reported by Hartwig, Thomas <t.hartwig at itth.com> */
+		.ident = "IBM ThinkPad T40p (2373-G3G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373G3G"),
+		},
+	},
+	{
+		/* Reported by Eric Benson <eric_a_benson at yahoo.com> */
+		.ident = "IBM ThinkPad T41p (2373-GEU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373GEU"),
+		},
+	},
+	{
+		/* Reported by Dwight Barkley <barkley at maths.warwick.ac.uk> */
+		.ident = "IBM ThinkPad T42 (2373-JTU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373JTU"),
+		},
+	},
+	{
+		/* Reported by Vernon Mauery <vernux at us.ibm.com> */
+		.ident = "IBM ThinkPad T40 (2373-MU4)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373MU4"),
+		},
+	},
+	{
+		/* Reported by Ajay Ramaswamy <ajay at ramaswamy.net> */
+		.ident = "IBM ThinkPad T41 (2373-XNX)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373XNX"),
+	      },
+	},
+	{
+		/* Reported by obi <graziano at cs.ucsb.edu> */
+		.ident = "IBM ThinkPad T41 (2378-DEU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2378DEU"),
+		},
+	},
+	{
+		/* Reported by Volker Braun <vbraun at physics.upenn.edu> */
+		.ident = "IBM ThinkPad T41 (2379-DJU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2379DJU"),
+		},
+	},
+	{
+		/* Reported by Pete Toscano <pete at verisignlabs.com> */
+		.ident = "IBM ThinkPad T42 (2373-FWG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373FWG"),
+		},
+	},
+	{
+		/* Reported by Frank Schmitt <tonne2004 at gehheimdienst.de> */
+		.ident = "IBM ThinkPad R40 (2722-3GG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "27223GG"),
+		},
+	},
+	{
+		/* Reported by Nils Trebing <nils.trebing at uni-konstanz.de> */
+		.ident = "IBM ThinkPad R40 (2722-5MG)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "27225MG"),
+		},
+	},
+	{
+		/* Reported by Paul Ionescu <i_p_a_u_l at yahoo.com> */
+		.ident = "IBM ThinkPad T41 (2373-TG5)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2373TG5"),
+		},
+	},
+	{
+		/* Reported by Michele Lamarca <lammic at gmail.com> */
+		.ident = "IBM ThinkPad T40 (2373-22G)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "237322G"),
+		},
+	},
+	{
+		/* Reported by Henrik Brix Andersen <brix at gentoo.org> */
+		.ident = "IBM ThinkPad X31 (2672-XXH)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2672XXH"),
+		},
+	},
+	{
+		/* Reported by Matthew Saltzman <mjs at clemson.edu> */
+		.ident = "IBM ThinkPad T41 (2373-7JU)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "23737JU"),
+		},
+	},
+	{ },
+	/* Negative reports: */
+	/* IBM thinkpad T30 2366 -> machine hangs 
+	   Reported by: Jakob Schiotz <schiotz at fysik.dtu.dk> */
+	/* IBM thinkpad T42p 2373-KUU -> machine hangs as X starts
+	   Reported by: Dax Kelson <dax at gurulabs.com> */
+	/* IBM ThinkPad X31 2672-XXH -> works, but doesn't fix the LCD 
+	   backlight on during S3 issue.
+	   Reported by: Henrik Brix Andersen <brix at gentoo.org> */
+};
+
+extern int radeon_force_sleep;
+#endif
+
 static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
 {
 	u32 tmp;
@@ -852,7 +1102,14 @@
 	/* because both INPLL and OUTPLL take the same lock, that's why. */
 	tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND;
 	OUTPLL( pllMCLK_MISC, tmp);
-	
+
+	/* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset
+	 * and radeon chip dependent. Thus we only enable it on Mac for
+	 * now (until we get more info on how to compute the correct
+	 * value for various X86 bridges).
+	 */
+
+#ifdef CONFIG_PPC_PMAC
 	/* AGP PLL control */
 	if (rinfo->family <= CHIP_FAMILY_RV280) {
 		OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
@@ -864,6 +1121,7 @@
 		OUTREG(BUS_CNTL1, INREG(BUS_CNTL1));
 		OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000);
 	}
+#endif
 
 	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL)
 				  & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
@@ -2790,6 +3048,29 @@
 #endif
 	}
 #endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_OF) */
+
+/* The PM code also works on some PC laptops.
+ * Only a few models are actually tested so Your mileage may vary.
+ * We can do D2 on at least M7 and M9 on some IBM ThinkPad T41 models.
+ */
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+	if (radeon_force_sleep || dmi_check_system(radeonfb_dmi_table)) {
+		if (radeon_force_sleep)
+			printk("radeonfb: forcefully enabling sleep mode\n");
+		else
+			printk("radeonfb: enabling sleep mode\n");
+
+		if (rinfo->is_mobility && rinfo->pm_reg &&
+		    rinfo->family <= CHIP_FAMILY_RV250)
+			rinfo->pm_mode |= radeon_pm_d2;
+
+		/* Power down TV DAC, that saves a significant amount of power,
+		 * we'll have something better once we actually have some TVOut
+		 * support
+		 */
+		OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000);
+	}
+#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */
 }
 
 void radeonfb_pm_exit(struct radeonfb_info *rinfo)
--- linux-2.6.11-rc4-tank/drivers/video/aty/radeon_base.c.tppm	2005-02-20 20:08:15.000000000 +0200
+++ linux-2.6.11-rc4-tank/drivers/video/aty/radeon_base.c	2005-02-20 20:18:20.000000000 +0200
@@ -272,6 +272,9 @@
 #ifdef CONFIG_MTRR
 static int nomtrr = 0;
 #endif
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+int radeon_force_sleep = 0;
+#endif
 
 /*
  * prototypes
@@ -2530,6 +2533,10 @@
 			force_measure_pll = 1;
 		} else if (!strncmp(this_opt, "ignore_edid", 11)) {
 			ignore_edid = 1;
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+		} else if (!strncmp(this_opt, "force_sleep", 11)) {
+			radeon_force_sleep = 1;
+#endif
 		} else
 			mode_option = this_opt;
 	}
@@ -2585,3 +2592,7 @@
 MODULE_PARM_DESC(panel_yres, "int: set panel yres");
 module_param(mode_option, charp, 0);
 MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+module_param(radeon_force_sleep, int, 0);
+MODULE_PARM_DESC(radeon_force_sleep, "bool: force ACPI sleep mode on untested machines");
+#endif

linux-2.6.11-random-ehci-patch.patch:
 ehci-hcd.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6.11-random-ehci-patch.patch ---
--- linux-2.6.11/drivers/usb/host/ehci-hcd.c.orig	2005-05-01 10:01:22.152008984 +0100
+++ linux-2.6.11/drivers/usb/host/ehci-hcd.c	2005-05-01 10:25:00.418949184 +0100
@@ -382,6 +382,7 @@ static int ehci_hc_reset (struct usb_hcd
 	ehci->hcs_params = readl (&ehci->caps->hcs_params);
 
 #ifdef	CONFIG_PCI
+	writel(0, &ehci->regs->intr_enable);
 	if (hcd->self.controller->bus == &pci_bus_type) {
 		struct pci_dev	*pdev = to_pci_dev(hcd->self.controller);
 

linux-2.6.11-serial-tickle-nmi.patch:
 8250.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6.11-serial-tickle-nmi.patch ---

NMI Watchdog detected LOCKUP on CPU2CPU 2
Modules linked in: loop usb_storage md5 ipv6 parport_pc lp parport autofs4 i2c_dev i2c_core rfcomm l2cap bluetooth sunrpc pcdPid: 3138, comm: gpm Not tainted 2.6.11-1.1290_FC4smp
RIP: 0010:[<ffffffff80273b8a>] <ffffffff80273b8a>{serial_in+106}
RSP: 0018:ffff81003afc3d50  EFLAGS: 00000002
RAX: 0000000000000020 RBX: 0000000000000020 RCX: 0000000000000000
RDX: 00000000000003fd RSI: 0000000000000005 RDI: ffffffff804dcd60
RBP: 00000000000024fc R08: 000000000000000a R09: 0000000000000033
R10: ffff81001beb7c20 R11: 0000000000000020 R12: ffffffff804dcd60
R13: ffffffff804ade76 R14: 000000000000002b R15: 000000000000002c
FS:  00002aaaaaac4920(0000) GS:ffffffff804fca00(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00002aaaaabcb000 CR3: 000000003c0d0000 CR4: 00000000000006e0
Process gpm (pid: 3138, threadinfo ffff81003afc2000, task ffff81003eb63780)
Stack: ffffffff80275f2e 0000000000000000 ffffffff80448380 0000000000007d6b
       000000000000002c fffffffffffffbbf 0000000000000292 0000000000008000
       ffffffff80138e8c 0000000000007d97
Call Trace:<ffffffff80275f2e>{serial8250_console_write+270} <ffffffff80138e8c>{__call_console_drivers+76}
       <ffffffff8013914b>{release_console_sem+315} <ffffffff80260325>{con_open+149}
       <ffffffff80254e99>{tty_open+537} <ffffffff80192713>{chrdev_open+387}
       <ffffffff80188824>{dentry_open+260} <ffffffff80188994>{filp_open+68}
       <ffffffff80187b73>{get_unused_fd+227} <ffffffff80188a6c>{sys_open+76}
       <ffffffff8010ebc6>{tracesys+209}

Code: 0f b6 c0 c3 66 90 41 57 49 89 f7 41 56 41 be 00 01 00 00 41
console shuts up ...


--- linux-2.6.11/drivers/serial/8250.c~	2005-05-14 02:49:02.000000000 -0400
+++ linux-2.6.11/drivers/serial/8250.c	2005-05-14 02:54:30.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
+#include <linux/nmi.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -2098,9 +2098,11 @@ static inline void wait_for_xmitr(struct
 	/* Wait up to 1s for flow control if necessary */
 	if (up->port.flags & UPF_CONS_FLOW) {
 		tmout = 1000000;
-		while (--tmout &&
-		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+		while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
 			udelay(1);
+			if ((tmout % 1000) == 0)
+				touch_nmi_watchdog();
+		}
 	}
 }
 

linux-2.6.11-serport-oops-fix.patch:
 serport.c |   98 +++++++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 68 insertions(+), 30 deletions(-)

--- NEW FILE linux-2.6.11-serport-oops-fix.patch ---

From: Dmitry Torokhov <dtor_core at ameritech.net>

serport - avoid calling serio_interrupt or serio_write_wakeup on unregistered
port.  Also fix memory leak which could happen if serport was left unused by
moving serio allocation down to serport_ldisc_read.

Signed-off-by: Dmitry Torokhov <dtor at mail.ru>
Signed-off-by: Andrew Morton <akpm at osdl.org>
---

 25-akpm/drivers/input/serio/serport.c |   98 +++++++++++++++++++++++-----------
 1 files changed, 68 insertions(+), 30 deletions(-)

diff -puN drivers/input/serio/serport.c~serport-oops-fix drivers/input/serio/serport.c
--- 25/drivers/input/serio/serport.c~serport-oops-fix	2005-04-04 02:02:22.000000000 -0700
+++ 25-akpm/drivers/input/serio/serport.c	2005-04-04 02:02:22.000000000 -0700
@@ -27,11 +27,15 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS_LDISC(N_MOUSE);
 
 #define SERPORT_BUSY	1
+#define SERPORT_ACTIVE	2
+#define SERPORT_DEAD	3
 
 struct serport {
 	struct tty_struct *tty;
 	wait_queue_head_t wait;
 	struct serio *serio;
+	struct serio_device_id id;
+	spinlock_t lock;
 	unsigned long flags;
 };
 
@@ -45,11 +49,29 @@ static int serport_serio_write(struct se
 	return -(serport->tty->driver->write(serport->tty, &data, 1) != 1);
 }
 
+static int serport_serio_open(struct serio *serio)
+{
+	struct serport *serport = serio->port_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serport->lock, flags);
+	set_bit(SERPORT_ACTIVE, &serport->flags);
+	spin_unlock_irqrestore(&serport->lock, flags);
+
+	return 0;
+}
+
+
 static void serport_serio_close(struct serio *serio)
 {
 	struct serport *serport = serio->port_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serport->lock, flags);
+	clear_bit(SERPORT_ACTIVE, &serport->flags);
+	set_bit(SERPORT_DEAD, &serport->flags);
+	spin_unlock_irqrestore(&serport->lock, flags);
 
-	serport->serio->id.type = 0;
 	wake_up_interruptible(&serport->wait);
 }
 
@@ -61,36 +83,21 @@ static void serport_serio_close(struct s
 static int serport_ldisc_open(struct tty_struct *tty)
 {
 	struct serport *serport;
-	struct serio *serio;
-	char name[64];
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	serport = kmalloc(sizeof(struct serport), GFP_KERNEL);
-	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-	if (unlikely(!serport || !serio)) {
-		kfree(serport);
-		kfree(serio);
+	serport = kcalloc(1, sizeof(struct serport), GFP_KERNEL);
+	if (!serport)
 		return -ENOMEM;
-	}
 
-	memset(serport, 0, sizeof(struct serport));
-	serport->serio = serio;
-	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 	serport->tty = tty;
-	tty->disc_data = serport;
-
-	memset(serio, 0, sizeof(struct serio));
-	strlcpy(serio->name, "Serial port", sizeof(serio->name));
-	snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
-	serio->id.type = SERIO_RS232;
-	serio->write = serport_serio_write;
-	serio->close = serport_serio_close;
-	serio->port_data = serport;
-
+	spin_lock_init(&serport->lock);
 	init_waitqueue_head(&serport->wait);
 
+	tty->disc_data = serport;
+	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+
 	return 0;
 }
 
@@ -100,7 +107,8 @@ static int serport_ldisc_open(struct tty
 
 static void serport_ldisc_close(struct tty_struct *tty)
 {
-	struct serport *serport = (struct serport*) tty->disc_data;
+	struct serport *serport = (struct serport *) tty->disc_data;
+
 	kfree(serport);
 }
 
@@ -116,9 +124,19 @@ static void serport_ldisc_close(struct t
 static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
+	unsigned long flags;
 	int i;
+
+	spin_lock_irqsave(&serport->lock, flags);
+
+	if (!test_bit(SERPORT_ACTIVE, &serport->flags))
+		goto out;
+
 	for (i = 0; i < count; i++)
 		serio_interrupt(serport->serio, cp[i], 0, NULL);
+
+out:
+	spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
@@ -141,16 +159,33 @@ static int serport_ldisc_room(struct tty
 static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char __user * buf, size_t nr)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
+	struct serio *serio;
 	char name[64];
 
 	if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
 		return -EBUSY;
 
+	serport->serio = serio = kcalloc(1, sizeof(struct serio), GFP_KERNEL);
+	if (!serio)
+		return -ENOMEM;
+
+	strlcpy(serio->name, "Serial port", sizeof(serio->name));
+	snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
+	serio->id = serport->id;
+	serio->id.type = SERIO_RS232;
+	serio->write = serport_serio_write;
+	serio->open = serport_serio_open;
+	serio->close = serport_serio_close;
+	serio->port_data = serport;
+
 	serio_register_port(serport->serio);
 	printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name));
-	wait_event_interruptible(serport->wait, !serport->serio->id.type);
+
+	wait_event_interruptible(serport->wait, test_bit(SERPORT_DEAD, &serport->flags));
 	serio_unregister_port(serport->serio);
+	serport->serio = NULL;
 
+	clear_bit(SERPORT_DEAD, &serport->flags);
 	clear_bit(SERPORT_BUSY, &serport->flags);
 
 	return 0;
@@ -163,16 +198,15 @@ static ssize_t serport_ldisc_read(struct
 static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
-	struct serio *serio = serport->serio;
 	unsigned long type;
 
 	if (cmd == SPIOCSTYPE) {
 		if (get_user(type, (unsigned long __user *) arg))
 			return -EFAULT;
 
-		serio->id.proto	= type & 0x000000ff;
-		serio->id.id	= (type & 0x0000ff00) >> 8;
-		serio->id.extra	= (type & 0x00ff0000) >> 16;
+		serport->id.proto = type & 0x000000ff;
+		serport->id.id	  = (type & 0x0000ff00) >> 8;
+		serport->id.extra = (type & 0x00ff0000) >> 16;
 
 		return 0;
 	}
@@ -182,9 +216,13 @@ static int serport_ldisc_ioctl(struct tt
 
 static void serport_ldisc_write_wakeup(struct tty_struct * tty)
 {
-	struct serport *sp = (struct serport *) tty->disc_data;
+	struct serport *serport = (struct serport *) tty->disc_data;
+	unsigned long flags;
 
-	serio_drv_write_wakeup(sp->serio);
+	spin_lock_irqsave(&serport->lock, flags);
+	if (test_bit(SERPORT_ACTIVE, &serport->flags))
+		serio_drv_write_wakeup(serport->serio);
+	spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
_

linux-2.6.11-slab-backtrace.patch:
 slab.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6.11-slab-backtrace.patch ---
Sometimes it's possible that the debug info gets disabled
due to alignment issues. If we then get a corruption we
have very few clues wtf happened.

--- linux-2.6.11/mm/slab.c~	2005-04-20 03:07:42.000000000 -0400
+++ linux-2.6.11/mm/slab.c	2005-04-20 03:07:48.000000000 -0400
@@ -1064,6 +1064,7 @@ static void check_poison_obj(kmem_cache_
 				printk(KERN_ERR "Slab corruption: (%s) start=%p, len=%d\n",
 						print_tainted(), realobj, size);
 				print_objinfo(cachep, objp, 0);
+				dump_stack();
 			}
 			/* Hexdump the affected line */
 			i = (i/16)*16;

linux-2.6.11-taint-check.patch:
 arch/i386/kernel/traps.c |    5 ++++-
 include/linux/kernel.h   |    1 +
 kernel/panic.c           |    7 +++++++
 mm/slab.c                |   12 +++++++++++-
 4 files changed, 23 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6.11-taint-check.patch ---
--- linux-2.6.11/kernel/panic.c~	2005-04-20 03:48:57.000000000 -0400
+++ linux-2.6.11/kernel/panic.c	2005-04-20 03:49:28.000000000 -0400
@@ -159,3 +159,10 @@ void add_taint(unsigned flag)
 	tainted |= flag;
 }
 EXPORT_SYMBOL(add_taint);
+
+int check_tainted(void)
+{
+	return tainted;
+}
+EXPORT_SYMBOL_GPL(check_tainted);
+
--- linux-2.6.11/include/linux/kernel.h~	2005-04-20 03:49:49.000000000 -0400
+++ linux-2.6.11/include/linux/kernel.h	2005-04-20 03:49:56.000000000 -0400
@@ -156,6 +156,7 @@ extern int panic_on_oops;
 extern int tainted;
 extern const char *print_tainted(void);
 extern void add_taint(unsigned);
+extern int check_tainted(void);
 
 #define crashdump_mode()       unlikely(netdump_mode || diskdump_mode)
 
--- linux-2.6.11/arch/i386/kernel/traps.c~	2005-04-20 03:57:00.000000000 -0400
+++ linux-2.6.11/arch/i386/kernel/traps.c	2005-04-20 03:58:23.000000000 -0400
@@ -182,7 +182,10 @@ void show_stack(struct task_struct *task
 			break;
 		if (i && ((i % 8) == 0))
 			printk("\n       ");
-		printk("%08lx ", *stack++);
+		if ((check_tainted() != 0) && (i==0))
+			printk("badc0ded ");
+		else
+			printk("%08lx ", *stack++);
 	}
 	printk("\nCall Trace:\n");
 	show_trace(task, esp);
--- linux-2.6.11/mm/slab.c~	2005-04-21 00:48:06.000000000 -0400
+++ linux-2.6.11/mm/slab.c	2005-04-21 00:57:00.000000000 -0400
@@ -1006,7 +1006,17 @@ static void dump_line(char *data, int of
 	int i;
 	printk(KERN_ERR "%03x:", offset);
 	for (i=0;i<limit;i++) {
-		printk(" %02x", (unsigned char)data[offset+i]);
+		if (check_tainted() == 0)
+			printk(" %02x", (unsigned char)data[offset+i]);
+		else {
+			switch (i) {
+			case 0:	printk(" f3 3d");
+					break;
+			case 1: break;
+			default:
+				printk(" %02x", (unsigned char)data[offset+i]);
+			}
+		}
 	}
 	printk("\n");
 }

linux-2.6.11-via-irq-quirk.patch:
 arch/i386/pci/irq.c    |    5 -----
 drivers/acpi/pci_irq.c |    4 ----
 drivers/pci/quirks.c   |   40 ++++++++++++++++++++++++----------------
 include/linux/acpi.h   |    6 ++++--
 4 files changed, 28 insertions(+), 27 deletions(-)

--- NEW FILE linux-2.6.11-via-irq-quirk.patch ---

tree 4c1b48179d7f18b3e037a473d8e04708b619ac5c
parent 2efe86b809d97debaaf9fcc13b041aedf15bd3d2
author Len Brown <lenb at toshiba.hsd1.ma.comcast.net> Fri, 27 May 2005 12:21:50 -0400
committer Linus Torvalds <torvalds at ppc970.osdl.org> Fri, 27 May 2005 22:15:04 -0700

[PATCH] VIA IRQ quirk

Delete quirk_via_bridge(), restore quirk_via_irqpic() -- but now
improved to be invoked upon device ENABLE, and now only for VIA devices
-- not all devices behind VIA bridges.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas at hp.com>
Signed-off-by: Len Brown <len.brown at intel.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

 arch/i386/pci/irq.c    |    5 -----
 drivers/acpi/pci_irq.c |    4 ----
 drivers/pci/quirks.c   |   40 ++++++++++++++++++++++++----------------
 include/linux/acpi.h   |    5 ++++-
 4 files changed, 28 insertions(+), 26 deletions(-)

Index: arch/i386/pci/irq.c
===================================================================
--- 87e039397918f4c5b0a21d798589a8ce517bfa2d/arch/i386/pci/irq.c  (mode:100644 sha1:d6598da4b67bbc6fc1dde2ad121c692471813175)
+++ 4c1b48179d7f18b3e037a473d8e04708b619ac5c/arch/i386/pci/irq.c  (mode:100644 sha1:da21b1d07c15529e954a21ab8b48a0c48bd0df6b)
@@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq)
 static int pirq_enable_irq(struct pci_dev *dev)
 {
 	u8 pin;
-	extern int via_interrupt_line_quirk;
 	struct pci_dev *temp_dev;
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_de
 		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
 		       'A' + pin, pci_name(dev), msg);
 	}
-	/* VIA bridges use interrupt line for apic/pci steering across
-	   the V-Link */
-	else if (via_interrupt_line_quirk)
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
 	return 0;
 }
 
Index: drivers/acpi/pci_irq.c
===================================================================
--- 87e039397918f4c5b0a21d798589a8ce517bfa2d/drivers/acpi/pci_irq.c  (mode:100644 sha1:12b0eea634073399d5f219e460dbf88acde98b34)
+++ 4c1b48179d7f18b3e037a473d8e04708b619ac5c/drivers/acpi/pci_irq.c  (mode:100644 sha1:8093f2e003215156d376c9a8c086e8d9dfaf9d30)
@@ -391,7 +391,6 @@ acpi_pci_irq_enable (
 	u8			pin = 0;
 	int			edge_level = ACPI_LEVEL_SENSITIVE;
 	int			active_high_low = ACPI_ACTIVE_LOW;
-	extern int		via_interrupt_line_quirk;
 	char			*link = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
@@ -444,9 +443,6 @@ acpi_pci_irq_enable (
 		}
  	}
 
-	if (via_interrupt_line_quirk)
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15);
-
 	dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
 	printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
Index: drivers/pci/quirks.c
===================================================================
--- 87e039397918f4c5b0a21d798589a8ce517bfa2d/drivers/pci/quirks.c  (mode:100644 sha1:026aa04669a29467559af822be1ad69d06f61ef0)
+++ 4c1b48179d7f18b3e037a473d8e04708b619ac5c/drivers/pci/quirks.c  (mode:100644 sha1:afc9d29acd8aa15521330a99c752ee07ed149c7d)
@@ -18,6 +18,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
 /* Deal with broken BIOS'es that neglect to enable passive release,
@@ -467,9 +468,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AM
  * non-x86 architectures (yes Via exists on PPC among other places),
  * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
  * interrupts delivered properly.
- *
- * TODO: When we have device-specific interrupt routers,
- * quirk_via_irqpic will go away from quirks.
  */
 
 /*
@@ -494,6 +492,29 @@ static void __devinit quirk_via_acpi(str
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi );
 
+static void __devinit quirk_via_irqpic(struct pci_dev *dev)
+{
+	u8 irq, new_irq;
+
+#ifdef CONFIG_X86_IO_APIC
+	if (nr_ioapics && !skip_ioapic_setup)
+		return;
+#endif
+#ifdef CONFIG_ACPI
+	if (acpi_irq_model != ACPI_IRQ_MODEL_PIC)
+		return;
+#endif
+	new_irq = dev->irq & 0xf;
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+	if (new_irq != irq) {
+		printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n",
+			pci_name(dev), irq, new_irq);
+		udelay(15);	/* unknown if delay really needed */
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
+	}
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic);
+
 /*
  * PIIX3 USB: We have to disable USB interrupts that are
  * hardwired to PIRQD# and may be shared with an
@@ -683,19 +704,6 @@ static void __init quirk_disable_pxb(str
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454NX,	quirk_disable_pxb );
 
-/*
- *	VIA northbridges care about PCI_INTERRUPT_LINE
- */
-int via_interrupt_line_quirk;
-
-static void __devinit quirk_via_bridge(struct pci_dev *pdev)
-{
-	if(pdev->devfn == 0) {
-		printk(KERN_INFO "PCI: Via IRQ fixup\n");
-		via_interrupt_line_quirk = 1;
-	}
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_ANY_ID,                     quirk_via_bridge );
 
 /*
  *	Serverworks CSB5 IDE does not fully support native mode
Index: include/linux/acpi.h
===================================================================
--- 87e039397918f4c5b0a21d798589a8ce517bfa2d/include/linux/acpi.h  (mode:100644 sha1:aefe6d051ace16fbcf13fe2c0d86e6fda90729e8)
+++ 4c1b48179d7f18b3e037a473d8e04708b619ac5c/include/linux/acpi.h  (mode:100644 sha1:d5a55bdb9c3cca13bc4c66e01da0b440341f0781)
@@ -25,6 +25,8 @@
 #ifndef _LINUX_ACPI_H
 #define _LINUX_ACPI_H
 
+#ifdef	CONFIG_ACPI
+
 #ifndef _LINUX
 #define _LINUX
 #endif
@@ -533,4 +535,5 @@ static inline int acpi_get_pxm(acpi_hand
 
 extern int pnpacpi_disabled;
 
-#endif /*_LINUX_ACPI_H*/
+#endif	/* CONFIG_ACPI */
+#endif	/*_LINUX_ACPI_H*/
-


linux-2.6.12-audit-git.patch:
 MAINTAINERS                    |    7 +
 fs/namei.c                     |    2 
 include/linux/audit.h          |   31 ++++--
 kernel/audit.c                 |   91 +++++++++++++-------
 kernel/auditsc.c               |  186 ++++++++++++++++++++++++++++-------------
 security/selinux/avc.c         |    4 
 security/selinux/hooks.c       |    2 
 security/selinux/ss/services.c |    4 
 8 files changed, 223 insertions(+), 104 deletions(-)

--- NEW FILE linux-2.6.12-audit-git.patch ---
Index: MAINTAINERS
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/MAINTAINERS  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/MAINTAINERS  (mode:100644)
@@ -358,6 +358,13 @@
 W:	http://linux-atm.sourceforge.net
 S:	Maintained
 
+AUDIT SUBSYSTEM
+P:	David Woodhouse
+M:	dwmw2 at infradead.org
+L:	linux-audit at redhat.com
+W:	http://people.redhat.com/sgrubb/audit/
+S:	Maintained
+
 ATMEL WIRELESS DRIVER
 P:	Simon Kelley
 M:	simon at thekelleys.org.uk
Index: fs/namei.c
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/fs/namei.c  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/fs/namei.c  (mode:100644)
@@ -1043,7 +1043,7 @@
 out:
 	if (unlikely(current->audit_context
 		     && nd && nd->dentry && nd->dentry->d_inode))
-		audit_inode(name, nd->dentry->d_inode);
+		audit_inode(name, nd->dentry->d_inode, flags);
 	return retval;
 }
 
Index: include/linux/audit.h
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/include/linux/audit.h  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/include/linux/audit.h  (mode:100644)
@@ -51,7 +51,8 @@
 #define AUDIT_WATCH_LIST	1009	/* List all file/dir watches */
 #define AUDIT_SIGNAL_INFO	1010	/* Get info about sender of signal to auditd */
 
-#define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages uninteresting to kernel */
+#define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages mostly uninteresting to kernel */
+#define AUDIT_USER_AVC		1107	/* We filter this differently */
 #define AUDIT_LAST_USER_MSG	1199
  
 #define AUDIT_DAEMON_START      1200    /* Daemon startup record */
@@ -75,10 +76,15 @@
 #define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */
 
 /* Rule flags */
-#define AUDIT_PER_TASK 0x01	/* Apply rule at task creation (not syscall) */
-#define AUDIT_AT_ENTRY 0x02	/* Apply rule at syscall entry */
-#define AUDIT_AT_EXIT  0x04	/* Apply rule at syscall exit */
-#define AUDIT_PREPEND  0x10	/* Prepend to front of list */
+#define AUDIT_FILTER_USER	0x00	/* Apply rule to user-generated messages */
+#define AUDIT_FILTER_TASK	0x01	/* Apply rule at task creation (not syscall) */
+#define AUDIT_FILTER_ENTRY	0x02	/* Apply rule at syscall entry */
+#define AUDIT_FILTER_WATCH	0x03	/* Apply rule to file system watches */
+#define AUDIT_FILTER_EXIT	0x04	/* Apply rule at syscall exit */
+
+#define AUDIT_NR_FILTERS	5
+
+#define AUDIT_FILTER_PREPEND	0x10	/* Prepend to front of list */
 
 /* Rule actions */
 #define AUDIT_NEVER    0	/* Do not build context if rule matches */
@@ -215,7 +221,7 @@
 extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
 extern void audit_getname(const char *name);
 extern void audit_putname(const char *name);
-extern void audit_inode(const char *name, const struct inode *inode);
+extern void audit_inode(const char *name, const struct inode *inode, unsigned flags);
 
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
@@ -230,6 +236,7 @@
 extern int audit_sockaddr(int len, void *addr);
 extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern void audit_signal_info(int sig, struct task_struct *t);
+extern int audit_filter_user(int pid, int type);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -237,7 +244,7 @@
 #define audit_syscall_exit(t,f,r) do { ; } while (0)
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
-#define audit_inode(n,i) do { ; } while (0)
+#define audit_inode(n,i,f) do { ; } while (0)
 #define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
 #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
 #define audit_get_loginuid(c) ({ -1; })
@@ -246,16 +253,17 @@
 #define audit_sockaddr(len, addr) ({ 0; })
 #define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_signal_info(s,t) do { ; } while (0)
+#define audit_filter_user(p,t) ({ 1; })
 #endif
 
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
 				/* Public API */
-extern void		    audit_log(struct audit_context *ctx, int type,
-				      const char *fmt, ...)
-			    __attribute__((format(printf,3,4)));
+extern void		    audit_log(struct audit_context *ctx, int gfp_mask,
+				      int type, const char *fmt, ...)
+				      __attribute__((format(printf,4,5)));
 
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx,int type);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, int type);
 extern void		    audit_log_format(struct audit_buffer *ab,
 					     const char *fmt, ...)
 			    __attribute__((format(printf,2,3)));
@@ -274,6 +282,7 @@
 					     int done, int multi,
 					     void *payload, int size);
 extern void		    audit_log_lost(const char *message);
+extern struct semaphore audit_netlink_sem;
 #else
 #define audit_log(c,t,f,...) do { ; } while (0)
 #define audit_log_start(c,t) ({ NULL; })
Index: kernel/audit.c
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/kernel/audit.c  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/kernel/audit.c  (mode:100644)
@@ -106,18 +106,12 @@
 static struct sk_buff_head audit_skb_queue;
 static struct task_struct *kauditd_task;
 static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
-
-/* There are three lists of rules -- one to search at task creation
- * time, one to search at syscall entry time, and another to search at
- * syscall exit time. */
-static LIST_HEAD(audit_tsklist);
-static LIST_HEAD(audit_entlist);
-static LIST_HEAD(audit_extlist);
+static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
 
 /* The netlink socket is only to be read by 1 CPU, which lets us assume
  * that list additions and deletions never happen simultaneously in
  * auditsc.c */
-static DECLARE_MUTEX(audit_netlink_sem);
+DECLARE_MUTEX(audit_netlink_sem);
 
 /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
  * audit records.  Since printk uses a 1024 byte buffer, this buffer
@@ -137,6 +131,7 @@
 	struct list_head     list;
 	struct sk_buff       *skb;	/* formatted skb ready to send */
 	struct audit_context *ctx;	/* NULL or associated context */
+	int		     gfp_mask;
 };
 
 static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
@@ -233,7 +228,7 @@
 {
 	int old		 = audit_rate_limit;
 	audit_rate_limit = limit;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 
 			"audit_rate_limit=%d old=%d by auid=%u",
 			audit_rate_limit, old, loginuid);
 	return old;
@@ -243,7 +238,7 @@
 {
 	int old		 = audit_backlog_limit;
 	audit_backlog_limit = limit;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 			"audit_backlog_limit=%d old=%d by auid=%u",
 			audit_backlog_limit, old, loginuid);
 	return old;
@@ -255,7 +250,7 @@
 	if (state != 0 && state != 1)
 		return -EINVAL;
 	audit_enabled = state;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 			"audit_enabled=%d old=%d by auid=%u",
 			audit_enabled, old, loginuid);
 	return old;
@@ -269,7 +264,7 @@
 	    && state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 	audit_failure = state;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 			"audit_failure=%d old=%d by auid=%u",
 			audit_failure, old, loginuid);
 	return old;
@@ -281,6 +276,7 @@
 
 	while (1) {
 		skb = skb_dequeue(&audit_skb_queue);
+		wake_up(&audit_backlog_wait);
 		if (skb) {
 			if (audit_pid) {
 				int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
@@ -423,7 +419,7 @@
 		if (status_get->mask & AUDIT_STATUS_PID) {
 			int old   = audit_pid;
 			audit_pid = status_get->pid;
-			audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 				"audit_pid=%d old=%d by auid=%u",
 				  audit_pid, old, loginuid);
 		}
@@ -435,15 +431,21 @@
 		break;
 	case AUDIT_USER:
 	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
-		ab = audit_log_start(NULL, msg_type);
-		if (!ab)
-			break;	/* audit_panic has been called */
-		audit_log_format(ab,
-				 "user pid=%d uid=%u auid=%u"
-				 " msg='%.1024s'",
-				 pid, uid, loginuid, (char *)data);
-		audit_set_pid(ab, pid);
-		audit_log_end(ab);
+		if (!audit_enabled && msg_type != AUDIT_USER_AVC)
+			return 0;
+
+		err = audit_filter_user(pid, msg_type);
+		if (err == 1) {
+			err = 0;
+			ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+			if (ab) {
+				audit_log_format(ab,
+						 "user pid=%d uid=%u auid=%u msg='%.1024s'",
+						 pid, uid, loginuid, (char *)data);
+				audit_set_pid(ab, pid);
+				audit_log_end(ab);
+			}
+		}
 		break;
 	case AUDIT_ADD:
 	case AUDIT_DEL:
@@ -522,7 +524,7 @@
 	skb_queue_head_init(&audit_skb_queue);
 	audit_initialized = 1;
 	audit_enabled = audit_default;
-	audit_log(NULL, AUDIT_KERNEL, "initialized");
+	audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
 	return 0;
 }
 __initcall(audit_init);
@@ -586,6 +588,7 @@
 		goto err;
 
 	ab->ctx = ctx;
+	ab->gfp_mask = gfp_mask;
 	nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
 	nlh->nlmsg_type = type;
 	nlh->nlmsg_flags = 0;
@@ -644,17 +647,42 @@
  * syscall, then the syscall is marked as auditable and an audit record
  * will be written at syscall exit.  If there is no associated task, tsk
  * should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
+
+struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
+				     int type)
 {
 	struct audit_buffer	*ab	= NULL;
 	struct timespec		t;
 	unsigned int		serial;
+	int reserve;
 
 	if (!audit_initialized)
 		return NULL;
 
-	if (audit_backlog_limit
-	    && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
+	if (gfp_mask & __GFP_WAIT)
+		reserve = 0;
+	else
+		reserve = 5; /* Allow atomic callers to go up to five 
+				entries over the normal backlog limit */
+
+	while (audit_backlog_limit
+	       && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
+		if (gfp_mask & __GFP_WAIT) {
+			int ret = 1;
+			/* Wait for auditd to drain the queue a little */
+			DECLARE_WAITQUEUE(wait, current);
+			set_current_state(TASK_INTERRUPTIBLE);
+			add_wait_queue(&audit_backlog_wait, &wait);
+
+			if (audit_backlog_limit &&
+			    skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
+				ret = schedule_timeout(HZ * 60);
+
+			__set_current_state(TASK_RUNNING);
+			remove_wait_queue(&audit_backlog_wait, &wait);
+			if (ret)
+				continue;
+		}
 		if (audit_rate_check())
 			printk(KERN_WARNING
 			       "audit: audit_backlog=%d > "
@@ -665,7 +693,7 @@
 		return NULL;
 	}
 
-	ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
+	ab = audit_buffer_alloc(ctx, gfp_mask, type);
 	if (!ab) {
 		audit_log_lost("out of memory in audit_log_start");
 		return NULL;
@@ -689,7 +717,7 @@
 {
 	struct sk_buff *skb = ab->skb;
 	int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
-				   GFP_ATOMIC);
+				   ab->gfp_mask);
 	if (ret < 0) {
 		audit_log_lost("out of memory in audit_expand");
 		return 0;
@@ -808,7 +836,7 @@
 		audit_log_format(ab, " %s", prefix);
 
 	/* We will allow 11 spaces for ' (deleted)' to be appended */
-	path = kmalloc(PATH_MAX+11, GFP_KERNEL);
+	path = kmalloc(PATH_MAX+11, ab->gfp_mask);
 	if (!path) {
 		audit_log_format(ab, "<no memory>");
 		return;
@@ -849,12 +877,13 @@
 /* Log an audit record.  This is a convenience function that calls
  * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
  * called in any context. */
-void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
+void audit_log(struct audit_context *ctx, int gfp_mask, int type, 
+	       const char *fmt, ...)
 {
 	struct audit_buffer *ab;
 	va_list args;
 
-	ab = audit_log_start(ctx, type);
+	ab = audit_log_start(ctx, gfp_mask, type);
 	if (ab) {
 		va_start(args, fmt);
 		audit_log_vformat(ab, fmt, args);
Index: kernel/auditsc.c
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/kernel/auditsc.c  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/kernel/auditsc.c  (mode:100644)
@@ -39,6 +39,7 @@
 #include <linux/audit.h>
 #include <linux/personality.h>
 #include <linux/time.h>
+#include <linux/kthread.h>
 #include <asm/unistd.h>
 
 /* 0 = no checking
@@ -95,6 +96,7 @@
 	uid_t		uid;
 	gid_t		gid;
 	dev_t		rdev;
+	unsigned	flags;
 };
 
 struct audit_aux_data {
@@ -167,9 +169,16 @@
 /* There are three lists of rules -- one to search at task creation
  * time, one to search at syscall entry time, and another to search at
  * syscall exit time. */
-static LIST_HEAD(audit_tsklist);
-static LIST_HEAD(audit_entlist);
-static LIST_HEAD(audit_extlist);
+static struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
+	LIST_HEAD_INIT(audit_filter_list[0]),
+	LIST_HEAD_INIT(audit_filter_list[1]),
+	LIST_HEAD_INIT(audit_filter_list[2]),
+	LIST_HEAD_INIT(audit_filter_list[3]),
+	LIST_HEAD_INIT(audit_filter_list[4]),
+#if AUDIT_NR_FILTERS != 5
+#error Fix audit_filter_list initialiser
+#endif
+};
 
 struct audit_entry {
 	struct list_head  list;
@@ -210,16 +219,15 @@
 /* Note that audit_add_rule and audit_del_rule are called via
  * audit_receive() in audit.c, and are protected by
  * audit_netlink_sem. */
-static inline int audit_add_rule(struct audit_entry *entry,
-				 struct list_head *list)
+static inline void audit_add_rule(struct audit_entry *entry,
+				  struct list_head *list)
 {
-	if (entry->rule.flags & AUDIT_PREPEND) {
-		entry->rule.flags &= ~AUDIT_PREPEND;
+	if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
+		entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
 		list_add_rcu(&entry->list, list);
 	} else {
 		list_add_tail_rcu(&entry->list, list);
 	}
-	return 0;
 }
 
 static void audit_free_rule(struct rcu_head *head)
@@ -245,7 +253,7 @@
 			return 0;
 		}
 	}
-	return -EFAULT;		/* No matching rule */
+	return -ENOENT;		/* No matching rule */
 }
 
 /* Copy rule from user-space to kernel-space.  Called during
@@ -260,6 +268,8 @@
 		return -1;
 	if (s->field_count < 0 || s->field_count > AUDIT_MAX_FIELDS)
 		return -1;
+	if ((s->flags & ~AUDIT_FILTER_PREPEND) >= AUDIT_NR_FILTERS)
+		return -1;
 
 	d->flags	= s->flags;
 	d->action	= s->action;
@@ -272,27 +282,60 @@
 	return 0;
 }
 
+static int audit_list_rules(void *_dest)
+{
+	int pid, seq;
+	int *dest = _dest;
+	struct audit_entry *entry;
+	int i;
+
+	pid = dest[0];
+	seq = dest[1];
+	kfree(dest);
+
+	down(&audit_netlink_sem);
+
+	/* The *_rcu iterators not needed here because we are
+	   always called with audit_netlink_sem held. */
+	for (i=0; i<AUDIT_NR_FILTERS; i++) {
+		list_for_each_entry(entry, &audit_filter_list[i], list)
+			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
+					 &entry->rule, sizeof(entry->rule));
+	}
+	audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
+	
+	up(&audit_netlink_sem);
+	return 0;
+}
+
 int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
 							uid_t loginuid)
 {
-	u32		   flags;
 	struct audit_entry *entry;
+	struct task_struct *tsk;
+	int *dest;
 	int		   err = 0;
+	unsigned listnr;
 
 	switch (type) {
 	case AUDIT_LIST:
-		/* The *_rcu iterators not needed here because we are
-		   always called with audit_netlink_sem held. */
-		list_for_each_entry(entry, &audit_tsklist, list)
-			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
-					 &entry->rule, sizeof(entry->rule));
-		list_for_each_entry(entry, &audit_entlist, list)
-			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
-					 &entry->rule, sizeof(entry->rule));
-		list_for_each_entry(entry, &audit_extlist, list)
-			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
-					 &entry->rule, sizeof(entry->rule));
-		audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
+		/* We can't just spew out the rules here because we might fill
+		 * the available socket buffer space and deadlock waiting for
+		 * auditctl to read from it... which isn't ever going to
+		 * happen if we're actually running in the context of auditctl
+		 * trying to _send_ the stuff */
+		 
+		dest = kmalloc(2 * sizeof(int), GFP_KERNEL);
+		if (!dest)
+			return -ENOMEM;
+		dest[0] = pid;
+		dest[1] = seq;
+
+		tsk = kthread_run(audit_list_rules, dest, "audit_list_rules");
+		if (IS_ERR(tsk)) {
+			kfree(dest);
+			err = PTR_ERR(tsk);
+		}
 		break;
 	case AUDIT_ADD:
 		if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
@@ -301,26 +344,20 @@
 			kfree(entry);
 			return -EINVAL;
 		}
-		flags = entry->rule.flags;
-		if (!err && (flags & AUDIT_PER_TASK))
-			err = audit_add_rule(entry, &audit_tsklist);
-		if (!err && (flags & AUDIT_AT_ENTRY))
-			err = audit_add_rule(entry, &audit_entlist);
-		if (!err && (flags & AUDIT_AT_EXIT))
-			err = audit_add_rule(entry, &audit_extlist);
-		audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+		listnr = entry->rule.flags & ~AUDIT_FILTER_PREPEND;
+		audit_add_rule(entry, &audit_filter_list[listnr]);
+		audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 
 				"auid=%u added an audit rule\n", loginuid);
 		break;
 	case AUDIT_DEL:
-		flags =((struct audit_rule *)data)->flags;
-		if (!err && (flags & AUDIT_PER_TASK))
-			err = audit_del_rule(data, &audit_tsklist);
-		if (!err && (flags & AUDIT_AT_ENTRY))
-			err = audit_del_rule(data, &audit_entlist);
-		if (!err && (flags & AUDIT_AT_EXIT))
-			err = audit_del_rule(data, &audit_extlist);
-		audit_log(NULL, AUDIT_CONFIG_CHANGE,
-				"auid=%u removed an audit rule\n", loginuid);
+		listnr =((struct audit_rule *)data)->flags & ~AUDIT_FILTER_PREPEND;
+		if (listnr >= AUDIT_NR_FILTERS)
+			return -EINVAL;
+
+		err = audit_del_rule(data, &audit_filter_list[listnr]);
+		if (!err)
+			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+				  "auid=%u removed an audit rule\n", loginuid);
 		break;
 	default:
 		return -EINVAL;
@@ -454,7 +491,7 @@
 	enum audit_state   state;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(e, &audit_tsklist, list) {
+	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
 		if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
 			rcu_read_unlock();
 			return state;
@@ -478,6 +515,9 @@
 	int		   word = AUDIT_WORD(ctx->major);
 	int		   bit  = AUDIT_BIT(ctx->major);
 
+	if (audit_pid && ctx->pid == audit_pid)
+		return AUDIT_DISABLED;
+
 	rcu_read_lock();
 	list_for_each_entry_rcu(e, list, list) {
 		if ((e->rule.mask[word] & bit) == bit
@@ -490,6 +530,37 @@
 	return AUDIT_BUILD_CONTEXT;
 }
 
+int audit_filter_user(int pid, int type)
+{
+	struct task_struct *tsk;
+	struct audit_entry *e;
+	enum audit_state   state;
+	int ret = 1;
+
+	read_lock(&tasklist_lock);
+	tsk = find_task_by_pid(pid);
+	if (tsk)
+		get_task_struct(tsk);
+	read_unlock(&tasklist_lock);
+
+	if (!tsk)
+		return -ESRCH;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
+		if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
+			if (state == AUDIT_DISABLED)
+				ret = 0;
+			break;
+		}
+	}
+	rcu_read_unlock();
+	put_task_struct(tsk);
+
+	return 1; /* Audit by default */
+
+}
+
 /* This should be called with task_lock() held. */
 static inline struct audit_context *audit_get_context(struct task_struct *tsk,
 						      int return_valid,
@@ -504,7 +575,7 @@
 
 	if (context->in_syscall && !context->auditable) {
 		enum audit_state state;
-		state = audit_filter_syscall(tsk, context, &audit_extlist);
+		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
 		if (state == AUDIT_RECORD_CONTEXT)
 			context->auditable = 1;
 	}
@@ -685,7 +756,7 @@
 	struct audit_buffer *ab;
 	struct audit_aux_data *aux;
 
-	ab = audit_log_start(context, AUDIT_SYSCALL);
+	ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "arch=%x syscall=%d",
@@ -717,7 +788,7 @@
 
 	for (aux = context->aux; aux; aux = aux->next) {
 
-		ab = audit_log_start(context, aux->type);
+		ab = audit_log_start(context, GFP_KERNEL, aux->type);
 		if (!ab)
 			continue; /* audit_panic has been called */
 
@@ -754,14 +825,14 @@
 	}
 
 	if (context->pwd && context->pwdmnt) {
-		ab = audit_log_start(context, AUDIT_CWD);
+		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
 		if (ab) {
 			audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
 			audit_log_end(ab);
 		}
 	}
 	for (i = 0; i < context->name_count; i++) {
-		ab = audit_log_start(context, AUDIT_PATH);
+		ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
 		if (!ab)
 			continue; /* audit_panic has been called */
 
@@ -770,6 +841,8 @@
 			audit_log_format(ab, " name=");
 			audit_log_untrustedstring(ab, context->names[i].name);
 		}
+		audit_log_format(ab, " flags=%x\n", context->names[i].flags);
+			 
 		if (context->names[i].ino != (unsigned long)-1)
 			audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
 					     " ouid=%u ogid=%u rdev=%02x:%02x",
@@ -800,7 +873,7 @@
 
 	/* Check for system calls that do not go through the exit
 	 * function (e.g., exit_group), then free context block. */
-	if (context->in_syscall && context->auditable && context->pid != audit_pid)
+	if (context->in_syscall && context->auditable)
 		audit_log_exit(context);
 
 	audit_free_context(context);
@@ -876,7 +949,7 @@
 
 	state = context->state;
 	if (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT)
-		state = audit_filter_syscall(tsk, context, &audit_entlist);
+		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
 	if (likely(state == AUDIT_DISABLED))
 		return;
 
@@ -905,7 +978,7 @@
 	if (likely(!context))
 		return;
 
-	if (context->in_syscall && context->auditable && context->pid != audit_pid)
+	if (context->in_syscall && context->auditable)
 		audit_log_exit(context);
 
 	context->in_syscall = 0;
@@ -996,7 +1069,7 @@
 
 /* Store the inode and device from a lookup.  Called from
  * fs/namei.c:path_lookup(). */
-void audit_inode(const char *name, const struct inode *inode)
+void audit_inode(const char *name, const struct inode *inode, unsigned flags)
 {
 	int idx;
 	struct audit_context *context = current->audit_context;
@@ -1022,12 +1095,13 @@
 		++context->ino_count;
 #endif
 	}
-	context->names[idx].ino  = inode->i_ino;
-	context->names[idx].dev	 = inode->i_sb->s_dev;
-	context->names[idx].mode = inode->i_mode;
-	context->names[idx].uid  = inode->i_uid;
-	context->names[idx].gid  = inode->i_gid;
-	context->names[idx].rdev = inode->i_rdev;
+	context->names[idx].flags = flags;
+	context->names[idx].ino   = inode->i_ino;
+	context->names[idx].dev	  = inode->i_sb->s_dev;
+	context->names[idx].mode  = inode->i_mode;
+	context->names[idx].uid   = inode->i_uid;
+	context->names[idx].gid   = inode->i_gid;
+	context->names[idx].rdev  = inode->i_rdev;
 }
 
 void auditsc_get_stamp(struct audit_context *ctx,
@@ -1044,7 +1118,7 @@
 	if (task->audit_context) {
 		struct audit_buffer *ab;
 
-		ab = audit_log_start(NULL, AUDIT_LOGIN);
+		ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
 		if (ab) {
 			audit_log_format(ab, "login pid=%d uid=%u "
 				"old auid=%u new auid=%u",
Index: security/selinux/avc.c
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/security/selinux/avc.c  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/security/selinux/avc.c  (mode:100644)
@@ -242,7 +242,7 @@
 	avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
 					     0, SLAB_PANIC, NULL, NULL);
 
-	audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
+	audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
 }
 
 int avc_get_hash_stats(char *page)
@@ -550,7 +550,7 @@
 			return;
 	}
 
-	ab = audit_log_start(current->audit_context, AUDIT_AVC);
+	ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");
Index: security/selinux/hooks.c
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/security/selinux/hooks.c  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/security/selinux/hooks.c  (mode:100644)
@@ -3419,7 +3419,7 @@
 	err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
 	if (err) {
 		if (err == -EINVAL) {
-			audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+			audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
 				  "SELinux:  unrecognized netlink message"
 				  " type=%hu for sclass=%hu\n",
 				  nlh->nlmsg_type, isec->sclass);
Index: security/selinux/ss/services.c
===================================================================
--- df4be07322c1bee5aa47e283a15377843ca2b05e/security/selinux/ss/services.c  (mode:100644)
+++ 99b6d171a827cbea045119f90b62de25ff92a70f/security/selinux/ss/services.c  (mode:100644)
@@ -365,7 +365,7 @@
 		goto out;
 	if (context_struct_to_string(tcontext, &t, &tlen) < 0)
 		goto out;
-	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+	audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
 	          "security_validate_transition:  denied for"
 	          " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
 	          o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@ -742,7 +742,7 @@
 		goto out;
 	if (context_struct_to_string(newcontext, &n, &nlen) < 0)
 		goto out;
-	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+	audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
 		  "security_compute_sid:  invalid context %s"
 		  " for scontext=%s"
 		  " tcontext=%s"

linux-2.6.12-audit-merge.patch:
 arch/ppc/Kconfig               |   17 +
 arch/ppc/kernel/entry.S        |   16 -
 arch/ppc/kernel/ppc_ksyms.c    |    2 
 arch/ppc/kernel/ptrace.c       |   40 ++
 include/asm-ppc/seccomp.h      |   10 
 include/asm-ppc/thread_info.h  |    7 
 include/linux/audit.h          |   94 ++++--
 init/Kconfig                   |    3 
 kernel/audit.c                 |  589 ++++++++++++++++++++---------------------
 kernel/auditsc.c               |  259 ++++++++++++------
 kernel/signal.c                |    7 
 net/socket.c                   |    9 
 security/selinux/avc.c         |   40 +-
 security/selinux/hooks.c       |    2 
 security/selinux/nlmsgtab.c    |   10 
 security/selinux/ss/services.c |    4 
 16 files changed, 675 insertions(+), 434 deletions(-)

--- NEW FILE linux-2.6.12-audit-merge.patch ---
Index: arch/ppc/Kconfig
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/arch/ppc/Kconfig  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/arch/ppc/Kconfig  (mode:100644)
@@ -1083,6 +1083,23 @@
 
 source kernel/power/Kconfig
 
+config SECCOMP
+	bool "Enable seccomp to safely compute untrusted bytecode"
+	depends on PROC_FS
+	default y
+	help
+	  This kernel feature is useful for number crunching applications
+	  that may need to compute untrusted bytecode during their
+	  execution. By using pipes or other transports made available to
+	  the process as file descriptors supporting the read/write
+	  syscalls, it's possible to isolate those applications in
+	  their own address space using seccomp. Once seccomp is
+	  enabled via /proc/<pid>/seccomp, it cannot be disabled
+	  and the task is only allowed to execute a few safe syscalls
+	  defined by each seccomp mode.
+
+	  If unsure, say Y. Only embedded should say N here.
+
 endmenu
 
 config ISA_DMA_API
Index: arch/ppc/kernel/entry.S
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/arch/ppc/kernel/entry.S  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/arch/ppc/kernel/entry.S  (mode:100644)
@@ -202,7 +202,7 @@
 	rlwinm	r11,r11,0,~_TIFL_FORCE_NOERROR
 	stw	r11,TI_LOCAL_FLAGS(r10)
 	lwz	r11,TI_FLAGS(r10)
-	andi.	r11,r11,_TIF_SYSCALL_TRACE
+	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
 syscall_dotrace_cont:
 	cmplwi	0,r0,NR_syscalls
@@ -237,7 +237,7 @@
 	SYNC
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
 	bne-	syscall_exit_work
 syscall_exit_cont:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
@@ -277,7 +277,8 @@
 	SAVE_NVGPRS(r1)
 	li	r0,0xc00
 	stw	r0,TRAP(r1)
-	bl	do_syscall_trace
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	do_syscall_trace_enter
 	lwz	r0,GPR0(r1)	/* Restore original registers */
 	lwz	r3,GPR3(r1)
 	lwz	r4,GPR4(r1)
@@ -291,7 +292,7 @@
 syscall_exit_work:
 	stw	r6,RESULT(r1)	/* Save result */
 	stw	r3,GPR3(r1)	/* Update return value */
-	andi.	r0,r9,_TIF_SYSCALL_TRACE
+	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
 	beq	5f
 	ori	r10,r10,MSR_EE
 	SYNC
@@ -303,7 +304,8 @@
 	li	r4,0xc00
 	stw	r4,TRAP(r1)
 4:
-	bl	do_syscall_trace
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	do_syscall_trace_leave
 	REST_NVGPRS(r1)
 2:
 	lwz	r3,GPR3(r1)
@@ -627,8 +629,8 @@
 	subi	r1,r3,STACK_FRAME_OVERHEAD
 	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
 	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,_TIF_SYSCALL_TRACE
-	bnel-	do_syscall_trace
+	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
+	bnel-	do_syscall_trace_leave
 	/* fall through */
 
 	.globl	ret_from_except_full
Index: arch/ppc/kernel/ppc_ksyms.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/arch/ppc/kernel/ppc_ksyms.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/arch/ppc/kernel/ppc_ksyms.c  (mode:100644)
@@ -55,7 +55,6 @@
 #define EXPORT_SYMTAB_STROPS
 
 extern void transfer_to_handler(void);
-extern void do_syscall_trace(void);
 extern void do_IRQ(struct pt_regs *regs);
 extern void MachineCheckException(struct pt_regs *regs);
 extern void AlignmentException(struct pt_regs *regs);
@@ -74,7 +73,6 @@
 EXPORT_SYMBOL(clear_pages);
 EXPORT_SYMBOL(clear_user_page);
 EXPORT_SYMBOL(do_signal);
-EXPORT_SYMBOL(do_syscall_trace);
 EXPORT_SYMBOL(transfer_to_handler);
 EXPORT_SYMBOL(do_IRQ);
 EXPORT_SYMBOL(MachineCheckException);
Index: arch/ppc/kernel/ptrace.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/arch/ppc/kernel/ptrace.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/arch/ppc/kernel/ptrace.c  (mode:100644)
@@ -27,6 +27,9 @@
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/signal.h>
+#include <linux/seccomp.h>
+#include <linux/audit.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -455,11 +458,10 @@
 	return ret;
 }
 
-void do_syscall_trace(void)
+static void do_syscall_trace(void)
 {
-        if (!test_thread_flag(TIF_SYSCALL_TRACE)
-	    || !(current->ptrace & PT_PTRACED))
-		return;
+	/* the 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 				 ? 0x80 : 0));
 
@@ -473,3 +475,33 @@
 		current->exit_code = 0;
 	}
 }
+
+void do_syscall_trace_enter(struct pt_regs *regs)
+{
+	if (test_thread_flag(TIF_SYSCALL_TRACE)
+	    && (current->ptrace & PT_PTRACED))
+		do_syscall_trace();
+
+	if (unlikely(current->audit_context))
+		audit_syscall_entry(current, AUDIT_ARCH_PPC,
+				    regs->gpr[0],
+				    regs->gpr[3], regs->gpr[4],
+				    regs->gpr[5], regs->gpr[6]);
+}
+
+void do_syscall_trace_leave(struct pt_regs *regs)
+{
+	secure_computing(regs->gpr[0]);
+
+	if (unlikely(current->audit_context))
+		audit_syscall_exit(current,
+				   (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+				   regs->result);
+
+	if ((test_thread_flag(TIF_SYSCALL_TRACE))
+	    && (current->ptrace & PT_PTRACED))
+		do_syscall_trace();
+}
+
+EXPORT_SYMBOL(do_syscall_trace_enter);
+EXPORT_SYMBOL(do_syscall_trace_leave);
Index: include/asm-ppc/seccomp.h
===================================================================
--- /dev/null  (tree:e4660ac807d16a7bd3af6db2dfce539acd94ba23)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/include/asm-ppc/seccomp.h  (mode:100644)
@@ -0,0 +1,10 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
Index: include/asm-ppc/thread_info.h
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/include/asm-ppc/thread_info.h  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/include/asm-ppc/thread_info.h  (mode:100644)
@@ -77,12 +77,19 @@
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
 #define TIF_MEMDIE		5
+#define TIF_SYSCALL_AUDIT       6       /* syscall auditing active */
+#define TIF_SECCOMP             7      /* secure computing */
+
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_SYSCALL_AUDIT      (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP            (1<<TIF_SECCOMP)
+
+#define _TIF_SYSCALL_T_OR_A     (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 /*
  * Non racy (local) flags bit numbers
Index: include/linux/audit.h
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/include/linux/audit.h  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/include/linux/audit.h  (mode:100644)
@@ -27,15 +27,52 @@
 #include <linux/sched.h>
 #include <linux/elf.h>
 
-/* Request and reply types */
-#define AUDIT_GET      1000	/* Get status */
-#define AUDIT_SET      1001	/* Set status (enable/disable/auditd) */
-#define AUDIT_LIST     1002	/* List filtering rules */
-#define AUDIT_ADD      1003	/* Add filtering rule */
-#define AUDIT_DEL      1004	/* Delete filtering rule */
-#define AUDIT_USER     1005	/* Send a message from user-space */
-#define AUDIT_LOGIN    1006     /* Define the login id and informaiton */
-#define AUDIT_KERNEL   2000	/* Asynchronous audit record. NOT A REQUEST. */
+/* The netlink messages for the audit system is divided into blocks:
+ * 1000 - 1099 are for commanding the audit system
+ * 1100 - 1199 user space trusted application messages
+ * 1200 - 1299 messages internal to the audit daemon
+ * 1300 - 1399 audit event messages
+ * 1400 - 1499 SE Linux use
+ * 1500 - 1999 future use
+ * 2000 is for otherwise unclassified kernel audit messages
+ *
+ * Messages from 1000-1199 are bi-directional. 1200-1299 are exclusively user
+ * space. Anything over that is kernel --> user space communication.
+ */
+#define AUDIT_GET		1000	/* Get status */
+#define AUDIT_SET		1001	/* Set status (enable/disable/auditd) */
+#define AUDIT_LIST		1002	/* List syscall filtering rules */
+#define AUDIT_ADD		1003	/* Add syscall filtering rule */
+#define AUDIT_DEL		1004	/* Delete syscall filtering rule */
+#define AUDIT_USER		1005	/* Message from userspace -- deprecated */
+#define AUDIT_LOGIN		1006	/* Define the login id and information */
+#define AUDIT_WATCH_INS		1007	/* Insert file/dir watch entry */
+#define AUDIT_WATCH_REM		1008	/* Remove file/dir watch entry */
+#define AUDIT_WATCH_LIST	1009	/* List all file/dir watches */
+#define AUDIT_SIGNAL_INFO	1010	/* Get info about sender of signal to auditd */
+
+#define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages uninteresting to kernel */
+#define AUDIT_LAST_USER_MSG	1199
+ 
+#define AUDIT_DAEMON_START      1200    /* Daemon startup record */
+#define AUDIT_DAEMON_END        1201    /* Daemon normal stop record */
+#define AUDIT_DAEMON_ABORT      1202    /* Daemon error stop record */
+#define AUDIT_DAEMON_CONFIG     1203    /* Daemon config change */
+
+#define AUDIT_SYSCALL		1300	/* Syscall event */
+#define AUDIT_FS_WATCH		1301	/* Filesystem watch event */
+#define AUDIT_PATH		1302	/* Filename path information */
+#define AUDIT_IPC		1303	/* IPC record */
+#define AUDIT_SOCKETCALL	1304	/* sys_socketcall arguments */
+#define AUDIT_CONFIG_CHANGE	1305	/* Audit system configuration change */
+#define AUDIT_SOCKADDR		1306	/* sockaddr copied as syscall arg */
+#define AUDIT_CWD		1307	/* Current working directory */
+
+#define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
+#define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
+#define AUDIT_AVC_PATH		1402	/* dentry, vfsmount pair from avc */
+
+#define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */
 
 /* Rule flags */
 #define AUDIT_PER_TASK 0x01	/* Apply rule at task creation (not syscall) */
@@ -132,16 +169,9 @@
 #define AUDIT_ARCH_V850		(EM_V850|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_X86_64	(EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
 
-#ifndef __KERNEL__
-struct audit_message {
-	struct nlmsghdr nlh;
-	char		data[1200];
-};
-#endif
-
 struct audit_status {
 	__u32		mask;		/* Bit mask for valid entries */
-	__u32		enabled;	/* 1 = enabled, 0 = disbaled */
+	__u32		enabled;	/* 1 = enabled, 0 = disabled */
 	__u32		failure;	/* Failure-to-log action */
 	__u32		pid;		/* pid of auditd process */
 	__u32		rate_limit;	/* messages rate limit (per second) */
@@ -161,6 +191,11 @@
 
 #ifdef __KERNEL__
 
+struct audit_sig_info {
+	uid_t		uid;
+	pid_t		pid;
+};
+
 struct audit_buffer;
 struct audit_context;
 struct inode;
@@ -185,11 +220,16 @@
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
 				 void *data, uid_t loginuid);
-extern void audit_get_stamp(struct audit_context *ctx,
-			    struct timespec *t, unsigned int *serial);
+extern unsigned int audit_serial(void);
+extern void auditsc_get_stamp(struct audit_context *ctx,
+			      struct timespec *t, unsigned int *serial);
 extern int  audit_set_loginuid(struct task_struct *task, uid_t loginuid);
 extern uid_t audit_get_loginuid(struct audit_context *ctx);
 extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
+extern int audit_socketcall(int nargs, unsigned long *args);
+extern int audit_sockaddr(int len, void *addr);
+extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
+extern void audit_signal_info(int sig, struct task_struct *t);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -198,18 +238,24 @@
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
 #define audit_inode(n,i) do { ; } while (0)
+#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
+#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
 #define audit_get_loginuid(c) ({ -1; })
 #define audit_ipc_perms(q,u,g,m) ({ 0; })
+#define audit_socketcall(n,a) ({ 0; })
+#define audit_sockaddr(len, addr) ({ 0; })
+#define audit_avc_path(dentry, mnt) ({ 0; })
+#define audit_signal_info(s,t) do { ; } while (0)
 #endif
 
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
 				/* Public API */
-extern void		    audit_log(struct audit_context *ctx,
+extern void		    audit_log(struct audit_context *ctx, int type,
 				      const char *fmt, ...)
-			    __attribute__((format(printf,2,3)));
+			    __attribute__((format(printf,3,4)));
 
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx,int type);
 extern void		    audit_log_format(struct audit_buffer *ab,
 					     const char *fmt, ...)
 			    __attribute__((format(printf,2,3)));
@@ -229,8 +275,8 @@
 					     void *payload, int size);
 extern void		    audit_log_lost(const char *message);
 #else
-#define audit_log(t,f,...) do { ; } while (0)
-#define audit_log_start(t) ({ NULL; })
+#define audit_log(c,t,f,...) do { ; } while (0)
+#define audit_log_start(c,t) ({ NULL; })
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
Index: init/Kconfig
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/init/Kconfig  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/init/Kconfig  (mode:100644)
@@ -164,6 +164,7 @@
 
 config AUDIT
 	bool "Auditing support"
+	depends on NET
 	default y if SECURITY_SELINUX
 	help
 	  Enable auditing infrastructure that can be used with another
@@ -173,7 +174,7 @@
 
 config AUDITSYSCALL
 	bool "Enable system-call auditing support"
-	depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
+	depends on AUDIT && (X86 || PPC || PPC64 || ARCH_S390 || IA64 || UML)
 	default y if SECURITY_SELINUX
 	help
 	  Enable low-overhead system-call auditing infrastructure that
Index: kernel/audit.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/kernel/audit.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/kernel/audit.c  (mode:100644)
@@ -46,6 +46,8 @@
 #include <asm/types.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/err.h>
+#include <linux/kthread.h>
 
 #include <linux/audit.h>
 
@@ -68,7 +70,7 @@
 
 /* If audit records are to be written to the netlink socket, audit_pid
  * contains the (non-zero) pid. */
-static int	audit_pid;
+int		audit_pid;
 
 /* If audit_limit is non-zero, limit the rate of sending audit records
  * to that number per second.  This prevents DoS attacks, but results in
@@ -77,7 +79,10 @@
 
 /* Number of outstanding audit_buffers allowed. */
 static int	audit_backlog_limit = 64;
-static atomic_t	audit_backlog	    = ATOMIC_INIT(0);
+
+/* The identity of the user shutting down the audit system. */
+uid_t		audit_sig_uid = -1;
+pid_t		audit_sig_pid = -1;
 
 /* Records can be lost in several ways:
    0) [suppressed in audit_alloc]
@@ -91,19 +96,17 @@
 /* The netlink socket. */
 static struct sock *audit_sock;
 
-/* There are two lists of audit buffers.  The txlist contains audit
- * buffers that cannot be sent immediately to the netlink device because
- * we are in an irq context (these are sent later in a tasklet).
- *
- * The second list is a list of pre-allocated audit buffers (if more
+/* The audit_freelist is a list of pre-allocated audit buffers (if more
  * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
  * being placed on the freelist). */
-static DEFINE_SPINLOCK(audit_txlist_lock);
 static DEFINE_SPINLOCK(audit_freelist_lock);
 static int	   audit_freelist_count = 0;
-static LIST_HEAD(audit_txlist);
 static LIST_HEAD(audit_freelist);
 
+static struct sk_buff_head audit_skb_queue;
+static struct task_struct *kauditd_task;
+static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
+
 /* There are three lists of rules -- one to search at task creation
  * time, one to search at syscall entry time, and another to search at
  * syscall exit time. */
@@ -112,7 +115,7 @@
 static LIST_HEAD(audit_extlist);
 
 /* The netlink socket is only to be read by 1 CPU, which lets us assume
- * that list additions and deletions never happen simultaneiously in
+ * that list additions and deletions never happen simultaneously in
  * auditsc.c */
 static DECLARE_MUTEX(audit_netlink_sem);
 
@@ -132,21 +135,14 @@
  * use simultaneously. */
 struct audit_buffer {
 	struct list_head     list;
-	struct sk_buff_head  sklist;	/* formatted skbs ready to send */
+	struct sk_buff       *skb;	/* formatted skb ready to send */
 	struct audit_context *ctx;	/* NULL or associated context */
-	int		     len;	/* used area of tmp */
-	char		     tmp[AUDIT_BUFSIZ];
-
-				/* Pointer to header and contents */
-	struct nlmsghdr      *nlh;
-	int		     total;
-	int		     type;
-	int		     pid;
 };
 
-void audit_set_type(struct audit_buffer *ab, int type)
+static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
 {
-	ab->type = type;
+	struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
+	nlh->nlmsg_pid = pid;
 }
 
 struct audit_entry {
@@ -154,9 +150,6 @@
 	struct audit_rule rule;
 };
 
-static void audit_log_end_irq(struct audit_buffer *ab);
-static void audit_log_end_fast(struct audit_buffer *ab);
-
 static void audit_panic(const char *message)
 {
 	switch (audit_failure)
@@ -227,10 +220,8 @@
 
 	if (print) {
 		printk(KERN_WARNING
-		       "audit: audit_lost=%d audit_backlog=%d"
-		       " audit_rate_limit=%d audit_backlog_limit=%d\n",
+		       "audit: audit_lost=%d audit_rate_limit=%d audit_backlog_limit=%d\n",
 		       atomic_read(&audit_lost),
-		       atomic_read(&audit_backlog),
 		       audit_rate_limit,
 		       audit_backlog_limit);
 		audit_panic(message);
@@ -242,7 +233,8 @@
 {
 	int old		 = audit_rate_limit;
 	audit_rate_limit = limit;
-	audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
+	audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+			"audit_rate_limit=%d old=%d by auid=%u",
 			audit_rate_limit, old, loginuid);
 	return old;
 }
@@ -251,7 +243,8 @@
 {
 	int old		 = audit_backlog_limit;
 	audit_backlog_limit = limit;
-	audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_backlog_limit=%d old=%d by auid=%u",
 			audit_backlog_limit, old, loginuid);
 	return old;
 }
@@ -262,8 +255,9 @@
 	if (state != 0 && state != 1)
 		return -EINVAL;
 	audit_enabled = state;
-	audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
-		  audit_enabled, old, loginuid);
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_enabled=%d old=%d by auid=%u",
+			audit_enabled, old, loginuid);
 	return old;
 }
 
@@ -275,12 +269,44 @@
 	    && state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 	audit_failure = state;
-	audit_log(NULL, "audit_failure=%d old=%d by auid %u",
-		  audit_failure, old, loginuid);
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_failure=%d old=%d by auid=%u",
+			audit_failure, old, loginuid);
 	return old;
 }
 
-#ifdef CONFIG_NET
+int kauditd_thread(void *dummy)
+{
+	struct sk_buff *skb;
+
+	while (1) {
+		skb = skb_dequeue(&audit_skb_queue);
+		if (skb) {
+			if (audit_pid) {
+				int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
+				if (err < 0) {
+					BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
+					printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
+					audit_pid = 0;
+				}
+			} else {
+				printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
+				kfree_skb(skb);
+			}
+		} else {
+			DECLARE_WAITQUEUE(wait, current);
+			set_current_state(TASK_INTERRUPTIBLE);
+			add_wait_queue(&kauditd_wait, &wait);
+
+			if (!skb_queue_len(&audit_skb_queue))
+				schedule();
+
+			__set_current_state(TASK_RUNNING);
+			remove_wait_queue(&kauditd_wait, &wait);
+		}
+	}
+}
+
 void audit_send_reply(int pid, int seq, int type, int done, int multi,
 		      void *payload, int size)
 {
@@ -293,13 +319,16 @@
 
 	skb = alloc_skb(len, GFP_KERNEL);
 	if (!skb)
-		goto nlmsg_failure;
+		return;
 
-	nlh		 = NLMSG_PUT(skb, pid, seq, t, len - sizeof(*nlh));
+	nlh		 = NLMSG_PUT(skb, pid, seq, t, size);
 	nlh->nlmsg_flags = flags;
 	data		 = NLMSG_DATA(nlh);
 	memcpy(data, payload, size);
-	netlink_unicast(audit_sock, skb, pid, MSG_DONTWAIT);
+
+	/* Ignore failure. It'll only happen if the sender goes away,
+	   because our timeout is set to infinite. */
+	netlink_unicast(audit_sock, skb, pid, 0);
 	return;
 
 nlmsg_failure:			/* Used by NLMSG_PUT */
@@ -321,10 +350,12 @@
 	case AUDIT_SET:
 	case AUDIT_ADD:
 	case AUDIT_DEL:
+	case AUDIT_SIGNAL_INFO:
 		if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
 			err = -EPERM;
 		break;
 	case AUDIT_USER:
+	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
 		if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
 			err = -EPERM;
 		break;
@@ -344,11 +375,21 @@
 	struct audit_buffer	*ab;
 	u16			msg_type = nlh->nlmsg_type;
 	uid_t			loginuid; /* loginuid of sender */
+	struct audit_sig_info   sig_data;
 
 	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
 	if (err)
 		return err;
 
+	/* As soon as there's any sign of userspace auditd, start kauditd to talk to it */
+	if (!kauditd_task)
+		kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
+	if (IS_ERR(kauditd_task)) {
+		err = PTR_ERR(kauditd_task);
+		kauditd_task = NULL;
+		return err;
+	}
+
 	pid  = NETLINK_CREDS(skb)->pid;
 	uid  = NETLINK_CREDS(skb)->uid;
 	loginuid = NETLINK_CB(skb).loginuid;
@@ -363,7 +404,7 @@
 		status_set.rate_limit	 = audit_rate_limit;
 		status_set.backlog_limit = audit_backlog_limit;
 		status_set.lost		 = atomic_read(&audit_lost);
-		status_set.backlog	 = atomic_read(&audit_backlog);
+		status_set.backlog	 = skb_queue_len(&audit_skb_queue);
 		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0,
 				 &status_set, sizeof(status_set));
 		break;
@@ -382,7 +423,8 @@
 		if (status_get->mask & AUDIT_STATUS_PID) {
 			int old   = audit_pid;
 			audit_pid = status_get->pid;
-			audit_log(NULL, "audit_pid=%d old=%d by auid %u",
+			audit_log(NULL, AUDIT_CONFIG_CHANGE,
+				"audit_pid=%d old=%d by auid=%u",
 				  audit_pid, old, loginuid);
 		}
 		if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
@@ -392,18 +434,15 @@
 							loginuid);
 		break;
 	case AUDIT_USER:
-		ab = audit_log_start(NULL);
+	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
+		ab = audit_log_start(NULL, msg_type);
 		if (!ab)
 			break;	/* audit_panic has been called */
 		audit_log_format(ab,
-				 "user pid=%d uid=%d length=%d loginuid=%u"
+				 "user pid=%d uid=%u auid=%u"
 				 " msg='%.1024s'",
-				 pid, uid,
-				 (int)(nlh->nlmsg_len
-				       - ((char *)data - (char *)nlh)),
-				 loginuid, (char *)data);
-		ab->type = AUDIT_USER;
-		ab->pid  = pid;
+				 pid, uid, loginuid, (char *)data);
+		audit_set_pid(ab, pid);
 		audit_log_end(ab);
 		break;
 	case AUDIT_ADD:
@@ -412,12 +451,14 @@
 			return -EINVAL;
 		/* fallthrough */
 	case AUDIT_LIST:
-#ifdef CONFIG_AUDITSYSCALL
 		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
 					   uid, seq, data, loginuid);
-#else
-		err = -EOPNOTSUPP;
-#endif
+		break;
+	case AUDIT_SIGNAL_INFO:
+		sig_data.uid = audit_sig_uid;
+		sig_data.pid = audit_sig_pid;
+		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 
+				0, 0, &sig_data, sizeof(sig_data));
 		break;
 	default:
 		err = -EINVAL;
@@ -467,87 +508,6 @@
 	up(&audit_netlink_sem);
 }
 
-/* Move data from tmp buffer into an skb.  This is an extra copy, and
- * that is unfortunate.  However, the copy will only occur when a record
- * is being written to user space, which is already a high-overhead
- * operation.  (Elimination of the copy is possible, for example, by
- * writing directly into a pre-allocated skb, at the cost of wasting
- * memory. */
-static void audit_log_move(struct audit_buffer *ab)
-{
-	struct sk_buff	*skb;
-	char		*start;
-	int		extra = ab->nlh ? 0 : NLMSG_SPACE(0);
-
-	/* possible resubmission */
-	if (ab->len == 0)
-		return;
-
-	skb = skb_peek_tail(&ab->sklist);
-	if (!skb || skb_tailroom(skb) <= ab->len + extra) {
-		skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
-		if (!skb) {
-			ab->len = 0; /* Lose information in ab->tmp */
-			audit_log_lost("out of memory in audit_log_move");
-			return;
-		}
-		__skb_queue_tail(&ab->sklist, skb);
-		if (!ab->nlh)
-			ab->nlh = (struct nlmsghdr *)skb_put(skb,
-							     NLMSG_SPACE(0));
-	}
-	start = skb_put(skb, ab->len);
-	memcpy(start, ab->tmp, ab->len);
-	ab->len = 0;
-}
-
-/* Iterate over the skbuff in the audit_buffer, sending their contents
- * to user space. */
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&ab->sklist))) {
-		int retval = 0;
-
-		if (audit_pid) {
-			if (ab->nlh) {
-				ab->nlh->nlmsg_len   = ab->total;
-				ab->nlh->nlmsg_type  = ab->type;
-				ab->nlh->nlmsg_flags = 0;
-				ab->nlh->nlmsg_seq   = 0;
-				ab->nlh->nlmsg_pid   = ab->pid;
-			}
-			skb_get(skb); /* because netlink_* frees */
-			retval = netlink_unicast(audit_sock, skb, audit_pid,
-						 MSG_DONTWAIT);
-		}
-		if (retval == -EAGAIN &&
-		    (atomic_read(&audit_backlog)) < audit_backlog_limit) {
-			skb_queue_head(&ab->sklist, skb);
-			audit_log_end_irq(ab);
-			return 1;
-		}
-		if (retval < 0) {
-			if (retval == -ECONNREFUSED) {
-				printk(KERN_ERR
-				       "audit: *NO* daemon at audit_pid=%d\n",
-				       audit_pid);
-				audit_pid = 0;
-			} else
-				audit_log_lost("netlink socket too busy");
-		}
-		if (!audit_pid) { /* No daemon */
-			int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
-			int len    = skb->len - offset;
-			skb->data[offset + len] = '\0';
-			printk(KERN_ERR "%s\n", skb->data + offset);
-		}
-		kfree_skb(skb);
-		ab->nlh = NULL;
-	}
-	return 0;
-}
 
 /* Initialize audit support at boot time. */
 static int __init audit_init(void)
@@ -558,40 +518,13 @@
 	if (!audit_sock)
 		audit_panic("cannot initialize netlink socket");
 
+	audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+	skb_queue_head_init(&audit_skb_queue);
 	audit_initialized = 1;
 	audit_enabled = audit_default;
-	audit_log(NULL, "initialized");
+	audit_log(NULL, AUDIT_KERNEL, "initialized");
 	return 0;
 }
-
-#else
-/* Without CONFIG_NET, we have no skbuffs.  For now, print what we have
- * in the buffer. */
-static void audit_log_move(struct audit_buffer *ab)
-{
-	printk(KERN_ERR "%*.*s\n", ab->len, ab->len, ab->tmp);
-	ab->len = 0;
-}
-
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
-	return 0;
-}
-
-/* Initialize audit support at boot time. */
-int __init audit_init(void)
-{
-	printk(KERN_INFO "audit: initializing WITHOUT netlink support\n");
-	audit_sock = NULL;
-	audit_pid  = 0;
-
-	audit_initialized = 1;
-	audit_enabled = audit_default;
-	audit_log(NULL, "initialized");
-	return 0;
-}
-#endif
-
 __initcall(audit_init);
 
 /* Process kernel command-line parameter at boot time.  audit=0 or audit=1. */
@@ -608,6 +541,102 @@
 
 __setup("audit=", audit_enable);
 
+static void audit_buffer_free(struct audit_buffer *ab)
+{
+	unsigned long flags;
+
+	if (!ab)
+		return;
+
+	if (ab->skb)
+		kfree_skb(ab->skb);
+
+	spin_lock_irqsave(&audit_freelist_lock, flags);
+	if (++audit_freelist_count > AUDIT_MAXFREE)
+		kfree(ab);
+	else
+		list_add(&ab->list, &audit_freelist);
+	spin_unlock_irqrestore(&audit_freelist_lock, flags);
+}
+
+static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
+						int gfp_mask, int type)
+{
+	unsigned long flags;
+	struct audit_buffer *ab = NULL;
+	struct nlmsghdr *nlh;
+
+	spin_lock_irqsave(&audit_freelist_lock, flags);
+	if (!list_empty(&audit_freelist)) {
+		ab = list_entry(audit_freelist.next,
+				struct audit_buffer, list);
+		list_del(&ab->list);
+		--audit_freelist_count;
+	}
+	spin_unlock_irqrestore(&audit_freelist_lock, flags);
+
+	if (!ab) {
+		ab = kmalloc(sizeof(*ab), gfp_mask);
+		if (!ab)
+			goto err;
+	}
+
+	ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);
+	if (!ab->skb)
+		goto err;
+
+	ab->ctx = ctx;
+	nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
+	nlh->nlmsg_type = type;
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_pid = 0;
+	nlh->nlmsg_seq = 0;
+	return ab;
+err:
+	audit_buffer_free(ab);
+	return NULL;
+}
+
+/* Compute a serial number for the audit record.  Audit records are
+ * written to user-space as soon as they are generated, so a complete
+ * audit record may be written in several pieces.  The timestamp of the
+ * record and this serial number are used by the user-space tools to
+ * determine which pieces belong to the same audit record.  The
+ * (timestamp,serial) tuple is unique for each syscall and is live from
+ * syscall entry to syscall exit.
+ *
+ * Atomic values are only guaranteed to be 24-bit, so we count down.
+ *
+ * NOTE: Another possibility is to store the formatted records off the
+ * audit context (for those records that have a context), and emit them
+ * all at syscall exit.  However, this could delay the reporting of
+ * significant errors until syscall exit (or never, if the system
+ * halts). */
+unsigned int audit_serial(void)
+{
+	static atomic_t serial = ATOMIC_INIT(0xffffff);
+	unsigned int a, b;
+
+	do {
+		a = atomic_read(&serial);
+		if (atomic_dec_and_test(&serial))
+			atomic_set(&serial, 0xffffff);
+		b = atomic_read(&serial);
+	} while (b != a - 1);
+
+	return 0xffffff - b;
+}
+
+static inline void audit_get_stamp(struct audit_context *ctx, 
+				   struct timespec *t, unsigned int *serial)
+{
+	if (ctx)
+		auditsc_get_stamp(ctx, t, serial);
+	else {
+		*t = CURRENT_TIME;
+		*serial = audit_serial();
+	}
+}
 
 /* Obtain an audit buffer.  This routine does locking to obtain the
  * audit buffer, but then no locking is required for calls to
@@ -615,10 +644,9 @@
  * syscall, then the syscall is marked as auditable and an audit record
  * will be written at syscall exit.  If there is no associated task, tsk
  * should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx)
+struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
 {
 	struct audit_buffer	*ab	= NULL;
-	unsigned long		flags;
 	struct timespec		t;
 	unsigned int		serial;
 
@@ -626,57 +654,48 @@
 		return NULL;
 
 	if (audit_backlog_limit
-	    && atomic_read(&audit_backlog) > audit_backlog_limit) {
+	    && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
 		if (audit_rate_check())
 			printk(KERN_WARNING
 			       "audit: audit_backlog=%d > "
 			       "audit_backlog_limit=%d\n",
-			       atomic_read(&audit_backlog),
+			       skb_queue_len(&audit_skb_queue),
 			       audit_backlog_limit);
 		audit_log_lost("backlog limit exceeded");
 		return NULL;
 	}
 
-	spin_lock_irqsave(&audit_freelist_lock, flags);
-	if (!list_empty(&audit_freelist)) {
-		ab = list_entry(audit_freelist.next,
-				struct audit_buffer, list);
-		list_del(&ab->list);
-		--audit_freelist_count;
-	}
-	spin_unlock_irqrestore(&audit_freelist_lock, flags);
-
-	if (!ab)
-		ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
+	ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
 	if (!ab) {
 		audit_log_lost("out of memory in audit_log_start");
 		return NULL;
 	}
 
-	atomic_inc(&audit_backlog);
-	skb_queue_head_init(&ab->sklist);
+	audit_get_stamp(ab->ctx, &t, &serial);
 
-	ab->ctx   = ctx;
-	ab->len   = 0;
-	ab->nlh   = NULL;
-	ab->total = 0;
-	ab->type  = AUDIT_KERNEL;
-	ab->pid   = 0;
-
-#ifdef CONFIG_AUDITSYSCALL
-	if (ab->ctx)
-		audit_get_stamp(ab->ctx, &t, &serial);
-	else
-#endif
-	{
-		t = CURRENT_TIME;
-		serial = 0;
-	}
 	audit_log_format(ab, "audit(%lu.%03lu:%u): ",
 			 t.tv_sec, t.tv_nsec/1000000, serial);
 	return ab;
 }
 
+/**
+ * audit_expand - expand skb in the audit buffer
+ * @ab: audit_buffer
+ *
+ * Returns 0 (no space) on failed expansion, or available space if
+ * successful.
+ */
+static inline int audit_expand(struct audit_buffer *ab, int extra)
+{
+	struct sk_buff *skb = ab->skb;
+	int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
+				   GFP_ATOMIC);
+	if (ret < 0) {
+		audit_log_lost("out of memory in audit_expand");
+		return 0;
+	}
+	return skb_tailroom(skb);
+}
 
 /* Format an audit message into the audit buffer.  If there isn't enough
  * room in the audit buffer, more room will be allocated and vsnprint
@@ -686,26 +705,35 @@
 			      va_list args)
 {
 	int len, avail;
+	struct sk_buff *skb;
+	va_list args2;
 
 	if (!ab)
 		return;
 
-	avail = sizeof(ab->tmp) - ab->len;
-	if (avail <= 0) {
-		audit_log_move(ab);
-		avail = sizeof(ab->tmp) - ab->len;
+	BUG_ON(!ab->skb);
+	skb = ab->skb;
+	avail = skb_tailroom(skb);
+	if (avail == 0) {
+		avail = audit_expand(ab, AUDIT_BUFSIZ);
+		if (!avail)
+			goto out;
 	}
-	len   = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
+	va_copy(args2, args);
+	len = vsnprintf(skb->tail, avail, fmt, args);
 	if (len >= avail) {
 		/* The printk buffer is 1024 bytes long, so if we get
 		 * here and AUDIT_BUFSIZ is at least 1024, then we can
 		 * log everything that printk could have logged. */
-		audit_log_move(ab);
-		avail = sizeof(ab->tmp) - ab->len;
-		len   = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
-	}
-	ab->len   += (len < avail) ? len : avail;
-	ab->total += (len < avail) ? len : avail;
+		avail = audit_expand(ab, max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail));
+		if (!avail)
+			goto out;
+		len = vsnprintf(skb->tail, avail, fmt, args2);
+	}
+	if (len > 0)
+		skb_put(skb, len);
+out:
+	return;
 }
 
 /* Format a message into the audit buffer.  All the work is done in
@@ -721,20 +749,47 @@
 	va_end(args);
 }
 
-void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
+/* This function will take the passed buf and convert it into a string of
+ * ascii hex digits. The new string is placed onto the skb. */
+void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, 
+		size_t len)
 {
-	int i;
+	int i, avail, new_len;
+	unsigned char *ptr;
+	struct sk_buff *skb;
+	static const unsigned char *hex = "0123456789ABCDEF";
+
+	BUG_ON(!ab->skb);
+	skb = ab->skb;
+	avail = skb_tailroom(skb);
+	new_len = len<<1;
+	if (new_len >= avail) {
+		/* Round the buffer request up to the next multiple */
+		new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
+		avail = audit_expand(ab, new_len);
+		if (!avail)
+			return;
+	}
 
-	for (i=0; i<len; i++)
-		audit_log_format(ab, "%02x", buf[i]);
+	ptr = skb->tail;
+	for (i=0; i<len; i++) {
+		*ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */
+		*ptr++ = hex[buf[i] & 0x0F];	  /* Lower nibble */
+	}
+	*ptr = 0;
+	skb_put(skb, len << 1); /* new string is twice the old string */
 }
 
+/* This code will escape a string that is passed to it if the string
+ * contains a control character, unprintable character, double quote mark, 
+ * or a space. Unescaped strings will start and end with a double quote mark.
+ * Strings that are escaped are printed in hex (2 digits per char). */
 void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
 {
 	const unsigned char *p = string;
 
 	while (*p) {
-		if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
+		if (*p == '"' || *p < 0x21 || *p > 0x7f) {
 			audit_log_hex(ab, string, strlen(string));
 			return;
 		}
@@ -743,117 +798,63 @@
 	audit_log_format(ab, "\"%s\"", string);
 }
 
-
-/* This is a helper-function to print the d_path without using a static
- * buffer or allocating another buffer in addition to the one in
- * audit_buffer. */
+/* This is a helper-function to print the escaped d_path */
 void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
 		      struct dentry *dentry, struct vfsmount *vfsmnt)
 {
-	char *p;
-	int  len, avail;
-
-	if (prefix) audit_log_format(ab, " %s", prefix);
-
-	if (ab->len > 128)
-		audit_log_move(ab);
-	avail = sizeof(ab->tmp) - ab->len;
-	p = d_path(dentry, vfsmnt, ab->tmp + ab->len, avail);
-	if (IS_ERR(p)) {
-		/* FIXME: can we save some information here? */
-		audit_log_format(ab, "<toolong>");
-	} else {
-				/* path isn't at start of buffer */
-		len	   = (ab->tmp + sizeof(ab->tmp) - 1) - p;
-		memmove(ab->tmp + ab->len, p, len);
-		ab->len   += len;
-		ab->total += len;
-	}
-}
-
-/* Remove queued messages from the audit_txlist and send them to userspace. */
-static void audit_tasklet_handler(unsigned long arg)
-{
-	LIST_HEAD(list);
-	struct audit_buffer *ab;
-	unsigned long	    flags;
+	char *p, *path;
 
-	spin_lock_irqsave(&audit_txlist_lock, flags);
-	list_splice_init(&audit_txlist, &list);
-	spin_unlock_irqrestore(&audit_txlist_lock, flags);
+	if (prefix)
+		audit_log_format(ab, " %s", prefix);
 
-	while (!list_empty(&list)) {
-		ab = list_entry(list.next, struct audit_buffer, list);
-		list_del(&ab->list);
-		audit_log_end_fast(ab);
+	/* We will allow 11 spaces for ' (deleted)' to be appended */
+	path = kmalloc(PATH_MAX+11, GFP_KERNEL);
+	if (!path) {
+		audit_log_format(ab, "<no memory>");
+		return;
 	}
+	p = d_path(dentry, vfsmnt, path, PATH_MAX+11);
+	if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
+		/* FIXME: can we save some information here? */
+		audit_log_format(ab, "<too long>");
+	} else 
+		audit_log_untrustedstring(ab, p);
+	kfree(path);
 }
 
-static DECLARE_TASKLET(audit_tasklet, audit_tasklet_handler, 0);
-
 /* The netlink_* functions cannot be called inside an irq context, so
  * the audit buffer is places on a queue and a tasklet is scheduled to
  * remove them from the queue outside the irq context.  May be called in
  * any context. */
-static void audit_log_end_irq(struct audit_buffer *ab)
-{
-	unsigned long flags;
-
-	if (!ab)
-		return;
-	spin_lock_irqsave(&audit_txlist_lock, flags);
-	list_add_tail(&ab->list, &audit_txlist);
-	spin_unlock_irqrestore(&audit_txlist_lock, flags);
-
-	tasklet_schedule(&audit_tasklet);
-}
-
-/* Send the message in the audit buffer directly to user space.  May not
- * be called in an irq context. */
-static void audit_log_end_fast(struct audit_buffer *ab)
+void audit_log_end(struct audit_buffer *ab)
 {
-	unsigned long flags;
-
-	BUG_ON(in_irq());
 	if (!ab)
 		return;
 	if (!audit_rate_check()) {
 		audit_log_lost("rate limit exceeded");
 	} else {
-		audit_log_move(ab);
-		if (audit_log_drain(ab))
-			return;
+		if (audit_pid) {
+			struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
+			nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
+			skb_queue_tail(&audit_skb_queue, ab->skb);
+			ab->skb = NULL;
+			wake_up_interruptible(&kauditd_wait);
+		} else {
+			printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
+		}
 	}
-
-	atomic_dec(&audit_backlog);
-	spin_lock_irqsave(&audit_freelist_lock, flags);
-	if (++audit_freelist_count > AUDIT_MAXFREE)
-		kfree(ab);
-	else
-		list_add(&ab->list, &audit_freelist);
-	spin_unlock_irqrestore(&audit_freelist_lock, flags);
-}
-
-/* Send or queue the message in the audit buffer, depending on the
- * current context.  (A convenience function that may be called in any
- * context.) */
-void audit_log_end(struct audit_buffer *ab)
-{
-	if (in_irq())
-		audit_log_end_irq(ab);
-	else
-		audit_log_end_fast(ab);
+	audit_buffer_free(ab);
 }
 
 /* Log an audit record.  This is a convenience function that calls
  * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
  * called in any context. */
-void audit_log(struct audit_context *ctx, const char *fmt, ...)
+void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
 {
 	struct audit_buffer *ab;
 	va_list args;
 
-	ab = audit_log_start(ctx);
+	ab = audit_log_start(ctx, type);
 	if (ab) {
 		va_start(args, fmt);
 		audit_log_vformat(ab, fmt, args);
Index: kernel/auditsc.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/kernel/auditsc.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/kernel/auditsc.c  (mode:100644)
@@ -34,7 +34,8 @@
 #include <asm/types.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-
+#include <linux/mount.h>
+#include <linux/socket.h>
 #include <linux/audit.h>
 #include <linux/personality.h>
 #include <linux/time.h>
@@ -112,6 +113,23 @@
 	mode_t			mode;
 };
 
+struct audit_aux_data_socketcall {
+	struct audit_aux_data	d;
+	int			nargs;
+	unsigned long		args[0];
+};
+
+struct audit_aux_data_sockaddr {
+	struct audit_aux_data	d;
+	int			len;
+	char			a[0];
+};
+
+struct audit_aux_data_path {
+	struct audit_aux_data	d;
+	struct dentry		*dentry;
+	struct vfsmount		*mnt;
+};
 
 /* The per-task audit context. */
 struct audit_context {
@@ -127,6 +145,8 @@
 	int		    auditable;  /* 1 if record should be written */
 	int		    name_count;
 	struct audit_names  names[AUDIT_NAMES];
+	struct dentry *	    pwd;
+	struct vfsmount *   pwdmnt;
 	struct audit_context *previous; /* For nested syscalls */
 	struct audit_aux_data *aux;
 
@@ -157,6 +177,8 @@
 	struct audit_rule rule;
 };
 
+extern int audit_pid;
+
 /* Check to see if two rules are identical.  It is called from
  * audit_del_rule during AUDIT_DEL. */
 static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
@@ -226,7 +248,6 @@
 	return -EFAULT;		/* No matching rule */
 }
 
-#ifdef CONFIG_NET
 /* Copy rule from user-space to kernel-space.  Called during
  * AUDIT_ADD. */
 static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
@@ -287,7 +308,8 @@
 			err = audit_add_rule(entry, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_add_rule(entry, &audit_extlist);
-		audit_log(NULL, "auid %u added an audit rule\n", loginuid);
+		audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+				"auid=%u added an audit rule\n", loginuid);
 		break;
 	case AUDIT_DEL:
 		flags =((struct audit_rule *)data)->flags;
@@ -297,7 +319,8 @@
 			err = audit_del_rule(data, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_del_rule(data, &audit_extlist);
-		audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
+		audit_log(NULL, AUDIT_CONFIG_CHANGE,
+				"auid=%u removed an audit rule\n", loginuid);
 		break;
 	default:
 		return -EINVAL;
@@ -305,7 +328,6 @@
 
 	return err;
 }
-#endif
 
 /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
  * otherwise. */
@@ -444,7 +466,7 @@
 
 /* At syscall entry and exit time, this filter is called if the
  * audit_state is not low enough that auditing cannot take place, but is
- * also not high enough that we already know we have to write and audit
+ * also not high enough that we already know we have to write an audit
  * record (i.e., the state is AUDIT_SETUP_CONTEXT or  AUDIT_BUILD_CONTEXT).
  */
 static enum audit_state audit_filter_syscall(struct task_struct *tsk,
@@ -532,6 +554,12 @@
 		if (context->names[i].name)
 			__putname(context->names[i].name);
 	context->name_count = 0;
+	if (context->pwd)
+		dput(context->pwd);
+	if (context->pwdmnt)
+		mntput(context->pwdmnt);
+	context->pwd = NULL;
+	context->pwdmnt = NULL;
 }
 
 static inline void audit_free_aux(struct audit_context *context)
@@ -539,6 +567,11 @@
 	struct audit_aux_data *aux;
 
 	while ((aux = context->aux)) {
+		if (aux->type == AUDIT_AVC_PATH) {
+			struct audit_aux_data_path *axi = (void *)aux;
+			dput(axi->dentry);
+			mntput(axi->mnt);
+		}
 		context->aux = aux->next;
 		kfree(aux);
 	}
@@ -625,7 +658,8 @@
 	struct vm_area_struct *vma;
 
 	get_task_comm(name, current);
-	audit_log_format(ab, " comm=%s", name);
+	audit_log_format(ab, " comm=");
+	audit_log_untrustedstring(ab, name);
 
 	if (!mm)
 		return;
@@ -649,23 +683,24 @@
 {
 	int i;
 	struct audit_buffer *ab;
+	struct audit_aux_data *aux;
 
-	ab = audit_log_start(context);
+	ab = audit_log_start(context, AUDIT_SYSCALL);
 	if (!ab)
 		return;		/* audit_panic has been called */
-	audit_log_format(ab, "syscall=%d", context->major);
+	audit_log_format(ab, "arch=%x syscall=%d",
+			 context->arch, context->major);
 	if (context->personality != PER_LINUX)
 		audit_log_format(ab, " per=%lx", context->personality);
-	audit_log_format(ab, " arch=%x", context->arch);
 	if (context->return_valid)
 		audit_log_format(ab, " success=%s exit=%ld", 
 				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
 				 context->return_code);
 	audit_log_format(ab,
 		  " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
-		  " pid=%d loginuid=%d uid=%d gid=%d"
-		  " euid=%d suid=%d fsuid=%d"
-		  " egid=%d sgid=%d fsgid=%d",
+		  " pid=%d auid=%u uid=%u gid=%u"
+		  " euid=%u suid=%u fsuid=%u"
+		  " egid=%u sgid=%u fsgid=%u",
 		  context->argv[0],
 		  context->argv[1],
 		  context->argv[2],
@@ -679,33 +714,57 @@
 		  context->egid, context->sgid, context->fsgid);
 	audit_log_task_info(ab);
 	audit_log_end(ab);
-	while (context->aux) {
-		struct audit_aux_data *aux;
 
-		ab = audit_log_start(context);
+	for (aux = context->aux; aux; aux = aux->next) {
+
+		ab = audit_log_start(context, aux->type);
 		if (!ab)
 			continue; /* audit_panic has been called */
 
-		aux = context->aux;
-		context->aux = aux->next;
-
-		audit_log_format(ab, "auxitem=%d", aux->type);
 		switch (aux->type) {
-		case AUDIT_AUX_IPCPERM: {
+		case AUDIT_IPC: {
 			struct audit_aux_data_ipcctl *axi = (void *)aux;
 			audit_log_format(ab, 
-					 " qbytes=%lx uid=%d gid=%d mode=%x",
+					 " qbytes=%lx iuid=%u igid=%u mode=%x",
 					 axi->qbytes, axi->uid, axi->gid, axi->mode);
-			}
+			break; }
+
+		case AUDIT_SOCKETCALL: {
+			int i;
+			struct audit_aux_data_socketcall *axs = (void *)aux;
+			audit_log_format(ab, "nargs=%d", axs->nargs);
+			for (i=0; i<axs->nargs; i++)
+				audit_log_format(ab, " a%d=%lx", i, axs->args[i]);
+			break; }
+
+		case AUDIT_SOCKADDR: {
+			struct audit_aux_data_sockaddr *axs = (void *)aux;
+
+			audit_log_format(ab, "saddr=");
+			audit_log_hex(ab, axs->a, axs->len);
+			break; }
+
+		case AUDIT_AVC_PATH: {
+			struct audit_aux_data_path *axi = (void *)aux;
+			audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
+			break; }
+
 		}
 		audit_log_end(ab);
-		kfree(aux);
 	}
 
+	if (context->pwd && context->pwdmnt) {
+		ab = audit_log_start(context, AUDIT_CWD);
+		if (ab) {
+			audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
+			audit_log_end(ab);
+		}
+	}
 	for (i = 0; i < context->name_count; i++) {
-		ab = audit_log_start(context);
+		ab = audit_log_start(context, AUDIT_PATH);
 		if (!ab)
 			continue; /* audit_panic has been called */
+
 		audit_log_format(ab, "item=%d", i);
 		if (context->names[i].name) {
 			audit_log_format(ab, " name=");
@@ -713,7 +772,7 @@
 		}
 		if (context->names[i].ino != (unsigned long)-1)
 			audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
-					     " uid=%d gid=%d rdev=%02x:%02x",
+					     " ouid=%u ogid=%u rdev=%02x:%02x",
 					 context->names[i].ino,
 					 MAJOR(context->names[i].dev),
 					 MINOR(context->names[i].dev),
@@ -741,42 +800,12 @@
 
 	/* Check for system calls that do not go through the exit
 	 * function (e.g., exit_group), then free context block. */
-	if (context->in_syscall && context->auditable)
+	if (context->in_syscall && context->auditable && context->pid != audit_pid)
 		audit_log_exit(context);
 
 	audit_free_context(context);
 }
 
-/* Compute a serial number for the audit record.  Audit records are
- * written to user-space as soon as they are generated, so a complete
- * audit record may be written in several pieces.  The timestamp of the
- * record and this serial number are used by the user-space daemon to
- * determine which pieces belong to the same audit record.  The
- * (timestamp,serial) tuple is unique for each syscall and is live from
- * syscall entry to syscall exit.
- *
- * Atomic values are only guaranteed to be 24-bit, so we count down.
- *
- * NOTE: Another possibility is to store the formatted records off the
- * audit context (for those records that have a context), and emit them
- * all at syscall exit.  However, this could delay the reporting of
- * significant errors until syscall exit (or never, if the system
- * halts). */
-static inline unsigned int audit_serial(void)
-{
-	static atomic_t serial = ATOMIC_INIT(0xffffff);
-	unsigned int a, b;
-
-	do {
-		a = atomic_read(&serial);
-		if (atomic_dec_and_test(&serial))
-			atomic_set(&serial, 0xffffff);
-		b = atomic_read(&serial);
-	} while (b != a - 1);
-
-	return 0xffffff - b;
-}
-
 /* Fill in audit context at syscall entry.  This only happens if the
  * audit context was created when the task was created and the state or
  * filters demand the audit context be built.  If the state from the
@@ -876,7 +905,7 @@
 	if (likely(!context))
 		return;
 
-	if (context->in_syscall && context->auditable)
+	if (context->in_syscall && context->auditable && context->pid != audit_pid)
 		audit_log_exit(context);
 
 	context->in_syscall = 0;
@@ -916,6 +945,13 @@
 	context->names[context->name_count].name = name;
 	context->names[context->name_count].ino  = (unsigned long)-1;
 	++context->name_count;
+	if (!context->pwd) {
+		read_lock(&current->fs->lock);
+		context->pwd = dget(current->fs->pwd);
+		context->pwdmnt = mntget(current->fs->pwdmnt);
+		read_unlock(&current->fs->lock);
+	}
+		
 }
 
 /* Intercept a putname request.  Called from
@@ -994,34 +1030,26 @@
 	context->names[idx].rdev = inode->i_rdev;
 }
 
-void audit_get_stamp(struct audit_context *ctx,
-		     struct timespec *t, unsigned int *serial)
+void auditsc_get_stamp(struct audit_context *ctx,
+		       struct timespec *t, unsigned int *serial)
 {
-	if (ctx) {
-		t->tv_sec  = ctx->ctime.tv_sec;
-		t->tv_nsec = ctx->ctime.tv_nsec;
-		*serial    = ctx->serial;
-		ctx->auditable = 1;
-	} else {
-		*t      = CURRENT_TIME;
-		*serial = 0;
-	}
+	t->tv_sec  = ctx->ctime.tv_sec;
+	t->tv_nsec = ctx->ctime.tv_nsec;
+	*serial    = ctx->serial;
+	ctx->auditable = 1;
 }
 
-extern int audit_set_type(struct audit_buffer *ab, int type);
-
 int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
 {
 	if (task->audit_context) {
 		struct audit_buffer *ab;
 
-		ab = audit_log_start(NULL);
+		ab = audit_log_start(NULL, AUDIT_LOGIN);
 		if (ab) {
 			audit_log_format(ab, "login pid=%d uid=%u "
-				"old loginuid=%u new loginuid=%u",
+				"old auid=%u new auid=%u",
 				task->pid, task->uid, 
 				task->audit_context->loginuid, loginuid);
-			audit_set_type(ab, AUDIT_LOGIN);
 			audit_log_end(ab);
 		}
 		task->audit_context->loginuid = loginuid;
@@ -1051,8 +1079,89 @@
 	ax->gid = gid;
 	ax->mode = mode;
 
-	ax->d.type = AUDIT_AUX_IPCPERM;
+	ax->d.type = AUDIT_IPC;
 	ax->d.next = context->aux;
 	context->aux = (void *)ax;
 	return 0;
 }
+
+int audit_socketcall(int nargs, unsigned long *args)
+{
+	struct audit_aux_data_socketcall *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->nargs = nargs;
+	memcpy(ax->args, args, nargs * sizeof(unsigned long));
+
+	ax->d.type = AUDIT_SOCKETCALL;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+int audit_sockaddr(int len, void *a)
+{
+	struct audit_aux_data_sockaddr *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->len = len;
+	memcpy(ax->a, a, len);
+
+	ax->d.type = AUDIT_SOCKADDR;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
+{
+	struct audit_aux_data_path *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->dentry = dget(dentry);
+	ax->mnt = mntget(mnt);
+
+	ax->d.type = AUDIT_AVC_PATH;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+void audit_signal_info(int sig, struct task_struct *t)
+{
+	extern pid_t audit_sig_pid;
+	extern uid_t audit_sig_uid;
+
+	if (unlikely(audit_pid && t->pid == audit_pid)) {
+		if (sig == SIGTERM || sig == SIGHUP) {
+			struct audit_context *ctx = current->audit_context;
+			audit_sig_pid = current->pid;
+			if (ctx)
+				audit_sig_uid = ctx->loginuid;
+			else
+				audit_sig_uid = current->uid;
+		}
+	}
+}
+
Index: kernel/signal.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/kernel/signal.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/kernel/signal.c  (mode:100644)
@@ -24,6 +24,7 @@
 #include <linux/ptrace.h>
 #include <linux/posix-timers.h>
 #include <linux/signal.h>
+#include <linux/audit.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -667,7 +668,11 @@
 	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
 	    && !capable(CAP_KILL))
 		return error;
-	return security_task_kill(t, info, sig);
+
+	error = security_task_kill(t, info, sig);
+	if (!error)
+		audit_signal_info(sig, t); /* Let audit system see the signal */
+	return error;
 }
 
 /* forward decl */
Index: net/socket.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/net/socket.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/net/socket.c  (mode:100644)
@@ -81,6 +81,7 @@
 #include <linux/syscalls.h>
 #include <linux/compat.h>
 #include <linux/kmod.h>
+#include <linux/audit.h>
 
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
@@ -226,7 +227,7 @@
 		return 0;
 	if(copy_from_user(kaddr,uaddr,ulen))
 		return -EFAULT;
-	return 0;
+	return audit_sockaddr(ulen, kaddr);
 }
 
 /**
@@ -1906,7 +1907,11 @@
 	/* copy_from_user should be SMP safe. */
 	if (copy_from_user(a, args, nargs[call]))
 		return -EFAULT;
-		
+
+	err = audit_socketcall(nargs[call]/sizeof(unsigned long), a);
+	if (err)
+		return err;
+
 	a0=a[0];
 	a1=a[1];
 	
Index: security/selinux/avc.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/security/selinux/avc.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/security/selinux/avc.c  (mode:100644)
@@ -242,7 +242,7 @@
 	avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
 					     0, SLAB_PANIC, NULL, NULL);
 
-	audit_log(current->audit_context, "AVC INITIALIZED\n");
+	audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
 }
 
 int avc_get_hash_stats(char *page)
@@ -532,6 +532,7 @@
                u16 tclass, u32 requested,
                struct av_decision *avd, int result, struct avc_audit_data *a)
 {
+	struct task_struct *tsk = current;
 	struct inode *inode = NULL;
 	u32 denied, audited;
 	struct audit_buffer *ab;
@@ -549,12 +550,18 @@
 			return;
 	}
 
-	ab = audit_log_start(current->audit_context);
+	ab = audit_log_start(current->audit_context, AUDIT_AVC);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");
 	avc_dump_av(ab, tclass,audited);
 	audit_log_format(ab, " for ");
+	if (a && a->tsk)
+		tsk = a->tsk;
+	if (tsk && tsk->pid) {
+		audit_log_format(ab, " pid=%d comm=", tsk->pid);
+		audit_log_untrustedstring(ab, tsk->comm);
+	}
 	if (a) {
 		switch (a->type) {
 		case AVC_AUDIT_DATA_IPC:
@@ -566,21 +573,18 @@
 		case AVC_AUDIT_DATA_FS:
 			if (a->u.fs.dentry) {
 				struct dentry *dentry = a->u.fs.dentry;
-				if (a->u.fs.mnt) {
-					audit_log_d_path(ab, "path=", dentry,
-							a->u.fs.mnt);
-				} else {
-					audit_log_format(ab, " name=%s",
-							 dentry->d_name.name);
-				}
+				if (a->u.fs.mnt)
+					audit_avc_path(dentry, a->u.fs.mnt);
+				audit_log_format(ab, " name=");
+				audit_log_untrustedstring(ab, dentry->d_name.name);
 				inode = dentry->d_inode;
 			} else if (a->u.fs.inode) {
 				struct dentry *dentry;
 				inode = a->u.fs.inode;
 				dentry = d_find_alias(inode);
 				if (dentry) {
-					audit_log_format(ab, " name=%s",
-							 dentry->d_name.name);
+					audit_log_format(ab, " name=");
+					audit_log_untrustedstring(ab, dentry->d_name.name);
 					dput(dentry);
 				}
 			}
@@ -623,22 +627,20 @@
 				case AF_UNIX:
 					u = unix_sk(sk);
 					if (u->dentry) {
-						audit_log_d_path(ab, "path=",
-							u->dentry, u->mnt);
+						audit_avc_path(u->dentry, u->mnt);
+						audit_log_format(ab, " name=");
+						audit_log_untrustedstring(ab, u->dentry->d_name.name);
 						break;
 					}
 					if (!u->addr)
 						break;
 					len = u->addr->len-sizeof(short);
 					p = &u->addr->name->sun_path[0];
+					audit_log_format(ab, " path=");
 					if (*p)
-						audit_log_format(ab,
-							"path=%*.*s", len,
-							len, p);
+						audit_log_untrustedstring(ab, p);
 					else
-						audit_log_format(ab,
-							"path=@%*.*s", len-1,
-							len-1, p+1);
+						audit_log_hex(ab, p, len);
 					break;
 				}
 			}
Index: security/selinux/hooks.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/security/selinux/hooks.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/security/selinux/hooks.c  (mode:100644)
@@ -3419,7 +3419,7 @@
 	err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
 	if (err) {
 		if (err == -EINVAL) {
-			audit_log(current->audit_context,
+			audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 				  "SELinux:  unrecognized netlink message"
 				  " type=%hu for sclass=%hu\n",
 				  nlh->nlmsg_type, isec->sclass);
Index: security/selinux/nlmsgtab.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/security/selinux/nlmsgtab.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/security/selinux/nlmsgtab.c  (mode:100644)
@@ -97,6 +97,7 @@
 	{ AUDIT_ADD,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
 	{ AUDIT_DEL,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
 	{ AUDIT_USER,		NETLINK_AUDIT_SOCKET__NLMSG_RELAY    },
+	{ AUDIT_SIGNAL_INFO,	NETLINK_AUDIT_SOCKET__NLMSG_READ     },
 };
 
 
@@ -141,8 +142,13 @@
 		break;
 
 	case SECCLASS_NETLINK_AUDIT_SOCKET:
-		err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
-				 sizeof(nlmsg_audit_perms));
+		if (nlmsg_type >= AUDIT_FIRST_USER_MSG &&
+		    nlmsg_type <= AUDIT_LAST_USER_MSG) {
+			*perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY;
+		} else {
+			err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
+					 sizeof(nlmsg_audit_perms));
+		}
 		break;
 
 	/* No messaging from userspace, or class unknown/unhandled */
Index: security/selinux/ss/services.c
===================================================================
--- e4660ac807d16a7bd3af6db2dfce539acd94ba23/security/selinux/ss/services.c  (mode:100644)
+++ 9b9337ae627fc56a0eda43c60860765f25efaa0b/security/selinux/ss/services.c  (mode:100644)
@@ -365,7 +365,7 @@
 		goto out;
 	if (context_struct_to_string(tcontext, &t, &tlen) < 0)
 		goto out;
-	audit_log(current->audit_context,
+	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 	          "security_validate_transition:  denied for"
 	          " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
 	          o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@ -742,7 +742,7 @@
 		goto out;
 	if (context_struct_to_string(newcontext, &n, &nlen) < 0)
 		goto out;
-	audit_log(current->audit_context,
+	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 		  "security_compute_sid:  invalid context %s"
 		  " for scontext=%s"
 		  " tcontext=%s"

linux-2.6.12-cpufreq-update.patch:
 2.6.12-rc2/include/linux/cpufreq.h                                   |    2 
 2/drivers/cpufreq/cpufreq.c                                          |    8 
 25-akpm/arch/i386/kernel/cpu/cpufreq/powernow-k7.c                   |    9 
 25-akpm/arch/i386/kernel/timers/common.c                             |    6 
 25-akpm/arch/i386/kernel/timers/timer_tsc.c                          |   20 
 25-akpm/include/asm-i386/timer.h                                     |    1 
 arch/i386/kernel/cpu/cpufreq/powernow-k8.c                           |  113 +
 arch/i386/kernel/cpu/cpufreq/powernow-k8.h                           |   15 
 b/Documentation/cpu-freq/user-guide.txt                              |    1 
 b/arch/i386/kernel/cpu/cpufreq/Kconfig                               |   14 
 b/arch/i386/kernel/cpu/cpufreq/Makefile                              |    1 
 b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c                         |    2 
 b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c                          |  179 ++
 b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c                  |    8 
 b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c                       |    3 
 b/drivers/cpufreq/Kconfig                                            |    4 
 b/drivers/cpufreq/cpufreq_ondemand.c                                 |   14 
 drivers/cpufreq/cpufreq_conservative.c                               |   34 
 drivers/cpufreq/cpufreq_ondemand.c                                   |  267 ++--
 linux-2.6.11/drivers/cpufreq/cpufreq_ondemand.c                      |    6 
 linux-2.6.12-rc2-mm3-full/drivers/cpufreq/cpufreq_ondemand.c         |    3 
 linux-2.6.12-rc3-mm3/drivers/cpufreq/Kconfig                         |   20 
 linux-2.6.12-rc3-mm3/drivers/cpufreq/Makefile                        |    1 
 linux-2.6.12-rc3-mm3/drivers/cpufreq/cpufreq_conservative.c          |  613 ++++++++++
 linux-2.6.12-rc4-mm2-ondemand/drivers/cpufreq/cpufreq_conservative.c |   53 
 linux-2.6.12-rc4-mm2-ondemand/drivers/cpufreq/cpufreq_ondemand.c     |   58 
 26 files changed, 1175 insertions(+), 280 deletions(-)

--- NEW FILE linux-2.6.12-cpufreq-update.patch ---
Subject: [CPUFREQ] powernow-k7: don't print khz element of FSB.

Signed-off-by: Dave Jones <davej at redhat.com>

diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2005-04-28 16:19:59 -04:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2005-04-28 16:19:59 -04:00
@@ -592,7 +592,7 @@
 		printk(KERN_WARNING PFX "can not determine bus frequency\n");
 		return -EINVAL;
 	}
-	dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000);
+	dprintk("FSB: %3dMHz\n", fsb/1000);
 
 	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
 		printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
Subject: [CPUFREQ] cpufreq-core: reduce warning messages.

cpufreq core is printing out messages at KERN_WARNING level that the core
recovers from without intervention, and that the system administrator can
do nothing about.  Patch below reduces the severity of these messages to
debug.

Signed-off-by: Matt Domsch <Matt_Domsch at dell.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Dave Jones <davej at redhat.com>

--- 1/drivers/cpufreq/cpufreq.c~	2005-05-10 22:28:57.000000000 -0400
+++ 2/drivers/cpufreq/cpufreq.c	2005-05-10 22:29:38.000000000 -0400
@@ -258,7 +258,7 @@ void cpufreq_notify_transition(struct cp
 			    (likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
 			    (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
 			{
-				printk(KERN_WARNING "Warning: CPU frequency is %u, "
+				dprintk(KERN_WARNING "Warning: CPU frequency is %u, "
 				       "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
 				freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
 			}
@@ -814,7 +814,7 @@ static void cpufreq_out_of_sync(unsigned
 {
 	struct cpufreq_freqs freqs;
 
-	printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing "
+	dprintk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing "
 	       "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
 
 	freqs.cpu = cpu;
@@ -923,7 +923,7 @@ static int cpufreq_suspend(struct sys_de
 		struct cpufreq_freqs freqs;
 
 		if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
-			printk(KERN_DEBUG "Warning: CPU frequency is %u, "
+			dprintk(KERN_DEBUG "Warning: CPU frequency is %u, "
 			       "cpufreq assumed %u kHz.\n",
 			       cur_freq, cpu_policy->cur);
 
@@ -1004,7 +1004,7 @@ static int cpufreq_resume(struct sys_dev
 			struct cpufreq_freqs freqs;
 
 			if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
-				printk(KERN_WARNING "Warning: CPU frequency"
+				dprintk(KERN_WARNING "Warning: CPU frequency"
 				       "is %u, cpufreq assumed %u kHz.\n",
 				       cur_freq, cpu_policy->cur);
 
Subject: [CPUFREQ] speedstep-centrino: Pentium 4 - M (HT) support

The Pentium 4 - Ms (HT) with CPUID 0xF34 and 0xF41 seem to support
centrino-like enhanced speedstep; however, no "table" support is possible.
Therefore, put NULL entries into speedstep-centrino.c

Signed-off-by: Dominik Brodowski <linux at dominikbrodowski.net>
Signed-off-by: Dave Jones <davej at redhat.com>

diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2005-04-28 16:19:09 -04:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2005-04-28 16:19:09 -04:00
@@ -54,6 +54,8 @@
 	CPU_DOTHAN_A1,
 	CPU_DOTHAN_A2,
 	CPU_DOTHAN_B0,
+	CPU_MP4HT_D0,
+	CPU_MP4HT_E0,
 };
 
 static const struct cpu_id cpu_ids[] = {
@@ -61,6 +63,8 @@
 	[CPU_DOTHAN_A1]	= { 6, 13, 1 },
 	[CPU_DOTHAN_A2]	= { 6, 13, 2 },
 	[CPU_DOTHAN_B0]	= { 6, 13, 6 },
+	[CPU_MP4HT_D0]	= {15,  3, 4 },
+	[CPU_MP4HT_E0]	= {15,  4, 1 },
 };
 #define N_IDS	(sizeof(cpu_ids)/sizeof(cpu_ids[0]))
 
@@ -226,6 +230,8 @@
 	{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
 	{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
 	{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
+	{ &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
+	{ &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
 
 	{ NULL, }
 };
Subject: [CPUFREQ] ondemand: trivial clean-ups

From: Eric Piel <Eric.Piel at tremplin-utc.net>

Trivial ondemand governor clean-ups:
- change from sampling_rate_in_HZ() to the official function
usecs_to_jiffies().
- use for_each_online_cpu() to instead of using "if (cpu_online(i))"

Signed-off-by: Eric Piel <eric.piel at tremplin-utc.net>
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
Signed-off-by: Dominik Brodowski <linux at dominikbrodowski.net>
Signed-off-by: Dave Jones <davej at redhat.com>

diff -Nru a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
--- a/drivers/cpufreq/cpufreq_ondemand.c	2005-04-28 16:19:20 -04:00
+++ b/drivers/cpufreq/cpufreq_ondemand.c	2005-04-28 16:19:20 -04:00
@@ -57,7 +57,6 @@
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER	(1000)
 #define DEF_SAMPLING_DOWN_FACTOR		(10)
 #define TRANSITION_LATENCY_LIMIT		(10 * 1000)
-#define sampling_rate_in_HZ(x)			(((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000)))
 
 static void do_dbs_timer(void *data);
 
@@ -281,7 +280,7 @@
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
 	up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
-			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
+			usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
 
 	if (idle_ticks < up_idle_ticks) {
 		__cpufreq_driver_target(policy, policy->max, 
@@ -328,7 +327,7 @@
 	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
 		dbs_tuners_ins.sampling_down_factor;
 	down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
-			sampling_rate_in_HZ(freq_down_sampling_rate);
+			usecs_to_jiffies(freq_down_sampling_rate);
 
 	if (idle_ticks > down_idle_ticks ) {
 		freq_down_step = (5 * policy->max) / 100;
@@ -348,11 +347,10 @@
 { 
 	int i;
 	down(&dbs_sem);
-	for (i = 0; i < NR_CPUS; i++)
-		if (cpu_online(i))
-			dbs_check_cpu(i);
+	for_each_online_cpu(i)
+		dbs_check_cpu(i);
 	schedule_delayed_work(&dbs_work, 
-			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate));
+			usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
 	up(&dbs_sem);
 } 
 
@@ -360,7 +358,7 @@
 {
 	INIT_WORK(&dbs_work, do_dbs_timer, NULL);
 	schedule_delayed_work(&dbs_work,
-			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate));
+			usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
 	return;
 }
 
Subject: [CPUFREQ] speedstep-smi: it works on at least one P4M

The speedstep-smi driver actually works on >=1 notebook with a
Pentium 4-M CPU where all other cpufreq drivers fail. Therefore,
allow speedstep-smi on P4Ms again, but warn users of likely failure

Signed-off-by: Dominik Brodowski <linux at dominikbrodowski.net>
Signed-off-by: Dave Jones <davej at redhat.com>

diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c	2005-04-28 16:19:25 -04:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c	2005-04-28 16:19:25 -04:00
@@ -357,6 +357,9 @@
 	case SPEEDSTEP_PROCESSOR_PIII_C:
 	case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
 		break;
+	case SPEEDSTEP_PROCESSOR_P4M:
+		printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n");
+		break;
 	default:
 		speedstep_processor = 0;
 	}
Subject: [CPUFREQ] Add warning comment about default governors.

This comes up time and time again. Until its fixed, place this
comment in the Kconfig which should stem the flow of resubmissions.

Signed-off-by: Rob Weryk <rjweryk at uwo.ca>
[...2248 lines suppressed...]
-static ssize_t store_down_threshold(struct cpufreq_policy *unused, 
-		const char *buf, size_t count)
-{
-	unsigned int input;
-	int ret;
-	ret = sscanf (buf, "%u", &input);
-
-	down(&dbs_sem);
-	if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || 
-			input < MIN_FREQUENCY_DOWN_THRESHOLD ||
-			input >= dbs_tuners_ins.up_threshold) {
-		up(&dbs_sem);
-		return -EINVAL;
-	}
-
-	dbs_tuners_ins.down_threshold = input;
-	up(&dbs_sem);
-
-	return count;
-}
-
 static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
 		const char *buf, size_t count)
 {
@@ -240,29 +209,6 @@ static ssize_t store_ignore_nice(struct 
 	return count;
 }
 
-static ssize_t store_freq_step(struct cpufreq_policy *policy,
-		const char *buf, size_t count)
-{
-	unsigned int input;
-	int ret;
-
-	ret = sscanf (buf, "%u", &input);
-
-	if ( ret != 1 )
-		return -EINVAL;
-
-	if ( input > 100 )
-		input = 100;
-	
-	/* no need to test here if freq_step is zero as the user might actually
-	 * want this, they would be crazy though :) */
-	down(&dbs_sem);
-	dbs_tuners_ins.freq_step = input;
-	up(&dbs_sem);
-
-	return count;
-}
-
 #define define_one_rw(_name) \
 static struct freq_attr _name = \
 __ATTR(_name, 0644, show_##_name, store_##_name)
@@ -270,9 +216,7 @@ __ATTR(_name, 0644, show_##_name, store_
 define_one_rw(sampling_rate);
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
-define_one_rw(down_threshold);
 define_one_rw(ignore_nice);
-define_one_rw(freq_step);
 
 static struct attribute * dbs_attributes[] = {
 	&sampling_rate_max.attr,
@@ -280,9 +224,7 @@ static struct attribute * dbs_attributes
 	&sampling_rate.attr,
 	&sampling_down_factor.attr,
 	&up_threshold.attr,
-	&down_threshold.attr,
 	&ignore_nice.attr,
-	&freq_step.attr,
 	NULL
 };
 
@@ -295,8 +237,8 @@ static struct attribute_group dbs_attr_g
 
 static void dbs_check_cpu(int cpu)
 {
-	unsigned int idle_ticks, up_idle_ticks, down_idle_ticks;
-	unsigned int freq_down_step;
+	unsigned int idle_ticks, up_idle_ticks, total_ticks;
+	unsigned int freq_next;
 	unsigned int freq_down_sampling_rate;
 	static int down_skip[NR_CPUS];
 	struct cpu_dbs_info_s *this_dbs_info;
@@ -310,17 +252,15 @@ static void dbs_check_cpu(int cpu)
 
 	policy = this_dbs_info->cur_policy;
 	/* 
-	 * The default safe range is 20% to 80% 
-	 * Every sampling_rate, we check
-	 * 	- If current idle time is less than 20%, then we try to 
-	 * 	  increase frequency
-	 * Every sampling_rate*sampling_down_factor, we check
-	 * 	- If current idle time is more than 80%, then we try to
-	 * 	  decrease frequency
+	 * Every sampling_rate, we check, if current idle time is less
+	 * than 20% (default), then we try to increase frequency
+	 * Every sampling_rate*sampling_down_factor, we look for a the lowest
+	 * frequency which can sustain the load while keeping idle time over
+	 * 30%. If such a frequency exist, we try to decrease to this frequency.
 	 *
 	 * Any frequency increase takes it to the maximum frequency. 
 	 * Frequency reduction happens at minimum steps of 
-	 * 5% (default) of max_frequency 
+	 * 5% (default) of current frequency 
 	 */
 
 	/* Check for frequency increase */
@@ -383,33 +323,27 @@ static void dbs_check_cpu(int cpu)
 			idle_ticks = tmp_idle_ticks;
 	}
 
-	/* Scale idle ticks by 100 and compare with up and down ticks */
-	idle_ticks *= 100;
 	down_skip[cpu] = 0;
+	/* if we cannot reduce the frequency anymore, break out early */
+	if (policy->cur == policy->min)
+		return;
 
+	/* Compute how many ticks there are between two measurements */
 	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
 		dbs_tuners_ins.sampling_down_factor;
-	down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
-		usecs_to_jiffies(freq_down_sampling_rate);
-
-	if (idle_ticks > down_idle_ticks) {
-		/* if we are already at the lowest speed then break out early
-		 * or if we 'cannot' reduce the speed as the user might want
-		 * freq_step to be zero */
-		if (policy->cur == policy->min || dbs_tuners_ins.freq_step == 0)
-			return;
+	total_ticks = usecs_to_jiffies(freq_down_sampling_rate);
 
-		freq_down_step = (dbs_tuners_ins.freq_step * policy->max) / 100;
-
-		/* max freq cannot be less than 100. But who knows.... */
-		if (unlikely(freq_down_step == 0))
-			freq_down_step = 5;
+	/*
+	 * The optimal frequency is the frequency that is the lowest that
+	 * can support the current CPU usage without triggering the up
+	 * policy. To be safe, we focus 10 points under the threshold.
+	 */
+	freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks;
+	freq_next = (freq_next * policy->cur) / 
+			(dbs_tuners_ins.up_threshold - 10);
 
-		__cpufreq_driver_target(policy,
-			policy->cur - freq_down_step,
-			CPUFREQ_RELATION_H);
-		return;
-	}
+	if (freq_next <= ((policy->cur * 95) / 100))
+		__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);
 }
 
 static void do_dbs_timer(void *data)
@@ -487,7 +421,6 @@ static int cpufreq_governor_dbs(struct c
 					DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
 			dbs_tuners_ins.sampling_rate = def_sampling_rate;
 			dbs_tuners_ins.ignore_nice = 0;
-			dbs_tuners_ins.freq_step = 5;
 
 			dbs_timer_init();
 		}

Subject: [CPUFREQ] ondemand governor default sampling downfactor as 1

[PATCH] [5/5] ondemand governor default sampling downfactor as 1

Make default sampling downfactor 1.
This works better with earlier auto downscaling change in ondemand governor.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
Signed-off-by: Dave Jones <davej at redhat.com>

--- linux-2.6.11/drivers/cpufreq/cpufreq_ondemand.c.org	2005-03-11 19:41:12.000000000 -0800
+++ linux-2.6.11/drivers/cpufreq/cpufreq_ondemand.c	2005-03-11 19:43:00.000000000 -0800
@@ -51,7 +51,8 @@ static unsigned int 				def_sampling_rat
 #define MIN_SAMPLING_RATE			(def_sampling_rate / 2)
 #define MAX_SAMPLING_RATE			(500 * def_sampling_rate)
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER	(1000)
-#define DEF_SAMPLING_DOWN_FACTOR		(10)
+#define DEF_SAMPLING_DOWN_FACTOR		(1)
+#define MAX_SAMPLING_DOWN_FACTOR		(10)
 #define TRANSITION_LATENCY_LIMIT		(10 * 1000)
 #define sampling_rate_in_HZ(x)			(((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000)))
 
@@ -119,6 +120,9 @@ static ssize_t store_sampling_down_facto
 	if (ret != 1 )
 		return -EINVAL;
 
+	if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
+		return -EINVAL;
+
 	down(&dbs_sem);
 	dbs_tuners_ins.sampling_down_factor = input;
 	up(&dbs_sem);


linux-2.6.12-detect-softlockups.patch:
 linux-2.6.11/kernel/softirq.c |    2 
 linux/include/linux/sched.h   |   13 ++++
 linux/init/main.c             |    1 
 linux/kernel/Makefile         |    1 
 linux/kernel/softlockup.c     |  130 ++++++++++++++++++++++++++++++++++++++++++
 linux/kernel/timer.c          |    1 
 linux/lib/Kconfig.debug       |   19 ++++++
 7 files changed, 166 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.12-detect-softlockups.patch ---
--- linux/kernel/softlockup.c.orig
+++ linux/kernel/softlockup.c
@@ -0,0 +1,130 @@
+/*
+ * Detect Soft Lockups
+ *
+ * started by Ingo Molnar, (C) 2005, Red Hat
+ *
+ * this code detects soft lockups: incidents in where on a CPU
+ * the kernel does not reschedule for 10 seconds or more.
+ */
+
+#include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/notifier.h>
+
+static DEFINE_SPINLOCK(print_lock);
+
+static DEFINE_PER_CPU(unsigned long, timestamp) = 0;
+static DEFINE_PER_CPU(unsigned long, print_timestamp) = 0;
+static DEFINE_PER_CPU(struct task_struct *, watchdog_task);
+
+extern void takeover_tasklets(unsigned int cpu);
+
+/*
+ * This callback runs from the timer interrupt, and checks
+ * whether the watchdog thread has hung or not:
+ */
+void softlockup_tick(struct pt_regs *regs)
+{
+	int this_cpu = smp_processor_id();
+	unsigned long timestamp = per_cpu(timestamp, this_cpu);
+
+	if (per_cpu(print_timestamp, this_cpu) == timestamp)
+		return;
+
+	if (time_after(jiffies, timestamp + 10*HZ)) {
+		per_cpu(print_timestamp, this_cpu) = timestamp;
+
+		spin_lock(&print_lock);
+		printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n",
+			this_cpu);
+		show_regs(regs);
+		dump_stack();
+		spin_unlock(&print_lock);
+	}
+}
+
+/*
+ * The watchdog thread - runs every second and touches the timestamp.
+ */
+static int watchdog(void * __bind_cpu)
+{
+	struct sched_param param = { .sched_priority = 99 };
+	int this_cpu = (long) __bind_cpu;
+
+	printk("softlockup thread %d started up.\n", this_cpu);
+
+	sched_setscheduler(current, SCHED_FIFO, &param);
+	current->flags |= PF_NOFREEZE;
+
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	/*
+	 * Run briefly once per second - if this gets delayed for
+	 * more than 10 seconds then the debug-printout triggers
+	 * in softlockup_tick():
+	 */
+	while (!kthread_should_stop()) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		msleep_interruptible(HZ);
+		per_cpu(timestamp, this_cpu) = jiffies;
+	}
+	__set_current_state(TASK_RUNNING);
+
+	return 0;
+}
+
+/*
+ * Create/destroy watchdog threads as CPUs come and go:
+ */
+static int __devinit
+cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+	int hotcpu = (unsigned long)hcpu;
+	struct task_struct *p;
+
+	switch (action) {
+	case CPU_UP_PREPARE:
+		BUG_ON(per_cpu(watchdog_task, hotcpu));
+		p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu);
+		if (IS_ERR(p)) {
+			printk("watchdog for %i failed\n", hotcpu);
+			return NOTIFY_BAD;
+		}
+  		per_cpu(watchdog_task, hotcpu) = p;
+		kthread_bind(p, hotcpu);
+ 		break;
+	case CPU_ONLINE:
+
+		wake_up_process(per_cpu(watchdog_task, hotcpu));
+		break;
+#ifdef CONFIG_HOTPLUG_CPU
+	case CPU_UP_CANCELED:
+		/* Unbind so it can run.  Fall thru. */
+		kthread_bind(per_cpu(watchdog_task, hotcpu), smp_processor_id());
+	case CPU_DEAD:
+		p = per_cpu(watchdog_task, hotcpu);
+		per_cpu(watchdog_task, hotcpu) = NULL;
+		kthread_stop(p);
+		takeover_tasklets(hotcpu);
+		break;
+#endif /* CONFIG_HOTPLUG_CPU */
+ 	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __devinitdata cpu_nfb = {
+	.notifier_call = cpu_callback
+};
+
+__init void spawn_softlockup_task(void)
+{
+	void *cpu = (void *)(long)smp_processor_id();
+
+	cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+	cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
+	register_cpu_notifier(&cpu_nfb);
+}
+
--- linux/kernel/Makefile.orig
+++ linux/kernel/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_AUDIT) += audit.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
+obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 
 ifneq ($(CONFIG_IA64),y)
--- linux/kernel/timer.c.orig
+++ linux/kernel/timer.c
@@ -921,6 +921,7 @@ void do_timer(struct pt_regs *regs)
 {
 	jiffies_64++;
 	update_times();
+	softlockup_tick(regs);
 }
 
 #ifdef __ARCH_WANT_SYS_ALARM
--- linux/init/main.c.orig
+++ linux/init/main.c
@@ -596,6 +596,7 @@ static void do_pre_smp_initcalls(void)
 	migration_init();
 #endif
 	spawn_ksoftirqd();
+	spawn_softlockup_task();
 }
 
 static void run_init_process(char *init_filename)
--- linux/include/linux/sched.h.orig
+++ linux/include/linux/sched.h
@@ -176,6 +176,19 @@ extern void update_process_times(int use
 extern void scheduler_tick(void);
 extern unsigned long cache_decay_ticks;
 
+#ifdef CONFIG_DETECT_SOFTLOCKUP
+extern void softlockup_tick(struct pt_regs *regs);
+extern void spawn_softlockup_task(void);
+#else
+static inline void softlockup_tick(struct pt_regs *regs)
+{
+}
+static inline void spawn_softlockup_task(void)
+{
+}
+#endif
+
+
 /* Attach to any functions which should be ignored in wchan output. */
 #define __sched		__attribute__((__section__(".sched.text")))
 /* Is this address in the __sched functions? */
--- linux/lib/Kconfig.debug.orig
+++ linux/lib/Kconfig.debug
@@ -27,6 +27,25 @@ config MAGIC_SYSRQ
 	  Enables console device to interpret special characters as
 	  commands to dump state information.
 
+config DETECT_SOFTLOCKUP
+	bool "Detect Soft Lockups"
+	depends on DEBUG_KERNEL
+	default y
+	help
+	  Say Y here to enable the kernel to detect "soft lockups",
+	  which are bugs that cause the kernel to loop in kernel
+	  mode for more than 10 seconds, without giving other tasks a
+	  chance to run.
+
+	  When a soft-lockup is detected, the kernel will print the
+	  current stack trace (which you should report), but the
+	  system will stay locked up. This feature has negligible
+	  overhead.
+
+	  (Note that "hard lockups" are separate type of bugs that
+	   can be detected via the NMI-watchdog, on platforms that
+	   support it.)
+
 config SCHEDSTATS
 	bool "Collect scheduler statistics"
 	depends on DEBUG_KERNEL && PROC_FS
--- linux-2.6.11/kernel/softirq.c~	2005-05-11 21:47:38.000000000 -0400
+++ linux-2.6.11/kernel/softirq.c	2005-05-11 21:47:53.000000000 -0400
@@ -455,7 +455,7 @@ void tasklet_kill_immediate(struct taskl
 	BUG();
 }
 
-static void takeover_tasklets(unsigned int cpu)
+void takeover_tasklets(unsigned int cpu)
 {
 	struct tasklet_struct **i;
 

linux-2.6.12-firedire-init-breakage.patch:
 ohci1394.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.12-firedire-init-breakage.patch ---

From: Alexander Viro <aviro at redhat.com>

	ohci does the following:
* disables interrupts from host
* does partial initialization
* registers irq
* finishes initialization and enables interrupts generation by host

	Unfortunately, that's broken - we register irq with SA_SHIRQ, so
we *can* get the handler called immediately.  It will find that interrupt
has nothing to do with it; however, before we figure that out we do
spin_lock_irqsave() on a spinlock that gets initialized after we have
registered irq.  Fix is obvious...

	Problem exists in all kernels since 2.4.3 (before that we used
to have a worse one in the same place - no spinlock at all).  Same fix
for all of them...

	I really wonder how much will be caught if we route everything
that would normally be spread by IOAPIC to the same IRQ vector and try
to boot such kernel - I suspect that quite a few drivers register irq
handlers too early and get away with that only because on the test boxen
IRQ in question happens to be not shared.

diff -urN RC12-rc4-base/drivers/ieee1394/ohci1394.c current/drivers/ieee1394/ohci1394.c
--- RC12-rc4-base/drivers/ieee1394/ohci1394.c	2005-05-07 04:04:56.000000000 -0400
+++ current/drivers/ieee1394/ohci1394.c	2005-05-13 20:57:34.000000000 -0400
@@ -478,7 +478,6 @@
 	int num_ports, i;
 
 	spin_lock_init(&ohci->phy_reg_lock);
-	spin_lock_init(&ohci->event_lock);
 
 	/* Put some defaults to these undefined bus options */
 	buf = reg_read(ohci, OHCI1394_BusOptions);
@@ -3399,7 +3398,14 @@
 	/* We hopefully don't have to pre-allocate IT DMA like we did
 	 * for IR DMA above. Allocate it on-demand and mark inactive. */
 	ohci->it_legacy_context.ohci = NULL;
+	spin_lock_init(&ohci->event_lock);
 
+	/*
+	 * interrupts are disabled, all right, but... due to SA_SHIRQ we
+	 * might get called anyway.  We'll see no event, of course, but
+	 * we need to get to that "no event", so enough should be initialized
+	 * by that point.
+	 */
 	if (request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
 			 OHCI1394_DRIVER_NAME, ohci))
 		FAIL(-ENOMEM, "Failed to allocate shared interrupt %d", dev->irq);


linux-2.6.12-input-kill-stupid-messages.patch:
 atkbd.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.12-input-kill-stupid-messages.patch ---
--- linux-2.6.11/drivers/input/keyboard/atkbd.c~	2005-04-30 15:40:09.000000000 -0400
+++ linux-2.6.11/drivers/input/keyboard/atkbd.c	2005-04-30 15:40:35.000000000 -0400
@@ -328,7 +328,7 @@ static irqreturn_t atkbd_interrupt(struc
 			atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
 			goto out;
 		case ATKBD_RET_ERR:
-			printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+//			printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
 			goto out;
 	}
 
@@ -348,9 +348,13 @@
 			break;
 		case ATKBD_KEY_UNKNOWN:
 			if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
+#if 0
+/* Quite a few key switchers and other tools trigger this and it confuses
+   people who can do nothing about it */			
 				printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
 				       "like XFree86, might be trying access hardware directly.\n",
 				       data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+#endif				       
 			} else {
 				printk(KERN_WARNING "atkbd.c: Unknown key %s "
 				       "(%s set %d, code %#x on %s).\n",


linux-2.6.12-ipmi-sysfs.patch:
 ipmi_devintf.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6.12-ipmi-sysfs.patch ---
>From bk-commits-head-owner at vger.kernel.org  Fri May 20 11:15:28 2005
Return-Path: <bk-commits-head-owner at vger.kernel.org>
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by devserv.devel.redhat.com (8.12.11/8.12.11) with ESMTP id j4KFFRHf006781;
	Fri, 20 May 2005 11:15:27 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])
	by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id j4KFFRO24912;
	Fri, 20 May 2005 11:15:27 -0400
Received: from vger.kernel.org (vger.kernel.org [12.107.209.244])
	by mx1.redhat.com (8.12.11/8.12.11) with ESMTP id j4KFFGqV025279;
	Fri, 20 May 2005 11:15:27 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S261480AbVETPN1 (ORCPT <rfc822;davej at redhat.com> + 6 others);
	Fri, 20 May 2005 11:13:27 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S261324AbVETPN0
	(ORCPT <rfc822;bk-commits-head-outgoing>);
	Fri, 20 May 2005 11:13:26 -0400
Received: from hera.kernel.org ([209.128.68.125]:20884 "EHLO hera.kernel.org")
	by vger.kernel.org with ESMTP id S261480AbVETPLp (ORCPT
	<rfc822;bk-commits-head at vger.kernel.org>);
	Fri, 20 May 2005 11:11:45 -0400
Received: from hera.kernel.org (localhost [127.0.0.1])
	by hera.kernel.org (8.13.1/8.13.1) with ESMTP id j4KFBgal002491
	for <bk-commits-head at vger.kernel.org>; Fri, 20 May 2005 08:11:42 -0700
Received: (from dwmw2 at localhost)
	by hera.kernel.org (8.13.1/8.13.1/Submit) id j4KFBgHG002490
	for bk-commits-head at vger.kernel.org; Fri, 20 May 2005 08:11:42 -0700
Date: Fri, 20 May 2005 08:11:42 -0700
Message-Id: <200505201511.j4KFBgHG002490 at hera.kernel.org>
From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
To: bk-commits-head at vger.kernel.org
Subject: [PATCH] Add sysfs support for the IPMI device interface
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
X-Git-Commit: 37e0915b701281182cea9fc90e894d10addf134a
X-Git-Parent: 45fed46f5b98aaf439e9ef125992ec853cd98499
X-Virus-Scanned: ClamAV version 0.85, clamav-milter version 0.85 on localhost
X-Virus-Status: Clean
Sender: bk-commits-head-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List: bk-commits-head at vger.kernel.org
X-RedHat-Spam-Score: 0 
X-Spam-Checker-Version: SpamAssassin 2.60 (1.212-2003-09-23-exp) on 
	devserv.devel.redhat.com
X-Spam-Level: 
X-Spam-Status: No, hits=-4.1 required=5.0 tests=AWL,BAYES_00 autolearn=ham 
	version=2.60
Status: RO
X-Status: A
Content-Length: 3163
Lines: 90

tree e327b635e017dfcfd989b203c16ebd55e1d2526b
parent 45fed46f5b98aaf439e9ef125992ec853cd98499
author Corey Minyard <minyard at acm.org> Fri, 20 May 2005 08:56:23 +0200
committer Linus Torvalds <torvalds at ppc970.osdl.org> Fri, 20 May 2005 21:58:04 -0700

[PATCH] Add sysfs support for the IPMI device interface

Add support for sysfs to the IPMI device interface.

Clean-ups based on Dimitry Torokovs comment by Philipp Hahn.

Signed-off-by: Corey Minyard <minyard at acm.org>
Signed-off-by: Philipp Hahn <pmhahn at titan.lahn.de>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

 drivers/char/ipmi/ipmi_devintf.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

Index: drivers/char/ipmi/ipmi_devintf.c
===================================================================
--- 6b1637f2083772b08337ba62a33ac6a4547ae788/drivers/char/ipmi/ipmi_devintf.c  (mode:100644 sha1:49d67f5384a2c2d9a0a5b97ad0cbd4c40c500b2b)
+++ e327b635e017dfcfd989b203c16ebd55e1d2526b/drivers/char/ipmi/ipmi_devintf.c  (mode:100644 sha1:4bb9af736fba2713ca53a1414526171c53f608f1)
@@ -44,6 +44,7 @@
 #include <linux/ipmi.h>
 #include <asm/semaphore.h>
 #include <linux/init.h>
+#include <linux/device.h>
 
 #define IPMI_DEVINTF_VERSION "v33"
 
@@ -519,15 +520,21 @@ MODULE_PARM_DESC(ipmi_major, "Sets the m
 		 " interface.  Other values will set the major device number"
 		 " to that value.");
 
+static struct class *ipmi_class;
+
 static void ipmi_new_smi(int if_num)
 {
-	devfs_mk_cdev(MKDEV(ipmi_major, if_num),
-		      S_IFCHR | S_IRUSR | S_IWUSR,
+	dev_t dev = MKDEV(ipmi_major, if_num);
+
+	devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
 		      "ipmidev/%d", if_num);
+
+	class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num);
 }
 
 static void ipmi_smi_gone(int if_num)
 {
+	class_simple_device_remove(ipmi_class, MKDEV(ipmi_major, if_num));
 	devfs_remove("ipmidev/%d", if_num);
 }
 
@@ -548,8 +555,15 @@ static __init int init_ipmi_devintf(void
 	printk(KERN_INFO "ipmi device interface version "
 	       IPMI_DEVINTF_VERSION "\n");
 
+	ipmi_class = class_simple_create(THIS_MODULE, "ipmi");
+	if (IS_ERR(ipmi_class)) {
+		printk(KERN_ERR "ipmi: can't register device class\n");
+		return PTR_ERR(ipmi_class);
+	}
+
 	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
 	if (rv < 0) {
+		class_simple_destroy(ipmi_class);
 		printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
 		return rv;
 	}
@@ -563,6 +577,7 @@ static __init int init_ipmi_devintf(void
 	rv = ipmi_smi_watcher_register(&smi_watcher);
 	if (rv) {
 		unregister_chrdev(ipmi_major, DEVICE_NAME);
+		class_simple_destroy(ipmi_class);
 		printk(KERN_WARNING "ipmi: can't register smi watcher\n");
 		return rv;
 	}
@@ -573,6 +588,7 @@ module_init(init_ipmi_devintf);
 
 static __exit void cleanup_ipmi(void)
 {
+	class_simple_destroy(ipmi_class);
 	ipmi_smi_watcher_unregister(&smi_watcher);
 	devfs_remove(DEVICE_NAME);
 	unregister_chrdev(ipmi_major, DEVICE_NAME);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


linux-2.6.12-kobject-ordering.patch:
 core.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6.12-kobject-ordering.patch ---

As a result of the split of the kobject-registration and the
corresponding hotplug event, the order of events for device_add() has
changed. This restores the old order, cause it confused some userspace
applications.

Signed-off-by: Kay Sievers <kay.sievers at vrfy.org>
---

--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -248,6 +248,7 @@ int device_add(struct device *dev)
 
 	if ((error = kobject_add(&dev->kobj)))
 		goto Error;
+	kobject_hotplug(&dev->kobj, KOBJ_ADD);
 	if ((error = device_pm_add(dev)))
 		goto PMError;
 	if ((error = bus_add_device(dev)))
@@ -260,14 +261,13 @@ int device_add(struct device *dev)
 	/* notify platform of device entry */
 	if (platform_notify)
 		platform_notify(dev);
-
-	kobject_hotplug(&dev->kobj, KOBJ_ADD);
  Done:
 	put_device(dev);
 	return error;
  BusError:
 	device_pm_remove(dev);
  PMError:
+	kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
 	kobject_del(&dev->kobj);
  Error:
 	if (parent)



linux-2.6.12-missing-exports.patch:
 drivers/char/random.c |    1 +
 lib/kobject_uevent.c  |    1 +
 2 files changed, 2 insertions(+)

--- NEW FILE linux-2.6.12-missing-exports.patch ---
WARNING:
/usr/src/build/566509-ppc64iseries/install/lib/modules/2.6.11-1.1311_FC4/kernel/drivers/input/input.ko
needs unknown symbol add_input_randomness

--- linux-2.6.11/drivers/char/random.c~	2005-05-14 16:42:24.000000000 -0400
+++ linux-2.6.11/drivers/char/random.c	2005-05-14 16:42:46.000000000 -0400
@@ -646,6 +646,7 @@ extern void add_input_randomness(unsigne
 	add_timer_randomness(&input_timer_state,
 			     (type << 4) ^ code ^ (code >> 4) ^ value);
 }
+EXPORT_SYMBOL_GPL(add_input_randomness);
 
 void add_interrupt_randomness(int irq)
 {


WARNING:
/usr/src/build/566509-ppc64iseries/install/lib/modules/2.6.11-1.1311_FC4/kernel/drivers/input/input.ko
needs unknown symbol hotplug_path

--- linux-2.6.11/lib/kobject_uevent.c~	2005-05-14 16:45:13.000000000 -0400
+++ linux-2.6.11/lib/kobject_uevent.c	2005-05-14 16:45:27.000000000 -0400
@@ -178,6 +178,7 @@ static inline int send_uevent(const char
 
 #ifdef CONFIG_HOTPLUG
 char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug";
+EXPORT_SYMBOL_GPL(hotplug_path);
 u64 hotplug_seqnum;
 static DEFINE_SPINLOCK(sequence_lock);
 

linux-2.6.12-net-atm-lanai-nodev-rmmod.patch:
 lanai.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6.12-net-atm-lanai-nodev-rmmod.patch ---
--- linux-2.6.11/drivers/atm/lanai.c~	2005-05-23 21:48:00.000000000 -0400
+++ linux-2.6.11/drivers/atm/lanai.c	2005-05-23 21:50:53.000000000 -0400
@@ -2760,6 +2760,7 @@ static void __exit lanai_module_exit(voi
 	 * gone, so there isn't much to do
 	 */
 	DPRINTK("cleanup_module()\n");
+	pci_unregister_driver(&lanai_driver);
 }
 
 module_init(lanai_module_init);

linux-2.6.12-net-conntrack-bridge-fix.patch:
 bridge/br_netfilter.c |    2 +-
 ipv4/ip_output.c      |    8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6.12-net-conntrack-bridge-fix.patch ---
diff-tree 9666dae51013b064e7d77fc36b5cee98dd167ed5 (from bcd61272db5e643b6d9c01c9d5085b914d9f19df)
Author: Patrick McHardy <kaber at trash.net>
Date:   Tue Jun 28 16:04:44 2005 -0700

    [NETFILTER]: Fix connection tracking bug in 2.6.12
    
    In 2.6.12 we started dropping the conntrack reference when a packet
    leaves the IP layer. This broke connection tracking on a bridge,
    because bridge-netfilter defers calling some NF_IP_* hooks to the bridge
    layer for locally generated packets going out a bridge, where the
    conntrack reference is no longer available. This patch keeps the
    reference in this case as a temporary solution, long term we will
    remove the defered hook calling. No attempt is made to drop the
    reference in the bridge-code when it is no longer needed, tc actions
    could already have sent the packet anywhere.
    
    Signed-off-by: Patrick McHardy <kaber at trash.net>
    Signed-off-by: David S. Miller <davem at davemloft.net>

diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsi
 		 * doesn't use the bridge parent of the indev by using
 		 * the BRNF_DONT_TAKE_PARENT mask. */
 		if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
-			nf_bridge->mask &= BRNF_DONT_TAKE_PARENT;
+			nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
 			nf_bridge->physindev = (struct net_device *)in;
 		}
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -188,7 +188,13 @@ static inline int ip_finish_output2(stru
 		skb = skb2;
 	}
 
-	nf_reset(skb);
+#ifdef CONFIG_BRIDGE_NETFILTER
+	/* bridge-netfilter defers calling some IP hooks to the bridge layer
+	 * and still needs the conntrack reference.
+	 */
+	if (skb->nf_bridge == NULL)
+#endif
+		nf_reset(skb);
 
 	if (hh) {
 		int hh_alen;

linux-2.6.12-net-e1000-update.patch:
 e1000.h         |   37 
 e1000_ethtool.c |  105 +-
 e1000_hw.c      | 2147 +++++++++++++++++++++++++++++++++++++++++++-------------
 e1000_hw.h      |  570 ++++++++++++++
 e1000_main.c    | 1147 +++++++++++++++++++++++------
 e1000_osdep.h   |   32 
 e1000_param.c   |    3 
 7 files changed, 3248 insertions(+), 793 deletions(-)

--- NEW FILE linux-2.6.12-net-e1000-update.patch ---
diff -urpN --exclude-from=/home/devel/davej/.exclude src/kernel/HEAD/devel/kernel-2.6.11/linux-2.6.11/drivers/net/e1000/e1000_ethtool.c e1000/e1000_ethtool.c
--- linux-2.6.11/drivers/net/e1000/e1000_ethtool.c	2005-05-13 15:58:55.000000000 -0400
+++ linux-2.6.11/drivers/net/e1000/e1000_ethtool.c	2005-05-14 02:38:28.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   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 
@@ -69,6 +69,7 @@ static const struct e1000_stats e1000_gs
 	{ "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
 	{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
 	{ "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) },
+	{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
 	{ "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
 	{ "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
 	{ "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
@@ -593,7 +594,7 @@ e1000_set_ringparam(struct net_device *n
 	tx_old = adapter->tx_ring;
 	rx_old = adapter->rx_ring;
 
-	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
 
 	if(netif_running(adapter->netdev))
@@ -784,8 +785,8 @@ e1000_intr_test(struct e1000_adapter *ad
 	/* Hook up test interrupt handler just for this test */
  	if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) {
  		shared_int = FALSE;
- 	} else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, 
-			netdev->name, netdev)){
+ 	} else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ,
+			      netdev->name, netdev)){
 		*data = 1;
 		return -1;
 	}
@@ -842,10 +843,8 @@ e1000_intr_test(struct e1000_adapter *ad
 			 * test failed.
 			 */
 			adapter->test_icr = 0;
-			E1000_WRITE_REG(&adapter->hw, IMC, 
-					(~mask & 0x00007FFF));
-			E1000_WRITE_REG(&adapter->hw, ICS, 
-					(~mask & 0x00007FFF));
+			E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF);
+			E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF);
 			msec_delay(10);
 
 			if(adapter->test_icr) {
@@ -919,7 +918,8 @@ e1000_setup_desc_rings(struct e1000_adap
 
 	/* Setup Tx descriptor ring and Tx buffers */
 
-	txdr->count = 80;
+	if(!txdr->count)
+		txdr->count = E1000_DEFAULT_TXD;   
 
 	size = txdr->count * sizeof(struct e1000_buffer);
 	if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
@@ -974,7 +974,8 @@ e1000_setup_desc_rings(struct e1000_adap
 
 	/* Setup Rx descriptor ring and Rx buffers */
 
-	rxdr->count = 80;
+	if(!rxdr->count)
+		rxdr->count = E1000_DEFAULT_RXD;   
 
 	size = rxdr->count * sizeof(struct e1000_buffer);
 	if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
@@ -1008,7 +1009,7 @@ e1000_setup_desc_rings(struct e1000_adap
 		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
 		struct sk_buff *skb;
 
-		if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, 
+		if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
 				GFP_KERNEL))) {
 			ret_val = 6;
 			goto err_nomem;
@@ -1310,31 +1311,62 @@ e1000_run_loopback_test(struct e1000_ada
 	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
 	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
-	int i, ret_val;
+	int i, j, k, l, lc, good_cnt, ret_val=0;
+	unsigned long time;
 
 	E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);
 
-	for(i = 0; i < 64; i++) {
-		e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024);
-		pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma,
-					    txdr->buffer_info[i].length,
-					    PCI_DMA_TODEVICE);
-	}
-	E1000_WRITE_REG(&adapter->hw, TDT, i);
-
-	msec_delay(200);
-
-	i = 0;
-	do {
-		pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma,
-					    rxdr->buffer_info[i].length,
-					    PCI_DMA_FROMDEVICE);
-
-		ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb,
-						   1024);
-		i++;
-	} while (ret_val != 0 && i < 64);
+	/* Calculate the loop count based on the largest descriptor ring 
+	 * The idea is to wrap the largest ring a number of times using 64
+	 * send/receive pairs during each loop
+	 */
+
+	if(rxdr->count <= txdr->count)
+		lc = ((txdr->count / 64) * 2) + 1;
+	else
+		lc = ((rxdr->count / 64) * 2) + 1;
 
+	k = l = 0;
+	for(j = 0; j <= lc; j++) { /* loop count loop */
+		for(i = 0; i < 64; i++) { /* send the packets */
+			e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 
+					1024);
+			pci_dma_sync_single_for_device(pdev, 
+					txdr->buffer_info[k].dma,
+				    	txdr->buffer_info[k].length,
+				    	PCI_DMA_TODEVICE);
+			if(unlikely(++k == txdr->count)) k = 0;
+		}
+		E1000_WRITE_REG(&adapter->hw, TDT, k);
+		msec_delay(200);
+		time = jiffies; /* set the start time for the receive */
+		good_cnt = 0;
+		do { /* receive the sent packets */
+			pci_dma_sync_single_for_cpu(pdev, 
+					rxdr->buffer_info[l].dma,
+				    	rxdr->buffer_info[l].length,
+				    	PCI_DMA_FROMDEVICE);
+	
+			ret_val = e1000_check_lbtest_frame(
+					rxdr->buffer_info[l].skb,
+				   	1024);
+			if(!ret_val)
+				good_cnt++;
+			if(unlikely(++l == rxdr->count)) l = 0;
+			/* time + 20 msecs (200 msecs on 2.4) is more than 
+			 * enough time to complete the receives, if it's 
+			 * exceeded, break and error off
+			 */
+		} while (good_cnt < 64 && jiffies < (time + 20));
+		if(good_cnt != 64) {
+			ret_val = 13; /* ret_val is the same as mis-compare */
+			break; 
+		}
+		if(jiffies >= (time + 2)) {
+			ret_val = 14; /* error code for time out error */
+			break;
+		}
+	} /* end loop count loop */
 	return ret_val;
 }
 
@@ -1354,13 +1386,12 @@ static int
 e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
 {
 	*data = 0;
-
 	if (adapter->hw.media_type == e1000_media_type_internal_serdes) {
 		int i = 0;
 		adapter->hw.serdes_link_down = TRUE;
 
-		/* on some blade server designs link establishment */
-		/* could take as long as 2-3 minutes.              */
+		/* On some blade server designs, link establishment
+		 * could take as long as 2-3 minutes */
 		do {
 			e1000_check_for_link(&adapter->hw);
 			if (adapter->hw.serdes_link_down == FALSE)
@@ -1368,9 +1399,11 @@ e1000_link_test(struct e1000_adapter *ad
 			msec_delay(20);
 		} while (i++ < 3750);
 
-		*data = 1; 
+		*data = 1;
 	} else {
 		e1000_check_for_link(&adapter->hw);
+		if(adapter->hw.autoneg)  /* if auto_neg is set wait for it */
+			msec_delay(4000);
 
 		if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
 			*data = 1;
diff -urpN --exclude-from=/home/devel/davej/.exclude src/kernel/HEAD/devel/kernel-2.6.11/linux-2.6.11/drivers/net/e1000/e1000.h e1000/e1000.h
--- linux-2.6.11/drivers/net/e1000/e1000.h	2005-05-13 15:58:55.000000000 -0400
+++ linux-2.6.11/drivers/net/e1000/e1000.h	2005-05-14 02:38:29.000000000 -0400
@@ -1,7 +1,7 @@
[...5787 lines suppressed...]
 		rctl &= ~E1000_RCTL_VFE;
 		E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+		if(adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
+			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
+		}
 	}
 
 	e1000_irq_enable(adapter);
@@ -2938,7 +3545,10 @@ e1000_vlan_rx_add_vid(struct net_device 
 {
 	struct e1000_adapter *adapter = netdev->priv;
 	uint32_t vfta, index;
-
+	if((adapter->hw.mng_cookie.status &
+		E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+		(vid == adapter->mng_vlan_id))
+		return;
 	/* add VID to filter table */
 	index = (vid >> 5) & 0x7F;
 	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -2959,6 +3569,10 @@ e1000_vlan_rx_kill_vid(struct net_device
 
 	e1000_irq_enable(adapter);
 
+	if((adapter->hw.mng_cookie.status &
+		E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
+		(vid == adapter->mng_vlan_id))
+		return;
 	/* remove VID from filter table */
 	index = (vid >> 5) & 0x7F;
 	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -3005,8 +3619,7 @@ e1000_set_spd_dplx(struct e1000_adapter 
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		DPRINTK(PROBE, ERR, 
-			"Unsupported Speed/Duplexity configuration\n");
+		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
 		return -EINVAL;
 	}
 	return 0;
@@ -3034,7 +3647,7 @@ e1000_suspend(struct pci_dev *pdev, uint
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev->priv;
-	uint32_t ctrl, ctrl_ext, rctl, manc, status;
+	uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
 	uint32_t wufc = adapter->wol;
 
 	netif_device_detach(netdev);
@@ -3076,6 +3689,9 @@ e1000_suspend(struct pci_dev *pdev, uint
 			E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
 		}
 
+		/* Allow time for pending master requests to run */
+		e1000_disable_pciex_master(&adapter->hw);
+
 		E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
 		E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
 		pci_enable_wake(pdev, 3, 1);
@@ -3100,6 +3716,16 @@ e1000_suspend(struct pci_dev *pdev, uint
 		}
 	}
 
+	switch(adapter->hw.mac_type) {
+	case e1000_82573:
+		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+		E1000_WRITE_REG(&adapter->hw, SWSM,
+				swsm & ~E1000_SWSM_DRV_LOAD);
+		break;
+	default:
+		break;
+	}
+
 	pci_disable_device(pdev);
 
 	state = (state > 0) ? 3 : 0;
@@ -3114,13 +3740,12 @@ e1000_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev->priv;
-	uint32_t manc, ret;
+	uint32_t manc, ret, swsm;
 
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
 	ret = pci_enable_device(pdev);
-	if (pdev->is_busmaster)
-		pci_set_master(pdev);
+	pci_set_master(pdev);
 
 	pci_enable_wake(pdev, 3, 0);
 	pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
@@ -3140,10 +3765,19 @@ e1000_resume(struct pci_dev *pdev)
 		E1000_WRITE_REG(&adapter->hw, MANC, manc);
 	}
 
+	switch(adapter->hw.mac_type) {
+	case e1000_82573:
+		swsm = E1000_READ_REG(&adapter->hw, SWSM);
+		E1000_WRITE_REG(&adapter->hw, SWSM,
+				swsm | E1000_SWSM_DRV_LOAD);
+		break;
+	default:
+		break;
+	}
+
 	return 0;
 }
 #endif
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Polling 'interrupt' - used by things like netconsole to send skbs
@@ -3151,7 +3785,7 @@ e1000_resume(struct pci_dev *pdev)
  * the interrupt routine is executing.
  */
 static void
-e1000_netpoll (struct net_device *netdev)
+e1000_netpoll(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev->priv;
 	disable_irq(adapter->pdev->irq);
diff -urpN --exclude-from=/home/devel/davej/.exclude src/kernel/HEAD/devel/kernel-2.6.11/linux-2.6.11/drivers/net/e1000/e1000_osdep.h e1000/e1000_osdep.h
--- linux-2.6.11/drivers/net/e1000/e1000_osdep.h	2005-03-02 02:37:50.000000000 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_osdep.h	2005-05-14 02:38:40.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   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 
@@ -42,7 +42,12 @@
 #include <linux/sched.h>
 
 #ifndef msec_delay
-#define msec_delay(x) msleep(x)
+#define msec_delay(x)	do { if(in_interrupt()) { \
+				/* Don't mdelay in interrupt context! */ \
+	                	BUG(); \
+			} else { \
+				msleep(x); \
+			} } while(0)
 
 /* Some workarounds require millisecond delays and are run during interrupt
  * context.  Most notably, when establishing link, the phy may need tweaking
@@ -96,6 +101,29 @@ typedef enum {
         (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
         ((offset) << 2)))
 
+#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
+#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
+
+#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
+    writew((value), ((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        ((offset) << 1))))
+
+#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
+    readw((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        ((offset) << 1)))
+
+#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
+    writeb((value), ((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        (offset))))
+
+#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
+    readb((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        (offset)))
+
 #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
 
 #endif /* _E1000_OSDEP_H_ */
diff -urpN --exclude-from=/home/devel/davej/.exclude src/kernel/HEAD/devel/kernel-2.6.11/linux-2.6.11/drivers/net/e1000/e1000_param.c e1000/e1000_param.c
--- linux-2.6.11/drivers/net/e1000/e1000_param.c	2005-03-02 02:38:13.000000000 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_param.c	2005-05-14 02:38:55.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
   
   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 
@@ -478,7 +478,6 @@ e1000_check_options(struct e1000_adapter
 				DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", 
 					opt.name);
 				break;
-			case -1:
 			default:
 				e1000_validate_option(&adapter->itr, &opt, 
 					adapter);

linux-2.6.12-net-make-orinoco-suck-less.patch:
 linux-2.6.12/drivers/net/wireless/orinoco.c | 2460 +++++++++++++++++-----------
 linux-2.6.12/drivers/net/wireless/orinoco.h |   31 
 linux-2.6/include/net/ieee80211.h           |  882 ++++++++++
 3 files changed, 2473 insertions(+), 900 deletions(-)

--- NEW FILE linux-2.6.12-net-make-orinoco-suck-less.patch ---
diff -urpN --exclude-from=/home/devel/davej/.exclude vanilla/drivers/net/wireless/orinoco.c linux-2.6.12/drivers/net/wireless/orinoco.c
--- vanilla/drivers/net/wireless/orinoco.c	2005-06-17 15:48:29.000000000 -0400
+++ linux-2.6.12/drivers/net/wireless/orinoco.c	2005-06-23 18:34:19.000000000 -0400
@@ -416,12 +416,50 @@
  *	  port.  This is supposed to allow 802.1x to work sanely, but
  *	  doesn't seem to yet.
  *
+ * v0.14alpha2 -> v0.15rc1 - 19 Apr 2004 - Pavel Roskin & David Gibson
+ *	o Fix bug which prevented setting 32 character ESSIDs from
+ *	  iwconfig (Thomas Schulz).
+ *	o Fix for incorrect CIS access in orinoco_plx (Pavel Roskin).
+ *	o Fix setting WEP key if __orinoco_fastkeychange() is not
+ *	  supported (Pavel Roskin).
+ *	o New wireless extensions API and scanning support (patch from
+ *	  Moustafa Youssef, updated by Jim Carter and Pavel Roskin).
+ *	o Add minimal ethtool support (Pavel Roskin).
+ *	o Replace CardServices() calls for compatibility with Linux
+ *	  2.6.2 and above (Pavel Roskin).
+ *	o Fix recognition of Intersil x.x.1 firmware (Pavel Roskin).
+ *	o Replace dump_recs with more flexible get_rid ioctl (Pavel
+ *	  Roskin).
+ *	o RF monitor mode support (Pavel Roskin).
+ *	o Lots of bugfixes.
+ *
+ * v0.15rc1 -> v0.15rc2 - 28 Jul 2004 - Pavel Roskin & David Gibson
+ *	o orinoco_pci saves PCI registers on suspend (Simon Huggins).
+ *	o Monitor mode disabled on Agere 8.xx firmware - it's broken.
+ *	o BAP timeout increased - needed for Intersil firmware.
+ *	o Tx power is no longer reported - it's unreliable.
+ *	o Use 802.11 header in rx path.  Hide packets with ToDS flag
+ *	  from programs that don't need promiscous mode (John Denker).
+ *	o Manual roaming implemented for Symbol and Intersil firmware.
+ *	o Use netdev_priv() instead of directly dereferencing dev->priv.
+ *	o Some simplification of pcmcia init code in orinoco_cs and
+ *	  spectrum_cs. 
+ *	o Numerous trivial cleanups, mainly arising from long-overdue
+ *	  merge with mainline.
+ *
+ * v0.15rc2 -> ???? - ???? - David Gibson
+ *	o Use ssleep() or msleep() instead of hardcoded
+ *	  schedule_timeout()s (Nishanth Aravamudan via kernel-janitors
+ *	  list).
+ *	o Several cleanups and bugfixes in pci/plx/tmd/nortel drivers.
+ *	o Fix memory leak in orinoco_join_ap().
+ *	o Change io handling to avoid sparse and gcc warnings.
+ *	o Use C99 array initializers and ARRAY_SIZE() for iw_handler
+ *	  tables.
+ *
  * TODO
- *	o New wireless extensions API (patch from Moustafa
- *	  Youssef, updated by Jim Carter and Pavel Roskin).
  *	o Handle de-encapsulation within network layer, provide 802.11
  *	  headers (patch from Thomas 'Dent' Mirlacher)
- *	o RF monitor mode support
  *	o Fix possible races in SPY handling.
  *	o Disconnect wireless extensions from fundamental configuration.
  *	o (maybe) Software WEP support (patch from Stano Meduna).
@@ -462,7 +500,10 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
+#include <linux/ethtool.h>
 #include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -492,6 +533,13 @@ EXPORT_SYMBOL(orinoco_debug);
 static int suppress_linkstatus; /* = 0 */
 module_param(suppress_linkstatus, bool, 0644);
 MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
+static int ignore_disconnect; /* = 0 */
+module_param(ignore_disconnect, int, 0644);
+MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
+
+static int force_monitor; /* = 0 */
+module_param(force_monitor, int, 0644);
+MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
 
 /********************************************************************/
 /* Compile time configuration and compatibility stuff               */
@@ -508,6 +556,10 @@ MODULE_PARM_DESC(suppress_linkstatus, "D
 /* Internal constants                                               */
 /********************************************************************/
 
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
+
 #define ORINOCO_MIN_MTU		256
 #define ORINOCO_MAX_MTU		(IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
 
@@ -534,6 +586,11 @@ MODULE_PARM_DESC(suppress_linkstatus, "D
 				 | HERMES_EV_WTERR | HERMES_EV_INFO \
 				 | HERMES_EV_INFDROP )
 
+#define MAX_RID_LEN 1024
+
+static const struct iw_handler_def orinoco_handler_def;
+static struct ethtool_ops orinoco_ethtool_ops;
+
 /********************************************************************/
 /* Data tables                                                      */
 /********************************************************************/
@@ -568,26 +625,45 @@ static struct {
 /* Data types                                                       */
 /********************************************************************/
 
-struct header_struct {
-	/* 802.3 */
-	u8 dest[ETH_ALEN];
-	u8 src[ETH_ALEN];
-	u16 len;
-	/* 802.2 */
+/* Used in Event handling.
+ * We avoid nested structres as they break on ARM -- Moustafa */
+struct hermes_tx_descriptor_802_11 {
+	/* hermes_tx_descriptor */
+	u16 status;
+	u16 reserved1;
+	u16 reserved2;
+	u32 sw_support;
+	u8 retry_count;
+	u8 tx_rate;
+	u16 tx_control;
+
+	/* ieee802_11_hdr */
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u16 data_len;
+
+	/* ethhdr */
+	unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
+	unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
+	unsigned short  h_proto;                /* packet type ID field */
+
+	/* p8022_hdr */
 	u8 dsap;
 	u8 ssap;
 	u8 ctrl;
-	/* SNAP */
 	u8 oui[3];
+
 	u16 ethertype;
 } __attribute__ ((packed));
 
-/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
-u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-
-#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
-
+/* Rx frame header except compatibility 802.3 header */
 struct hermes_rx_descriptor {
+	/* Control */
 	u16 status;
 	u32 time;
 	u8 silence;
@@ -595,16 +671,26 @@ struct hermes_rx_descriptor {
 	u8 rate;
 	u8 rxflow;
 	u32 reserved;
+
+	/* 802.11 header */
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+
+	/* Data length */
+	u16 data_len;
 } __attribute__ ((packed));
 
 /********************************************************************/
 /* Function prototypes                                              */
 /********************************************************************/
 
-static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int __orinoco_program_rids(struct net_device *dev);
 static void __orinoco_set_multicast_list(struct net_device *dev);
-static int orinoco_debug_dump_recs(struct net_device *dev);
 
 /********************************************************************/
 /* Internal helper functions                                        */
@@ -626,6 +712,10 @@ static inline void set_port_type(struct 
 			priv->createibss = 1;
 		}
 		break;
+	case IW_MODE_MONITOR:
+		priv->port_type = 3;
+		priv->createibss = 0;
[...3868 lines suppressed...]
+
+	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+				 * WEP key changes */
+
+	/* If the host performs {en,de}cryption, then set to 1 */
+	int host_encrypt;
+	int host_decrypt;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	int wpa_enabled;
+	int drop_unencrypted;
+	int tkip_countermeasures;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+
+	struct list_head crypt_deinit_list;
+	struct ieee80211_crypt_data *crypt[WEP_KEYS];
+	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+	struct timer_list crypt_deinit_timer;
+
+	int bcrx_sta_key; /* use individual keys to override default keys even
+			   * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx;
+	u16 fts; /* Fragmentation Threshold */
+
+	/* Association info */
+	u8 bssid[ETH_ALEN];
+
+	enum ieee80211_state state;
+
+	int mode;       /* A, B, G */
+	int modulation; /* CCK, OFDM */
+	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
+	int abg_ture;   /* ABG flag              */
+
+	/* Callback functions */
+	void (*set_security)(struct net_device *dev,
+			     struct ieee80211_security *sec);
+	int (*hard_start_xmit)(struct ieee80211_txb *txb,
+			       struct net_device *dev);
+	int (*reset_port)(struct net_device *dev);
+
+	/* This must be the last item so that it points to the data
+	 * allocated beyond this structure by alloc_ieee80211 */
+	u8 priv[0];
+};
+
+#define IEEE_A            (1<<0)
+#define IEEE_B            (1<<1)
+#define IEEE_G            (1<<2)
+#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
+
+extern inline void *ieee80211_priv(struct net_device *dev)
+{
+	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+}
+
+extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+{
+	/* Single white space is for Linksys APs */
+	if (essid_len == 1 && essid[0] == ' ')
+		return 1;
+
+	/* Otherwise, if the entire essid is 0, we assume it is hidden */
+	while (essid_len) {
+		essid_len--;
+		if (essid[essid_len] != '\0')
+			return 0;
+	}
+
+	return 1;
+}
+
+extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+{
+	/*
+	 * It is possible for both access points and our device to support
+	 * combinations of modes, so as long as there is one valid combination
+	 * of ap/device supported modes, then return success
+	 *
+	 */
+	if ((mode & IEEE_A) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_G) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_B) &&
+	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	return 0;
+}
+
+extern inline int ieee80211_get_hdrlen(u16 fc)
+{
+	int hdrlen = 24;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = 30; /* Addr4 */
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (WLAN_FC_GET_STYPE(fc)) {
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = 10;
+			break;
+		default:
+			hdrlen = 16;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+
+
+/* ieee80211.c */
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
+
+extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+
+/* ieee80211_tx.c */
+
+
+extern int ieee80211_xmit(struct sk_buff *skb,
+			  struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+
+/* ieee80211_rx.c */
+extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats);
+extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+			     struct ieee80211_hdr *header,
+			     struct ieee80211_rx_stats *stats);
+
+/* iee80211_wx.c */
+extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+
+
+extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+{
+	ieee->scans++;
+}
+
+extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+{
+	return ieee->scans;
+}
+
+static inline const char *escape_essid(const char *essid, u8 essid_len) {
+	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+	const char *s = essid;
+	char *d = escaped;
+
+	if (ieee80211_is_empty_essid(essid, essid_len)) {
+		memcpy(escaped, "<hidden>", sizeof("<hidden>"));
+		return escaped;
+	}
+
+	essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
+	while (essid_len--) {
+		if (*s == '\0') {
+			*d++ = '\\';
+			*d++ = '0';
+			s++;
+		} else {
+			*d++ = *s++;
+		}
+	}
+	*d = '\0';
+	return escaped;
+}
+
+#endif /* IEEE80211_H */


linux-2.6.12-net-sundance-ip100A.patch:
 sundance.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6.12-net-sundance-ip100A.patch ---
--- linux-2.6.11/drivers/net/sundance.c~	2005-05-06 15:11:22.000000000 -0400
+++ linux-2.6.11/drivers/net/sundance.c	2005-05-06 15:12:22.000000000 -0400
@@ -282,6 +282,7 @@ static struct pci_device_id sundance_pci
 	{0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3},
 	{0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
 	{0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+	{0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
@@ -299,7 +300,8 @@ static struct pci_id_info pci_id_tbl[] =
 	{"D-Link DFE-580TX 4 port Server Adapter"},
 	{"D-Link DFE-530TXS FAST Ethernet Adapter"},
 	{"D-Link DL10050-based FAST Ethernet Adapter"},
-	{"Sundance Technology Alta"},
+	{"IC Plus IP100 Fast Ethernet Adapter"},
+	{"IC Plus IP100A Fast Ethernet Adapter" },
 	{NULL,},			/* 0 terminated list. */
 };
 

linux-2.6.12-net-tulip-double-spinunlock.patch:
 media.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6.12-net-tulip-double-spinunlock.patch ---
--- linux-2.6.11/drivers/net/tulip/media.c~	2005-05-23 17:24:34.000000000 -0400
+++ linux-2.6.11/drivers/net/tulip/media.c	2005-05-23 17:24:51.000000000 -0400
@@ -174,6 +174,7 @@ void tulip_mdio_write(struct net_device 
 				break;
 		}
 		spin_unlock_irqrestore(&tp->mii_lock, flags);
+		return;
 	}
 		
 	/* Establish sync by sending 32 logic ones. */

linux-2.6.12-nmi.patch:
 arch/i386/kernel/apic.c      |    2 --
 arch/i386/kernel/io_apic.c   |    2 --
 arch/i386/kernel/nmi.c       |   11 +++++++----
 arch/i386/kernel/smpboot.c   |    3 ---
 arch/x86_64/kernel/io_apic.c |    2 --
 arch/x86_64/kernel/nmi.c     |    9 +++++++--
 include/asm-i386/apic.h      |    1 -
 include/asm-x86_64/apic.h    |    1 -
 8 files changed, 14 insertions(+), 17 deletions(-)

--- NEW FILE linux-2.6.12-nmi.patch ---

tree 6adb8d33585f8eee20794827c79e40991aeeaee5
parent fd51f666fa591294bd7462447512666e61c56ea0
author Jack F Vogel <jfv at bluesong.net> Sun, 01 May 2005 22:58:48 -0700
committer Linus Torvalds <torvalds at ppc970.osdl.org> Sun, 01 May 2005 22:58:48 -0700

[PATCH] check nmi watchdog is broken

A bug against an xSeries system showed up recently noting that the
check_nmi_watchdog() test was failing.

I have been investigating it and discovered in both i386 and x86_64 the
recent change to the routine to use the cpu_callin_map has uncovered a
problem.  Prior to that change, on an SMP box, the test was trivally
passing because all cpu's were found to not yet be online, but now with the
callin_map they are discovered, it goes on to test the counter and they
have not yet begun to increment, so it announces a CPU is stuck and bails
out.

On all the systems I have access to test, the announcement of failure is
also bougs...  by the time you can login and check /proc/interrupts, the
NMI count is happily incrementing on all CPUs.  Its just that the test is
being done too early.

I have tried moving the call to the test around a bit, and it was always
too early.  I finally hit on this proposed solution, it delays the routine
via a late_initcall(), seems like the right solution to me.

Signed-off-by: Adrian Bunk <bunk at stusta.de>
Cc: Andi Kleen <ak at muc.de>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

 i386/kernel/apic.c      |    2 --
 i386/kernel/io_apic.c   |    2 --
 i386/kernel/nmi.c       |   11 +++++++----
 i386/kernel/smpboot.c   |    3 ---
 x86_64/kernel/io_apic.c |    2 --
 x86_64/kernel/nmi.c     |    9 +++++++--
 asm-i386/apic.h         |    1 -
 asm-x86_64/apic.h       |    1 -
 8 files changed, 14 insertions(+), 17 deletions(-)

Index: arch/i386/kernel/apic.c
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/arch/i386/kernel/apic.c  (mode:100644 sha1:e3879f7625c2e80a923bf12ede3dce08ca714d0a)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/arch/i386/kernel/apic.c  (mode:100644 sha1:d509836b70c356ec5c61df9cdb967cf5f5c753ba)
@@ -1265,8 +1265,6 @@ int __init APIC_init_uniprocessor (void)
 
 	setup_local_APIC();
 
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		check_nmi_watchdog();
 #ifdef CONFIG_X86_IO_APIC
 	if (smp_found_config)
 		if (!skip_ioapic_setup && nr_ioapics)
Index: arch/i386/kernel/io_apic.c
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/arch/i386/kernel/io_apic.c  (mode:100644 sha1:5e0d55be54357bbc4a1f232a1535b9276d9d876f)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/arch/i386/kernel/io_apic.c  (mode:100644 sha1:7a324e8b86f9c4b5f2cf8d9bc40a9426cbd21c0a)
@@ -2175,7 +2175,6 @@ static inline void check_timer(void)
 				disable_8259A_irq(0);
 				setup_nmi();
 				enable_8259A_irq(0);
-				check_nmi_watchdog();
 			}
 			return;
 		}
@@ -2198,7 +2197,6 @@ static inline void check_timer(void)
 				add_pin_to_irq(0, 0, pin2);
 			if (nmi_watchdog == NMI_IO_APIC) {
 				setup_nmi();
-				check_nmi_watchdog();
 			}
 			return;
 		}
Index: arch/i386/kernel/nmi.c
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/arch/i386/kernel/nmi.c  (mode:100644 sha1:2f89d000f9540b0e95b6f09b18858dee85c2f64c)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/arch/i386/kernel/nmi.c  (mode:100644 sha1:2c0ee9c2d0204bc400ea92791c6cd2c23c4fd9de)
@@ -102,20 +102,21 @@ int nmi_active;
 	(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|	\
 	 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
 
-int __init check_nmi_watchdog (void)
+static int __init check_nmi_watchdog(void)
 {
 	unsigned int prev_nmi_count[NR_CPUS];
 	int cpu;
 
-	printk(KERN_INFO "testing NMI watchdog ... ");
+	if (nmi_watchdog == NMI_NONE)
+		return 0;
+
+	printk(KERN_INFO "Testing NMI watchdog ... ");
 
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
 	local_irq_enable();
 	mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
-	/* FIXME: Only boot CPU is online at this stage.  Check CPUs
-           as they come up. */
 	for (cpu = 0; cpu < NR_CPUS; cpu++) {
 #ifdef CONFIG_SMP
 		/* Check cpu_callin_map here because that is set
@@ -139,6 +140,8 @@ int __init check_nmi_watchdog (void)
 
 	return 0;
 }
+/* This needs to happen later in boot so counters are working */
+late_initcall(check_nmi_watchdog);
 
 static int __init setup_nmi_watchdog(char *str)
 {
Index: arch/i386/kernel/smpboot.c
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/arch/i386/kernel/smpboot.c  (mode:100644 sha1:fd36d2f65f885e73a61c9fb131bcb1bf2a7e4aea)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/arch/i386/kernel/smpboot.c  (mode:100644 sha1:cbea7ac582e57a09fe919e4cc444c53a6a525ba4)
@@ -1089,9 +1089,6 @@ static void __init smp_boot_cpus(unsigne
 		}
 	}
 
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		check_nmi_watchdog();
-
 	smpboot_setup_io_apic();
 
 	setup_boot_APIC_clock();
Index: arch/x86_64/kernel/io_apic.c
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/arch/x86_64/kernel/io_apic.c  (mode:100644 sha1:29a257295484ee01c16d0ebdf1bfdbe2caeeb1d3)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/arch/x86_64/kernel/io_apic.c  (mode:100644 sha1:60be58617eb977e1620beda8e363ba9cfd9fc17c)
@@ -1607,7 +1607,6 @@ static inline void check_timer(void)
 				disable_8259A_irq(0);
 				setup_nmi();
 				enable_8259A_irq(0);
-				check_nmi_watchdog();
 			}
 			return;
 		}
@@ -1627,7 +1626,6 @@ static inline void check_timer(void)
 			nmi_watchdog_default();
 			if (nmi_watchdog == NMI_IO_APIC) {
 				setup_nmi();
-				check_nmi_watchdog();
 			}
 			return;
 		}
Index: arch/x86_64/kernel/nmi.c
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/arch/x86_64/kernel/nmi.c  (mode:100644 sha1:e00d4adec36bd22619a348af72242bf06d4204c7)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/arch/x86_64/kernel/nmi.c  (mode:100644 sha1:61de0b34a01e850fedb824115b2e0560ed98ff59)
@@ -112,17 +112,20 @@ static __init int cpu_has_lapic(void)
 	} 	
 }
 
-int __init check_nmi_watchdog (void)
+static int __init check_nmi_watchdog (void)
 {
 	int counts[NR_CPUS];
 	int cpu;
 
+	if (nmi_watchdog == NMI_NONE)
+		return 0;
+
 	if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic())  {
 		nmi_watchdog = NMI_NONE;
 		return -1; 
 	}	
 
-	printk(KERN_INFO "testing NMI watchdog ... ");
+	printk(KERN_INFO "Testing NMI watchdog ... ");
 
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		counts[cpu] = cpu_pda[cpu].__nmi_count; 
@@ -148,6 +151,8 @@ int __init check_nmi_watchdog (void)
 
 	return 0;
 }
+/* Have this called later during boot so counters are updating */
+late_initcall(check_nmi_watchdog);
 
 int __init setup_nmi_watchdog(char *str)
 {
Index: include/asm-i386/apic.h
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/include/asm-i386/apic.h  (mode:100644 sha1:e1de67483f383e2e8bdb851b810d81c22ef11cab)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/include/asm-i386/apic.h  (mode:100644 sha1:a5810cf7b5783b9c156a33af77b1d1f0e960246e)
@@ -109,7 +109,6 @@ extern int APIC_init_uniprocessor (void)
 extern void disable_APIC_timer(void);
 extern void enable_APIC_timer(void);
 
-extern int check_nmi_watchdog (void);
 extern void enable_NMI_through_LVT0 (void * dummy);
 
 extern unsigned int nmi_watchdog;
Index: include/asm-x86_64/apic.h
===================================================================
--- 0addf0006900152975c38bd75fdfd238c9179013/include/asm-x86_64/apic.h  (mode:100644 sha1:c025cc3ef7890c5377c684f6aaf73e485a8b8cdd)
+++ 6adb8d33585f8eee20794827c79e40991aeeaee5/include/asm-x86_64/apic.h  (mode:100644 sha1:e4b1017b8b2b1cbb7208abcd123b38e49d0d3e46)
@@ -99,7 +99,6 @@ extern void disable_APIC_timer(void);
 extern void enable_APIC_timer(void);
 extern void clustered_apic_check(void);
 
-extern int check_nmi_watchdog(void);
 extern void nmi_watchdog_default(void);
 extern int setup_nmi_watchdog(char *);
 


linux-2.6.12-ns558-nodev-rmmod.patch:
 ns558.c |    3 +++
 1 files changed, 3 insertions(+)

--- NEW FILE linux-2.6.12-ns558-nodev-rmmod.patch ---

rmmod (with no device present) ..

Unable to handle kernel paging request at virtual address 6b6b6b6b
 printing eip:
cc821462
*pde = 00000000
Oops: 0000 [#1]
Modules linked in: ns558 gameport md5 ipv6 autofs4 l2cap bluetooth sunrpc via_rhine mii ext3 jbd dm_mod
CPU:    0
EIP:    0060:[<cc821462>]    Not tainted VLI
EFLAGS: 00010286   (2.6.11-1.1341_FC4)
EIP is at ns558_exit+0x32/0x5a [ns558]
eax: 00000014   ebx: 6b6b6b57   ecx: 00000000   edx: 6b6b6b6b
esi: 00000003   edi: bfa819e4   ebp: ca749000   esp: ca749f6c
ds: 007b   es: 007b   ss: 0068
Process rmmod (pid: 9963, threadinfo=ca749000 task=cad03aa0)
Stack: cc822300 c014626f 3535736e 42920038 10861720 00000880 bfa819a0 cad03aa0
       ca749fbc c0108436 bfa819a0 00000880 bfa841e4 00000003 00000000 bfa819a0
       00000003 00000000 bfa819a0 c0103a51 bfa819a0 00000880 bfa841e4 00000003
Call Trace:
 [<c014626f>] sys_delete_module+0x117/0x154
 [<c0108436>] do_syscall_trace+0xef/0x123
 [<c0103a51>] syscall_call+0x7/0xb
Code: eb 26 8b 43 10 e8 ef 52 00 00 8b 4b 08 89 ca f7 da 23 53 04 b8 40 bc 3c c0 e8 6c 78 90 f3 89 d8 e8 0e be 93 f3 8b 53 14 8d 5a ec <8b> 43 14 0f 18 00 90 81 fa e0 20 82 cc 75 c8 a1 00 25 82 cc 85


--- linux-2.6.11/drivers/input/gameport/ns558.c~	2005-05-23 21:38:35.000000000 -0400
+++ linux-2.6.11/drivers/input/gameport/ns558.c	2005-05-23 21:38:50.000000000 -0400
@@ -277,6 +277,9 @@ static void __exit ns558_exit(void)
 {
 	struct ns558 *ns558;
 
+	if (list_empty(&ns558_list))
+		return;
+
 	list_for_each_entry(ns558, &ns558_list, node) {
 		gameport_unregister_port(ns558->gameport);
 		release_region(ns558->io & ~(ns558->size - 1), ns558->size);

linux-2.6.12-pwc-warning.patch:
 pwc-uncompress.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

--- NEW FILE linux-2.6.12-pwc-warning.patch ---

The patch titled

     pwc-uncompress warning fix

has been added to the -mm tree.  Its filename is

     pwc-uncompress-warning-fix.patch

Patches currently in -mm which might be from akpm at osdl.org are

git-alsa-fix.patch
git-ia64-pre.patch
git-ia64-post.patch
bk-nfs.patch
git-scsi-misc-mptfusion-fix.patch
git-scsi-misc-qla-build-fix.patch
hub-use-kthread.patch
bk-watchdog.patch
is_multicast_ether_addr-hack.patch
wireless-device-attr-fixes.patch
wireless-device-attr-fixes-2.patch
ipw2100-old-gcc-fix.patch
add-x86-64-specific-support-for-sparsemem-tidy.patch
add-page_state-info-to-show_mem-warning-fixes.patch
vm-early-zone-reclaim-tidy.patch
hugepage-consolidation-ia64-fix.patch
node-local-per-cpu-pages-tidy.patch
node-local-per-cpu-pages-tidy-2.patch
node-local-per-cpu-pages-tidy-2-fix.patch
avoiding-mmap-fragmentation-tidy.patch
avoiding-mmap-fragmentation-revert-unneeded-64-bit-changes-vs-x86_64-task_size-fixes-for-compatibility-mode-processes.patch
mm-remove-pg_highmem-tidy.patch
cs89x0c-support-for-philips-pnx0105-network-adapter-tidy.patch
dmfe-warning-fix.patch
mips-add-vr41xx-gpio-support-fix.patch
x86-x86_64-pcibus_to_node-fix.patch
numa-aware-block-device-control-structure-allocation-tidy.patch
i386-selectable-frequency-of-the-timer-interrupt-fix.patch
optimise-storage-of-read-mostly-variables-x86_64-fix-fix-fix.patch
x86_64-div-by-zero-fix.patch
mempool-bounce-buffer-restriction.patch
arm-irqs_disabled-type-fix.patch
i386-cpu-hotplug-updated-for-mm-smp_processor_id-cleanup-fix.patch
sibling-map-initializing-rework-smp_processor_id-cleanup-fix.patch
cpu-state-clean-after-hot-remove-smp_processor_id-cleanup-fix.patch
x86_64-change-init-sections-for-cpu-hotplug-support-fix.patch
detect-soft-lockups-smp_processor_id-cleanup-fix.patch
blk-reduce-locking.patch
blk-reduce-locking-fixes.patch
timers-fixes-improvements-smp_processor_id-cleanup-fix.patch
page_uptodate_lock-hashing.patch
kprobes-function-return-probes-fix-4.patch
kprobes-temporary-disarming-of-reentrant-probe-for-x86_64-fix.patch
fix-of-dcache-race-leading-to-busy-inodes-on-umount-fix.patch
fix-of-dcache-race-leading-to-busy-inodes-on-umount-tidy.patch
i2o-fix-waitqueue-brain-damage.patch
pwc-uncompress-warning-fix.patch
fix-tpm-driver-sysfs-owernship-changes-fix-3.patch
dlm-lockspaces-callbacks-directory-build-fix.patch
dlm-lockspaces-callbacks-directory-fix-2.patch
dlm-device-interface-fix.patch
connector-warning-fixes.patch
connector-netlink-id-fix.patch
connector-add-a-fork-connector-build-fix.patch
i2o-new-sysfs-attributes-and-adaptec-specific-block-fix-fix.patch
i2o-build-fix.patch
isofs-show-hidden-files-add-granularity-for-assoc-hidden-files-flags-tidy.patch
isofs-show-hidden-files-add-granularity-for-assoc-hidden-files-flags-fix.patch
nr_blockdev_pages-in_interrupt-warning.patch
numa-aware-slab-allocator-v3-__bad_size-fix.patch
dynamic-sched-domains-sched-changes-fix.patch
bttv-support-for-adlink-rtv24-capture-card-tidy.patch
bttv-support-for-adlink-rtv24-capture-card-more-tidy.patch
v4l-update-for-saa7134-cards-fix.patch
v4l-update-for-saa7134-cards-fix-2.patch
gregkh-i2c-i2c-address_range_removal-v4l-fix-fix.patch
nfs-patch-for-fscache-fixes.patch
kexec-x86_64-optimise-storage-of-read-mostly-variables-x86_64-fix.patch
kdump-accessing-dump-file-in-linear-raw-format.patch
kdump-use-real-pt_regs-from-exception-fix.patch
reiser4-mm-remove-pg_highmem-fix.patch
v9fs-debug-and-support-routines-fix.patch
s1d13xxxfb-linkage-fix.patch
intelfbdrv-naming-fix.patch
intelfb-add-voffset-option-to-avoid-conficts-with-xorg-i810-driver-fix.patch
intelfb-documentation-fix.patch
framebuffer-driver-for-arc-lcd-board-tidy.patch
xip-fs-mm-execute-in-place-3rd-version-fix.patch
xip-ext2-execute-in-place-3rd-version-fixes.patch



From: Andrew Morton <akpm at osdl.org>

drivers/usb/media/pwc/pwc-uncompress.c: In function `pwc_decompress':
drivers/usb/media/pwc/pwc-uncompress.c:140: warning: unreachable code at beginning of switch statement

Signed-off-by: Andrew Morton <akpm at osdl.org>
---

 drivers/usb/media/pwc/pwc-uncompress.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

diff -puN drivers/usb/media/pwc/pwc-uncompress.c~pwc-uncompress-warning-fix drivers/usb/media/pwc/pwc-uncompress.c
--- 25/drivers/usb/media/pwc/pwc-uncompress.c~pwc-uncompress-warning-fix	2005-06-14 21:20:23.000000000 -0700
+++ 25-akpm/drivers/usb/media/pwc/pwc-uncompress.c	2005-06-14 21:20:23.000000000 -0700
@@ -118,9 +118,9 @@ int pwc_decompress(struct pwc_device *pd
 		   return -ENXIO; /* No such device or address: missing decompressor */
 		 }
 
+#if 0
 		switch (pdev->type)
 		 {
-#if 0		 
 		  case 675:
 		  case 680:
 		  case 690:
@@ -128,18 +128,17 @@ int pwc_decompress(struct pwc_device *pd
 		  case 730:
 		  case 740:
 		  case 750:
-		    pwc_dec23_decompress(&pdev->image, &pdev->view, &pdev->offset,
-				yuv, image,
-				flags,
+		    pwc_dec23_decompress(&pdev->image, &pdev->view,
+				&pdev->offset, yuv, image, flags,
 				pdev->decompress_data, pdev->vbandlength);
 		    break;
 		  case 645:
 		  case 646:
 		    /* TODO & FIXME */
-#endif		    
-		    return -ENXIO; /* No such device or address: missing decompressor */
+		    return -ENXIO; /* Missing decompressor */
 		    break;
 		 }
+#endif
 	}
 	return 0;
 }


linux-2.6.12-rc3-ehci-misc-updates.patch:
 ehci-hcd.c |   65 +++++++++++++++++++++++++++++++++++++++++--------------------
 ehci-hub.c |    2 +
 ehci.h     |   19 +++++++++--------
 3 files changed, 56 insertions(+), 30 deletions(-)

--- NEW FILE linux-2.6.12-rc3-ehci-misc-updates.patch ---
Miscellaneous updates for EHCI.

 - Mostly updates the power switching on EHCI controllers.  One routine
   centralizes the "power on/off all ports" logic, and the capability to
   do that is reported more correctly.

 - Courtesy Colin Leroy, a patch to always power up ports after resumes
   which didn't keep a USB device suspended.  The reset-everything logic
   powers down those ports (on some hardware) so something needs to turn
   them back on.

 - Minor tweaks/bugfixes for the debug port support.

Signed-off-by: David Brownell <dbrownell at users.sourceforge.net>

--- a/drivers/usb/host/ehci-hcd.c	2005-04-05 15:04:13 -07:00
+++ b/drivers/usb/host/ehci-hcd.c	2005-04-05 15:04:13 -07:00
@@ -346,6 +347,22 @@
 	return 0;
 }
 
+static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
+{
+	unsigned port;
+
+	if (!HCS_PPC (ehci->hcs_params))
+		return;
+
+	ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down");
+	for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
+		(void) ehci_hub_control(ehci_to_hcd(ehci),
+				is_on ? SetPortFeature : ClearPortFeature,
+				USB_PORT_FEAT_POWER,
+				port--, NULL, 0);
+	msleep(20);
+}
+
 
 /* called by khubd or root hub init threads */
 
@@ -362,8 +379,10 @@
 	dbg_hcs_params (ehci, "reset");
 	dbg_hcc_params (ehci, "reset");
 
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = readl (&ehci->caps->hcs_params);
+
 #ifdef	CONFIG_PCI
-	/* EHCI 0.96 and later may have "extended capabilities" */
 	if (hcd->self.controller->bus == &pci_bus_type) {
 		struct pci_dev	*pdev = to_pci_dev(hcd->self.controller);
 
@@ -383,9 +402,30 @@
 			break;
 		}
 
+		/* optional debug port, normally in the first BAR */
+		temp = pci_find_capability (pdev, 0x0a);
+		if (temp) {
+			pci_read_config_dword(pdev, temp, &temp);
+			temp >>= 16;
+			if ((temp & (3 << 13)) == (1 << 13)) {
+				temp &= 0x1fff;
+				ehci->debug = hcd->regs + temp;
+				temp = readl (&ehci->debug->control);
+				ehci_info (ehci, "debug port %d%s\n",
+					HCS_DEBUG_PORT(ehci->hcs_params),
+					(temp & DBGP_ENABLED)
+						? " IN USE"
+						: "");
+				if (!(temp & DBGP_ENABLED))
+					ehci->debug = NULL;
+			}
+		}
+
 		temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
 	} else
 		temp = 0;
+
+	/* EHCI 0.96 and later may have "extended capabilities" */
 	while (temp && count--) {
 		u32		cap;
 
@@ -414,8 +454,7 @@
 		ehci_reset (ehci);
 #endif
 
-	/* cache this readonly data; minimize PCI reads */
-	ehci->hcs_params = readl (&ehci->caps->hcs_params);
+	ehci_port_power (ehci, 0);
 
 	/* at least the Genesys GL880S needs fixup here */
 	temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
@@ -657,16 +696,11 @@
 static void ehci_stop (struct usb_hcd *hcd)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
-	u8			rh_ports, port;
 
 	ehci_dbg (ehci, "stop\n");
 
 	/* Turn off port power on all root hub ports. */
-	rh_ports = HCS_N_PORTS (ehci->hcs_params);
-	for (port = 1; port <= rh_ports; port++)
-		(void) ehci_hub_control(hcd,
-			ClearPortFeature, USB_PORT_FEAT_POWER,
-			port, NULL, 0);
+	ehci_port_power (ehci, 0);
 
 	/* no more interrupts ... */
 	del_timer_sync (&ehci->watchdog);
@@ -748,7 +782,6 @@
 	unsigned		port;
 	struct usb_device	*root = hcd->self.root_hub;
 	int			retval = -EINVAL;
-	int			powerup = 0;
 
 	// maybe restore (PCI) FLADJ
 
@@ -766,8 +799,6 @@
 			up (&hcd->self.root_hub->serialize);
 			break;
 		}
-		if ((status & PORT_POWER) == 0)
-			powerup = 1;
 		if (!root->children [port])
 			continue;
 		dbg_port (ehci, __FUNCTION__, port + 1, status);
@@ -794,16 +825,9 @@
 		retval = ehci_start (hcd);
 
 		/* here we "know" root ports should always stay powered;
-		 * but some controllers may lost all power.
+		 * but some controllers may lose all power.
 		 */
-		if (powerup) {
-			ehci_dbg (ehci, "...powerup ports...\n");
-			for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
-				(void) ehci_hub_control(hcd,
-					SetPortFeature, USB_PORT_FEAT_POWER,
-						port--, NULL, 0);
-			msleep(20);
-		}
+		ehci_port_power (ehci, 1);
 	}
 
 	return retval;
--- a/drivers/usb/host/ehci-hub.c	2005-04-05 15:04:13 -07:00
+++ b/drivers/usb/host/ehci-hub.c	2005-04-05 15:04:13 -07:00
@@ -281,6 +281,8 @@
 	temp = 0x0008;			/* per-port overcurrent reporting */
 	if (HCS_PPC (ehci->hcs_params))
 		temp |= 0x0001;		/* per-port power control */
+	else
+		temp |= 0x0002;		/* no power switching */
 #if 0
 // re-enable when we support USB_PORT_FEAT_INDICATOR below.
 	if (HCS_INDICATOR (ehci->hcs_params))
--- a/drivers/usb/host/ehci.h	2005-04-05 15:04:13 -07:00
+++ b/drivers/usb/host/ehci.h	2005-04-05 15:04:13 -07:00
@@ -47,6 +47,12 @@
 #define	EHCI_MAX_ROOT_PORTS	15		/* see HCS_N_PORTS */
 
 struct ehci_hcd {			/* one per controller */
+	/* glue to PCI and HCD framework */
+	struct ehci_caps __iomem *caps;
+	struct ehci_regs __iomem *regs;
+	struct ehci_dbg_port __iomem *debug;
+
+	__u32			hcs_params;	/* cached register copy */
 	spinlock_t		lock;
 
 	/* async schedule support */
@@ -84,11 +90,6 @@
 
 	unsigned		is_tdi_rh_tt:1;	/* TDI roothub with TT */
 
-	/* glue to PCI and HCD framework */
-	struct ehci_caps __iomem *caps;
-	struct ehci_regs __iomem *regs;
-	__u32			hcs_params;	/* cached register copy */
-
 	/* irq statistics */
 #ifdef EHCI_STATS
 	struct ehci_stats	stats;
@@ -165,7 +166,7 @@
 	/* these fields are specified as 8 and 16 bit registers,
 	 * but some hosts can't perform 8 or 16 bit PCI accesses.
 	 */
-	u32	hc_capbase;
+	u32		hc_capbase;
 #define HC_LENGTH(p)		(((p)>>00)&0x00ff)	/* bits 7:0 */
 #define HC_VERSION(p)		(((p)>>16)&0xffff)	/* bits 31:16 */
 	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
@@ -273,7 +274,7 @@
 #define DBGP_ENABLED	(1<<28)
 #define DBGP_DONE	(1<<16)
 #define DBGP_INUSE	(1<<10)
-#define DBGP_ERRCODE(x)	(((x)>>7)&0x0f)
+#define DBGP_ERRCODE(x)	(((x)>>7)&0x07)
 #	define DBGP_ERR_BAD	1
 #	define DBGP_ERR_SIGNAL	2
 #define DBGP_ERROR	(1<<6)
@@ -282,11 +283,11 @@
 #define DBGP_LEN(x)	(((x)>>0)&0x0f)
 	u32	pids;
 #define DBGP_PID_GET(x)		(((x)>>16)&0xff)
-#define DBGP_PID_SET(data,tok)	(((data)<<8)|(tok));
+#define DBGP_PID_SET(data,tok)	(((data)<<8)|(tok))
 	u32	data03;
 	u32	data47;
 	u32	address;
-#define DBGP_EPADDR(dev,ep)	(((dev)<<8)|(ep));
+#define DBGP_EPADDR(dev,ep)	(((dev)<<8)|(ep))
 } __attribute__ ((packed));
 
 /*-------------------------------------------------------------------------*/



linux-2.6.12-rc4-audit-git.patch:
 arch/ppc/Kconfig               |   17 +
 arch/ppc/kernel/entry.S        |   16 -
 arch/ppc/kernel/ppc_ksyms.c    |    2 
 arch/ppc/kernel/ptrace.c       |   40 ++
 include/asm-ppc/seccomp.h      |   10 
 include/asm-ppc/thread_info.h  |    7 
 include/linux/audit.h          |   93 ++++--
 init/Kconfig                   |    3 
 kernel/audit.c                 |  589 ++++++++++++++++++++---------------------
 kernel/auditsc.c               |  236 +++++++++++-----
 kernel/signal.c                |    7 
 net/socket.c                   |    9 
 security/selinux/avc.c         |   28 +
 security/selinux/hooks.c       |    2 
 security/selinux/nlmsgtab.c    |   10 
 security/selinux/ss/services.c |    4 
 16 files changed, 650 insertions(+), 423 deletions(-)

--- NEW FILE linux-2.6.12-rc4-audit-git.patch ---
Index: arch/ppc/Kconfig
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/arch/ppc/Kconfig  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/arch/ppc/Kconfig  (mode:100644)
@@ -1083,6 +1083,23 @@
 
 source kernel/power/Kconfig
 
+config SECCOMP
+	bool "Enable seccomp to safely compute untrusted bytecode"
+	depends on PROC_FS
+	default y
+	help
+	  This kernel feature is useful for number crunching applications
+	  that may need to compute untrusted bytecode during their
+	  execution. By using pipes or other transports made available to
+	  the process as file descriptors supporting the read/write
+	  syscalls, it's possible to isolate those applications in
+	  their own address space using seccomp. Once seccomp is
+	  enabled via /proc/<pid>/seccomp, it cannot be disabled
+	  and the task is only allowed to execute a few safe syscalls
+	  defined by each seccomp mode.
+
+	  If unsure, say Y. Only embedded should say N here.
+
 endmenu
 
 config ISA_DMA_API
Index: arch/ppc/kernel/entry.S
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/arch/ppc/kernel/entry.S  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/arch/ppc/kernel/entry.S  (mode:100644)
@@ -202,7 +202,7 @@
 	rlwinm	r11,r11,0,~_TIFL_FORCE_NOERROR
 	stw	r11,TI_LOCAL_FLAGS(r10)
 	lwz	r11,TI_FLAGS(r10)
-	andi.	r11,r11,_TIF_SYSCALL_TRACE
+	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
 syscall_dotrace_cont:
 	cmplwi	0,r0,NR_syscalls
@@ -237,7 +237,7 @@
 	SYNC
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
 	bne-	syscall_exit_work
 syscall_exit_cont:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
@@ -277,7 +277,8 @@
 	SAVE_NVGPRS(r1)
 	li	r0,0xc00
 	stw	r0,TRAP(r1)
-	bl	do_syscall_trace
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	do_syscall_trace_enter
 	lwz	r0,GPR0(r1)	/* Restore original registers */
 	lwz	r3,GPR3(r1)
 	lwz	r4,GPR4(r1)
@@ -291,7 +292,7 @@
 syscall_exit_work:
 	stw	r6,RESULT(r1)	/* Save result */
 	stw	r3,GPR3(r1)	/* Update return value */
-	andi.	r0,r9,_TIF_SYSCALL_TRACE
+	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
 	beq	5f
 	ori	r10,r10,MSR_EE
 	SYNC
@@ -303,7 +304,8 @@
 	li	r4,0xc00
 	stw	r4,TRAP(r1)
 4:
-	bl	do_syscall_trace
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	do_syscall_trace_leave
 	REST_NVGPRS(r1)
 2:
 	lwz	r3,GPR3(r1)
@@ -627,8 +629,8 @@
 	subi	r1,r3,STACK_FRAME_OVERHEAD
 	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
 	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,_TIF_SYSCALL_TRACE
-	bnel-	do_syscall_trace
+	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
+	bnel-	do_syscall_trace_leave
 	/* fall through */
 
 	.globl	ret_from_except_full
Index: arch/ppc/kernel/ppc_ksyms.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/arch/ppc/kernel/ppc_ksyms.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/arch/ppc/kernel/ppc_ksyms.c  (mode:100644)
@@ -55,7 +55,6 @@
 #define EXPORT_SYMTAB_STROPS
 
 extern void transfer_to_handler(void);
-extern void do_syscall_trace(void);
 extern void do_IRQ(struct pt_regs *regs);
 extern void MachineCheckException(struct pt_regs *regs);
 extern void AlignmentException(struct pt_regs *regs);
@@ -74,7 +73,6 @@
 EXPORT_SYMBOL(clear_pages);
 EXPORT_SYMBOL(clear_user_page);
 EXPORT_SYMBOL(do_signal);
-EXPORT_SYMBOL(do_syscall_trace);
 EXPORT_SYMBOL(transfer_to_handler);
 EXPORT_SYMBOL(do_IRQ);
 EXPORT_SYMBOL(MachineCheckException);
Index: arch/ppc/kernel/ptrace.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/arch/ppc/kernel/ptrace.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/arch/ppc/kernel/ptrace.c  (mode:100644)
@@ -27,6 +27,9 @@
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/signal.h>
+#include <linux/seccomp.h>
+#include <linux/audit.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -455,11 +458,10 @@
 	return ret;
 }
 
-void do_syscall_trace(void)
+static void do_syscall_trace(void)
 {
-        if (!test_thread_flag(TIF_SYSCALL_TRACE)
-	    || !(current->ptrace & PT_PTRACED))
-		return;
+	/* the 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 				 ? 0x80 : 0));
 
@@ -473,3 +475,33 @@
 		current->exit_code = 0;
 	}
 }
+
+void do_syscall_trace_enter(struct pt_regs *regs)
+{
+	if (test_thread_flag(TIF_SYSCALL_TRACE)
+	    && (current->ptrace & PT_PTRACED))
+		do_syscall_trace();
+
+	if (unlikely(current->audit_context))
+		audit_syscall_entry(current, AUDIT_ARCH_PPC,
+				    regs->gpr[0],
+				    regs->gpr[3], regs->gpr[4],
+				    regs->gpr[5], regs->gpr[6]);
+}
+
+void do_syscall_trace_leave(struct pt_regs *regs)
+{
+	secure_computing(regs->gpr[0]);
+
+	if (unlikely(current->audit_context))
+		audit_syscall_exit(current,
+				   (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+				   regs->result);
+
+	if ((test_thread_flag(TIF_SYSCALL_TRACE))
+	    && (current->ptrace & PT_PTRACED))
+		do_syscall_trace();
+}
+
+EXPORT_SYMBOL(do_syscall_trace_enter);
+EXPORT_SYMBOL(do_syscall_trace_leave);
Index: include/asm-ppc/seccomp.h
===================================================================
--- /dev/null  (tree:46ae0ec07caf01fa5c743112ae8ee932d1e66854)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/include/asm-ppc/seccomp.h  (mode:100644)
@@ -0,0 +1,10 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
Index: include/asm-ppc/thread_info.h
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/include/asm-ppc/thread_info.h  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/include/asm-ppc/thread_info.h  (mode:100644)
@@ -77,12 +77,19 @@
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
 #define TIF_MEMDIE		5
+#define TIF_SYSCALL_AUDIT       6       /* syscall auditing active */
+#define TIF_SECCOMP             7      /* secure computing */
+
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_SYSCALL_AUDIT      (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP            (1<<TIF_SECCOMP)
+
+#define _TIF_SYSCALL_T_OR_A     (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 /*
  * Non racy (local) flags bit numbers
Index: include/linux/audit.h
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/include/linux/audit.h  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/include/linux/audit.h  (mode:100644)
@@ -27,15 +27,51 @@
 #include <linux/sched.h>
 #include <linux/elf.h>
 
-/* Request and reply types */
-#define AUDIT_GET      1000	/* Get status */
-#define AUDIT_SET      1001	/* Set status (enable/disable/auditd) */
-#define AUDIT_LIST     1002	/* List filtering rules */
-#define AUDIT_ADD      1003	/* Add filtering rule */
-#define AUDIT_DEL      1004	/* Delete filtering rule */
-#define AUDIT_USER     1005	/* Send a message from user-space */
-#define AUDIT_LOGIN    1006     /* Define the login id and informaiton */
-#define AUDIT_KERNEL   2000	/* Asynchronous audit record. NOT A REQUEST. */
+/* The netlink messages for the audit system is divided into blocks:
+ * 1000 - 1099 are for commanding the audit system
+ * 1100 - 1199 user space trusted application messages
+ * 1200 - 1299 messages internal to the audit daemon
+ * 1300 - 1399 audit event messages
+ * 1400 - 1499 SE Linux use
+ * 1500 - 1999 future use
+ * 2000 is for otherwise unclassified kernel audit messages
+ *
+ * Messages from 1000-1199 are bi-directional. 1200-1299 are exclusively user
+ * space. Anything over that is kernel --> user space communication.
+ */
+#define AUDIT_GET		1000	/* Get status */
+#define AUDIT_SET		1001	/* Set status (enable/disable/auditd) */
+#define AUDIT_LIST		1002	/* List syscall filtering rules */
+#define AUDIT_ADD		1003	/* Add syscall filtering rule */
+#define AUDIT_DEL		1004	/* Delete syscall filtering rule */
+#define AUDIT_USER		1005	/* Message from userspace -- deprecated */
+#define AUDIT_LOGIN		1006	/* Define the login id and information */
+#define AUDIT_WATCH_INS		1007	/* Insert file/dir watch entry */
+#define AUDIT_WATCH_REM		1008	/* Remove file/dir watch entry */
+#define AUDIT_WATCH_LIST	1009	/* List all file/dir watches */
+#define AUDIT_SIGNAL_INFO	1010	/* Get info about sender of signal to auditd */
+
+#define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages uninteresting to kernel */
+#define AUDIT_LAST_USER_MSG	1199
+ 
+#define AUDIT_DAEMON_START      1200    /* Daemon startup record */
+#define AUDIT_DAEMON_END        1201    /* Daemon normal stop record */
+#define AUDIT_DAEMON_ABORT      1202    /* Daemon error stop record */
+#define AUDIT_DAEMON_CONFIG     1203    /* Daemon config change */
+
+#define AUDIT_SYSCALL		1300	/* Syscall event */
+#define AUDIT_FS_WATCH		1301	/* Filesystem watch event */
+#define AUDIT_PATH		1302	/* Filname path information */
+#define AUDIT_IPC		1303	/* IPC record */
+#define AUDIT_SOCKETCALL	1304	/* sys_socketcall arguments */
+#define AUDIT_CONFIG_CHANGE	1305	/* Audit system configuration change */
+#define AUDIT_SOCKADDR		1306	/* sockaddr copied as syscall arg */
+
+#define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
+#define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
+#define AUDIT_AVC_PATH		1402	/* dentry, vfsmount pair from avc */
+
+#define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */
 
 /* Rule flags */
 #define AUDIT_PER_TASK 0x01	/* Apply rule at task creation (not syscall) */
@@ -132,16 +168,9 @@
 #define AUDIT_ARCH_V850		(EM_V850|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_X86_64	(EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
 
-#ifndef __KERNEL__
-struct audit_message {
-	struct nlmsghdr nlh;
-	char		data[1200];
-};
-#endif
-
 struct audit_status {
 	__u32		mask;		/* Bit mask for valid entries */
-	__u32		enabled;	/* 1 = enabled, 0 = disbaled */
+	__u32		enabled;	/* 1 = enabled, 0 = disabled */
 	__u32		failure;	/* Failure-to-log action */
 	__u32		pid;		/* pid of auditd process */
 	__u32		rate_limit;	/* messages rate limit (per second) */
@@ -161,6 +190,11 @@
 
 #ifdef __KERNEL__
 
+struct audit_sig_info {
+	uid_t		uid;
+	pid_t		pid;
+};
+
 struct audit_buffer;
 struct audit_context;
 struct inode;
@@ -185,11 +219,16 @@
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
 				 void *data, uid_t loginuid);
-extern void audit_get_stamp(struct audit_context *ctx,
-			    struct timespec *t, unsigned int *serial);
+extern unsigned int audit_serial(void);
+extern void auditsc_get_stamp(struct audit_context *ctx,
+			      struct timespec *t, unsigned int *serial);
 extern int  audit_set_loginuid(struct task_struct *task, uid_t loginuid);
 extern uid_t audit_get_loginuid(struct audit_context *ctx);
 extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
+extern int audit_socketcall(int nargs, unsigned long *args);
+extern int audit_sockaddr(int len, void *addr);
+extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
+extern void audit_signal_info(int sig, struct task_struct *t);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -198,18 +237,24 @@
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
 #define audit_inode(n,i) do { ; } while (0)
+#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
+#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
 #define audit_get_loginuid(c) ({ -1; })
 #define audit_ipc_perms(q,u,g,m) ({ 0; })
+#define audit_socketcall(n,a) ({ 0; })
+#define audit_sockaddr(len, addr) ({ 0; })
+#define audit_avc_path(dentry, mnt) ({ 0; })
+#define audit_signal_info(s,t) do { ; } while (0)
 #endif
 
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
 				/* Public API */
-extern void		    audit_log(struct audit_context *ctx,
+extern void		    audit_log(struct audit_context *ctx, int type,
 				      const char *fmt, ...)
-			    __attribute__((format(printf,2,3)));
+			    __attribute__((format(printf,3,4)));
 
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx,int type);
 extern void		    audit_log_format(struct audit_buffer *ab,
 					     const char *fmt, ...)
 			    __attribute__((format(printf,2,3)));
@@ -229,8 +274,8 @@
 					     void *payload, int size);
 extern void		    audit_log_lost(const char *message);
 #else
-#define audit_log(t,f,...) do { ; } while (0)
-#define audit_log_start(t) ({ NULL; })
+#define audit_log(c,t,f,...) do { ; } while (0)
+#define audit_log_start(c,t) ({ NULL; })
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
Index: init/Kconfig
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/init/Kconfig  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/init/Kconfig  (mode:100644)
@@ -164,6 +164,7 @@
 
 config AUDIT
 	bool "Auditing support"
+	depends on NET
 	default y if SECURITY_SELINUX
 	help
 	  Enable auditing infrastructure that can be used with another
@@ -173,7 +174,7 @@
 
 config AUDITSYSCALL
 	bool "Enable system-call auditing support"
-	depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
+	depends on AUDIT && (X86 || PPC || PPC64 || ARCH_S390 || IA64 || UML)
 	default y if SECURITY_SELINUX
 	help
 	  Enable low-overhead system-call auditing infrastructure that
Index: kernel/audit.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/kernel/audit.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/kernel/audit.c  (mode:100644)
@@ -46,6 +46,8 @@
 #include <asm/types.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/err.h>
+#include <linux/kthread.h>
 
 #include <linux/audit.h>
 
@@ -68,7 +70,7 @@
 
 /* If audit records are to be written to the netlink socket, audit_pid
  * contains the (non-zero) pid. */
-static int	audit_pid;
+int		audit_pid;
 
 /* If audit_limit is non-zero, limit the rate of sending audit records
  * to that number per second.  This prevents DoS attacks, but results in
@@ -77,7 +79,10 @@
 
 /* Number of outstanding audit_buffers allowed. */
 static int	audit_backlog_limit = 64;
-static atomic_t	audit_backlog	    = ATOMIC_INIT(0);
+
+/* The identity of the user shutting down the audit system. */
+uid_t		audit_sig_uid = -1;
+pid_t		audit_sig_pid = -1;
 
 /* Records can be lost in several ways:
    0) [suppressed in audit_alloc]
@@ -91,19 +96,17 @@
 /* The netlink socket. */
 static struct sock *audit_sock;
 
-/* There are two lists of audit buffers.  The txlist contains audit
- * buffers that cannot be sent immediately to the netlink device because
- * we are in an irq context (these are sent later in a tasklet).
- *
- * The second list is a list of pre-allocated audit buffers (if more
+/* The audit_freelist is a list of pre-allocated audit buffers (if more
  * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
  * being placed on the freelist). */
-static DEFINE_SPINLOCK(audit_txlist_lock);
 static DEFINE_SPINLOCK(audit_freelist_lock);
 static int	   audit_freelist_count = 0;
-static LIST_HEAD(audit_txlist);
 static LIST_HEAD(audit_freelist);
 
+static struct sk_buff_head audit_skb_queue;
+static struct task_struct *kauditd_task;
+static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
+
 /* There are three lists of rules -- one to search at task creation
  * time, one to search at syscall entry time, and another to search at
  * syscall exit time. */
@@ -112,7 +115,7 @@
 static LIST_HEAD(audit_extlist);
 
 /* The netlink socket is only to be read by 1 CPU, which lets us assume
- * that list additions and deletions never happen simultaneiously in
+ * that list additions and deletions never happen simultaneously in
  * auditsc.c */
 static DECLARE_MUTEX(audit_netlink_sem);
 
@@ -132,21 +135,14 @@
  * use simultaneously. */
 struct audit_buffer {
 	struct list_head     list;
-	struct sk_buff_head  sklist;	/* formatted skbs ready to send */
+	struct sk_buff       *skb;	/* formatted skb ready to send */
 	struct audit_context *ctx;	/* NULL or associated context */
-	int		     len;	/* used area of tmp */
-	char		     tmp[AUDIT_BUFSIZ];
-
-				/* Pointer to header and contents */
-	struct nlmsghdr      *nlh;
-	int		     total;
-	int		     type;
-	int		     pid;
 };
 
-void audit_set_type(struct audit_buffer *ab, int type)
+static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
 {
-	ab->type = type;
+	struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
+	nlh->nlmsg_pid = pid;
 }
 
 struct audit_entry {
@@ -154,9 +150,6 @@
 	struct audit_rule rule;
 };
 
-static void audit_log_end_irq(struct audit_buffer *ab);
-static void audit_log_end_fast(struct audit_buffer *ab);
-
 static void audit_panic(const char *message)
 {
 	switch (audit_failure)
@@ -227,10 +220,8 @@
 
 	if (print) {
 		printk(KERN_WARNING
-		       "audit: audit_lost=%d audit_backlog=%d"
-		       " audit_rate_limit=%d audit_backlog_limit=%d\n",
+		       "audit: audit_lost=%d audit_rate_limit=%d audit_backlog_limit=%d\n",
 		       atomic_read(&audit_lost),
-		       atomic_read(&audit_backlog),
 		       audit_rate_limit,
 		       audit_backlog_limit);
 		audit_panic(message);
@@ -242,7 +233,8 @@
 {
 	int old		 = audit_rate_limit;
 	audit_rate_limit = limit;
-	audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
+	audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+			"audit_rate_limit=%d old=%d by auid=%u",
 			audit_rate_limit, old, loginuid);
 	return old;
 }
@@ -251,7 +243,8 @@
 {
 	int old		 = audit_backlog_limit;
 	audit_backlog_limit = limit;
-	audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_backlog_limit=%d old=%d by auid=%u",
 			audit_backlog_limit, old, loginuid);
 	return old;
 }
@@ -262,8 +255,9 @@
 	if (state != 0 && state != 1)
 		return -EINVAL;
 	audit_enabled = state;
-	audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
-		  audit_enabled, old, loginuid);
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_enabled=%d old=%d by auid=%u",
+			audit_enabled, old, loginuid);
 	return old;
 }
 
@@ -275,12 +269,44 @@
 	    && state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 	audit_failure = state;
-	audit_log(NULL, "audit_failure=%d old=%d by auid %u",
-		  audit_failure, old, loginuid);
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_failure=%d old=%d by auid=%u",
+			audit_failure, old, loginuid);
 	return old;
 }
 
-#ifdef CONFIG_NET
+int kauditd_thread(void *dummy)
+{
+	struct sk_buff *skb;
+
+	while (1) {
+		skb = skb_dequeue(&audit_skb_queue);
+		if (skb) {
+			if (audit_pid) {
+				int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
+				if (err < 0) {
+					BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
+					printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
+					audit_pid = 0;
+				}
+			} else {
+				printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
+				kfree_skb(skb);
+			}
+		} else {
+			DECLARE_WAITQUEUE(wait, current);
+			set_current_state(TASK_INTERRUPTIBLE);
+			add_wait_queue(&kauditd_wait, &wait);
+
+			if (!skb_queue_len(&audit_skb_queue))
+				schedule();
+
+			__set_current_state(TASK_RUNNING);
+			remove_wait_queue(&kauditd_wait, &wait);
+		}
+	}
+}
+
 void audit_send_reply(int pid, int seq, int type, int done, int multi,
 		      void *payload, int size)
 {
@@ -293,13 +319,16 @@
 
 	skb = alloc_skb(len, GFP_KERNEL);
 	if (!skb)
-		goto nlmsg_failure;
+		return;
 
-	nlh		 = NLMSG_PUT(skb, pid, seq, t, len - sizeof(*nlh));
+	nlh		 = NLMSG_PUT(skb, pid, seq, t, size);
 	nlh->nlmsg_flags = flags;
 	data		 = NLMSG_DATA(nlh);
 	memcpy(data, payload, size);
-	netlink_unicast(audit_sock, skb, pid, MSG_DONTWAIT);
+
+	/* Ignore failure. It'll only happen if the sender goes away,
+	   because our timeout is set to infinite. */
+	netlink_unicast(audit_sock, skb, pid, 0);
 	return;
 
 nlmsg_failure:			/* Used by NLMSG_PUT */
@@ -321,10 +350,12 @@
 	case AUDIT_SET:
 	case AUDIT_ADD:
 	case AUDIT_DEL:
+	case AUDIT_SIGNAL_INFO:
 		if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
 			err = -EPERM;
 		break;
 	case AUDIT_USER:
+	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
 		if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
 			err = -EPERM;
 		break;
@@ -344,11 +375,21 @@
 	struct audit_buffer	*ab;
 	u16			msg_type = nlh->nlmsg_type;
 	uid_t			loginuid; /* loginuid of sender */
+	struct audit_sig_info   sig_data;
 
 	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
 	if (err)
 		return err;
 
+	/* As soon as there's any sign of userspace auditd, start kauditd to talk to it */
+	if (!kauditd_task)
+		kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
+	if (IS_ERR(kauditd_task)) {
+		err = PTR_ERR(kauditd_task);
+		kauditd_task = NULL;
+		return err;
+	}
+
 	pid  = NETLINK_CREDS(skb)->pid;
 	uid  = NETLINK_CREDS(skb)->uid;
 	loginuid = NETLINK_CB(skb).loginuid;
@@ -363,7 +404,7 @@
 		status_set.rate_limit	 = audit_rate_limit;
 		status_set.backlog_limit = audit_backlog_limit;
 		status_set.lost		 = atomic_read(&audit_lost);
-		status_set.backlog	 = atomic_read(&audit_backlog);
+		status_set.backlog	 = skb_queue_len(&audit_skb_queue);
 		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0,
 				 &status_set, sizeof(status_set));
 		break;
@@ -382,7 +423,8 @@
 		if (status_get->mask & AUDIT_STATUS_PID) {
 			int old   = audit_pid;
 			audit_pid = status_get->pid;
-			audit_log(NULL, "audit_pid=%d old=%d by auid %u",
+			audit_log(NULL, AUDIT_CONFIG_CHANGE,
+				"audit_pid=%d old=%d by auid=%u",
 				  audit_pid, old, loginuid);
 		}
 		if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
@@ -392,18 +434,15 @@
 							loginuid);
 		break;
 	case AUDIT_USER:
-		ab = audit_log_start(NULL);
+	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
+		ab = audit_log_start(NULL, msg_type);
 		if (!ab)
 			break;	/* audit_panic has been called */
 		audit_log_format(ab,
-				 "user pid=%d uid=%d length=%d loginuid=%u"
+				 "user pid=%d uid=%u auid=%u"
 				 " msg='%.1024s'",
-				 pid, uid,
-				 (int)(nlh->nlmsg_len
-				       - ((char *)data - (char *)nlh)),
-				 loginuid, (char *)data);
-		ab->type = AUDIT_USER;
-		ab->pid  = pid;
+				 pid, uid, loginuid, (char *)data);
+		audit_set_pid(ab, pid);
 		audit_log_end(ab);
 		break;
 	case AUDIT_ADD:
@@ -412,12 +451,14 @@
 			return -EINVAL;
 		/* fallthrough */
 	case AUDIT_LIST:
-#ifdef CONFIG_AUDITSYSCALL
 		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
 					   uid, seq, data, loginuid);
-#else
-		err = -EOPNOTSUPP;
-#endif
+		break;
+	case AUDIT_SIGNAL_INFO:
+		sig_data.uid = audit_sig_uid;
+		sig_data.pid = audit_sig_pid;
+		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 
+				0, 0, &sig_data, sizeof(sig_data));
 		break;
 	default:
 		err = -EINVAL;
@@ -467,87 +508,6 @@
 	up(&audit_netlink_sem);
 }
 
-/* Move data from tmp buffer into an skb.  This is an extra copy, and
- * that is unfortunate.  However, the copy will only occur when a record
- * is being written to user space, which is already a high-overhead
- * operation.  (Elimination of the copy is possible, for example, by
- * writing directly into a pre-allocated skb, at the cost of wasting
- * memory. */
-static void audit_log_move(struct audit_buffer *ab)
-{
-	struct sk_buff	*skb;
-	char		*start;
-	int		extra = ab->nlh ? 0 : NLMSG_SPACE(0);
-
-	/* possible resubmission */
-	if (ab->len == 0)
-		return;
-
-	skb = skb_peek_tail(&ab->sklist);
-	if (!skb || skb_tailroom(skb) <= ab->len + extra) {
-		skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
-		if (!skb) {
-			ab->len = 0; /* Lose information in ab->tmp */
-			audit_log_lost("out of memory in audit_log_move");
-			return;
-		}
-		__skb_queue_tail(&ab->sklist, skb);
-		if (!ab->nlh)
-			ab->nlh = (struct nlmsghdr *)skb_put(skb,
-							     NLMSG_SPACE(0));
-	}
-	start = skb_put(skb, ab->len);
-	memcpy(start, ab->tmp, ab->len);
-	ab->len = 0;
-}
-
-/* Iterate over the skbuff in the audit_buffer, sending their contents
- * to user space. */
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&ab->sklist))) {
-		int retval = 0;
-
-		if (audit_pid) {
-			if (ab->nlh) {
-				ab->nlh->nlmsg_len   = ab->total;
-				ab->nlh->nlmsg_type  = ab->type;
-				ab->nlh->nlmsg_flags = 0;
-				ab->nlh->nlmsg_seq   = 0;
-				ab->nlh->nlmsg_pid   = ab->pid;
-			}
-			skb_get(skb); /* because netlink_* frees */
-			retval = netlink_unicast(audit_sock, skb, audit_pid,
-						 MSG_DONTWAIT);
-		}
-		if (retval == -EAGAIN &&
-		    (atomic_read(&audit_backlog)) < audit_backlog_limit) {
-			skb_queue_head(&ab->sklist, skb);
-			audit_log_end_irq(ab);
-			return 1;
-		}
-		if (retval < 0) {
-			if (retval == -ECONNREFUSED) {
-				printk(KERN_ERR
-				       "audit: *NO* daemon at audit_pid=%d\n",
-				       audit_pid);
-				audit_pid = 0;
-			} else
-				audit_log_lost("netlink socket too busy");
-		}
-		if (!audit_pid) { /* No daemon */
-			int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
-			int len    = skb->len - offset;
-			skb->data[offset + len] = '\0';
-			printk(KERN_ERR "%s\n", skb->data + offset);
-		}
-		kfree_skb(skb);
-		ab->nlh = NULL;
-	}
-	return 0;
-}
 
 /* Initialize audit support at boot time. */
 static int __init audit_init(void)
@@ -558,40 +518,13 @@
 	if (!audit_sock)
 		audit_panic("cannot initialize netlink socket");
 
+	audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+	skb_queue_head_init(&audit_skb_queue);
 	audit_initialized = 1;
 	audit_enabled = audit_default;
-	audit_log(NULL, "initialized");
+	audit_log(NULL, AUDIT_KERNEL, "initialized");
 	return 0;
 }
-
-#else
-/* Without CONFIG_NET, we have no skbuffs.  For now, print what we have
- * in the buffer. */
-static void audit_log_move(struct audit_buffer *ab)
-{
-	printk(KERN_ERR "%*.*s\n", ab->len, ab->len, ab->tmp);
-	ab->len = 0;
-}
-
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
-	return 0;
-}
-
-/* Initialize audit support at boot time. */
-int __init audit_init(void)
-{
-	printk(KERN_INFO "audit: initializing WITHOUT netlink support\n");
-	audit_sock = NULL;
-	audit_pid  = 0;
-
-	audit_initialized = 1;
-	audit_enabled = audit_default;
-	audit_log(NULL, "initialized");
-	return 0;
-}
-#endif
-
 __initcall(audit_init);
 
 /* Process kernel command-line parameter at boot time.  audit=0 or audit=1. */
@@ -608,6 +541,102 @@
 
 __setup("audit=", audit_enable);
 
+static void audit_buffer_free(struct audit_buffer *ab)
+{
+	unsigned long flags;
+
+	if (!ab)
+		return;
+
+	if (ab->skb)
+		kfree_skb(ab->skb);
+
+	spin_lock_irqsave(&audit_freelist_lock, flags);
+	if (++audit_freelist_count > AUDIT_MAXFREE)
+		kfree(ab);
+	else
+		list_add(&ab->list, &audit_freelist);
+	spin_unlock_irqrestore(&audit_freelist_lock, flags);
+}
+
+static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
+						int gfp_mask, int type)
+{
+	unsigned long flags;
+	struct audit_buffer *ab = NULL;
+	struct nlmsghdr *nlh;
+
+	spin_lock_irqsave(&audit_freelist_lock, flags);
+	if (!list_empty(&audit_freelist)) {
+		ab = list_entry(audit_freelist.next,
+				struct audit_buffer, list);
+		list_del(&ab->list);
+		--audit_freelist_count;
+	}
+	spin_unlock_irqrestore(&audit_freelist_lock, flags);
+
+	if (!ab) {
+		ab = kmalloc(sizeof(*ab), gfp_mask);
+		if (!ab)
+			goto err;
+	}
+
+	ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);
+	if (!ab->skb)
+		goto err;
+
+	ab->ctx = ctx;
+	nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
+	nlh->nlmsg_type = type;
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_pid = 0;
+	nlh->nlmsg_seq = 0;
+	return ab;
+err:
+	audit_buffer_free(ab);
+	return NULL;
+}
+
+/* Compute a serial number for the audit record.  Audit records are
+ * written to user-space as soon as they are generated, so a complete
+ * audit record may be written in several pieces.  The timestamp of the
+ * record and this serial number are used by the user-space tools to
+ * determine which pieces belong to the same audit record.  The
+ * (timestamp,serial) tuple is unique for each syscall and is live from
+ * syscall entry to syscall exit.
+ *
+ * Atomic values are only guaranteed to be 24-bit, so we count down.
+ *
+ * NOTE: Another possibility is to store the formatted records off the
+ * audit context (for those records that have a context), and emit them
+ * all at syscall exit.  However, this could delay the reporting of
+ * significant errors until syscall exit (or never, if the system
+ * halts). */
+unsigned int audit_serial(void)
+{
+	static atomic_t serial = ATOMIC_INIT(0xffffff);
+	unsigned int a, b;
+
+	do {
+		a = atomic_read(&serial);
+		if (atomic_dec_and_test(&serial))
+			atomic_set(&serial, 0xffffff);
+		b = atomic_read(&serial);
+	} while (b != a - 1);
+
+	return 0xffffff - b;
+}
+
+static inline void audit_get_stamp(struct audit_context *ctx, 
+				   struct timespec *t, unsigned int *serial)
+{
+	if (ctx)
+		auditsc_get_stamp(ctx, t, serial);
+	else {
+		*t = CURRENT_TIME;
+		*serial = audit_serial();
+	}
+}
 
 /* Obtain an audit buffer.  This routine does locking to obtain the
  * audit buffer, but then no locking is required for calls to
@@ -615,10 +644,9 @@
  * syscall, then the syscall is marked as auditable and an audit record
  * will be written at syscall exit.  If there is no associated task, tsk
  * should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx)
+struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
 {
 	struct audit_buffer	*ab	= NULL;
-	unsigned long		flags;
 	struct timespec		t;
 	unsigned int		serial;
 
@@ -626,57 +654,48 @@
 		return NULL;
 
 	if (audit_backlog_limit
-	    && atomic_read(&audit_backlog) > audit_backlog_limit) {
+	    && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
 		if (audit_rate_check())
 			printk(KERN_WARNING
 			       "audit: audit_backlog=%d > "
 			       "audit_backlog_limit=%d\n",
-			       atomic_read(&audit_backlog),
+			       skb_queue_len(&audit_skb_queue),
 			       audit_backlog_limit);
 		audit_log_lost("backlog limit exceeded");
 		return NULL;
 	}
 
-	spin_lock_irqsave(&audit_freelist_lock, flags);
-	if (!list_empty(&audit_freelist)) {
-		ab = list_entry(audit_freelist.next,
-				struct audit_buffer, list);
-		list_del(&ab->list);
-		--audit_freelist_count;
-	}
-	spin_unlock_irqrestore(&audit_freelist_lock, flags);
-
-	if (!ab)
-		ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
+	ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
 	if (!ab) {
 		audit_log_lost("out of memory in audit_log_start");
 		return NULL;
 	}
 
-	atomic_inc(&audit_backlog);
-	skb_queue_head_init(&ab->sklist);
+	audit_get_stamp(ab->ctx, &t, &serial);
 
-	ab->ctx   = ctx;
-	ab->len   = 0;
-	ab->nlh   = NULL;
-	ab->total = 0;
-	ab->type  = AUDIT_KERNEL;
-	ab->pid   = 0;
-
-#ifdef CONFIG_AUDITSYSCALL
-	if (ab->ctx)
-		audit_get_stamp(ab->ctx, &t, &serial);
-	else
-#endif
-	{
-		t = CURRENT_TIME;
-		serial = 0;
-	}
 	audit_log_format(ab, "audit(%lu.%03lu:%u): ",
 			 t.tv_sec, t.tv_nsec/1000000, serial);
 	return ab;
 }
 
+/**
+ * audit_expand - expand skb in the audit buffer
+ * @ab: audit_buffer
+ *
+ * Returns 0 (no space) on failed expansion, or available space if
+ * successful.
+ */
+static inline int audit_expand(struct audit_buffer *ab, int extra)
+{
+	struct sk_buff *skb = ab->skb;
+	int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
+				   GFP_ATOMIC);
+	if (ret < 0) {
+		audit_log_lost("out of memory in audit_expand");
+		return 0;
+	}
+	return skb_tailroom(skb);
+}
 
 /* Format an audit message into the audit buffer.  If there isn't enough
  * room in the audit buffer, more room will be allocated and vsnprint
@@ -686,26 +705,35 @@
 			      va_list args)
 {
 	int len, avail;
+	struct sk_buff *skb;
+	va_list args2;
 
 	if (!ab)
 		return;
 
-	avail = sizeof(ab->tmp) - ab->len;
-	if (avail <= 0) {
-		audit_log_move(ab);
-		avail = sizeof(ab->tmp) - ab->len;
+	BUG_ON(!ab->skb);
+	skb = ab->skb;
+	avail = skb_tailroom(skb);
+	if (avail == 0) {
+		avail = audit_expand(ab, AUDIT_BUFSIZ);
+		if (!avail)
+			goto out;
 	}
-	len   = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
+	va_copy(args2, args);
+	len = vsnprintf(skb->tail, avail, fmt, args);
 	if (len >= avail) {
 		/* The printk buffer is 1024 bytes long, so if we get
 		 * here and AUDIT_BUFSIZ is at least 1024, then we can
 		 * log everything that printk could have logged. */
-		audit_log_move(ab);
-		avail = sizeof(ab->tmp) - ab->len;
-		len   = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
-	}
-	ab->len   += (len < avail) ? len : avail;
-	ab->total += (len < avail) ? len : avail;
+		avail = audit_expand(ab, max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail));
+		if (!avail)
+			goto out;
+		len = vsnprintf(skb->tail, avail, fmt, args2);
+	}
+	if (len > 0)
+		skb_put(skb, len);
+out:
+	return;
 }
 
 /* Format a message into the audit buffer.  All the work is done in
@@ -721,20 +749,47 @@
 	va_end(args);
 }
 
-void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
+/* This function will take the passed buf and convert it into a string of
+ * ascii hex digits. The new string is placed onto the skb. */
+void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, 
+		size_t len)
 {
-	int i;
+	int i, avail, new_len;
+	unsigned char *ptr;
+	struct sk_buff *skb;
+	static const unsigned char *hex = "0123456789ABCDEF";
+
+	BUG_ON(!ab->skb);
+	skb = ab->skb;
+	avail = skb_tailroom(skb);
+	new_len = len<<1;
+	if (new_len >= avail) {
+		/* Round the buffer request up to the next multiple */
+		new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
+		avail = audit_expand(ab, new_len);
+		if (!avail)
+			return;
+	}
 
-	for (i=0; i<len; i++)
-		audit_log_format(ab, "%02x", buf[i]);
+	ptr = skb->tail;
+	for (i=0; i<len; i++) {
+		*ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */
+		*ptr++ = hex[buf[i] & 0x0F];	  /* Lower nibble */
+	}
+	*ptr = 0;
+	skb_put(skb, len << 1); /* new string is twice the old string */
 }
 
+/* This code will escape a string that is passed to it if the string
+ * contains a control character, unprintable character, double quote mark, 
+ * or a space. Unescaped strings will start and end with a double quote mark.
+ * Strings that are escaped are printed in hex (2 digits per char). */
 void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
 {
 	const unsigned char *p = string;
 
 	while (*p) {
-		if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
+		if (*p == '"' || *p < 0x21 || *p > 0x7f) {
 			audit_log_hex(ab, string, strlen(string));
 			return;
 		}
@@ -743,117 +798,63 @@
 	audit_log_format(ab, "\"%s\"", string);
 }
 
-
-/* This is a helper-function to print the d_path without using a static
- * buffer or allocating another buffer in addition to the one in
- * audit_buffer. */
+/* This is a helper-function to print the escaped d_path */
 void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
 		      struct dentry *dentry, struct vfsmount *vfsmnt)
 {
-	char *p;
-	int  len, avail;
-
-	if (prefix) audit_log_format(ab, " %s", prefix);
-
-	if (ab->len > 128)
-		audit_log_move(ab);
-	avail = sizeof(ab->tmp) - ab->len;
-	p = d_path(dentry, vfsmnt, ab->tmp + ab->len, avail);
-	if (IS_ERR(p)) {
-		/* FIXME: can we save some information here? */
-		audit_log_format(ab, "<toolong>");
-	} else {
-				/* path isn't at start of buffer */
-		len	   = (ab->tmp + sizeof(ab->tmp) - 1) - p;
-		memmove(ab->tmp + ab->len, p, len);
-		ab->len   += len;
-		ab->total += len;
-	}
-}
-
-/* Remove queued messages from the audit_txlist and send them to userspace. */
-static void audit_tasklet_handler(unsigned long arg)
-{
-	LIST_HEAD(list);
-	struct audit_buffer *ab;
-	unsigned long	    flags;
+	char *p, *path;
 
-	spin_lock_irqsave(&audit_txlist_lock, flags);
-	list_splice_init(&audit_txlist, &list);
-	spin_unlock_irqrestore(&audit_txlist_lock, flags);
+	if (prefix)
+		audit_log_format(ab, " %s", prefix);
 
-	while (!list_empty(&list)) {
-		ab = list_entry(list.next, struct audit_buffer, list);
-		list_del(&ab->list);
-		audit_log_end_fast(ab);
+	/* We will allow 11 spaces for ' (deleted)' to be appended */
+	path = kmalloc(PATH_MAX+11, GFP_KERNEL);
+	if (!path) {
+		audit_log_format(ab, "<no memory>");
+		return;
 	}
+	p = d_path(dentry, vfsmnt, path, PATH_MAX+11);
+	if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
+		/* FIXME: can we save some information here? */
+		audit_log_format(ab, "<too long>");
+	} else 
+		audit_log_untrustedstring(ab, p);
+	kfree(path);
 }
 
-static DECLARE_TASKLET(audit_tasklet, audit_tasklet_handler, 0);
-
 /* The netlink_* functions cannot be called inside an irq context, so
  * the audit buffer is places on a queue and a tasklet is scheduled to
  * remove them from the queue outside the irq context.  May be called in
  * any context. */
-static void audit_log_end_irq(struct audit_buffer *ab)
-{
-	unsigned long flags;
-
-	if (!ab)
-		return;
-	spin_lock_irqsave(&audit_txlist_lock, flags);
-	list_add_tail(&ab->list, &audit_txlist);
-	spin_unlock_irqrestore(&audit_txlist_lock, flags);
-
-	tasklet_schedule(&audit_tasklet);
-}
-
-/* Send the message in the audit buffer directly to user space.  May not
- * be called in an irq context. */
-static void audit_log_end_fast(struct audit_buffer *ab)
+void audit_log_end(struct audit_buffer *ab)
 {
-	unsigned long flags;
-
-	BUG_ON(in_irq());
 	if (!ab)
 		return;
 	if (!audit_rate_check()) {
 		audit_log_lost("rate limit exceeded");
 	} else {
-		audit_log_move(ab);
-		if (audit_log_drain(ab))
-			return;
+		if (audit_pid) {
+			struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
+			nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
+			skb_queue_tail(&audit_skb_queue, ab->skb);
+			ab->skb = NULL;
+			wake_up_interruptible(&kauditd_wait);
+		} else {
+			printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
+		}
 	}
-
-	atomic_dec(&audit_backlog);
-	spin_lock_irqsave(&audit_freelist_lock, flags);
-	if (++audit_freelist_count > AUDIT_MAXFREE)
-		kfree(ab);
-	else
-		list_add(&ab->list, &audit_freelist);
-	spin_unlock_irqrestore(&audit_freelist_lock, flags);
-}
-
-/* Send or queue the message in the audit buffer, depending on the
- * current context.  (A convenience function that may be called in any
- * context.) */
-void audit_log_end(struct audit_buffer *ab)
-{
-	if (in_irq())
-		audit_log_end_irq(ab);
-	else
-		audit_log_end_fast(ab);
+	audit_buffer_free(ab);
 }
 
 /* Log an audit record.  This is a convenience function that calls
  * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
  * called in any context. */
-void audit_log(struct audit_context *ctx, const char *fmt, ...)
+void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
 {
 	struct audit_buffer *ab;
 	va_list args;
 
-	ab = audit_log_start(ctx);
+	ab = audit_log_start(ctx, type);
 	if (ab) {
 		va_start(args, fmt);
 		audit_log_vformat(ab, fmt, args);
Index: kernel/auditsc.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/kernel/auditsc.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/kernel/auditsc.c  (mode:100644)
@@ -34,7 +34,8 @@
 #include <asm/types.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-
+#include <linux/mount.h>
+#include <linux/socket.h>
 #include <linux/audit.h>
 #include <linux/personality.h>
 #include <linux/time.h>
@@ -112,6 +113,23 @@
 	mode_t			mode;
 };
 
+struct audit_aux_data_socketcall {
+	struct audit_aux_data	d;
+	int			nargs;
+	unsigned long		args[0];
+};
+
+struct audit_aux_data_sockaddr {
+	struct audit_aux_data	d;
+	int			len;
+	char			a[0];
+};
+
+struct audit_aux_data_path {
+	struct audit_aux_data	d;
+	struct dentry		*dentry;
+	struct vfsmount		*mnt;
+};
 
 /* The per-task audit context. */
 struct audit_context {
@@ -157,6 +175,8 @@
 	struct audit_rule rule;
 };
 
+extern int audit_pid;
+
 /* Check to see if two rules are identical.  It is called from
  * audit_del_rule during AUDIT_DEL. */
 static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
@@ -226,7 +246,6 @@
 	return -EFAULT;		/* No matching rule */
 }
 
-#ifdef CONFIG_NET
 /* Copy rule from user-space to kernel-space.  Called during
  * AUDIT_ADD. */
 static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
@@ -287,7 +306,8 @@
 			err = audit_add_rule(entry, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_add_rule(entry, &audit_extlist);
-		audit_log(NULL, "auid %u added an audit rule\n", loginuid);
+		audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+				"auid=%u added an audit rule\n", loginuid);
 		break;
 	case AUDIT_DEL:
 		flags =((struct audit_rule *)data)->flags;
@@ -297,7 +317,8 @@
 			err = audit_del_rule(data, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_del_rule(data, &audit_extlist);
-		audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
+		audit_log(NULL, AUDIT_CONFIG_CHANGE,
+				"auid=%u removed an audit rule\n", loginuid);
 		break;
 	default:
 		return -EINVAL;
@@ -305,7 +326,6 @@
 
 	return err;
 }
-#endif
 
 /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
  * otherwise. */
@@ -444,7 +464,7 @@
 
 /* At syscall entry and exit time, this filter is called if the
  * audit_state is not low enough that auditing cannot take place, but is
- * also not high enough that we already know we have to write and audit
+ * also not high enough that we already know we have to write an audit
  * record (i.e., the state is AUDIT_SETUP_CONTEXT or  AUDIT_BUILD_CONTEXT).
  */
 static enum audit_state audit_filter_syscall(struct task_struct *tsk,
@@ -539,6 +559,11 @@
 	struct audit_aux_data *aux;
 
 	while ((aux = context->aux)) {
+		if (aux->type == AUDIT_AVC_PATH) {
+			struct audit_aux_data_path *axi = (void *)aux;
+			dput(axi->dentry);
+			mntput(axi->mnt);
+		}
 		context->aux = aux->next;
 		kfree(aux);
 	}
@@ -625,7 +650,8 @@
 	struct vm_area_struct *vma;
 
 	get_task_comm(name, current);
-	audit_log_format(ab, " comm=%s", name);
+	audit_log_format(ab, " comm=");
+	audit_log_untrustedstring(ab, name);
 
 	if (!mm)
 		return;
@@ -650,22 +676,22 @@
 	int i;
 	struct audit_buffer *ab;
 
-	ab = audit_log_start(context);
+	ab = audit_log_start(context, AUDIT_SYSCALL);
 	if (!ab)
 		return;		/* audit_panic has been called */
-	audit_log_format(ab, "syscall=%d", context->major);
+	audit_log_format(ab, "arch=%x syscall=%d",
+			 context->arch, context->major);
 	if (context->personality != PER_LINUX)
 		audit_log_format(ab, " per=%lx", context->personality);
-	audit_log_format(ab, " arch=%x", context->arch);
 	if (context->return_valid)
 		audit_log_format(ab, " success=%s exit=%ld", 
 				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
 				 context->return_code);
 	audit_log_format(ab,
 		  " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
-		  " pid=%d loginuid=%d uid=%d gid=%d"
-		  " euid=%d suid=%d fsuid=%d"
-		  " egid=%d sgid=%d fsgid=%d",
+		  " pid=%d auid=%u uid=%u gid=%u"
+		  " euid=%u suid=%u fsuid=%u"
+		  " egid=%u sgid=%u fsgid=%u",
 		  context->argv[0],
 		  context->argv[1],
 		  context->argv[2],
@@ -682,28 +708,51 @@
 	while (context->aux) {
 		struct audit_aux_data *aux;
 
-		ab = audit_log_start(context);
+		aux = context->aux;
+
+		ab = audit_log_start(context, aux->type);
 		if (!ab)
 			continue; /* audit_panic has been called */
 
-		aux = context->aux;
-		context->aux = aux->next;
-
-		audit_log_format(ab, "auxitem=%d", aux->type);
 		switch (aux->type) {
-		case AUDIT_AUX_IPCPERM: {
+		case AUDIT_IPC: {
 			struct audit_aux_data_ipcctl *axi = (void *)aux;
 			audit_log_format(ab, 
-					 " qbytes=%lx uid=%d gid=%d mode=%x",
+					 " qbytes=%lx iuid=%u igid=%u mode=%x",
 					 axi->qbytes, axi->uid, axi->gid, axi->mode);
-			}
+			break; }
+
+		case AUDIT_SOCKETCALL: {
+			int i;
+			struct audit_aux_data_socketcall *axs = (void *)aux;
+			audit_log_format(ab, "nargs=%d", axs->nargs);
+			for (i=0; i<axs->nargs; i++)
+				audit_log_format(ab, " a%d=%lx", i, axs->args[i]);
+			break; }
+
+		case AUDIT_SOCKADDR: {
+			struct audit_aux_data_sockaddr *axs = (void *)aux;
+
+			audit_log_format(ab, "saddr=");
+			audit_log_hex(ab, axs->a, axs->len);
+			break; }
+
+		case AUDIT_AVC_PATH: {
+			struct audit_aux_data_path *axi = (void *)aux;
+			audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
+			dput(axi->dentry);
+			mntput(axi->mnt);
+			break; }
+
 		}
 		audit_log_end(ab);
+
+		context->aux = aux->next;
 		kfree(aux);
 	}
 
 	for (i = 0; i < context->name_count; i++) {
-		ab = audit_log_start(context);
+		ab = audit_log_start(context, AUDIT_PATH);
 		if (!ab)
 			continue; /* audit_panic has been called */
 		audit_log_format(ab, "item=%d", i);
@@ -713,7 +762,7 @@
 		}
 		if (context->names[i].ino != (unsigned long)-1)
 			audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
-					     " uid=%d gid=%d rdev=%02x:%02x",
+					     " ouid=%u ogid=%u rdev=%02x:%02x",
 					 context->names[i].ino,
 					 MAJOR(context->names[i].dev),
 					 MINOR(context->names[i].dev),
@@ -741,42 +790,12 @@
 
 	/* Check for system calls that do not go through the exit
 	 * function (e.g., exit_group), then free context block. */
-	if (context->in_syscall && context->auditable)
+	if (context->in_syscall && context->auditable && context->pid != audit_pid)
 		audit_log_exit(context);
 
 	audit_free_context(context);
 }
 
-/* Compute a serial number for the audit record.  Audit records are
- * written to user-space as soon as they are generated, so a complete
- * audit record may be written in several pieces.  The timestamp of the
- * record and this serial number are used by the user-space daemon to
- * determine which pieces belong to the same audit record.  The
- * (timestamp,serial) tuple is unique for each syscall and is live from
- * syscall entry to syscall exit.
- *
- * Atomic values are only guaranteed to be 24-bit, so we count down.
- *
- * NOTE: Another possibility is to store the formatted records off the
- * audit context (for those records that have a context), and emit them
- * all at syscall exit.  However, this could delay the reporting of
- * significant errors until syscall exit (or never, if the system
- * halts). */
-static inline unsigned int audit_serial(void)
-{
-	static atomic_t serial = ATOMIC_INIT(0xffffff);
-	unsigned int a, b;
-
-	do {
-		a = atomic_read(&serial);
-		if (atomic_dec_and_test(&serial))
-			atomic_set(&serial, 0xffffff);
-		b = atomic_read(&serial);
-	} while (b != a - 1);
-
-	return 0xffffff - b;
-}
-
 /* Fill in audit context at syscall entry.  This only happens if the
  * audit context was created when the task was created and the state or
  * filters demand the audit context be built.  If the state from the
@@ -876,7 +895,7 @@
 	if (likely(!context))
 		return;
 
-	if (context->in_syscall && context->auditable)
+	if (context->in_syscall && context->auditable && context->pid != audit_pid)
 		audit_log_exit(context);
 
 	context->in_syscall = 0;
@@ -994,34 +1013,26 @@
 	context->names[idx].rdev = inode->i_rdev;
 }
 
-void audit_get_stamp(struct audit_context *ctx,
-		     struct timespec *t, unsigned int *serial)
+void auditsc_get_stamp(struct audit_context *ctx,
+		       struct timespec *t, unsigned int *serial)
 {
-	if (ctx) {
-		t->tv_sec  = ctx->ctime.tv_sec;
-		t->tv_nsec = ctx->ctime.tv_nsec;
-		*serial    = ctx->serial;
-		ctx->auditable = 1;
-	} else {
-		*t      = CURRENT_TIME;
-		*serial = 0;
-	}
+	t->tv_sec  = ctx->ctime.tv_sec;
+	t->tv_nsec = ctx->ctime.tv_nsec;
+	*serial    = ctx->serial;
+	ctx->auditable = 1;
 }
 
-extern int audit_set_type(struct audit_buffer *ab, int type);
-
 int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
 {
 	if (task->audit_context) {
 		struct audit_buffer *ab;
 
-		ab = audit_log_start(NULL);
+		ab = audit_log_start(NULL, AUDIT_LOGIN);
 		if (ab) {
 			audit_log_format(ab, "login pid=%d uid=%u "
-				"old loginuid=%u new loginuid=%u",
+				"old auid=%u new auid=%u",
 				task->pid, task->uid, 
 				task->audit_context->loginuid, loginuid);
-			audit_set_type(ab, AUDIT_LOGIN);
 			audit_log_end(ab);
 		}
 		task->audit_context->loginuid = loginuid;
@@ -1051,8 +1062,89 @@
 	ax->gid = gid;
 	ax->mode = mode;
 
-	ax->d.type = AUDIT_AUX_IPCPERM;
+	ax->d.type = AUDIT_IPC;
 	ax->d.next = context->aux;
 	context->aux = (void *)ax;
 	return 0;
 }
+
+int audit_socketcall(int nargs, unsigned long *args)
+{
+	struct audit_aux_data_socketcall *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->nargs = nargs;
+	memcpy(ax->args, args, nargs * sizeof(unsigned long));
+
+	ax->d.type = AUDIT_SOCKETCALL;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+int audit_sockaddr(int len, void *a)
+{
+	struct audit_aux_data_sockaddr *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->len = len;
+	memcpy(ax->a, a, len);
+
+	ax->d.type = AUDIT_SOCKADDR;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
+{
+	struct audit_aux_data_path *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->dentry = dget(dentry);
+	ax->mnt = mntget(mnt);
+
+	ax->d.type = AUDIT_AVC_PATH;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+void audit_signal_info(int sig, struct task_struct *t)
+{
+	extern pid_t audit_sig_pid;
+	extern uid_t audit_sig_uid;
+
+	if (unlikely(audit_pid && t->pid == audit_pid)) {
+		if (sig == SIGTERM || sig == SIGHUP) {
+			struct audit_context *ctx = current->audit_context;
+			audit_sig_pid = current->pid;
+			if (ctx)
+				audit_sig_uid = ctx->loginuid;
+			else
+				audit_sig_uid = current->uid;
+		}
+	}
+}
+
Index: kernel/signal.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/kernel/signal.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/kernel/signal.c  (mode:100644)
@@ -24,6 +24,7 @@
 #include <linux/ptrace.h>
 #include <linux/posix-timers.h>
 #include <linux/signal.h>
+#include <linux/audit.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -658,7 +659,11 @@
 	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
 	    && !capable(CAP_KILL))
 		return error;
-	return security_task_kill(t, info, sig);
+
+	error = security_task_kill(t, info, sig);
+	if (!error)
+		audit_signal_info(sig, t); /* Let audit system see the signal */
+	return error;
 }
 
 /* forward decl */
Index: net/socket.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/net/socket.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/net/socket.c  (mode:100644)
@@ -81,6 +81,7 @@
 #include <linux/syscalls.h>
 #include <linux/compat.h>
 #include <linux/kmod.h>
+#include <linux/audit.h>
 
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
@@ -226,7 +227,7 @@
 		return 0;
 	if(copy_from_user(kaddr,uaddr,ulen))
 		return -EFAULT;
-	return 0;
+	return audit_sockaddr(ulen, kaddr);
 }
 
 /**
@@ -1906,7 +1907,11 @@
 	/* copy_from_user should be SMP safe. */
 	if (copy_from_user(a, args, nargs[call]))
 		return -EFAULT;
-		
+
+	err = audit_socketcall(nargs[call]/sizeof(unsigned long), args);
+	if (err)
+		return err;
+
 	a0=a[0];
 	a1=a[1];
 	
Index: security/selinux/avc.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/security/selinux/avc.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/security/selinux/avc.c  (mode:100644)
@@ -242,7 +242,7 @@
 	avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
 					     0, SLAB_PANIC, NULL, NULL);
 
-	audit_log(current->audit_context, "AVC INITIALIZED\n");
+	audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
 }
 
 int avc_get_hash_stats(char *page)
@@ -532,6 +532,7 @@
                u16 tclass, u32 requested,
                struct av_decision *avd, int result, struct avc_audit_data *a)
 {
+	struct task_struct *tsk = current;
 	struct inode *inode = NULL;
 	u32 denied, audited;
 	struct audit_buffer *ab;
@@ -549,12 +550,18 @@
 			return;
 	}
 
-	ab = audit_log_start(current->audit_context);
+	ab = audit_log_start(current->audit_context, AUDIT_AVC);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");
 	avc_dump_av(ab, tclass,audited);
 	audit_log_format(ab, " for ");
+	if (a && a->tsk)
+		tsk = a->tsk;
+	if (tsk && tsk->pid) {
+		audit_log_format(ab, " pid=%d comm=", tsk->pid);
+		audit_log_untrustedstring(ab, tsk->comm);
+	}
 	if (a) {
 		switch (a->type) {
 		case AVC_AUDIT_DATA_IPC:
@@ -566,13 +573,10 @@
 		case AVC_AUDIT_DATA_FS:
 			if (a->u.fs.dentry) {
 				struct dentry *dentry = a->u.fs.dentry;
-				if (a->u.fs.mnt) {
-					audit_log_d_path(ab, "path=", dentry,
-							a->u.fs.mnt);
-				} else {
-					audit_log_format(ab, " name=%s",
-							 dentry->d_name.name);
-				}
+				if (a->u.fs.mnt)
+					audit_avc_path(dentry, a->u.fs.mnt);
+				audit_log_format(ab, " name=%s",
+						 dentry->d_name.name);
 				inode = dentry->d_inode;
 			} else if (a->u.fs.inode) {
 				struct dentry *dentry;
@@ -623,8 +627,10 @@
 				case AF_UNIX:
 					u = unix_sk(sk);
 					if (u->dentry) {
-						audit_log_d_path(ab, "path=",
-							u->dentry, u->mnt);
+						audit_avc_path(u->dentry, u->mnt);
+						audit_log_format(ab, " name=%s",
+								 u->dentry->d_name.name);
+
 						break;
 					}
 					if (!u->addr)
Index: security/selinux/hooks.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/security/selinux/hooks.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/security/selinux/hooks.c  (mode:100644)
@@ -3419,7 +3419,7 @@
 	err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
 	if (err) {
 		if (err == -EINVAL) {
-			audit_log(current->audit_context,
+			audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 				  "SELinux:  unrecognized netlink message"
 				  " type=%hu for sclass=%hu\n",
 				  nlh->nlmsg_type, isec->sclass);
Index: security/selinux/nlmsgtab.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/security/selinux/nlmsgtab.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/security/selinux/nlmsgtab.c  (mode:100644)
@@ -97,6 +97,7 @@
 	{ AUDIT_ADD,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
 	{ AUDIT_DEL,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
 	{ AUDIT_USER,		NETLINK_AUDIT_SOCKET__NLMSG_RELAY    },
+	{ AUDIT_SIGNAL_INFO,	NETLINK_AUDIT_SOCKET__NLMSG_READ     },
 };
 
 
@@ -141,8 +142,13 @@
 		break;
 
 	case SECCLASS_NETLINK_AUDIT_SOCKET:
-		err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
-				 sizeof(nlmsg_audit_perms));
+		if (nlmsg_type >= AUDIT_FIRST_USER_MSG &&
+		    nlmsg_type <= AUDIT_LAST_USER_MSG) {
+			*perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY;
+		} else {
+			err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
+					 sizeof(nlmsg_audit_perms));
+		}
 		break;
 
 	/* No messaging from userspace, or class unknown/unhandled */
Index: security/selinux/ss/services.c
===================================================================
--- 46ae0ec07caf01fa5c743112ae8ee932d1e66854/security/selinux/ss/services.c  (mode:100644)
+++ 279ace274d6a5e7c696c95f397bfbf5d5d5c347a/security/selinux/ss/services.c  (mode:100644)
@@ -365,7 +365,7 @@
 		goto out;
 	if (context_struct_to_string(tcontext, &t, &tlen) < 0)
 		goto out;
-	audit_log(current->audit_context,
+	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 	          "security_validate_transition:  denied for"
 	          " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
 	          o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@ -742,7 +742,7 @@
 		goto out;
 	if (context_struct_to_string(newcontext, &n, &nlen) < 0)
 		goto out;
-	audit_log(current->audit_context,
+	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 		  "security_compute_sid:  invalid context %s"
 		  " for scontext=%s"
 		  " tcontext=%s"

linux-2.6.12-sata-sil-extra-id.patch:
 sata_sil.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6.12-sata-sil-extra-id.patch ---
--- linux-2.6.11/drivers/scsi/sata_sil.c~	2005-05-23 19:31:51.000000000 -0400
+++ linux-2.6.11/drivers/scsi/sata_sil.c	2005-05-23 19:32:03.000000000 -0400
@@ -82,6 +82,7 @@ static struct pci_device_id sil_pci_tbl[
 	{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
 	{ 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+	{ 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ }	/* terminate list */
 };
 

linux-2.6.12-scsi-blacklist.patch:
 scsi_devinfo.c |    1 +
 1 files changed, 1 insertion(+)

--- NEW FILE linux-2.6.12-scsi-blacklist.patch ---

Reports LUN over and over..
https://bugzilla.redhat.com/beta/show_bug.cgi?id=155457

--- linux-2.6.11/drivers/scsi/scsi_devinfo.c~	2005-04-29 18:16:15.000000000 -0400
+++ linux-2.6.11/drivers/scsi/scsi_devinfo.c	2005-04-29 18:18:27.000000000 -0400
@@ -114,6 +114,7 @@ static struct {
 	{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN},	/* locks up */
 	{"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN},	/* locks up */
 	{"YAMAHA", "CRW6416S", "1.0c", BLIST_NOLUN},	/* locks up */
+	{"", "Scanner", "1.80", BLIST_NOLUN},	/* responds to all lun */
 
 	/*
 	 * Other types of devices that have special flags.

linux-2.6.12-scsicam-geom-fix.patch:
 scsicam.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

--- NEW FILE linux-2.6.12-scsicam-geom-fix.patch ---
--- linux-2.6.9/drivers/scsi/scsicam.c.orig
+++ linux-2.6.9/drivers/scsi/scsicam.c
@@ -58,6 +58,15 @@ int scsicam_bios_param(struct block_devi
 	unsigned char *p;
 	int ret;
 
+	/* Are we above the max. allowed for cylinder/sector/head? */
+	if (capacity > 65535*63*255) {
+		ip[0] = 255;
+		ip[1] = 63;
+		ip[2] = 65535;
+
+		return 0;
+	}
+
 	p = scsi_bios_ptable(bdev);
 	if (!p)
 		return -1;
@@ -85,11 +94,7 @@ int scsicam_bios_param(struct block_devi
 			ip[0] = 64;
 			ip[1] = 32;
 		}
-
-		if (capacity > 65535*63*255)
-			ip[2] = 65535;
-		else
-			ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
+		ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
 	}
 
 	return 0;

linux-2.6.12-speedtouch-resync.patch:
 speedtch.c |    2 ++
 1 files changed, 2 insertions(+)

--- NEW FILE linux-2.6.12-speedtouch-resync.patch ---
--- linux-2.6.11/drivers/usb/atm/speedtch.c.orig	2005-05-25 09:22:49.000000000 +0100
+++ linux-2.6.11/drivers/usb/atm/speedtch.c	2005-05-25 09:21:41.000000000 +0100
@@ -386,6 +386,8 @@ static void speedtch_poll_status(struct 
 		if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
 			instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
 			printk(KERN_NOTICE "ADSL line is down\n");
+			/* It'll never resync again unless we ask it to... */
+			speedtch_start_synchro(instance);
 		}
 		break;
 

linux-2.6.12-usb-old_scheme_first.patch:
 hub.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6.12-usb-old_scheme_first.patch ---
diff -urNp --exclude-from=/home/davej/.exclude linux-1301/drivers/usb/core/hub.c linux-1400/drivers/usb/core/hub.c
--- linux-1301/drivers/usb/core/hub.c
+++ linux-1400/drivers/usb/core/hub.c
@@ -69,7 +69,7 @@ MODULE_PARM_DESC (blinkenlights, "true t
  * otherwise the new scheme is used.  If that fails and "use_both_schemes"
  * is set, then the driver will make another attempt, using the other scheme.
  */
-static int old_scheme_first = 0;
+static int old_scheme_first = 1;
 module_param(old_scheme_first, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(old_scheme_first,
 		 "start with the old device initialization scheme");

linux-2.6.12-vm-singlebiterror.patch:
 slab.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+)

--- NEW FILE linux-2.6.12-vm-singlebiterror.patch ---
--- linux-2.6.11/mm/slab.c~	2005-05-01 00:51:59.000000000 -0400
+++ linux-2.6.11/mm/slab.c	2005-05-01 01:19:38.000000000 -0400
@@ -1004,8 +1004,12 @@ static void poison_obj(kmem_cache_t *cac
 static void dump_line(char *data, int offset, int limit)
 {
 	int i;
+	unsigned char total=0;
+
 	printk(KERN_ERR "%03x:", offset);
 	for (i=0;i<limit;i++) {
+		if (data[offset+i] != POISON_FREE)
+			total += data[offset+i];
 		if (check_tainted() == 0)
 			printk(" %02x", (unsigned char)data[offset+i]);
 		else {
@@ -1019,6 +1023,18 @@ static void dump_line(char *data, int of
 		}
 	}
 	printk("\n");
+	switch (total) {
+		case 0x36:
+		case 0x6a:
+		case 0x6f:
+		case 0x81:
+		case 0xac:
+		case 0xd3:
+		case 0xd5:
+		case 0xea:
+			printk (KERN_ERR "Single bit error detected. Possibly bad RAM. Run memtest86.\n");
+			return;
+	}
 }
 #endif
 


--- NEW FILE linux-2.6.12.tar.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBCs1xyyGugalF9Dw4RAlRHAJ9U4Lq+GmLR6Rs/44fYwizxJ03HFwCfUTs0
4fGx0BgzA0JlDd1zOqE2J3I=
=CDaz
-----END PGP SIGNATURE-----

linux-2.6.12rc-ac-ide-fixes.patch:
 2/drivers/ide/ide-cd.c                     |    6 
 2/drivers/ide/ide-io.c                     |   57 ++
 linux-2.6.12/drivers/cdrom/cdrom.c         |    3 
 linux-2.6.12/drivers/ide/Kconfig           |    6 
 linux-2.6.12/drivers/ide/ide-cd.c          |  114 +++-
 linux-2.6.12/drivers/ide/ide-disk.c        |   12 
 linux-2.6.12/drivers/ide/ide-dma.c         |    1 
 linux-2.6.12/drivers/ide/ide-io.c          |    8 
 linux-2.6.12/drivers/ide/ide-iops.c        |   97 +--
 linux-2.6.12/drivers/ide/pci/Makefile      |    1 
 linux-2.6.12/drivers/ide/pci/cs5520.c      |    2 
 linux-2.6.12/drivers/ide/pci/generic.c     |   73 +-
 linux-2.6.12/drivers/ide/pci/hpt366.c      |  472 ++++++++--------
 linux-2.6.12/drivers/ide/pci/it821x.c      |  812 +++++++++++++++++++++++++++++
 linux-2.6.12/drivers/ide/pci/serverworks.c |   10 
 linux-2.6.12/drivers/ide/pci/siimage.c     |    8 
 linux-2.6.12/drivers/ide/pci/trm290.c      |    1 
 linux-2.6.12/drivers/scsi/libata-core.c    |    1 
 linux-2.6.12/include/asm-i386/ide.h        |   14 
 linux-2.6.12/include/linux/ide.h           |    4 
 linux-2.6.12/include/linux/pci_ids.h       |    2 
 21 files changed, 1337 insertions(+), 367 deletions(-)

--- NEW FILE linux-2.6.12rc-ac-ide-fixes.patch ---
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.12/drivers/cdrom/cdrom.c linux-2.6.12/drivers/cdrom/cdrom.c
--- linux.vanilla-2.6.12/drivers/cdrom/cdrom.c	2005-06-19 11:30:47.000000000 +0100
+++ linux-2.6.12/drivers/cdrom/cdrom.c	2005-06-21 13:46:29.000000000 +0100
@@ -1131,7 +1131,8 @@
 	This ensures that the drive gets unlocked after a mount fails.  This 
 	is a goto to avoid bloating the driver with redundant code. */ 
 clean_up_and_return:
-	cdinfo(CD_WARNING, "open failed.\n"); 
+	/* Don't log this, its a perfectly normal user occurence */
+	/* cdinfo(CD_WARNING, "open failed.\n");  */
 	if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
 			cdo->lock_door(cdi, 0);
 			cdinfo(CD_OPEN, "door unlocked.\n");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.12/drivers/ide/ide-cd.c linux-2.6.12/drivers/ide/ide-cd.c
--- linux.vanilla-2.6.12/drivers/ide/ide-cd.c	2005-06-19 11:30:47.000000000 +0100
+++ linux-2.6.12/drivers/ide/ide-cd.c	2005-06-22 16:32:49.419755488 +0100
@@ -394,7 +394,8 @@
 			 * we cannot reliably check if drive can auto-close
 			 */
 			if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
-				log = 0;
+				break;
+			log = 1;
 			break;
 		case UNIT_ATTENTION:
 			/*
@@ -416,6 +417,11 @@
 			      struct request *failed_command,
 			      struct request_sense *sense)
 {
+	unsigned long sector;
+	unsigned long bio_sectors;
+	unsigned long valid;
+	struct cdrom_info *info = drive->driver_data;
+	
 	if (!cdrom_log_sense(drive, failed_command, sense))
 		return;
 
@@ -428,13 +434,43 @@
 		if (sense->sense_key == 0x05 && sense->asc == 0x24)
 			return;
 
+	if (sense->error_code == 0x70) {	/* Current Error */
+		switch(sense->sense_key) {
+			case MEDIUM_ERROR:
+			case VOLUME_OVERFLOW:
+			case ILLEGAL_REQUEST:
+				if(!sense->valid)
+					break;
+				if(failed_command == NULL || !blk_fs_request(failed_command))
+					break;
+				sector = (sense->information[0] << 24) |
+					 (sense->information[1] << 16) |
+					 (sense->information[2] <<  8) |
+					 (sense->information[3]);
+					 
+				bio_sectors = bio_sectors(failed_command->bio);
+				if(bio_sectors < 4)
+					bio_sectors = 4;
+				if(drive->queue->hardsect_size == 2048)
+					sector <<= 2;	/* Device sector size is 2K */
+				sector &= ~(bio_sectors -1);
+				valid = (sector - failed_command->sector) << 9;
+				
+				if(valid < 0)
+					valid = 0;
+				if(sector < get_capacity(info->disk) &&
+					drive->probed_capacity - sector < 4 * 75) {
+					set_capacity(info->disk, sector);
+				}
+		}
+	}
 #if VERBOSE_IDE_CD_ERRORS
 	{
 		int i;
 		const char *s;
 		char buf[80];
 
-		printk ("ATAPI device %s:\n", drive->name);
+		printk (KERN_ERR "ATAPI device %s:\n", drive->name);
 		if (sense->error_code==0x70)
 			printk("  Error: ");
 		else if (sense->error_code==0x71)
@@ -610,17 +646,22 @@
 				sense = failed->sense;
 				failed->sense_len = rq->sense_len;
 			}
-
+			cdrom_analyze_sense_data(drive, failed, sense);
 			/*
 			 * now end failed request
 			 */
 			spin_lock_irqsave(&ide_lock, flags);
-			end_that_request_chunk(failed, 0, failed->data_len);
-			end_that_request_last(failed);
+			if(blk_fs_request(failed)) {
+				if(__ide_end_request(drive, failed, 0, failed->hard_nr_sectors))
+					BUG();
+			} else {
+				end_that_request_chunk(failed, 0, failed->data_len);
+				end_that_request_last(failed);
+			}
 			spin_unlock_irqrestore(&ide_lock, flags);
 		}
-
-		cdrom_analyze_sense_data(drive, failed, sense);
+		else
+			cdrom_analyze_sense_data(drive, NULL , sense);
 	}
 
 	if (!rq->current_nr_sectors && blk_fs_request(rq))
@@ -634,6 +675,13 @@
 	ide_end_request(drive, uptodate, nsectors);
 }
 
+static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat)
+{
+	if(stat & 0x80)
+		return;
+	ide_dump_status(drive, msg, stat);
+}
+
 /* Returns 0 if the request should be continued.
    Returns 1 if the request was ended. */
 static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
@@ -762,16 +810,16 @@
 			   sense_key == DATA_PROTECT) {
 			/* No point in retrying after an illegal
 			   request or data protect error.*/
-			ide_dump_status (drive, "command error", stat);
+			ide_dump_status_no_sense (drive, "command error", stat);
 			do_end_request = 1;
 		} else if (sense_key == MEDIUM_ERROR) {
 			/* No point in re-trying a zillion times on a bad 
 			 * sector...  If we got here the error is not correctable */
-			ide_dump_status (drive, "media error (bad sector)", stat);
+			ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
 			do_end_request = 1;
 		} else if (sense_key == BLANK_CHECK) {
 			/* Disk appears blank ?? */
-			ide_dump_status (drive, "media error (blank)", stat);
+			ide_dump_status_no_sense (drive, "media error (blank)", stat);
 			do_end_request = 1;
 		} else if ((err & ~ABRT_ERR) != 0) {
 			/* Go to the default handler
@@ -783,13 +831,27 @@
 			do_end_request = 1;
 		}
 
-		if (do_end_request)
-			cdrom_end_request(drive, 0);
+		/* End a request through request sense analysis when we have
+		   sense data. We need this in order to perform end of media
+		   processing */
+		   
+		if (do_end_request) {
+			if (stat & ERR_STAT) {
+				unsigned long flags;
+				spin_lock_irqsave(&ide_lock, flags);
+				blkdev_dequeue_request(rq);
+				HWGROUP(drive)->rq = NULL;
+				spin_unlock_irqrestore(&ide_lock, flags);
 
-		/* If we got a CHECK_CONDITION status,
-		   queue a request sense command. */
-		if ((stat & ERR_STAT) != 0)
-			cdrom_queue_request_sense(drive, NULL, NULL);
+				cdrom_queue_request_sense(drive, rq->sense, rq);
+			}
+			else cdrom_end_request(drive, 0);
+		} else {
+			/* If we got a CHECK_CONDITION status,
+			   queue a request sense command. */
+			if (stat & ERR_STAT)
+				cdrom_queue_request_sense(drive, NULL, NULL);
+		}
 	} else {
 		blk_dump_rq_flags(rq, "ide-cd: bad rq");
 		cdrom_end_request(drive, 0);
@@ -1495,8 +1557,7 @@
 }
 
 
-static
-int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
+static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
 {
 	struct request_sense sense;
 	int retries = 10;
@@ -2236,6 +2297,9 @@
 		toc->capacity = 0x1fffff;
 
 	set_capacity(info->disk, toc->capacity * sectors_per_frame);
+	/* Save a private copy of te TOC capacity for error handling */
+	drive->probed_capacity = toc->capacity * sectors_per_frame;
+	
 	blk_queue_hardsect_size(drive->queue,
 				sectors_per_frame << SECTOR_BITS);
 
[...2234 lines suppressed...]
 		case PCI_DEVICE_ID_SII_680:
 			return 0;
@@ -1088,7 +1090,9 @@
 static ide_pci_device_t siimage_chipsets[] __devinitdata = {
 	/* 0 */ DECLARE_SII_DEV("SiI680"),
 	/* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
-	/* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
+	/* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA"),
+	/* 3 */ DECLARE_SII_DEV("ATI IXP300"),
+	/* 4 */ DECLARE_SII_DEV("ATI IXP400")
 };
 
 /**
@@ -1110,6 +1114,8 @@
 #ifdef CONFIG_BLK_DEV_IDE_SATA
 	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
 	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
 #endif
 	{ 0, },
 };
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.12/drivers/ide/pci/trm290.c linux-2.6.12/drivers/ide/pci/trm290.c
--- linux.vanilla-2.6.12/drivers/ide/pci/trm290.c	2005-06-19 11:21:23.000000000 +0100
+++ linux-2.6.12/drivers/ide/pci/trm290.c	2005-06-22 16:36:37.616064376 +0100
@@ -256,6 +256,7 @@
 	u8 reg = 0;
 	struct pci_dev *dev = hwif->pci_dev;
 
+	/* FIXME: does this device support PIO LBA48 ? */
 	hwif->no_lba48 = 1;
 	hwif->chipset = ide_trm290;
 	cfgbase = pci_resource_start(dev, 4);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.12/drivers/scsi/libata-core.c linux-2.6.12/drivers/scsi/libata-core.c
--- linux.vanilla-2.6.12/drivers/scsi/libata-core.c	2005-06-19 11:30:52.000000000 +0100
+++ linux-2.6.12/drivers/scsi/libata-core.c	2005-06-21 10:34:00.000000000 +0100
@@ -1897,7 +1897,6 @@
 	"SAMSUNG CD-ROM SC-148C",
 	"SAMSUNG CD-ROM SC",
 	"SanDisk SDP3B-64",
-	"SAMSUNG CD-ROM SN-124",
 	"ATAPI CD-ROM DRIVE 40X MAXIMUM",
 	"_NEC DV5800A",
 };
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.12/include/asm-i386/ide.h linux-2.6.12/include/asm-i386/ide.h
--- linux.vanilla-2.6.12/include/asm-i386/ide.h	2005-06-19 11:21:43.000000000 +0100
+++ linux-2.6.12/include/asm-i386/ide.h	2005-06-21 13:22:13.000000000 +0100
@@ -41,16 +41,20 @@
 
 static __inline__ unsigned long ide_default_io_base(int index)
 {
+	if(pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) {
+		switch(index) {
+			case 2: return 0x1e8;
+			case 3: return 0x168;
+			case 4: return 0x1e0;
+			case 5: return 0x160;
+			}
+	}
 	switch (index) {
 		case 0:	return 0x1f0;
 		case 1:	return 0x170;
-		case 2: return 0x1e8;
-		case 3: return 0x168;
-		case 4: return 0x1e0;
-		case 5: return 0x160;
 		default:
 			return 0;
-	}
+	}		
 }
 
 #define IDE_ARCH_OBSOLETE_INIT
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.12/include/linux/ide.h linux-2.6.12/include/linux/ide.h
--- linux.vanilla-2.6.12/include/linux/ide.h	2005-06-19 11:30:59.000000000 +0100
+++ linux-2.6.12/include/linux/ide.h	2005-06-22 16:39:34.019247016 +0100
@@ -190,7 +190,7 @@
 #define WAIT_READY	(5*HZ)		/* 5sec - some laptops are very slow */
 #define WAIT_PIDENTIFY	(10*HZ)	/* 10sec  - should be less than 3ms (?), if all ATAPI CD is closed at boot */
 #define WAIT_WORSTCASE	(30*HZ)	/* 30sec  - worst case when spinning up */
-#define WAIT_CMD	(10*HZ)	/* 10sec  - maximum wait for an IRQ to happen */
+#define WAIT_CMD	(15*HZ)	/* 15sec  - maximum wait for an IRQ to happen */
 #define WAIT_MIN_SLEEP	(2*HZ/100)	/* 20msec - minimum sleep time */
 
 #define HOST(hwif,chipset)					\
@@ -747,6 +747,7 @@
 	unsigned int	usage;		/* current "open()" count for drive */
 	unsigned int	failures;	/* current failure count */
 	unsigned int	max_failures;	/* maximum allowed failure count */
+	u64		probed_capacity;/* initial reported media capacity (ide-cd only currently) */
 
 	u64		capacity64;	/* total number of sectors */
 
@@ -908,6 +909,7 @@
 	unsigned	no_dsc     : 1;	/* 0 default, 1 dsc_overlap disabled */
 	unsigned	auto_poll  : 1; /* supports nop auto-poll */
 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
+	unsigned 	polling    : 1; /* doing a polled command ignore irqs */
 
 	struct device	gendev;
 	struct semaphore gendev_rel_sem; /* To deal with device release() */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.12/include/linux/pci_ids.h linux-2.6.12/include/linux/pci_ids.h
--- linux.vanilla-2.6.12/include/linux/pci_ids.h	2005-06-19 11:30:59.000000000 +0100
+++ linux-2.6.12/include/linux/pci_ids.h	2005-06-20 21:25:36.000000000 +0100
@@ -1810,6 +1810,8 @@
 #define PCI_VENDOR_ID_ITE		0x1283
 #define PCI_DEVICE_ID_ITE_IT8172G	0x8172
 #define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
+#define PCI_DEVICE_ID_ITE_8211		0x8211
+#define PCI_DEVICE_ID_ITE_8212		0x8212
 #define PCI_DEVICE_ID_ITE_8872		0x8872
 #define PCI_DEVICE_ID_ITE_IT8330G_0	0xe886
 
--- 1/drivers/ide/ide-io.c~	2005-07-12 12:52:08.390768080 +0100
+++ 2/drivers/ide/ide-io.c	2005-07-12 12:52:08.390768080 +0100
@@ -223,6 +223,63 @@
 }
 
 /**
+ *	ide_end_dequeued_request	-	complete an IDE I/O
+ *	@drive: IDE device for the I/O
+ *	@uptodate:
+ *	@nr_sectors: number of sectors completed
+ *
+ *	Complete an I/O that is no longer on the request queue. This 
+ *	typically occurs when we pull the request and issue a REQUEST_SENSE.
+ *	We must still finish the old request but we must not tamper with the
+ *	queue in the meantime.
+ *
+ *	NOTE: This path does not handle barrier, but barrier is not supported
+ *	on ide-cd anyway.
+ */
+
+int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
+			     int uptodate, int nr_sectors)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&ide_lock, flags);
+
+	BUG_ON(!(rq->flags & REQ_STARTED));
+
+	/*
+	 * if failfast is set on a request, override number of sectors and
+	 * complete the whole request right now
+	 */
+	if (blk_noretry_request(rq) && end_io_error(uptodate))
+		nr_sectors = rq->hard_nr_sectors;
+
+	if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
+		rq->errors = -EIO;
+
+	/*
+	 * decide whether to reenable DMA -- 3 is a random magic for now,
+	 * if we DMA timeout more than 3 times, just stay in PIO
+	 */
+	if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
+		drive->state = 0;
+		HWGROUP(drive)->hwif->ide_dma_on(drive);
+	}
+
+	if (!end_that_request_first(rq, uptodate, nr_sectors)) {
+		add_disk_randomness(rq->rq_disk);
+		if (blk_rq_tagged(rq))
+			blk_queue_end_tag(drive->queue, rq);
+		end_that_request_last(rq);
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&ide_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
+
+
+/**
  *	ide_complete_pm_request - end the current Power Management request
  *	@drive: target drive
  *	@rq: request
--- 1/drivers/ide/ide-cd.c~	2005-07-12 12:52:28.287743280 +0100
+++ 2/drivers/ide/ide-cd.c	2005-07-12 12:53:45.991930448 +0100
@@ -650,15 +650,15 @@
 			/*
 			 * now end failed request
 			 */
-			spin_lock_irqsave(&ide_lock, flags);
 			if(blk_fs_request(failed)) {
-				if(__ide_end_request(drive, failed, 0, failed->hard_nr_sectors))
+				if(ide_end_dequeued_request(drive, failed, 0, failed->hard_nr_sectors))
 					BUG();
 			} else {
+				spin_lock_irqsave(&ide_lock, flags);
 				end_that_request_chunk(failed, 0, failed->data_len);
 				end_that_request_last(failed);
+				spin_unlock_irqrestore(&ide_lock, flags);
 			}
-			spin_unlock_irqrestore(&ide_lock, flags);
 		}
 		else
 			cdrom_analyze_sense_data(drive, NULL , sense);

linux-2.6.12rc-ppc32-clockspreading-fix.patch:
 arch/ppc/platforms/pmac_feature.c |   12 ++++--------
 drivers/macintosh/via-pmu.c       |    9 +++++++--
 include/asm-ppc/pmac_feature.h    |    3 +++
 3 files changed, 14 insertions(+), 10 deletions(-)

--- NEW FILE linux-2.6.12rc-ppc32-clockspreading-fix.patch ---
>From benh at kernel.crashing.org Mon May  2 06:49:45 2005
Return-path: <benh at kernel.crashing.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Mon, 02 May 2005 06:49:45 +0100
Received: from phoenix.infradead.org ([2001:8b0:10b:1:2c0:f0ff:fe31:e18])
	by baythorne.infradead.org with esmtps (Exim 4.43 #1 (Red Hat Linux)) id
	1DSToP-0004ZQ-0C for dwmw2 at baythorne.infradead.org; Mon, 02 May 2005
	06:49:45 +0100
Received: from djurbala-pt.tunnel.tserv2.fmt.ipv6.he.net
	([2001:470:1f01:ffff::eb] helo=gate.crashing.org) by phoenix.infradead.org
	with esmtps (Exim 4.43 #1 (Red Hat Linux)) id 1DSTo5-0006nT-9H for
	dwmw2 at infradead.org; Mon, 02 May 2005 06:49:42 +0100
Received: from gaston (localhost [127.0.0.1]) by gate.crashing.org
	(8.12.8/8.12.8) with ESMTP id j425gNgJ017759 for <dwmw2 at infradead.org>;
	Mon, 2 May 2005 00:42:24 -0500
Subject: clock spreading fix
From: Benjamin Herrenschmidt <benh at kernel.crashing.org>
To: David Woodhouse <dwmw2 at infradead.org>
Content-Type: text/plain
Date: Mon, 02 May 2005 15:46:09 +1000
Message-Id: <1115012769.6155.6.camel at gaston>
Mime-Version: 1.0
X-Mailer: Evolution 2.2.2 
X-Spam-Score: 0.0 (/)
X-Evolution-Source: imap://dwmw2@pentafluge.infradead.org/
Content-Transfer-Encoding: 8bit

Index: linux-work/include/asm-ppc/pmac_feature.h
===================================================================
--- linux-work.orig/include/asm-ppc/pmac_feature.h	2005-05-02 10:49:57.000000000 +1000
+++ linux-work/include/asm-ppc/pmac_feature.h	2005-05-02 15:43:08.000000000 +1000
@@ -316,6 +316,9 @@
 extern void pmac_suspend_agp_for_card(struct pci_dev *dev);
 extern void pmac_resume_agp_for_card(struct pci_dev *dev);
 
+/* Used by the via-pmu driver for suspend/resume
+ */
+extern void pmac_tweak_clock_spreading(int enable);
 
 /*
  * The part below is for use by macio_asic.c only, do not rely
Index: linux-work/arch/ppc/platforms/pmac_feature.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/pmac_feature.c	2005-05-02 13:16:22.000000000 +1000
+++ linux-work/arch/ppc/platforms/pmac_feature.c	2005-05-02 15:43:55.000000000 +1000
@@ -1591,8 +1591,10 @@
 }
 
 
-static void __pmac pmac_tweak_clock_spreading(struct macio_chip* macio, int enable)
+void __pmac pmac_tweak_clock_spreading(int enable)
 {
+	struct macio_chip* macio = &macio_chips[0];
+
 	/* Hack for doing clock spreading on some machines PowerBooks and
 	 * iBooks. This implements the "platform-do-clockspreading" OF
 	 * property as decoded manually on various models. For safety, we also
@@ -1707,9 +1709,6 @@
 	    macio->type != macio_intrepid)
 		return -ENODEV;
 
-	/* Disable clock spreading */
-	pmac_tweak_clock_spreading(macio, 0);
-
 	/* We power off the wireless slot in case it was not done
 	 * by the driver. We don't power it on automatically however
 	 */
@@ -1852,9 +1851,6 @@
 	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
 	udelay(100);
 
-	/* Enable clock spreading */
-	pmac_tweak_clock_spreading(macio, 1);
-
 	return 0;
 }
 
@@ -2822,7 +2818,7 @@
 	 * clock spreading now. This should be a platform function but we
 	 * don't do these at the moment
 	 */
-	pmac_tweak_clock_spreading(&macio_chips[0], 1);
+	pmac_tweak_clock_spreading(1);
 
 #endif /* CONFIG_POWER4 */
 
Index: linux-work/drivers/macintosh/via-pmu.c
===================================================================
--- linux-work.orig/drivers/macintosh/via-pmu.c	2005-05-02 10:48:11.000000000 +1000
+++ linux-work/drivers/macintosh/via-pmu.c	2005-05-02 15:45:49.000000000 +1000
@@ -2351,6 +2351,10 @@
 		return -EBUSY;
 	}
 
+	/* Disable clock spreading on some machines */
+	pmac_tweak_clock_spreading(0);
+
+	/* Stop preemption */
 	preempt_disable();
 
 	/* Make sure the decrementer won't interrupt us */
@@ -2417,11 +2421,12 @@
 
 	/* Re-enable local CPU interrupts */
 	local_irq_enable();
-
 	mdelay(100);
-
 	preempt_enable();
 
+	/* Re-enable clock spreading on some machines */
+	pmac_tweak_clock_spreading(1);
+
 	/* Resume devices */
 	device_resume();
 

-- 
Benjamin Herrenschmidt <benh at kernel.crashing.org>



--- NEW FILE patch-2.6.12.2.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBCwzrEyGugalF9Dw4RAsslAJ9b9H2LzcCbti03MeNMKYIGDDzCcACfW5Ce
sNP0nWZ6o3qcuiU9PjSt/Ew=
=eo2m
-----END PGP SIGNATURE-----


Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/.cvsignore,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -r1.124 -r1.125
--- .cvsignore	13 Jun 2005 04:35:57 -0000	1.124
+++ .cvsignore	13 Jul 2005 04:16:28 -0000	1.125
@@ -1,8 +1,9 @@
 linux-2.6.*.tar.bz2
+patch-2.6.*-bk*.bz2
 patch-2.6.*-rc*.bz2
 patch-2.6.*-final*.bz2
 kernel-2.6.*.config
 temp-*
-kernel-2.6.11
-linux-2.6.11.tar.bz2
-patch-2.6.11.12.bz2
+kernel-2.6.12
+linux-2.6.12.tar.bz2
+patch-2.6.12.2.bz2




Index: Makefile.config
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/Makefile.config,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- Makefile.config	17 May 2005 23:50:40 -0000	1.19
+++ Makefile.config	13 Jul 2005 04:16:28 -0000	1.20
@@ -6,7 +6,7 @@
 
 CONFIGFILES	= \
 	$(CFG)-i686.config $(CFG)-i686-smp.config \
-	$(CFG)-i586.config $(CFG)-i586-smp.config \
+	$(CFG)-i586.config \
 	$(CFG)-x86_64.config $(CFG)-x86_64-smp.config \
 	$(CFG)-ppc64iseries.config \
 	$(CFG)-s390.config $(CFG)-s390x.config \
@@ -18,7 +18,7 @@
 
 configs: $(CONFIGFILES)
 	@rm -f $(TEMPFILES)
-	@rm -f temp-xen-generic temp-x86-xen-generic temp-generic
+	@rm -f temp-generic
 
 # Augment the clean target to clean up our own cruft
 clean ::
@@ -52,12 +52,6 @@
 temp-ia64-generic: configs/config-ia64-generic temp-generic
 	perl scripts/merge.pl $^ > $@
 
-temp-x86-xen-generic: temp-x86-generic temp-generic
-	perl scripts/merge.pl $^ > $@
-
-temp-xen-generic: configs/config-xen-generic temp-x86-xen-generic
-	perl scripts/merge.pl $^ > $@
-
 kernel-$(VERSION)-i686.config: configs/config-i686 temp-x86-generic 
 	perl scripts/merge.pl $^ i386 > $@
 
@@ -67,9 +61,6 @@
 kernel-$(VERSION)-i586.config: configs/config-i586 temp-x86-generic 
 	perl scripts/merge.pl $^ i386 > $@
 
-kernel-$(VERSION)-i586-smp.config: configs/config-i586-smp temp-x86-generic 
-	perl scripts/merge.pl $^ i386 > $@
-
 kernel-$(VERSION)-x86_64-smp.config: configs/config-x86_64-smp temp-x86_64-generic 
 	perl scripts/merge.pl $^ x86_64 > $@
 
@@ -109,8 +100,3 @@
 kernel-$(VERSION)-ia64.config: configs/config-ia64 temp-ia64-generic
 	perl scripts/merge.pl $^ ia64 > $@
 
-kernel-$(VERSION)-i686-xen0.config: configs/config-xen-xen0 temp-xen-generic
-	perl scripts/merge.pl $^ xen > $@
-
-kernel-$(VERSION)-i686-xenU.config: configs/config-xen-xenU temp-xen-generic
-	perl scripts/merge.pl $^ xen > $@


Index: branch
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/branch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- branch	19 Oct 2004 04:04:36 -0000	1.1
+++ branch	13 Jul 2005 04:16:28 -0000	1.2
@@ -1 +1 @@
-FC-3
+scratch


Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/kernel-2.6.spec,v
retrieving revision 1.847
retrieving revision 1.848
diff -u -r1.847 -r1.848
--- kernel-2.6.spec	13 Jun 2005 04:36:23 -0000	1.847
+++ kernel-2.6.spec	13 Jul 2005 04:16:28 -0000	1.848
@@ -8,6 +8,7 @@
 
 %define buildup 1
 %define buildsmp 1
+
 %define builddoc 0
 
 # Versions of various parts
@@ -18,7 +19,7 @@
 # that the kernel isn't the stock distribution kernel, for example by
 # adding some text to the end of the version number.
 #
-%define sublevel 11
+%define sublevel 12
 %define kversion 2.6.%{sublevel}
 %define rpmversion 2.6.%{sublevel}
 %define rhbsys  %([ -r /etc/beehive-root -o -n "%{?__beehive_build}" ] && echo || echo .`whoami`)
@@ -26,7 +27,7 @@
 %define release %(R="$Revision$"; RR="${R##: }"; echo ${RR%%?})_FC3%{rhbsys}
 %endif
 %if %{FC4}
-%define release %(R="1.773"; RR="${R##: }"; echo ${RR%%?})_FC4%{rhbsys}
+%define release %(R="$Revision$"; RR="${R##: }"; echo ${RR%%?})_FC4%{rhbsys}
 %endif
 %define signmodules 0
 %define make_target bzImage
@@ -42,11 +43,15 @@
 %define builddoc 1
 %define buildup 0
 %define buildsmp 0
-%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}*.config
+%define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-*.config
 %endif
 
 # Second, per-architecture exclusions (ifarch)
 
+%ifarch i586
+%define buildsmp 0
+%endif
+
 %ifarch %{all_x86}
 %define all_arch_configs $RPM_SOURCE_DIR/kernel-%{kversion}-i?86*.config
 %define image_install_path boot
@@ -109,7 +114,6 @@
 %define signmodules 1
 %endif
 
-
 #
 # Three sets of minimum package version requirements in the form of Conflicts:
 # to versions below the minimum
@@ -127,7 +131,7 @@
 # problems with the newer kernel or lack certain things that make 
 # integration in the distro harder than needed.
 #
-%define package_conflicts  cipe < 1.4.5, kudzu <= 0.92, initscripts < 7.23, dev < 3.2-7, iptables < 1.2.5-3, bcm5820 < 1.81, nvidia-rh72 <= 1.0, selinux-policy-targeted < 1.17.30-2.94 ipw2200-firmware < 2.2
+%define package_conflicts  cipe < 1.4.5, kudzu <= 0.92, initscripts < 7.23, dev < 3.2-7, iptables < 1.2.5-3, bcm5820 < 1.81, nvidia-rh72 <= 1.0 selinux-policy-targeted < 1.17.30-3.16
 
 #
 # Several packages had bugs in them that became obvious when the NPTL
@@ -139,17 +143,18 @@
 # Packages that need to be installed before the kernel is, because the %post
 # scripts use them.
 #
-%define kernel_prereq  fileutils, module-init-tools, initscripts >= 5.83, mkinitrd >= 4.1.15, kernel-utils
+%define kernel_prereq  fileutils, module-init-tools, initscripts >= 5.83, mkinitrd >= 4.1.18-2
 
 Name: kernel
 Group: System Environment/Kernel
 License: GPLv2
 Version: %{rpmversion}
 Release: %{release}
-ExclusiveArch: noarch %{all_x86} x86_64
+ExclusiveArch: noarch %{all_x86} x86_64 ppc64 ppc64iseries ppc
 ExclusiveOS: Linux
 Provides: kernel = %{version}
 Provides: kernel-drm = 4.3.0
+Provides: kernel-%{_target_cpu} = %{rpmversion}-%{release}
 Prereq: %{kernel_prereq}
 Conflicts: %{kernel_dot_org_conflicts}
 Conflicts: %{package_conflicts}
@@ -158,13 +163,12 @@
 # a correct but undesirable perl dependency from the module headers which
 # isn't required for the kernel proper to function
 AutoReqProv: no
-Requires: udev >= 039-10.FC3.7
 
 #
 # List the packages used during the kernel build
 #
 BuildPreReq: module-init-tools, patch >= 2.5.4, bash >= 2.03, sh-utils, tar
-BuildPreReq: bzip2, findutils, gzip, m4, perl, make >= 3.78, gnupg
+BuildPreReq: bzip2, findutils, gzip, m4, perl, make >= 3.78, gnupg, diffutils
 BuildRequires: gcc >= 3.4.2, binutils >= 2.12, redhat-rpm-config
 BuildConflicts: rhbuildsys(DiskFree) < 500Mb
 
@@ -175,114 +179,115 @@
 Source11: genkey
 
 Source20: kernel-%{kversion}-i586.config
-Source21: kernel-%{kversion}-i586-smp.config
-Source22: kernel-%{kversion}-i686.config
-Source23: kernel-%{kversion}-i686-smp.config
-Source25: kernel-%{kversion}-x86_64.config
-Source26: kernel-%{kversion}-x86_64-smp.config
-Source27: kernel-%{kversion}-ppc64.config
-Source28: kernel-%{kversion}-ppc64iseries.config
-Source29: kernel-%{kversion}-s390.config
-Source30: kernel-%{kversion}-s390x.config
-#Source31: kernel-%{kversion}-sparc.config
-#Source32: kernel-%{kversion}-sparc64.config
-#Source33: kernel-%{kversion}-sparc64-smp.config
-Source34: kernel-%{kversion}-ppc.config
-Source34: kernel-%{kversion}-ppc-smp.config
-Source36: kernel-%{kversion}-ia64.config
-
+Source21: kernel-%{kversion}-i686.config
+Source22: kernel-%{kversion}-i686-smp.config
+Source23: kernel-%{kversion}-x86_64.config
+Source24: kernel-%{kversion}-x86_64-smp.config
+Source25: kernel-%{kversion}-ppc64.config
+Source26: kernel-%{kversion}-ppc64iseries.config
+Source27: kernel-%{kversion}-s390.config
+Source28: kernel-%{kversion}-s390x.config
+#Source29: kernel-%{kversion}-sparc.config
+#Source30: kernel-%{kversion}-sparc64.config
+#Source31: kernel-%{kversion}-sparc64-smp.config
+Source32: kernel-%{kversion}-ppc.config
+Source33: kernel-%{kversion}-ppc-smp.config
+Source34: kernel-%{kversion}-ia64.config
 
 #
 # Patches 0 through 100 are meant for core subsystem upgrades
 #
-Patch1: patch-2.6.11.12.bz2
+Patch1: patch-2.6.12.2.bz2
 
 # Patches 100 through 500 are meant for architecture patches
 
-# 200 - 300   x86(-64)
+# 200 - 299   x86(-64)
 
-Patch210: linux-2.6.10-x86-tune-p4.patch
-Patch211: linux-2.6.11-x86_64-pmdpud-race.patch
-Patch212: linux-2.6.11-x86_64-badpmd-debug.patch
-Patch214: linux-2.6.11-x86_64-more-debug.patch
+Patch200: linux-2.6.10-x86-tune-p4.patch
 
-
-# 300 - 330   ppc(64)
+# 300 - 399   ppc(64)
 Patch300: linux-2.6.2-ppc64-build.patch
 Patch301: linux-2.6.8-ppc64-netboot.patch
 Patch302: linux-2.6.10-ppc-headerabuse.patch
+Patch303: linux-2.6.11-ppc32-pmac-sleep-fix.patch
+Patch304: linux-2.6.11-cpufreq-add-suspend.patch
+Patch305: linux-2.6.11-ppc32-750-erratum-fix.patch
+Patch306: linux-2.6.11-ppc32-pbook-clock-spreading.patch
+Patch307: linux-2.6.11-mac-mini-sound.patch
+Patch308: linux-2.6.11-pmac-volume-save.patch
+Patch309: linux-2.6.11-pmac-ide-sleep.patch
+Patch310: linux-2.6.11-kallsyms-extra-text.patch
+Patch311: linux-2.6.12rc-ppc32-clockspreading-fix.patch
+
+# 400 - 499   ia64
+Patch400: linux-2.6.3-ia64-build.patch
+
+# 500 - 599   s390(x)
+Patch500: linux-2.6.1-s390-compile.patch
+Patch501: linux-2.6.9-s390-autoraid.patch
+Patch502: linux-2.6.9-s390-zfcp_port-fix.patch
 
-# 330 - 350   ia64
-Patch330: linux-2.6.3-ia64-build.patch
-
-# 350 - 400   s390(x)
-Patch350: linux-2.6.1-s390-compile.patch
-Patch351: linux-2.6.9-s390-autoraid.patch
-Patch353: linux-2.6.9-s390-zfcp_port-fix.patch
-Patch360: linux-2.6.9-s390-qeth_hipersocket-fix.patch
-
-# 400 - sparc(64)
-Patch400: linux-2.6.3-sparc-addbzimage.patch
+# 600 - 699   sparc(64)
+Patch600: linux-2.6.3-sparc-addbzimage.patch
 
 #
 # Patches 500 through 1000 are reserved for bugfixes to the core system
 # and patches related to how RPMs are build
 #
-Patch500: linux-2.4.0-nonintconfig.patch
-Patch511: linux-2.6.11-exec-shield.patch
-Patch512: linux-2.6.10-x86_64-read-implies-exec32.patch
+Patch800: linux-2.4.0-nonintconfig.patch
+Patch801: linux-2.6.0-must_check.patch
+
+Patch810: linux-2.6.11-execshield.patch
+Patch811: linux-2.6.10-x86_64-read-implies-exec32.patch
+Patch813: linux-2.6.11-execshield-vdso.patch
 
-Patch530: linux-2.6.0-must_check.patch
 # Module signing infrastructure.
-Patch600: linux-2.6.7-modsign-core.patch
-Patch601: linux-2.6.7-modsign-crypto.patch
-Patch602: linux-2.6.7-modsign-ksign.patch
-Patch603: linux-2.6.7-modsign-mpilib.patch
-Patch604: linux-2.6.7-modsign-script.patch
-Patch605: linux-2.6.7-modsign-include.patch
-Patch606: linux-2.6.9-sha1.patch
+Patch900: linux-2.6.7-modsign-core.patch
+Patch901: linux-2.6.7-modsign-crypto.patch
+Patch902: linux-2.6.7-modsign-ksign.patch
+Patch903: linux-2.6.7-modsign-mpilib.patch
+Patch904: linux-2.6.7-modsign-script.patch
+Patch905: linux-2.6.7-modsign-include.patch
 
 # Tux http accelerator.
-Patch700: linux-2.6.11-tux.patch
+Patch910: linux-2.6.11-tux.patch
 
 #
 # Patches 1000 to 5000 are reserved for bugfixes to drivers and filesystems
 #
 Patch1000: linux-2.4.0-test11-vidfail.patch
 Patch1010: linux-2.6.10-periodic-slab-debug.patch
+Patch1011: linux-2.6.11-slab-backtrace.patch
 Patch1020: linux-2.6.4-stackusage.patch
 
-Patch1050: linux-2.6.12-devmem.patch
-Patch1051: linux-2.6.11-devmem.patch
+Patch1050: linux-2.6.11-devmem.patch
 
 Patch1060: linux-2.6.3-crash-driver.patch
 Patch1070: linux-2.6.0-sleepon.patch
 
 # SCSI bits.
-Patch1130: linux-2.6.10-scsi-blacklist.patch
-Patch1131: linux-2.6.9-scsi-advansys-enabler.patch
-Patch1132: linux-2.6.11-scsi-st_ioctl-CAP_ADMIN.patch
-Patch1133: linux-2.6.11-scsi-queue-lock.patch
-Patch1134: linux-2.6.11-scsi-aacraid-openoops.patch
-Patch1135: linux-2.6.11-scsi-gfp-fix.patch
-Patch1136: linux-2.6.9-scsi-megaraid-legacy.patch
+Patch1101: linux-2.6.9-scsi-advansys-enabler.patch
+Patch1102: linux-2.6.9-scsi-megaraid-legacy.patch
+Patch1103: linux-2.6.12-scsi-blacklist.patch
+Patch1104: linux-2.6.12-scsicam-geom-fix.patch
 
 # NFS bits.
-Patch1201: linux-2.6.9-NFSD-non-null-getxattr.patch
-Patch1207: linux-2.6.8-lockd-racewarn2.patch
-Patch1209: linux-2.6.9-lockd-block-nosleep.patch
-Patch1210: linux-2.6.9-lockd-reclaims.patch
-
-Patch1300: linux-2.6.11-net-conntrack-leak.patch
-Patch1301: linux-2.6.11-net-conntrack-checksum-unnecessary.patch
+Patch1200: linux-2.6.9-NFSD-non-null-getxattr.patch
+Patch1201: linux-2.6.8-lockd-racewarn2.patch
+Patch1202: linux-2.6.9-lockd-block-nosleep.patch
+Patch1203: linux-2.6.9-lockd-reclaims.patch
 
 # NIC driver updates
-Patch1351: linux-2.6.9-net-tr-irqlock-fix.patch
-Patch1362: linux-2.6.9-net-airo-nullptr.patch
+Patch1300: linux-2.6.9-net-tr-irqlock-fix.patch
+Patch1301: linux-2.6.12-net-sundance-ip100A.patch
+Patch1302: linux-2.6.12-net-make-orinoco-suck-less.patch
+Patch1304: linux-2.6.12-net-atm-lanai-nodev-rmmod.patch
+Patch1305: linux-2.6.12-net-conntrack-bridge-fix.patch
 
 # USB bits
-Patch1400: linux-2.6.10-usb-use_both_schemes.patch
-Patch1401: linux-2.6.11-usb-aggressive-init-retry.patch
+Patch1400: linux-2.6.12-usb-old_scheme_first.patch
+Patch1401: linux-2.6.12-rc3-ehci-misc-updates.patch
+Patch1402: linux-2.6.11-random-ehci-patch.patch
 
 # Netdump and Diskdump bits.
 Patch1500: linux-2.6.10-crashdump-common.patch
@@ -291,17 +296,34 @@
 Patch1503: linux-2.6.10-diskdump.patch
 
 # Misc bits.
+Patch1600: linux-2.6.11-i2c-config.patch
+Patch1610: linux-2.6.11-atkbd-dell-multimedia.patch
+Patch1620: linux-2.6.11-isdn-icn-nodev.patch
+Patch1640: linux-2.6.11-panic-stackdump.patch
+Patch1650: linux-2.6.11-acpi-thinkpad-c2c3.patch
 Patch1700: linux-2.6.10-revert-module-invalidparam.patch
-Patch1710: linux-2.6.11-panic-stackdump.patch
-Patch1720: linux-2.6.10-ac11-firewire-fixes.patch
+Patch1710: linux-2.6.12rc-ac-ide-fixes.patch
+Patch1711: linux-2.6-ide-tune-locking.patch
+Patch1720: linux-2.6.9-module_version.patch
+Patch1730: linux-2.6.9-spinlock-debug-panic.patch
 Patch1740: linux-2.6.11-default-elevator.patch
-Patch1760: linux-2.6.9-module_version.patch
-Patch1910: linux-2.6.9-spinlock-debug-panic.patch
+Patch1760: linux-2.6.11-dentry-size.patch
+Patch1770: linux-2.6.11-taint-check.patch
+Patch1800: linux-2.6.11-parport-sysctl-perms.patch
+Patch1810: linux-2.6.11-libata-promise-pata-on-sata.patch
+Patch1820: linux-2.6.12-input-kill-stupid-messages.patch
+Patch1830: linux-2.6.12-audit-merge.patch
+Patch1831: linux-2.6.12-audit-git.patch
+Patch1860: linux-2.6.11-serial-tickle-nmi.patch
+Patch1870: linux-2.6.12-missing-exports.patch
+Patch1880: linux-2.6.11-radeon-backlight.patch
+Patch1890: linux-2.6.12-firedire-init-breakage.patch 
+Patch1900: linux-2.6.12-pwc-warning.patch
+Patch1910: linux-2.6.12-ns558-nodev-rmmod.patch
 
 Patch2000: linux-2.6.11-vm-taint.patch
-Patch2003: linux-2.6.9-vm-oomkiller-debugging.patch
-
-Patch2100: linux-2.6.11-ide-acfixes.patch
+Patch2001: linux-2.6.9-vm-oomkiller-debugging.patch
+Patch2002: linux-2.6.12-vm-singlebiterror.patch
 
 Patch2999: linux-2.6.3-printopen.patch
 
@@ -309,9 +331,6 @@
 # External drivers that are about to get accepted upstream
 #
 
-# PWC webcam driver
-Patch3000: linux-2.6.11-pwc.patch
-
 # Intel Centrino wireless drivers.
 Patch3020: linux-2.6.9-ipw2100.patch
 Patch3021: linux-2.6.9-ipw2200.patch
@@ -337,6 +356,18 @@
 of the operating system:  memory allocation, process allocation, device
 input and output, etc.
 
+%package devel
+Summary: Development package for building kernel modules to match the kernel.
+Group: System Environment/Kernel
+AutoReqProv: no
+Provides: kernel-devel-%{_target_cpu} = %{rpmversion}-%{release}
+Prereq: /usr/sbin/hardlink, /usr/bin/find
+
+%description devel
+This package provides kernel headers and makefiles sufficient to build modules
+against the kernel package.
+
+
 %package doc
 Summary: Various documentation bits found in the kernel source.
 Group: Documentation
@@ -356,6 +387,7 @@
 Group: System Environment/Kernel
 Provides: kernel = %{version}
 Provides: kernel-drm = 4.3.0
+Provides: kernel-%{_target_cpu} = %{rpmversion}-%{release}smp
 Prereq: %{kernel_prereq}
 Conflicts: %{kernel_dot_org_conflicts}
 Conflicts: %{package_conflicts}
@@ -375,9 +407,30 @@
 
 Install the kernel-smp package if your machine uses two or more CPUs.
 
-%prep
+%package smp-devel
+Summary: Development package for building kernel modules to match the SMP kernel.
+Group: System Environment/Kernel
+Provides: kernel-smp-devel-%{_target_cpu} = %{rpmversion}-%{release}
+Provides: kernel-devel-%{_target_cpu} = %{rpmversion}-%{release}smp
+Provides: kernel-devel = %{rpmversion}-%{release}smp
+AutoReqProv: no
+Prereq: /usr/sbin/hardlink, /usr/bin/find
 
+%description smp-devel
+This package provides kernel headers and makefiles sufficient to build modules
+against the SMP kernel package.
+
+%prep
+if [ ! -d kernel-%{kversion}/vanilla ]; then
 %setup -q -n %{name}-%{version} -c
+rm -f pax_global_header
+mv linux-%{kversion} vanilla
+else
+ cd kernel-%{kversion}
+fi
+rm -rf linux-%{kversion}
+cp -rl vanilla linux-%{kversion}
+
 cd linux-%{kversion}
 
 #
@@ -397,14 +450,7 @@
 # x86(-64)
 #
 # Compile 686 kernels tuned for Pentium4.
-%patch210 -p1
-# x86_64: Only free PMDs and PUDs after other CPUs have been flushed
-%patch211 -p1
-# Debug the bad pmd problem.
-%patch212 -p1
-# More debugging for teh pmd problem
-%patch214 -p1
-
+%patch200 -p1
 
 # 
 # ppc64
@@ -412,15 +458,24 @@
 
 # Patch for Kconfig and Makefile build issues
 %patch300 -p1
-%patch301 -p1
+#%patch301 -p1
 %patch302 -p1
+#%patch303 -p1
+#%patch304 -p1
+#%patch305 -p1
+#%patch306 -p1
+#%patch307 -p1
+#%patch308 -p1
+#%patch309 -p1
+#%patch310 -p1
+#%patch311 -p1
 
 #
 # ia64
 #
 
 # Basic build fixes
-%patch330 -p1
+%patch400 -p1
 
 
 #
@@ -428,18 +483,16 @@
 #
 
 # Basic build fixes
-%patch350 -p1
+%patch500 -p1
 # Auto raidstart for S390
-%patch351 -p1
+%patch501 -p1
 # Recover after aborted nameserver request.
-%patch353 -p1
-# Support broadcast on z800/z900 HiperSockets
-%patch360 -p1
+%patch502 -p1
 
 #
 # sparc/sparc64
 #
-%patch400 -p1
+%patch600 -p1
 
 #
 # Patches 500 through 1000 are reserved for bugfixes to the core system
@@ -450,36 +503,36 @@
 # This patch adds a "make nonint_oldconfig" which is non-interactive and
 # also gives a list of missing options at the end. Useful for automated
 # builds (as used in the buildsystem).
-%patch500 -p1
-
-
-#
-# The execshield patch series, broken into smaller pieces
-#
-# Exec shield core
-%patch511 -p1
-# Revert x86-64 read-implies-exec on 32 bit processes.
-%patch512 -p1 -R
+%patch800 -p1
 
 #
 # Patch that adds a __must_check attribute for functions for which checking
 # the return value is mantadory (eg copy_from_user)
 #
-%patch530 -p1
+%patch801 -p1
+
+
+# Exec shield 
+%patch810 -p1
+
+# Revert x86-64 read-implies-exec on 32 bit processes.
+%patch811 -p1 -R
+
+# Fix up the vdso.
+%patch813 -p1
 
 #
 # GPG signed kernel modules
 #
-%patch600 -p1
-%patch601 -p1
-%patch602 -p1
-%patch603 -p1
-%patch604 -p1
-%patch605 -p1
-%patch606 -p1
+%patch900 -p1
+%patch901 -p1
+%patch902 -p1
+%patch903 -p1
+%patch904 -p1
+%patch905 -p1
 
 # Tux
-%patch700 -p1
+%patch910 -p1
 
 #
 # Patches 1000 to 5000 are reserved for bugfixes to drivers and filesystems
@@ -495,6 +548,8 @@
 
 # Periodically scan slab caches for corruption.
 %patch1010 -p1
+# Stack backtrace if we find corruption.
+%patch1011 -p1
 
 #
 # Fix the extreme stack usage in some kernel functions
@@ -505,7 +560,6 @@
 # Make /dev/mem a need-to-know function 
 #
 %patch1050 -p1
-%patch1051 -p1
 
 #
 # /dev/crash driver for the crashdump analysis tool
@@ -520,50 +574,48 @@
 #
 # SCSI Bits.
 #
-# Blacklist some device
-%patch1130 -p1
 # Enable Advansys driver
-%patch1131 -p1
-# SCSI tape security: require CAP_ADMIN for SG_IO etc.
-%patch1132 -p1
-# Improved blkdev queue locking.
-%patch1133 -p1
-# fix oops in open when using adaptec tools.
-%patch1134 -p1
-# SCSI gfp flags syntax error.
-%patch1135 -p1
+%patch1101 -p1
 # Enable both new and old megaraid drivers.
-%patch1136 -p1
+%patch1102 -p1
+# Blacklist some SCSI devices that don't like having LUNs probed.
+%patch1103 -p1
+# SCSI CAM geometry fix.
+%patch1104 -p1
 
 #
 # Various upstream NFS/NFSD fixes.
 #
+%patch1200 -p1
 %patch1201 -p1
-%patch1207 -p1
-%patch1209 -p1
-%patch1210 -p1
-
-# Fix conntrack leak with raw sockets.
-%patch1300 -p1
-# Don't checksum CHECKSUM_UNNECESSARY skbs in TCP connection tracking
-%patch1301 -p1
+%patch1202 -p1
+%patch1203 -p1
 
 # NIC driver fixes.
 # Use correct spinlock functions in token ring net code
-%patch1351 -p1
-# NULL out ptrs in airo after kfree'ing them.
-%patch1362 -p1
+%patch1300 -p1
+# New PCI ID for sundance driver.
+%patch1301 -p1
+# Make orinoco driver suck less.
+%patch1302 -p1
+# Fix rmmod lanai
+%patch1304 -p1
+# Fix connection tracking bug with bridging.
+%patch1305 -p1
 
 # USB Bits.
 # Enable both old and new style USB initialisation.
 %patch1400 -p1
-# Retry more aggressively during USB device initialization
-%patch1401 -p1
+# Fix port power switching for EHCI
+#%patch1401 -p1
+# Do something else originally described as "Alan's hint for ehci"
+%patch1402 -p1
 
 # netdump bits
 %patch1500 -p1
-%patch1501 -p1
-%patch1502 -p1
+# Netdump is broken right now. It applies, but not with -F1. Its h0rked. Leave it off.
+#%patch1501 -p1
+#%patch1502 -p1
 %patch1503 -p1
 
 #
@@ -571,17 +623,54 @@
 #
 
 # Misc fixes
+# Make some I2C drivers arch dependant.
+%patch1600 -p1
+# Make multimedia buttons on Dell Inspiron 8200 work.
+%patch1610 -p1
+# ISDN ICN driver barfs if probed with no cards present.
+%patch1620 -p1
+# Print stack trace when we panic.
+%patch1640 -p1
+# Blacklist another 'No C2/C3 states' Thinkpad R40e BIOS.
+%patch1650 -p1
 # Don't barf on obsolete module parameters.
 %patch1700 -p1
-# Print stack trace when we panic.
+# Numerous IDE fixes.
 %patch1710 -p1
-# Various fixes for firewire from -mm
+%patch1711 -p1
+# Add missing MODULE_VERSION tags to some modules.
 %patch1720 -p1
-# Set CFQ as default elevator
+# Make spinlock debugging panic instead of continue.
+%patch1730 -p1
+# Make CFQ default elevator again
 %patch1740 -p1
-# Add missing MODULE_VERSION tags to some modules.
+# Adjust struct dentry size for 32/64bit.
 %patch1760 -p1
-# Make spinlock debugging panic instead of continue.
+# Check tainted bit on oops.
+%patch1770 -p1
+# Fix up some permissions in /proc
+%patch1800 -p1
+# Support PATA on Promise SATA.
+%patch1810 -p1
+# The input layer spews crap no-one cares about.
+%patch1820 -p1
+# Audit code from git tree which was imported into 2.6.12-git1
+%patch1830 -p1
+# Audit code from git tree which is still in 2.6.12-mm
+%patch1831 -p1
+# Always set nobh on ext3 volumes.
+#%patch1840 -p1
+# Tickle the NMI whilst doing serial writes.
+%patch1860 -p1
+# Missing EXPORT_SYMBOL's
+%patch1870 -p1
+# Radeon on thinkpad backlight power-management goodness.
+%patch1880 -p1
+# Fix ochi1394 smp init.
+%patch1890 -p1
+# Fix warning in pwc driver.
+%patch1900 -p1
+# Fix oops in ns558 on rmmod
 %patch1910 -p1
 
 #
@@ -590,26 +679,22 @@
 # Display taint bits on VM error.
 %patch2000 -p1
 # Extra debugging on OOM Kill.
-%patch2003 -p1
+%patch2001 -p1
+# Spot single bit errors in slab corruption.
+%patch2002 -p1
 
-# IDE bits.
-# Numerous fixes from 2.6.11-ac7
-%patch2100 -p1
 
 #
 # Local hack (off for any shipped kernels) to printk all files opened 
 # the first 180 seconds after boot for debugging userspace startup 
 # speeds
 #
-# %patch2999 -p1
+#%patch2999 -p1
 
 #
 # External drivers that are about to get accepted upstream
 #
 
-# PWC driver
-%patch3000 -p1
-
 # Intel wireless
 %patch3020 -p1
 %patch3021 -p1
@@ -643,7 +728,7 @@
 
 
 # now run oldconfig over all the config files
-for i in *.config 
+for i in *.config
 do 
 	mv $i .config 
 	Arch=`head -1 .config | cut -b 3-`
@@ -685,8 +770,12 @@
     # Pick the right config file for the kernel we're building
     if [ -n "$1" ] ; then
 	Config=kernel-%{kversion}-%{_target_cpu}-$1.config
+	DevelDir=/usr/src/kernels/%{KVERREL}-$1-%{_target_cpu}
+	DevelLink=/usr/src/kernels/%{KVERREL}$1-%{_target_cpu}
     else
 	Config=kernel-%{kversion}-%{_target_cpu}.config
+	DevelDir=/usr/src/kernels/%{KVERREL}-%{_target_cpu}
+	DevelLink=
     fi
 
     KernelVer=%{version}-%{release}$1
@@ -712,12 +801,16 @@
     
     # Start installing the results
 
+%if "%{_enable_debug_packages}" == "1"
     mkdir -p $RPM_BUILD_ROOT/usr/lib/debug/boot
+%endif
     mkdir -p $RPM_BUILD_ROOT/%{image_install_path}
     install -m 644 .config $RPM_BUILD_ROOT/boot/config-$KernelVer
     install -m 644 System.map $RPM_BUILD_ROOT/boot/System.map-$KernelVer
     cp arch/$Arch/boot/bzImage $RPM_BUILD_ROOT/%{image_install_path}/vmlinuz-$KernelVer
-    cp arch/$Arch/boot/zImage.stub $RPM_BUILD_ROOT/%{image_install_path}/zImage.stub-$KernelVer || :
+	if [ -f arch/$Arch/boot/zImage.stub ]; then
+      cp arch/$Arch/boot/zImage.stub $RPM_BUILD_ROOT/%{image_install_path}/zImage.stub-$KernelVer || :
+	fi
 
     mkdir -p $RPM_BUILD_ROOT/lib/modules/$KernelVer
     make -s ARCH=$Arch INSTALL_MOD_PATH=$RPM_BUILD_ROOT modules_install KERNELRELEASE=$KernelVer
@@ -743,8 +836,12 @@
     cp arch/%{_arch}/kernel/asm-offsets.s $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/arch/%{_arch}/kernel || :
     cp .config $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
     cp -a scripts $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
-    cp -a arch/%{_arch}/scripts $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/arch/%{_arch} || :
-    cp -a arch/%{_arch}/*lds $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/arch/%{_arch}/ || :
+	if [ -d arch/%{_arch}/scripts ]; then
+      cp -a arch/%{_arch}/scripts $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/arch/%{_arch} || :
+	fi
+	if [ -f arch/%{_arch}/*lds ]; then
+      cp -a arch/%{_arch}/*lds $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/arch/%{_arch}/ || :
+	fi
     rm -f $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/scripts/*.o
     rm -f $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/scripts/*/*.o
     mkdir -p $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/include
@@ -760,8 +857,10 @@
     #
     # save the vmlinux file for kernel debugging into the kernel-debuginfo rpm
     #
+%if "%{_enable_debug_packages}" == "1"
     mkdir -p $RPM_BUILD_ROOT/usr/lib/debug/lib/modules/$KernelVer
     cp vmlinux $RPM_BUILD_ROOT/usr/lib/debug/lib/modules/$KernelVer
+%endif
 
     # gpg sign the modules
 %if %{signmodules}
@@ -770,8 +869,9 @@
 	KEYFLAGS="$KEYFLAGS --secret-keyring ../kernel.sec" 
 	KEYFLAGS="$KEYFLAGS --keyring ../kernel.pub" 
 	export KEYFLAGS 
-    for i in ` find $RPM_BUILD_ROOT/lib/modules/$KernelVer -name "*.ko" -type f` ; do
-	sh ./scripts/modsign/modsign.sh $i Red
+    for i in ` find $RPM_BUILD_ROOT/lib/modules/$KernelVer -name "*.ko" -type f`
+	do
+		sh ./scripts/modsign/modsign.sh $i Red
         mv -f $i.signed $i
     done
 	unset KEYFLAGS
@@ -781,12 +881,26 @@
     find $RPM_BUILD_ROOT/lib/modules/$KernelVer -name "*.ko" -type f  | xargs chmod u+x
 
     # detect missing or incorrect license tags
-    for i in `find $RPM_BUILD_ROOT/lib/modules/$KernelVer -name "*.ko" ` ; do echo -n "$i " ; /sbin/modinfo -l $i >> modinfo ; done
-    cat modinfo | grep -v "^GPL" | grep -v "^Dual BSD/GPL" | grep -v "^Dual MPL/GPL" | grep -v "^GPL and additional rights" | grep -v "^GPL v2" && exit 1 
+    for i in `find $RPM_BUILD_ROOT/lib/modules/$KernelVer -name "*.ko" `
+	do
+		echo -n "$i " 
+		/sbin/modinfo -l $i >> modinfo
+	done
+    cat modinfo |\
+		grep -v "^GPL" |
+		grep -v "^Dual BSD/GPL" |\
+		grep -v "^Dual MPL/GPL" |\
+		grep -v "^GPL and additional rights" |\
+		grep -v "^GPL v2" && exit 1 
     rm -f modinfo
     # remove files that will be auto generated by depmod at rpm -i time
     rm -f $RPM_BUILD_ROOT/lib/modules/$KernelVer/modules.*
 
+    # Move the devel headers out of the root file system
+    mkdir -p $RPM_BUILD_ROOT/usr/src/kernels
+    mv $RPM_BUILD_ROOT/lib/modules/$KernelVer/build $RPM_BUILD_ROOT/$DevelDir
+    ln -sf ../../..$DevelDir $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
+    [ -z "$DevelLink" ] || ln -sf `basename $DevelDir` $RPM_BUILD_ROOT/$DevelLink
 }
 
 ###
@@ -847,10 +961,24 @@
 [ ! -x /usr/sbin/module_upgrade ] || /usr/sbin/module_upgrade
 [ -x /sbin/new-kernel-pkg ] && /sbin/new-kernel-pkg --package kernel --mkinitrd --depmod --install %{KVERREL}
 
+%post devel
+if [ -x /usr/sbin/hardlink ] ; then
+pushd /usr/src/kernels/%{KVERREL}-%{_target_cpu} > /dev/null
+/usr/bin/find . -type f | while read f; do hardlink -c /usr/src/kernels/*FC*/$f $f ; done
+popd > /dev/null
+fi
+
 %post smp
 [ ! -x /usr/sbin/module_upgrade ] || /usr/sbin/module_upgrade
 [ -x /sbin/new-kernel-pkg ] && /sbin/new-kernel-pkg --package kernel-smp --mkinitrd --depmod --install %{KVERREL}smp
 
+%post smp-devel
+if [ -x /usr/sbin/hardlink ] ; then
+pushd /usr/src/kernels/%{KVERREL}-smp-%{_target_cpu} > /dev/null
+/usr/bin/find . -type f | while read f; do hardlink -c /usr/src/kernels/*FC*/$f $f ; done
+popd > /dev/null
+fi
+
 
 %preun 
 /sbin/modprobe loop 2> /dev/null > /dev/null  || :
@@ -860,7 +988,6 @@
 /sbin/modprobe loop 2> /dev/null > /dev/null  || :
 [ -x /sbin/new-kernel-pkg ] && /sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{KVERREL}smp
 
-
 ###
 ### file lists
 ###
@@ -873,7 +1000,12 @@
 /boot/config-%{KVERREL}
 %dir /lib/modules/%{KVERREL}
 /lib/modules/%{KVERREL}/kernel
-%verify(not mtime) /lib/modules/%{KVERREL}/build
+/lib/modules/%{KVERREL}/build
+/lib/modules/%{KVERREL}/source
+
+%files devel
+%defattr(-,root,root)
+%verify(not mtime) /usr/src/kernels/%{KVERREL}-%{_target_cpu}
 %endif
 
 %if %{buildsmp}
@@ -884,112 +1016,373 @@
 /boot/config-%{KVERREL}smp
 %dir /lib/modules/%{KVERREL}smp
 /lib/modules/%{KVERREL}smp/kernel
-%verify(not mtime) /lib/modules/%{KVERREL}smp/build
-%endif
+/lib/modules/%{KVERREL}smp/build
+/lib/modules/%{KVERREL}smp/source
 
+%files smp-devel
+%defattr(-,root,root)
+%verify(not mtime) /usr/src/kernels/%{KVERREL}-smp-%{_target_cpu}
+/usr/src/kernels/%{KVERREL}smp-%{_target_cpu}
+%endif
 
 # only some architecture builds need kernel-doc
 
 %if %{builddoc}
 %files doc
 %defattr(-,root,root)
-/usr/share/doc/kernel-doc-%{kversion}/Documentation/*
+%{_datadir}/doc/kernel-doc-%{kversion}/Documentation/*
+%dir %{_datadir}/doc/kernel-doc-%{kversion}/Documentation
+%dir %{_datadir}/doc/kernel-doc-%{kversion}
 %endif
 
 %changelog
-* Mon Jun 13 2005 Dave Jones <davej at redhat.com>
-- Rebase to 2.6.11.12
+* Tue Jul 12 2005 Dave Jones <davej at redhat.com>
+- Fix up several reports of CD's causing crashes
+- Fix connection tracking bug with bridging.
+
+* Mon Jul 11 2005 Dave Jones <davej at redhat.com>
+- Bump selinux policy requires again.
+- Fix up locking in piix IDE driver whilst tuning chipset.
+
+* Tue Jul  5 2005 Dave Jones <davej at redhat.com>
+- Fixup ACPI problem that prevented boot for some folks.
+- Fix up selinux policy requires:
+
+* Fri Jul  1 2005 Dave Jones <davej at redhat.com>
+- 2.6.12.2
 
-* Fri Jun 10 2005 Dave Jones <davej at redhat.com>
-- Fix up TASK_SIZE thinko in execshield patch. (#160097)
+* Mon Jun 27 2005 Dave Jones <davej at redhat.com>
+- Finalise 2.6.12 port to FC3
 
 * Fri Jun  3 2005 Dave Jones <davej at redhat.com>
-- Don't checksum CHECKSUM_UNNECESSARY skbs in TCP connection tracking. (#158710)
+- Begin 2.6.12rc5 port to FC3
 
 * Wed Jun  1 2005 Dave Jones <davej at redhat.com>
-- Exec-shield improvements (Should fix #154759)
+- Fix up ALI IDE regression. (#157175)
 
-* Tue May 31 2005 Dave Jones <davej at redhat.com>
-- Rebase to 2.6.11.11
+* Mon May 30 2005 Dave Jones <davej at redhat.com>
+- Fix up VIA IRQ quirk.
 
-* Thu May 19 2005 Dave Jones <davej at redhat.com>
-- Fix syntactical error in GFP flag usage in SCSI layer.
+* Sun May 29 2005 Dave Jones <davej at redhat.com>
+- Fix slab corruption in firewire (#158424)
 
-* Tue May 17 2005 Dave Jones <davej at redhat.com> [2.6.11-1.27_FC3]
-- Remove the unused (and outdated) Xen patches from the FC3 tree.
+* Fri May 27 2005 Dave Jones <davej at redhat.com>
+- remove non-cleanroom pwc driver compression.
+- Fix unintialised value in single bit error detector. (#158825)
+
+* Wed May 25 2005 Dave Jones <davej at redhat.com>
+- Disable TPM driver, it breaks 8139 driver.
+- Revert to previous version of ipw2x00 drivers.
+  The newer ones sadly brought too many problems this close to
+  the release. I'll look at updating them again for an update.
+- Update to 2.6.12rc5
+  Fix potential local DoS. 1-2 other small fixes.
+- Tweak to fix up some vdso arithmetic.
+- Disable sysenter again for now.
+
+* Wed May 25 2005 David Woodhouse <dwmw2 at redhat.com>
+- Turn off CONFIG_ISA on PPC again. It makes some Macs unhappy (#149200)
+- Make Speedtouch DSL modem resync automatically
+
+* Tue May 24 2005 Dave Jones <davej at redhat.com>
+- Update various cpufreq drivers.
+- 2.6.12-rc4-git8
+  kobject ordering, tg3 fixes, ppc32 ipic fix,
+  ppc64 powermac smp fix. token-ring fixes,
+  TCP fix. ipv6 fix.
+- Disable slab debugging.
+
+* Mon May 23 2005 Dave Jones <davej at redhat.com>
+- Add extra id to SATA Sil driver. (#155748)
+- Fix oops on rmmod of lanai & ms558 drivers when no hardware present.
+
+* Mon May 23 2005 Dave Jones <davej at redhat.com>
+- Fix double unlock of spinlock on tulip. (#158522)
+
+* Mon May 23 2005 David Woodhouse <dwmw2 at redhat.com>
+- audit updates: log serial # in user messages, escape comm= in syscalls
+
+* Mon May 23 2005 Dave Jones <davej at redhat.com>
+- 2.6.12-rc4-git6
+  MMC update, reiserfs fixes, AIO fix.
+- Fix absolute symlink in -devel (#158582)
+- 2.6.12-rc4-git7
+  PPC64 & i2c fixes
+- Fix another divide by zero in ipw2100 (#158406)
+- Fix dir ownership in kernel-doc rpm (#158478)
+
+* Sun May 22 2005 Dave Jones <davej at redhat.com>
+- Fix divide by zero in ipw2100 driver. (#158406)
+- 2.6.12-rc4-git5
+  More x86-64 updates, Further pktcdvd frobbing,
+  yet more dvb updates, x86(64) ioremap fixes,
+  ppc updates, IPMI sysfs support (reverted for now due to breakage),
+  various SCSI fixes (aix7xxx, spi transport), vmalloc improvements
+
+* Sat May 21 2005 David Woodhouse <dwmw2 at redhat.com>
+- Fix oops in avc_audit() (#158377)
+- Include serial numbers in non-syscall audit messages
+
+* Sat May 21 2005 Bill Nottingham <notting at redhat.com>
+- bump ipw2200 conflict
+
+* Sat May 21 2005 Dave Jones <davej at redhat.com> [2.6.11-1.1334_FC4]
+- driver core: restore event order for device_add()
+
+* Sat May 21 2005 David Woodhouse <dwmw2 at redhat.com>
+- More audit updates. Including a fix for AVC_USER messages.
+
+* Fri May 20 2005 Dave Jones <davej at redhat.com>
+- 2.6.12-rc4-git4
+  networking fixes (netlink, pkt_sched, ipsec, netfilter,
+  ip_vs, af_unix, ipv4/6, xfrm). TG3 driver improvements.
+
+* Thu May 19 2005 Dave Jones <davej at redhat.com> [2.6.11-1.1327_FC4]
+- 2.6.12-rc4-git3
+  Further fixing to raw driver. More DVB updates,
+  driver model updates, power management improvements,
+  ext3 fixes.  
+- Radeon on thinkpad backlight power-management goodness.
+  (Peter Jones owes me two tacos).
+- Fix ieee1394 smp init.
+
+* Thu May 19 2005 Rik van Riel <riel at redhat.com>
+- Xen: disable TLS warning (#156414)
+
+* Thu May 19 2005 David Woodhouse <dwmw2 at redhat.com>
+- Update audit patches
+
+* Thu May 19 2005 Dave Jones <davej at redhat.com> [2.6.11-1.1325_FC4]
+- Fix up missing symbols in ipw2200 driver.
+- Reenable debugfs / usbmon. SELinux seems to cope ok now.
+  (Needs selinux-targeted-policy >= 1.23.16-1)
+
+* Wed May 18 2005 Dave Jones <davej at redhat.com>
+- Fix up some warnings in the IDE patches.
+- 2.6.12-rc4-git2
+  Further pktcdvd fixing, DVB update, Lots of x86-64 updates,
+  ptrace fixes, ieee1394 changes, input layer tweaks,
+  md layer fixes, PCI hotplug improvements, PCMCIA fixes,
+  libata fixes, serial layer, usb core, usbnet, VM fixes,
+  SELinux tweaks.
+- Update ipw2100 driver to 1.1.0
+- Update ipw2200 driver to 1.0.4 (#158073)
+
+* Tue May 17 2005 Dave Jones <davej at redhat.com>
+- 2.6.12-rc4-git1
+  ARM, ioctl security fixes, mmc driver update,
+  ibm_emac & tulip netdriver fixes, serial updates
+  ELF loader security fix.
+
+* Mon May 16 2005 Rik van Riel <riel at redhat.com>
+- enable Xen again (not tested yet)
+- fix a typo in the EXPORT_SYMBOL patch
+
+* Sat May 14 2005 Dave Jones <davej at redhat.com>
+- Update E1000 driver from netdev-2.6 tree. 
+- Add some missing EXPORT_SYMBOLs.
+
+* Fri May 13 2005 Dave Jones <davej at redhat.com>
+- Bump maximum supported CPUs on x86-64 to 32.
+- Tickle the NMI watchdog when we're doing serial writes.
+- SCSI CAM geometry fix.
+- Slab debug single-bit error improvement.
+
+* Thu May 12 2005 David Woodhouse <dwmw2 at redhat.com>
+- Enable CONFIG_ISA on ppc32 to make the RS/6000 user happy.
+- Update audit patches
+
+* Wed May 11 2005 Dave Jones <davej at redhat.com>
+- Add Ingo's patch to detect soft lockups.
+- Thread exits silently via __RESTORE_ALL exception for iret. (#154369)
 
-* Mon May 16 2005 Dave Jones <davej at redhat.com>
-- Rebase to 2.6.11.10, (fixing CAN-2005-1264)
+* Wed May 11 2005 David Woodhouse <dwmw2 at redhat.com>
+- Import post-rc4 audit fixes from git, including ppc syscall auditing
 
-* Thu May 12 2005 Dave Jones <davej at redhat.com>
-- Rebase to 2.6.11.9, (fixing CAN-2005-1263)
+* Wed May 11 2005 Dave Jones <davej at redhat.com>
+- Revert NMI watchdog changes.
 
 * Tue May 10 2005 Dave Jones <davej at redhat.com>
-- Fix two bugs in x86-64 page fault handler.
+- Enable PNP on x86-64
+
+* Tue May 10 2005 Jeremy Katz <katzj at redhat.com>
+- make other -devel packages provide kernel-devel so they get 
+  installed instead of upgraded (#155988)
 
 * Mon May  9 2005 Dave Jones <davej at redhat.com>
-- Rebase to 2.6.11.8
-  | Fixes CAN-2005-1368 (local DoS in key lookup). (#156680)
-  | Fixes CAN-2005-1369 (i2c alarms sysfs DoS). (#156683)
-- Merge IDE fixes from 2.6.11-ac7
-- Add Conflicts for older IPW firmwares.
-- Fix conntrack leak with raw sockets.
+- Rebase to 2.6.12-rc4
+  | Xen builds are temporarily disabled again.
+- Conflict if old version of ipw firmware is present.
 
-* Sun May  1 2005 Dave Jones <davej at redhat.com>
-- Various firewire fixes backported from -mm. (#133798)
-  (Thanks to Jody McIntyre for doing this)
+* Fri May  6 2005 Dave Jones <davej at redhat.com>
+- Add PCI ID for new sundance driver. (#156859)
+
+* Thu May  5 2005 David Woodhouse <dwmw2 at redhat.com>
+- Import audit fixes from upstream
+
+* Wed May  4 2005 Jeremy Katz <katzj at redhat.com>
+- enable radeonfb and agp on ppc64 to fix X on the G5
+
+* Tue May  3 2005 Dave Jones <davej at redhat.com>
+- Disable usbmon/debugfs again for now until SELinux policy is fixed.
 
-* Fri Apr 29 2005 Dave Jones <davej at redhat.com>
-- fix oops in aacraid open when using adaptec tools. (#148761)
+* Mon May  2 2005 David Woodhouse <dwmw2 at redhat.com>
+- Make kallsyms include platform-specific symbols
+- Fix might_sleep warning in pbook clock-spreading fix
+
+* Sun May  1 2005 Dave Jones <davej at redhat.com>
+- Fix yesterdays IDE fixes.
 - Blacklist another brainless SCSI scanner. (#155457)
 
-* Thu Apr 21 2005 Dave Jones <davej at redhat.com>
-- Fix up SCSI queue locking. (#155472)
+* Sun May  1 2005 David Woodhouse <dwmw2 at redhat.com>
+- Fix EHCI port power switching
+
+* Sun May  1 2005 Dave Jones <davej at redhat.com>
+- Enable usbmon & debugfs. (#156489)
+
+* Sat Apr 30 2005 Dave Jones <davej at redhat.com>
+- Numerous IDE layer fixes from Alan Cox.
+- Kill off some stupid messages from the input layer.
+
+* Fri Apr 29 2005 Roland McGrath <roland at redhat.com>
+- Fix the 32bit emulation on x86-64 segfaults.
+
+* Wed Apr 27 2005 Dave Jones <davej at redhat.com>
+- Hopefully fix the random reboots some folks saw on x86-64.
+
+* Wed Apr 27 2005 Jeremy Katz <katzj at redhat.com>
+- fix prereqs for -devel packages
+
+* Wed Apr 27 2005 Rik van Riel <riel at redhat.com>
+- Fix up the vdso stuff so kernel-xen* compile again
+- Import upstream bugfix so xenU domains can be started again
+
+* Tue Apr 26 2005 Dave Jones <davej at redhat.com>
+- Fix up the vdso again, which broke on the last rebase to -rc3
+- Fix the put_user() fix. (#155999)
+
+* Mon Apr 25 2005 Dave Jones <davej at redhat.com>
+- Fix x86-64 put_user()
+- Fix serio oops.
+- Fix ipv6_skip_exthdr() invocation causing OOPS.
+- Fix up some permissions on some /proc files.
+- Support PATA drives on Promise SATA. (#147303)
+
+* Mon Apr 25 2005 Rik van Riel <riel at redhat.com>
+- upgrade to the latest version of xenolinux patches
+- reenable xen (it boots, ship it!)
+
+* Sat Apr 23 2005 David Woodhouse <dwmw2 at redhat.com>
+- Enable adt746x and windtunnel thermal modules
+- Disable clock spreading on certain pbooks before sleep
+- Sound support for Mac Mini
+
+* Fri Apr 22 2005 Dave Jones <davej at redhat.com>
+- Reenable i2c-viapro on x86-64.
+
+* Fri Apr 22 2005 Dave Jones <davej at redhat.com>
+- Don't build powernow-k6 on anything other than 586 kernels.
+- Temporarily disable Xen again.
+
+* Wed Apr 20 2005 Dave Jones <davej at redhat.com>
+- 2.6.12rc3
+
+* Wed Apr 20 2005 Dave Jones <davej at redhat.com>
+- Adjust struct dentry 'padding' based on 64bit'ness.
 
 * Tue Apr 19 2005 Dave Jones <davej at redhat.com>
-- SCSI tape security: require CAP_ADMIN for SG_IO etc. (#155355)
+- Print stack trace when we panic.
+  Might give more clues for some of the wierd panics being seen right now.
+- Blacklist another 'No C2/C3 states' Thinkpad R40e BIOS. (#155236)
 
 * Mon Apr 18 2005 Dave Jones <davej at redhat.com>
-- Retry more aggressively during USB device initialization
+- Make ISDN ICN driver not oops when probed with no hardware present.
+- Add missing MODULE_LICENSE to mac_modes.ko
+
+* Sat Apr 16 2005 Dave Jones <davej at redhat.com>
+- Make some i2c drivers arch dependant.
+- Make multimedia buttons on Dell inspiron 8200 work. (#126148)
+- Add diffutils buildreq (#155121)
 
 * Thu Apr 14 2005 Dave Jones <davej at redhat.com>
 - Build DRM modular. (#154769)
 
+* Wed Apr 13 2005 Rik van Riel <riel at redhat.com>
+- fix up Xen for 2.6.12-rc2
+- drop arch/xen/i386/signal.c, thanks to Roland's vdso patch (yay!)
+- reenable xen compile - this kernel test boots on my system
+
+* Tue Apr 12 2005 Dave Jones <davej at redhat.com>
+- Further vdso work from Roland.
+
+* Mon Apr 11 2005 David Woodhouse <dwmw2 at redhat.com>
+- Disable PPC cpufreq/sleep patches which make sleep less reliable
+- Add TIMEOUT to hotplug environment when requesting firmware (#153993)
+
+* Sun Apr 10 2005 Dave Jones <davej at redhat.com>
+- Integrate Roland McGrath's changes to make exec-shield
+  and vdso play nicely together.
+
 * Fri Apr  8 2005 Dave Jones <davej at redhat.com>
 - Disable Longhaul driver (again).
 
-* Thu Apr  7 2005 Dave Jones <davej at redhat.com> [2.6.11-1.14_FC3]
-- Update to 2.6.11.7
-- Set CFQ as default elevator again.
-
-* Wed Apr  5 2005 Dave Jones <davej at redhat.com>
-- Disable slab debug.
-- Re-add the pwc driver. (#152593)
-
-* Wed Mar 30 2005 Dave Jones <davej at redhat.com>
-- x86_64: Only free PMDs and PUDs after other CPUs have been flushed
+* Wed Apr  6 2005 Dave Jones <davej at redhat.com>
+- 2.6.12rc2
+  - netdump/netconsole currently broken.
+  - Xen temporarily disabled.
+
+* Fri Apr  1 2005 Dave Jones <davej at redhat.com>
+- Make the CFQ elevator the default again.
+
+* Thu Mar 31 2005 Rik van Riel <riel at redhat.com>
+- upgrade to new upstream Xen code, twice 
+- for performance reasons, disable CONFIG_DEBUG_PAGEALLOC for FC4t2
+
+* Wed Mar 30 2005 Rik van Riel <riel at redhat.com>
+- fix Xen kernel compilation (pci, page table, put_user, execshield, ...)
+- reenable Xen kernel compilation
+
+* Tue Mar 29 2005 Rik van Riel <riel at redhat.com>
+- apply Xen patches again (they don't compile yet, though)
+- Use uname in kernel-devel directories (#145914)
+- add uname-based kernel-devel provisions (#152357)
+- make sure /usr/share/doc/kernel-doc-%%{kversion} is owned by a
+  package, so it will get removed again on uninstall/upgrade (#130667)
+
+* Mon Mar 28 2005 Dave Jones <davej at redhat.com>
+- Don't generate debuginfo files if %%_enable_debug_packages isnt set. (#152268)
+
+* Sun Mar 27 2005 Dave Jones <davej at redhat.com>
+- 2.6.12rc1-bk2
+- Disable NVidia FB driver for time being, it isn't stable.
 
-* Sat Mar 26 2005 Dave Jones <davej at redhat.com>
-- Update to 2.6.11.6
+* Thu Mar 24 2005 Dave Jones <davej at redhat.com>
+- rebuild
 
 * Tue Mar 22 2005 Dave Jones <davej at redhat.com>
-- Fix up several calls to memset with swapped arguments.
-
-* Sat Mar 19 2005 Dave Jones <davej at redhat.com>
-- Update to 2.6.11.5
+- Fix several instances of swapped arguments to memset()
+- 2.6.12rc1-bk1
 
 * Fri Mar 18 2005 Dave Jones <davej at redhat.com>
-- Kjournald oops race. (#146344)
+- kjournald release race. (#146344)
+- 2.6.12rc1
 
-* Tue Mar 15 2005 Dave Jones <davej at redhat.com>
-- Update to 2.6.11.4
+* Thu Mar 17 2005 Rik van Riel <riel at redhat.com>
+- upgrade to latest upstream Xen code
+
+* Tue Mar 15 2005 Rik van Riel <riel at redhat.com>
+- add Provides: headers for external kernel modules (#149249)
+- move build & source symlinks from kernel-*-devel to kernel-* (#149210)
+- fix xen0 and xenU devel %%post scripts to use /usr/src/kernels (#149210)
 
 * Thu Mar 10 2005 Dave Jones <davej at redhat.com>
-- Update to 2.6.11.2
 - Reenable advansys driver for x86
 
-* Sun Mar  6 2005 Dave Jones <davej at redhat.com> [2.6.11-1.1_FC3]
-- FC3 build.
+* Tue Mar  8 2005 Dave Jones <davej at redhat.com>
+- Change SELinux execute-related permission checking. (#149819)
+
+* Sun Mar  6 2005 Dave Jones <davej at redhat.com>
+- Forward port some FC3 patches that got lost.
 
 * Fri Mar  4 2005 Dave Jones <davej at redhat.com>
 - Fix up ACPI vs keyboard controller problem.


Index: sources
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/sources,v
retrieving revision 1.127
retrieving revision 1.128
diff -u -r1.127 -r1.128
--- sources	13 Jun 2005 04:35:57 -0000	1.127
+++ sources	13 Jul 2005 04:16:28 -0000	1.128
@@ -1,2 +1,2 @@
-f00fd1b5a80f52baf9d1d83acddfa325  linux-2.6.11.tar.bz2
-ab25e6cd997d4aa17b73300c781efecc  patch-2.6.11.12.bz2
+c5d2a1b62e1dad502c871bba267337d5  linux-2.6.12.tar.bz2
+3a4225e9dff9d6d03da41327e972f161  patch-2.6.12.2.bz2


Index: upstream
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/upstream,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- upstream	13 Jun 2005 04:35:57 -0000	1.31
+++ upstream	13 Jul 2005 04:16:28 -0000	1.32
@@ -1,2 +1,3 @@
-linux-2.6.11.tar.bz2
-patch-2.6.11.12.bz2
+linux-2.6.12.tar.bz2
+patch-2.6.12.2.bz2
+


--- linux-2.6.10-ac11-firewire-fixes.patch DELETED ---


--- linux-2.6.10-scsi-blacklist.patch DELETED ---


--- linux-2.6.10-usb-use_both_schemes.patch DELETED ---


--- linux-2.6.11-exec-shield.patch DELETED ---


--- linux-2.6.11-ide-acfixes.patch DELETED ---


--- linux-2.6.11-net-conntrack-checksum-unnecessary.patch DELETED ---


--- linux-2.6.11-net-conntrack-leak.patch DELETED ---


--- linux-2.6.11-pwc.patch DELETED ---


--- linux-2.6.11-scsi-aacraid-openoops.patch DELETED ---


--- linux-2.6.11-scsi-gfp-fix.patch DELETED ---


--- linux-2.6.11-scsi-queue-lock.patch DELETED ---


--- linux-2.6.11-scsi-st_ioctl-CAP_ADMIN.patch DELETED ---


--- linux-2.6.11-usb-aggressive-init-retry.patch DELETED ---


--- linux-2.6.11-x86_64-badpmd-debug.patch DELETED ---


--- linux-2.6.11-x86_64-more-debug.patch DELETED ---


--- linux-2.6.11-x86_64-pmdpud-race.patch DELETED ---


--- linux-2.6.11.tar.bz2.sign DELETED ---


--- linux-2.6.12-devmem.patch DELETED ---


--- linux-2.6.9-ide-cd-early-EOF.patch DELETED ---


--- linux-2.6.9-net-airo-nullptr.patch DELETED ---


--- linux-2.6.9-s390-qeth_hipersocket-fix.patch DELETED ---


--- linux-2.6.9-sha1.patch DELETED ---


--- patch-2.6.11.11.bz2.sign DELETED ---


--- patch-2.6.11.12.bz2.sign DELETED ---


--- patch-2.6.11.9.bz2.sign DELETED ---




More information about the fedora-cvs-commits mailing list