x86: Introduce set_desc_base() and set_desc_limit()
[safe/jmp/linux-2.6] / drivers / pnp / pnpbios / bioscalls.c
index a721261..45ad3e9 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * bioscalls.c - the lowlevel layer of the PnPBIOS driver
- *
  */
 
 #include <linux/types.h>
@@ -8,7 +7,6 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 #include <linux/kernel.h>
-#include <linux/pnpbios.h>
 #include <linux/device.h>
 #include <linux/pnp.h>
 #include <linux/mm.h>
 #include "pnpbios.h"
 
 static struct {
-       u16     offset;
-       u16     segment;
+       u16 offset;
+       u16 segment;
 } pnp_bios_callpoint;
 
-
 /*
  * These are some opcodes for a "static asmlinkage"
  * As this code is *not* executed inside the linux kernel segment, but in a
@@ -44,8 +41,7 @@ static struct {
 
 asmlinkage void pnp_bios_callfunc(void);
 
-__asm__(
-       ".text                  \n"
+__asm__(".text                 \n"
        __ALIGN_STR "\n"
        "pnp_bios_callfunc:\n"
        "       pushl %edx      \n"
@@ -55,24 +51,16 @@ __asm__(
        "       lcallw *pnp_bios_callpoint\n"
        "       addl $16, %esp  \n"
        "       lret            \n"
-       ".previous              \n"
-);
-
-#define Q_SET_SEL(cpu, selname, address, size) \
-do { \
-struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
-set_base(gdt[(selname) >> 3], __va((u32)(address))); \
-set_limit(gdt[(selname) >> 3], size); \
-} while(0)
+       ".previous              \n");
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
-set_base(gdt[(selname) >> 3], (u32)(address)); \
-set_limit(gdt[(selname) >> 3], size); \
+       struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+       set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
+       set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
 } while(0)
 
-static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
+static struct desc_struct bad_bios_desc;
 
 /*
  * At some point we want to use this stack frame pointer to unwind
@@ -85,7 +73,6 @@ u32 pnp_bios_is_utter_crap = 0;
 
 static spinlock_t pnp_bios_lock;
 
-
 /*
  * Support Functions
  */
@@ -104,7 +91,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
         * PnP BIOSes are generally not terribly re-entrant.
         * Also, don't rely on them to save everything correctly.
         */
-       if(pnp_bios_is_utter_crap)
+       if (pnp_bios_is_utter_crap)
                return PNP_FUNCTION_NOT_SUPPORTED;
 
        cpu = get_cpu();
@@ -120,112 +107,128 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
        if (ts2_size)
                Q2_SET_SEL(smp_processor_id(), PNP_TS2, ts2_base, ts2_size);
 
-       __asm__ __volatile__(
-               "pushl %%ebp\n\t"
-               "pushl %%edi\n\t"
-               "pushl %%esi\n\t"
-               "pushl %%ds\n\t"
-               "pushl %%es\n\t"
-               "pushl %%fs\n\t"
-               "pushl %%gs\n\t"
-               "pushfl\n\t"
-               "movl %%esp, pnp_bios_fault_esp\n\t"
-               "movl $1f, pnp_bios_fault_eip\n\t"
-               "lcall %5,%6\n\t"
-               "1:popfl\n\t"
-               "popl %%gs\n\t"
-               "popl %%fs\n\t"
-               "popl %%es\n\t"
-               "popl %%ds\n\t"
-               "popl %%esi\n\t"
-               "popl %%edi\n\t"
-               "popl %%ebp\n\t"
-               : "=a" (status)
-               : "0" ((func) | (((u32)arg1) << 16)),
-                 "b" ((arg2) | (((u32)arg3) << 16)),
-                 "c" ((arg4) | (((u32)arg5) << 16)),
-                 "d" ((arg6) | (((u32)arg7) << 16)),
-                 "i" (PNP_CS32),
-                 "i" (0)
-               : "memory"
-       );
+       __asm__ __volatile__("pushl %%ebp\n\t"
+                            "pushl %%edi\n\t"
+                            "pushl %%esi\n\t"
+                            "pushl %%ds\n\t"
+                            "pushl %%es\n\t"
+                            "pushl %%fs\n\t"
+                            "pushl %%gs\n\t"
+                            "pushfl\n\t"
+                            "movl %%esp, pnp_bios_fault_esp\n\t"
+                            "movl $1f, pnp_bios_fault_eip\n\t"
+                            "lcall %5,%6\n\t"
+                            "1:popfl\n\t"
+                            "popl %%gs\n\t"
+                            "popl %%fs\n\t"
+                            "popl %%es\n\t"
+                            "popl %%ds\n\t"
+                            "popl %%esi\n\t"
+                            "popl %%edi\n\t"
+                            "popl %%ebp\n\t":"=a"(status)
+                            :"0"((func) | (((u32) arg1) << 16)),
+                            "b"((arg2) | (((u32) arg3) << 16)),
+                            "c"((arg4) | (((u32) arg5) << 16)),
+                            "d"((arg6) | (((u32) arg7) << 16)),
+                            "i"(PNP_CS32), "i"(0)
+                            :"memory");
        spin_unlock_irqrestore(&pnp_bios_lock, flags);
 
        get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
        put_cpu();
 
        /* If we get here and this is set then the PnP BIOS faulted on us. */
