aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tsbogend@alpha.franken.de>2017-07-03 04:38:05 -0400
committerHelge Deller <deller@gmx.de>2017-07-03 11:00:46 -0400
commit33f9e02495d15a061f0c94ef46f5103a2d0c20f3 (patch)
tree3fcc0f6afa5e86730eec9755c2d28103cad67298
parent247462316f85a9e0479445c1a4223950b68ffac1 (diff)
parisc: DMA API: return error instead of BUG_ON for dma ops on non dma devs
Enabling parport pc driver on a B2600 (and probably other 64bit PARISC systems) produced following BUG: CPU: 0 PID: 1 Comm: swapper Not tainted 4.12.0-rc5-30198-g1132d5e #156 task: 000000009e050000 task.stack: 000000009e04c000 YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI PSW: 00001000000001101111111100001111 Not tainted r00-03 000000ff0806ff0f 000000009e04c990 0000000040871b78 000000009e04cac0 r04-07 0000000040c14de0 ffffffffffffffff 000000009e07f098 000000009d82d200 r08-11 000000009d82d210 0000000000000378 0000000000000000 0000000040c345e0 r12-15 0000000000000005 0000000040c345e0 0000000000000000 0000000040c9d5e0 r16-19 0000000040c345e0 00000000f00001c4 00000000f00001bc 0000000000000061 r20-23 000000009e04ce28 0000000000000010 0000000000000010 0000000040b89e40 r24-27 0000000000000003 0000000000ffffff 000000009d82d210 0000000040c14de0 r28-31 0000000000000000 000000009e04ca90 000000009e04cb40 0000000000000000 sr00-03 0000000000000000 0000000000000000 0000000000000000 0000000000000000 sr04-07 0000000000000000 0000000000000000 0000000000000000 0000000000000000 IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000404aece0 00000000404aece4 IIR: 03ffe01f ISR: 0000000010340000 IOR: 000001781304cac8 CPU: 0 CR30: 000000009e04c000 CR31: 00000000e2976de2 ORIG_R28: 0000000000000200 IAOQ[0]: sba_dma_supported+0x80/0xd0 IAOQ[1]: sba_dma_supported+0x84/0xd0 RP(r2): parport_pc_probe_port+0x178/0x1200 Cause is a call to dma_coerce_mask_and_coherenet in parport_pc_probe_port, which PARISC DMA API doesn't handle very nicely. This commit gives back DMA_ERROR_CODE for DMA API calls, if device isn't capable of DMA transaction. Cc: <stable@vger.kernel.org> # v3.13+ Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--arch/parisc/include/asm/dma-mapping.h11
-rw-r--r--drivers/parisc/ccio-dma.c12
-rw-r--r--drivers/parisc/dino.c5
-rw-r--r--drivers/parisc/lba_pci.c6
-rw-r--r--drivers/parisc/sba_iommu.c14
5 files changed, 41 insertions, 7 deletions
diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h
index 5404c6a726b2..9a2a8956a695 100644
--- a/arch/parisc/include/asm/dma-mapping.h
+++ b/arch/parisc/include/asm/dma-mapping.h
@@ -20,6 +20,8 @@
20** flush/purge and allocate "regular" cacheable pages for everything. 20** flush/purge and allocate "regular" cacheable pages for everything.
21*/ 21*/
22 22
23#define DMA_ERROR_CODE (~(dma_addr_t)0)
24
23#ifdef CONFIG_PA11 25#ifdef CONFIG_PA11
24extern const struct dma_map_ops pcxl_dma_ops; 26extern const struct dma_map_ops pcxl_dma_ops;
25extern const struct dma_map_ops pcx_dma_ops; 27extern const struct dma_map_ops pcx_dma_ops;
@@ -54,12 +56,13 @@ parisc_walk_tree(struct device *dev)
54 break; 56 break;
55 } 57 }
56 } 58 }
57 BUG_ON(!dev->platform_data);
58 return dev->platform_data; 59 return dev->platform_data;
59} 60}
60 61
61#define GET_IOC(dev) (HBA_DATA(parisc_walk_tree(dev))->iommu) 62#define GET_IOC(dev) ({ \
62 63 void *__pdata = parisc_walk_tree(dev); \
64 __pdata ? HBA_DATA(__pdata)->iommu : NULL; \
65})
63 66
64#ifdef CONFIG_IOMMU_CCIO 67#ifdef CONFIG_IOMMU_CCIO
65struct parisc_device; 68struct parisc_device;
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index e32ca2ef9e54..56c93f096de9 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -741,6 +741,8 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
741 741
742 BUG_ON(!dev); 742 BUG_ON(!dev);
743 ioc = GET_IOC(dev); 743 ioc = GET_IOC(dev);
744 if (!ioc)
745 return DMA_ERROR_CODE;
744 746
745 BUG_ON(size <= 0); 747 BUG_ON(size <= 0);
746 748
@@ -814,6 +816,10 @@ ccio_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
814 816
815 BUG_ON(!dev); 817 BUG_ON(!dev);
816 ioc = GET_IOC(dev); 818 ioc = GET_IOC(dev);
819 if (!ioc) {
820 WARN_ON(!ioc);
821 return;
822 }
817 823
818 DBG_RUN("%s() iovp 0x%lx/%x\n", 824 DBG_RUN("%s() iovp 0x%lx/%x\n",
819 __func__, (long)iova, size); 825 __func__, (long)iova, size);
@@ -918,6 +924,8 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
918 924
919 BUG_ON(!dev); 925 BUG_ON(!dev);
920 ioc = GET_IOC(dev); 926 ioc = GET_IOC(dev);
927 if (!ioc)
928 return 0;
921 929
922 DBG_RUN_SG("%s() START %d entries\n", __func__, nents); 930 DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
923 931
@@ -990,6 +998,10 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
990 998
991 BUG_ON(!dev); 999 BUG_ON(!dev);
992 ioc = GET_IOC(dev); 1000 ioc = GET_IOC(dev);
1001 if (!ioc) {
1002 WARN_ON(!ioc);
1003 return;
1004 }
993 1005
994 DBG_RUN_SG("%s() START %d entries, %p,%x\n", 1006 DBG_RUN_SG("%s() START %d entries, %p,%x\n",
995 __func__, nents, sg_virt(sglist), sglist->length); 1007 __func__, nents, sg_virt(sglist), sglist->length);
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 1133b5cc88ca..5c63b920b471 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -154,7 +154,10 @@ struct dino_device
154}; 154};
155 155
156/* Looks nice and keeps the compiler happy */ 156/* Looks nice and keeps the compiler happy */
157#define DINO_DEV(d) ((struct dino_device *) d) 157#define DINO_DEV(d) ({ \
158 void *__pdata = d; \
159 BUG_ON(!__pdata); \
160 (struct dino_device *)__pdata; })
158 161
159 162
160/* 163/*
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 2ec2aef4d211..bc286cbbbc9b 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -111,8 +111,10 @@ static u32 lba_t32;
111 111
112 112
113/* Looks nice and keeps the compiler happy */ 113/* Looks nice and keeps the compiler happy */
114#define LBA_DEV(d) ((struct lba_device *) (d)) 114#define LBA_DEV(d) ({ \
115 115 void *__pdata = d; \
116 BUG_ON(!__pdata); \
117 (struct lba_device *)__pdata; })
116 118
117/* 119/*
118** Only allow 8 subsidiary busses per LBA 120** Only allow 8 subsidiary busses per LBA
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 33385e574433..87ad5fd6a7a2 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -691,6 +691,8 @@ static int sba_dma_supported( struct device *dev, u64 mask)
691 return 0; 691 return 0;
692 692
693 ioc = GET_IOC(dev); 693 ioc = GET_IOC(dev);
694 if (!ioc)
695 return 0;
694 696
695 /* 697 /*
696 * check if mask is >= than the current max IO Virt Address 698 * check if mask is >= than the current max IO Virt Address
@@ -722,6 +724,8 @@ sba_map_single(struct device *dev, void *addr, size_t size,
722 int pide; 724 int pide;
723 725
724 ioc = GET_IOC(dev); 726 ioc = GET_IOC(dev);
727 if (!ioc)
728 return DMA_ERROR_CODE;
725 729
726 /* save offset bits */ 730 /* save offset bits */
727 offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK; 731 offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
@@ -813,6 +817,10 @@ sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
813 DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size); 817 DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size);
814 818
815 ioc = GET_IOC(dev); 819 ioc = GET_IOC(dev);
820 if (!ioc) {
821 WARN_ON(!ioc);
822 return;
823 }
816 offset = iova & ~IOVP_MASK; 824 offset = iova & ~IOVP_MASK;
817 iova ^= offset; /* clear offset bits */ 825 iova ^= offset; /* clear offset bits */
818 size += offset; 826 size += offset;
@@ -952,6 +960,8 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
952 DBG_RUN_SG("%s() START %d entries\n", __func__, nents); 960 DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
953 961
954 ioc = GET_IOC(dev); 962 ioc = GET_IOC(dev);
963 if (!ioc)
964 return 0;
955 965
956 /* Fast path single entry scatterlists. */ 966 /* Fast path single entry scatterlists. */
957 if (nents == 1) { 967 if (nents == 1) {
@@ -1037,6 +1047,10 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
1037 __func__, nents, sg_virt(sglist), sglist->length); 1047 __func__, nents, sg_virt(sglist), sglist->length);
1038 1048
1039 ioc = GET_IOC(dev); 1049 ioc = GET_IOC(dev);
1050 if (!ioc) {
1051 WARN_ON(!ioc);
1052 return;
1053 }
1040 1054
1041#ifdef SBA_COLLECT_STATS 1055#ifdef SBA_COLLECT_STATS
1042 ioc->usg_calls++; 1056 ioc->usg_calls++;