2010-02-12 09:35:54

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 0/7] transforming the PCI DMA API into the generic device model

This patchset transforms the PCI DMA API into the generic device
model. It's one of the reasons why we introduced the generic DMA API
long ago; driver writers are always able to use the generic DMA API
with any bus instead of using bus specific DMA APIs such as
pci_map_single, sbus_map_single, etc (only two bus specific APIs
exist now; pci and ssb).

Some of the PCI DMA API are already implented on the top of the
generic DMA API (include/asm-generic/pci-dma-compat.h). But there are
some exceptions. This patchset finishes the transformation.

=
Documentation/DMA-API.txt | 10 ++
arch/alpha/Kconfig | 1 +
arch/alpha/include/asm/dma-mapping.h | 79 ++++-------
arch/alpha/include/asm/pci.h | 125 +----------------
arch/alpha/kernel/pci-noop.c | 101 +++++--------
arch/alpha/kernel/pci_iommu.c | 201 ++++++++++++--------------
arch/arm/common/it8152.c | 27 ----
arch/arm/include/asm/dma-mapping.h | 8 +
arch/arm/mach-ixp4xx/common-pci.c | 26 ----
arch/arm/mach-ixp4xx/include/mach/hardware.h | 5 -
arch/arm/mach-pxa/include/mach/hardware.h | 1 -
arch/powerpc/include/asm/dma-mapping.h | 3 -
arch/powerpc/kernel/pci-common.c | 15 --
arch/sparc/include/asm/dma-mapping.h | 14 ++-
arch/sparc/kernel/iommu.c | 10 --
arch/sparc/kernel/ioport.c | 11 --
drivers/pci/pci.c | 31 ----
include/asm-generic/pci-dma-compat.h | 13 ++-
include/linux/dma-mapping.h | 8 +
include/linux/pci.h | 2 -
20 files changed, 214 insertions(+), 477 deletions(-)


2010-02-12 09:35:31

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 7/7] pci: move pci_set_dma_mask and pci_set_consistent_dma_mask to pci-dma-compat.h

We can use pci-dma-compat.h to implement pci_set_dma_mask and
pci_set_consistent_dma_mask as we do with the other PCI DMA API.

We can remove HAVE_ARCH_PCI_SET_DMA_MASK too.

Signed-off-by: FUJITA Tomonori <[email protected]>
Cc: Jesse Barnes <[email protected]>
---
drivers/pci/pci.c | 28 ----------------------------
include/asm-generic/pci-dma-compat.h | 13 ++++++++++---
include/linux/pci.h | 2 --
3 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index aacb86f..57af999 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2114,32 +2114,6 @@ void pci_msi_off(struct pci_dev *dev)
}
}

-#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
-/*
- * These can be overridden by arch-specific implementations
- */
-int
-pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- int ret = dma_set_mask(&dev->dev, mask);
- if (ret)
- return ret;
- dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
- return 0;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- int ret = dma_set_coherent_mask(&dev->dev, mask);
- if (ret)
- return ret;
-
- dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask));
- return 0;
-}
-#endif
-
#ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
{
@@ -2857,8 +2831,6 @@ EXPORT_SYMBOL(pci_set_mwi);
EXPORT_SYMBOL(pci_try_set_mwi);
EXPORT_SYMBOL(pci_clear_mwi);
EXPORT_SYMBOL_GPL(pci_intx);
-EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_set_consistent_dma_mask);
EXPORT_SYMBOL(pci_assign_resource);
EXPORT_SYMBOL(pci_find_parent_resource);
EXPORT_SYMBOL(pci_select_bars);
diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h
index 37b3706..ddfa9c5 100644
--- a/include/asm-generic/pci-dma-compat.h
+++ b/include/asm-generic/pci-dma-compat.h
@@ -6,9 +6,6 @@

#include <linux/dma-mapping.h>

-/* note pci_set_dma_mask isn't here, since it's a public function
- * exported from drivers/pci, use dma_supported instead */
-
static inline int
pci_dma_supported(struct pci_dev *hwdev, u64 mask)
{
@@ -104,4 +101,14 @@ pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr)
return dma_mapping_error(&pdev->dev, dma_addr);
}

+static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ return dma_set_mask(&dev->dev, mask);
+}
+
+static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ return dma_set_coherent_mask(&dev->dev, mask);
+}
+
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 032f42c..12b8aff 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -720,8 +720,6 @@ int pci_try_set_mwi(struct pci_dev *dev);
void pci_clear_mwi(struct pci_dev *dev);
void pci_intx(struct pci_dev *dev, int enable);
void pci_msi_off(struct pci_dev *dev);
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
int pcix_get_max_mmrbc(struct pci_dev *dev);
--
1.5.6.5

2010-02-12 09:35:43

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 4/7] dma-mapping.h: add dma_set_coherent_mask

dma_set_coherent_mask corresponds to pci_set_consistent_dma_mask. This
is necessary to move to the generic device model DMA API from the PCI
bus specific API in the long term.

dma_set_coherent_mask works in the exact same way that
pci_set_consistent_dma_mask does. So this patch also changes
pci_set_consistent_dma_mask to call dma_set_coherent_mask.

Signed-off-by: FUJITA Tomonori <[email protected]>
Cc: James Bottomley <[email protected]>
Cc: David S. Miller <[email protected]>
Cc: Jesse Barnes <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Russell King <[email protected]>
---
Documentation/DMA-API.txt | 10 ++++++++++
drivers/pci/pci.c | 7 +++----
include/linux/dma-mapping.h | 8 ++++++++
3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index bd34a62..d7d9eef 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -167,6 +167,16 @@ parameters if it is.

Returns: 0 if successful and a negative error if not.

