All of lore.kernel.org
 help / color / mirror / Atom feed
From: Russell King - ARM Linux <linux@arm.linux.org.uk>
To: Mark Brown <broonie@kernel.org>
Cc: Tejun Heo <tj@kernel.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	linux-ide@vger.kernel.org, linaro-kernel@lists.linaro.org,
	linux-arm-kernel@lists.infradead.org,
	kernel-build-reports@lists.linaro.org
Subject: Re: sata_dwc_460ex build failures in -next
Date: Mon, 12 Jan 2015 12:50:37 +0000	[thread overview]
Message-ID: <20150112125037.GH12302@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20150112123655.GF4160@sirena.org.uk>

On Mon, Jan 12, 2015 at 12:36:55PM +0000, Mark Brown wrote:
> On Mon, Jan 12, 2015 at 08:03:27AM +0000, Build bot for Mark Brown wrote:
> 
> > 	arm64-allmodconfig
> > ../drivers/ata/sata_dwc_460ex.c:719:3: error: implicit declaration of function 'dma_cache_sync' [-Werror=implicit-function-declaration]
> > 
> > 	arm-allmodconfig
> > ../drivers/ata/sata_dwc_460ex.c:719:3: error: implicit declaration of function 'dma_cache_sync' [-Werror=implicit-function-declaration]
> 
> Since commit 84683a7e081ff60e (sata_dwc_460ex: enable COMPILE_TEST for
> the driver) the sata_dwc_460ex has been breaking the all*config builds
> for arm and arm64 as the driver uses dma_cache_sync() but this function
> is not provided on those architectures.
> 
> Either a more specific dependency is needed or the function shouldn't be
> used, I've not looked at the code.

The driver does look rather broken.  Let's first read up when dma_cache_sync()
should be used:

  void
  dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                 enum dma_data_direction direction)
  
  Do a partial sync of memory that was allocated by
  dma_alloc_noncoherent(), starting at virtual address vaddr and
  continuing on for size.  Again, you *must* observe the cache line
  boundaries when doing this.

Note "memory that was allocated by dma_alloc_noncoherent()".

Now, let's look at the driver:

static int map_sg_to_lli(struct scatterlist *sg, int num_elems,
                        struct lli *lli, dma_addr_t dma_lli,
                        void __iomem *dmadr_addr, int dir)
{
...
                dma_cache_sync(NULL, lli, (sizeof(struct lli) * idx),
                               DMA_BIDIRECTIONAL);
}

static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems,
                              struct lli *lli, dma_addr_t dma_lli,
                              void __iomem *addr, int dir)
{
        /* Convert SG list to linked list of items (LLIs) for AHB DMA */
        num_lli = map_sg_to_lli(sg, num_elems, lli, dma_lli, addr, dir);
}

        dma_chan = dma_dwc_xfer_setup(sg, qc->n_elem, hsdevp->llit[tag],
                                      hsdevp->llit_dma[tag],
                                      (void *__iomem)(&hsdev->sata_dwc_regs->\
                                      dmadr), qc->dma_dir);

        for (i = 0; i < SATA_DWC_QCMD_MAX; i++) {
                hsdevp->llit[i] = dma_alloc_coherent(pdev,
                                                     SATA_DWC_DMAC_LLI_TBL_SZ,
                                                     &(hsdevp->llit_dma[i]),
                                                     GFP_ATOMIC);

So, hsdevp->llit[x] is allocated using dma_alloc_*coherent*(), not
dma_alloc_*noncohernet*(), so dma_cache_sync() should not be used
according to the DMA API documentation.

Moreover, that GFP_ATOMIC flag looks mightily suspicious - we've done
a previous allocation using kzalloc(, GFP_KERNEL), so we aren't in an
atomic region, so why use GFP_ATOMIC there?

It doesn't look like it'll pass sparse checks either:

struct sata_dwc_device {
        u8                      *reg_base;
        struct sata_dwc_regs    *sata_dwc_regs; /* DW Synopsys SATA specific */
};

        u8 *base = NULL;

        base = of_iomap(ofdev->dev.of_node, 0);
        hsdev->reg_base = base;
        hsdev->sata_dwc_regs = (void *__iomem)(base + SATA_DWC_REG_OFFSET);

Maybe it should be moved to drivers/staging? :)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

WARNING: multiple messages have this Message-ID (diff)
From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: sata_dwc_460ex build failures in -next
Date: Mon, 12 Jan 2015 12:50:37 +0000	[thread overview]
Message-ID: <20150112125037.GH12302@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20150112123655.GF4160@sirena.org.uk>

