Current feisty/upstream delta

Ben Collins ben.collins at ubuntu.com
Tue Apr 17 16:32:16 UTC 2007


These are the patches that are left to be merged in a branch for pushing
to Linus during the 2.6.22 window.

Quick glance:

- DSDT-initramfs patch (not ours, needs a lot of effort to get 
  upstream).
- Speakup integration. Just hold this off for now.
- toshiba_acpi: mjg59 will look into this further
- Lots of KERN_ERR->KERN_INFO changes
- tulip updates
- Disable PM messing with console.
- Disable NMI by default (kyle's patch, might not be suited for 
  upstream).

Some more tidbits in there. Ask questions here or refer to
ubuntu-feisty.git for change logs.

diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 1a6f8bb..465af04 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -221,14 +221,6 @@ static int __init check_nmi_watchdog(void)
 	unsigned int *prev_nmi_count;
 	int cpu;
 
-	/* Enable NMI watchdog for newer systems.
-	   Probably safe on most older systems too, but let's be careful.
-	   IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
-	   which hangs the system. Disable watchdog for all thinkpads */
-	if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
-		!dmi_name_in_vendors("ThinkPad"))
-		nmi_watchdog = NMI_LOCAL_APIC;
-
 	if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
 		return 0;
 
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index 43005f0..1c553c8 100644
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -112,7 +112,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
 				pr = pci_find_parent_resource(dev, r);
 				if (!r->start || !pr ||
 				    request_resource(pr, r) < 0) {
-					printk(KERN_ERR "PCI: Cannot allocate "
+					printk(KERN_INFO "PCI: Cannot allocate "
 						"resource region %d "
 						"of bridge %s\n",
 						idx, pci_name(dev));
@@ -155,7 +155,7 @@ static void __init pcibios_allocate_resources(int pass)
 				    r->start, r->end, r->flags, disabled, pass);
 				pr = pci_find_parent_resource(dev, r);
 				if (!pr || request_resource(pr, r) < 0) {
-					printk(KERN_ERR "PCI: Cannot allocate "
+					printk(KERN_INFO "PCI: Cannot allocate "
 						"resource region %d "
 						"of device %s\n",
 						idx, pci_name(dev));
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 9cb42ec..ac2155f 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -187,10 +187,7 @@ void nmi_watchdog_default(void)
 {
 	if (nmi_watchdog != NMI_DEFAULT)
 		return;
-	if (nmi_known_cpu())
-		nmi_watchdog = NMI_LOCAL_APIC;
-	else
-		nmi_watchdog = NMI_IO_APIC;
+	nmi_watchdog = NMI_NONE;
 }
 
 static int endflag __initdata = 0;
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f4f000a..6198756 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -268,6 +268,23 @@ config ACPI_CUSTOM_DSDT_FILE
 	  Enter the full path name to the file which includes the AmlCode
 	  declaration.
 
+config ACPI_CUSTOM_DSDT_INITRD
+	bool "Read Custom DSDT from initramfs"
+	depends on BLK_DEV_INITRD
+	default y
+	help
+	  The DSDT (Differentiated System Description Table) often needs to be
+	  overridden because of broken BIOS implementations. If this feature is
+	  activated you will be able to provide a customized DSDT by adding it
+	  to your initramfs.  For now you need to use a special mkinitrd tool.
+	  For more details see <file:Documentation/dsdt-initrd.txt> or 
+	  <http://gaugusch.at/kernel.shtml>. If there is no table found, it 
+	  will fallback to the custom DSDT in-kernel (if activated) or to the
+	  DSDT from the BIOS.
+
+	  Even if you do not need a new one at the moment, you may want to use a
+	  better implemented DSDT later. It is safe to say Y here.
+
 config ACPI_BLACKLIST_YEAR
 	int "Disable ACPI for systems before Jan 1st this year" if X86_32
 	default 0
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 57ae1e5..76e07f7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -70,10 +70,15 @@ extern char line_buf[80];
 int acpi_specific_hotkey_enabled = TRUE;
 EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
 
+#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
+int acpi_must_unregister_table = FALSE;
+#endif
+
 static unsigned int acpi_irq_irq;
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
 static struct workqueue_struct *kacpid_wq;
+static struct workqueue_struct *kacpi_notify_wq;
 
 acpi_status acpi_os_initialize(void)
 {
@@ -92,8 +97,9 @@ acpi_status acpi_os_initialize1(void)
 		return AE_NULL_ENTRY;
 	}
 	kacpid_wq = create_singlethread_workqueue("kacpid");
+	kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
 	BUG_ON(!kacpid_wq);
-
+	BUG_ON(!kacpi_notify_wq);
 	return AE_OK;
 }
 
@@ -105,6 +111,7 @@ acpi_status acpi_os_terminate(void)
 	}
 
 	destroy_workqueue(kacpid_wq);
+	destroy_workqueue(kacpi_notify_wq);
 
 	return AE_OK;
 }
@@ -220,6 +227,67 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
 	return AE_OK;
 }
 
+#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
+struct acpi_table_header * acpi_find_dsdt_initrd(void)
+{
+	struct file *firmware_file;
+	mm_segment_t oldfs;
+	unsigned long len, len2;
+	struct acpi_table_header *dsdt_buffer, *ret = NULL;
+	struct kstat stat;
+	/* maybe this could be an argument on the cmd line, but let's keep it simple for now */
+	char *ramfs_dsdt_name = "/DSDT.aml";
+
+	printk(KERN_INFO PREFIX "Looking for DSDT in initramfs... ");
+
+	/* 
+	 * Never do this at home, only the user-space is allowed to open a file.
+	 * The clean way would be to use the firmware loader. But this code must be run
+	 * before there is any userspace available. So we need a static/init firmware 
+	 * infrastructure, which doesn't exist yet...
+	 */
+	if (vfs_stat(ramfs_dsdt_name, &stat) < 0) {
+		printk("file %s not found, using machine DSDT.\n", ramfs_dsdt_name);
+		return ret;
+	}
+
+	len = stat.size;
+	/* check especially against empty files */
+	if (len <= 4) {
+		printk("error file is too small, only %lu bytes.\n", len);
+		return ret;
+	}
+
+	firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0);
+	if (IS_ERR(firmware_file)) {
+		printk("error, could not open file %s.\n", ramfs_dsdt_name);
+		return ret;
+	}
+
+	dsdt_buffer = ACPI_ALLOCATE(len);
+	if (!dsdt_buffer) {
+		printk("error when allocating %lu bytes of memory.\n", len);
+		goto err;
+	}
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, &firmware_file->f_pos);
+	set_fs(oldfs);
+	if (len2 < len) {
+		printk("error trying to read %lu bytes from %s.\n", len, ramfs_dsdt_name);
+		ACPI_FREE(dsdt_buffer);
+		goto err;
+	}
+
+	printk("successfully read %lu bytes from %s.\n", len, ramfs_dsdt_name);
+	ret = dsdt_buffer;
+err:
+	filp_close(firmware_file, NULL);
+	return ret;
+}
+#endif
+
 acpi_status
 acpi_os_table_override(struct acpi_table_header * existing_table,
 		       struct acpi_table_header ** new_table)
@@ -227,13 +295,20 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
 	if (!existing_table || !new_table)
 		return AE_BAD_PARAMETER;
 
+	*new_table = NULL;
+
 #ifdef CONFIG_ACPI_CUSTOM_DSDT
 	if (strncmp(existing_table->signature, "DSDT", 4) == 0)
 		*new_table = (struct acpi_table_header *)AmlCode;
-	else
-		*new_table = NULL;
-#else
-	*new_table = NULL;
+#endif
+#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
+	if (strncmp(existing_table->signature, "DSDT", 4) == 0) {
+		struct acpi_table_header* initrd_table = acpi_find_dsdt_initrd();
+		if (initrd_table) {
+			*new_table = initrd_table;
+			acpi_must_unregister_table = TRUE;
+		}
+	}
 #endif
 	return AE_OK;
 }
@@ -575,10 +650,22 @@ static void acpi_os_execute_deferred(struct work_struct *work)
 	}
 
 	dpc->function(dpc->context);
-
 	kfree(dpc);
+	/* Yield cpu to notify thread */
+	cond_resched();
+}
 
-	return;
+static void acpi_os_execute_notify(struct work_struct *work)
+{
+	struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
+	if (!dpc) {
+		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
+		return;
+	}
+
+	dpc->function(dpc->context);
+
+	kfree(dpc);
 }
 
 /*******************************************************************************
@@ -602,14 +689,12 @@ acpi_status acpi_os_execute(acpi_execute_type type,
 	acpi_status status = AE_OK;
 	struct acpi_os_dpc *dpc;
 
-	ACPI_FUNCTION_TRACE("os_queue_for_execution");
-
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 			  "Scheduling function [%p(%p)] for deferred execution.\n",
 			  function, context));
 
 	if (!function)
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
+		return AE_BAD_PARAMETER;
 
 	/*
 	 * Allocate/initialize DPC structure.  Note that this memory will be
@@ -620,19 +705,25 @@ acpi_status acpi_os_execute(acpi_execute_type type,
 	 * having a static work_struct.
 	 */
 