+int
+dma_set_coherent_mask(struct device *dev, u64 mask)
+int
+pci_set_consistent_dma_mask(struct pci_device *dev, u64 mask)
+
+Checks to see if the mask is possible and updates the device
+parameters if it is.
+
+Returns: 0 if successful and a negative error if not.
+
u64
dma_get_required_mask(struct device *dev)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5c881e9..aacb86f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2131,12 +2131,11 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
int
pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
{
- if (!pci_dma_supported(dev, mask))
- return -EIO;
+ int ret = dma_set_coherent_mask(&dev->dev, mask);
+ if (ret)
+ return ret;

- dev->dev.coherent_dma_mask = mask;
dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask));
-
return 0;
}
#endif
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 86e7dc3..599d8e4 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -127,6 +127,14 @@ static inline u64 dma_get_mask(struct device *dev)
return DMA_BIT_MASK(32);
}

+static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ if (!dma_supported(dev, mask))
+ return -EIO;
+ dev->coherent_dma_mask = mask;
+ return 0;
+}
+
extern u64 dma_get_required_mask(struct device *dev);

static inline unsigned int dma_get_max_seg_size(struct device *dev)
--
1.5.6.5

2010-02-12 09:35:47

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 3/7] pci: convert pci_set_dma_mask to call dma_set_mask

This changes pci_set_dma_mask to call the generic DMA API,
dma_set_mask.

pci_set_dma_mask (in drivers/pci/pci.c) does the same things that
dma_set_mask does on all the architectures that use pci_set_dma_mask;
calls dma_supprted and sets dev->dma_mask. So we safely change
pci_set_dma_mask to simply call dma_set_mask.

Signed-off-by: FUJITA Tomonori <[email protected]>
Cc: James Bottomley <[email protected]>
Cc: David S. Miller <[email protected]>
Cc: Jesse Barnes <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Russell King <[email protected]>
---
drivers/pci/pci.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 315fea4..5c881e9 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2121,15 +2121,13 @@ void pci_msi_off(struct pci_dev *dev)
int
pci_set_dma_mask(struct pci_dev *dev, u64 mask)
{
- if (!pci_dma_supported(dev, mask))
- return -EIO;
-
- dev->dma_mask = mask;
+ int ret = dma_set_mask(&dev->dev, mask);
+ if (ret)
+ return ret;
dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
-
return 0;
}
-
+
int
pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
{
--
1.5.6.5

2010-02-12 09:35:29

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 1/7] sparc: unify 32bit and 64bit dma_set_mask

sparc has two dma_set_mask implementations for 32bit and 64bit. They
are same except for the error returned value. We can safely unify them
since the error returned value doesn't matter as long as it is
negative (as DMA-API.txt describes).

This patch also changes dma_set_mask not to call
pci_set_dma_mask. Instead, dma_set_mask does the same thing that
pci_set_dma_mask does. This change enables ut to change
pci_set_dma_mask to call dma_set_mask; we can implement
pci_set_dma_mask as pci-dma-compat.h does.

Signed-off-by: FUJITA Tomonori <[email protected]>
Cc: David Miller <[email protected]>
---
arch/sparc/include/asm/dma-mapping.h | 14 +++++++++++++-
arch/sparc/kernel/iommu.c | 10 ----------
arch/sparc/kernel/ioport.c | 11 -----------
3 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 5a8c308..4b4a0c0 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -8,7 +8,6 @@
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)

extern int dma_supported(struct device *dev, u64 mask);
-extern int dma_set_mask(struct device *dev, u64 dma_mask);

#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
@@ -62,4 +61,17 @@ static inline int dma_get_cache_alignment(void)
return (1 << INTERNODE_CACHE_SHIFT);
}

+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+#ifdef CONFIG_PCI
+ if (dev->bus == &pci_bus_type) {
+ if (!dev->dma_mask || !dma_supported(dev, mask))
+ return -EINVAL;
+ *dev->dma_mask = mask;
+ return 0;
+ }
+#endif
+ return -EINVAL;
+}
+
#endif
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 5fad949..8414549 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -862,13 +862,3 @@ int dma_supported(struct device *dev, u64 device_mask)
return 0;
}
EXPORT_SYMBOL(dma_supported);
-
-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type)
- return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
- return -EINVAL;
-}
-EXPORT_SYMBOL(dma_set_mask);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 3c8c44f..84e5386 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -676,17 +676,6 @@ int dma_supported(struct device *dev, u64 mask)
}
EXPORT_SYMBOL(dma_supported);

-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type)
- return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
- return -EOPNOTSUPP;
-}
-EXPORT_SYMBOL(dma_set_mask);
-
-
#ifdef CONFIG_PROC_FS

static int sparc_io_proc_show(struct seq_file *m, void *v)
--
1.5.6.5

2010-02-12 09:35:41

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 2/7] alpha: use include/linux/pci-dma-compat.h

This converts Alpha to use include/linux/pci-dma-compat.h. Alpha is
the only architecutre that implements the PCI DMA API in the own
way. That makes it difficult to implement the generic DMA API via the
PCI bus specific DMA API.

The generic DMA API calls the PCI DMA API implementation in
arch/alpha/kernel/pci_iommu.c on non Jensen systems. It calls
the DMA API in arch/alpha/kernel/pci-noop.c on Jensen systems.

Signed-off-by: FUJITA Tomonori <[email protected]>
Cc: Richard Henderson <[email protected]>
Cc: Ivan Kokshaysky <[email protected]>
Cc: Matt Turner <[email protected]>
---
arch/alpha/Kconfig | 1 +
arch/alpha/include/asm/dma-mapping.h | 79 +++++---------
arch/alpha/include/asm/pci.h | 125 +--------------------
arch/alpha/kernel/pci-noop.c | 101 +++++++----------
arch/alpha/kernel/pci_iommu.c | 201 ++++++++++++++++------------------
5 files changed, 165 insertions(+), 342 deletions(-)

diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 759f49d..75291fd 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -10,6 +10,7 @@ config ALPHA
select HAVE_OPROFILE
select HAVE_SYSCALL_WRAPPERS
select HAVE_PERF_EVENTS
+ select HAVE_DMA_ATTRS
help
The Alpha is a 64-bit general-purpose processor designed and
marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h
index f514ede..1bce816 100644
--- a/arch/alpha/include/asm/dma-mapping.h
+++ b/arch/alpha/include/asm/dma-mapping.h
@@ -1,70 +1,49 @@
#ifndef _ALPHA_DMA_MAPPING_H
#define _ALPHA_DMA_MAPPING_H

+#include <linux/dma-attrs.h>

-#ifdef CONFIG_PCI
+extern struct dma_map_ops *dma_ops;

-#include <linux/pci.h>
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ return dma_ops;
+}

-#define dma_map_single(dev, va, size, dir) \
- pci_map_single(alpha_gendev_to_pci(dev), va, size, dir)
-#define dma_unmap_single(dev, addr, size, dir) \
- pci_unmap_single(alpha_gendev_to_pci(dev), addr, size, dir)
-#define dma_alloc_coherent(dev, size, addr, gfp) \
- __pci_alloc_consistent(alpha_gendev_to_pci(dev), size, addr, gfp)
-#define dma_free_coherent(dev, size, va, addr) \
- pci_free_consistent(alpha_gendev_to_pci(dev), size, va, addr)
-#define dma_map_page(dev, page, off, size, dir) \
- pci_map_page(alpha_gendev_to_pci(dev), page, off, size, dir)
-#define dma_unmap_page(dev, addr, size, dir) \
- pci_unmap_page(alpha_gendev_to_pci(dev), addr, size, dir)
-#define dma_map_sg(dev, sg, nents, dir) \
- pci_map_sg(alpha_gendev_to_pci(dev), sg, nents, dir)
-#define dma_unmap_sg(dev, sg, nents, dir) \
- pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir)
-#define dma_supported(dev, mask) \
- pci_dma_supported(alpha_gendev_to_pci(dev), mask)
-#define dma_mapping_error(dev, addr) \
- pci_dma_mapping_error(alpha_gendev_to_pci(dev), addr)
+#include <asm-generic/dma-mapping-common.h>

-#else /* no PCI - no IOMMU. */
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ return get_dma_ops(dev)->alloc_coherent(dev, size, dma_handle, gfp);
+}

-#include <asm/io.h> /* for virt_to_phys() */
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ get_dma_ops(dev)->free_coherent(dev, size, vaddr, dma_handle);
+}

-struct scatterlist;
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp);
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction);
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return get_dma_ops(dev)->mapping_error(dev, dma_addr);
+}

-#define dma_free_coherent(dev, size, va, addr) \
- free_pages((unsigned long)va, get_order(size))
-#define dma_supported(dev, mask) (mask < 0x00ffffffUL ? 0 : 1)
-#define dma_map_single(dev, va, size, dir) virt_to_phys(va)
-#define dma_map_page(dev, page, off, size, dir) (page_to_pa(page) + off)
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ return get_dma_ops(dev)->dma_supported(dev, mask);
+}

-#define dma_unmap_single(dev, addr, size, dir) ((void)0)
-#define dma_unmap_page(dev, addr, size, dir) ((void)0)
-#define dma_unmap_sg(dev, sg, nents, dir) ((void)0)
-
-#define dma_mapping_error(dev, addr) (0)
-
-#endif /* !CONFIG_PCI */
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+ return get_dma_ops(dev)->set_dma_mask(dev, mask);
+}

#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
#define dma_is_consistent(d, h) (1)

-int dma_set_mask(struct device *dev, u64 mask);
-
-#define dma_sync_single_for_cpu(dev, addr, size, dir) ((void)0)
-#define dma_sync_single_for_device(dev, addr, size, dir) ((void)0)
-#define dma_sync_sg_for_cpu(dev, sg, nents, dir) ((void)0)
-#define dma_sync_sg_for_device(dev, sg, nents, dir) ((void)0)
#define dma_cache_sync(dev, va, size, dir) ((void)0)
-#define dma_sync_single_range_for_cpu(dev, addr, offset, size, dir) ((void)0)
-#define dma_sync_single_range_for_device(dev, addr, offset, size, dir) ((void)0)
-
#define dma_get_cache_alignment() L1_CACHE_BYTES

#endif /* _ALPHA_DMA_MAPPING_H */
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index e1846ba..28d0497 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -70,128 +70,11 @@ extern inline void pcibios_penalize_isa_irq(int irq, int active)
decisions. */
#define PCI_DMA_BUS_IS_PHYS 0