On Mon, Jan 12, 2015 at 12:36:55PM +0000, Mark Brown wrote:
> On Mon, Jan 12, 2015 at 08:03:27AM +0000, Build bot for Mark Brown wrote:
> 
> > 	arm64-allmodconfig
> > ../drivers/ata/sata_dwc_460ex.c:719:3: error: implicit declaration of function 'dma_cache_sync' [-Werror=implicit-function-declaration]
> > 
> > 	arm-allmodconfig
> > ../drivers/ata/sata_dwc_460ex.c:719:3: error: implicit declaration of function 'dma_cache_sync' [-Werror=implicit-function-declaration]
> 
> Since commit 84683a7e081ff60e (sata_dwc_460ex: enable COMPILE_TEST for
> the driver) the sata_dwc_460ex has been breaking the all*config builds
> for arm and arm64 as the driver uses dma_cache_sync() but this function
> is not provided on those architectures.
> 
> Either a more specific dependency is needed or the function shouldn't be
> used, I've not looked at the code.

The driver does look rather broken.  Let's first read up when dma_cache_sync()
should be used:

  void
  dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                 enum dma_data_direction direction)
  
  Do a partial sync of memory that was allocated by
  dma_alloc_noncoherent(), starting at virtual address vaddr and
  continuing on for size.  Again, you *must* observe the cache line
  boundaries when doing this.

Note "memory that was allocated by dma_alloc_noncoherent()".

Now, let's look at the driver:

static int map_sg_to_lli(struct scatterlist *sg, int num_elems,
                        struct lli *lli, dma_addr_t dma_lli,
                        void __iomem *dmadr_addr, int dir)
{
...
                dma_cache_sync(NULL, lli, (sizeof(struct lli) * idx),
                               DMA_BIDIRECTIONAL);
}

static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems,
                              struct lli *lli, dma_addr_t dma_lli,
                              void __iomem *addr, int dir)
{
        /* Convert SG list to linked list of items (LLIs) for AHB DMA */
        num_lli = map_sg_to_lli(sg, num_elems, lli, dma_lli, addr, dir);
}

        dma_chan = dma_dwc_xfer_setup(sg, qc->n_elem, hsdevp->llit[tag],
                                      hsdevp->llit_dma[tag],
                                      (void *__iomem)(&hsdev->sata_dwc_regs->\
                                      dmadr), qc->dma_dir);

        for (i = 0; i < SATA_DWC_QCMD_MAX; i++) {
                hsdevp->llit[i] = dma_alloc_coherent(pdev,
                                                     SATA_DWC_DMAC_LLI_TBL_SZ,
                                                     &(hsdevp->llit_dma[i]),
                                                     GFP_ATOMIC);

So, hsdevp->llit[x] is allocated using dma_alloc_*coherent*(), not
dma_alloc_*noncohernet*(), so dma_cache_sync() should not be used
according to the DMA API documentation.

Moreover, that GFP_ATOMIC flag looks mightily suspicious - we've done
a previous allocation using kzalloc(, GFP_KERNEL), so we aren't in an
atomic region, so why use GFP_ATOMIC there?

It doesn't look like it'll pass sparse checks either:

struct sata_dwc_device {
        u8                      *reg_base;
        struct sata_dwc_regs    *sata_dwc_regs; /* DW Synopsys SATA specific */
};

        u8 *base = NULL;

        base = of_iomap(ofdev->dev.of_node, 0);
        hsdev->reg_base = base;
        hsdev->sata_dwc_regs = (void *__iomem)(base + SATA_DWC_REG_OFFSET);

Maybe it should be moved to drivers/staging? :)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

  reply	other threads:[~2015-01-12 12:50 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <E1YAZyB-0007iE-CZ@debutante>
2015-01-12 12:36 ` sata_dwc_460ex build failures in -next Mark Brown
2015-01-12 12:50   ` Russell King - ARM Linux [this message]
2015-01-12 12:50     ` Russell King - ARM Linux
2015-01-12 12:59     ` Andy Shevchenko
2015-01-12 12:59       ` Andy Shevchenko
2015-01-12 13:07       ` Mark Brown
2015-01-12 13:07         ` Mark Brown

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=20150112125037.GH12302@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=kernel-build-reports@lists.linaro.org \
    --cc=linaro-kernel@lists.linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-ide@vger.kernel.org \
    --cc=tj@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.