-	dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
+	dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
 	if (!dpc)
 		return_ACPI_STATUS(AE_NO_MEMORY);
 
 	dpc->function = function;
 	dpc->context = context;
 
-	INIT_WORK(&dpc->work, acpi_os_execute_deferred);
-	if (!queue_work(kacpid_wq, &dpc->work)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Call to queue_work() failed.\n"));
-		kfree(dpc);
-		status = AE_ERROR;
+	if (type == OSL_NOTIFY_HANDLER) {
+		INIT_WORK(&dpc->work, acpi_os_execute_notify);
+		if (!queue_work(kacpi_notify_wq, &dpc->work)) {
+			status = AE_ERROR;
+			kfree(dpc);
+		}
+	} else {
+		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+		if (!queue_work(kacpid_wq, &dpc->work)) {
+			status = AE_ERROR;
+			kfree(dpc);
+		}
 	}
 
 	return_ACPI_STATUS(status);
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 11e2d44..3bef9f3 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -278,6 +278,14 @@ acpi_tb_table_override(struct acpi_table_header *header,
 	address.pointer.logical = new_table;
 
 	status = acpi_tb_get_this_table(&address, new_table, table_info);
+
+#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
+	if (acpi_must_unregister_table) {
+		ACPI_FREE(new_table);
+		acpi_must_unregister_table = FALSE;
+	}
+#endif
+
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table"));
 		return_ACPI_STATUS(status);
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index d9b651f..edf9dd1 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -27,13 +27,28 @@
  *		engineering the Windows drivers
  *	Yasushi Nagato - changes for linux kernel 2.4 -> 2.5
  *	Rob Miller - TV out and hotkeys help
+ *      Daniel Silverstone - Punting of hotkeys via acpi using a thread    	
  *
+ *  PLEASE NOTE
+ *
+ *  This is an experimental version of toshiba_acpi which includes emulation
+ *  of the original toshiba driver's /proc/toshiba and /dev/toshiba,
+ *  allowing Toshiba userspace utilities to work.  The relevant code was
+ *  based on toshiba.c (copyright 1996-2001 Jonathan A. Buzzard) and
+ *  incorporated into this driver with help from Gintautas Miliauskas,
+ *  Charles Schwieters, and Christoph Burger-Scheidlin.
+ *
+ *  Caveats:
+ *      * hotkey status in /proc/toshiba is not implemented
+ *      * to make accesses to /dev/toshiba load this driver instead of
+ *          the original driver, you will have to modify your module
+ *          auto-loading configuration
  *
  *  TODO
  *
  */
 
-#define TOSHIBA_ACPI_VERSION	"0.18"
+#define TOSHIBA_ACPI_VERSION	"0.19a-dev"
 #define PROC_INTERFACE_VERSION	1
 
 #include <linux/kernel.h>
@@ -41,12 +56,32 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <linux/miscdevice.h>
+#include <linux/toshiba.h>
+#include <asm/io.h>
 #include <linux/backlight.h>
-
+#include <linux/freezer.h>
 #include <asm/uaccess.h>
 
 #include <acpi/acpi_drivers.h>
 
+/* Some compatibility for isa legacy interface */
+#ifndef isa_readb
+
+#define isa_readb(a) readb(__ISA_IO_base + (a))
+#define isa_readw(a) readw(__ISA_IO_base + (a))
+#define isa_readl(a) readl(__ISA_IO_base + (a))
+#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
+#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
+#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
+#define isa_memset_io(a,b,c)            memset_io(__ISA_IO_base + (a),(b),(c))
+#define isa_memcpy_fromio(a,b,c)        memcpy_fromio((a),__ISA_IO_base + (b),(c))
+#define isa_memcpy_toio(a,b,c)          memcpy_toio(__ISA_IO_base + (a),(b),(c))
+
+#endif
+
 MODULE_AUTHOR("John Belmonte");
 MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver");
 MODULE_LICENSE("GPL");
@@ -216,6 +251,11 @@ static struct backlight_device *toshiba_backlight_device;
 static int force_fan;
 static int last_key_event;
 static int key_event_valid;
+static int hotkeys_over_acpi = 1;
+static int hotkeys_check_per_sec = 2;
+
+module_param(hotkeys_over_acpi, uint, 0400);
+module_param(hotkeys_check_per_sec, uint, 0400);
 
 typedef struct _ProcItem {
 	const char *name;
@@ -443,27 +483,34 @@ static char *read_keys(char *p)
 	u32 hci_result;
 	u32 value;
 
-	if (!key_event_valid) {
-		hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
-		if (hci_result == HCI_SUCCESS) {
-			key_event_valid = 1;
-			last_key_event = value;
-		} else if (hci_result == HCI_EMPTY) {
-			/* better luck next time */
-		} else if (hci_result == HCI_NOT_SUPPORTED) {
-			/* This is a workaround for an unresolved issue on
-			 * some machines where system events sporadically
-			 * become disabled. */
-			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
-			printk(MY_NOTICE "Re-enabled hotkeys\n");
-		} else {
-			printk(MY_ERR "Error reading hotkey status\n");
-			goto end;
+	if (!hotkeys_over_acpi) {
+		if (!key_event_valid) {
+			hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
+			if (hci_result == HCI_SUCCESS) {
+				key_event_valid = 1;
+				last_key_event = value;
+			} else if (hci_result == HCI_EMPTY) {
+				/* better luck next time */
+			} else if (hci_result == HCI_NOT_SUPPORTED) {
+				/* This is a workaround for an
+				 * unresolved issue on some machines
+				 * where system events sporadically
+				 * become disabled. */
+				hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
+				printk(MY_NOTICE "Re-enabled hotkeys\n");
+			} else {
+				printk(MY_ERR "Error reading hotkey status\n");
+				goto end;
+			}
 		}
+	} else {
+		key_event_valid = 0;
+		last_key_event = 0;
 	}
 
 	p += sprintf(p, "hotkey_ready:            %d\n", key_event_valid);
 	p += sprintf(p, "hotkey:                  0x%04x\n", last_key_event);
+	p += sprintf(p, "hotkeys_via_acpi:        %d\n", hotkeys_over_acpi);
 
       end:
 	return p;
@@ -490,6 +537,179 @@ static char *read_version(char *p)
 	return p;
 }
 
+/* /dev/toshiba and /proc/toshiba handlers {{{
+ *
+ * ISSUE: lots of magic numbers and mysterious code
+ */
+
+#define TOSH_MINOR_DEV		181
+#define OLD_PROC_TOSHIBA	"toshiba"
+
+static int
+tosh_acpi_bridge(SMMRegisters* regs)
+{
+	acpi_status status;
+
+	/* assert(sizeof(SMMRegisters) == sizeof(u32)*HCI_WORDS); */
+	status = hci_raw((u32*)regs, (u32*)regs);
+	if (status == AE_OK && (regs->eax & 0xff00) == HCI_SUCCESS)
+		return 0;
+
+	return -EINVAL;
+}
+
+static int
+tosh_ioctl(struct inode* ip, struct file* fp, unsigned int cmd,
+	unsigned long arg)
+{
+	SMMRegisters regs;
+	unsigned short ax,bx;
+	int err;
+
+	if ((!arg) || (cmd != TOSH_SMM))
+		return -EINVAL;
+
+	if (copy_from_user(&regs, (SMMRegisters*)arg, sizeof(SMMRegisters)))
+		return -EFAULT;
+
+	ax = regs.eax & 0xff00;
+	bx = regs.ebx & 0xffff;
+
+	/* block HCI calls to read/write memory & PCI devices */
+	if (((ax==HCI_SET) || (ax==HCI_GET)) && (bx>0x0069))
+		return -EINVAL;
+
+	err = tosh_acpi_bridge(&regs);
+
+	if (copy_to_user((SMMRegisters*)arg, &regs, sizeof(SMMRegisters)))
+		return -EFAULT;
+
+	return err;
+}
+
+static int
+tosh_get_machine_id(void)
+{
+	int id;
+	unsigned short bx,cx;
+	unsigned long address;
+
+	id = (0x100*(int)isa_readb(0xffffe))+((int)isa_readb(0xffffa));
+
+	/* do we have a SCTTable machine identication number on our hands */
+	if (id==0xfc2f) {
+		bx = 0xe6f5; /* cheat */
+		/* now twiddle with our pointer a bit */
+		address = 0x000f0000+bx;
+		cx = isa_readw(address);
+		address = 0x000f0009+bx+cx;
+		cx = isa_readw(address);
+		address = 0x000f000a+cx;
+		cx = isa_readw(address);
+		/* now construct our machine identification number */
+		id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8);
+	}
+
+	return id;
+}
+
+static int tosh_id;
+static int tosh_bios;
+static int tosh_date;
+static int tosh_sci;
+
+static struct file_operations tosh_fops = {
+	.owner = THIS_MODULE,
+	.ioctl = tosh_ioctl
+};
+
+static struct miscdevice tosh_device = {
+	TOSH_MINOR_DEV,
+	"toshiba",
+	&tosh_fops
+};
+
+static void
+setup_tosh_info(void __iomem *bios)
+{
+	int major, minor;
+	int day, month, year;
+
+	tosh_id = tosh_get_machine_id();
+
+	/* get the BIOS version */
+	major = isa_readb(0xfe009)-'0';
+	minor = ((isa_readb(0xfe00b)-'0')*10)+(isa_readb(0xfe00c)-'0');
+	tosh_bios = (major*0x100)+minor;
+
+	/* get the BIOS date */
+	day = ((isa_readb(0xffff5)-'0')*10)+(isa_readb(0xffff6)-'0');
+	month = ((isa_readb(0xffff8)-'0')*10)+(isa_readb(0xffff9)-'0');
+	year = ((isa_readb(0xffffb)-'0')*10)+(isa_readb(0xffffc)-'0');
+	tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6)
+		| ((day & 0x1f)<<1);
+}
+
+/* /proc/toshiba read handler */
+static int
+tosh_get_info(char* buffer, char** start, off_t fpos, int length)
+{
+	char* temp = buffer;
+	/* TODO: tosh_fn_status() */
+	int key = 0;
+
+	/* Format:
+	 *    0) Linux driver version (this will change if format changes)
+	 *    1) Machine ID
+	 *    2) SCI version
+	 *    3) BIOS version (major, minor)
+	 *    4) BIOS date (in SCI date format)
+	 *    5) Fn Key status
+	 */
+
+	temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
+		tosh_id,
+		(tosh_sci & 0xff00)>>8,
+		tosh_sci & 0xff,
+		(tosh_bios & 0xff00)>>8,
+		tosh_bios & 0xff,
+		tosh_date,
+		key);
+
+	return temp-buffer;
+}
+
+static int __init
+old_driver_emulation_init(void)
+{
+	int status;
+	void __iomem *bios = ioremap(0xf0000, 0x10000);
+	if (!bios)
+		return -ENOMEM;
+
+	if ((status = misc_register(&tosh_device))) {
+		printk(MY_ERR "failed to register misc device %d (\"%s\")\n",
+			tosh_device.minor, tosh_device.name);
+		return status;
+	}
+
+	setup_tosh_info(bios);
+	create_proc_info_entry(OLD_PROC_TOSHIBA, 0, NULL, tosh_get_info);
+
+	iounmap(bios);
+
+	return 0;
+}
+
+static void __exit
+old_driver_emulation_exit(void)
+{
+	remove_proc_entry(OLD_PROC_TOSHIBA, NULL);
+	misc_deregister(&tosh_device);
+}
+
+/* }}} end of /dev/toshiba and /proc/toshiba handlers */
+
 /* proc and module init
  */
 
@@ -540,16 +760,144 @@ static struct backlight_properties toshiba_backlight_data = {
         .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1,
 };
 
+static struct semaphore thread_sem;
+static int thread_should_die;
+
+static struct acpi_device *threaded_device = 0;
+
+static void thread_deliver_button_event(u32 value)
+{
+	if (!threaded_device) return;
+	if( value == 0x0100 ) {
+		/* Ignore FN on its own */
+	} else if( value & 0x80 ) {
+		acpi_bus_generate_event( threaded_device, 1, value & ~0x80 );
+	} else {
+		acpi_bus_generate_event( threaded_device, 0, value );
+	}
+}
+
+static int toshiba_acpi_thread(void *data)
+{
+	int dropped = 0;
+	u32 hci_result, value;
+
+	daemonize("ktoshkeyd");
+	set_user_nice(current, 4);
+	thread_should_die = 0;
+
+	up(&thread_sem);
+
+	do {
+		/* In case we get stuck; we can rmmod the module here */
+		if (thread_should_die)
+			break;
+
+		hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
+		if (hci_result == HCI_SUCCESS) {
+			dropped++;
+		} else if (hci_result == HCI_EMPTY) {
+                         /* better luck next time */
+		} else if (hci_result == HCI_NOT_SUPPORTED) {
+			/* This is a workaround for an unresolved issue on
+			 * some machines where system events sporadically
+			 * become disabled. */
+			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
+			printk(MY_NOTICE "Re-enabled hotkeys\n");
+		}
+	} while (hci_result != HCI_EMPTY);
+
+	printk(MY_INFO "Dropped %d keys from the queue on startup\n", dropped);
+
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ / hotkeys_check_per_sec);
+
+		if (thread_should_die)
+			break;
+
+		if (try_to_freeze())
+			continue;
+
+		do {
+			hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
+			if (hci_result == HCI_SUCCESS) {
+				thread_deliver_button_event(value);
+			} else if (hci_result == HCI_EMPTY) {
+				/* better luck next time */
+			} else if (hci_result == HCI_NOT_SUPPORTED) {
+				/* This is a workaround for an
+				 * unresolved issue on some machines
+				 * where system events sporadically
+				 * become disabled. */
+				hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
+				printk(MY_NOTICE "Re-enabled hotkeys\n");
+			}
+		} while (hci_result == HCI_SUCCESS);
+	}
+	set_user_nice(current, -20);	/* Become nasty so we are cleaned up
+					 * before the module exits making us oops */
+	up(&thread_sem);
+	return 0;
+}
+
+static int acpi_toshkeys_add (struct acpi_device *device)
+{
+	threaded_device = device;
+	strcpy(acpi_device_name(device), "Toshiba laptop hotkeys");
+	strcpy(acpi_device_class(device), "hkey");
+	return 0;
+}
+
+static int acpi_toshkeys_remove (struct acpi_device *device, int type)
+{
+	if (threaded_device == device)
+		threaded_device = 0;
+	return 0;
+}
+
+static struct acpi_driver acpi_threaded_toshkeys = {
+	.name = "Toshiba laptop hotkeys driver",
+	.class = "hkey",
+	.ids = "TOS6200,TOS6207,TOS6208",
+	.ops = {
+		.add = acpi_toshkeys_add,
+		.remove = acpi_toshkeys_remove,
+	},
+};
+
+static int __init init_threaded_acpi(void)
+{
+        acpi_status result = AE_OK;
+        result = acpi_bus_register_driver(&acpi_threaded_toshkeys);
+        if( result < 0 )
+                printk(MY_ERR "Registration of toshkeys acpi device failed\n");
+        return result;
+}
+
+static void kill_threaded_acpi(void)
+{
+        acpi_bus_unregister_driver(&acpi_threaded_toshkeys);
+}
+
 static void __exit toshiba_acpi_exit(void)
 {
 	if (toshiba_backlight_device)
 		backlight_device_unregister(toshiba_backlight_device);
 
+	if (hotkeys_over_acpi) {
+		thread_should_die = 1;
+		down(&thread_sem);
+		kill_threaded_acpi();
+	}
+
 	remove_device();
 
 	if (toshiba_proc_dir)
 		remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
 
+	old_driver_emulation_exit();
+
 	return;
 }
 