-       if(pnp_bios_is_utter_crap)
-       {
-               printk(KERN_ERR "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue\n");
-               printk(KERN_ERR "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably\n");
-               printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS\n");
+       if (pnp_bios_is_utter_crap) {
+               printk(KERN_ERR
+                      "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue\n");
+               printk(KERN_ERR
+                      "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably\n");
+               printk(KERN_ERR
+                      "PnPBIOS: Check with your vendor for an updated BIOS\n");
        }
 
        return status;
 }
 
-void pnpbios_print_status(const char * module, u16 status)
+void pnpbios_print_status(const char *module, u16 status)
 {
-       switch(status) {
+       switch (status) {
        case PNP_SUCCESS:
                printk(KERN_ERR "PnPBIOS: %s: function successful\n", module);
                break;
        case PNP_NOT_SET_STATICALLY:
-               printk(KERN_ERR "PnPBIOS: %s: unable to set static resources\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: unable to set static resources\n",
+                      module);
                break;
        case PNP_UNKNOWN_FUNCTION:
-               printk(KERN_ERR "PnPBIOS: %s: invalid function number passed\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: invalid function number passed\n",
+                      module);
                break;
        case PNP_FUNCTION_NOT_SUPPORTED:
-               printk(KERN_ERR "PnPBIOS: %s: function not supported on this system\n", module);
+               printk(KERN_ERR
+                      "PnPBIOS: %s: function not supported on this system\n",
+                      module);
                break;
        case PNP_INVALID_HANDLE:
                printk(KERN_ERR "PnPBIOS: %s: invalid handle\n", module);
                break;
        case PNP_BAD_PARAMETER:
-               printk(KERN_ERR "PnPBIOS: %s: invalid parameters were passed\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: invalid parameters were passed\n",
+                      module);
                break;
        case PNP_SET_FAILED:
-               printk(KERN_ERR "PnPBIOS: %s: unable to set resources\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: unable to set resources\n",
+                      module);
                break;
        case PNP_EVENTS_NOT_PENDING:
                printk(KERN_ERR "PnPBIOS: %s: no events are pending\n", module);
                break;
        case PNP_SYSTEM_NOT_DOCKED:
-               printk(KERN_ERR "PnPBIOS: %s: the system is not docked\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: the system is not docked\n",
+                      module);
                break;
        case PNP_NO_ISA_PNP_CARDS:
-               printk(KERN_ERR "PnPBIOS: %s: no isapnp cards are installed on this system\n", module);
+               printk(KERN_ERR
+                      "PnPBIOS: %s: no isapnp cards are installed on this system\n",
+                      module);
                break;
        case PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES:
-               printk(KERN_ERR "PnPBIOS: %s: cannot determine the capabilities of the docking station\n", module);
+               printk(KERN_ERR
+                      "PnPBIOS: %s: cannot determine the capabilities of the docking station\n",
+                      module);
                break;
        case PNP_CONFIG_CHANGE_FAILED_NO_BATTERY:
-               printk(KERN_ERR "PnPBIOS: %s: unable to undock, the system does not have a battery\n", module);
+               printk(KERN_ERR
+                      "PnPBIOS: %s: unable to undock, the system does not have a battery\n",
+                      module);
                break;
        case PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT:
-               printk(KERN_ERR "PnPBIOS: %s: could not dock due to resource conflicts\n", module);
+               printk(KERN_ERR
+                      "PnPBIOS: %s: could not dock due to resource conflicts\n",
+                      module);
                break;
        case PNP_BUFFER_TOO_SMALL:
-               printk(KERN_ERR "PnPBIOS: %s: the buffer passed is too small\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: the buffer passed is too small\n",
+                      module);
                break;
        case PNP_USE_ESCD_SUPPORT:
                printk(KERN_ERR "PnPBIOS: %s: use ESCD instead\n", module);
                break;
        case PNP_MESSAGE_NOT_SUPPORTED:
-               printk(KERN_ERR "PnPBIOS: %s: the message is unsupported\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: the message is unsupported\n",
+                      module);
                break;
        case PNP_HARDWARE_ERROR:
-               printk(KERN_ERR "PnPBIOS: %s: a hardware failure has occured\n", module);
+               printk(KERN_ERR "PnPBIOS: %s: a hardware failure has occured\n",
+                      module);
                break;
        default:
-               printk(KERN_ERR "PnPBIOS: %s: unexpected status 0x%x\n", module, status);
+               printk(KERN_ERR "PnPBIOS: %s: unexpected status 0x%x\n", module,
+                      status);
                break;
        }
 }
 
-
 /*
  * PnP BIOS Low Level Calls
  */
@@ -250,19 +253,22 @@ void pnpbios_print_status(const char * module, u16 status)
 static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
 {
        u16 status;
+
        if (!pnp_bios_present())
                return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0,
-                              data, sizeof(struct pnp_dev_node_info), NULL, 0);
+       status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2,
+                              PNP_TS1, PNP_DS, 0, 0, data,
+                              sizeof(struct pnp_dev_node_info), NULL, 0);
        data->no_nodes &= 0xff;
        return status;
 }
 
 int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
 {
-       int status = __pnp_bios_dev_node_info( data );
-       if ( status )
-               pnpbios_print_status( "dev_node_info", status );
+       int status = __pnp_bios_dev_node_info(data);
+
+       if (status)
+               pnpbios_print_status("dev_node_info", status);
        return status;
 }
 
