diff options
author | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
commit | ed03f430cdc8c802652467e9097606fedc2c7abc (patch) | |
tree | 30941ec1e6f93e99358fefe18175e5dd800a4379 /drivers/pnp | |
parent | ed349a8a0a780ed27e2a765f16cee54d9b63bfee (diff) | |
parent | 6f957eaf79356a32e838f5f262ee9a60544b1d5b (diff) |
Pull pnpacpi into acpica branch
Diffstat (limited to 'drivers/pnp')
-rw-r--r-- | drivers/pnp/card.c | 25 | ||||
-rw-r--r-- | drivers/pnp/driver.c | 47 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 78 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 48 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/bioscalls.c | 45 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/core.c | 8 |
6 files changed, 196 insertions, 55 deletions
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index bd7c966ea2d7..0ecbe4edbec1 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c | |||
@@ -69,6 +69,7 @@ static int card_probe(struct pnp_card * card, struct pnp_card_driver * drv) | |||
69 | return 0; | 69 | return 0; |
70 | clink->card = card; | 70 | clink->card = card; |
71 | clink->driver = drv; | 71 | clink->driver = drv; |
72 | clink->pm_state = PMSG_ON; | ||
72 | if (drv->probe) { | 73 | if (drv->probe) { |
73 | if (drv->probe(clink, id)>=0) | 74 | if (drv->probe(clink, id)>=0) |
74 | return 1; | 75 | return 1; |
@@ -333,6 +334,28 @@ void pnp_release_card_device(struct pnp_dev * dev) | |||
333 | up_write(&dev->dev.bus->subsys.rwsem); | 334 | up_write(&dev->dev.bus->subsys.rwsem); |
334 | } | 335 | } |
335 | 336 | ||
337 | /* | ||
338 | * suspend/resume callbacks | ||
339 | */ | ||
340 | static int card_suspend(struct pnp_dev *dev, pm_message_t state) | ||
341 | { | ||
342 | struct pnp_card_link *link = dev->card_link; | ||
343 | if (link->pm_state.event == state.event) | ||
344 | return 0; | ||
345 | link->pm_state = state; | ||
346 | return link->driver->suspend(link, state); | ||
347 | } | ||
348 | |||
349 | static int card_resume(struct pnp_dev *dev) | ||
350 | { | ||
351 | struct pnp_card_link *link = dev->card_link; | ||
352 | if (link->pm_state.event == PM_EVENT_ON) | ||
353 | return 0; | ||
354 | link->pm_state = PMSG_ON; | ||
355 | link->driver->resume(link); | ||
356 | return 0; | ||
357 | } | ||
358 | |||
336 | /** | 359 | /** |
337 | * pnp_register_card_driver - registers a PnP card driver with the PnP Layer | 360 | * pnp_register_card_driver - registers a PnP card driver with the PnP Layer |
338 | * @drv: pointer to the driver to register | 361 | * @drv: pointer to the driver to register |
@@ -348,6 +371,8 @@ int pnp_register_card_driver(struct pnp_card_driver * drv) | |||
348 | drv->link.flags = drv->flags; | 371 | drv->link.flags = drv->flags; |
349 | drv->link.probe = NULL; | 372 | drv->link.probe = NULL; |
350 | drv->link.remove = &card_remove_first; | 373 | drv->link.remove = &card_remove_first; |
374 | drv->link.suspend = drv->suspend ? card_suspend : NULL; | ||
375 | drv->link.resume = drv->resume ? card_resume : NULL; | ||
351 | 376 | ||
352 | spin_lock(&pnp_lock); | 377 | spin_lock(&pnp_lock); |
353 | list_add_tail(&drv->global_list, &pnp_card_drivers); | 378 | list_add_tail(&drv->global_list, &pnp_card_drivers); |
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index d3ccce706ab4..15fb758a9e52 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -146,10 +146,57 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv) | |||
146 | return 1; | 146 | return 1; |
147 | } | 147 | } |
148 | 148 | ||
149 | static int pnp_bus_suspend(struct device *dev, pm_message_t state) | ||
150 | { | ||
151 | struct pnp_dev * pnp_dev = to_pnp_dev(dev); | ||
152 | struct pnp_driver * pnp_drv = pnp_dev->driver; | ||
153 | int error; | ||
154 | |||
155 | if (!pnp_drv) | ||
156 | return 0; | ||
157 | |||
158 | if (pnp_drv->suspend) { | ||
159 | error = pnp_drv->suspend(pnp_dev, state); | ||
160 | if (error) | ||
161 | return error; | ||
162 | } | ||
163 | |||
164 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) && | ||
165 | pnp_can_disable(pnp_dev)) { | ||
166 | error = pnp_stop_dev(pnp_dev); | ||
167 | if (error) | ||
168 | return error; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int pnp_bus_resume(struct device *dev) | ||
175 | { | ||
176 | struct pnp_dev * pnp_dev = to_pnp_dev(dev); | ||
177 | struct pnp_driver * pnp_drv = pnp_dev->driver; | ||
178 | int error; | ||
179 | |||
180 | if (!pnp_drv) | ||
181 | return 0; | ||
182 | |||
183 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) { | ||
184 | error = pnp_start_dev(pnp_dev); | ||
185 | if (error) | ||
186 | return error; | ||
187 | } | ||
188 | |||
189 | if (pnp_drv->resume) | ||
190 | return pnp_drv->resume(pnp_dev); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
149 | 194 | ||
150 | struct bus_type pnp_bus_type = { | 195 | struct bus_type pnp_bus_type = { |
151 | .name = "pnp", | 196 | .name = "pnp", |
152 | .match = pnp_bus_match, | 197 | .match = pnp_bus_match, |
198 | .suspend = pnp_bus_suspend, | ||
199 | .resume = pnp_bus_resume, | ||
153 | }; | 200 | }; |
154 | 201 | ||
155 | 202 | ||
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 261668618b2d..c4256aa32bcb 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -470,6 +470,53 @@ int pnp_auto_config_dev(struct pnp_dev *dev) | |||
470 | } | 470 | } |
471 | 471 | ||
472 | /** | 472 | /** |
473 | * pnp_start_dev - low-level start of the PnP device | ||
474 | * @dev: pointer to the desired device | ||
475 | * | ||
476 | * assumes that resources have alread been allocated | ||
477 | */ | ||
478 | |||
479 | int pnp_start_dev(struct pnp_dev *dev) | ||
480 | { | ||
481 | if (!pnp_can_write(dev)) { | ||
482 | pnp_info("Device %s does not supported activation.", dev->dev.bus_id); | ||
483 | return -EINVAL; | ||
484 | } | ||
485 | |||
486 | if (dev->protocol->set(dev, &dev->res)<0) { | ||
487 | pnp_err("Failed to activate device %s.", dev->dev.bus_id); | ||
488 | return -EIO; | ||
489 | } | ||
490 | |||
491 | pnp_info("Device %s activated.", dev->dev.bus_id); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | /** | ||
497 | * pnp_stop_dev - low-level disable of the PnP device | ||
498 | * @dev: pointer to the desired device | ||
499 | * | ||
500 | * does not free resources | ||
501 | */ | ||
502 | |||
503 | int pnp_stop_dev(struct pnp_dev *dev) | ||
504 | { | ||
505 | if (!pnp_can_disable(dev)) { | ||
506 | pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); | ||
507 | return -EINVAL; | ||
508 | } | ||
509 | if (dev->protocol->disable(dev)<0) { | ||
510 | pnp_err("Failed to disable device %s.", dev->dev.bus_id); | ||
511 | return -EIO; | ||
512 | } | ||
513 | |||
514 | pnp_info("Device %s disabled.", dev->dev.bus_id); | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | /** | ||
473 | * pnp_activate_dev - activates a PnP device for use | 520 | * pnp_activate_dev - activates a PnP device for use |
474 | * @dev: pointer to the desired device | 521 | * @dev: pointer to the desired device |
475 | * | 522 | * |
@@ -477,6 +524,8 @@ int pnp_auto_config_dev(struct pnp_dev *dev) | |||
477 | */ | 524 | */ |
478 | int pnp_activate_dev(struct pnp_dev *dev) | 525 | int pnp_activate_dev(struct pnp_dev *dev) |
479 | { | 526 | { |
527 | int error; | ||
528 | |||
480 | if (!dev) | 529 | if (!dev) |
481 | return -EINVAL; | 530 | return -EINVAL; |
482 | if (dev->active) { | 531 | if (dev->active) { |
@@ -487,18 +536,11 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
487 | if (pnp_auto_config_dev(dev)) | 536 | if (pnp_auto_config_dev(dev)) |
488 | return -EBUSY; | 537 | return -EBUSY; |
489 | 538 | ||
490 | if (!pnp_can_write(dev)) { | 539 | error = pnp_start_dev(dev); |
491 | pnp_info("Device %s does not supported activation.", dev->dev.bus_id); | 540 | if (error) |
492 | return -EINVAL; | 541 | return error; |
493 | } | ||
494 | |||
495 | if (dev->protocol->set(dev, &dev->res)<0) { | ||
496 | pnp_err("Failed to activate device %s.", dev->dev.bus_id); | ||
497 | return -EIO; | ||
498 | } | ||
499 | 542 | ||
500 | dev->active = 1; | 543 | dev->active = 1; |
501 | pnp_info("Device %s activated.", dev->dev.bus_id); | ||
502 | 544 | ||
503 | return 1; | 545 | return 1; |
504 | } | 546 | } |
@@ -511,23 +553,19 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
511 | */ | 553 | */ |
512 | int pnp_disable_dev(struct pnp_dev *dev) | 554 | int pnp_disable_dev(struct pnp_dev *dev) |
513 | { | 555 | { |
556 | int error; | ||
557 | |||
514 | if (!dev) | 558 | if (!dev) |
515 | return -EINVAL; | 559 | return -EINVAL; |
516 | if (!dev->active) { | 560 | if (!dev->active) { |
517 | return 0; /* the device is already disabled */ | 561 | return 0; /* the device is already disabled */ |
518 | } | 562 | } |
519 | 563 | ||
520 | if (!pnp_can_disable(dev)) { | 564 | error = pnp_stop_dev(dev); |
521 | pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); | 565 | if (error) |
522 | return -EINVAL; | 566 | return error; |
523 | } | ||
524 | if (dev->protocol->disable(dev)<0) { | ||
525 | pnp_err("Failed to disable device %s.", dev->dev.bus_id); | ||
526 | return -EIO; | ||
527 | } | ||
528 | 567 | ||
529 | dev->active = 0; | 568 | dev->active = 0; |
530 | pnp_info("Device %s disabled.", dev->dev.bus_id); | ||
531 | 569 | ||
532 | /* release the resources so that other devices can use them */ | 570 | /* release the resources so that other devices can use them */ |
533 | down(&pnp_res_mutex); | 571 | down(&pnp_res_mutex); |
@@ -558,6 +596,8 @@ EXPORT_SYMBOL(pnp_manual_config_dev); | |||
558 | #if 0 | 596 | #if 0 |
559 | EXPORT_SYMBOL(pnp_auto_config_dev); | 597 | EXPORT_SYMBOL(pnp_auto_config_dev); |
560 | #endif | 598 | #endif |
599 | EXPORT_SYMBOL(pnp_start_dev); | ||
600 | EXPORT_SYMBOL(pnp_stop_dev); | ||
561 | EXPORT_SYMBOL(pnp_activate_dev); | 601 | EXPORT_SYMBOL(pnp_activate_dev); |
562 | EXPORT_SYMBOL(pnp_disable_dev); | 602 | EXPORT_SYMBOL(pnp_disable_dev); |
563 | EXPORT_SYMBOL(pnp_resource_change); | 603 | EXPORT_SYMBOL(pnp_resource_change); |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index b8b46ab54f4e..c6db14d30ed6 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -453,6 +453,45 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | |||
453 | return; | 453 | return; |
454 | } | 454 | } |
455 | 455 | ||
456 | static void | ||
457 | pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r) | ||
458 | { | ||
459 | struct acpi_resource_address64 addr, *p = &addr; | ||
460 | acpi_status status; | ||
461 | struct pnp_mem * mem; | ||
462 | struct pnp_port * port; | ||
463 | |||
464 | status = acpi_resource_to_address64(r, p); | ||
465 | if (!ACPI_SUCCESS(status)) { | ||
466 | pnp_warn("PnPACPI: failed to convert resource type %d", r->type); | ||
467 | return; | ||
468 | } | ||
469 | |||
470 | if (p->address_length == 0) | ||
471 | return; | ||
472 | |||
473 | if (p->resource_type == ACPI_MEMORY_RANGE) { | ||
474 | mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL); | ||
475 | if (!mem) | ||
476 | return; | ||
477 | mem->min = mem->max = p->minimum; | ||
478 | mem->size = p->address_length; | ||
479 | mem->align = 0; | ||
480 | mem->flags = (p->info.mem.write_protect == | ||
481 | ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0; | ||
482 | pnp_register_mem_resource(option,mem); | ||
483 | } else if (p->resource_type == ACPI_IO_RANGE) { | ||
484 | port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL); | ||
485 | if (!port) | ||
486 | return; | ||
487 | port->min = port->max = p->minimum; | ||
488 | port->size = p->address_length; | ||
489 | port->align = 0; | ||
490 | port->flags = PNP_PORT_FLAG_FIXED; | ||
491 | pnp_register_port_resource(option,port); | ||
492 | } | ||
493 | } | ||
494 | |||
456 | struct acpipnp_parse_option_s { | 495 | struct acpipnp_parse_option_s { |
457 | struct pnp_option *option; | 496 | struct pnp_option *option; |
458 | struct pnp_option *option_independent; | 497 | struct pnp_option *option_independent; |
@@ -495,6 +534,11 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, | |||
495 | pnpacpi_parse_fixed_mem32_option(option, | 534 | pnpacpi_parse_fixed_mem32_option(option, |
496 | &res->data.fixed_memory32); | 535 | &res->data.fixed_memory32); |
497 | break; | 536 | break; |
537 | case ACPI_RESOURCE_TYPE_ADDRESS16: | ||
538 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
539 | case ACPI_RESOURCE_TYPE_ADDRESS64: | ||
540 | pnpacpi_parse_address_option(option, res); | ||
541 | break; | ||
498 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | 542 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
499 | switch (res->data.start_dpf.compatibility_priority) { | 543 | switch (res->data.start_dpf.compatibility_priority) { |
500 | case ACPI_GOOD_CONFIGURATION: | 544 | case ACPI_GOOD_CONFIGURATION: |
@@ -568,11 +612,9 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, | |||
568 | case ACPI_RESOURCE_TYPE_MEMORY24: | 612 | case ACPI_RESOURCE_TYPE_MEMORY24: |
569 | case ACPI_RESOURCE_TYPE_MEMORY32: | 613 | case ACPI_RESOURCE_TYPE_MEMORY32: |
570 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 614 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
571 | #if 0 | ||
572 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 615 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
573 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 616 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
574 | case ACPI_RESOURCE_TYPE_ADDRESS64: | 617 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
575 | #endif | ||
576 | (*res_cnt) ++; | 618 | (*res_cnt) ++; |
577 | default: | 619 | default: |
578 | return AE_OK; | 620 | return AE_OK; |
@@ -593,11 +635,9 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, | |||
593 | case ACPI_RESOURCE_TYPE_MEMORY24: | 635 | case ACPI_RESOURCE_TYPE_MEMORY24: |
594 | case ACPI_RESOURCE_TYPE_MEMORY32: | 636 | case ACPI_RESOURCE_TYPE_MEMORY32: |
595 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 637 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
596 | #if 0 | ||
597 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 638 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
598 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 639 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
599 | case ACPI_RESOURCE_TYPE_ADDRESS64: | 640 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
600 | #endif | ||
601 | (*resource)->type = res->type; | 641 | (*resource)->type = res->type; |
602 | (*resource)++; | 642 | (*resource)++; |
603 | default: | 643 | default: |
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) \ | ||
71 | do { \ | ||
72 | set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \ | ||
73 | set_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) \ |
77 | do { \ | 62 | do { \ |
78 | set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \ | 63 | struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ |
79 | set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \ | 64 | set_base(gdt[(selname) >> 3], (u32)(address)); \ |
65 | set_limit(gdt[(selname) >> 3], size); \ | ||
80 | } while(0) | 66 | } while(0) |
81 | 67 | ||
82 | static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; | 68 | static 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) | |||
290 | static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) | 276 | static 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 | } |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index f49674f07949..b154b3f52cbe 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/mm.h> | 56 | #include <linux/mm.h> |
57 | #include <linux/smp.h> | 57 | #include <linux/smp.h> |
58 | #include <linux/slab.h> | 58 | #include <linux/slab.h> |
59 | #include <linux/kobject_uevent.h> | ||
60 | #include <linux/completion.h> | 59 | #include <linux/completion.h> |
61 | #include <linux/spinlock.h> | 60 | #include <linux/spinlock.h> |
62 | #include <linux/dmi.h> | 61 | #include <linux/dmi.h> |
@@ -106,8 +105,6 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) | |||
106 | char *argv [3], **envp, *buf, *scratch; | 105 | char *argv [3], **envp, *buf, *scratch; |
107 | int i = 0, value; | 106 | int i = 0, value; |
108 | 107 | ||
109 | if (!hotplug_path [0]) | ||
110 | return -ENOENT; | ||
111 | if (!current->fs->root) { | 108 | if (!current->fs->root) { |
112 | return -EAGAIN; | 109 | return -EAGAIN; |
113 | } | 110 | } |
@@ -119,8 +116,9 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) | |||
119 | return -ENOMEM; | 116 | return -ENOMEM; |
120 | } | 117 | } |
121 | 118 | ||
122 | /* only one standardized param to hotplug command: type */ | 119 | /* FIXME: if there are actual users of this, it should be integrated into |
123 | argv [0] = hotplug_path; | 120 | * the driver core and use the usual infrastructure like sysfs and uevents */ |
121 | argv [0] = "/sbin/pnpbios"; | ||
124 | argv [1] = "dock"; | 122 | argv [1] = "dock"; |
125 | argv [2] = NULL; | 123 | argv [2] = NULL; |
126 | 124 | ||