@@ -557,6 +905,7 @@ static int __init toshiba_acpi_init(void)
 {
 	acpi_status status = AE_OK;
 	u32 hci_result;
+	int status2;
 
 	if (acpi_disabled)
 		return -ENODEV;
@@ -577,6 +926,9 @@ static int __init toshiba_acpi_init(void)
 	       TOSHIBA_ACPI_VERSION);
 	printk(MY_INFO "    HCI method: %s\n", method_hci);
 
+	if ((status2 = old_driver_emulation_init()))
+		return status2;
+
 	force_fan = 0;
 	key_event_valid = 0;
 
@@ -602,6 +954,26 @@ static int __init toshiba_acpi_init(void)
 		toshiba_acpi_exit();
 	}
 
+	if (hotkeys_over_acpi && ACPI_SUCCESS(status)) {
+		printk(MY_INFO "Toshiba hotkeys are sent as ACPI events\n");
+		if (hotkeys_check_per_sec < 1)
+			hotkeys_check_per_sec = 1;
+		if (hotkeys_check_per_sec > 10)
+			hotkeys_check_per_sec = 10;
+		printk(MY_INFO "ktoshkeyd will check %d time%s per second\n",
+			hotkeys_check_per_sec, hotkeys_check_per_sec==1?"":"s");
+		if (init_threaded_acpi() >= 0) {
+			init_MUTEX_LOCKED(&thread_sem);
+			kernel_thread(toshiba_acpi_thread, NULL, CLONE_KERNEL);
+			down(&thread_sem);
+		} else {
+			remove_device();
+			remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
+			status = AE_ERROR;
+			printk(MY_INFO "ktoshkeyd initialisation failed. Refusing to load module\n");
+		}
+	}
+
 	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
 }
 
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 3368745..17c60a0 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -139,7 +139,7 @@ config ATM_ENI_BURST_RX_2W
 
 config ATM_FIRESTREAM
 	tristate "Fujitsu FireStream (FS50/FS155) "
-	depends on PCI && ATM
+	depends on PCI && ATM && ISA_DMA_API
 	help
 	  Driver for the Fujitsu FireStream 155 (MB86697) and
 	  FireStream 50 (MB86695) ATM PCI chips.
@@ -149,7 +149,7 @@ config ATM_FIRESTREAM
 
 config ATM_ZATM
 	tristate "ZeitNet ZN1221/ZN1225"
-	depends on PCI && ATM
+	depends on PCI && ATM && ISA_DMA_API
 	help
 	  Driver for the ZeitNet ZN1221 (MMF) and ZN1225 (UTP-5) 155 Mbps ATM
 	  adapters.
