diff options
Diffstat (limited to 'drivers/pnp/pnpbios')
-rw-r--r-- | drivers/pnp/pnpbios/bioscalls.c | 45 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/core.c | 8 |
2 files changed, 21 insertions, 32 deletions
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 6b7583f497d0..a1f0b0ba2bfe 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c | |||
@@ -31,15 +31,6 @@ static struct { | |||
31 | } pnp_bios_callpoint; | 31 | } pnp_bios_callpoint; |
32 | 32 | ||
33 | 33 | ||
34 | /* The PnP BIOS entries in the GDT */ | ||
35 | #define PNP_GDT (GDT_ENTRY_PNPBIOS_BASE * 8) | ||
36 | |||
37 | #define PNP_CS32 (PNP_GDT+0x00) /* segment for calling fn */ | ||
38 | #define PNP_CS16 (PNP_GDT+0x08) /* code segment for BIOS */ | ||
39 | #define PNP_DS (PNP_GDT+0x10) /* data segment for BIOS */ | ||
40 | #define PNP_TS1 (PNP_GDT+0x18) /* transfer data segment */ | ||
41 | #define PNP_TS2 (PNP_GDT+0x20) /* another data segment */ | ||
42 | |||
43 | /* | 34 | /* |
44 | * These are some opcodes for a "static asmlinkage" | 35 | * These are some opcodes for a "static asmlinkage" |
45 | * As this code is *not* executed inside the linux kernel segment, but in a | 36 | * As this code is *not* executed inside the linux kernel segment, but in a |
@@ -67,16 +58,11 @@ __asm__( | |||
67 | ".previous \n" | 58 | ".previous \n" |
68 | ); | 59 | ); |
69 | 60 | ||
70 | #define Q_SET_SEL(cpu, selname, address, size) \ | ||
71 | do { \ | ||
72 | set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \ | ||
73 | set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ | ||
74 | } while(0) | ||
75 | |||
76 | #define Q2_SET_SEL(cpu, selname, address, size) \ | 61 | #define Q2_SET_SEL(cpu, selname, address, size) \ |
77 | do { \ | 62 | do { \ |
78 | set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \ | 63 | struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ |
79 | set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ | 64 | set_base(gdt[(selname) >> 3], (u32)(address)); \ |
65 | set_limit(gdt[(selname) >> 3], size); \ | ||
80 | } while(0) | 66 | } while(0) |
81 | 67 | ||
82 | static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; | 68 | static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; |
@@ -115,8 +101,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, | |||
115 | return PNP_FUNCTION_NOT_SUPPORTED; | 101 | return PNP_FUNCTION_NOT_SUPPORTED; |
116 | 102 | ||
117 | cpu = get_cpu(); | 103 | cpu = get_cpu(); |
118 | save_desc_40 = per_cpu(cpu_gdt_table,cpu)[0x40 / 8]; | 104 | save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; |
119 | per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = bad_bios_desc; | 105 | get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; |
120 | 106 | ||
121 | /* On some boxes IRQ's during PnP BIOS calls are deadly. */ | 107 | /* On some boxes IRQ's during PnP BIOS calls are deadly. */ |
122 | spin_lock_irqsave(&pnp_bios_lock, flags); | 108 | spin_lock_irqsave(&pnp_bios_lock, flags); |
@@ -158,7 +144,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, | |||
158 | ); | 144 | ); |
159 | spin_unlock_irqrestore(&pnp_bios_lock, flags); | 145 | spin_unlock_irqrestore(&pnp_bios_lock, flags); |
160 | 146 | ||
161 | per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = save_desc_40; | 147 | get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; |
162 | put_cpu(); | 148 | put_cpu(); |
163 | 149 | ||
164 | /* If we get here and this is set then the PnP BIOS faulted on us. */ | 150 | /* If we get here and this is set then the PnP BIOS faulted on us. */ |
@@ -290,12 +276,15 @@ int pnp_bios_dev_node_info(struct pnp_dev_node_info *data) | |||
290 | static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) | 276 | static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) |
291 | { | 277 | { |
292 | u16 status; | 278 | u16 status; |
279 | u16 tmp_nodenum; | ||
293 | if (!pnp_bios_present()) | 280 | if (!pnp_bios_present()) |
294 | return PNP_FUNCTION_NOT_SUPPORTED; | 281 | return PNP_FUNCTION_NOT_SUPPORTED; |
295 | if ( !boot && pnpbios_dont_use_current_config ) | 282 | if ( !boot && pnpbios_dont_use_current_config ) |
296 | return PNP_FUNCTION_NOT_SUPPORTED; | 283 | return PNP_FUNCTION_NOT_SUPPORTED; |
284 | tmp_nodenum = *nodenum; | ||
297 | status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0, | 285 | status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0, |
298 | nodenum, sizeof(char), data, 65536); | 286 | &tmp_nodenum, sizeof(tmp_nodenum), data, 65536); |
287 | *nodenum = tmp_nodenum; | ||
299 | return status; | 288 | return status; |
300 | } | 289 | } |
301 | 290 | ||
@@ -535,10 +524,12 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header) | |||
535 | 524 | ||
536 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); | 525 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
537 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); | 526 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
538 | for(i=0; i < NR_CPUS; i++) | 527 | for (i = 0; i < NR_CPUS; i++) { |
539 | { | 528 | struct desc_struct *gdt = get_cpu_gdt_table(i); |
540 | Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024); | 529 | if (!gdt) |
541 | Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024); | 530 | continue; |
542 | Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024); | 531 | set_base(gdt[GDT_ENTRY_PNPBIOS_CS32], &pnp_bios_callfunc); |
543 | } | 532 | set_base(gdt[GDT_ENTRY_PNPBIOS_CS16], __va(header->fields.pm16cseg)); |
533 | set_base(gdt[GDT_ENTRY_PNPBIOS_DS], __va(header->fields.pm16dseg)); | ||
534 | } | ||
544 | } | 535 | } |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index f49674f07949..b154b3f52cbe 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/mm.h> | 56 | #include <linux/mm.h> |
57 | #include <linux/smp.h> | 57 | #include <linux/smp.h> |
58 | #include <linux/slab.h> | 58 | #include <linux/slab.h> |
59 | #include <linux/kobject_uevent.h> | ||
60 | #include <linux/completion.h> | 59 | #include <linux/completion.h> |
61 | #include <linux/spinlock.h> | 60 | #include <linux/spinlock.h> |
62 | #include <linux/dmi.h> | 61 | #include <linux/dmi.h> |
@@ -106,8 +105,6 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) | |||
106 | char *argv [3], **envp, *buf, *scratch; | 105 | char *argv [3], **envp, *buf, *scratch; |
107 | int i = 0, value; | 106 | int i = 0, value; |
108 | 107 | ||
109 | if (!hotplug_path [0]) | ||
110 | return -ENOENT; | ||
111 | if (!current->fs->root) { | 108 | if (!current->fs->root) { |
112 | return -EAGAIN; | 109 | return -EAGAIN; |
113 | } | 110 | } |
@@ -119,8 +116,9 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) | |||
119 | return -ENOMEM; | 116 | return -ENOMEM; |
120 | } | 117 | } |
121 | 118 | ||
122 | /* only one standardized param to hotplug command: type */ | 119 | /* FIXME: if there are actual users of this, it should be integrated into |
123 | argv [0] = hotplug_path; | 120 | * the driver core and use the usual infrastructure like sysfs and uevents */ |
121 | argv [0] = "/sbin/pnpbios"; | ||
124 | argv [1] = "dock"; | 122 | argv [1] = "dock"; |
125 | argv [2] = NULL; | 123 | argv [2] = NULL; |
126 | 124 | ||