aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/driver.c12
-rw-r--r--drivers/pnp/interface.c13
-rw-r--r--drivers/pnp/manager.c27
-rw-r--r--drivers/pnp/pnpacpi/core.c2
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c44
-rw-r--r--drivers/pnp/pnpbios/core.c2
-rw-r--r--drivers/pnp/pnpbios/rsparser.c33
-rw-r--r--drivers/pnp/quirks.c43
8 files changed, 112 insertions, 64 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
318extern struct semaphore pnp_res_mutex;
319
320static ssize_t 321static ssize_t
321pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, 322pnp_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
17DECLARE_MUTEX(pnp_res_mutex); 18DEFINE_MUTEX(pnp_res_mutex);
18 19
19static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 20static 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
372fail: 373fail:
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
424fail: 425fail:
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 6b9840cce0f4..6aa231ef642d 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -391,8 +391,8 @@ acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle,
391 pnpacpi_allocated_resource, res); 391 pnpacpi_allocated_resource, res);
392} 392}
393 393
394static void pnpacpi_parse_dma_option(struct pnp_option *option, 394static __init void pnpacpi_parse_dma_option(struct pnp_option *option,
395 struct acpi_resource_dma *p) 395 struct acpi_resource_dma *p)
396{ 396{
397 int i; 397 int i;
398 struct pnp_dma *dma; 398 struct pnp_dma *dma;
@@ -411,8 +411,8 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option,
411 pnp_register_dma_resource(option, dma); 411 pnp_register_dma_resource(option, dma);
412} 412}
413 413
414static void pnpacpi_parse_irq_option(struct pnp_option *option, 414static __init void pnpacpi_parse_irq_option(struct pnp_option *option,
415 struct acpi_resource_irq *p) 415 struct acpi_resource_irq *p)
416{ 416{
417 int i; 417 int i;
418 struct pnp_irq *irq; 418 struct pnp_irq *irq;
@@ -431,8 +431,8 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option,
431 pnp_register_irq_resource(option, irq); 431 pnp_register_irq_resource(option, irq);
432} 432}
433 433
434static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, 434static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
435 struct acpi_resource_extended_irq *p) 435 struct acpi_resource_extended_irq *p)
436{ 436{
437 int i; 437 int i;
438 struct pnp_irq *irq; 438 struct pnp_irq *irq;
@@ -451,8 +451,8 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
451 pnp_register_irq_resource(option, irq); 451 pnp_register_irq_resource(option, irq);
452} 452}
453 453
454static void pnpacpi_parse_port_option(struct pnp_option *option, 454static __init void pnpacpi_parse_port_option(struct pnp_option *option,
455 struct acpi_resource_io *io) 455 struct acpi_resource_io *io)
456{ 456{
457 struct pnp_port *port; 457 struct pnp_port *port;
458 458
@@ -470,8 +470,8 @@ static void pnpacpi_parse_port_option(struct pnp_option *option,
470 pnp_register_port_resource(option, port); 470 pnp_register_port_resource(option, port);
471} 471}
472 472
473static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, 473static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
474 struct acpi_resource_fixed_io *io) 474 struct acpi_resource_fixed_io *io)
475{ 475{
476 struct pnp_port *port; 476 struct pnp_port *port;
477 477
@@ -487,8 +487,8 @@ static void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
487 pnp_register_port_resource(option, port); 487 pnp_register_port_resource(option, port);
488} 488}
489 489
490static void pnpacpi_parse_mem24_option(struct pnp_option *option, 490static __init void pnpacpi_parse_mem24_option(struct pnp_option *option,
491 struct acpi_resource_memory24 *p) 491 struct acpi_resource_memory24 *p)
492{ 492{
493 struct pnp_mem *mem; 493 struct pnp_mem *mem;
494 494
@@ -508,8 +508,8 @@ static void pnpacpi_parse_mem24_option(struct pnp_option *option,
508 pnp_register_mem_resource(option, mem); 508 pnp_register_mem_resource(option, mem);
509} 509}
510 510
511static void pnpacpi_parse_mem32_option(struct pnp_option *option, 511static __init void pnpacpi_parse_mem32_option(struct pnp_option *option,
512 struct acpi_resource_memory32 *p) 512 struct acpi_resource_memory32 *p)
513{ 513{
514 struct pnp_mem *mem; 514 struct pnp_mem *mem;
515 515
@@ -529,8 +529,8 @@ static void pnpacpi_parse_mem32_option(struct pnp_option *option,
529 pnp_register_mem_resource(option, mem); 529 pnp_register_mem_resource(option, mem);
530} 530}
531 531
532static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, 532static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
533 struct acpi_resource_fixed_memory32 *p) 533 struct acpi_resource_fixed_memory32 *p)
534{ 534{
535 struct pnp_mem *mem; 535 struct pnp_mem *mem;
536 536
@@ -549,8 +549,8 @@ static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
549 pnp_register_mem_resource(option, mem); 549 pnp_register_mem_resource(option, mem);
550} 550}
551 551
552static void pnpacpi_parse_address_option(struct pnp_option *option, 552static __init void pnpacpi_parse_address_option(struct pnp_option *option,
553 struct acpi_resource *r) 553 struct acpi_resource *r)
554{ 554{
555 struct acpi_resource_address64 addr, *p = &addr; 555 struct acpi_resource_address64 addr, *p = &addr;
556 acpi_status status; 556 acpi_status status;
@@ -596,8 +596,8 @@ struct acpipnp_parse_option_s {
596 struct pnp_dev *dev; 596 struct pnp_dev *dev;
597}; 597};
598 598
599static acpi_status pnpacpi_option_resource(struct acpi_resource *res, 599static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
600 void *data) 600 void *data)
601{ 601{
602 int priority = 0; 602 int priority = 0;
603 struct acpipnp_parse_option_s *parse_data = data; 603 struct acpipnp_parse_option_s *parse_data = data;
@@ -696,8 +696,8 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
696 return AE_OK; 696 return AE_OK;
697} 697}
698 698
699acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, 699acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle,
700 struct pnp_dev * dev) 700 struct pnp_dev *dev)
701{ 701{
702 acpi_status status; 702 acpi_status status;
703 struct acpipnp_parse_option_s parse_data; 703 struct acpipnp_parse_option_s parse_data;
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
318static int insert_device(struct pnp_bios_node *node) 318static 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
265static void pnpbios_parse_mem_option(unsigned char *p, int size, 265static __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
281static void pnpbios_parse_mem32_option(unsigned char *p, int size, 281static __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
297static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, 297static __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
312static void pnpbios_parse_irq_option(unsigned char *p, int size, 312static __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
330static void pnpbios_parse_dma_option(unsigned char *p, int size, 330static __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
343static void pnpbios_parse_port_option(unsigned char *p, int size, 343static __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
359static void pnpbios_parse_fixed_port_option(unsigned char *p, int size, 359static __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
374static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p, 374static __init unsigned char *
375 unsigned char *end, 375pnpbios_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
784int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node *node) 784int __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
112static 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