@@ -237,7 +237,7 @@ config ATM_IDT77252_USE_SUNI
 
 config ATM_AMBASSADOR
 	tristate "Madge Ambassador (Collage PCI 155 Server)"
-	depends on PCI && ATM
+	depends on PCI && ATM && ISA_DMA_API
 	select BITREVERSE
 	help
 	  This is a driver for ATMizer based ATM card produced by Madge
@@ -262,7 +262,7 @@ config ATM_AMBASSADOR_DEBUG
 
 config ATM_HORIZON
 	tristate "Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)"
-	depends on PCI && ATM
+	depends on PCI && ATM && ISA_DMA_API
 	help
 	  This is a driver for the Horizon chipset ATM adapter cards once
 	  produced by Madge Networks Ltd. Say Y (or M to compile as a module
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 472810f..8b557ef 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -19,6 +19,55 @@
 #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
 #define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
 
+int disable_auto_probe = 0;
+
+static ssize_t disable_auto_probe_show(struct subsystem *subsys, char *page)
+{
+	return sprintf(page, "%s\n", disable_auto_probe ? "true" : "false");
+}
+static ssize_t disable_auto_probe_store(struct subsystem *subsys,
+					const char *page, size_t count)
+{
+	char l = page[0];
+
+        if (!count)
+                return -EINVAL;
+
+	switch (l) {
+		case 'Y':
+		case 'y':
+		case 'T':
+		case 't':
+		case '1':
+			disable_auto_probe = 1;
+			break;
+		case 'N':
+		case 'n':
+		case 'F':
+		case 'f':
+		case '0':
+			disable_auto_probe = 0;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+        return count;
+}
+
+static struct subsys_attribute disable_auto_probe_attr =
+	__ATTR(disable_auto_probe, 0644, disable_auto_probe_show,
+	       disable_auto_probe_store);
+
+static struct attribute *bus_attrs[] = {
+	&disable_auto_probe_attr.attr,
+	NULL
+};
+
+static struct attribute_group bus_attr_group = {
+	.attrs = bus_attrs,
+};
+
 /*
  * sysfs bindings for drivers
  */
@@ -812,7 +861,12 @@ EXPORT_SYMBOL_GPL(bus_unregister_notifier);
 
 int __init buses_init(void)
 {
-	return subsystem_register(&bus_subsys);
+	int error = subsystem_register(&bus_subsys);
+	if (!error)
+		error = sysfs_create_group(&bus_subsys.kset.kobj,
+					   &bus_attr_group);
+
+	return error;
 }
 
 
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 510e788..9e93105 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -25,6 +25,7 @@
 
 #define to_drv(node) container_of(node, struct device_driver, kobj.entry)
 
+extern int disable_auto_probe;
 
 static void driver_bound(struct device *dev)
 {
@@ -242,6 +245,9 @@ int device_attach(struct device * dev)
 {
 	int ret = 0;
 
+	if (disable_auto_probe)
+		return 0;
+
 	down(&dev->sem);
 	if (dev->driver) {
 		ret = device_bind_driver(dev);
@@ -290,6 +296,8 @@ static int __driver_attach(struct device * dev, void * data)
  */
 int driver_attach(struct device_driver * drv)
 {
+	if (disable_auto_probe)
+		return 0;
 	return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
 }
 
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index f9c903b..4d8a2fb 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -160,6 +160,11 @@ static void platform_device_release(struct device *dev)
  *
  *	Create a platform device object which can have other objects attached
  *	to it, and which will have attached objects freed when it is released.
+ *
+ *	This device will be marked as not supporting hotpluggable drivers.  In
+ *	the unusual case that the device isn't being dynamically allocated as
+ *	of a legacy "probe the hardware" driver, infrastructure code should
+ *	consider reversing this marking.
  */
 struct platform_device *platform_device_alloc(const char *name, unsigned int id)
 {
@@ -172,6 +177,7 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
 		pa->pdev.id = id;
 		device_initialize(&pa->pdev.dev);
 		pa->pdev.dev.release = platform_device_release;
+		pa->pdev.dev.is_driver_not_hotpluggable = 1;
 	}
 
 	return pa ? &pa->pdev : NULL;
@@ -349,6 +355,13 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
  *	memory allocated for the device allows drivers using such devices
  *	to be unloaded iwithout waiting for the last reference to the device
  *	to be dropped.
+ *
+ *	This interface is primarily intended for use with legacy drivers
+ *	which probe hardware directly.  Because such drivers create device
+ *	nodes themselves, rather than letting system infrastructure handle
+ *	such device enumeration tasks, they don't fully conform to the Linux
+ *	driver model.  In particular, when such drivers are built as modules,
+ *	they can't be "hotplugged".
  */
 struct platform_device *platform_device_register_simple(char *name, unsigned int id,
 							struct resource *res, unsigned int num)
@@ -525,6 +538,13 @@ static int platform_uevent(struct device *dev, char **envp, int num_envp,
 {
 	struct platform_device	*pdev = to_platform_device(dev);
 
+	/* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in
+	 * legacy probe-the-hardware drivers, which don't properly split
+	 * out enumeration logic from drivers.
+	 */
+	if (dev->is_driver_not_hotpluggable)
+		return 0;
+
 	envp[0] = buffer;
 	snprintf(buffer, buffer_size, "MODALIAS=%s", pdev->name);
 	return 0;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 58c1deb..f6c10db 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -141,7 +141,7 @@ source "drivers/block/paride/Kconfig"
 
 config BLK_CPQ_DA
 	tristate "Compaq SMART2 support"
-	depends on PCI
+	depends on PCI && ISA_DMA_API
 	help
 	  This is the driver for Compaq Smart Array controllers.  Everyone
 	  using these boards should say Y here.  See the file
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 9e43e39..9e0cdae 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -613,6 +613,7 @@ config HVC_RTAS
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
 	depends on PPC_PSERIES
+	select HVC_CONSOLE
 	help
 	  Partitionable IBM Power5 ppc64 machines allow hosting of
 	  firmware virtual consoles from one Linux partition by
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index b99b756..d631f79 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -667,3 +667,4 @@ console_map_init(void)
 }
 
 EXPORT_SYMBOL(con_copy_unimap);
+EXPORT_SYMBOL(inverse_translate);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 7a6c1c0..2754403 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -41,6 +41,22 @@
 #include <linux/input.h>
 #include <linux/reboot.h>
 
+
+#include <linux/speakup.h>
+        
+#if defined(CONFIG_SPEAKUP_MODULE)
+
+spk_key_func addr_spk_key = NULL;
+#define speakup_key_call(__vc, __shift, __keycode, __key, __down)	\
+	(addr_spk_key && (*addr_spk_key)(__vc, __shift, __keycode, __key, __down))
+
+#elif defined(CONFIG_SPEAKUP)
+#define speakup_key_call(__vc, __shift, __keycode, __key, __down)	\
+	speakup_key(__vc, __shift, __keycode, __key, __down)
+#else
+#define speakup_key_call(__vc, __shift, __keycode, __key, __down)	0
+#endif
+ 
 static void kbd_disconnect(struct input_handle *handle);
 extern void ctrl_alt_del(void);
 
@@ -65,6 +81,10 @@ extern void ctrl_alt_del(void);
 
 #define KBD_DEFLOCK 0
 
+/* Key types processed even in raw modes */
+
+#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) | (1 << KT_SPKUP))
+
 void compute_shiftstate(void);
 
 /*
@@ -80,7 +100,7 @@ void compute_shiftstate(void);
 typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
 			    char up_flag);
 static k_handler_fn K_HANDLERS;
-static k_handler_fn *k_handler[16] = { K_HANDLERS };
+k_handler_fn *k_handler[16] = { K_HANDLERS };
 
 #define FN_HANDLERS\
 	fn_null,	fn_enter,	fn_show_ptregs,	fn_show_mem,\
@@ -101,13 +121,16 @@ static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
 const int max_vals[] = {
 	255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
 	NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
-	255, NR_LOCK - 1, 255, NR_BRL - 1
+	255, NR_LOCK - 1, 255, NR_BRL - 1, 255
 };
 
 const int NR_TYPES = ARRAY_SIZE(max_vals);
 
 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
-static struct kbd_struct *kbd = kbd_table;
+struct kbd_struct *kbd = kbd_table;
+
+EXPORT_SYMBOL(kbd);
+EXPORT_SYMBOL(k_handler);
 
 struct vt_spawn_console vt_spawn_con = {
 	.lock = SPIN_LOCK_UNLOCKED,
@@ -266,6 +289,8 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
 		kd_nosound(0);
 }
 
+EXPORT_SYMBOL(kd_mksound);
+
 /*
  * Setting the keyboard rate.
  */
@@ -1060,6 +1085,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
 	int code;
 
 	switch (keycode) {
+		case KEY_RESERVED:
+			break;
 		case KEY_PAUSE:
 			put_queue(vc, 0xe1);
 			put_queue(vc, 0x1d | up_flag);
@@ -1119,6 +1146,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
 
 static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
 {
+	if (keycode == KEY_RESERVED)
+		return 0;
 	if (keycode > 127)
 		return -1;
 
@@ -1233,6 +1262,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 	key_map = key_maps[shift_final];
 
 	if (!key_map) {
+		if (speakup_key_call(vc, shift_final, keycode, K(KT_SHIFT,0), !down ))
+			return;
+
 		compute_shiftstate();
 		kbd->slockstate = 0;
 		return;
@@ -1256,9 +1288,12 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 
 	type -= 0xf0;
 
-	if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
+	if (speakup_key_call(vc, shift_final, keycode, keysym, !down ))
 		return;
 
+	if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
+		return;
+ 
 	if (type == KT_LETTER) {
 		type = KT_LATIN;
 		if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
@@ -1274,6 +1309,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 		kbd->slockstate = 0;
 }
 
+struct input_dev *fakekeydev=NULL;
+EXPORT_SYMBOL(fakekeydev);
+
 static void kbd_event(struct input_handle *handle, unsigned int event_type,
 		      unsigned int event_code, int value)
 {
@@ -1311,6 +1349,7 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
 		return NULL;
 
 	handle->dev = dev;
+	fakekeydev = dev;
 	handle->handler = handler;
 	handle->name = "kbd";
 
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 06c32a3..0d237bc 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -119,6 +119,11 @@ struct con_driver {
 	int flag;
 };
 
+#include <linux/speakup.h>
+#ifdef CONFIG_SPEAKUP_MODULE
+#include <speakup/spk_con_module.h>
+#endif
+
 static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
 const struct consw *conswitchp;
 
@@ -234,6 +239,10 @@ enum {
 #define DO_UPDATE(vc)	CON_IS_VISIBLE(vc)
 #endif
 
+#ifdef CONFIG_PROM_CONSOLE
+static int force_prom_console;
+#endif
+
 static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
 {
 	unsigned short *p;
@@ -739,6 +748,7 @@ int vc_allocate(unsigned int currcons)	/* return 0 on success */
 	    }
 	    vc->vc_kmalloced = 1;
 	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+	    speakup_allocate(vc);
 	}
 	return 0;
 }
@@ -1003,6 +1013,7 @@ static void lf(struct vc_data *vc)
 		vc->vc_pos += vc->vc_size_row;
 	}
 	vc->vc_need_wrap = 0;
+	speakup_con_write(vc, "\n",1);	
 }
 
 static void ri(struct vc_data *vc)
@@ -1031,6 +1042,7 @@ static inline void bs(struct vc_data *vc)
 		vc->vc_pos -= 2;
 		vc->vc_x--;
 		vc->vc_need_wrap = 0;
+		speakup_bs(vc);
 	}
 }
 
@@ -1568,6 +1580,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 				break;
 		}
 		vc->vc_pos += (vc->vc_x << 1);
+		speakup_con_write(vc, " ", 1);
 		return;
 	case 10: case 11: case 12:
 		lf(vc);
@@ -2107,6 +2120,7 @@ display_glyph:
 			}
 			if (vc->vc_decim)
 				insert_char(vc, 1);
+			speakup_con_write(vc, (char *) &c, 1);
 			scr_writew(himask ?
 				     ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
 				     (vc->vc_attr << 8) + tc,
@@ -2141,6 +2155,7 @@ display_glyph:
 	release_console_sem();
 
 out:
+	speakup_con_update(vc);
 	return n;
 #undef FLUSH
 }
@@ -2166,6 +2181,7 @@ static void console_callback(struct work_struct *ignored)
 			/* we only changed when the console had already
 			   been allocated - a new console is not created
 			   in an interrupt routine */
+			speakup_con_update(vc_cons[want_console].d);
 		}
 		want_console = -1;
 	}
@@ -2184,7 +2200,8 @@ static void console_callback(struct work_struct *ignored)
 		do_blank_screen(0);
 		blank_timer_expired = 0;
 	}
