diff options
Diffstat (limited to 'drivers/pnp')
-rw-r--r-- | drivers/pnp/driver.c | 12 | ||||
-rw-r--r-- | drivers/pnp/interface.c | 13 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 27 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/core.c | 2 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 60 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/bioscalls.c | 5 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/core.c | 2 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/rsparser.c | 33 | ||||
-rw-r--r-- | drivers/pnp/quirks.c | 43 |
9 files changed, 128 insertions, 69 deletions
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index a262762c5b88..12a1645a2e43 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -161,8 +161,7 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state) | |||
161 | return error; | 161 | return error; |
162 | } | 162 | } |
163 | 163 | ||
164 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) && | 164 | if (pnp_can_disable(pnp_dev)) { |
165 | pnp_can_disable(pnp_dev)) { | ||
166 | error = pnp_stop_dev(pnp_dev); | 165 | error = pnp_stop_dev(pnp_dev); |
167 | if (error) | 166 | if (error) |
168 | return error; | 167 | return error; |
@@ -185,14 +184,17 @@ static int pnp_bus_resume(struct device *dev) | |||
185 | if (pnp_dev->protocol && pnp_dev->protocol->resume) | 184 | if (pnp_dev->protocol && pnp_dev->protocol->resume) |
186 | pnp_dev->protocol->resume(pnp_dev); | 185 | pnp_dev->protocol->resume(pnp_dev); |
187 | 186 | ||
188 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) { | 187 | if (pnp_can_write(pnp_dev)) { |
189 | error = pnp_start_dev(pnp_dev); | 188 | error = pnp_start_dev(pnp_dev); |
190 | if (error) | 189 | if (error) |
191 | return error; | 190 | return error; |
192 | } | 191 | } |
193 | 192 | ||
194 | if (pnp_drv->resume) | 193 | if (pnp_drv->resume) { |
195 | return pnp_drv->resume(pnp_dev); | 194 | error = pnp_drv->resume(pnp_dev); |
195 | if (error) | ||
196 | return error; | ||
197 | } | ||
196 | 198 | ||
197 | return 0; | 199 | return 0; |
198 | } | 200 | } |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 31548044fdde..982658477a58 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -10,9 +10,12 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pnp.h> | ||
13 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
14 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/mutex.h> | ||
18 | |||
16 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
17 | 20 | ||
18 | #include "base.h" | 21 | #include "base.h" |
@@ -315,8 +318,6 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, | |||
315 | return ret; | 318 | return ret; |
316 | } | 319 | } |
317 | 320 | ||
318 | extern struct semaphore pnp_res_mutex; | ||
319 | |||
320 | static ssize_t | 321 | static ssize_t |
321 | pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | 322 | pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, |
322 | const char *ubuf, size_t count) | 323 | const char *ubuf, size_t count) |
@@ -361,10 +362,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
361 | goto done; | 362 | goto done; |
362 | } | 363 | } |
363 | if (!strnicmp(buf, "get", 3)) { | 364 | if (!strnicmp(buf, "get", 3)) { |
364 | down(&pnp_res_mutex); | 365 | mutex_lock(&pnp_res_mutex); |
365 | if (pnp_can_read(dev)) | 366 | if (pnp_can_read(dev)) |
366 | dev->protocol->get(dev, &dev->res); | 367 | dev->protocol->get(dev, &dev->res); |
367 | up(&pnp_res_mutex); | 368 | mutex_unlock(&pnp_res_mutex); |
368 | goto done; | 369 | goto done; |
369 | } | 370 | } |
370 | if (!strnicmp(buf, "set", 3)) { | 371 | if (!strnicmp(buf, "set", 3)) { |
@@ -373,7 +374,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
373 | goto done; | 374 | goto done; |
374 | buf += 3; | 375 | buf += 3; |
375 | pnp_init_resource_table(&dev->res); | 376 | pnp_init_resource_table(&dev->res); |
376 | down(&pnp_res_mutex); | 377 | mutex_lock(&pnp_res_mutex); |
377 | while (1) { | 378 | while (1) { |
378 | while (isspace(*buf)) | 379 | while (isspace(*buf)) |
379 | ++buf; | 380 | ++buf; |
@@ -455,7 +456,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
455 | } | 456 | } |
456 | break; | 457 | break; |
457 | } | 458 | } |
458 | up(&pnp_res_mutex); | 459 | mutex_unlock(&pnp_res_mutex); |
459 | goto done; | 460 | goto done; |
460 | } | 461 | } |
461 | 462 | ||
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index c6b3d4e63ccc..c28caf272c11 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -12,9 +12,10 @@ | |||
12 | #include <linux/pnp.h> | 12 | #include <linux/pnp.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/bitmap.h> | 14 | #include <linux/bitmap.h> |
15 | #include <linux/mutex.h> | ||
15 | #include "base.h" | 16 | #include "base.h" |
16 | 17 | ||
17 | DECLARE_MUTEX(pnp_res_mutex); | 18 | DEFINE_MUTEX(pnp_res_mutex); |
18 | 19 | ||
19 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | 20 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) |
20 | { | 21 | { |
@@ -297,7 +298,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
297 | if (!pnp_can_configure(dev)) | 298 | if (!pnp_can_configure(dev)) |
298 | return -ENODEV; | 299 | return -ENODEV; |
299 | 300 | ||
300 | down(&pnp_res_mutex); | 301 | mutex_lock(&pnp_res_mutex); |
301 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ | 302 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ |
302 | if (dev->independent) { | 303 | if (dev->independent) { |
303 | port = dev->independent->port; | 304 | port = dev->independent->port; |
@@ -366,12 +367,12 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
366 | } else if (dev->dependent) | 367 | } else if (dev->dependent) |
367 | goto fail; | 368 | goto fail; |
368 | 369 | ||
369 | up(&pnp_res_mutex); | 370 | mutex_unlock(&pnp_res_mutex); |
370 | return 1; | 371 | return 1; |
371 | 372 | ||
372 | fail: | 373 | fail: |
373 | pnp_clean_resource_table(&dev->res); | 374 | pnp_clean_resource_table(&dev->res); |
374 | up(&pnp_res_mutex); | 375 | mutex_unlock(&pnp_res_mutex); |
375 | return 0; | 376 | return 0; |
376 | } | 377 | } |
377 | 378 | ||
@@ -396,7 +397,7 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, | |||
396 | return -ENOMEM; | 397 | return -ENOMEM; |
397 | *bak = dev->res; | 398 | *bak = dev->res; |
398 | 399 | ||
399 | down(&pnp_res_mutex); | 400 | mutex_lock(&pnp_res_mutex); |
400 | dev->res = *res; | 401 | dev->res = *res; |
401 | if (!(mode & PNP_CONFIG_FORCE)) { | 402 | if (!(mode & PNP_CONFIG_FORCE)) { |
402 | for (i = 0; i < PNP_MAX_PORT; i++) { | 403 | for (i = 0; i < PNP_MAX_PORT; i++) { |
@@ -416,14 +417,14 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, | |||
416 | goto fail; | 417 | goto fail; |
417 | } | 418 | } |
418 | } | 419 | } |
419 | up(&pnp_res_mutex); | 420 | mutex_unlock(&pnp_res_mutex); |
420 | 421 | ||
421 | kfree(bak); | 422 | kfree(bak); |
422 | return 0; | 423 | return 0; |
423 | 424 | ||
424 | fail: | 425 | fail: |
425 | dev->res = *bak; | 426 | dev->res = *bak; |
426 | up(&pnp_res_mutex); | 427 | mutex_unlock(&pnp_res_mutex); |
427 | kfree(bak); | 428 | kfree(bak); |
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | } | 430 | } |
@@ -513,7 +514,7 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
513 | int error; | 514 | int error; |
514 | 515 | ||
515 | if (dev->active) | 516 | if (dev->active) |
516 | return 0; /* the device is already active */ | 517 | return 0; |
517 | 518 | ||
518 | /* ensure resources are allocated */ | 519 | /* ensure resources are allocated */ |
519 | if (pnp_auto_config_dev(dev)) | 520 | if (pnp_auto_config_dev(dev)) |
@@ -524,7 +525,7 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
524 | return error; | 525 | return error; |
525 | 526 | ||
526 | dev->active = 1; | 527 | dev->active = 1; |
527 | return 1; | 528 | return 0; |
528 | } | 529 | } |
529 | 530 | ||
530 | /** | 531 | /** |
@@ -538,7 +539,7 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
538 | int error; | 539 | int error; |
539 | 540 | ||
540 | if (!dev->active) | 541 | if (!dev->active) |
541 | return 0; /* the device is already disabled */ | 542 | return 0; |
542 | 543 | ||
543 | error = pnp_stop_dev(dev); | 544 | error = pnp_stop_dev(dev); |
544 | if (error) | 545 | if (error) |
@@ -547,11 +548,11 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
547 | dev->active = 0; | 548 | dev->active = 0; |
548 | 549 | ||
549 | /* release the resources so that other devices can use them */ | 550 | /* release the resources so that other devices can use them */ |
550 | down(&pnp_res_mutex); | 551 | mutex_lock(&pnp_res_mutex); |
551 | pnp_clean_resource_table(&dev->res); | 552 | pnp_clean_resource_table(&dev->res); |
552 | up(&pnp_res_mutex); | 553 | mutex_unlock(&pnp_res_mutex); |
553 | 554 | ||
554 | return 1; | 555 | return 0; |
555 | } | 556 | } |
556 | 557 | ||
557 | /** | 558 | /** |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index dada89906314..662b4c279cfc 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -183,7 +183,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
183 | if (ACPI_SUCCESS(status)) | 183 | if (ACPI_SUCCESS(status)) |
184 | dev->capabilities |= PNP_CONFIGURABLE; | 184 | dev->capabilities |= PNP_CONFIGURABLE; |
185 | dev->capabilities |= PNP_READ; | 185 | dev->capabilities |= PNP_READ; |
186 | if (device->flags.dynamic_status) | 186 | if (device->flags.dynamic_status && (dev->capabilities & PNP_CONFIGURABLE)) |
187 | dev->capabilities |= PNP_WRITE; | 187 | dev->capabilities |= PNP_WRITE; |
188 | if (device->flags.removable) | 188 | if (device->flags.removable) |
189 | dev->capabilities |= PNP_REMOVABLE; | 189 | dev->capabilities |= PNP_REMOVABLE; |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 3c5eb374adf8..6aa231ef642d 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -76,6 +76,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, | |||
76 | int i = 0; | 76 | int i = 0; |
77 | int irq; | 77 | int irq; |
78 | int p, t; | 78 | int p, t; |
79 | static unsigned char warned; | ||
79 | 80 | ||
80 | if (!valid_IRQ(gsi)) | 81 | if (!valid_IRQ(gsi)) |
81 | return; | 82 | return; |
@@ -83,9 +84,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, | |||
83 | while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && | 84 | while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && |
84 | i < PNP_MAX_IRQ) | 85 | i < PNP_MAX_IRQ) |
85 | i++; | 86 | i++; |
86 | if (i >= PNP_MAX_IRQ) { | 87 | if (i >= PNP_MAX_IRQ && !warned) { |
87 | printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ " | 88 | printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ " |
88 | "resources: %d \n", PNP_MAX_IRQ); | 89 | "resources: %d \n", PNP_MAX_IRQ); |
90 | warned = 1; | ||
89 | return; | 91 | return; |
90 | } | 92 | } |
91 | /* | 93 | /* |
@@ -169,6 +171,7 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, | |||
169 | int bus_master, int transfer) | 171 | int bus_master, int transfer) |
170 | { | 172 | { |
171 | int i = 0; | 173 | int i = 0; |
174 | static unsigned char warned; | ||
172 | 175 | ||
173 | while (i < PNP_MAX_DMA && | 176 | while (i < PNP_MAX_DMA && |
174 | !(res->dma_resource[i].flags & IORESOURCE_UNSET)) | 177 | !(res->dma_resource[i].flags & IORESOURCE_UNSET)) |
@@ -183,9 +186,10 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, | |||
183 | } | 186 | } |
184 | res->dma_resource[i].start = dma; | 187 | res->dma_resource[i].start = dma; |
185 | res->dma_resource[i].end = dma; | 188 | res->dma_resource[i].end = dma; |
186 | } else { | 189 | } else if (!warned) { |
187 | printk(KERN_ERR "pnpacpi: exceeded the max number of DMA " | 190 | printk(KERN_ERR "pnpacpi: exceeded the max number of DMA " |
188 | "resources: %d \n", PNP_MAX_DMA); | 191 | "resources: %d \n", PNP_MAX_DMA); |
192 | warned = 1; | ||
189 | } | 193 | } |
190 | } | 194 | } |
191 | 195 | ||
@@ -193,6 +197,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, | |||
193 | u64 io, u64 len, int io_decode) | 197 | u64 io, u64 len, int io_decode) |
194 | { | 198 | { |
195 | int i = 0; | 199 | int i = 0; |
200 | static unsigned char warned; | ||
196 | 201 | ||
197 | while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && | 202 | while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && |
198 | i < PNP_MAX_PORT) | 203 | i < PNP_MAX_PORT) |
@@ -207,9 +212,10 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, | |||
207 | } | 212 | } |
208 | res->port_resource[i].start = io; | 213 | res->port_resource[i].start = io; |
209 | res->port_resource[i].end = io + len - 1; | 214 | res->port_resource[i].end = io + len - 1; |
210 | } else { | 215 | } else if (!warned) { |
211 | printk(KERN_ERR "pnpacpi: exceeded the max number of IO " | 216 | printk(KERN_ERR "pnpacpi: exceeded the max number of IO " |
212 | "resources: %d \n", PNP_MAX_PORT); | 217 | "resources: %d \n", PNP_MAX_PORT); |
218 | warned = 1; | ||
213 | } | 219 | } |
214 | } | 220 | } |
215 | 221 | ||
@@ -218,6 +224,7 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, | |||
218 | int write_protect) | 224 | int write_protect) |
219 | { | 225 | { |
220 | int i = 0; | 226 | int i = 0; |
227 | static unsigned char warned; | ||
221 | 228 | ||
222 | while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && | 229 | while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && |
223 | (i < PNP_MAX_MEM)) | 230 | (i < PNP_MAX_MEM)) |
@@ -233,9 +240,10 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, | |||
233 | 240 | ||
234 | res->mem_resource[i].start = mem; | 241 | res->mem_resource[i].start = mem; |
235 | res->mem_resource[i].end = mem + len - 1; | 242 | res->mem_resource[i].end = mem + len - 1; |
236 | } else { | 243 | } else if (!warned) { |
237 | printk(KERN_ERR "pnpacpi: exceeded the max number of mem " | 244 | printk(KERN_ERR "pnpacpi: exceeded the max number of mem " |
238 | "resources: %d\n", PNP_MAX_MEM); | 245 | "resources: %d\n", PNP_MAX_MEM); |
246 | warned = 1; | ||
239 | } | 247 | } |
240 | } | 248 | } |
241 | 249 | ||
@@ -383,8 +391,8 @@ acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, | |||
383 | pnpacpi_allocated_resource, res); | 391 | pnpacpi_allocated_resource, res); |
384 | } | 392 | } |
385 | 393 | ||
386 | static void pnpacpi_parse_dma_option(struct pnp_option *option, | 394 | static __init void pnpacpi_parse_dma_option(struct pnp_option *option, |
387 | struct acpi_resource_dma *p) | 395 | struct acpi_resource_dma *p) |
388 | { | 396 | { |
389 | int i; | 397 | int i; |
390 | struct pnp_dma *dma; | 398 | struct pnp_dma *dma; |
@@ -403,8 +411,8 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, | |||
403 | pnp_register_dma_resource(option, dma); | 411 | pnp_register_dma_resource(option, dma); |
404 | } | 412 | } |
405 | 413 | ||
406 | static void pnpacpi_parse_irq_option(struct pnp_option *option, | 414 | static __init void pnpacpi_parse_irq_option(struct pnp_option *option, |
407 | struct acpi_resource_irq *p) | 415 | struct acpi_resource_irq *p) |
408 | { | 416 | { |
409 | int i; | 417 | int i; |
410 | struct pnp_irq *irq; | 418 | struct pnp_irq *irq; |
@@ -423,8 +431,8 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option, | |||
423 | pnp_register_irq_resource(option, irq); | 431 | pnp_register_irq_resource(option, irq); |
424 | } | 432 | } |
425 | 433 | ||
426 | static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, | 434 | static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option, |
427 | struct acpi_resource_extended_irq *p) | 435 | struct acpi_resource_extended_irq *p) |
428 | { | 436 | { |
429 | int i; | 437 | int i; |
430 | struct pnp_irq *irq; | 438 | struct pnp_irq *irq; |
@@ -443,8 +451,8 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, | |||
443 | pnp_register_irq_resource(option, irq); | 451 | pnp_register_irq_resource(option, irq); |
444 | } | 452 | } |
445 | 453 | ||
446 | static void pnpacpi_parse_port_option(struct pnp_option *option, | 454 | static __init void pnpacpi_parse_port_option(struct pnp_option *option, |
447 | struct acpi_resource_io *io) | 455 | struct acpi_resource_io *io) |
448 | { | 456 | { |
449 | struct pnp_port *port; | 457 | struct pnp_port *port; |
450 | 458 | ||
@@ -462,8 +470,8 @@ static void pnpacpi_parse_port_option(struct pnp_option *option, | |||
462 | pnp_register_port_resource(option, port); | 470 | pnp_register_port_resource(option, port); |
463 | } | 471 | } |
464 | 472 | ||
465 | static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, | 473 | static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option, |
466 | struct acpi_resource_fixed_io *io) | 474 | struct acpi_resource_fixed_io *io) |
467 | { | 475 | { |
468 | struct pnp_port *port; | 476 | struct pnp_port *port; |
469 | 477 | ||
@@ -479,8 +487,8 @@ static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, | |||
479 | pnp_register_port_resource(option, port); | 487 | pnp_register_port_resource(option, port); |
480 | } | 488 | } |
481 | 489 | ||
482 | static void pnpacpi_parse_mem24_option(struct pnp_option *option, | 490 | static __init void pnpacpi_parse_mem24_option(struct pnp_option *option, |
483 | struct acpi_resource_memory24 *p) | 491 | struct acpi_resource_memory24 *p) |
484 | { | 492 | { |
485 | struct pnp_mem *mem; | 493 | struct pnp_mem *mem; |
486 | 494 | ||
@@ -500,8 +508,8 @@ static void pnpacpi_parse_mem24_option(struct pnp_option *option, | |||
500 | pnp_register_mem_resource(option, mem); | 508 | pnp_register_mem_resource(option, mem); |
501 | } | 509 | } |
502 | 510 | ||
503 | static void pnpacpi_parse_mem32_option(struct pnp_option *option, | 511 | static __init void pnpacpi_parse_mem32_option(struct pnp_option *option, |
504 | struct acpi_resource_memory32 *p) | 512 | struct acpi_resource_memory32 *p) |
505 | { | 513 | { |
506 | struct pnp_mem *mem; | 514 | struct pnp_mem *mem; |
507 | 515 | ||
@@ -521,8 +529,8 @@ static void pnpacpi_parse_mem32_option(struct pnp_option *option, | |||
521 | pnp_register_mem_resource(option, mem); | 529 | pnp_register_mem_resource(option, mem); |
522 | } | 530 | } |
523 | 531 | ||
524 | static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | 532 | static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, |
525 | struct acpi_resource_fixed_memory32 *p) | 533 | struct acpi_resource_fixed_memory32 *p) |
526 | { | 534 | { |
527 | struct pnp_mem *mem; | 535 | struct pnp_mem *mem; |
528 | 536 | ||
@@ -541,8 +549,8 @@ static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | |||
541 | pnp_register_mem_resource(option, mem); | 549 | pnp_register_mem_resource(option, mem); |
542 | } | 550 | } |
543 | 551 | ||
544 | static void pnpacpi_parse_address_option(struct pnp_option *option, | 552 | static __init void pnpacpi_parse_address_option(struct pnp_option *option, |
545 | struct acpi_resource *r) | 553 | struct acpi_resource *r) |
546 | { | 554 | { |
547 | struct acpi_resource_address64 addr, *p = &addr; | 555 | struct acpi_resource_address64 addr, *p = &addr; |
548 | acpi_status status; | 556 | acpi_status status; |
@@ -588,8 +596,8 @@ struct acpipnp_parse_option_s { | |||
588 | struct pnp_dev *dev; | 596 | struct pnp_dev *dev; |
589 | }; | 597 | }; |
590 | 598 | ||
591 | static acpi_status pnpacpi_option_resource(struct acpi_resource *res, | 599 | static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, |
592 | void *data) | 600 | void *data) |
593 | { | 601 | { |
594 | int priority = 0; | 602 | int priority = 0; |
595 | struct acpipnp_parse_option_s *parse_data = data; | 603 | struct acpipnp_parse_option_s *parse_data = data; |
@@ -688,8 +696,8 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, | |||
688 | return AE_OK; | 696 | return AE_OK; |
689 | } | 697 | } |
690 | 698 | ||
691 | acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, | 699 | acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle, |
692 | struct pnp_dev * dev) | 700 | struct pnp_dev *dev) |
693 | { | 701 | { |
694 | acpi_status status; | 702 | acpi_status status; |
695 | struct acpipnp_parse_option_s parse_data; | 703 | struct acpipnp_parse_option_s parse_data; |
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 5dba68fe33f5..a8364d815222 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c | |||
@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(address)); \ | |||
61 | set_limit(gdt[(selname) >> 3], size); \ | 61 | set_limit(gdt[(selname) >> 3], size); \ |
62 | } while(0) | 62 | } while(0) |
63 | 63 | ||
64 | static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; | 64 | static struct desc_struct bad_bios_desc; |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * At some point we want to use this stack frame pointer to unwind | 67 | * At some point we want to use this stack frame pointer to unwind |
@@ -477,6 +477,9 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header) | |||
477 | pnp_bios_callpoint.offset = header->fields.pm16offset; | 477 | pnp_bios_callpoint.offset = header->fields.pm16offset; |
478 | pnp_bios_callpoint.segment = PNP_CS16; | 478 | pnp_bios_callpoint.segment = PNP_CS16; |
479 | 479 | ||
480 | bad_bios_desc.a = 0; | ||
481 | bad_bios_desc.b = 0x00409200; | ||
482 | |||
480 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); | 483 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
481 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); | 484 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
482 | for (i = 0; i < NR_CPUS; i++) { | 485 | for (i = 0; i < NR_CPUS; i++) { |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index e33e03f71084..f7e67197a568 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -315,7 +315,7 @@ struct pnp_protocol pnpbios_protocol = { | |||
315 | .disable = pnpbios_disable_resources, | 315 | .disable = pnpbios_disable_resources, |
316 | }; | 316 | }; |
317 | 317 | ||
318 | static int insert_device(struct pnp_bios_node *node) | 318 | static int __init insert_device(struct pnp_bios_node *node) |
319 | { | 319 | { |
320 | struct list_head *pos; | 320 | struct list_head *pos; |
321 | struct pnp_dev *dev; | 321 | struct pnp_dev *dev; |
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 3fabf11b0027..caade3531416 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
@@ -262,8 +262,8 @@ len_err: | |||
262 | * Resource Configuration Options | 262 | * Resource Configuration Options |
263 | */ | 263 | */ |
264 | 264 | ||
265 | static void pnpbios_parse_mem_option(unsigned char *p, int size, | 265 | static __init void pnpbios_parse_mem_option(unsigned char *p, int size, |
266 | struct pnp_option *option) | 266 | struct pnp_option *option) |
267 | { | 267 | { |
268 | struct pnp_mem *mem; | 268 | struct pnp_mem *mem; |
269 | 269 | ||
@@ -278,8 +278,8 @@ static void pnpbios_parse_mem_option(unsigned char *p, int size, | |||
278 | pnp_register_mem_resource(option, mem); | 278 | pnp_register_mem_resource(option, mem); |
279 | } | 279 | } |
280 | 280 | ||
281 | static void pnpbios_parse_mem32_option(unsigned char *p, int size, | 281 | static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, |
282 | struct pnp_option *option) | 282 | struct pnp_option *option) |
283 | { | 283 | { |
284 | struct pnp_mem *mem; | 284 | struct pnp_mem *mem; |
285 | 285 | ||
@@ -294,8 +294,8 @@ static void pnpbios_parse_mem32_option(unsigned char *p, int size, | |||
294 | pnp_register_mem_resource(option, mem); | 294 | pnp_register_mem_resource(option, mem); |
295 | } | 295 | } |
296 | 296 | ||
297 | static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | 297 | static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, |
298 | struct pnp_option *option) | 298 | struct pnp_option *option) |
299 | { | 299 | { |
300 | struct pnp_mem *mem; | 300 | struct pnp_mem *mem; |
301 | 301 | ||
@@ -309,7 +309,7 @@ static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | |||
309 | pnp_register_mem_resource(option, mem); | 309 | pnp_register_mem_resource(option, mem); |
310 | } | 310 | } |
311 | 311 | ||
312 | static void pnpbios_parse_irq_option(unsigned char *p, int size, | 312 | static __init void pnpbios_parse_irq_option(unsigned char *p, int size, |
313 | struct pnp_option *option) | 313 | struct pnp_option *option) |
314 | { | 314 | { |
315 | struct pnp_irq *irq; | 315 | struct pnp_irq *irq; |
@@ -327,7 +327,7 @@ static void pnpbios_parse_irq_option(unsigned char *p, int size, | |||
327 | pnp_register_irq_resource(option, irq); | 327 | pnp_register_irq_resource(option, irq); |
328 | } | 328 | } |
329 | 329 | ||
330 | static void pnpbios_parse_dma_option(unsigned char *p, int size, | 330 | static __init void pnpbios_parse_dma_option(unsigned char *p, int size, |
331 | struct pnp_option *option) | 331 | struct pnp_option *option) |
332 | { | 332 | { |
333 | struct pnp_dma *dma; | 333 | struct pnp_dma *dma; |
@@ -340,8 +340,8 @@ static void pnpbios_parse_dma_option(unsigned char *p, int size, | |||
340 | pnp_register_dma_resource(option, dma); | 340 | pnp_register_dma_resource(option, dma); |
341 | } | 341 | } |
342 | 342 | ||
343 | static void pnpbios_parse_port_option(unsigned char *p, int size, | 343 | static __init void pnpbios_parse_port_option(unsigned char *p, int size, |
344 | struct pnp_option *option) | 344 | struct pnp_option *option) |
345 | { | 345 | { |
346 | struct pnp_port *port; | 346 | struct pnp_port *port; |
347 | 347 | ||
@@ -356,8 +356,8 @@ static void pnpbios_parse_port_option(unsigned char *p, int size, | |||
356 | pnp_register_port_resource(option, port); | 356 | pnp_register_port_resource(option, port); |
357 | } | 357 | } |
358 | 358 | ||
359 | static void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | 359 | static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, |
360 | struct pnp_option *option) | 360 | struct pnp_option *option) |
361 | { | 361 | { |
362 | struct pnp_port *port; | 362 | struct pnp_port *port; |
363 | 363 | ||
@@ -371,9 +371,9 @@ static void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | |||
371 | pnp_register_port_resource(option, port); | 371 | pnp_register_port_resource(option, port); |
372 | } | 372 | } |
373 | 373 | ||
374 | static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p, | 374 | static __init unsigned char * |
375 | unsigned char *end, | 375 | pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, |
376 | struct pnp_dev *dev) | 376 | struct pnp_dev *dev) |
377 | { | 377 | { |
378 | unsigned int len, tag; | 378 | unsigned int len, tag; |
379 | int priority = 0; | 379 | int priority = 0; |
@@ -781,7 +781,8 @@ len_err: | |||
781 | * Core Parsing Functions | 781 | * Core Parsing Functions |
782 | */ | 782 | */ |
783 | 783 | ||
784 | int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node *node) | 784 | int __init pnpbios_parse_data_stream(struct pnp_dev *dev, |
785 | struct pnp_bios_node *node) | ||
785 | { | 786 | { |
786 | unsigned char *p = (char *)node->data; | 787 | unsigned char *p = (char *)node->data; |
787 | unsigned char *end = (char *)(node->data + node->size); | 788 | unsigned char *end = (char *)(node->data + node->size); |
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index e903b8c2b1fa..4065139753b6 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pnp.h> | 18 | #include <linux/pnp.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/dmi.h> | ||
20 | #include <linux/kallsyms.h> | 21 | #include <linux/kallsyms.h> |
21 | #include "base.h" | 22 | #include "base.h" |
22 | 23 | ||
@@ -108,6 +109,46 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) | |||
108 | "pnp: SB audio device quirk - increasing port range\n"); | 109 | "pnp: SB audio device quirk - increasing port range\n"); |
109 | } | 110 | } |
110 | 111 | ||
112 | static void quirk_supermicro_h8dce_system(struct pnp_dev *dev) | ||
113 | { | ||
114 | int i; | ||
115 | static struct dmi_system_id supermicro_h8dce[] = { | ||
116 | { | ||
117 | .ident = "Supermicro H8DCE", | ||
118 | .matches = { | ||
119 | DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), | ||
120 | DMI_MATCH(DMI_PRODUCT_NAME, "H8DCE"), | ||
121 | }, | ||
122 | }, | ||
123 | { } | ||
124 | }; | ||
125 | |||
126 | if (!dmi_check_system(supermicro_h8dce)) | ||
127 | return; | ||
128 | |||
129 | /* | ||
130 | * On the Supermicro H8DCE, there's a system device with resources | ||
131 | * that overlap BAR 6 of the built-in SATA PCI adapter. If the PNP | ||
132 | * system device claims them, the sata_nv driver won't be able to. | ||
133 | * More details at: | ||
134 | * https://bugzilla.redhat.com/show_bug.cgi?id=280641 | ||
135 | * https://bugzilla.redhat.com/show_bug.cgi?id=313491 | ||
136 | * http://lkml.org/lkml/2008/1/9/449 | ||
137 | * http://thread.gmane.org/gmane.linux.acpi.devel/27312 | ||
138 | */ | ||
139 | for (i = 0; i < PNP_MAX_MEM; i++) { | ||
140 | if (pnp_mem_valid(dev, i) && pnp_mem_len(dev, i) && | ||
141 | (pnp_mem_start(dev, i) & 0xdfef0000) == 0xdfef0000) { | ||
142 | dev_warn(&dev->dev, "disabling 0x%llx-0x%llx to prevent" | ||
143 | " conflict with sata_nv PCI device\n", | ||
144 | (unsigned long long) pnp_mem_start(dev, i), | ||
145 | (unsigned long long) (pnp_mem_start(dev, i) + | ||
146 | pnp_mem_len(dev, i) - 1)); | ||
147 | pnp_mem_flags(dev, i) = 0; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
111 | /* | 152 | /* |
112 | * PnP Quirks | 153 | * PnP Quirks |
113 | * Cards or devices that need some tweaking due to incomplete resource info | 154 | * Cards or devices that need some tweaking due to incomplete resource info |
@@ -128,6 +169,8 @@ static struct pnp_fixup pnp_fixups[] = { | |||
128 | {"CTL0043", quirk_sb16audio_resources}, | 169 | {"CTL0043", quirk_sb16audio_resources}, |
129 | {"CTL0044", quirk_sb16audio_resources}, | 170 | {"CTL0044", quirk_sb16audio_resources}, |
130 | {"CTL0045", quirk_sb16audio_resources}, | 171 | {"CTL0045", quirk_sb16audio_resources}, |
172 | {"PNP0c01", quirk_supermicro_h8dce_system}, | ||
173 | {"PNP0c02", quirk_supermicro_h8dce_system}, | ||
131 | {""} | 174 | {""} |
132 | }; | 175 | }; |
133 | 176 | ||