aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/pci/pci.c')
-rw-r--r--arch/s390/pci/pci.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 3290f11ae1d9..753a56731951 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -259,7 +259,10 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
259} 259}
260 260
261/* Create a virtual mapping cookie for a PCI BAR */ 261/* Create a virtual mapping cookie for a PCI BAR */
262void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max) 262void __iomem *pci_iomap_range(struct pci_dev *pdev,
263 int bar,
264 unsigned long offset,
265 unsigned long max)
263{ 266{
264 struct zpci_dev *zdev = get_zdev(pdev); 267 struct zpci_dev *zdev = get_zdev(pdev);
265 u64 addr; 268 u64 addr;
@@ -270,14 +273,27 @@ void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max)
270 273
271 idx = zdev->bars[bar].map_idx; 274 idx = zdev->bars[bar].map_idx;
272 spin_lock(&zpci_iomap_lock); 275 spin_lock(&zpci_iomap_lock);
273 zpci_iomap_start[idx].fh = zdev->fh; 276 if (zpci_iomap_start[idx].count++) {
274 zpci_iomap_start[idx].bar = bar; 277 BUG_ON(zpci_iomap_start[idx].fh != zdev->fh ||
278 zpci_iomap_start[idx].bar != bar);
279 } else {
280 zpci_iomap_start[idx].fh = zdev->fh;
281 zpci_iomap_start[idx].bar = bar;
282 }
283 /* Detect overrun */
284 BUG_ON(!zpci_iomap_start[idx].count);
275 spin_unlock(&zpci_iomap_lock); 285 spin_unlock(&zpci_iomap_lock);
276 286
277 addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); 287 addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
278 return (void __iomem *) addr; 288 return (void __iomem *) addr + offset;
279} 289}
280EXPORT_SYMBOL_GPL(pci_iomap); 290EXPORT_SYMBOL_GPL(pci_iomap_range);
291
292void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
293{
294 return pci_iomap_range(dev, bar, 0, maxlen);
295}
296EXPORT_SYMBOL(pci_iomap);
281 297
282void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) 298void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
283{ 299{
@@ -285,8 +301,12 @@ void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
285 301
286 idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48; 302 idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
287 spin_lock(&zpci_iomap_lock); 303 spin_lock(&zpci_iomap_lock);
288 zpci_iomap_start[idx].fh = 0; 304 /* Detect underrun */
289 zpci_iomap_start[idx].bar = 0; 305 BUG_ON(!zpci_iomap_start[idx].count);
306 if (!--zpci_iomap_start[idx].count) {
307 zpci_iomap_start[idx].fh = 0;
308 zpci_iomap_start[idx].bar = 0;
309 }
290 spin_unlock(&zpci_iomap_lock); 310 spin_unlock(&zpci_iomap_lock);
291} 311}
292EXPORT_SYMBOL_GPL(pci_iounmap); 312EXPORT_SYMBOL_GPL(pci_iounmap);