aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Bounine <[email protected]>2016-03-22 14:26:59 -0700
committerLinus Torvalds <[email protected]>2016-03-22 15:36:02 -0700
commit83472457505c454592d91807754135d0ad34b125 (patch)
tree3c93685eba4fff5416df6201fdd6f9b4c2fc7774
parent72d8a0d23083ba89fb00a7ad9b07419e34ebe47c (diff)
rapidio/tsi721_dma: update error reporting from prep_sg callback
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 <[email protected]> Cc: Matt Porter <[email protected]> Cc: Aurelien Jacquiot <[email protected]> Cc: Andre van Herk <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r--drivers/rapidio/devices/tsi721_dma.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c
index 494482e4ab0a..5bc9071ebcae 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -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;
}