vserver 1.9.5.x5
[linux-2.6.git] / drivers / pnp / pnpbios / core.c
index 967ecb2..0d1736c 100644 (file)
 #include <linux/pnpbios.h>
 #include <linux/device.h>
 #include <linux/pnp.h>
-#include <asm/page.h>
-#include <asm/system.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <asm/desc.h>
 #include <linux/slab.h>
-#include <linux/kmod.h>
+#include <linux/kobject_uevent.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
+#include <linux/dmi.h>
+#include <linux/delay.h>
+#include <linux/acpi.h>
+
+#include <asm/page.h>
+#include <asm/desc.h>
 #include <asm/system.h>
 #include <asm/byteorder.h>
 
@@ -129,7 +132,7 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
        /* only one standardized param to hotplug command: type */
        argv [0] = hotplug_path;
        argv [1] = "dock";
-       argv [2] = 0;
+       argv [2] = NULL;
 
        /* minimal command environment */
        envp [i++] = "HOME=/";
@@ -152,7 +155,7 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
        envp [i++] = scratch;
        scratch += sprintf (scratch, "DOCK=%x/%x/%x",
                info->location_id, info->serial, info->capabilities);
-       envp[i] = 0;
+       envp[i] = NULL;
        
        value = call_usermodehelper (argv [0], argv, envp, 0);
        kfree (buf);
@@ -176,8 +179,7 @@ static int pnp_dock_thread(void * unused)
                /*
                 * Poll every 2 seconds
                 */
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ*2);
+               msleep_interruptible(2000);
                if(signal_pending(current))
                        break;
 
@@ -251,8 +253,10 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table
        node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -1;
-       if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node))
+       if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) {
+               kfree(node);
                return -ENODEV;
+       }
        if(pnpbios_write_resources_to_node(res, node)<0) {
                kfree(node);
                return -1;
@@ -498,14 +502,51 @@ int __init pnpbios_probe_system(void)
        return 0;
 }
 
+static int __init exploding_pnp_bios(struct dmi_system_id *d)
+{
+       printk(KERN_WARNING "%s detected. Disabling PnPBIOS\n", d->ident);
+       return 0;
+}
+
+static struct dmi_system_id pnpbios_dmi_table[] = {
+       {       /* PnPBIOS GPF on boot */
+               .callback = exploding_pnp_bios,
+               .ident = "Higraded P14H",
+               .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+                       DMI_MATCH(DMI_BIOS_VERSION, "07.00T"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Higraded"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P14H"),
+               },
+       },
+       {       /* PnPBIOS GPF on boot */
+               .callback = exploding_pnp_bios,
+               .ident = "ASUS P4P800",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
+                       DMI_MATCH(DMI_BOARD_NAME, "P4P800"),
+               },
+       },
+       { }
+};
+
 int __init pnpbios_init(void)
 {
        int ret;
-       if(pnpbios_disabled || (dmi_broken & BROKEN_PNP_BIOS)) {
+
+       if (pnpbios_disabled || dmi_check_system(pnpbios_dmi_table)) {
                printk(KERN_INFO "PnPBIOS: Disabled\n");
                return -ENODEV;
        }
 
+#ifdef CONFIG_PNPACPI
+       if (!acpi_disabled && !pnpacpi_disabled) {
+               pnpbios_disabled = 1;
+               printk(KERN_INFO "PnPBIOS: Disabled by ACPI PNP\n");
+               return -ENODEV;
+       }
+#endif /* CONFIG_ACPI */
+
        /* scan the system for pnpbios support */
        if (!pnpbios_probe_system())
                return -ENODEV;
@@ -542,6 +583,8 @@ subsys_initcall(pnpbios_init);
 
 static int __init pnpbios_thread_init(void)
 {
+       if (pnpbios_disabled)
+               return 0;
 #ifdef CONFIG_HOTPLUG
        init_completion(&unload_sem);
        if (kernel_thread(pnp_dock_thread, NULL, CLONE_KERNEL) > 0)