-/* Allocate and map kernel buffer using consistent mode DMA for PCI
- device. Returns non-NULL cpu-view pointer to the buffer if
- successful and sets *DMA_ADDRP to the pci side dma address as well,
- else DMA_ADDRP is undefined. */
-
-extern void *__pci_alloc_consistent(struct pci_dev *, size_t,
- dma_addr_t *, gfp_t);
-static inline void *
-pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma)
-{
- return __pci_alloc_consistent(dev, size, dma, GFP_ATOMIC);
-}
-
-/* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must
- be values that were returned from pci_alloc_consistent. SIZE must
- be the same as what as passed into pci_alloc_consistent.
- References to the memory and mappings associated with CPU_ADDR or
- DMA_ADDR past this call are illegal. */
-
-extern void pci_free_consistent(struct pci_dev *, size_t, void *, dma_addr_t);
-
-/* Map a single buffer of the indicate size for PCI DMA in streaming mode.
- The 32-bit PCI bus mastering address to use is returned. Once the device
- is given the dma address, the device owns this memory until either
- pci_unmap_single or pci_dma_sync_single_for_cpu is performed. */
-
-extern dma_addr_t pci_map_single(struct pci_dev *, void *, size_t, int);
-
-/* Likewise, but for a page instead of an address. */
-extern dma_addr_t pci_map_page(struct pci_dev *, struct page *,
- unsigned long, size_t, int);
-
-/* Test for pci_map_single or pci_map_page having generated an error. */
-
-static inline int
-pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr)
-{
- return dma_addr == 0;
-}
-
-/* Unmap a single streaming mode DMA translation. The DMA_ADDR and
- SIZE must match what was provided for in a previous pci_map_single
- call. All other usages are undefined. After this call, reads by
- the cpu to the buffer are guaranteed to see whatever the device
- wrote there. */
-
-extern void pci_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
-extern void pci_unmap_page(struct pci_dev *, dma_addr_t, size_t, int);
-
-/* Map a set of buffers described by scatterlist in streaming mode for
- PCI DMA. This is the scatter-gather version of the above
- pci_map_single interface. Here the scatter gather list elements
- are each tagged with the appropriate PCI dma address and length.
- They are obtained via sg_dma_{address,length}(SG).
-
- NOTE: An implementation may be able to use a smaller number of DMA
- address/length pairs than there are SG table elements. (for
- example via virtual mapping capabilities) The routine returns the
- number of addr/length pairs actually used, at most nents.
-
- Device ownership issues as mentioned above for pci_map_single are
- the same here. */
-
-extern int pci_map_sg(struct pci_dev *, struct scatterlist *, int, int);
-
-/* Unmap a set of streaming mode DMA translations. Again, cpu read
- rules concerning calls here are the same as for pci_unmap_single()
- above. */
-
-extern void pci_unmap_sg(struct pci_dev *, struct scatterlist *, int, int);
-
-/* Make physical memory consistent for a single streaming mode DMA
- translation after a transfer and device currently has ownership
- of the buffer.
-
- If you perform a pci_map_single() but wish to interrogate the
- buffer using the cpu, yet do not wish to teardown the PCI dma
- mapping, you must call this function before doing so. At the next
- point you give the PCI dma address back to the card, you must first
- perform a pci_dma_sync_for_device, and then the device again owns
- the buffer. */
-
-static inline void
-pci_dma_sync_single_for_cpu(struct pci_dev *dev, dma_addr_t dma_addr,
- long size, int direction)
-{
- /* Nothing to do. */
-}
-
-static inline void
-pci_dma_sync_single_for_device(struct pci_dev *dev, dma_addr_t dma_addr,
- size_t size, int direction)
-{
- /* Nothing to do. */
-}
-
-/* Make physical memory consistent for a set of streaming mode DMA
- translations after a transfer. The same as pci_dma_sync_single_*
- but for a scatter-gather list, same rules and usage. */
-
-static inline void
-pci_dma_sync_sg_for_cpu(struct pci_dev *dev, struct scatterlist *sg,
- int nents, int direction)
-{
- /* Nothing to do. */
-}
-
-static inline void
-pci_dma_sync_sg_for_device(struct pci_dev *dev, struct scatterlist *sg,
- int nents, int direction)
-{
- /* Nothing to do. */
-}
-
-/* Return whether the given PCI device DMA address mask can
- be supported properly. For example, if your device can
- only drive the low 24-bits during PCI bus mastering, then
- you would pass 0x00ffffff as the mask to this function. */
+#ifdef CONFIG_PCI

-extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
+/* implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>

-#ifdef CONFIG_PCI
static inline void pci_dma_burst_advice(struct pci_dev *pdev,
enum pci_dma_burst_strategy *strat,
unsigned long *strategy_parameter)
@@ -230,8 +113,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
return hose->need_domain_info;
}

-struct pci_dev *alpha_gendev_to_pci(struct device *dev);
-
#endif /* __KERNEL__ */

/* Values for the `which' argument to sys_pciconfig_iobase. */
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index c19a376..823a540 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -106,58 +106,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
return -ENODEV;
}

-/* Stubs for the routines in pci_iommu.c: */
-
-void *
-__pci_alloc_consistent(struct pci_dev *pdev, size_t size,
- dma_addr_t *dma_addrp, gfp_t gfp)
-{
- return NULL;
-}
-
-void
-pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
- dma_addr_t dma_addr)
-{
-}
-
-dma_addr_t
-pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size,
- int direction)
-{
- return (dma_addr_t) 0;
-}
-
-void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
- int direction)
-{
-}
-
-int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
-{
- return 0;
-}
-
-void
-pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
-{
-}
-
-int
-pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
-{
- return 0;
-}
-
-/* Generic DMA mapping functions: */
-
-void *
-dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
+static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;

@@ -171,11 +121,22 @@ dma_alloc_coherent(struct device *dev, size_t size,
return ret;
}

-EXPORT_SYMBOL(dma_alloc_coherent);
+static void alpha_noop_free_coherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_addr)
+{
+ free_pages((unsigned long)cpu_addr, get_order(size));
+}
+
+static dma_addr_t alpha_noop_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ return page_to_pa(page) + offset;
+}

-int
-dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
- enum dma_data_direction direction)
+static int alpha_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
int i;
struct scatterlist *sg;
@@ -192,19 +153,37 @@ dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
return nents;
}

-EXPORT_SYMBOL(dma_map_sg);
+static int alpha_noop_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static int alpha_noop_supported(struct device *dev, u64 mask)
+{
+ return mask < 0x00ffffffUL ? 0 : 1;
+}

-int
-dma_set_mask(struct device *dev, u64 mask)
+static int alpha_noop_set_mask(struct device *dev, u64 mask)
{
if (!dev->dma_mask || !dma_supported(dev, mask))
return -EIO;

*dev->dma_mask = mask;
-
return 0;
}
-EXPORT_SYMBOL(dma_set_mask);
+
+struct dma_map_ops alpha_noop_ops = {
+ .alloc_coherent = alpha_noop_alloc_coherent,
+ .free_coherent = alpha_noop_free_coherent,
+ .map_page = alpha_noop_map_page,
+ .map_sg = alpha_noop_map_sg,
+ .mapping_error = alpha_noop_mapping_error,
+ .dma_supported = alpha_noop_supported,
+ .set_dma_mask = alpha_noop_set_mask,
+};
+
+struct dma_map_ops *dma_ops = &alpha_noop_ops;
+EXPORT_SYMBOL(dma_ops);