@@ -280,17 +286,20 @@ int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
  *               or volatile current (0) config
  * Output: *nodenum=next node or 0xff if no more nodes
  */
-static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
+static int __pnp_bios_get_dev_node(u8 *nodenum, char boot,
+                                  struct pnp_bios_node *data)
 {
        u16 status;
        u16 tmp_nodenum;
+
        if (!pnp_bios_present())
                return PNP_FUNCTION_NOT_SUPPORTED;
-       if ( !boot && pnpbios_dont_use_current_config )
+       if (!boot && pnpbios_dont_use_current_config)
                return PNP_FUNCTION_NOT_SUPPORTED;
        tmp_nodenum = *nodenum;
-       status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
-                              &tmp_nodenum, sizeof(tmp_nodenum), data, 65536);
+       status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2,
+                              boot ? 2 : 1, PNP_DS, 0, &tmp_nodenum,
+                              sizeof(tmp_nodenum), data, 65536);
        *nodenum = tmp_nodenum;
        return status;
 }
@@ -298,104 +307,66 @@ static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node
 int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
 {
        int status;
-       status =  __pnp_bios_get_dev_node( nodenum, boot, data );
-       if ( status )
-               pnpbios_print_status( "get_dev_node", status );
+
+       status = __pnp_bios_get_dev_node(nodenum, boot, data);
+       if (status)
+               pnpbios_print_status("get_dev_node", status);
        return status;
 }
 