-
+	speakup_con_update(vc_cons[fg_console].d);
+	
 	release_console_sem();
 }
 
@@ -2229,6 +2246,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
 		/* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
 		goto quit;
 	}
+	speakup_con_update(vc_cons[fg_console].d);
 
 	if (vc->vc_mode != KD_TEXT)
 		goto quit;
@@ -2241,6 +2259,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
 
 	/* Contrived structure to try to emulate original need_wrap behaviour
 	 * Problems caused when we have need_wrap set on '\n' character */
+	speakup_con_write(vc, b, count);
 	while (count--) {
 		c = *b++;
 		if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
@@ -2285,6 +2304,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
 		}
 	}
 	set_cursor(vc);
+	speakup_con_update(vc);
 
 quit:
 	clear_bit(0, &printing);
@@ -2650,6 +2670,7 @@ static int __init con_init(void)
 	master_display_fg = vc = vc_cons[currcons].d;
 	set_origin(vc);
 	save_screen(vc);
+	speakup_init(vc);
 	gotoxy(vc, vc->vc_x, vc->vc_y);
 	csi_J(vc, 0);
 	update_screen(vc);
@@ -2683,6 +2704,17 @@ static const struct tty_operations con_ops = {
 	.unthrottle = con_unthrottle,
 };
 
+#ifdef CONFIG_PROM_CONSOLE
+static int __init check_prom_console(char *str)
+{
+	force_prom_console = 1;
+	printk ("PROM console forced!\n");
+	return 1;
+}
+
+__setup("forcepromconsole", check_prom_console);
+#endif
+
 int __init vty_init(void)
 {
 	vcs_init();
@@ -2705,7 +2737,8 @@ int __init vty_init(void)
 	kbd_init();
 	console_map_init();
 #ifdef CONFIG_PROM_CONSOLE
-	prom_con_init();
+	if (force_prom_console)
+		prom_con_init();
 #endif
 #ifdef CONFIG_MDA_CONSOLE
 	mda_console_init();
@@ -3820,3 +3853,4 @@ EXPORT_SYMBOL(vc_cons);
 EXPORT_SYMBOL(take_over_console);
 EXPORT_SYMBOL(give_up_console);
 #endif
+EXPORT_SYMBOL(screen_glyph);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 5a5c565..e5752bc 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -741,7 +741,7 @@ static void probe_hwif(ide_hwif_t *hwif)
 			}
 		}
 		if (!msgout)
-			printk(KERN_ERR "%s: ports already in use, skipping probe\n",
+			printk(KERN_INFO "%s: ports already in use, skipping probe\n",
 				hwif->name);
 		return;	
 	}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 6c9bd51..af8df47 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -363,7 +369,7 @@ static struct resource* hwif_request_region(ide_hwif_t *hwif,
 	struct resource *res = request_region(addr, num, hwif->name);
 
 	if (!res)
-		printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
+		printk(KERN_INFO "%s: I/O resource 0x%lX-0x%lX not free.\n",
 				hwif->name, addr, addr+num-1);
 	return res;
 }
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 7cf2b4f..91de183 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -73,7 +73,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
 
 		case EV_KEY:
 
-			if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value)
+			if (code > KEY_MAX || !!test_bit(code, dev->key) == value)
 				return;
 
 			if (value == 2)
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 4e71a66..49184de 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -385,7 +385,8 @@ static int alps_reconnect(struct psmouse *psmouse)
 	struct alps_data *priv = psmouse->private;
 	int version;
 
-	psmouse_reset(psmouse);
+	/* UBUNTU: Causes lockups on resume */
+	/* psmouse_reset(psmouse); */
 
 	if (!(priv->i = alps_get_model(psmouse, &version)))
 		return -1;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index debe944..2cf61ee 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -9,6 +9,7 @@
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
+#define USE_REAL_TIME_DELAY
 
 #include <linux/delay.h>
 #include <linux/module.h>
