aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp/pnpbios/bioscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp/pnpbios/bioscalls.c')
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c45
1 files changed, 18 insertions, 27 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) \
71do { \
72set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \
73set_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) \
77do { \ 62do { \
78set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \ 63struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
79set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ 64set_base(gdt[(selname) >> 3], (u32)(address)); \
65set_limit(gdt[(selname) >> 3], size); \
80} while(0) 66} while(0)
81 67
82static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; 68static 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)
290static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) 276static 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}