-
 /*
  * Call PnP BIOS with function 0x02, "set system device node"
  * Input: *nodenum = desired node, 
  *        boot = whether to set nonvolatile boot (!=0)
  *               or volatile current (0) config
  */
-static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
+static int __pnp_bios_set_dev_node(u8 nodenum, char boot,
+                                  struct pnp_bios_node *data)
 {
        u16 status;
+
        if (!pnp_bios_present())
                return PNP_FUNCTION_NOT_SUPPORTED;
-       if ( !boot && pnpbios_dont_use_current_config )
+       if (!boot && pnpbios_dont_use_current_config)
                return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0,
-                              data, 65536, NULL, 0);
+       status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1,
+                              boot ? 2 : 1, PNP_DS, 0, 0, data, 65536, NULL,
+                              0);
        return status;
 }
 
 int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
 {
        int status;
-       status =  __pnp_bios_set_dev_node( nodenum, boot, data );
-       if ( status ) {
-               pnpbios_print_status( "set_dev_node", status );
+
+       status = __pnp_bios_set_dev_node(nodenum, boot, data);
+       if (status) {
+               pnpbios_print_status("set_dev_node", status);
                return status;
        }
-       if ( !boot ) { /* Update devlist */
-               status =  pnp_bios_get_dev_node( &nodenum, boot, data );
-               if ( status )
+       if (!boot) {            /* Update devlist */
+               status = pnp_bios_get_dev_node(&nodenum, boot, data);
+               if (status)
                        return status;
        }
        return status;
 }
 
-#if needed
-/*
- * Call PnP BIOS with function 0x03, "get event"
- */
-static int pnp_bios_get_event(u16 *event)
-{
-       u16 status;
-       if (!pnp_bios_present())
-               return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0,
-                              event, sizeof(u16), NULL, 0);
-       return status;
-}
-#endif
-
-#if needed
-/*
- * Call PnP BIOS with function 0x04, "send message"
- */
-static int pnp_bios_send_message(u16 message)
-{
-       u16 status;
-       if (!pnp_bios_present())
-               return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-       return status;
-}
-#endif
-
 /*
  * Call PnP BIOS with function 0x05, "get docking station information"
  */
 int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
 {
        u16 status;
-       if (!pnp_bios_present())
-               return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
-                              data, sizeof(struct pnp_docking_station_info), NULL, 0);
-       return status;
-}
 
-#if needed
-/*
- * Call PnP BIOS with function 0x09, "set statically allocated resource
- * information"
- */
-static int pnp_bios_set_stat_res(char *info)
-{
-       u16 status;
        if (!pnp_bios_present())
                return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
-                              info, *((u16 *) info), 0, 0);
+       status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1,
+                              PNP_DS, 0, 0, 0, 0, data,
+                              sizeof(struct pnp_docking_station_info), NULL,
+                              0);
        return status;
 }
-#endif
 
 /*
  * Call PnP BIOS with function 0x0a, "get statically allocated resource
@@ -404,36 +375,23 @@ static int pnp_bios_set_stat_res(char *info)
 static int __pnp_bios_get_stat_res(char *info)
 {
        u16 status;
+
        if (!pnp_bios_present())
                return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
-                              info, 65536, NULL, 0);
+       status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1,
+                              PNP_DS, 0, 0, 0, 0, info, 65536, NULL, 0);
        return status;
 }
 
 int pnp_bios_get_stat_res(char *info)
 {
        int status;
-       status = __pnp_bios_get_stat_res( info );
-       if ( status )
-               pnpbios_print_status( "get_stat_res", status );
-       return status;
-}
 
-#if needed
-/*
- * Call PnP BIOS with function 0x0b, "get APM id table"
- */
-static int pnp_bios_apm_id_table(char *table, u16 *size)
-{
-       u16 status;
-       if (!pnp_bios_present())
-               return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0,
-                              table, *size, size, sizeof(u16));
+       status = __pnp_bios_get_stat_res(info);
+       if (status)
+               pnpbios_print_status("get_stat_res", status);
        return status;
 }
