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 | } |