From: Krzysztof Halasa on
Hi,

Noticed this problem a bit late :-(

6fee48cd330c68332f9712bc968d934a1a84a32a broke
pci_set_consistent_dma_mask() on IXP4xx and most probably PXA. Affected
devices are e.g. IDE controller (CS5536-based: disk inaccessible) and
e1000 ethernet ("Detected Tx Unit Hang").

The attached patch makes it work again, though I'm not sure it's the
best solution.

Ideas?

Signed-off-by: Krzysztof HaƂasa <khc(a)pm.waw.pl>

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index ca32ed7..bd2a7d3 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -129,6 +129,14 @@ static inline u64 dma_get_mask(struct device *dev)

static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
{
+#ifdef CONFIG_DMABOUNCE
+ if (dev->archdata.dmabounce) {
+ if (mask >= ISA_DMA_THRESHOLD)
+ return 0;
+ else
+ return -EIO;
+ }
+#endif
if (!dma_supported(dev, mask))
return -EIO;
dev->coherent_dma_mask = mask;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: FUJITA Tomonori on
On Tue, 10 Aug 2010 22:36:21 +0200
Krzysztof Halasa <khc(a)pm.waw.pl> wrote:

> 6fee48cd330c68332f9712bc968d934a1a84a32a broke
> pci_set_consistent_dma_mask() on IXP4xx and most probably PXA. Affected
> devices are e.g. IDE controller (CS5536-based: disk inaccessible) and
> e1000 ethernet ("Detected Tx Unit Hang").

Sorry about that.

> The attached patch makes it work again, though I'm not sure it's the
> best solution.

I think that we should avoid adding "#ifdef CONFIG_DMABOUNCE" to a
generic place.

Why the above patch breaks dmabounce.c? We can't set dev->coherent_dma_mask?


> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index ca32ed7..bd2a7d3 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -129,6 +129,14 @@ static inline u64 dma_get_mask(struct device *dev)
>
> static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
> {
> +#ifdef CONFIG_DMABOUNCE
> + if (dev->archdata.dmabounce) {
> + if (mask >= ISA_DMA_THRESHOLD)
> + return 0;
> + else
> + return -EIO;
> + }
> +#endif
> if (!dma_supported(dev, mask))
> return -EIO;
> dev->coherent_dma_mask = mask;
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo(a)vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Russell King - ARM Linux on
On Wed, Aug 11, 2010 at 11:06:00AM +0900, FUJITA Tomonori wrote:
> On Tue, 10 Aug 2010 22:36:21 +0200
> Krzysztof Halasa <khc(a)pm.waw.pl> wrote:
>
> > 6fee48cd330c68332f9712bc968d934a1a84a32a broke
> > pci_set_consistent_dma_mask() on IXP4xx and most probably PXA. Affected
> > devices are e.g. IDE controller (CS5536-based: disk inaccessible) and
> > e1000 ethernet ("Detected Tx Unit Hang").
>
> Sorry about that.
>
> > The attached patch makes it work again, though I'm not sure it's the
> > best solution.
>
> I think that we should avoid adding "#ifdef CONFIG_DMABOUNCE" to a
> generic place.
>
> Why the above patch breaks dmabounce.c? We can't set dev->coherent_dma_mask?

It doesn't break dmabounce.

What it breaks is the fact that a PCI device which can do 32-bit DMA is
connected to a PCI bus which can only access the first 64MB of memory
through the host bridge, but the system has more than 64MB available.

Allowing a 32-bit DMA mask means that dmabounce can't detect that memory
above 64MB needs to be bounced to memory below the 64MB boundary.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: FUJITA Tomonori on
On Wed, 11 Aug 2010 08:25:32 +0100
Russell King - ARM Linux <linux(a)arm.linux.org.uk> wrote:

> On Wed, Aug 11, 2010 at 11:06:00AM +0900, FUJITA Tomonori wrote:
> > On Tue, 10 Aug 2010 22:36:21 +0200
> > Krzysztof Halasa <khc(a)pm.waw.pl> wrote:
> >
> > > 6fee48cd330c68332f9712bc968d934a1a84a32a broke
> > > pci_set_consistent_dma_mask() on IXP4xx and most probably PXA. Affected
> > > devices are e.g. IDE controller (CS5536-based: disk inaccessible) and
> > > e1000 ethernet ("Detected Tx Unit Hang").
> >
> > Sorry about that.
> >
> > > The attached patch makes it work again, though I'm not sure it's the
> > > best solution.
> >
> > I think that we should avoid adding "#ifdef CONFIG_DMABOUNCE" to a
> > generic place.
> >
> > Why the above patch breaks dmabounce.c? We can't set dev->coherent_dma_mask?
>
> It doesn't break dmabounce.
>
> What it breaks is the fact that a PCI device which can do 32-bit DMA is
> connected to a PCI bus which can only access the first 64MB of memory
> through the host bridge, but the system has more than 64MB available.
>
> Allowing a 32-bit DMA mask means that dmabounce can't detect that memory
> above 64MB needs to be bounced to memory below the 64MB boundary.

But dmabounce doesn't look at dev->coherent_dma_mask.

The change breaks __dma_alloc_buffer()? If we set dev->coherent_dma_mask
to DMA_BIT_MASK(32) for ixp4xx's pci devices, __dma_alloc_buffer()
doesn't use GFP_DMA.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Russell King - ARM Linux on
On Fri, Aug 13, 2010 at 03:23:53PM +0900, FUJITA Tomonori wrote:
> On Wed, 11 Aug 2010 08:25:32 +0100
> Russell King - ARM Linux <linux(a)arm.linux.org.uk> wrote:
> > It doesn't break dmabounce.
> >
> > What it breaks is the fact that a PCI device which can do 32-bit DMA is
> > connected to a PCI bus which can only access the first 64MB of memory
> > through the host bridge, but the system has more than 64MB available.
> >
> > Allowing a 32-bit DMA mask means that dmabounce can't detect that memory
> > above 64MB needs to be bounced to memory below the 64MB boundary.
>
> But dmabounce doesn't look at dev->coherent_dma_mask.
>
> The change breaks __dma_alloc_buffer()? If we set dev->coherent_dma_mask
> to DMA_BIT_MASK(32) for ixp4xx's pci devices, __dma_alloc_buffer()
> doesn't use GFP_DMA.

With an incorrect coherent_dma_mask, dma_alloc_coherent() will return
memory outside of the 64MB window. This means that when dmabounce comes
to allocate the replacement buffer, it gets a buffer which won't be
accessible to the DMA controller - which is a condition it doesn't check
for.

Ergo, it breaks dmabounce.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/