|
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