void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 8449504..ce9e54c 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -216,10 +216,30 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n)
for (i = 0; i < n; ++i)
p[i] = 0;
}
-
-/* True if the machine supports DAC addressing, and DEV can
- make use of it given MASK. */
-static int pci_dac_dma_supported(struct pci_dev *hwdev, u64 mask);
+
+/*
+ * True if the machine supports DAC addressing, and DEV can
+ * make use of it given MASK.
+ */
+static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
+{
+ dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
+ int ok = 1;
+
+ /* If this is not set, the machine doesn't support DAC at all. */
+ if (dac_offset == 0)
+ ok = 0;
+
+ /* The device has to be able to address our DAC bit. */
+ if ((dac_offset & dev->dma_mask) != dac_offset)
+ ok = 0;
+
+ /* If both conditions above are met, we are fine. */
+ DBGA("pci_dac_dma_supported %s from %p\n",
+ ok ? "yes" : "no", __builtin_return_address(0));
+
+ return ok;
+}

/* Map a single buffer of the indicated size for PCI DMA in streaming
mode. The 32-bit PCI bus mastering address to use is returned.
@@ -301,23 +321,36 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
return ret;
}

-dma_addr_t
-pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
+/* Helper for generic DMA-mapping functions. */
+static struct pci_dev *alpha_gendev_to_pci(struct device *dev)
{
- int dac_allowed;
+ if (dev && dev->bus == &pci_bus_type)
+ return to_pci_dev(dev);

- if (dir == PCI_DMA_NONE)
- BUG();
+ /* Assume that non-PCI devices asking for DMA are either ISA or EISA,
+ BUG() otherwise. */
+ BUG_ON(!isa_bridge);

- dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
- return pci_map_single_1(pdev, cpu_addr, size, dac_allowed);
+ /* Assume non-busmaster ISA DMA when dma_mask is not set (the ISA
+ bridge is bus master then). */
+ if (!dev || !dev->dma_mask || !*dev->dma_mask)
+ return isa_bridge;
+
+ /* For EISA bus masters, return isa_bridge (it might have smaller
+ dma_mask due to wiring limitations). */
+ if (*dev->dma_mask >= isa_bridge->dma_mask)
+ return isa_bridge;
+
+ /* This assumes ISA bus master with dma_mask 0xffffff. */
+ return NULL;
}
-EXPORT_SYMBOL(pci_map_single);

-dma_addr_t
-pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
- size_t size, int dir)
+static dma_addr_t alpha_pci_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
int dac_allowed;

if (dir == PCI_DMA_NONE)
@@ -327,7 +360,6 @@ pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
return pci_map_single_1(pdev, (char *)page_address(page) + offset,
size, dac_allowed);
}
-EXPORT_SYMBOL(pci_map_page);

/* Unmap a single streaming mode DMA translation. The DMA_ADDR and
SIZE must match what was provided for in a previous pci_map_single
@@ -335,16 +367,17 @@ EXPORT_SYMBOL(pci_map_page);
the cpu to the buffer are guaranteed to see whatever the device
wrote there. */

-void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
- int direction)
+static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long flags;
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
struct pci_iommu_arena *arena;
long dma_ofs, npages;

- if (direction == PCI_DMA_NONE)
+ if (dir == PCI_DMA_NONE)
BUG();

if (dma_addr >= __direct_map_base
@@ -393,25 +426,16 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n",
dma_addr, size, npages, __builtin_return_address(0));
}
-EXPORT_SYMBOL(pci_unmap_single);
-
-void
-pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr,
- size_t size, int direction)
-{
- pci_unmap_single(pdev, dma_addr, size, direction);
-}
-EXPORT_SYMBOL(pci_unmap_page);

/* Allocate and map kernel buffer using consistent mode DMA for PCI
device. Returns non-NULL cpu-view pointer to the buffer if
successful and sets *DMA_ADDRP to the pci side dma address as well,
else DMA_ADDRP is undefined. */

-void *
-__pci_alloc_consistent(struct pci_dev *pdev, size_t size,
- dma_addr_t *dma_addrp, gfp_t gfp)
+static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_addrp, gfp_t gfp)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
void *cpu_addr;
long order = get_order(size);

@@ -439,13 +463,12 @@ try_again:
gfp |= GFP_DMA;
goto try_again;
}
-
+
DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n",
size, cpu_addr, *dma_addrp, __builtin_return_address(0));

return cpu_addr;
}
-EXPORT_SYMBOL(__pci_alloc_consistent);

/* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must
be values that were returned from pci_alloc_consistent. SIZE must
@@ -453,17 +476,16 @@ EXPORT_SYMBOL(__pci_alloc_consistent);
References to the memory and mappings associated with CPU_ADDR or
DMA_ADDR past this call are illegal. */

-void
-pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
- dma_addr_t dma_addr)
+static void alpha_pci_free_coherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_addr)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
free_pages((unsigned long)cpu_addr, get_order(size));

DBGA2("pci_free_consistent: [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0));
}
-EXPORT_SYMBOL(pci_free_consistent);

/* Classify the elements of the scatterlist. Write dma_address
of each element with:
@@ -626,23 +648,21 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
return 1;
}

-int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
+static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
struct scatterlist *start, *end, *out;
struct pci_controller *hose;
struct pci_iommu_arena *arena;
dma_addr_t max_dma;
int dac_allowed;
- struct device *dev;

- if (direction == PCI_DMA_NONE)
+ if (dir == PCI_DMA_NONE)
BUG();

- dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
-
- dev = pdev ? &pdev->dev : NULL;
+ dac_allowed = dev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;

/* Fast path single entry scatterlists. */
if (nents == 1) {
@@ -699,19 +719,19 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
/* Some allocation failed while mapping the scatterlist
entries. Unmap them now. */
if (out > start)
- pci_unmap_sg(pdev, start, out - start, direction);
+ pci_unmap_sg(pdev, start, out - start, dir);
return 0;
}
-EXPORT_SYMBOL(pci_map_sg);

