48 #include <linux/types.h>
49 #include <linux/module.h>
51 #include <linux/linkage.h>
52 #include <linux/kernel.h>
53 #include <linux/device.h>
57 #include <linux/slab.h>
68 #include <asm/byteorder.h>
83 return (pnp_bios_install !=
NULL);
106 if (!(envp = kcalloc(20,
sizeof(
char *),
GFP_KERNEL)))
117 argv[0] =
"/sbin/pnpbios";
122 envp[i++] =
"HOME=/";
123 envp[i++] =
"PATH=/sbin:/bin:/usr/sbin:/usr/bin";
127 envp[i++] =
"DEBUG=kernel";
136 scratch +=
sprintf(scratch,
"ACTION=%s", dock ?
"add" :
"remove") + 1;
140 scratch +=
sprintf(scratch,
"DOCK=%x/%x/%x",
153 static int pnp_dock_thread(
void *
unused)
156 int docked = -1,
d = 0;
189 if (pnp_dock_event(
d, &now) == 0) {
193 "PnPBIOS: Docking station %stached\n",
194 docked ?
"at" :
"de");
204 static int pnpbios_get_resources(
struct pnp_dev *
dev)
226 static int pnpbios_set_resources(
struct pnp_dev *dev)
254 static void pnpbios_zero_data_stream(
struct pnp_bios_node *node)
256 unsigned char *
p = (
char *)node->
data;
257 unsigned char *
end = (
char *)(node->
data + node->
size);
261 while ((
char *)p < (
char *)
end) {
263 len = (p[2] << 8) | p[1];
266 if (((p[0] >> 3) & 0x0f) == 0x0f)
271 for (i = 0; i < len; i++)
276 "PnPBIOS: Resource structure did not contain an end tag.\n");
279 static int pnpbios_disable_resources(
struct pnp_dev *dev)
296 pnpbios_zero_data_stream(node);
308 .name =
"Plug and Play BIOS",
309 .get = pnpbios_get_resources,
310 .set = pnpbios_set_resources,
311 .disable = pnpbios_disable_resources,
355 static void __init build_devlist(
void)
358 unsigned int nodes_got = 0;
359 unsigned int devs = 0;
366 for (nodenum = 0; nodenum < 0xff;) {
367 u8 thisnodenum = nodenum;
373 (&nodenum, (
char)PNPMODE_DYNAMIC, node))
381 if (insert_device(node) == 0)
383 if (nodenum <= thisnodenum) {
385 "PnPBIOS: build_devlist: Node number 0x%x is out of sequence following node 0x%x. Aborting.\n",
386 (
unsigned int)nodenum,
387 (
unsigned int)thisnodenum);
394 "PnPBIOS: %i node%s reported by PnP BIOS; %i recorded by driver\n",
395 nodes_got, nodes_got != 1 ?
"s" :
"", devs);
404 static int pnpbios_disabled;
407 static int __init pnpbios_setup(
char *
str)
411 while ((str !=
NULL) && (*str !=
'\0')) {
412 if (
strncmp(str,
"off", 3) == 0)
413 pnpbios_disabled = 1;
414 if (
strncmp(str,
"on", 2) == 0)
415 pnpbios_disabled = 0;
416 invert = (
strncmp(str,
"no-", 3) == 0);
419 if (
strncmp(str,
"curr", 4) == 0)
420 pnpbios_dont_use_current_config = invert;
423 str +=
strspn(str,
", \t");
429 __setup(
"pnpbios=", pnpbios_setup);
432 #define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
434 static int __init pnpbios_probe_system(
void)
440 printk(
KERN_INFO "PnPBIOS: Scanning system for PnP BIOS support...\n");
449 check = (
void *)check + 16) {
453 "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n",
455 length = check->
fields.length;
458 "PnPBIOS: installation structure is invalid, skipping\n");
461 for (sum = 0, i = 0; i <
length; i++)
462 sum += check->
chars[i];
465 "PnPBIOS: installation structure is corrupted, skipping\n");
468 if (check->
fields.version < 0x10) {
470 "PnPBIOS: PnP BIOS version %d.%d is not supported\n",
471 check->
fields.version >> 4,
472 check->
fields.version & 15);
476 "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n",
480 pnp_bios_install =
check;
496 .callback = exploding_pnp_bios,
497 .ident =
"Higraded P14H",
506 .callback = exploding_pnp_bios,
507 .ident =
"ASUS P4P800",
516 static int __init pnpbios_init(
void)
520 #if defined(CONFIG_PPC)
529 #ifdef CONFIG_PNPACPI
531 pnpbios_disabled = 1;
538 if (!pnpbios_probe_system())
548 "PnPBIOS: Unable to get node info. Aborting.\n");
556 "PnPBIOS: Unable to register driver. Aborting.\n");
574 static int __init pnpbios_thread_init(
void)
576 #if defined(CONFIG_PPC)
580 if (pnpbios_disabled)
582 #ifdef CONFIG_HOTPLUG
585 init_completion(&unload_sem);
588 return PTR_ERR(task);