rapidio/tsi721_dma: update error reporting from prep_sg callback
authorAlexandre Bounine <alexandre.bounine@idt.com>
Tue, 22 Mar 2016 21:26:59 +0000 (14:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 Mar 2016 22:36:02 +0000 (15:36 -0700)
Switch to returning error-valued pointer instead of simple NULL pointer.
This allows to properly identify situation when request queue is full
and therefore gives to upper layer an option to retry operation later.

Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Andre van Herk <andre.van.herk@prodrive-technologies.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/rapidio/devices/tsi721_dma.c

index 494482e4ab0a21f638b9581439f348a04d6e1be3..5bc9071ebcae26b3bd299fca9f2de38cec3251ed 100644 (file)
@@ -767,7 +767,7 @@ struct dma_async_tx_descriptor *tsi721_prep_rio_sg(struct dma_chan *dchan,
                        void *tinfo)
 {
        struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan);
-       struct tsi721_tx_desc *desc, *_d;
+       struct tsi721_tx_desc *desc;
        struct rio_dma_ext *rext = tinfo;
        enum dma_rtype rtype;
        struct dma_async_tx_descriptor *txd = NULL;
@@ -775,7 +775,7 @@ struct dma_async_tx_descriptor *tsi721_prep_rio_sg(struct dma_chan *dchan,
        if (!sgl || !sg_len) {
                tsi_err(&dchan->dev->device, "DMAC%d No SG list",
                        bdma_chan->id);
-               return NULL;
+               return ERR_PTR(-EINVAL);
        }
 
        tsi_debug(DMA, &dchan->dev->device, "DMAC%d %s", bdma_chan->id,
@@ -800,28 +800,33 @@ struct dma_async_tx_descriptor *tsi721_prep_rio_sg(struct dma_chan *dchan,
                tsi_err(&dchan->dev->device,
                        "DMAC%d Unsupported DMA direction option",
                        bdma_chan->id);
-               return NULL;
+               return ERR_PTR(-EINVAL);
        }
 
        spin_lock_bh(&bdma_chan->lock);
 
-       list_for_each_entry_safe(desc, _d, &bdma_chan->free_list, desc_node) {
-               if (async_tx_test_ack(&desc->txd)) {
-                       list_del_init(&desc->desc_node);
-                       desc->destid = rext->destid;
-                       desc->rio_addr = rext->rio_addr;
-                       desc->rio_addr_u = 0;
-                       desc->rtype = rtype;
-                       desc->sg_len    = sg_len;
-                       desc->sg        = sgl;
-                       txd             = &desc->txd;
-                       txd->flags      = flags;
-                       break;
-               }
+       if (!list_empty(&bdma_chan->free_list)) {
+               desc = list_first_entry(&bdma_chan->free_list,
+                               struct tsi721_tx_desc, desc_node);
+               list_del_init(&desc->desc_node);
+               desc->destid = rext->destid;
+               desc->rio_addr = rext->rio_addr;
+               desc->rio_addr_u = 0;
+               desc->rtype = rtype;
+               desc->sg_len    = sg_len;
+               desc->sg        = sgl;
+               txd             = &desc->txd;
+               txd->flags      = flags;
        }
 
        spin_unlock_bh(&bdma_chan->lock);
 
+       if (!txd) {
+               tsi_debug(DMA, &dchan->dev->device,
+                         "DMAC%d free TXD is not available", bdma_chan->id);
+               return ERR_PTR(-EBUSY);
+       }
+
        return txd;
 }