/* Unmap a set of streaming mode DMA translations. Again, cpu read
rules concerning calls here are the same as for pci_unmap_single()
above. */

-void
-pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
- int direction)
+static void alpha_pci_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
unsigned long flags;
struct pci_controller *hose;
struct pci_iommu_arena *arena;
@@ -719,7 +739,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
dma_addr_t max_dma;
dma_addr_t fbeg, fend;

- if (direction == PCI_DMA_NONE)
+ if (dir == PCI_DMA_NONE)
BUG();

if (! alpha_mv.mv_pci_tbi)
@@ -783,15 +803,13 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,

DBGA("pci_unmap_sg: %ld entries\n", nents - (end - sg));
}
-EXPORT_SYMBOL(pci_unmap_sg);
-

/* Return whether the given PCI device DMA address mask can be
supported properly. */

-int
-pci_dma_supported(struct pci_dev *pdev, u64 mask)
+static int alpha_pci_supported(struct device *dev, u64 mask)
{
+ struct pci_dev *pdev = alpha_gendev_to_pci(dev);
struct pci_controller *hose;
struct pci_iommu_arena *arena;

@@ -818,7 +836,6 @@ pci_dma_supported(struct pci_dev *pdev, u64 mask)

return 0;
}
-EXPORT_SYMBOL(pci_dma_supported);


/*
@@ -918,66 +935,32 @@ iommu_unbind(struct pci_iommu_arena *arena, long pg_start, long pg_count)
return 0;
}

-/* True if the machine supports DAC addressing, and DEV can
- make use of it given MASK. */
-
-static int
-pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
-{
- dma64_addr_t dac_offset = alpha_mv.pci_dac_offset;
- int ok = 1;
-
- /* If this is not set, the machine doesn't support DAC at all. */
- if (dac_offset == 0)
- ok = 0;
-
- /* The device has to be able to address our DAC bit. */
- if ((dac_offset & dev->dma_mask) != dac_offset)
- ok = 0;
-
- /* If both conditions above are met, we are fine. */
- DBGA("pci_dac_dma_supported %s from %p\n",
- ok ? "yes" : "no", __builtin_return_address(0));
-
- return ok;
-}
-
-/* Helper for generic DMA-mapping functions. */
-
-struct pci_dev *
-alpha_gendev_to_pci(struct device *dev)
+static int alpha_pci_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
- if (dev && dev->bus == &pci_bus_type)
- return to_pci_dev(dev);
-
- /* Assume that non-PCI devices asking for DMA are either ISA or EISA,
- BUG() otherwise. */
- BUG_ON(!isa_bridge);
-
- /* Assume non-busmaster ISA DMA when dma_mask is not set (the ISA
- bridge is bus master then). */
- if (!dev || !dev->dma_mask || !*dev->dma_mask)
- return isa_bridge;
-
- /* For EISA bus masters, return isa_bridge (it might have smaller
- dma_mask due to wiring limitations). */
- if (*dev->dma_mask >= isa_bridge->dma_mask)
- return isa_bridge;
-
- /* This assumes ISA bus master with dma_mask 0xffffff. */
- return NULL;
+ return dma_addr == 0;
}
-EXPORT_SYMBOL(alpha_gendev_to_pci);

-int
-dma_set_mask(struct device *dev, u64 mask)
+static int alpha_pci_set_mask(struct device *dev, u64 mask)
{
if (!dev->dma_mask ||
!pci_dma_supported(alpha_gendev_to_pci(dev), mask))
return -EIO;

*dev->dma_mask = mask;
-
return 0;
}
-EXPORT_SYMBOL(dma_set_mask);
+
+struct dma_map_ops alpha_pci_ops = {
+ .alloc_coherent = alpha_pci_alloc_coherent,
+ .free_coherent = alpha_pci_free_coherent,
+ .map_page = alpha_pci_map_page,
+ .unmap_page = alpha_pci_unmap_page,
+ .map_sg = alpha_pci_map_sg,
+ .unmap_sg = alpha_pci_unmap_sg,
+ .mapping_error = alpha_pci_mapping_error,
+ .dma_supported = alpha_pci_supported,
+ .set_dma_mask = alpha_pci_set_mask,
+};
+
+struct dma_map_ops *dma_ops = &alpha_pci_ops;
+EXPORT_SYMBOL(dma_ops);
--
1.5.6.5

2010-02-12 09:36:36

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 5/7] powerpc: use generic pci_set_dma_mask and pci_set_consistent_dma_mask

This converts powerpc to use the generic pci_set_dma_mask and
pci_set_consistent_dma_mask (drivers/pci/pci.c).

The generic pci_set_dma_mask does what powerpc's pci_set_dma_mask
does.

Unlike powerpc's pci_set_consistent_dma_mask, the gneric
pci_set_consistent_dma_mask sets only coherent_dma_mask. It doesn't
work for powerpc? pci_set_consistent_dma_mask API should set only
coherent_dma_mask?

Signed-off-by: FUJITA Tomonori <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
---
arch/powerpc/include/asm/dma-mapping.h | 3 ---
arch/powerpc/kernel/pci-common.c | 15 ---------------
2 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 80a973b..c85ef23 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -127,9 +127,6 @@ static inline int dma_supported(struct device *dev, u64 mask)
return dma_ops->dma_supported(dev, mask);
}

-/* We have our own implementation of pci_set_dma_mask() */
-#define HAVE_ARCH_PCI_SET_DMA_MASK
-
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index cadbed6..a8bc6f2 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -63,21 +63,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
}
EXPORT_SYMBOL(get_pci_dma_ops);

