/* * These are some opcodes for a "static asmlinkage" * As this code is *not* executed inside the linux kernel segment, but in a * alias at offset 0, we need a far return that can not be compiled by * default (please, prove me wrong! this is *really* ugly!) * This is the only way to get the bios to return into the kernel code, * because the bios code runs in 16 bit protected mode and therefore can only * return to the caller if the call is within the first 64kB, and the linux * kernel begins at offset 3GB...
*/
/* * PnP BIOSes are generally not terribly re-entrant. * Also, don't rely on them to save everything correctly.
*/ if (pnp_bios_is_utter_crap) return PNP_FUNCTION_NOT_SUPPORTED;
/* On some boxes IRQ's during PnP BIOS calls are deadly. */
spin_lock_irqsave(&pnp_bios_lock, flags);
/* The lock prevents us bouncing CPU here */ if (ts1_size)
Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size); if (ts2_size)
Q2_SET_SEL(smp_processor_id(), PNP_TS2, ts2_base, ts2_size);
/* 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");
}
return status;
}
void pnpbios_print_status(constchar *module, u16 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); break; case PNP_UNKNOWN_FUNCTION:
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); 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); break; case PNP_SET_FAILED:
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); break; case PNP_NO_ISA_PNP_CARDS:
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); 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); break; case PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT:
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); 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); break; case PNP_HARDWARE_ERROR:
printk(KERN_ERR "PnPBIOS: %s: a hardware failure has occurred\n",
module); break; default:
printk(KERN_ERR "PnPBIOS: %s: unexpected status 0x%x\n", module,
status); break;
}
}
/* * Call PnP BIOS with function 0x00, "get number of system device nodes"
*/ staticint __pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
{
u16 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); return status;
}
/* * Note that some PnP BIOSes (e.g., on Sony Vaio laptops) die a horrible * death if they are asked to access the "current" configuration. * Therefore, if it's a matter of indifference, it's better to call * get_dev_node() and set_dev_node() with boot=1 rather than with boot=0.
*/
/* * Call PnP BIOS with function 0x01, "get system device node" * Input: *nodenum = desired node, * boot = whether to get nonvolatile boot (!=0) * or volatile current (0) config * Output: *nodenum=next node or 0xff if no more nodes
*/ staticint __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
{
u16 status;
u16 tmp_nodenum;
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); return status;
} if (!boot) { /* Update devlist */
status = pnp_bios_get_dev_node(&nodenum, boot, data); if (status) return status;
} return status;
}
/* * Call PnP BIOS with function 0x05, "get docking station information"
*/ int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
{
u16 status;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.