From: Vinod Koul <vkoul@kernel.org>
To: Gustavo Pimentel <Gustavo.Pimentel@synopsys.com>
Cc: linux-pci@vger.kernel.org, dmaengine@vger.kernel.org,
Dan Williams <dan.j.williams@intel.com>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Russell King <rmk+kernel@armlinux.org.uk>,
Joao Pinto <Joao.Pinto@synopsys.com>
Subject: Re: [RFC v6 1/6] dmaengine: Add Synopsys eDMA IP core driver
Date: Mon, 6 May 2019 16:50:01 +0530 [thread overview]
Message-ID: <20190506112001.GE3845@vkoul-mobl.Dlink> (raw)
In-Reply-To: <0e877ac0115d37e466ac234f47c51cb1cae7f292.1556043127.git.gustavo.pimentel@synopsys.com>
On 23-04-19, 20:30, Gustavo Pimentel wrote:
> Add Synopsys PCIe Endpoint eDMA IP core driver to kernel.
Still an RFC ?
> +static struct dw_edma_chunk *dw_edma_alloc_chunk(struct dw_edma_desc *desc)
> +{
> + struct dw_edma_chan *chan = desc->chan;
> + struct dw_edma *dw = chan->chip->dw;
> + struct dw_edma_chunk *chunk;
> +
> + chunk = kzalloc(sizeof(*chunk), GFP_KERNEL);
Looking at the code this should be called from one of the
device_prep_xxx calls so this should not sleep, so GFP_NOWAIT please
(pls audit rest of the mem allocations in the code)
> + if (unlikely(!chunk))
> + return NULL;
> +
> + INIT_LIST_HEAD(&chunk->list);
> + chunk->chan = chan;
> + chunk->cb = !(desc->chunks_alloc % 2);
? why %2?
> +static enum dma_status
> +dw_edma_device_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
> + struct dma_tx_state *txstate)
> +{
> + struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
> + struct dw_edma_desc *desc;
> + struct virt_dma_desc *vd;
> + unsigned long flags;
> + enum dma_status ret;
> + u32 residue = 0;
> +
> + ret = dma_cookie_status(dchan, cookie, txstate);
> + if (ret == DMA_COMPLETE)
> + return ret;
> +
> + if (ret == DMA_IN_PROGRESS && chan->status == EDMA_ST_PAUSE)
> + ret = DMA_PAUSED;
Don't you want to set residue on paused channel, how else will user know
the position of pause?
> +static struct dma_async_tx_descriptor *
> +dw_edma_device_transfer(struct dw_edma_transfer *xfer)
> +{
> + struct dw_edma_chan *chan = dchan2dw_edma_chan(xfer->dchan);
> + enum dma_transfer_direction direction = xfer->direction;
> + phys_addr_t src_addr, dst_addr;
> + struct scatterlist *sg = NULL;
> + struct dw_edma_chunk *chunk;
> + struct dw_edma_burst *burst;
> + struct dw_edma_desc *desc;
> + u32 cnt;
> + int i;
> +
> + if ((direction == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_WRITE) ||
> + (direction == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_READ))
> + return NULL;
> +
> + if (xfer->cyclic) {
> + if (!xfer->xfer.cyclic.len || !xfer->xfer.cyclic.cnt)
> + return NULL;
> + } else {
> + if (xfer->xfer.sg.len < 1)
> + return NULL;
> + }
> +
> + if (!chan->configured)
> + return NULL;
> +
> + desc = dw_edma_alloc_desc(chan);
> + if (unlikely(!desc))
> + goto err_alloc;
> +
> + chunk = dw_edma_alloc_chunk(desc);
> + if (unlikely(!chunk))
> + goto err_alloc;
> +
> + src_addr = chan->config.src_addr;
> + dst_addr = chan->config.dst_addr;
> +
> + if (xfer->cyclic) {
> + cnt = xfer->xfer.cyclic.cnt;
> + } else {
> + cnt = xfer->xfer.sg.len;
> + sg = xfer->xfer.sg.sgl;
> + }
> +
> + for (i = 0; i < cnt; i++) {
> + if (!xfer->cyclic && !sg)
> + break;
> +
> + if (chunk->bursts_alloc == chan->ll_max) {
> + chunk = dw_edma_alloc_chunk(desc);
> + if (unlikely(!chunk))
> + goto err_alloc;
> + }
> +
> + burst = dw_edma_alloc_burst(chunk);
> + if (unlikely(!burst))
> + goto err_alloc;
> +
> + if (xfer->cyclic)
> + burst->sz = xfer->xfer.cyclic.len;
> + else
> + burst->sz = sg_dma_len(sg);
> +
> + chunk->ll_region.sz += burst->sz;
> + desc->alloc_sz += burst->sz;
> +
> + if (direction == DMA_DEV_TO_MEM) {
> + burst->sar = src_addr;
We are device to mem, so src is peripheral.. okay
> + if (xfer->cyclic) {
> + burst->dar = xfer->xfer.cyclic.paddr;
> + } else {
> + burst->dar = sg_dma_address(sg);
> + src_addr += sg_dma_len(sg);
and we increment the src, doesn't make sense to me!
> + }
> + } else {
> + burst->dar = dst_addr;
> + if (xfer->cyclic) {
> + burst->sar = xfer->xfer.cyclic.paddr;
> + } else {
> + burst->sar = sg_dma_address(sg);
> + dst_addr += sg_dma_len(sg);
same here as well
> +static void dw_edma_done_interrupt(struct dw_edma_chan *chan)
> +{
> + struct dw_edma_desc *desc;
> + struct virt_dma_desc *vd;
> + unsigned long flags;
> +
> + dw_edma_v0_core_clear_done_int(chan);
> +
> + spin_lock_irqsave(&chan->vc.lock, flags);
> + vd = vchan_next_desc(&chan->vc);
> + if (vd) {
> + switch (chan->request) {
> + case EDMA_REQ_NONE:
> + desc = vd2dw_edma_desc(vd);
> + if (desc->chunks_alloc) {
> + chan->status = EDMA_ST_BUSY;
> + dw_edma_start_transfer(chan);
> + } else {
> + list_del(&vd->node);
> + vchan_cookie_complete(vd);
> + chan->status = EDMA_ST_IDLE;
> + }
> + break;
Empty line after each break please
> + case EDMA_REQ_STOP:
> + list_del(&vd->node);
> + vchan_cookie_complete(vd);
> + chan->request = EDMA_REQ_NONE;
> + chan->status = EDMA_ST_IDLE;
Why do we need to track request as well as status?
> +static int dw_edma_alloc_chan_resources(struct dma_chan *dchan)
> +{
> + struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
> +
> + if (chan->status != EDMA_ST_IDLE)
> + return -EBUSY;
> +
> + dma_cookie_init(dchan);
not using vchan_init() you need to do this and init the lists..?
> +struct dw_edma_transfer {
> + struct dma_chan *dchan;
> + union Xfer {
no camel case please
It would help to run checkpatch with --strict option to find any style
issues and fix them as well
--
~Vinod
next prev parent reply other threads:[~2019-05-06 11:20 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-23 18:30 [RFC v6 0/6] dmaengine: Add Synopsys eDMA IP driver (version 0) Gustavo Pimentel
2019-04-23 18:30 ` [RFC v6 1/6] dmaengine: Add Synopsys eDMA IP core driver Gustavo Pimentel
2019-05-06 11:20 ` Vinod Koul [this message]
2019-05-06 16:42 ` Gustavo Pimentel
2019-05-07 5:03 ` Vinod Koul
2019-05-07 9:08 ` Gustavo Pimentel
2019-05-07 9:56 ` Vinod Koul
2019-04-23 18:30 ` [RFC v6 2/6] dmaengine: Add Synopsys eDMA IP version 0 support Gustavo Pimentel
2019-05-06 11:56 ` Vinod Koul
2019-04-23 18:30 ` [RFC v6 3/6] dmaengine: Add Synopsys eDMA IP version 0 debugfs support Gustavo Pimentel
2019-05-06 12:07 ` Vinod Koul
2019-05-06 17:09 ` Gustavo Pimentel
2019-05-07 5:11 ` Vinod Koul
2019-05-07 9:48 ` Gustavo Pimentel
2019-04-23 18:30 ` [RFC v6 4/6] PCI: Add Synopsys endpoint EDDA Device ID Gustavo Pimentel
2019-04-23 18:30 ` [RFC v6 5/6] dmaengine: Add Synopsys eDMA IP PCIe glue-logic Gustavo Pimentel
2019-04-23 18:30 ` [RFC v6 6/6] MAINTAINERS: Add Synopsys eDMA IP driver maintainer Gustavo Pimentel
2019-05-06 8:12 ` [RFC v6 0/6] dmaengine: Add Synopsys eDMA IP driver (version 0) Gustavo Pimentel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190506112001.GE3845@vkoul-mobl.Dlink \
--to=vkoul@kernel.org \
--cc=Gustavo.Pimentel@synopsys.com \
--cc=Joao.Pinto@synopsys.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=dan.j.williams@intel.com \
--cc=dmaengine@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=rmk+kernel@armlinux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox