lkml.org 
[lkml]   [2017]   [Jul]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.12 39/84] parisc: DMA API: return error instead of BUG_ON for dma ops on non dma devs
    Date
    4.12-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

    commit 33f9e02495d15a061f0c94ef46f5103a2d0c20f3 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 #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 <tsbogend@alpha.franken.de>
    Signed-off-by: Helge Deller <deller@gmx.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/parisc/include/asm/dma-mapping.h | 11 +++++++----
    drivers/parisc/ccio-dma.c | 12 ++++++++++++
    drivers/parisc/dino.c | 5 ++++-
    drivers/parisc/lba_pci.c | 6 ++++--
    drivers/parisc/sba_iommu.c | 14 ++++++++++++++
    5 files changed, 41 insertions(+), 7 deletions(-)

    --- a/arch/parisc/include/asm/dma-mapping.h
    +++ b/arch/parisc/include/asm/dma-mapping.h
    @@ -20,6 +20,8 @@
    ** flush/purge and allocate "regular" cacheable pages for everything.
    */

    +#define DMA_ERROR_CODE (~(dma_addr_t)0)
    +
    #ifdef CONFIG_PA11
    extern const struct dma_map_ops pcxl_dma_ops;
    extern const struct dma_map_ops pcx_dma_ops;
    @@ -54,12 +56,13 @@ parisc_walk_tree(struct device *dev)
    break;
    }
    }
    - BUG_ON(!dev->platform_data);
    return dev->platform_data;
    }
    -
    -#define GET_IOC(dev) (HBA_DATA(parisc_walk_tree(dev))->iommu)
    -
    +
    +#define GET_IOC(dev) ({ \
    + void *__pdata = parisc_walk_tree(dev); \
    + __pdata ? HBA_DATA(__pdata)->iommu : NULL; \
    +})

    #ifdef CONFIG_IOMMU_CCIO
    struct parisc_device;
    --- a/drivers/parisc/ccio-dma.c
    +++ b/drivers/parisc/ccio-dma.c
    @@ -741,6 +741,8 @@ ccio_map_single(struct device *dev, void

    BUG_ON(!dev);
    ioc = GET_IOC(dev);
    + if (!ioc)
    + return DMA_ERROR_CODE;

    BUG_ON(size <= 0);

    @@ -814,6 +816,10 @@ ccio_unmap_page(struct device *dev, dma_

    BUG_ON(!dev);
    ioc = GET_IOC(dev);
    + if (!ioc) {
    + WARN_ON(!ioc);
    + return;
    + }

    DBG_RUN("%s() iovp 0x%lx/%x\n",
    __func__, (long)iova, size);
    @@ -918,6 +924,8 @@ ccio_map_sg(struct device *dev, struct s

    BUG_ON(!dev);
    ioc = GET_IOC(dev);
    + if (!ioc)
    + return 0;

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

    @@ -990,6 +998,10 @@ ccio_unmap_sg(struct device *dev, struct

    BUG_ON(!dev);
    ioc = GET_IOC(dev);
    + if (!ioc) {
    + WARN_ON(!ioc);
    + return;
    + }

    DBG_RUN_SG("%s() START %d entries, %p,%x\n",
    __func__, nents, sg_virt(sglist), sglist->length);
    --- a/drivers/parisc/dino.c
    +++ b/drivers/parisc/dino.c
    @@ -154,7 +154,10 @@ struct dino_device
    };

    /* Looks nice and keeps the compiler happy */
    -#define DINO_DEV(d) ((struct dino_device *) d)
    +#define DINO_DEV(d) ({ \
    + void *__pdata = d; \
    + BUG_ON(!__pdata); \
    + (struct dino_device *)__pdata; })


    /*
    --- a/drivers/parisc/lba_pci.c
    +++ b/drivers/parisc/lba_pci.c
    @@ -111,8 +111,10 @@ static u32 lba_t32;


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

    /*
    ** Only allow 8 subsidiary busses per LBA
    --- a/drivers/parisc/sba_iommu.c
    +++ b/drivers/parisc/sba_iommu.c
    @@ -691,6 +691,8 @@ static int sba_dma_supported( struct dev
    return 0;

    ioc = GET_IOC(dev);
    + if (!ioc)
    + return 0;

    /*
    * check if mask is >= than the current max IO Virt Address
    @@ -722,6 +724,8 @@ sba_map_single(struct device *dev, void
    int pide;

    ioc = GET_IOC(dev);
    + if (!ioc)
    + return DMA_ERROR_CODE;

    /* save offset bits */
    offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
    @@ -813,6 +817,10 @@ sba_unmap_page(struct device *dev, dma_a
    DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size);

    ioc = GET_IOC(dev);
    + if (!ioc) {
    + WARN_ON(!ioc);
    + return;
    + }
    offset = iova & ~IOVP_MASK;
    iova ^= offset; /* clear offset bits */
    size += offset;
    @@ -952,6 +960,8 @@ sba_map_sg(struct device *dev, struct sc
    DBG_RUN_SG("%s() START %d entries\n", __func__, nents);

    ioc = GET_IOC(dev);
    + if (!ioc)
    + return 0;

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

    ioc = GET_IOC(dev);
    + if (!ioc) {
    + WARN_ON(!ioc);
    + return;
    + }

    #ifdef SBA_COLLECT_STATS
    ioc->usg_calls++;

    \
     
     \ /
      Last update: 2017-07-19 11:59    [W:4.106 / U:0.500 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site