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(®s, (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(®s);
+
+ if (copy_to_user((SMMRegisters*)arg, ®s, 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