Skip to content

Commit 635a582

Browse files
tsbogendgregkh
authored andcommitted
parisc: DMA API: return error instead of BUG_ON for dma ops on non dma devs
commit 33f9e02 upstream. 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 hardkernel#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. Signed-off-by: Thomas Bogendoerfer <[email protected]> Signed-off-by: Helge Deller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f265641 commit 635a582

File tree

5 files changed

+41
-7
lines changed

5 files changed

+41
-7
lines changed

arch/parisc/include/asm/dma-mapping.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ struct hppa_dma_ops {
3939
** flush/purge and allocate "regular" cacheable pages for everything.
4040
*/
4141

42+
#define DMA_ERROR_CODE (~(dma_addr_t)0)
43+
4244
#ifdef CONFIG_PA11
4345
extern struct hppa_dma_ops pcxl_dma_ops;
4446
extern struct hppa_dma_ops pcx_dma_ops;
@@ -209,12 +211,13 @@ parisc_walk_tree(struct device *dev)
209211
break;
210212
}
211213
}
212-
BUG_ON(!dev->platform_data);
213214
return dev->platform_data;
214215
}
215-
216-
#define GET_IOC(dev) (HBA_DATA(parisc_walk_tree(dev))->iommu)
217-
216+
217+
#define GET_IOC(dev) ({ \
218+
void *__pdata = parisc_walk_tree(dev); \
219+
__pdata ? HBA_DATA(__pdata)->iommu : NULL; \
220+
})
218221

219222
#ifdef CONFIG_IOMMU_CCIO
220223
struct parisc_device;

drivers/parisc/ccio-dma.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
741741

742742
BUG_ON(!dev);
743743
ioc = GET_IOC(dev);
744+
if (!ioc)
745+
return DMA_ERROR_CODE;
744746

745747
BUG_ON(size <= 0);
746748

@@ -805,6 +807,10 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
805807

806808
BUG_ON(!dev);
807809
ioc = GET_IOC(dev);
810+
if (!ioc) {
811+
WARN_ON(!ioc);
812+
return;
813+
}
808814

809815
DBG_RUN("%s() iovp 0x%lx/%x\n",
810816
__func__, (long)iova, size);
@@ -908,6 +914,8 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
908914

909915
BUG_ON(!dev);
910916
ioc = GET_IOC(dev);
917+
if (!ioc)
918+
return 0;
911919

912920
DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
913921

@@ -980,6 +988,10 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
980988

981989
BUG_ON(!dev);
982990
ioc = GET_IOC(dev);
991+
if (!ioc) {
992+
WARN_ON(!ioc);
993+
return;
994+
}
983995

984996
DBG_RUN_SG("%s() START %d entries, %p,%x\n",
985997
__func__, nents, sg_virt(sglist), sglist->length);

drivers/parisc/dino.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,10 @@ struct dino_device
154154
};
155155

156156
/* 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; })
158161

159162

160163
/*

drivers/parisc/lba_pci.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ static u32 lba_t32;
111111

112112

113113
/* Looks nice and keeps the compiler happy */
114-
#define LBA_DEV(d) ((struct lba_device *) (d))
115-
114+
#define LBA_DEV(d) ({ \
115+
void *__pdata = d; \
116+
BUG_ON(!__pdata); \
117+
(struct lba_device *)__pdata; })
116118

117119
/*
118120
** Only allow 8 subsidiary busses per LBA

drivers/parisc/sba_iommu.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,8 @@ static int sba_dma_supported( struct device *dev, u64 mask)
691691
return 0;
692692

693693
ioc = GET_IOC(dev);
694+
if (!ioc)
695+
return 0;
694696

695697
/*
696698
* 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,
722724
int pide;
723725

724726
ioc = GET_IOC(dev);
727+
if (!ioc)
728+
return DMA_ERROR_CODE;
725729

726730
/* save offset bits */
727731
offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
@@ -803,6 +807,10 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
803807
DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size);
804808

805809
ioc = GET_IOC(dev);
810+
if (!ioc) {
811+
WARN_ON(!ioc);
812+
return;
813+
}
806814
offset = iova & ~IOVP_MASK;
807815
iova ^= offset; /* clear offset bits */
808816
size += offset;
@@ -942,6 +950,8 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
942950
DBG_RUN_SG("%s() START %d entries\n", __func__, nents);
943951

944952
ioc = GET_IOC(dev);
953+
if (!ioc)
954+
return 0;
945955

946956
/* Fast path single entry scatterlists. */
947957
if (nents == 1) {
@@ -1027,6 +1037,10 @@ sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
10271037
__func__, nents, sg_virt(sglist), sglist->length);
10281038

10291039
ioc = GET_IOC(dev);
1040+
if (!ioc) {
1041+
WARN_ON(!ioc);
1042+
return;
1043+
}
10301044

10311045
#ifdef SBA_COLLECT_STATS
10321046
ioc->usg_calls++;

0 commit comments

Comments
 (0)