-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- return dma_set_mask(&dev->dev, mask);
-}
-
-int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- int rc;
-
- rc = dma_set_mask(&dev->dev, mask);
- dev->dev.coherent_dma_mask = dev->dma_mask;
-
- return rc;
-}
-
struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
{
struct pci_controller *phb;
--
1.5.6.5

2010-02-12 09:36:38

by FUJITA Tomonori

[permalink] [raw]
Subject: [PATCH -mm 6/7] arm: use generic pci_set_dma_mask and pci_set_consistent_dma_mask

This converts arm to the generic pci_set_dma_mask and
pci_set_consistent_dma_mask (removes HAVE_ARCH_PCI_SET_DMA_MASK for
dmabounce).

Signed-off-by: FUJITA Tomonori <[email protected]>
Cc: Russell King <[email protected]>
---
arch/arm/common/it8152.c | 27 --------------------------
arch/arm/include/asm/dma-mapping.h | 8 +++++++
arch/arm/mach-ixp4xx/common-pci.c | 26 -------------------------
arch/arm/mach-ixp4xx/include/mach/hardware.h | 5 ----
arch/arm/mach-pxa/include/mach/hardware.h | 1 -
5 files changed, 8 insertions(+), 59 deletions(-)

diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 2793447..ee1d3b8 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -272,33 +272,6 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
}

-/*
- * We override these so we properly do dmabounce otherwise drivers
- * are able to set the dma_mask to 0xffffffff and we can no longer
- * trap bounces. :(
- *
- * We just return true on everyhing except for < 64MB in which case
- * we will fail miseralby and die since we can't handle that case.
- */
-int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask);
- if (mask >= PHYS_OFFSET + SZ_64M - 1)
- return 0;
-
- return -EIO;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask);
- if (mask >= PHYS_OFFSET + SZ_64M - 1)
- return 0;
-
- return -EIO;
-}
-
int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
{
it8152_io.start = IT8152_IO_BASE + 0x12000;
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index a96300b..f6a138d 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -88,6 +88,14 @@ static inline int dma_supported(struct device *dev, u64 mask)

static inline int dma_set_mask(struct device *dev, u64 dma_mask)
{
+#ifdef CONFIG_DMABOUNCE
+ if (dev->archdata.dmabounce) {
+ if (dma_mask >= ISA_DMA_THRESHOLD)
+ return 0;
+ else
+ return -EIO;
+ }
+#endif
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;

diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index c4a0159..e318153 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -502,32 +502,6 @@ struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
}

-/*
- * We override these so we properly do dmabounce otherwise drivers
- * are able to set the dma_mask to 0xffffffff and we can no longer
- * trap bounces. :(
- *
- * We just return true on everyhing except for < 64MB in which case
- * we will fail miseralby and die since we can't handle that case.
- */
-int
-pci_set_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (mask >= SZ_64M - 1 )
- return 0;
-
- return -EIO;
-}
-
-int
-pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
-{
- if (mask >= SZ_64M - 1 )
- return 0;
-
- return -EIO;
-}
-
EXPORT_SYMBOL(ixp4xx_pci_read);
EXPORT_SYMBOL(ixp4xx_pci_write);

diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
index f9d1c43..f91ca6d 100644
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
+++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h
@@ -26,11 +26,6 @@
#define PCIBIOS_MAX_MEM 0x4BFFFFFF
#endif

-/*
- * We override the standard dma-mask routines for bouncing.
- */
-#define HAVE_ARCH_PCI_SET_DMA_MASK
-
#define pcibios_assign_all_busses() 1

/* Register locations and bits */
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
index e741bf1..7515757 100644
--- a/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -314,7 +314,6 @@ extern unsigned long get_clock_tick_rate(void);
#define PCIBIOS_MIN_IO 0
#define PCIBIOS_MIN_MEM 0
#define pcibios_assign_all_busses() 1
-#define HAVE_ARCH_PCI_SET_DMA_MASK 1
#endif


--
1.5.6.5

2010-02-12 15:01:55

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [PATCH -mm 6/7] arm: use generic pci_set_dma_mask and pci_set_consistent_dma_mask

On Fri, Feb 12, 2010 at 06:33:31PM +0900, FUJITA Tomonori wrote:
> This converts arm to the generic pci_set_dma_mask and
> pci_set_consistent_dma_mask (removes HAVE_ARCH_PCI_SET_DMA_MASK for
> dmabounce).
>
> Signed-off-by: FUJITA Tomonori <[email protected]>
> Cc: Russell King <[email protected]>

This looks like it's right; I don't have any way to test it though
since I don't have the hardware.

Therefore, I'll just give it:

Looked-over-by: Russell King <[email protected]>

since I don't think it warrants Reviewed-by nor Acked-by from me.

2010-02-13 01:09:35

by David Miller

[permalink] [raw]
Subject: Re: [PATCH -mm 1/7] sparc: unify 32bit and 64bit dma_set_mask

From: FUJITA Tomonori <[email protected]>
Date: Fri, 12 Feb 2010 18:33:26 +0900

> sparc has two dma_set_mask implementations for 32bit and 64bit. They
> are same except for the error returned value. We can safely unify them
> since the error returned value doesn't matter as long as it is
> negative (as DMA-API.txt describes).
>
> This patch also changes dma_set_mask not to call
> pci_set_dma_mask. Instead, dma_set_mask does the same thing that
> pci_set_dma_mask does. This change enables ut to change
> pci_set_dma_mask to call dma_set_mask; we can implement
> pci_set_dma_mask as pci-dma-compat.h does.
>
> Signed-off-by: FUJITA Tomonori <[email protected]>

Acked-by: David S. Miller <[email protected]>

2010-02-14 23:34:56

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH -mm 3/7] pci: convert pci_set_dma_mask to call dma_set_mask

