aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2015-02-27 10:43:21 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-02-27 11:50:04 -0500
commit1803ba2d7a55af525c46d8ce9161521dd2ae4400 (patch)
tree8b74f5cfd3ad8941a4282c48d065023f38229f34 /arch/s390
parentfb3d1c085c05e0e4b112d915dbd06b20b259e6c5 (diff)
s390/pci: fix [un]map_resources sequence
Commit 8cfc99b58366 ("s390: add pci_iomap_range") introduced counters to keep track of the number of mappings created. This revealed that we don't have our internal mappings in order when using hotunplug or resume from hibernate. This patch addresses both issues. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/pci/pci.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 753a56731951..6500d26d465f 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -483,9 +483,8 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
483 airq_iv_free_bit(zpci_aisb_iv, zdev->aisb); 483 airq_iv_free_bit(zpci_aisb_iv, zdev->aisb);
484} 484}
485 485
486static void zpci_map_resources(struct zpci_dev *zdev) 486static void zpci_map_resources(struct pci_dev *pdev)
487{ 487{
488 struct pci_dev *pdev = zdev->pdev;
489 resource_size_t len; 488 resource_size_t len;
490 int i; 489 int i;
491 490
@@ -499,9 +498,8 @@ static void zpci_map_resources(struct zpci_dev *zdev)
499 } 498 }
500} 499}
501 500
502static void zpci_unmap_resources(struct zpci_dev *zdev) 501static void zpci_unmap_resources(struct pci_dev *pdev)
503{ 502{
504 struct pci_dev *pdev = zdev->pdev;
505 resource_size_t len; 503 resource_size_t len;
506 int i; 504 int i;
507 505
@@ -651,7 +649,7 @@ int pcibios_add_device(struct pci_dev *pdev)
651 649
652 zdev->pdev = pdev; 650 zdev->pdev = pdev;
653 pdev->dev.groups = zpci_attr_groups; 651 pdev->dev.groups = zpci_attr_groups;
654 zpci_map_resources(zdev); 652 zpci_map_resources(pdev);
655 653
656 for (i = 0; i < PCI_BAR_COUNT; i++) { 654 for (i = 0; i < PCI_BAR_COUNT; i++) {
657 res = &pdev->resource[i]; 655 res = &pdev->resource[i];
@@ -663,6 +661,11 @@ int pcibios_add_device(struct pci_dev *pdev)
663 return 0; 661 return 0;
664} 662}
665 663
664void pcibios_release_device(struct pci_dev *pdev)
665{
666 zpci_unmap_resources(pdev);
667}
668
666int pcibios_enable_device(struct pci_dev *pdev, int mask) 669int pcibios_enable_device(struct pci_dev *pdev, int mask)
667{ 670{
668 struct zpci_dev *zdev = get_zdev(pdev); 671 struct zpci_dev *zdev = get_zdev(pdev);
@@ -670,7 +673,6 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask)
670 zdev->pdev = pdev; 673 zdev->pdev = pdev;
671 zpci_debug_init_device(zdev); 674 zpci_debug_init_device(zdev);
672 zpci_fmb_enable_device(zdev); 675 zpci_fmb_enable_device(zdev);
673 zpci_map_resources(zdev);
674 676
675 return pci_enable_resources(pdev, mask); 677 return pci_enable_resources(pdev, mask);
676} 678}
@@ -679,7 +681,6 @@ void pcibios_disable_device(struct pci_dev *pdev)
679{ 681{
680 struct zpci_dev *zdev = get_zdev(pdev); 682 struct zpci_dev *zdev = get_zdev(pdev);
681 683
682 zpci_unmap_resources(zdev);
683 zpci_fmb_disable_device(zdev); 684 zpci_fmb_disable_device(zdev);
684 zpci_debug_exit_device(zdev); 685 zpci_debug_exit_device(zdev);
685 zdev->pdev = NULL; 686 zdev->pdev = NULL;
@@ -688,7 +689,8 @@ void pcibios_disable_device(struct pci_dev *pdev)
688#ifdef CONFIG_HIBERNATE_CALLBACKS 689#ifdef CONFIG_HIBERNATE_CALLBACKS
689static int zpci_restore(struct device *dev) 690static int zpci_restore(struct device *dev)
690{ 691{
691 struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); 692 struct pci_dev *pdev = to_pci_dev(dev);
693 struct zpci_dev *zdev = get_zdev(pdev);
692 int ret = 0; 694 int ret = 0;
693 695
694 if (zdev->state != ZPCI_FN_STATE_ONLINE) 696 if (zdev->state != ZPCI_FN_STATE_ONLINE)
@@ -698,7 +700,7 @@ static int zpci_restore(struct device *dev)
698 if (ret) 700 if (ret)
699 goto out; 701 goto out;
700 702
701 zpci_map_resources(zdev); 703 zpci_map_resources(pdev);
702 zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, 704 zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET,
703 zdev->start_dma + zdev->iommu_size - 1, 705 zdev->start_dma + zdev->iommu_size - 1,
704 (u64) zdev->dma_table); 706 (u64) zdev->dma_table);
@@ -709,12 +711,14 @@ out:
709 711
710static int zpci_freeze(struct device *dev) 712static int zpci_freeze(struct device *dev)
711{ 713{
712 struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); 714 struct pci_dev *pdev = to_pci_dev(dev);
715 struct zpci_dev *zdev = get_zdev(pdev);
713 716
714 if (zdev->state != ZPCI_FN_STATE_ONLINE) 717 if (zdev->state != ZPCI_FN_STATE_ONLINE)
715 return 0; 718 return 0;
716 719
717 zpci_unregister_ioat(zdev, 0); 720 zpci_unregister_ioat(zdev, 0);
721 zpci_unmap_resources(pdev);
718 return clp_disable_fh(zdev); 722 return clp_disable_fh(zdev);
719} 723}
720 724