@@ -657,7 +658,7 @@ static int __devinit i8042_check_aux(void)
 static int i8042_controller_check(void)
 {
 	if (i8042_flush() == I8042_BUFFER_SIZE) {
-		printk(KERN_ERR "i8042.c: No controller found.\n");
+		printk(KERN_INFO "i8042.c: No controller found.\n");
 		return -ENODEV;
 	}
 
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
index 6443392..99c9d3a 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/message/i2o/Kconfig
@@ -56,7 +56,7 @@ config I2O_EXT_ADAPTEC_DMA64
 
 config I2O_CONFIG
 	tristate "I2O Configuration support"
-	depends on I2O
+	depends on I2O && ISA_DMA_API
 	---help---
 	  Say Y for support of the configuration interface for the I2O adapters.
 	  If you have a RAID controller from Adaptec and you want to use the
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 6f93a76..9496eea 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1827,10 +1827,10 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
 	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) {
-		dev_err(&pdev->dev,
+		dev_info(&pdev->dev,
 			   "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n",
 		           pdev->vendor, pdev->device, pci_rev);
-		dev_err(&pdev->dev, "Try the \"8139too\" driver instead.\n");
+		dev_info(&pdev->dev, "Try the \"8139too\" driver instead.\n");
 		return -ENODEV;
 	}
 
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 29b5ccd..af68639 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -149,7 +149,7 @@ static char *dongle_types[] = {
 static chipio_t pnp_info;
 static const struct pnp_device_id nsc_ircc_pnp_table[] = {
 	{ .id = "NSC6001", .driver_data = 0 },
-	{ .id = "IBM0071", .driver_data = 0 },
+	{ .id = "IBM0071", .driver_data = 1 },
 	{ }
 };
 
@@ -929,6 +929,9 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i
 	 * On my box, cfg_base is in the PnP descriptor of the
 	 * motherboard. Oh well... Jean II */
 
+	if (id->driver_data == 1)
+		dongle_id = 0x9;
+
 	if (pnp_port_valid(dev, 0) &&
 		!(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED))
 		pnp_info.fir_base = pnp_port_start(dev, 0);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 577babd..e4c3e34 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1681,6 +1681,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	dev->poll_controller = rtl8169_netpoll;
 #endif
 
+	/* Ubuntu temporary workaround for bug #76489, disable
+	 * NETIF_F_TSO by default for RTL8111/8168B chipsets.
+	 * People can re-enable if required */
+	if (tp->mac_version == RTL_GIGA_MAC_VER_11
+				|| tp->mac_version == RTL_GIGA_MAC_VER_12)
+		dev->features &= ~NETIF_F_TSO;
+
 	tp->intr_mask = 0xffff;
 	tp->pci_dev = pdev;
 	tp->mmio_addr = ioaddr;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index ef67173..df65e67 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -1972,6 +1972,7 @@ static void happy_meal_tx(struct happy_meal *hp)
 	}
 	hp->tx_old = elem;
 	TXD((">"));
+	udelay(1);
 
 	if (netif_queue_stopped(dev) &&
 	    TX_BUFFS_AVAIL(hp) > (MAX_SKB_FRAGS + 1))
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index 20bd52b..ab98bc5 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -44,8 +44,10 @@ static const unsigned char comet_miireg2offset[32] = {
 
 /* MII transceiver control section.
    Read and write the MII registers using software-generated serial
-   MDIO protocol.  See the MII specifications or DP83840A data sheet
-   for details. */
+   MDIO protocol.
+   See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
+   or DP83840A data sheet for more details.
+   */
 
 int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
 {
@@ -261,24 +263,56 @@ void tulip_select_media(struct net_device *dev, int startup)
 				u16 *reset_sequence = &((u16*)(p+3))[init_length];
 				int reset_length = p[2 + init_length*2];
 				misc_info = reset_sequence + reset_length;
-				if (startup)
+				if (startup) {
+					int timeout = 10;	/* max 1 ms */
 					for (i = 0; i < reset_length; i++)
 						iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
+				
+					/* flush posted writes */
+					ioread32(ioaddr + CSR15);
+
+					/* Sect 3.10.3 in DP83840A.pdf (p39) */
+					udelay(500);
+
+					/* Section 4.2 in DP83840A.pdf (p43) */
+					/* and IEEE 802.3 "22.2.4.1.1 Reset" */
+					while (timeout-- &&
+						(tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
+						udelay(100);
+				}
 				for (i = 0; i < init_length; i++)
 					iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
+
+				ioread32(ioaddr + CSR15);	/* flush posted writes */
 			} else {
 				u8 *init_sequence = p + 2;
 				u8 *reset_sequence = p + 3 + init_length;
 				int reset_length = p[2 + init_length];
 				misc_info = (u16*)(reset_sequence + reset_length);
 				if (startup) {
+					int timeout = 10;	/* max 1 ms */
 					iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
 					for (i = 0; i < reset_length; i++)
 						iowrite32(reset_sequence[i], ioaddr + CSR12);
+
+					/* flush posted writes */
+					ioread32(ioaddr + CSR12);
+
+					/* Sect 3.10.3 in DP83840A.pdf (p39) */
+					udelay(500);
+
+					/* Section 4.2 in DP83840A.pdf (p43) */
+					/* and IEEE 802.3 "22.2.4.1.1 Reset" */
+					while (timeout-- &&
+						(tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
+						udelay(100);
 				}
 				for (i = 0; i < init_length; i++)
 					iowrite32(init_sequence[i], ioaddr + CSR12);
+
+				ioread32(ioaddr + CSR12);	/* flush posted writes */
 			}
+
 			tmp_info = get_u16(&misc_info[1]);
 			if (tmp_info)
 				tp->advertising[phy_num] = tmp_info | 1;
@@ -485,10 +519,11 @@ void __devinit tulip_find_mii (struct net_device *dev, int board_idx)
 		/* Enable autonegotiation: some boards default to off. */
 		if (tp->default_port == 0) {
 			new_bmcr = mii_reg0 | BMCR_ANENABLE;
-			if (new_bmcr != mii_reg0) {
-				new_bmcr |= BMCR_ANRESTART;
-				ane_switch = 1;
-			}
+			/* DM9161E PHY seems to need to restart
+			 * autonegotiation even if it defaults to enabled.
+			 */
+			new_bmcr |= BMCR_ANRESTART;
+			ane_switch = 1;
 		}
 		/* ...or disable nway, if forcing media */
 		else {
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 25f25da..2b68cda 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -36,7 +36,10 @@
 #define TULIP_BAR	0	/* CBIO */
 #endif
 
-
+#ifndef PCI_ULI5261_ID
+#define PCI_ULI5261_ID  0x526110B9      /* ULi M5261 ID*/
+#define PCI_ULI5263_ID  0x526310B9      /* ULi M5263 ID*/
+#endif
 
 struct tulip_chip_table {
 	char *chip_name;
@@ -482,8 +485,11 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp)
 			udelay(10);
 
 		if (!i)
-			printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n",
-					pci_name(tp->pdev));
+			printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
+					" (CSR5 0x%x CSR6 0x%x)\n",
+					pci_name(tp->pdev),
+					ioread32(ioaddr + CSR5),
+					ioread32(ioaddr + CSR6));
 	}
 }
 
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 5a35354..8d9ccba 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -21,7 +21,7 @@
 #else
 #define DRV_VERSION	"1.1.14"
 #endif
-#define DRV_RELDATE	"May 11, 2002"
+#define DRV_RELDATE	"December 15, 2004"
 
 
 #include <linux/module.h>
@@ -155,7 +155,7 @@ struct tulip_chip_table tulip_tbl[] = {
 	tulip_media_task },
 
   /* DC21142, DC21143 */
-  { "Digital DS21142/43 Tulip", 128, 0x0801fbff,
+  { "Digital DS21142/DS21143 Tulip", 128, 0x0801fbff,
 	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY
 	| HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task },
 
@@ -230,8 +230,12 @@ static struct pci_device_id tulip_pci_tbl[] = {
 	{ 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
 	{ 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
+	/* Ubuntu: On non-sparc, this seems to be handled better by the
+	 * dmfe driver. */
+#ifdef __sparc__
 	{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
+#endif
 	{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
@@ -389,6 +393,11 @@ static void tulip_up(struct net_device *dev)
 				goto media_picked;
 			}
 	}
+	if (tp->chip_id == PCI_ULI5261_ID || tp->chip_id == PCI_ULI5263_ID) {
+		for (i = tp->mtable->leafcount - 1; i >= 0; i--)
+			if (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaIsMII)
+				goto media_picked;
+	}
 	/* Start sensing first non-full-duplex media. */
 	for (i = tp->mtable->leafcount - 1;
 		 (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 21f76f5..c3aa6a7 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -62,7 +62,7 @@ config COSA
 #
 config LANMEDIA
 	tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
-	depends on WAN && PCI
+	depends on WAN && PCI && ISA_DMA_API
 	---help---
 	  Driver for the following Lan Media family of serial boards:
 
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 606a467..0510de0 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -561,7 +561,10 @@ static int socket_resume(struct pcmcia_socket *skt)
 
 	if (!(skt->state & SOCKET_PRESENT)) {
 		skt->state &= ~SOCKET_SUSPEND;
-		return socket_insert(skt);
+		/* UBUNTU: This causes problems on resume. Userspace
+		 * scripts take care of this. */
+		/* return socket_insert(skt); */
+		return 0;
 	}
 
 	ret = socket_setup(skt, resume_delay);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index ea74f98..6d3fe52 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1266,6 +1266,19 @@ static int __init init_i82365(void)
     if (ret)
 	return ret;
 
+    printk(KERN_INFO "Intel ISA PCIC probe: ");
+    sockets = 0;
+
+    isa_probe();
+
+    if (sockets == 0) {
+	printk("not found.\n");
+	release_region(i365_base, 2);
+	driver_unregister(&i82365_driver);
+	return -ENODEV;
+    }
+
+
     i82365_device = platform_device_alloc("i82365", 0);
     if (i82365_device) {
 	    ret = platform_device_add(i82365_device);
@@ -1275,21 +1288,9 @@ static int __init init_i82365(void)
 	    ret = -ENOMEM;
 
     if (ret) {
-	driver_unregister(&i82365_driver);
-	return ret;
-    }
-
-    printk(KERN_INFO "Intel ISA PCIC probe: ");
-    sockets = 0;
-
-    isa_probe();
-
-    if (sockets == 0) {
-	printk("not found.\n");
-	platform_device_unregister(i82365_device);
 	release_region(i365_base, 2);
 	driver_unregister(&i82365_driver);
-	return -ENODEV;
+	return ret;
     }
 
     /* Set up interrupt handler(s) */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 7869c34..16699aa 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1364,7 +1364,7 @@ config SCSI_DC395x
 
 config SCSI_DC390T
 	tristate "Tekram DC390(T) and Am53/79C974 SCSI support"
-	depends on PCI && SCSI
+	depends on PCI && SCSI && ISA_DMA_API
 	---help---
 	  This driver supports PCI SCSI host adapters based on the Am53C974A
 	  chip, e.g. Tekram DC390(T), DawiControl 2974 and some onboard
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index b49f2a7..0477699 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1156,14 +1156,27 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
                 US_SC_DEVICE, US_PR_DEVICE, NULL,
                 US_FL_FIX_INQUIRY ),
 
-/* This is a virtual windows driver CD, which the zd1211rw driver automatically
- * converts into a WLAN device. */
+/* These are virtual windows driver CDs, which the zd1211rw driver automatically
+ * converts into WLAN devices. */
 UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
                 "ZyXEL",
                 "G-220F USB-WLAN Install",
                 US_SC_DEVICE, US_PR_DEVICE, NULL,
                 US_FL_IGNORE_DEVICE ),
 
+UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
+                "SiteCom",
+                "WL-117 USB-WLAN Install",
+                US_SC_DEVICE, US_PR_DEVICE, NULL,
+                US_FL_IGNORE_DEVICE ),
+
+/* SanDisk that has a second LUN for a driver ISO */
+UNUSUAL_DEV( 0x0781, 0x5406, 0x0000, 0xffff,
+		"SanDisk",
+		"U3 Cruzer Micro",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_SINGLE_LUN ),
+
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
 		"ATI",
@@ -1286,6 +1299,14 @@ UNUSUAL_DEV(  0x0ea0, 0x6828, 0x0110, 0x0110,
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Edward Chapman <[EMAIL PROTECTED]>
+   Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive */
+UNUSUAL_DEV( 0x0dd8, 0xd202, 0x0000, 0x9999,
+		"Netac",
+		"USB Flash Disk",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Reported by Benjamin Schiller <sbenni at gmx.de>
  * It is also sold by Easylite as DJ 20 */
 UNUSUAL_DEV(  0x0ed1, 0x7636, 0x0103, 0x0103,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4e83f01..db373cf 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -547,8 +547,8 @@ config FB_TGA
 	  cards. Say Y if you have one of those.
 
 config FB_VESA
-	bool "VESA VGA graphics support"
+	tristate "VESA VGA graphics support"
 	depends on (FB = y) && X86
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index e16322d..f24dc44 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -23,11 +23,19 @@
 
 #include <video/vga.h>
 #include <asm/io.h>
+#ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
+#endif
 
 #define dac_reg	(0x3c8)
 #define dac_val	(0x3c9)
 
+struct vesafb_info
+{
+	u32 pseudo_palette[256];
+	int mtrr_hdl;
+};
+
 /* --------------------------------------------------------------------- */
 
 static struct fb_var_screeninfo vesafb_defined __initdata = {
@@ -41,22 +49,40 @@ static struct fb_var_screeninfo vesafb_defined __initdata = {
 	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
-static struct fb_fix_screeninfo vesafb_fix __initdata = {
+static struct fb_fix_screeninfo vesafb_fix = {
 	.id	= "VESA VGA",
 	.type	= FB_TYPE_PACKED_PIXELS,
 	.accel	= FB_ACCEL_NONE,
 };
 
-static int   inverse    __read_mostly;
-static int   mtrr       __read_mostly;		/* disable mtrr */
-static int   vram_remap __initdata;		/* Set amount of memory to be used */
-static int   vram_total __initdata;		/* Set total amount of memory */
-static int   pmi_setpal __read_mostly = 1;	/* pmi for palette changes ??? */
-static int   ypan       __read_mostly;		/* 0..nothing, 1..ypan, 2..ywrap */
-static void  (*pmi_start)(void) __read_mostly;
-static void  (*pmi_pal)  (void) __read_mostly;
-static int   depth      __read_mostly;
-static int   vga_compat __read_mostly;
+static int	mtrr		__read_mostly;	/* disable mtrr */
+static int	vram_remap	__initdata;	/* Set amount of memory to be used */
+static int	vram_total	__initdata;	/* Set total amount of memory */
+static int	pmi_setpal	__read_mostly = 1; /* pmi for palette changes ??? */
+static int	redraw		__read_mostly;
+static int	ypan		__read_mostly;	/* 0..nothing, 1..ypan, 2..ywrap */
+static int	ywrap		__read_mostly;
+static void	(*pmi_start)(void) __read_mostly;
+static void	(*pmi_pal)(void) __read_mostly;
+static int	depth		__read_mostly;
+static int	vga_compat	__read_mostly;
+
+module_param(redraw, bool, 0);
+module_param(ypan, bool, 0);
+module_param(ywrap, bool, 0);
+module_param_named(vgapal, pmi_setpal, invbool, 0);
+MODULE_PARM_DESC(vgapal, "Use VGA for setting palette (default)");
+module_param_named(pmipal, pmi_setpal, bool, 0);
+MODULE_PARM_DESC(pmipal, "Use PMI for setting palette");
+module_param(mtrr, bool, 0);
+MODULE_PARM_DESC(mtrr, "Enable MTRR support (default)");
+module_param_named(nomtrr, mtrr, invbool, 0);
+MODULE_PARM_DESC(nomtrr, "Disable MTRR support");
+module_param(vram_remap, int, 0);
+MODULE_PARM_DESC(vram_remap, "Set total amount of memory to be used");
+module_param(vram_total, int, 0);
+MODULE_PARM_DESC(vram_total, "Total amount of memory");
+
 /* --------------------------------------------------------------------- */
 
 static int vesafb_pan_display(struct fb_var_screeninfo *var,
@@ -183,6 +209,7 @@ static struct fb_ops vesafb_ops = {
 	.fb_imageblit	= cfb_imageblit,
 };
 
+#ifndef MODULE
 static int __init vesafb_setup(char *options)
 {
 	char *this_opt;
@@ -193,9 +220,7 @@ static int __init vesafb_setup(char *options)
 	while ((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt) continue;
 		
-		if (! strcmp(this_opt, "inverse"))
-			inverse=1;
-		else if (! strcmp(this_opt, "redraw"))
+		if (! strcmp(this_opt, "redraw"))
 			ypan=0;
 		else if (! strcmp(this_opt, "ypan"))
 			ypan=1;
@@ -216,10 +241,12 @@ static int __init vesafb_setup(char *options)
 	}
 	return 0;
 }
+#endif
 
 static int __init vesafb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
+	struct vesafb_info *vfb_info;
 	int i, err;
 	unsigned int size_vmode;
 	unsigned int size_remap;
@@ -278,13 +305,14 @@ static int __init vesafb_probe(struct platform_device *dev)
 		   spaces our resource handlers simply don't know about */
 	}
 
-	info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
+	info = framebuffer_alloc(sizeof(struct vesafb_info), &dev->dev);
 	if (!info) {
 		release_mem_region(vesafb_fix.smem_start, size_total);
 		return -ENOMEM;
 	}
-	info->pseudo_palette = info->par;
-	info->par = NULL;
+	vfb_info = (struct vesafb_info *) info->par;
+	vfb_info->mtrr_hdl = -1;
+	info->pseudo_palette = vfb_info->pseudo_palette;
 
 	info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
 	if (!info->screen_base) {
@@ -418,18 +446,16 @@ static int __init vesafb_probe(struct platform_device *dev)
 		}
 
 		if (type) {
-			int rc;
-
 			/* Find the largest power-of-two */
 			while (temp_size & (temp_size - 1))
 				temp_size &= (temp_size - 1);
 
 			/* Try and find a power of two to add */
 			do {
-				rc = mtrr_add(vesafb_fix.smem_start, temp_size,
+				vfb_info->mtrr_hdl = mtrr_add(vesafb_fix.smem_start, temp_size,
 					      type, 1);
 				temp_size >>= 1;
-			} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
+			} while (temp_size >= PAGE_SIZE && vfb_info->mtrr_hdl == -EINVAL);
 		}
 	}
 #endif
@@ -454,6 +480,7 @@ static int __init vesafb_probe(struct platform_device *dev)
 	}
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
 	       info->node, info->fix.id);
+	dev_set_drvdata(&dev->dev, info);
 	return 0;
 err:
 	if (info->screen_base)
@@ -463,8 +490,28 @@ err:
 	return err;
 }
 
+static int __exit vesafb_remove(struct platform_device *device)
+{
+	struct fb_info *info = dev_get_drvdata(&device->dev);
+
+	unregister_framebuffer(info);
+#ifdef CONFIG_MTRR
+	{
+		struct vesafb_info *vfb_info = (struct vesafb_info *) info->par;
+		if (vfb_info->mtrr_hdl >= 0)
+			mtrr_del(vfb_info->mtrr_hdl, 0, 0);
+	}
+#endif
+	iounmap(info->screen_base);
+	framebuffer_release(info);
+	release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len);
+
+	return 0;
+}
+
 static struct platform_driver vesafb_driver = {
 	.probe	= vesafb_probe,
+	.remove = vesafb_remove,
 	.driver	= {
 		.name	= "vesafb",
 	},
@@ -475,11 +522,18 @@ static struct platform_device *vesafb_device;
 static int __init vesafb_init(void)
 {
 	int ret;
+#ifndef MODULE
 	char *option = NULL;
 
 	/* ignore error return of fb_get_options */
 	fb_get_options("vesafb", &option);
 	vesafb_setup(option);
+#else
+	if (redraw)
+		ypan = 0;
+	if (ywrap)
+		ypan = 2;
+#endif
 	ret = platform_driver_register(&vesafb_driver);
 
 	if (!ret) {
@@ -498,6 +552,14 @@ static int __init vesafb_init(void)
 
 	return ret;
 }
+
+static void __exit vesafb_exit(void)
+{
+	platform_device_unregister(vesafb_device);
+	platform_driver_unregister(&vesafb_driver);
+}
+
 module_init(vesafb_init);
+module_exit(vesafb_exit);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 6aff63d..9baed7d 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/screen_info.h>
+#include <linux/dmi.h>
 
 #include <asm/io.h>
 #include <video/vga.h>
@@ -80,18 +81,18 @@ struct vga16fb_par {
 
 static struct fb_var_screeninfo vga16fb_defined __initdata = {
 	.xres		= 640,
-	.yres		= 480,
+	.yres		= 400,
 	.xres_virtual	= 640,
-	.yres_virtual	= 480,
+	.yres_virtual	= 400,
 	.bits_per_pixel	= 4,	
 	.activate	= FB_ACTIVATE_TEST,
 	.height		= -1,
 	.width		= -1,
 	.pixclock	= 39721,
-	.left_margin	= 48,
-	.right_margin	= 16,
-	.upper_margin	= 33,
-	.lower_margin	= 10,
+	.left_margin	= 40,
+	.right_margin	= 24,
+	.upper_margin	= 39,
+	.lower_margin	= 9,
 	.hsync_len 	= 96,
 	.vsync_len	= 2,
 	.vmode		= FB_VMODE_NONINTERLACED,
@@ -1315,6 +1316,17 @@ static struct fb_ops vga16fb_ops = {
 	.fb_imageblit	= vga16fb_imageblit,
 };
 
+static int __init vga16fb_fudge(struct dmi_system_id *d)
+{
+	vga16fb_defined.yres = 480;
+	vga16fb_defined.yres_virtual = 480;
+	vga16fb_defined.left_margin = 48;
+	vga16fb_defined.right_margin = 16;
+	vga16fb_defined.upper_margin = 33;
+	vga16fb_defined.lower_margin = 10;
+	return 0;
+}
+
 #ifndef MODULE
 static int vga16fb_setup(char *options)
 {
@@ -1330,6 +1342,19 @@ static int vga16fb_setup(char *options)
 }
 #endif
 
+static struct dmi_system_id __initdata vga16fb_dmi_table[] = {
+	{
+		vga16fb_fudge, "Apple",
+		{ DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), },
+	},
+	{
+		vga16fb_fudge, "Sony VGN-S260",
+		{ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), },
+		{ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-S260"), },
+	},
+	{ }
+};
+
 static int __init vga16fb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
@@ -1340,6 +1365,8 @@ static int __init vga16fb_probe(struct platform_device *dev)
 	printk(KERN_DEBUG "vga16fb: initializing\n");
 	info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev);
 
+	dmi_check_system(vga16fb_dmi_table);
+
 	if (!info) {
 		ret = -ENOMEM;
 		goto err_fb_alloc;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 23ab145..48d1f13 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -444,6 +444,7 @@ static void nfs_destroy_server(struct nfs_server *server)
  */
 static int nfs_start_lockd(struct nfs_server *server)
 {
+	static int warned;
 	int error = 0;
 
 	if (server->nfs_client->cl_nfsversion > 3)
@@ -452,9 +453,28 @@ static int nfs_start_lockd(struct nfs_server *server)
 		goto out;
 	error = lockd_up((server->flags & NFS_MOUNT_TCP) ?
 			IPPROTO_TCP : IPPROTO_UDP);
-	if (error < 0)
+	if (error < 0) {
+		/*
+		 * Ubuntu: fix NFS mounting regression from Edgy->Feisty.
+		 * In 2.6.18 and older kernels any failures to start lockd were
+		 * ignored.  This meant an Edgy user could successfully mount
+		 * NFS filesystems without having installed nfs-common.
+		 * 
+		 * This behaviour has been changed in 2.6.19 and later kernels,
+		 * and so mounting NFS filesystems without nfs-common fail with
+		 * can't read superblock.
+		 *
+		 * This workaround fixes this by issuing a warning (on the first
+		 * lockd start failure), and then allowing the mount to continue
+		 * without locking.
+		 */
+		if (warned++ == 0) {
+			printk(KERN_ERR "nfs: Starting lockd failed (do you have nfs-common installed?).\n");
+			printk(KERN_ERR "nfs: Continuing anyway, but this workaround will go away soon.\n");
+		}
 		server->flags |= NFS_MOUNT_NONLM;
-	else
+		error = 0;
+	} else
 		server->destroy = nfs_destroy_server;
 out:
 	return error;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index b37ce33..cc15b52 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -638,6 +638,19 @@ static int execdomains_read_proc(char *page, char **start, off_t off,
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
+#ifdef CONFIG_VERSION_SIGNATURE
+static int version_signature_read_proc(char *page, char **start, off_t off,
+				       int count, int *eof, void *data)
+{
+	int len;
+
+	strcpy(page, CONFIG_VERSION_SIGNATURE);
+	strcat(page, "\n");
+	len = strlen(page);
+	return proc_calc_metrics(page, start, off, count, eof, len);
+}
+#endif
+
 #ifdef CONFIG_MAGIC_SYSRQ
 /*
  * writing 'C' to /proc/sysrq-trigger is like sysrq-C
@@ -691,6 +704,9 @@ void __init proc_misc_init(void)
 		{"cmdline",	cmdline_read_proc},
 		{"locks",	locks_read_proc},
 		{"execdomains",	execdomains_read_proc},
+#ifdef CONFIG_VERSION_SIGNATURE
+		{"version_signature", version_signature_read_proc},
+#endif
 		{NULL,}
 	};
 	for (p = simple_ones; p->name; p++)
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 0cd63bc..85143e1 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -95,6 +95,10 @@ acpi_status
 acpi_os_table_override(struct acpi_table_header *existing_table,
 		       struct acpi_table_header **new_table);
 
+#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
+extern int acpi_must_unregister_table;
+#endif
+
 /*
  * Spinlock primitives
  */
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 326da7d..a914398 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -12,6 +12,7 @@
 #define APOLLO_MOUSE_MINOR 7
 #define PC110PAD_MINOR 9
 /*#define ADB_MOUSE_MINOR 10	FIXME OBSOLETE */
+#define SYNTH_MINOR   25
 #define WATCHDOG_MINOR		130	/* Watchdog timer     */
 #define TEMP_MINOR		131	/* Temperature Sensor */
 #define RTC_MINOR 135
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index ed29622..f5fcffb 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -77,6 +77,21 @@ config PM_SYSFS_DEPRECATED
 	  handle the wide variability of device power states; any replacements
 	  are likely to be bus or driver specific.
 
+config PM_DISABLE_CONSOLE
+	bool "Disable Power Management messing with the active console"
+	depends on PM
+	default n
+	---help---
+	  By defauly, PM will take over the active console (generally, this means
+	  switching to the console when suspending from X). This can at times cause
+	  problems, especially if userspace suspend scripts try to do things with the
+	  console before or after suspending (e.g. calling vbestate).
+
+	  To work around this, enable this option so that PM will not handle the
+	  console.
+
+	  If unsure, say N.
+
 config SOFTWARE_SUSPEND
 	bool "Software Suspend"
 	depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP))
diff --git a/kernel/power/console.c b/kernel/power/console.c
index 623786d..e916793 100644
--- a/kernel/power/console.c
+++ b/kernel/power/console.c
@@ -16,6 +16,7 @@ static int orig_fgconsole, orig_kmsg;
 
 int pm_prepare_console(void)
 {
+#ifndef CONFIG_PM_DISABLE_CONSOLE
 	acquire_console_sem();
 
 	orig_fgconsole = fg_console;
@@ -36,15 +37,18 @@ int pm_prepare_console(void)
 	}
 	orig_kmsg = kmsg_redirect;
 	kmsg_redirect = SUSPEND_CONSOLE;
+#endif
 	return 0;
 }
 
 void pm_restore_console(void)
 {
+#ifndef CONFIG_PM_DISABLE_CONSOLE
 	acquire_console_sem();
 	set_console(orig_fgconsole);
 	release_console_sem();
 	kmsg_redirect = orig_kmsg;
+#endif
 	return;
 }
 #endif
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index 7c434e0..d144d12 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -74,7 +74,7 @@ deb-pkg: FORCE
 	$(MAKE) KBUILD_SRC=
 	$(CONFIG_SHELL) $(srctree)/scripts/package/builddeb
 
-clean-dirs += $(objtree)/debian/
+#clean-dirs += $(objtree)/debian/
 
 
 # tarball targets


-- 
Ubuntu:    http://www.ubuntu.com/
Linux1394: http://www.linux1394.org/





More information about the kernel-team mailing list