-#endif
 
 /*
  * Call PnP BIOS with function 0x40, "get isa pnp configuration structure"
@@ -441,19 +399,22 @@ static int pnp_bios_apm_id_table(char *table, u16 *size)
 static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
 {
        u16 status;
+
        if (!pnp_bios_present())
                return PNP_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
-                              data, sizeof(struct pnp_isa_config_struc), NULL, 0);
+       status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS,
+                              0, 0, 0, 0, data,
+                              sizeof(struct pnp_isa_config_struc), NULL, 0);
        return status;
 }
 
 int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
 {
        int status;
-       status = __pnp_bios_isapnp_config( data );
-       if ( status )
-               pnpbios_print_status( "isapnp_config", status );
+
+       status = __pnp_bios_isapnp_config(data);
+       if (status)
+               pnpbios_print_status("isapnp_config", status);
        return status;
 }
 
@@ -463,19 +424,22 @@ int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
 static int __pnp_bios_escd_info(struct escd_info_struc *data)
 {
        u16 status;
+
        if (!pnp_bios_present())
                return ESCD_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS,
-                              data, sizeof(struct escd_info_struc), NULL, 0);
+       status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4,
+                              PNP_TS1, PNP_DS, data,
+                              sizeof(struct escd_info_struc), NULL, 0);
        return status;
 }
 
 int pnp_bios_escd_info(struct escd_info_struc *data)
 {
        int status;
-       status = __pnp_bios_escd_info( data );
-       if ( status )
-               pnpbios_print_status( "escd_info", status );
+
+       status = __pnp_bios_escd_info(data);
+       if (status)
+               pnpbios_print_status("escd_info", status);
        return status;
 }
 
@@ -486,57 +450,46 @@ int pnp_bios_escd_info(struct escd_info_struc *data)
 static int __pnp_bios_read_escd(char *data, u32 nvram_base)
 {
        u16 status;
+
        if (!pnp_bios_present())
                return ESCD_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
-                              data, 65536, __va(nvram_base), 65536);
+       status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0,
+                              0, data, 65536, __va(nvram_base), 65536);
        return status;
 }
 
 int pnp_bios_read_escd(char *data, u32 nvram_base)
 {
        int status;
-       status = __pnp_bios_read_escd( data, nvram_base );
-       if ( status )
-               pnpbios_print_status( "read_escd", status );
-       return status;
-}
 
-#if needed
-/*
- * Call PnP BIOS function 0x43, "write ESCD"
- */
-static int pnp_bios_write_escd(char *data, u32 nvram_base)
-{
-       u16 status;
-       if (!pnp_bios_present())
-               return ESCD_FUNCTION_NOT_SUPPORTED;
-       status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
-                              data, 65536, __va(nvram_base), 65536);
+       status = __pnp_bios_read_escd(data, nvram_base);
+       if (status)
+               pnpbios_print_status("read_escd", status);
        return status;
 }
-#endif
-
-
-/*
- * Initialization
- */
 
 void pnpbios_calls_init(union pnp_bios_install_struct *header)
 {
        int i;
+
        spin_lock_init(&pnp_bios_lock);
        pnp_bios_callpoint.offset = header->fields.pm16offset;
        pnp_bios_callpoint.segment = PNP_CS16;
 
-       set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
-       _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
-       for (i = 0; i < NR_CPUS; i++) {
-               struct desc_struct *gdt = get_cpu_gdt_table(i);
-               if (!gdt)
-                       continue;
-               Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024);
-               Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024);
-               Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024);
+       bad_bios_desc.a = 0;
+       bad_bios_desc.b = 0x00409200;
+
+       set_desc_base(&bad_bios_desc, (unsigned long)__va(0x40UL << 4));
+       set_desc_limit(&bad_bios_desc, 4095 - (0x40 << 4));
+       for_each_possible_cpu(i) {
+               struct desc_struct *gdt = get_cpu_gdt_table(i);
+               if (!gdt)
+                       continue;
+               set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
+                        (unsigned long)&pnp_bios_callfunc);
+               set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS16],
+                        (unsigned long)__va(header->fields.pm16cseg));
+               set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS],
+                        (unsigned long)__va(header->fields.pm16dseg));
        }
 }