From: Andrew Morton Deuglify bioscalls.c Signed-off-by: Andrew Morton --- drivers/pnp/pnpbios/bioscalls.c | 228 +++++++++++++++++++++++----------------- 1 files changed, 132 insertions(+), 96 deletions(-) diff -puN drivers/pnp/pnpbios/bioscalls.c~bioscalls-cleanup drivers/pnp/pnpbios/bioscalls.c --- devel/drivers/pnp/pnpbios/bioscalls.c~bioscalls-cleanup 2005-09-22 22:48:59.000000000 -0700 +++ devel-akpm/drivers/pnp/pnpbios/bioscalls.c 2005-09-22 22:48:59.000000000 -0700 @@ -1,6 +1,5 @@ /* * bioscalls.c - the lowlevel layer of the PnPBIOS driver - * */ #include @@ -67,17 +66,21 @@ __asm__( ".previous \n" ); -#define Q_SET_SEL(cpu, selname, address, size) \ -do { \ -set_base(get_cpu_gdt_table(cpu)[(selname) >> 3], __va((u32)(address))); \ -set_limit(get_cpu_gdt_table(cpu)[(selname) >> 3], size); \ -} while(0) - -#define Q2_SET_SEL(cpu, selname, address, size) \ -do { \ -set_base(get_cpu_gdt_table(cpu)[(selname) >> 3], (u32)(address)); \ -set_limit(get_cpu_gdt_table(cpu)[(selname) >> 3], size); \ -} while(0) +#define Q_SET_SEL(cpu, selname, address, size) \ + do { \ + set_base(get_cpu_gdt_table(cpu)[(selname) >> 3], \ + __va((u32)(address))); \ + set_limit(get_cpu_gdt_table(cpu)[(selname) >> 3], \ + size); \ + } while(0) + +#define Q2_SET_SEL(cpu, selname, address, size) \ + do { \ + set_base(get_cpu_gdt_table(cpu)[(selname) >> 3], \ + (u32)(address)); \ + set_limit(get_cpu_gdt_table(cpu)[(selname) >> 3], \ + size); \ + } while(0) static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; @@ -111,7 +114,7 @@ static inline u16 call_pnp_bios(u16 func * 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(); @@ -162,11 +165,13 @@ static inline u16 call_pnp_bios(u16 func 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; @@ -179,55 +184,69 @@ void pnpbios_print_status(const char * m 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; } } @@ -257,19 +276,22 @@ void pnpbios_print_status(const char * m 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; } @@ -287,24 +309,27 @@ int pnp_bios_dev_node_info(struct pnp_de * 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; + 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_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0, - nodenum, sizeof(char), data, 65536); + status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, + boot ? 2 : 1, PNP_DS, 0, + nodenum, sizeof(char), data, 65536); return status; } 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 ); + int status = __pnp_bios_get_dev_node(nodenum, boot, data); + + if (status) + pnpbios_print_status("get_dev_node", status); return status; } @@ -315,29 +340,31 @@ int pnp_bios_get_dev_node(u8 *nodenum, c * 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 ); + int 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; @@ -350,6 +377,7 @@ int pnp_bios_set_dev_node(u8 nodenum, ch 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, @@ -365,9 +393,11 @@ static int pnp_bios_get_event(u16 *event 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); + status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, + 0, 0, 0, 0, 0, 0); return status; } #endif @@ -378,10 +408,12 @@ static int pnp_bios_send_message(u16 mes 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); + 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; } @@ -393,10 +425,11 @@ int pnp_bios_dock_station_info(struct pn 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_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, + PNP_DS, 0, 0, 0, 0, info, *((u16 *) info), 0, 0); return status; } #endif @@ -408,19 +441,20 @@ static int pnp_bios_set_stat_res(char *i 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 ); + int status = __pnp_bios_get_stat_res(info); + + if (status) + pnpbios_print_status("get_stat_res", status); return status; } @@ -431,10 +465,11 @@ int pnp_bios_get_stat_res(char *info) 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 = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, + PNP_DS, 0, 0, table, *size, size, sizeof(u16)); return status; } #endif @@ -445,19 +480,21 @@ static int pnp_bios_apm_id_table(char *t 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 ); + int status = __pnp_bios_isapnp_config(data); + + if (status) + pnpbios_print_status("isapnp_config", status); return status; } @@ -467,19 +504,21 @@ int pnp_bios_isapnp_config(struct pnp_is 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 ); + int status = __pnp_bios_escd_info(data); + + if (status) + pnpbios_print_status("escd_info", status); return status; } @@ -490,19 +529,20 @@ int pnp_bios_escd_info(struct escd_info_ 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 ); + int status = __pnp_bios_read_escd(data, nvram_base); + + if (status) + pnpbios_print_status("read_escd", status); return status; } @@ -513,30 +553,26 @@ int pnp_bios_read_escd(char *data, u32 n 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 = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, + 0, 0, data, 65536, __va(nvram_base), 65536); 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++) - { + for (i=0; i < NR_CPUS; i++) { 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); _