|
36 | 36 | #include <asm/pci_clp.h> |
37 | 37 | #include <asm/pci_dma.h> |
38 | 38 |
|
| 39 | +#include "pci_bus.h" |
| 40 | + |
39 | 41 | /* list of all detected zpci devices */ |
40 | 42 | static LIST_HEAD(zpci_list); |
41 | 43 | static DEFINE_SPINLOCK(zpci_list_lock); |
42 | 44 |
|
43 | 45 | static DECLARE_BITMAP(zpci_domain, ZPCI_DOMAIN_BITMAP_SIZE); |
44 | 46 | static DEFINE_SPINLOCK(zpci_domain_lock); |
45 | | -static unsigned int zpci_num_domains_allocated; |
46 | 47 |
|
47 | 48 | #define ZPCI_IOMAP_ENTRIES \ |
48 | 49 | min(((unsigned long) ZPCI_NR_DEVICES * PCI_STD_NUM_BARS / 2), \ |
@@ -90,17 +91,12 @@ void zpci_remove_reserved_devices(void) |
90 | 91 | spin_unlock(&zpci_list_lock); |
91 | 92 |
|
92 | 93 | list_for_each_entry_safe(zdev, tmp, &remove, entry) |
93 | | - zpci_remove_device(zdev); |
94 | | -} |
95 | | - |
96 | | -static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) |
97 | | -{ |
98 | | - return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; |
| 94 | + zpci_zdev_put(zdev); |
99 | 95 | } |
100 | 96 |
|
101 | 97 | int pci_domain_nr(struct pci_bus *bus) |
102 | 98 | { |
103 | | - return ((struct zpci_dev *) bus->sysdata)->domain; |
| 99 | + return ((struct zpci_bus *) bus->sysdata)->domain_nr; |
104 | 100 | } |
105 | 101 | EXPORT_SYMBOL_GPL(pci_domain_nr); |
106 | 102 |
|
@@ -508,15 +504,15 @@ static struct resource *__alloc_res(struct zpci_dev *zdev, unsigned long start, |
508 | 504 | return r; |
509 | 505 | } |
510 | 506 |
|
511 | | -static int zpci_setup_bus_resources(struct zpci_dev *zdev, |
512 | | - struct list_head *resources) |
| 507 | +int zpci_setup_bus_resources(struct zpci_dev *zdev, |
| 508 | + struct list_head *resources) |
513 | 509 | { |
514 | 510 | unsigned long addr, size, flags; |
515 | 511 | struct resource *res; |
516 | 512 | int i, entry; |
517 | 513 |
|
518 | 514 | snprintf(zdev->res_name, sizeof(zdev->res_name), |
519 | | - "PCI Bus %04x:%02x", zdev->domain, ZPCI_BUS_NR); |
| 515 | + "PCI Bus %04x:%02x", zdev->uid, ZPCI_BUS_NR); |
520 | 516 |
|
521 | 517 | for (i = 0; i < PCI_STD_NUM_BARS; i++) { |
522 | 518 | if (!zdev->bars[i].size) |
@@ -610,98 +606,53 @@ void pcibios_disable_device(struct pci_dev *pdev) |
610 | 606 | zpci_debug_exit_device(zdev); |
611 | 607 | } |
612 | 608 |
|
613 | | -static int zpci_alloc_domain(struct zpci_dev *zdev) |
| 609 | +static int __zpci_register_domain(int domain) |
614 | 610 | { |
615 | 611 | spin_lock(&zpci_domain_lock); |
616 | | - if (zpci_num_domains_allocated > (ZPCI_NR_DEVICES - 1)) { |
| 612 | + if (test_bit(domain, zpci_domain)) { |
617 | 613 | spin_unlock(&zpci_domain_lock); |
618 | | - pr_err("Adding PCI function %08x failed because the configured limit of %d is reached\n", |
619 | | - zdev->fid, ZPCI_NR_DEVICES); |
620 | | - return -ENOSPC; |
| 614 | + pr_err("Domain %04x is already assigned\n", domain); |
| 615 | + return -EEXIST; |
621 | 616 | } |
| 617 | + set_bit(domain, zpci_domain); |
| 618 | + spin_unlock(&zpci_domain_lock); |
| 619 | + return domain; |
| 620 | +} |
622 | 621 |
|
623 | | - if (zpci_unique_uid) { |
624 | | - zdev->domain = (u16) zdev->uid; |
625 | | - if (zdev->domain == 0) { |
626 | | - pr_warn("UID checking is active but no UID is set for PCI function %08x, so automatic domain allocation is used instead\n", |
627 | | - zdev->fid); |
628 | | - update_uid_checking(false); |
629 | | - goto auto_allocate; |
630 | | - } |
| 622 | +static int __zpci_alloc_domain(void) |
| 623 | +{ |
| 624 | + int domain; |
631 | 625 |
|
632 | | - if (test_bit(zdev->domain, zpci_domain)) { |
633 | | - spin_unlock(&zpci_domain_lock); |
634 | | - pr_err("Adding PCI function %08x failed because domain %04x is already assigned\n", |
635 | | - zdev->fid, zdev->domain); |
636 | | - return -EEXIST; |
637 | | - } |
638 | | - set_bit(zdev->domain, zpci_domain); |
639 | | - zpci_num_domains_allocated++; |
640 | | - spin_unlock(&zpci_domain_lock); |
641 | | - return 0; |
642 | | - } |
643 | | -auto_allocate: |
| 626 | + spin_lock(&zpci_domain_lock); |
644 | 627 | /* |
645 | 628 | * We can always auto allocate domains below ZPCI_NR_DEVICES. |
646 | 629 | * There is either a free domain or we have reached the maximum in |
647 | 630 | * which case we would have bailed earlier. |
648 | 631 | */ |
649 | | - zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); |
650 | | - set_bit(zdev->domain, zpci_domain); |
651 | | - zpci_num_domains_allocated++; |
| 632 | + domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); |
| 633 | + set_bit(domain, zpci_domain); |
652 | 634 | spin_unlock(&zpci_domain_lock); |
653 | | - return 0; |
| 635 | + return domain; |
654 | 636 | } |
655 | 637 |
|
656 | | -static void zpci_free_domain(struct zpci_dev *zdev) |
| 638 | +int zpci_alloc_domain(int domain) |
657 | 639 | { |
658 | | - spin_lock(&zpci_domain_lock); |
659 | | - clear_bit(zdev->domain, zpci_domain); |
660 | | - zpci_num_domains_allocated--; |
661 | | - spin_unlock(&zpci_domain_lock); |
| 640 | + if (zpci_unique_uid) { |
| 641 | + if (domain) |
| 642 | + return __zpci_register_domain(domain); |
| 643 | + pr_warn("UID checking was active but no UID is provided: switching to automatic domain allocation\n"); |
| 644 | + update_uid_checking(false); |
| 645 | + } |
| 646 | + return __zpci_alloc_domain(); |
662 | 647 | } |
663 | 648 |
|
664 | | -void pcibios_remove_bus(struct pci_bus *bus) |
| 649 | +void zpci_free_domain(int domain) |
665 | 650 | { |
666 | | - struct zpci_dev *zdev = get_zdev_by_bus(bus); |
667 | | - |
668 | | - zpci_exit_slot(zdev); |
669 | | - zpci_cleanup_bus_resources(zdev); |
670 | | - zpci_destroy_iommu(zdev); |
671 | | - zpci_free_domain(zdev); |
672 | | - |
673 | | - spin_lock(&zpci_list_lock); |
674 | | - list_del(&zdev->entry); |
675 | | - spin_unlock(&zpci_list_lock); |
676 | | - |
677 | | - zpci_dbg(3, "rem fid:%x\n", zdev->fid); |
678 | | - kfree(zdev); |
| 651 | + spin_lock(&zpci_domain_lock); |
| 652 | + clear_bit(domain, zpci_domain); |
| 653 | + spin_unlock(&zpci_domain_lock); |
679 | 654 | } |
680 | 655 |
|
681 | | -static int zpci_scan_bus(struct zpci_dev *zdev) |
682 | | -{ |
683 | | - LIST_HEAD(resources); |
684 | | - int ret; |
685 | | - |
686 | | - ret = zpci_setup_bus_resources(zdev, &resources); |
687 | | - if (ret) |
688 | | - goto error; |
689 | | - |
690 | | - zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, |
691 | | - zdev, &resources); |
692 | | - if (!zdev->bus) { |
693 | | - ret = -EIO; |
694 | | - goto error; |
695 | | - } |
696 | | - zdev->bus->max_bus_speed = zdev->max_bus_speed; |
697 | | - pci_bus_add_devices(zdev->bus); |
698 | | - return 0; |
699 | | - |
700 | | -error: |
701 | | - zpci_cleanup_bus_resources(zdev); |
702 | | - pci_free_resource_list(&resources); |
703 | | - return ret; |
704 | | -} |
705 | 656 |
|
706 | 657 | int zpci_enable_device(struct zpci_dev *zdev) |
707 | 658 | { |
@@ -736,50 +687,68 @@ int zpci_create_device(struct zpci_dev *zdev) |
736 | 687 | { |
737 | 688 | int rc; |
738 | 689 |
|
739 | | - rc = zpci_alloc_domain(zdev); |
740 | | - if (rc) |
741 | | - goto out; |
| 690 | + kref_init(&zdev->kref); |
| 691 | + |
| 692 | + spin_lock(&zpci_list_lock); |
| 693 | + list_add_tail(&zdev->entry, &zpci_list); |
| 694 | + spin_unlock(&zpci_list_lock); |
742 | 695 |
|
743 | 696 | rc = zpci_init_iommu(zdev); |
744 | 697 | if (rc) |
745 | | - goto out_free; |
| 698 | + goto out; |
746 | 699 |
|
747 | 700 | mutex_init(&zdev->lock); |
748 | 701 | if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { |
749 | 702 | rc = zpci_enable_device(zdev); |
750 | 703 | if (rc) |
751 | 704 | goto out_destroy_iommu; |
752 | 705 | } |
753 | | - rc = zpci_scan_bus(zdev); |
| 706 | + |
| 707 | + rc = zpci_bus_device_register(zdev, &pci_root_ops); |
754 | 708 | if (rc) |
755 | 709 | goto out_disable; |
756 | 710 |
|
757 | | - spin_lock(&zpci_list_lock); |
758 | | - list_add_tail(&zdev->entry, &zpci_list); |
759 | | - spin_unlock(&zpci_list_lock); |
760 | | - |
761 | 711 | zpci_init_slot(zdev); |
762 | | - |
763 | 712 | return 0; |
764 | 713 |
|
765 | 714 | out_disable: |
766 | 715 | if (zdev->state == ZPCI_FN_STATE_ONLINE) |
767 | 716 | zpci_disable_device(zdev); |
768 | 717 | out_destroy_iommu: |
769 | 718 | zpci_destroy_iommu(zdev); |
770 | | -out_free: |
771 | | - zpci_free_domain(zdev); |
772 | 719 | out: |
| 720 | + spin_lock(&zpci_list_lock); |
| 721 | + list_del(&zdev->entry); |
| 722 | + spin_unlock(&zpci_list_lock); |
773 | 723 | return rc; |
774 | 724 | } |
775 | 725 |
|
776 | | -void zpci_remove_device(struct zpci_dev *zdev) |
| 726 | +void zpci_release_device(struct kref *kref) |
777 | 727 | { |
778 | | - if (!zdev->bus) |
779 | | - return; |
| 728 | + struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref); |
| 729 | + |
| 730 | + switch (zdev->state) { |
| 731 | + case ZPCI_FN_STATE_ONLINE: |
| 732 | + case ZPCI_FN_STATE_CONFIGURED: |
| 733 | + zpci_disable_device(zdev); |
| 734 | + fallthrough; |
| 735 | + case ZPCI_FN_STATE_STANDBY: |
| 736 | + if (zdev->zbus) { |
| 737 | + zpci_exit_slot(zdev); |
| 738 | + zpci_cleanup_bus_resources(zdev); |
| 739 | + zpci_bus_device_unregister(zdev); |
| 740 | + zpci_destroy_iommu(zdev); |
| 741 | + } |
| 742 | + fallthrough; |
| 743 | + default: |
| 744 | + break; |
| 745 | + } |
780 | 746 |
|
781 | | - pci_stop_root_bus(zdev->bus); |
782 | | - pci_remove_root_bus(zdev->bus); |
| 747 | + spin_lock(&zpci_list_lock); |
| 748 | + list_del(&zdev->entry); |
| 749 | + spin_unlock(&zpci_list_lock); |
| 750 | + zpci_dbg(3, "rem fid:%x\n", zdev->fid); |
| 751 | + kfree(zdev); |
783 | 752 | } |
784 | 753 |
|
785 | 754 | int zpci_report_error(struct pci_dev *pdev, |
|
0 commit comments