On Fri, 2010-02-12 at 18:33 +0900, FUJITA Tomonori wrote:
> This changes pci_set_dma_mask to call the generic DMA API,
> dma_set_mask.
>
> pci_set_dma_mask (in drivers/pci/pci.c) does the same things that
> dma_set_mask does on all the architectures that use pci_set_dma_mask;
> calls dma_supprted and sets dev->dma_mask. So we safely change
> pci_set_dma_mask to simply call dma_set_mask.
>
> Signed-off-by: FUJITA Tomonori <[email protected]>
> Cc: James Bottomley <[email protected]>
> Cc: David S. Miller <[email protected]>
> Cc: Jesse Barnes <[email protected]>

Acked-by: Benjamin Herrenschmidt <[email protected]>

> Cc: Russell King <[email protected]>
> ---
> drivers/pci/pci.c | 10 ++++------
> 1 files changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 315fea4..5c881e9 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -2121,15 +2121,13 @@ void pci_msi_off(struct pci_dev *dev)
> int
> pci_set_dma_mask(struct pci_dev *dev, u64 mask)
> {
> - if (!pci_dma_supported(dev, mask))
> - return -EIO;
> -
> - dev->dma_mask = mask;
> + int ret = dma_set_mask(&dev->dev, mask);
> + if (ret)
> + return ret;
> dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
> -
> return 0;
> }
> -
> +
> int
> pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
> {

2010-02-14 23:36:50

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH -mm 5/7] powerpc: use generic pci_set_dma_mask and pci_set_consistent_dma_mask

On Fri, 2010-02-12 at 18:33 +0900, FUJITA Tomonori wrote:
> This converts powerpc to use the generic pci_set_dma_mask and
> pci_set_consistent_dma_mask (drivers/pci/pci.c).
>
> The generic pci_set_dma_mask does what powerpc's pci_set_dma_mask
> does.
>
> Unlike powerpc's pci_set_consistent_dma_mask, the gneric
> pci_set_consistent_dma_mask sets only coherent_dma_mask. It doesn't
> work for powerpc? pci_set_consistent_dma_mask API should set only
> coherent_dma_mask?

I don't know why we do it that way, your patch looks correct to me, if
we have a driver bug assuming it does both masks at once, then we'll
fix it.

Do you need me to merge that via powerpc.git or are you happy to carry
it with the rest of your PCI DMA changes ?

> Signed-off-by: FUJITA Tomonori <[email protected]>

Acked-by: Benjamin Herrenschmidt <[email protected]>
> ---
> arch/powerpc/include/asm/dma-mapping.h | 3 ---
> arch/powerpc/kernel/pci-common.c | 15 ---------------
> 2 files changed, 0 insertions(+), 18 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
> index 80a973b..c85ef23 100644
> --- a/arch/powerpc/include/asm/dma-mapping.h
> +++ b/arch/powerpc/include/asm/dma-mapping.h
> @@ -127,9 +127,6 @@ static inline int dma_supported(struct device *dev, u64 mask)
> return dma_ops->dma_supported(dev, mask);
> }
>
> -/* We have our own implementation of pci_set_dma_mask() */
> -#define HAVE_ARCH_PCI_SET_DMA_MASK
> -
> static inline int dma_set_mask(struct device *dev, u64 dma_mask)
> {
> struct dma_map_ops *dma_ops = get_dma_ops(dev);
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
> index cadbed6..a8bc6f2 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -63,21 +63,6 @@ struct dma_map_ops *get_pci_dma_ops(void)
> }
> EXPORT_SYMBOL(get_pci_dma_ops);
>
> -int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
> -{
> - return dma_set_mask(&dev->dev, mask);
> -}
> -
> -int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
> -{
> - int rc;
> -
> - rc = dma_set_mask(&dev->dev, mask);
> - dev->dev.coherent_dma_mask = dev->dma_mask;
> -
> - return rc;
> -}
> -
> struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
> {
> struct pci_controller *phb;

2010-02-15 01:58:20

by FUJITA Tomonori

[permalink] [raw]
Subject: Re: [PATCH -mm 5/7] powerpc: use generic pci_set_dma_mask and pci_set_consistent_dma_mask

On Mon, 15 Feb 2010 10:36:40 +1100
Benjamin Herrenschmidt <[email protected]> wrote:

> On Fri, 2010-02-12 at 18:33 +0900, FUJITA Tomonori wrote:
> > This converts powerpc to use the generic pci_set_dma_mask and
> > pci_set_consistent_dma_mask (drivers/pci/pci.c).
> >
> > The generic pci_set_dma_mask does what powerpc's pci_set_dma_mask
> > does.
> >
> > Unlike powerpc's pci_set_consistent_dma_mask, the gneric
> > pci_set_consistent_dma_mask sets only coherent_dma_mask. It doesn't
> > work for powerpc? pci_set_consistent_dma_mask API should set only
> > coherent_dma_mask?
>
> I don't know why we do it that way, your patch looks correct to me, if
> we have a driver bug assuming it does both masks at once, then we'll
> fix it.
>
> Do you need me to merge that via powerpc.git or are you happy to carry
> it with the rest of your PCI DMA changes ?

I guess it's easier if Andrew carries all the patches since some of
the patches in this patchset depend on my other patches in -mm.


> > Signed-off-by: FUJITA Tomonori <[email protected]>
>
> Acked-by: Benjamin Herrenschmidt <[email protected]>

Thanks!

2010-02-15 02:41:37

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [PATCH -mm 5/7] powerpc: use generic pci_set_dma_mask and pci_set_consistent_dma_mask

On Mon, 2010-02-15 at 10:57 +0900, FUJITA Tomonori wrote:
> I guess it's easier if Andrew carries all the patches since some of
> the patches in this patchset depend on my other patches in -mm.

Fine with me.

Cheers,
Ben.