From patchwork Thu Apr 17 14:40:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 4009061 X-Patchwork-Delegate: vinod.koul@intel.com Return-Path: X-Original-To: patchwork-dmaengine@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 114C79F336 for ; Thu, 17 Apr 2014 14:40:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0D20520397 for ; Thu, 17 Apr 2014 14:40:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BE04D20394 for ; Thu, 17 Apr 2014 14:40:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750971AbaDQOkc (ORCPT ); Thu, 17 Apr 2014 10:40:32 -0400 Received: from www.linutronix.de ([62.245.132.108]:49269 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750982AbaDQOkb (ORCPT ); Thu, 17 Apr 2014 10:40:31 -0400 Received: from localhost ([127.0.0.1] helo=ionos.tec.linutronix.de) by Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1WanUL-0004jy-Jz; Thu, 17 Apr 2014 16:40:29 +0200 Message-Id: <20140417143249.095049101@linutronix.de> User-Agent: quilt/0.60-1 Date: Thu, 17 Apr 2014 14:40:44 -0000 From: Thomas Gleixner To: dmaengine@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, dan.j.williams@intel.com, vinod.koul@intel.com, nsekhar@ti.com, joelf@ti.com, Peter Ujfalusi Subject: [patch 1/6] dma: edma: Sanitize residue reporting References: <20140417133737.892475126@linutronix.de> Content-Disposition: inline; filename=dma-edma-sanitize-residue-reporting.patch X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1, SHORTCIRCUIT=-0.0001 Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The residue reporting in edma_tx_status() is just broken. It blindly walks the psets and recalculates the lenght of the transfer from the hardware parameters. For cyclic transfers it adds the link pset, which results in interestingly large residues. For non-cyclic it adds the dummy pset, which is stupid as well. Aside of that it's silly to walk through the pset params when the per descriptor residue is known at the point of creating it. Store the information in edma_desc and use it. Signed-off-by: Thomas Gleixner Reviewed-by: Joel Fernandes --- drivers/dma/edma.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux-2.6/drivers/dma/edma.c =================================================================== --- linux-2.6.orig/drivers/dma/edma.c +++ linux-2.6/drivers/dma/edma.c @@ -64,6 +64,7 @@ struct edma_desc { int absync; int pset_nr; int processed; + u32 residue; struct edmacc_param pset[0]; }; @@ -416,6 +417,7 @@ static struct dma_async_tx_descriptor *e } edesc->pset_nr = sg_len; + edesc->residue = 0; /* Allocate a PaRAM slot, if needed */ nslots = min_t(unsigned, MAX_NR_SG, sg_len); @@ -450,6 +452,7 @@ static struct dma_async_tx_descriptor *e } edesc->absync = ret; + edesc->residue += sg_dma_len(sg); /* If this is the last in a current SG set of transactions, enable interrupts so that next set is processed */ @@ -527,6 +530,7 @@ static struct dma_async_tx_descriptor *e edesc->cyclic = 1; edesc->pset_nr = nslots; + edesc->residue = buf_len; dev_dbg(dev, "%s: nslots=%d\n", __func__, nslots); dev_dbg(dev, "%s: period_len=%d\n", __func__, period_len); @@ -622,6 +626,7 @@ static void edma_callback(unsigned ch_nu vchan_cyclic_callback(&edesc->vdesc); } else if (edesc->processed == edesc->pset_nr) { dev_dbg(dev, "Transfer complete, stopping channel %d\n", ch_num); + edesc->residue = 0; edma_stop(echan->ch_num); vchan_cookie_complete(&edesc->vdesc); edma_execute(echan); @@ -754,25 +759,6 @@ static void edma_issue_pending(struct dm spin_unlock_irqrestore(&echan->vchan.lock, flags); } -static size_t edma_desc_size(struct edma_desc *edesc) -{ - int i; - size_t size; - - if (edesc->absync) - for (size = i = 0; i < edesc->pset_nr; i++) - size += (edesc->pset[i].a_b_cnt & 0xffff) * - (edesc->pset[i].a_b_cnt >> 16) * - edesc->pset[i].ccnt; - else - size = (edesc->pset[0].a_b_cnt & 0xffff) * - (edesc->pset[0].a_b_cnt >> 16) + - (edesc->pset[0].a_b_cnt & 0xffff) * - (SZ_64K - 1) * edesc->pset[0].ccnt; - - return size; -} - /* Check request completion status */ static enum dma_status edma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, @@ -789,12 +775,10 @@ static enum dma_status edma_tx_status(st spin_lock_irqsave(&echan->vchan.lock, flags); vdesc = vchan_find_desc(&echan->vchan, cookie); - if (vdesc) { - txstate->residue = edma_desc_size(to_edma_desc(&vdesc->tx)); - } else if (echan->edesc && echan->edesc->vdesc.tx.cookie == cookie) { - struct edma_desc *edesc = echan->edesc; - txstate->residue = edma_desc_size(edesc); - } + if (vdesc) + txstate->residue = to_edma_desc(&vdesc->tx)->residue; + else if (echan->edesc && echan->edesc->vdesc.tx.cookie == cookie) + txstate->residue = echan->edesc->residue; spin_unlock_irqrestore(&echan->vchan.lock, flags); return ret;