diff options
Diffstat (limited to 'drivers/pnp/isapnp/core.c')
| -rw-r--r-- | drivers/pnp/isapnp/core.c | 340 |
1 files changed, 168 insertions, 172 deletions
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 257f5d827d83..f1bccdbdeb08 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c | |||
| @@ -44,6 +44,8 @@ | |||
| 44 | #include <linux/mutex.h> | 44 | #include <linux/mutex.h> |
| 45 | #include <asm/io.h> | 45 | #include <asm/io.h> |
| 46 | 46 | ||
| 47 | #include "../base.h" | ||
| 48 | |||
| 47 | #if 0 | 49 | #if 0 |
| 48 | #define ISAPNP_REGION_OK | 50 | #define ISAPNP_REGION_OK |
| 49 | #endif | 51 | #endif |
| @@ -88,6 +90,14 @@ MODULE_LICENSE("GPL"); | |||
| 88 | #define _LTAG_MEM32RANGE 0x85 | 90 | #define _LTAG_MEM32RANGE 0x85 |
| 89 | #define _LTAG_FIXEDMEM32RANGE 0x86 | 91 | #define _LTAG_FIXEDMEM32RANGE 0x86 |
| 90 | 92 | ||
| 93 | /* Logical device control and configuration registers */ | ||
| 94 | |||
| 95 | #define ISAPNP_CFG_ACTIVATE 0x30 /* byte */ | ||
| 96 | #define ISAPNP_CFG_MEM 0x40 /* 4 * dword */ | ||
| 97 | #define ISAPNP_CFG_PORT 0x60 /* 8 * word */ | ||
| 98 | #define ISAPNP_CFG_IRQ 0x70 /* 2 * word */ | ||
| 99 | #define ISAPNP_CFG_DMA 0x74 /* 2 * byte */ | ||
| 100 | |||
| 91 | /* | 101 | /* |
| 92 | * Sizes of ISAPNP logical device configuration register sets. | 102 | * Sizes of ISAPNP logical device configuration register sets. |
| 93 | * See PNP-ISA-v1.0a.pdf, Appendix A. | 103 | * See PNP-ISA-v1.0a.pdf, Appendix A. |
| @@ -388,28 +398,6 @@ static void __init isapnp_skip_bytes(int count) | |||
| 388 | } | 398 | } |
| 389 | 399 | ||
| 390 | /* | 400 | /* |
| 391 | * Parse EISA id. | ||
| 392 | */ | ||
| 393 | static void isapnp_parse_id(struct pnp_dev *dev, unsigned short vendor, | ||
| 394 | unsigned short device) | ||
| 395 | { | ||
| 396 | struct pnp_id *id; | ||
| 397 | |||
| 398 | if (!dev) | ||
| 399 | return; | ||
| 400 | id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); | ||
| 401 | if (!id) | ||
| 402 | return; | ||
| 403 | sprintf(id->id, "%c%c%c%x%x%x%x", | ||
| 404 | 'A' + ((vendor >> 2) & 0x3f) - 1, | ||
| 405 | 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, | ||
| 406 | 'A' + ((vendor >> 8) & 0x1f) - 1, | ||
| 407 | (device >> 4) & 0x0f, | ||
| 408 | device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f); | ||
| 409 | pnp_add_id(id, dev); | ||
| 410 | } | ||
| 411 | |||
| 412 | /* | ||
| 413 | * Parse logical device tag. | 401 | * Parse logical device tag. |
| 414 | */ | 402 | */ |
| 415 | static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, | 403 | static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, |
| @@ -417,30 +405,31 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, | |||
| 417 | { | 405 | { |
| 418 | unsigned char tmp[6]; | 406 | unsigned char tmp[6]; |
| 419 | struct pnp_dev *dev; | 407 | struct pnp_dev *dev; |
| 408 | u32 eisa_id; | ||
| 409 | char id[8]; | ||
| 420 | 410 | ||
| 421 | isapnp_peek(tmp, size); | 411 | isapnp_peek(tmp, size); |
| 422 | dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); | 412 | eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24; |
| 413 | pnp_eisa_id_to_string(eisa_id, id); | ||
| 414 | |||
| 415 | dev = pnp_alloc_dev(&isapnp_protocol, number, id); | ||
| 423 | if (!dev) | 416 | if (!dev) |
| 424 | return NULL; | 417 | return NULL; |
| 425 | dev->number = number; | 418 | |
| 426 | isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]); | ||
| 427 | dev->regs = tmp[4]; | ||
| 428 | dev->card = card; | 419 | dev->card = card; |
| 429 | if (size > 5) | ||
| 430 | dev->regs |= tmp[5] << 8; | ||
| 431 | dev->protocol = &isapnp_protocol; | ||
| 432 | dev->capabilities |= PNP_CONFIGURABLE; | 420 | dev->capabilities |= PNP_CONFIGURABLE; |
| 433 | dev->capabilities |= PNP_READ; | 421 | dev->capabilities |= PNP_READ; |
| 434 | dev->capabilities |= PNP_WRITE; | 422 | dev->capabilities |= PNP_WRITE; |
| 435 | dev->capabilities |= PNP_DISABLE; | 423 | dev->capabilities |= PNP_DISABLE; |
| 436 | pnp_init_resource_table(&dev->res); | 424 | pnp_init_resources(dev); |
| 437 | return dev; | 425 | return dev; |
| 438 | } | 426 | } |
| 439 | 427 | ||
| 440 | /* | 428 | /* |
| 441 | * Add IRQ resource to resources list. | 429 | * Add IRQ resource to resources list. |
| 442 | */ | 430 | */ |
| 443 | static void __init isapnp_parse_irq_resource(struct pnp_option *option, | 431 | static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, |
| 432 | struct pnp_option *option, | ||
| 444 | int size) | 433 | int size) |
| 445 | { | 434 | { |
| 446 | unsigned char tmp[3]; | 435 | unsigned char tmp[3]; |
| @@ -457,13 +446,14 @@ static void __init isapnp_parse_irq_resource(struct pnp_option *option, | |||
| 457 | irq->flags = tmp[2]; | 446 | irq->flags = tmp[2]; |
| 458 | else | 447 | else |
| 459 | irq->flags = IORESOURCE_IRQ_HIGHEDGE; | 448 | irq->flags = IORESOURCE_IRQ_HIGHEDGE; |
| 460 | pnp_register_irq_resource(option, irq); | 449 | pnp_register_irq_resource(dev, option, irq); |
| 461 | } | 450 | } |
| 462 | 451 | ||
| 463 | /* | 452 | /* |
| 464 | * Add DMA resource to resources list. | 453 | * Add DMA resource to resources list. |
| 465 | */ | 454 | */ |
| 466 | static void __init isapnp_parse_dma_resource(struct pnp_option *option, | 455 | static void __init isapnp_parse_dma_resource(struct pnp_dev *dev, |
| 456 | struct pnp_option *option, | ||
| 467 | int size) | 457 | int size) |
| 468 | { | 458 | { |
| 469 | unsigned char tmp[2]; | 459 | unsigned char tmp[2]; |
| @@ -475,13 +465,14 @@ static void __init isapnp_parse_dma_resource(struct pnp_option *option, | |||
| 475 | return; | 465 | return; |
| 476 | dma->map = tmp[0]; | 466 | dma->map = tmp[0]; |
| 477 | dma->flags = tmp[1]; | 467 | dma->flags = tmp[1]; |
| 478 | pnp_register_dma_resource(option, dma); | 468 | pnp_register_dma_resource(dev, option, dma); |
| 479 | } | 469 | } |
| 480 | 470 | ||
| 481 | /* | 471 | /* |
| 482 | * Add port resource to resources list. | 472 | * Add port resource to resources list. |
| 483 | */ | 473 | */ |
| 484 | static void __init isapnp_parse_port_resource(struct pnp_option *option, | 474 | static void __init isapnp_parse_port_resource(struct pnp_dev *dev, |
| 475 | struct pnp_option *option, | ||
| 485 | int size) | 476 | int size) |
| 486 | { | 477 | { |
| 487 | unsigned char tmp[7]; | 478 | unsigned char tmp[7]; |
| @@ -496,13 +487,14 @@ static void __init isapnp_parse_port_resource(struct pnp_option *option, | |||
| 496 | port->align = tmp[5]; | 487 | port->align = tmp[5]; |
| 497 | port->size = tmp[6]; | 488 | port->size = tmp[6]; |
| 498 | port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0; | 489 | port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0; |
| 499 | pnp_register_port_resource(option, port); | 490 | pnp_register_port_resource(dev, option, port); |
| 500 | } | 491 | } |
| 501 | 492 | ||
| 502 | /* | 493 | /* |
| 503 | * Add fixed port resource to resources list. | 494 | * Add fixed port resource to resources list. |
| 504 | */ | 495 | */ |
| 505 | static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option, | 496 | static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, |
| 497 | struct pnp_option *option, | ||
| 506 | int size) | 498 | int size) |
| 507 | { | 499 | { |
| 508 | unsigned char tmp[3]; | 500 | unsigned char tmp[3]; |
| @@ -516,13 +508,14 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option, | |||
| 516 | port->size = tmp[2]; | 508 | port->size = tmp[2]; |
| 517 | port->align = 0; | 509 | port->align = 0; |
| 518 | port->flags = PNP_PORT_FLAG_FIXED; | 510 | port->flags = PNP_PORT_FLAG_FIXED; |
| 519 | pnp_register_port_resource(option, port); | 511 | pnp_register_port_resource(dev, option, port); |
| 520 | } | 512 | } |
| 521 | 513 | ||
| 522 | /* | 514 | /* |
| 523 | * Add memory resource to resources list. | 515 | * Add memory resource to resources list. |
| 524 | */ | 516 | */ |
| 525 | static void __init isapnp_parse_mem_resource(struct pnp_option *option, | 517 | static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, |
| 518 | struct pnp_option *option, | ||
| 526 | int size) | 519 | int size) |
| 527 | { | 520 | { |
| 528 | unsigned char tmp[9]; | 521 | unsigned char tmp[9]; |
| @@ -537,13 +530,14 @@ static void __init isapnp_parse_mem_resource(struct pnp_option *option, | |||
| 537 | mem->align = (tmp[6] << 8) | tmp[5]; | 530 | mem->align = (tmp[6] << 8) | tmp[5]; |
| 538 | mem->size = ((tmp[8] << 8) | tmp[7]) << 8; | 531 | mem->size = ((tmp[8] << 8) | tmp[7]) << 8; |
| 539 | mem->flags = tmp[0]; | 532 | mem->flags = tmp[0]; |
| 540 | pnp_register_mem_resource(option, mem); | 533 | pnp_register_mem_resource(dev, option, mem); |
| 541 | } | 534 | } |
| 542 | 535 | ||
| 543 | /* | 536 | /* |
| 544 | * Add 32-bit memory resource to resources list. | 537 | * Add 32-bit memory resource to resources list. |
| 545 | */ | 538 | */ |
| 546 | static void __init isapnp_parse_mem32_resource(struct pnp_option *option, | 539 | static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, |
| 540 | struct pnp_option *option, | ||
| 547 | int size) | 541 | int size) |
| 548 | { | 542 | { |
| 549 | unsigned char tmp[17]; | 543 | unsigned char tmp[17]; |
| @@ -560,13 +554,14 @@ static void __init isapnp_parse_mem32_resource(struct pnp_option *option, | |||
| 560 | mem->size = | 554 | mem->size = |
| 561 | (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; | 555 | (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; |
| 562 | mem->flags = tmp[0]; | 556 | mem->flags = tmp[0]; |
| 563 | pnp_register_mem_resource(option, mem); | 557 | pnp_register_mem_resource(dev, option, mem); |
| 564 | } | 558 | } |
| 565 | 559 | ||
| 566 | /* | 560 | /* |
| 567 | * Add 32-bit fixed memory resource to resources list. | 561 | * Add 32-bit fixed memory resource to resources list. |
| 568 | */ | 562 | */ |
| 569 | static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option, | 563 | static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, |
| 564 | struct pnp_option *option, | ||
| 570 | int size) | 565 | int size) |
| 571 | { | 566 | { |
| 572 | unsigned char tmp[9]; | 567 | unsigned char tmp[9]; |
| @@ -581,7 +576,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option, | |||
| 581 | mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; | 576 | mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; |
| 582 | mem->align = 0; | 577 | mem->align = 0; |
| 583 | mem->flags = tmp[0]; | 578 | mem->flags = tmp[0]; |
| 584 | pnp_register_mem_resource(option, mem); | 579 | pnp_register_mem_resource(dev, option, mem); |
| 585 | } | 580 | } |
| 586 | 581 | ||
| 587 | /* | 582 | /* |
| @@ -613,6 +608,8 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 613 | unsigned char type, tmp[17]; | 608 | unsigned char type, tmp[17]; |
| 614 | struct pnp_option *option; | 609 | struct pnp_option *option; |
| 615 | struct pnp_dev *dev; | 610 | struct pnp_dev *dev; |
| 611 | u32 eisa_id; | ||
| 612 | char id[8]; | ||
| 616 | 613 | ||
| 617 | if ((dev = isapnp_parse_device(card, size, number++)) == NULL) | 614 | if ((dev = isapnp_parse_device(card, size, number++)) == NULL) |
| 618 | return 1; | 615 | return 1; |
| @@ -652,8 +649,10 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 652 | case _STAG_COMPATDEVID: | 649 | case _STAG_COMPATDEVID: |
| 653 | if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) { | 650 | if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) { |
| 654 | isapnp_peek(tmp, 4); | 651 | isapnp_peek(tmp, 4); |
| 655 | isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], | 652 | eisa_id = tmp[0] | tmp[1] << 8 | |
| 656 | (tmp[3] << 8) | tmp[2]); | 653 | tmp[2] << 16 | tmp[3] << 24; |
| 654 | pnp_eisa_id_to_string(eisa_id, id); | ||
| 655 | pnp_add_id(dev, id); | ||
| 657 | compat++; | 656 | compat++; |
| 658 | size = 0; | 657 | size = 0; |
| 659 | } | 658 | } |
| @@ -661,13 +660,13 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 661 | case _STAG_IRQ: | 660 | case _STAG_IRQ: |
| 662 | if (size < 2 || size > 3) | 661 | if (size < 2 || size > 3) |
| 663 | goto __skip; | 662 | goto __skip; |
| 664 | isapnp_parse_irq_resource(option, size); | 663 | isapnp_parse_irq_resource(dev, option, size); |
| 665 | size = 0; | 664 | size = 0; |
| 666 | break; | 665 | break; |
| 667 | case _STAG_DMA: | 666 | case _STAG_DMA: |
| 668 | if (size != 2) | 667 | if (size != 2) |
| 669 | goto __skip; | 668 | goto __skip; |
| 670 | isapnp_parse_dma_resource(option, size); | 669 | isapnp_parse_dma_resource(dev, option, size); |
| 671 | size = 0; | 670 | size = 0; |
| 672 | break; | 671 | break; |
| 673 | case _STAG_STARTDEP: | 672 | case _STAG_STARTDEP: |
| @@ -687,17 +686,18 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 687 | if (size != 0) | 686 | if (size != 0) |
| 688 | goto __skip; | 687 | goto __skip; |
| 689 | priority = 0; | 688 | priority = 0; |
| 689 | dev_dbg(&dev->dev, "end dependent options\n"); | ||
| 690 | break; | 690 | break; |
| 691 | case _STAG_IOPORT: | 691 | case _STAG_IOPORT: |
| 692 | if (size != 7) | 692 | if (size != 7) |
| 693 | goto __skip; | 693 | goto __skip; |
| 694 | isapnp_parse_port_resource(option, size); | 694 | isapnp_parse_port_resource(dev, option, size); |
| 695 | size = 0; | 695 | size = 0; |
| 696 | break; | 696 | break; |
| 697 | case _STAG_FIXEDIO: | 697 | case _STAG_FIXEDIO: |
| 698 | if (size != 3) | 698 | if (size != 3) |
| 699 | goto __skip; | 699 | goto __skip; |
| 700 | isapnp_parse_fixed_port_resource(option, size); | 700 | isapnp_parse_fixed_port_resource(dev, option, size); |
| 701 | size = 0; | 701 | size = 0; |
| 702 | break; | 702 | break; |
| 703 | case _STAG_VENDOR: | 703 | case _STAG_VENDOR: |
| @@ -705,7 +705,7 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 705 | case _LTAG_MEMRANGE: | 705 | case _LTAG_MEMRANGE: |
| 706 | if (size != 9) | 706 | if (size != 9) |
| 707 | goto __skip; | 707 | goto __skip; |
| 708 | isapnp_parse_mem_resource(option, size); | 708 | isapnp_parse_mem_resource(dev, option, size); |
| 709 | size = 0; | 709 | size = 0; |
| 710 | break; | 710 | break; |
| 711 | case _LTAG_ANSISTR: | 711 | case _LTAG_ANSISTR: |
| @@ -720,13 +720,13 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 720 | case _LTAG_MEM32RANGE: | 720 | case _LTAG_MEM32RANGE: |
| 721 | if (size != 17) | 721 | if (size != 17) |
| 722 | goto __skip; | 722 | goto __skip; |
| 723 | isapnp_parse_mem32_resource(option, size); | 723 | isapnp_parse_mem32_resource(dev, option, size); |
| 724 | size = 0; | 724 | size = 0; |
| 725 | break; | 725 | break; |
| 726 | case _LTAG_FIXEDMEM32RANGE: | 726 | case _LTAG_FIXEDMEM32RANGE: |
| 727 | if (size != 9) | 727 | if (size != 9) |
| 728 | goto __skip; | 728 | goto __skip; |
| 729 | isapnp_parse_fixed_mem32_resource(option, size); | 729 | isapnp_parse_fixed_mem32_resource(dev, option, size); |
| 730 | size = 0; | 730 | size = 0; |
| 731 | break; | 731 | break; |
| 732 | case _STAG_END: | 732 | case _STAG_END: |
| @@ -734,9 +734,8 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 734 | isapnp_skip_bytes(size); | 734 | isapnp_skip_bytes(size); |
| 735 | return 1; | 735 | return 1; |
| 736 | default: | 736 | default: |
| 737 | printk(KERN_ERR | 737 | dev_err(&dev->dev, "unknown tag %#x (card %i), " |
| 738 | "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", | 738 | "ignored\n", type, card->number); |
| 739 | type, dev->number, card->number); | ||
| 740 | } | 739 | } |
| 741 | __skip: | 740 | __skip: |
| 742 | if (size > 0) | 741 | if (size > 0) |
| @@ -789,9 +788,8 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card) | |||
| 789 | isapnp_skip_bytes(size); | 788 | isapnp_skip_bytes(size); |
| 790 | return; | 789 | return; |
| 791 | default: | 790 | default: |
| 792 | printk(KERN_ERR | 791 | dev_err(&card->dev, "unknown tag %#x, ignored\n", |
| 793 | "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", | 792 | type); |
| 794 | type, card->number); | ||
| 795 | } | 793 | } |
| 796 | __skip: | 794 | __skip: |
| 797 | if (size > 0) | 795 | if (size > 0) |
| @@ -822,25 +820,6 @@ static unsigned char __init isapnp_checksum(unsigned char *data) | |||
| 822 | } | 820 | } |
| 823 | 821 | ||
| 824 | /* | 822 | /* |
| 825 | * Parse EISA id for ISA PnP card. | ||
| 826 | */ | ||
| 827 | static void isapnp_parse_card_id(struct pnp_card *card, unsigned short vendor, | ||
| 828 | unsigned short device) | ||
| 829 | { | ||
| 830 | struct pnp_id *id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); | ||
| 831 | |||
| 832 | if (!id) | ||
| 833 | return; | ||
| 834 | sprintf(id->id, "%c%c%c%x%x%x%x", | ||
| 835 | 'A' + ((vendor >> 2) & 0x3f) - 1, | ||
| 836 | 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, | ||
| 837 | 'A' + ((vendor >> 8) & 0x1f) - 1, | ||
| 838 | (device >> 4) & 0x0f, | ||
| 839 | device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f); | ||
| 840 | pnp_add_card_id(id, card); | ||
| 841 | } | ||
| 842 | |||
| 843 | /* | ||
| 844 | * Build device list for all present ISA PnP devices. | 823 | * Build device list for all present ISA PnP devices. |
| 845 | */ | 824 | */ |
| 846 | static int __init isapnp_build_device_list(void) | 825 | static int __init isapnp_build_device_list(void) |
| @@ -848,6 +827,8 @@ static int __init isapnp_build_device_list(void) | |||
| 848 | int csn; | 827 | int csn; |
| 849 | unsigned char header[9], checksum; | 828 | unsigned char header[9], checksum; |
| 850 | struct pnp_card *card; | 829 | struct pnp_card *card; |
| 830 | u32 eisa_id; | ||
| 831 | char id[8]; | ||
| 851 | 832 | ||
| 852 | isapnp_wait(); | 833 | isapnp_wait(); |
| 853 | isapnp_key(); | 834 | isapnp_key(); |
| @@ -855,32 +836,30 @@ static int __init isapnp_build_device_list(void) | |||
| 855 | isapnp_wake(csn); | 836 | isapnp_wake(csn); |
| 856 | isapnp_peek(header, 9); | 837 | isapnp_peek(header, 9); |
| 857 | checksum = isapnp_checksum(header); | 838 | checksum = isapnp_checksum(header); |
| 839 | eisa_id = header[0] | header[1] << 8 | | ||
| 840 | header[2] << 16 | header[3] << 24; | ||
| 841 | pnp_eisa_id_to_string(eisa_id, id); | ||
| 842 | card = pnp_alloc_card(&isapnp_protocol, csn, id); | ||
| 843 | if (!card) | ||
| 844 | continue; | ||
| 845 | |||
| 858 | #if 0 | 846 | #if 0 |
| 859 | printk(KERN_DEBUG | 847 | dev_info(&card->dev, |
| 860 | "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", | 848 | "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", |
| 861 | header[0], header[1], header[2], header[3], header[4], | 849 | header[0], header[1], header[2], header[3], header[4], |
| 862 | header[5], header[6], header[7], header[8]); | 850 | header[5], header[6], header[7], header[8]); |
| 863 | printk(KERN_DEBUG "checksum = 0x%x\n", checksum); | 851 | dev_info(&card->dev, "checksum = %#x\n", checksum); |
| 864 | #endif | 852 | #endif |
| 865 | if ((card = | ||
| 866 | kzalloc(sizeof(struct pnp_card), GFP_KERNEL)) == NULL) | ||
| 867 | continue; | ||
| 868 | |||
| 869 | card->number = csn; | ||
| 870 | INIT_LIST_HEAD(&card->devices); | 853 | INIT_LIST_HEAD(&card->devices); |
| 871 | isapnp_parse_card_id(card, (header[1] << 8) | header[0], | ||
| 872 | (header[3] << 8) | header[2]); | ||
| 873 | card->serial = | 854 | card->serial = |
| 874 | (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | | 855 | (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | |
| 875 | header[4]; | 856 | header[4]; |
| 876 | isapnp_checksum_value = 0x00; | 857 | isapnp_checksum_value = 0x00; |
| 877 | isapnp_parse_resource_map(card); | 858 | isapnp_parse_resource_map(card); |
| 878 | if (isapnp_checksum_value != 0x00) | 859 | if (isapnp_checksum_value != 0x00) |
| 879 | printk(KERN_ERR | 860 | dev_err(&card->dev, "invalid checksum %#x\n", |
| 880 | "isapnp: checksum for device %i is not valid (0x%x)\n", | 861 | isapnp_checksum_value); |
| 881 | csn, isapnp_checksum_value); | ||
| 882 | card->checksum = isapnp_checksum_value; | 862 | card->checksum = isapnp_checksum_value; |
| 883 | card->protocol = &isapnp_protocol; | ||
| 884 | 863 | ||
| 885 | pnp_add_card(card); | 864 | pnp_add_card(card); |
| 886 | } | 865 | } |
| @@ -947,100 +926,117 @@ EXPORT_SYMBOL(isapnp_cfg_begin); | |||
| 947 | EXPORT_SYMBOL(isapnp_cfg_end); | 926 | EXPORT_SYMBOL(isapnp_cfg_end); |
| 948 | EXPORT_SYMBOL(isapnp_write_byte); | 927 | EXPORT_SYMBOL(isapnp_write_byte); |
| 949 | 928 | ||
| 950 | static int isapnp_read_resources(struct pnp_dev *dev, | 929 | static int isapnp_get_resources(struct pnp_dev *dev) |
| 951 | struct pnp_resource_table *res) | ||
| 952 | { | 930 | { |
| 953 | int tmp, ret; | 931 | struct pnp_resource *pnp_res; |
| 932 | int i, ret; | ||
| 954 | 933 | ||
| 934 | dev_dbg(&dev->dev, "get resources\n"); | ||
| 935 | pnp_init_resources(dev); | ||
| 936 | isapnp_cfg_begin(dev->card->number, dev->number); | ||
| 955 | dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE); | 937 | dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE); |
| 956 | if (dev->active) { | 938 | if (!dev->active) |
| 957 | for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { | 939 | goto __end; |
| 958 | ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1)); | 940 | |
| 959 | if (!ret) | 941 | for (i = 0; i < ISAPNP_MAX_PORT; i++) { |
| 960 | continue; | 942 | ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1)); |
| 961 | res->port_resource[tmp].start = ret; | 943 | if (ret) { |
| 962 | res->port_resource[tmp].flags = IORESOURCE_IO; | 944 | pnp_res = pnp_add_io_resource(dev, ret, ret, 0); |
| 945 | if (pnp_res) | ||
| 946 | pnp_res->index = i; | ||
| 963 | } | 947 | } |
| 964 | for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { | 948 | } |
| 965 | ret = | 949 | for (i = 0; i < ISAPNP_MAX_MEM; i++) { |
| 966 | isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8; | 950 | ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8; |
| 967 | if (!ret) | 951 | if (ret) { |
| 968 | continue; | 952 | pnp_res = pnp_add_mem_resource(dev, ret, ret, 0); |
| 969 | res->mem_resource[tmp].start = ret; | 953 | if (pnp_res) |
| 970 | res->mem_resource[tmp].flags = IORESOURCE_MEM; | 954 | pnp_res->index = i; |
| 971 | } | 955 | } |
| 972 | for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { | 956 | } |
| 973 | ret = | 957 | for (i = 0; i < ISAPNP_MAX_IRQ; i++) { |
| 974 | (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> | 958 | ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8; |
| 975 | 8); | 959 | if (ret) { |
| 976 | if (!ret) | 960 | pnp_res = pnp_add_irq_resource(dev, ret, 0); |
| 977 | continue; | 961 | if (pnp_res) |
| 978 | res->irq_resource[tmp].start = | 962 | pnp_res->index = i; |
| 979 | res->irq_resource[tmp].end = ret; | ||
| 980 | res->irq_resource[tmp].flags = IORESOURCE_IRQ; | ||
| 981 | } | 963 | } |
| 982 | for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { | 964 | } |
| 983 | ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); | 965 | for (i = 0; i < ISAPNP_MAX_DMA; i++) { |
| 984 | if (ret == 4) | 966 | ret = isapnp_read_byte(ISAPNP_CFG_DMA + i); |
| 985 | continue; | 967 | if (ret != 4) { |
| 986 | res->dma_resource[tmp].start = | 968 | pnp_res = pnp_add_dma_resource(dev, ret, 0); |
| 987 | res->dma_resource[tmp].end = ret; | 969 | if (pnp_res) |
| 988 | res->dma_resource[tmp].flags = IORESOURCE_DMA; | 970 | pnp_res->index = i; |
| 989 | } | 971 | } |
| 990 | } | 972 | } |
| 991 | return 0; | ||
| 992 | } | ||
| 993 | |||
| 994 | static int isapnp_get_resources(struct pnp_dev *dev, | ||
| 995 | struct pnp_resource_table *res) | ||
| 996 | { | ||
| 997 | int ret; | ||
| 998 | 973 | ||
| 999 | pnp_init_resource_table(res); | 974 | __end: |
| 1000 | isapnp_cfg_begin(dev->card->number, dev->number); | ||
| 1001 | ret = isapnp_read_resources(dev, res); | ||
| 1002 | isapnp_cfg_end(); | 975 | isapnp_cfg_end(); |
| 1003 | return ret; | 976 | return 0; |
| 1004 | } | 977 | } |
| 1005 | 978 | ||
| 1006 | static int isapnp_set_resources(struct pnp_dev *dev, | 979 | static int isapnp_set_resources(struct pnp_dev *dev) |
| 1007 | struct pnp_resource_table *res) | ||
| 1008 | { | 980 | { |
| 1009 | int tmp; | 981 | struct pnp_resource *pnp_res; |
| 982 | struct resource *res; | ||
| 983 | int tmp, index; | ||
| 1010 | 984 | ||
| 985 | dev_dbg(&dev->dev, "set resources\n"); | ||
| 1011 | isapnp_cfg_begin(dev->card->number, dev->number); | 986 | isapnp_cfg_begin(dev->card->number, dev->number); |
| 1012 | dev->active = 1; | 987 | dev->active = 1; |
| 1013 | for (tmp = 0; | 988 | for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { |
| 1014 | tmp < ISAPNP_MAX_PORT | 989 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp); |
| 1015 | && (res->port_resource[tmp]. | 990 | if (!pnp_res) |
| 1016 | flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO; | 991 | continue; |
| 1017 | tmp++) | 992 | res = &pnp_res->res; |
| 1018 | isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), | 993 | if (pnp_resource_valid(res)) { |
| 1019 | res->port_resource[tmp].start); | 994 | index = pnp_res->index; |
| 1020 | for (tmp = 0; | 995 | dev_dbg(&dev->dev, " set io %d to %#llx\n", |
| 1021 | tmp < ISAPNP_MAX_IRQ | 996 | index, (unsigned long long) res->start); |
| 1022 | && (res->irq_resource[tmp]. | 997 | isapnp_write_word(ISAPNP_CFG_PORT + (index << 1), |
| 1023 | flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ; | 998 | res->start); |
| 1024 | tmp++) { | 999 | } |
| 1025 | int irq = res->irq_resource[tmp].start; | 1000 | } |
| 1026 | if (irq == 2) | 1001 | for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { |
| 1027 | irq = 9; | 1002 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp); |
| 1028 | isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq); | 1003 | if (!pnp_res) |
| 1004 | continue; | ||
| 1005 | res = &pnp_res->res; | ||
| 1006 | if (pnp_resource_valid(res)) { | ||
| 1007 | int irq = res->start; | ||
| 1008 | if (irq == 2) | ||
| 1009 | irq = 9; | ||
| 1010 | index = pnp_res->index; | ||
| 1011 | dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq); | ||
| 1012 | isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq); | ||
| 1013 | } | ||
| 1014 | } | ||
| 1015 | for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { | ||
| 1016 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp); | ||
| 1017 | if (!pnp_res) | ||
| 1018 | continue; | ||
| 1019 | res = &pnp_res->res; | ||
| 1020 | if (pnp_resource_valid(res)) { | ||
| 1021 | index = pnp_res->index; | ||
| 1022 | dev_dbg(&dev->dev, " set dma %d to %lld\n", | ||
| 1023 | index, (unsigned long long) res->start); | ||
| 1024 | isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start); | ||
| 1025 | } | ||
| 1026 | } | ||
| 1027 | for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { | ||
| 1028 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp); | ||
| 1029 | if (!pnp_res) | ||
| 1030 | continue; | ||
| 1031 | res = &pnp_res->res; | ||
| 1032 | if (pnp_resource_valid(res)) { | ||
| 1033 | index = pnp_res->index; | ||
| 1034 | dev_dbg(&dev->dev, " set mem %d to %#llx\n", | ||
| 1035 | index, (unsigned long long) res->start); | ||
| 1036 | isapnp_write_word(ISAPNP_CFG_MEM + (index << 3), | ||
| 1037 | (res->start >> 8) & 0xffff); | ||
| 1038 | } | ||
| 1029 | } | 1039 | } |
| 1030 | for (tmp = 0; | ||
| 1031 | tmp < ISAPNP_MAX_DMA | ||
| 1032 | && (res->dma_resource[tmp]. | ||
| 1033 | flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA; | ||
| 1034 | tmp++) | ||
| 1035 | isapnp_write_byte(ISAPNP_CFG_DMA + tmp, | ||
| 1036 | res->dma_resource[tmp].start); | ||
| 1037 | for (tmp = 0; | ||
| 1038 | tmp < ISAPNP_MAX_MEM | ||
| 1039 | && (res->mem_resource[tmp]. | ||
| 1040 | flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM; | ||
| 1041 | tmp++) | ||
| 1042 | isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3), | ||
| 1043 | (res->mem_resource[tmp].start >> 8) & 0xffff); | ||
| 1044 | /* FIXME: We aren't handling 32bit mems properly here */ | 1040 | /* FIXME: We aren't handling 32bit mems properly here */ |
| 1045 | isapnp_activate(dev->number); | 1041 | isapnp_activate(dev->number); |
| 1046 | isapnp_cfg_end(); | 1042 | isapnp_cfg_end(); |
| @@ -1138,13 +1134,13 @@ static int __init isapnp_init(void) | |||
| 1138 | protocol_for_each_card(&isapnp_protocol, card) { | 1134 | protocol_for_each_card(&isapnp_protocol, card) { |
| 1139 | cards++; | 1135 | cards++; |
| 1140 | if (isapnp_verbose) { | 1136 | if (isapnp_verbose) { |
| 1141 | printk(KERN_INFO "isapnp: Card '%s'\n", | 1137 | dev_info(&card->dev, "card '%s'\n", |
| 1142 | card->name[0] ? card->name : "Unknown"); | 1138 | card->name[0] ? card->name : "unknown"); |
| 1143 | if (isapnp_verbose < 2) | 1139 | if (isapnp_verbose < 2) |
| 1144 | continue; | 1140 | continue; |
| 1145 | card_for_each_dev(card, dev) { | 1141 | card_for_each_dev(card, dev) { |
| 1146 | printk(KERN_INFO "isapnp: Device '%s'\n", | 1142 | dev_info(&card->dev, "device '%s'\n", |
| 1147 | dev->name[0] ? dev->name : "Unknown"); | 1143 | dev->name[0] ? dev->name : "unknown"); |
| 1148 | } | 1144 | } |
| 1149 | } | 1145 | } |
| 1150 | } | 1146 | } |
