aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/pci
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2016-01-29 09:13:30 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-02-23 02:56:16 -0500
commit9a99649f2a89fdfc9dde5d5401675561567bf99a (patch)
treeb15f95ac2c6a81c3dd85b4ab815406c164979d5f /arch/s390/pci
parent1b17cb796f5d40ffa239c6926385abd83a77a49b (diff)
s390/pci: remove pdev pointer from arch data
For each PCI function we need to maintain arch specific data in struct zpci_dev which also contains a pointer to struct pci_dev. When a function is registered or deregistered (which is triggered by PCI common code) we need to adjust that pointer which could interfere with the machine check handler (triggered by FW) using zpci_dev->pdev. Since multiple instances of the same pdev could exist at a time this can't be solved with locking. Fix that by ditching the pdev pointer and use a bus walk to reach struct pci_dev (only one instance of a pdev can be registered at the bus at a time). Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/pci')
-rw-r--r--arch/s390/pci/pci.c6
-rw-r--r--arch/s390/pci/pci_debug.c5
-rw-r--r--arch/s390/pci/pci_dma.c21
-rw-r--r--arch/s390/pci/pci_event.c13
4 files changed, 26 insertions, 19 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 8f19c8f9d660..f76d01e69fb8 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -637,11 +637,9 @@ static void zpci_cleanup_bus_resources(struct zpci_dev *zdev)
637 637
638int pcibios_add_device(struct pci_dev *pdev) 638int pcibios_add_device(struct pci_dev *pdev)
639{ 639{
640 struct zpci_dev *zdev = to_zpci(pdev);
641 struct resource *res; 640 struct resource *res;
642 int i; 641 int i;
643 642
644 zdev->pdev = pdev;
645 pdev->dev.groups = zpci_attr_groups; 643 pdev->dev.groups = zpci_attr_groups;
646 zpci_map_resources(pdev); 644 zpci_map_resources(pdev);
647 645
@@ -664,8 +662,7 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask)
664{ 662{
665 struct zpci_dev *zdev = to_zpci(pdev); 663 struct zpci_dev *zdev = to_zpci(pdev);
666 664
667 zdev->pdev = pdev; 665 zpci_debug_init_device(zdev, dev_name(&pdev->dev));
668 zpci_debug_init_device(zdev);
669 zpci_fmb_enable_device(zdev); 666 zpci_fmb_enable_device(zdev);
670 667
671 return pci_enable_resources(pdev, mask); 668 return pci_enable_resources(pdev, mask);
@@ -677,7 +674,6 @@ void pcibios_disable_device(struct pci_dev *pdev)
677 674
678 zpci_fmb_disable_device(zdev); 675 zpci_fmb_disable_device(zdev);
679 zpci_debug_exit_device(zdev); 676 zpci_debug_exit_device(zdev);
680 zdev->pdev = NULL;
681} 677}
682 678
683#ifdef CONFIG_HIBERNATE_CALLBACKS 679#ifdef CONFIG_HIBERNATE_CALLBACKS
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c
index 4129b0a5fd78..c555de3d12d6 100644
--- a/arch/s390/pci/pci_debug.c
+++ b/arch/s390/pci/pci_debug.c
@@ -128,10 +128,9 @@ static const struct file_operations debugfs_pci_perf_fops = {
128 .release = single_release, 128 .release = single_release,
129}; 129};
130 130
131void zpci_debug_init_device(struct zpci_dev *zdev) 131void zpci_debug_init_device(struct zpci_dev *zdev, const char *name)
132{ 132{
133 zdev->debugfs_dev = debugfs_create_dir(dev_name(&zdev->pdev->dev), 133 zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root);
134 debugfs_root);
135 if (IS_ERR(zdev->debugfs_dev)) 134 if (IS_ERR(zdev->debugfs_dev))
136 zdev->debugfs_dev = NULL; 135 zdev->debugfs_dev = NULL;
137 136
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 4638b93c7632..a06ce8037cec 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -217,27 +217,29 @@ void dma_cleanup_tables(unsigned long *table)
217 dma_free_cpu_table(table); 217 dma_free_cpu_table(table);
218} 218}
219 219
220static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev, 220static unsigned long __dma_alloc_iommu(struct device *dev,
221 unsigned long start, int size) 221 unsigned long start, int size)
222{ 222{
223 struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
223 unsigned long boundary_size; 224 unsigned long boundary_size;
224 225
225 boundary_size = ALIGN(dma_get_seg_boundary(&zdev->pdev->dev) + 1, 226 boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
226 PAGE_SIZE) >> PAGE_SHIFT; 227 PAGE_SIZE) >> PAGE_SHIFT;
227 return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages, 228 return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages,
228 start, size, 0, boundary_size, 0); 229 start, size, 0, boundary_size, 0);
229} 230}
230 231
231static unsigned long dma_alloc_iommu(struct zpci_dev *zdev, int size) 232static unsigned long dma_alloc_iommu(struct device *dev, int size)
232{ 233{
234 struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
233 unsigned long offset, flags; 235 unsigned long offset, flags;
234 int wrap = 0; 236 int wrap = 0;
235 237
236 spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags); 238 spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags);
237 offset = __dma_alloc_iommu(zdev, zdev->next_bit, size); 239 offset = __dma_alloc_iommu(dev, zdev->next_bit, size);
238 if (offset == -1) { 240 if (offset == -1) {
239 /* wrap-around */ 241 /* wrap-around */
240 offset = __dma_alloc_iommu(zdev, 0, size); 242 offset = __dma_alloc_iommu(dev, 0, size);
241 wrap = 1; 243 wrap = 1;
242 } 244 }
243 245
@@ -251,8 +253,9 @@ static unsigned long dma_alloc_iommu(struct zpci_dev *zdev, int size)
251 return offset; 253 return offset;
252} 254}
253 255
254static void dma_free_iommu(struct zpci_dev *zdev, unsigned long offset, int size) 256static void dma_free_iommu(struct device *dev, unsigned long offset, int size)
255{ 257{
258 struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
256 unsigned long flags; 259 unsigned long flags;
257 260
258 spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags); 261 spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags);
@@ -293,7 +296,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
293 296
294 /* This rounds up number of pages based on size and offset */ 297 /* This rounds up number of pages based on size and offset */
295 nr_pages = iommu_num_pages(pa, size, PAGE_SIZE); 298 nr_pages = iommu_num_pages(pa, size, PAGE_SIZE);
296 iommu_page_index = dma_alloc_iommu(zdev, nr_pages); 299 iommu_page_index = dma_alloc_iommu(dev, nr_pages);
297 if (iommu_page_index == -1) { 300 if (iommu_page_index == -1) {
298 ret = -ENOSPC; 301 ret = -ENOSPC;
299 goto out_err; 302 goto out_err;
@@ -319,7 +322,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
319 return dma_addr + (offset & ~PAGE_MASK); 322 return dma_addr + (offset & ~PAGE_MASK);
320 323
321out_free: 324out_free:
322 dma_free_iommu(zdev, iommu_page_index, nr_pages); 325 dma_free_iommu(dev, iommu_page_index, nr_pages);
323out_err: 326out_err:
324 zpci_err("map error:\n"); 327 zpci_err("map error:\n");
325 zpci_err_dma(ret, pa); 328 zpci_err_dma(ret, pa);
@@ -346,7 +349,7 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
346 349
347 atomic64_add(npages, &zdev->unmapped_pages); 350 atomic64_add(npages, &zdev->unmapped_pages);
348 iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT; 351 iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT;
349 dma_free_iommu(zdev, iommu_page_index, npages); 352 dma_free_iommu(dev, iommu_page_index, npages);
350} 353}
351 354
352static void *s390_dma_alloc(struct device *dev, size_t size, 355static void *s390_dma_alloc(struct device *dev, size_t size,
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
index b0e04751c5d5..fb2a9a560fdc 100644
--- a/arch/s390/pci/pci_event.c
+++ b/arch/s390/pci/pci_event.c
@@ -46,11 +46,14 @@ struct zpci_ccdf_avail {
46static void __zpci_event_error(struct zpci_ccdf_err *ccdf) 46static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
47{ 47{
48 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 48 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
49 struct pci_dev *pdev = zdev ? zdev->pdev : NULL; 49 struct pci_dev *pdev = NULL;
50 50
51 zpci_err("error CCDF:\n"); 51 zpci_err("error CCDF:\n");
52 zpci_err_hex(ccdf, sizeof(*ccdf)); 52 zpci_err_hex(ccdf, sizeof(*ccdf));
53 53
54 if (zdev)
55 pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
56
54 pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n", 57 pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n",
55 pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); 58 pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
56 59
@@ -58,6 +61,7 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
58 return; 61 return;
59 62
60 pdev->error_state = pci_channel_io_perm_failure; 63 pdev->error_state = pci_channel_io_perm_failure;
64 pci_dev_put(pdev);
61} 65}
62 66
63void zpci_event_error(void *data) 67void zpci_event_error(void *data)
@@ -69,9 +73,12 @@ void zpci_event_error(void *data)
69static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) 73static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
70{ 74{
71 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 75 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
72 struct pci_dev *pdev = zdev ? zdev->pdev : NULL; 76 struct pci_dev *pdev = NULL;
73 int ret; 77 int ret;
74 78
79 if (zdev)
80 pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
81
75 pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n", 82 pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n",
76 pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); 83 pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
77 zpci_err("avail CCDF:\n"); 84 zpci_err("avail CCDF:\n");
@@ -138,6 +145,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
138 default: 145 default:
139 break; 146 break;
140 } 147 }
148 if (pdev)
149 pci_dev_put(pdev);
141} 150}
142 151
143void zpci_event_availability(void *data) 152void zpci_event_availability(void *data)