All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Brownell <david-b@pacbell.net>
To: James Bottomley <James.Bottomley@steeleye.com>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] generic device DMA (dma_pool update)
Date: Mon, 30 Dec 2002 15:11:19 -0800	[thread overview]
Message-ID: <3E10D297.1090206@pacbell.net> (raw)
In-Reply-To: 3E0D04DB.1000500@pacbell.net

[-- Attachment #1: Type: text/plain, Size: 1729 bytes --]

  >>> - There's no analogue to pci_pool, and there's nothing like
  >>>   "kmalloc" (likely built from N dma-coherent pools).
  >>
  >> I didn't want to build another memory pool re-implementation.  The
  >> mempool API seems to me to be flexible enough for this, is there some
  >> reason it won't work?
  >
  > I didn't notice any way it would track, and return, DMA addresses.
  > It's much like a kmem_cache in that way.

Here's a patch (against 2.5.53) that does it with current allocators:

- adds new dma_pool calls, implemented by inlines using "kmem_cache_t *"
   (wrapped) or "struct pci_pool *" depending on the arch/config.

        struct dma_pool *dma_pool_create(char *, struct device *, size_t)
        void dma_pool_destroy (struct dma_pool *pool)
        void *dma_pool_alloc(struct dma_pool *, int mem_flags, dma_addr_t *)
        void dma_pool_free(struct dma_pool *, void *, dma_addr_t)

- new kmalloc/kfree style calls, likewise turned by inlines into kmalloc
   or code that can use dma_pool (but can't yet, needs a device dma state
   hook), falling back to dma_alloc_coherent for page allocation otherwise.

        void *dma_alloc(struct device *, size_t, dma_addr_t *, int mem_flags)
        void dma_free(struct device *, size_t, void *, dma_addr_t)

- pci_pool is now arch-specific like the rest of the pci dma calls.
   along with a DMA-API.txt update, this makes 2/3 of this patch. so
   x86 uses dma_pool instead, through <asm-generic/pci-dma-compat.h>

An immediate effect of this patch is that on x86, both USB and Firewire will
do their pci_pool allocations through kmem_cache_t, which is a smarter (and
faster) allocator.  (So would other drivers using pci_pool calls.)

Comments?

- Dave





[-- Attachment #2: dma-1230.patch --]
[-- Type: text/plain, Size: 27449 bytes --]

--- ./include-dist/asm-generic/dma-mapping.h	Wed Dec 25 08:47:40 2002
+++ ./include/asm-generic/dma-mapping.h	Mon Dec 30 11:17:32 2002
@@ -152,5 +152,33 @@
 	BUG();
 }
 
+#ifdef __dma_slab_flags
+/* if we can use the slab allocator, do so.  */
+#include <asm-generic/dma-slab.h>
+
+#else
+
+extern void *
+dma_alloc (struct device *dev, size_t size, dma_addr_t *handle, int mem_flags);
+
+extern void
+dma_free (struct device *dev, size_t size, void *vaddr, dma_addr_t dma);
+
+
+#define dma_pool pci_pool
+
+static inline struct dma_pool *
+dma_pool_create (const char *name, struct device *dev, size_t size)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+	return pci_pool_create(name, to_pci_dev(dev), size, 0, 0);
+}
+
+#define dma_pool_destroy	pci_pool_destroy
+#define dma_pool_alloc		pci_pool_alloc
+#define dma_pool_free		pci_pool_free
+
+#endif
+
 #endif
 
--- ./include-dist/asm-generic/dma-slab.h	Wed Dec 31 16:00:00 1969
+++ ./include/asm-generic/dma-slab.h	Mon Dec 30 10:35:47 2002
@@ -0,0 +1,59 @@
+#ifndef _ASM_GENERIC_DMA_SLAB_H
+#define _ASM_GENERIC_DMA_SLAB_H
+
+/* flags == SLAB_KERNEL or SLAB_ATOMIC */
+static inline void *
+dma_alloc (struct device *dev, size_t size, dma_addr_t *handle, int mem_flags)
+{
+	void	*ret;
+
+	/* We rely on kmalloc memory being aligned to L1_CACHE_BYTES, to
+	 * prevent cacheline sharing during DMA.  With dma-incoherent caches,
+	 * such sharing causes bugs, not just cache-related slowdown.
+	 */
+	ret = kmalloc (size, mem_flags | __dma_slab_flags (dev));
+	if (likely (ret != 0))
+		*handle = virt_to_phys (ret);
+	return ret;
+}
+
+static inline void
+dma_free (struct device *dev, size_t size, void *vaddr, dma_addr_t dma)
+{
+	kfree (vaddr);
+}
+
+
+struct dma_pool {
+	/* these caches are forced to be hw-aligned too */
+	kmem_cache_t 	*cache;
+	struct device	*dev;
+	char		name [0];
+};
+
+extern struct dma_pool *
+dma_pool_create (const char *name, struct device *dev, size_t size);
+
+extern void dma_pool_destroy (struct dma_pool *pool);
+
+
+/* flags == SLAB_KERNEL or SLAB_ATOMIC */
+static inline void *
+dma_pool_alloc (struct dma_pool *pool, int flags, dma_addr_t *handle)
+{
+	void		*ret;
+
+	ret = kmem_cache_alloc (pool->cache, flags);
+	if (likely (ret != 0))
+		*handle = virt_to_phys (ret);
+	return ret;
+}
+
+static inline void
+dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t addr)
+{
+	kmem_cache_free (pool->cache, vaddr);
+}
+
+#endif
+
--- ./include-dist/asm-i386/dma-mapping.h	Wed Dec 25 08:49:09 2002
+++ ./include/asm-i386/dma-mapping.h	Mon Dec 30 13:12:07 2002
@@ -134,4 +134,9 @@
 	flush_write_buffers();
 }
 
+/* use the slab allocator to manage dma buffers */
+#define __dma_slab_flags(dev) \
+	((*(dev)->dma_mask <= 0x00ffffff) ? SLAB_DMA : 0)
+#include <asm-generic/dma-slab.h>
+
 #endif
--- ./include-dist/asm-ppc/dma-mapping.h	Wed Dec 25 08:48:02 2002
+++ ./include/asm-ppc/dma-mapping.h	Mon Dec 30 10:43:51 2002
@@ -1 +1,7 @@
+#ifndef CONFIG_NOT_COHERENT_CACHE
+/* use the slab allocator to manage dma buffers */
+#define __dma_slab_flags(dev) \
+	((*(dev)->dma_mask != 0xffffffff) ? SLAB_DMA : 0)
+#endif
+
 #include <asm-generic/dma-mapping.h>
--- ./include-dist/asm-um/dma-mapping.h	Wed Dec 25 08:49:40 2002
+++ ./include/asm-um/dma-mapping.h	Mon Dec 30 13:25:28 2002
@@ -1 +1,4 @@
+/* use the slab allocator to manage dma buffers */
+#define __dma_slab_flags(dev) 0
+
 #include <asm-generic/dma-mapping.h>
--- ./include-dist/asm-arm/dma-mapping.h	Wed Dec 25 08:48:19 2002
+++ ./include/asm-arm/dma-mapping.h	Mon Dec 30 13:25:36 2002
@@ -1 +1,6 @@
+#ifdef	CONFIG_SA1111
+/* we can just use the slab allocator to manage dma buffers */
+#define __dma_slab_flags(dev) SLAB_DMA
+#endif
+
 #include <asm-generic/dma-mapping.h>
--- ./drivers/base-dist/dma.c	Wed Dec 31 16:00:00 1969
+++ ./drivers/base/dma.c	Mon Dec 30 14:37:46 2002
@@ -0,0 +1,106 @@
+/* the non-inlined support for coherent dma memory buffer calls */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include <asm/io.h>
+#include <asm/scatterlist.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+
+
+#ifdef __dma_slab_flags
+
+/*
+ * Slab memory can be used for DMA buffers on some platforms (including i386).
+ * This implementation is mostly inlined in <asm-generic/dma-slab.h>.
+ */
+
+struct dma_pool *
+dma_pool_create (const char *name, struct device *dev, size_t size)
+{
+	int		tmp;
+	struct dma_pool	*pool;
+
+	tmp = strlen (name);
+	pool = kmalloc (sizeof *pool + tmp + strlen (dev->bus_id) + 2, SLAB_KERNEL);
+	if (!pool)
+		return pool;
+
+	/* bus_id makes the name unique over dev->bus, not globally */
+	memcpy (pool->name, name, tmp);
+	pool->name [tmp] = '/';
+	strcpy (&pool->name [tmp + 1], dev->bus_id);
+
+	tmp = SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN;
+	if (__dma_slab_flags (dev) & SLAB_DMA)
+		tmp |= SLAB_CACHE_DMA;
+
+	pool->cache = kmem_cache_create (pool->name, size, 0, tmp, 0, 0);
+	if (!pool->cache) {
+		kfree (pool);
+		pool = 0;
+	} else
+		pool->dev = get_device (dev);
+	return pool;
+}
+EXPORT_SYMBOL (dma_pool_create);
+
+void dma_pool_destroy (struct dma_pool *pool)
+{
+	kmem_cache_destroy (pool->cache);
+	put_device (pool->dev);
+	kfree (pool);
+}
+EXPORT_SYMBOL (dma_pool_destroy);
+
+#elif	defined (CONFIG_PCI)
+
+#include <linux/pci.h>
+
+/*
+ * Otherwise, assume wrapping pci_pool will do.
+ * This implementation is mostly inlined in <asm-generic/dma-mapping.h>.
+ */
+
+void *
+dma_alloc (struct device *dev, size_t size, dma_addr_t *handle, int mem_flags)
+{
+	struct pci_dev	*pdev = to_pci_dev(dev);
+
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	if (size >= PAGE_SIZE)
+		return pci_alloc_consistent (pdev, size, handle);
+
+	/* FIXME keep N pools of per-device dma state, not just a u64 for the
+	 * dma mask.  allocate from the right pool here.  (unless this platform
+	 * has a pci_alloc_consistent() that does 1/Nth page allocations.)
+	 * and since pci_alloc_consistent can't fail (so must BUG out), it
+	 * might be a good idea to cache a few larger buffers here too.
+	 */
+#warning "broken dma_alloc()"
+
+	return 0;
+}
+EXPORT_SYMBOL (dma_alloc);
+
+void
+dma_free (struct device *dev, size_t size, void *vaddr, dma_addr_t dma)
+{
+	struct pci_dev	*pdev = to_pci_dev(dev);
+
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	pci_free_consistent (pdev, size, vaddr, dma);
+}
+EXPORT_SYMBOL (dma_free);
+
+
+#else
+#error "no dma buffer allocation is available"
+#endif
--- ./drivers/base-dist/Makefile	Wed Dec 25 08:50:00 2002
+++ ./drivers/base/Makefile	Sat Dec 28 11:10:42 2002
@@ -2,7 +2,7 @@
 
 obj-y		:= core.o sys.o interface.o power.o bus.o \
 			driver.o class.o intf.o platform.o \
-			cpu.o firmware.o
+			cpu.o firmware.o dma.o
 
 obj-$(CONFIG_NUMA)	+= node.o  memblk.o
 
@@ -11,4 +11,4 @@
 obj-$(CONFIG_HOTPLUG)	+= hotplug.o
 
 export-objs	:= core.o power.o sys.o bus.o driver.o \
-			class.o intf.o platform.o firmware.o
+			class.o intf.o platform.o firmware.o dma.o
--- ./Documentation-dist/DMA-API.txt	Wed Dec 25 08:54:25 2002
+++ ./Documentation/DMA-API.txt	Mon Dec 30 12:01:37 2002
@@ -5,7 +5,8 @@
 
 This document describes the DMA API.  For a more gentle introduction
 phrased in terms of the pci_ equivalents (and actual examples) see
-DMA-mapping.txt
+DMA-mapping.txt; USB device drivers will normally use the USB DMA
+APIs, see Documentation/usb/dma.txt instead.
 
 This API is split into two pieces.  Part I describes the API and the
 corresponding pci_ API.  Part II describes the extensions to the API
@@ -20,18 +21,31 @@
 To get the pci_ API, you must #include <linux/pci.h>
 To get the dma_ API, you must #include <linux/dma-mapping.h>
 
-void *
-dma_alloc_coherent(struct device *dev, size_t size,
+
+I.A Coherent memory
++++++++++++++++++++
+Coherent memory is memory for which a write by either the device or the
+processor can immediately be read by the other, without having to worry
+about caches losing the write.  Drivers should normally use memory barrier
+instructions to ensure that the device and processor see writes in the
+intended order.  CPUs and compilers commonly re-order reads, unless rmb()
+or mb() is used.  Many also reorder writes unless wmb() or mb() is used.
+
+Just as with normal kernel memory, there are several allocation APIs.
+One talks in terms of pages, another talks in terms of arbitrary sized
+buffers, and another talks in terms of pools of fixed-size blocks.
+
+
+ALLOCATING AND FREEING ONE OR MORE PAGES
+
+	void *
+	dma_alloc_coherent(struct device *dev, size_t size,
 			     dma_addr_t *dma_handle)
-void *
-pci_alloc_consistent(struct pci_dev *dev, size_t size,
+	void *
+	pci_alloc_consistent(struct pci_dev *dev, size_t size,
 			     dma_addr_t *dma_handle)
 
-Consistent memory is memory for which a write by either the device or
-the processor can immediately be read by the processor or device
-without having to worry about caching effects.
-
-This routine allocates a region of <size> bytes of consistent memory.
+This routine allocates a region of <size> bytes of coherent memory.
 it also returns a <dma_handle> which may be cast to an unsigned
 integer the same width as the bus and used as the physical address
 base of the region.
@@ -39,26 +53,113 @@
 Returns: a pointer to the allocated region (in the processor's virtual
 address space) or NULL if the allocation failed.
 
-Note: consistent memory can be expensive on some platforms, and the
+Note: coherent memory can be expensive on some platforms, and the
 minimum allocation length may be as big as a page, so you should
-consolidate your requests for consistent memory as much as possible.
+consolidate your requests for coherent memory as much as possible.
+Or better yet, use the other APIs (below), which handle 1/N page
+allocations as well as N-page allocations.
 
-void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr
+	void
+	dma_free_coherent(struct device *dev, size_t size, void *cpu_addr
 			   dma_addr_t dma_handle)
-void
-pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr
+	void
+	pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr
 			   dma_addr_t dma_handle)
 
-Free the region of consistent memory you previously allocated.  dev,
+Free the region of coherent memory you previously allocated.  dev,
 size and dma_handle must all be the same as those passed into the
-consistent allocate.  cpu_addr must be the virtual address returned by
-the consistent allocate
+coherent allocation.  cpu_addr must be the virtual address returned by
+the coherent allocation.
+
+
+If you are working with coherent memory that's smaller than a page, use the
+pool allocators (for fixed size allocations) or dma_alloc (otherwise).  All
+this memory is aligned to at least L1_CACHE_BYTES, so that cacheline sharing
+can't cause bugs (on systems with cache-incoherent dma) or performance loss
+(on the more widely used systems with cache-coherent DMA).
+
+Note that there is no pci analogue to dma_alloc(), and there's no USB
+analogue to dma pools.
+
+
+ALLOCATING AND FREEING ARBITRARY SIZED BUFFERS
+
+	void *
+	dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+		int mem_flags)
+
+	void
+	dma_free(struct device *dev, void *vaddr, dma_addr_t dma)
+
+These are like kmalloc and kfree, except that since they return dma-coherent
+memory they must also return DMA addresses.  Also, they aren't guaranteed to
+accept mem_flags values other than SLAB_KERNEL and SLAB_ATOMIC.  The allocator
+returns null when it fails for any reason.
+
+
+POOL CREATION AND DESTRUCTION
+
+Device drivers often use pools of coherent memory, along with memory
+barriers, to communicate to devices through request queues.
+
+	struct dma_pool *
+	dma_pool_create(char *name, struct pci_dev *dev, size_t size);
+
+	struct pci_pool *
+	pci_pool_create(char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t alloc)
 
-int
-dma_supported(struct device *dev, u64 mask)
-int
-pci_dma_supported(struct device *dev, u64 mask)
+Pools are like a kmem_cache_t but they work for dma-coherent memory.  They
+must be created (or destroyed) in thread contexts.  For the generic API, use
+'size' to force alignment to bigger boundaries than L1_CACHE_BYTES, and to
+ensure that allocations can't cross 'alloc' byte boundaries.
+
+Returns the pool, or null if one can't be created.
+
+	void
+	dma_pool_destroy(struct dma_pool *pool)
+
+	void
+	pci_pool_destroy(struct pci_pool *pool)
+
+These calls just destroy the pool provided.  The caller guarantees all the
+memory has been returned to the pool, and is not currently in use.
+
+ALLOCATING AND FREEING MEMORY FROM A POOL
+
+	void *
+	dma_pool_alloc(struct dma_pool *pool, int mem_flags, dma_addr_t *handle)
+
+	void *
+	pci_pool_alloc(struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
+
+When allocation succeeds, a pointer to the allocated memory is returned
+and the dma address is stored at the other end of the handle.  "flags"
+can be SLAB_KERNEL or SLAB_ATOMIC, controlling whether it's OK to sleep.
+If allocation fails for any reason, null is returned.
+
+	void *
+	dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
+
+	void *
+	pci_pool_free(struct pci_pool *pool, void *vaddr, dma_addr_t dma)
+
+When your driver is done using memory allocated using the pool allocation
+calls, pass both of the memory addresses to the free() routine.
+
+
+I.B DMA masks
++++++++++++++
+Hardware often has limitations in the DMA address space it supports.
+Some common examples are x86 ISA addresses, in the first 16 MBytes of
+PC address space, and "highmem" I/O, over the 4 GB mark.  The coherent
+memory allocators will never return "highmem" pointers.
+
+	int
+	dma_supported(struct device *dev, u64 mask)
+
+	int
+	pci_dma_supported(struct device *dev, u64 mask)
 
 Checks to see if the device can support DMA to the memory described by
 mask.
@@ -70,21 +171,31 @@
 internal API for use by the platform than an external API for use by
 driver writers.
 
-int
-dma_set_mask(struct device *dev, u64 mask)
-int
-pci_dma_set_mask(struct pci_device *dev, u64 mask)
+	int
+	dma_set_mask(struct device *dev, u64 mask)
+
+	int
+	pci_dma_set_mask(struct pci_device *dev, u64 mask)
 
 Checks to see if the mask is possible and updates the device
 parameters if it is.
 
 Returns: 1 if successful and 0 if not
 
-dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+
+I.C DMA mappings
+++++++++++++++++
+To work with arbitrary DMA-ready memory, you need to map it into the DMA
+address space of the device.  This might involve an IOMMU or a bounce buffer.
+The two kinds of mapping are  flat "single" mappings, sometimes for single
+pages; and grouped "scatter/gather" ones.  If you're not using the mappings
+for one-shot I/O, you may also need to synchronize the mappings.
+
+	dma_addr_t
+	dma_map_single(struct device *dev, void *cpu_addr, size_t size,
 		      enum dma_data_direction direction)
-dma_addr_t
-pci_map_single(struct device *dev, void *cpu_addr, size_t size,
+	dma_addr_t
+	pci_map_single(struct device *dev, void *cpu_addr, size_t size,
 		      int direction)
 
 Maps a piece of processor virtual memory so it can be accessed by the
--- ./include-dist/linux/pci.h	Wed Dec 25 08:48:53 2002
+++ ./include/linux/pci.h	Mon Dec 30 12:47:36 2002
@@ -672,14 +672,6 @@
 struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
 
-/* kmem_cache style wrapper around pci_alloc_consistent() */
-struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
-		size_t size, size_t align, size_t allocation);
-void pci_pool_destroy (struct pci_pool *pool);
-
-void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
-void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
-
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
 extern struct pci_dev *isa_bridge;
 #endif
--- ./include-dist/asm-generic/pci-dma-compat.h	Wed Dec 25 08:47:40 2002
+++ ./include/asm-generic/pci-dma-compat.h	Mon Dec 30 13:14:41 2002
@@ -35,6 +35,39 @@
 	return dma_map_single(&hwdev->dev, ptr, size, (enum dma_data_direction)direction);
 }
 
+static inline struct pci_pool *
+pci_pool_create (const char *name, struct pci_dev *hwdev,
+		size_t size, size_t align, size_t allocation)
+{
+	if (size < align)
+		size = align;
+	if (allocation) {
+		while (align < allocation && (allocation % size) != 0) {
+			align <<= 1;
+			if (size < align)
+				size = align;
+		}
+	}
+	return (struct pci_pool *) dma_pool_create(name, &hwdev->dev, size);
+}
+
+static inline void pci_pool_destroy (struct pci_pool *pool)
+{
+	dma_pool_destroy ((struct dma_pool *) pool);
+}
+
+static inline void *
+pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle)
+{
+	return dma_pool_alloc((struct dma_pool *) pool, flags, handle);
+}
+
+static inline void
+pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr)
+{
+	return dma_pool_free((struct dma_pool *) pool, vaddr, addr);
+}
+
 static inline void
 pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
 		 size_t size, int direction)
--- ./drivers/pci-dist/pool.c	Wed Dec 25 08:51:41 2002
+++ ./drivers/pci/pool.c	Mon Dec 30 12:51:57 2002
@@ -2,6 +2,8 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 
+#ifndef __dma_slab_flags
+
 /*
  * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
  * small blocks are easily used by drivers for bus mastering controllers.
@@ -403,3 +405,5 @@
 EXPORT_SYMBOL (pci_pool_destroy);
 EXPORT_SYMBOL (pci_pool_alloc);
 EXPORT_SYMBOL (pci_pool_free);
+
+#endif /* !__dma_slab_flags */
--- ./include-dist/asm-alpha/pci.h	Wed Dec 25 08:49:02 2002
+++ ./include/asm-alpha/pci.h	Mon Dec 30 12:35:11 2002
@@ -81,6 +81,14 @@
 
 extern void pci_free_consistent(struct pci_dev *, size_t, void *, dma_addr_t);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /* 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
--- ./include-dist/asm-arm/pci.h	Wed Dec 25 08:48:18 2002
+++ ./include/asm-arm/pci.h	Mon Dec 30 12:35:29 2002
@@ -76,6 +76,14 @@
 	consistent_free(vaddr, size, dma_handle);
 }
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /* Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
  *
--- ./include-dist/asm-ia64/pci.h	Wed Dec 25 08:47:47 2002
+++ ./include/asm-ia64/pci.h	Mon Dec 30 12:36:21 2002
@@ -58,6 +58,14 @@
 #define sg_dma_address			platform_pci_dma_address
 #define pci_dma_supported		platform_pci_dma_supported
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /* pci_unmap_{single,page} is not a nop, thus... */
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
 	dma_addr_t ADDR_NAME;
--- ./include-dist/asm-mips/pci.h	Wed Dec 25 08:48:27 2002
+++ ./include/asm-mips/pci.h	Mon Dec 30 12:36:52 2002
@@ -77,6 +77,14 @@
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /*
  * Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
--- ./include-dist/asm-mips64/pci.h	Wed Dec 25 08:49:31 2002
+++ ./include/asm-mips64/pci.h	Mon Dec 30 12:37:04 2002
@@ -70,6 +70,14 @@
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 
 #ifdef CONFIG_MAPPED_PCI_IO
 
--- ./include-dist/asm-parisc/pci.h	Wed Dec 25 08:48:31 2002
+++ ./include/asm-parisc/pci.h	Mon Dec 30 12:37:26 2002
@@ -146,6 +146,14 @@
 	void (*dma_sync_sg)(struct pci_dev *dev, struct scatterlist *sg, int nelems, int direction);
 };
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 
 /*
 ** We could live without the hppa_dma_ops indirection if we didn't want
--- ./include-dist/asm-ppc/pci.h	Wed Dec 25 08:48:02 2002
+++ ./include/asm-ppc/pci.h	Mon Dec 30 12:37:45 2002
@@ -91,6 +91,14 @@
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /* Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
  *
--- ./include-dist/asm-ppc64/pci.h	Wed Dec 25 08:47:38 2002
+++ ./include/asm-ppc64/pci.h	Mon Dec 30 12:37:53 2002
@@ -43,6 +43,14 @@
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
 				 size_t size, int direction);
 extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
--- ./include-dist/asm-sh/pci.h	Wed Dec 25 08:49:37 2002
+++ ./include/asm-sh/pci.h	Mon Dec 30 12:38:03 2002
@@ -71,6 +71,14 @@
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /* Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
  *
--- ./include-dist/asm-sparc/pci.h	Wed Dec 25 08:49:17 2002
+++ ./include/asm-sparc/pci.h	Mon Dec 30 12:38:13 2002
@@ -47,6 +47,14 @@
  */
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /* Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
  *
--- ./include-dist/asm-sparc64/pci.h	Wed Dec 25 08:49:25 2002
+++ ./include/asm-sparc64/pci.h	Mon Dec 30 12:38:21 2002
@@ -55,6 +55,14 @@
  */
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 /* Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
  *
--- ./include-dist/asm-v850/pci.h	Wed Dec 25 08:49:46 2002
+++ ./include/asm-v850/pci.h	Mon Dec 30 12:38:36 2002
@@ -74,4 +74,12 @@
 pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
 		     dma_addr_t dma_addr);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 #endif /* __V850_PCI_H__ */
--- ./include-dist/asm-x86_64/pci.h	Wed Dec 25 08:47:55 2002
+++ ./include/asm-x86_64/pci.h	Mon Dec 30 12:40:43 2002
@@ -69,6 +69,14 @@
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 
+/* kmem_cache style wrapper around pci_alloc_consistent() */
+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
+		size_t size, size_t align, size_t allocation);
+void pci_pool_destroy (struct pci_pool *pool);
+
+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
+
 #ifdef CONFIG_GART_IOMMU
 
 /* Map a single buffer of the indicated size for DMA in streaming mode.

  parent reply	other threads:[~2002-12-30 22:57 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-12-27 20:21 [RFT][PATCH] generic device DMA implementation David Brownell
2002-12-27 21:40 ` James Bottomley
2002-12-28  1:29   ` David Brownell
2002-12-28 16:18     ` James Bottomley
2002-12-28 18:16       ` David Brownell
2002-12-28  1:56   ` David Brownell
2002-12-28 16:13     ` James Bottomley
2002-12-28 17:41       ` David Brownell
2002-12-30 23:11     ` David Brownell [this message]
2002-12-31 15:00       ` [PATCH] generic device DMA (dma_pool update) James Bottomley
2002-12-31 17:04         ` David Brownell
2002-12-31 17:23           ` James Bottomley
2002-12-31 18:11             ` David Brownell
2002-12-31 18:44               ` James Bottomley
2002-12-31 19:29                 ` David Brownell
2002-12-31 19:50                   ` James Bottomley
2002-12-31 21:17                     ` David Brownell
2002-12-31 16:36       ` James Bottomley
2002-12-31 17:32         ` David Brownell
2002-12-27 21:47 ` [RFT][PATCH] generic device DMA implementation James Bottomley
2002-12-28  2:28   ` David Brownell
  -- strict thread matches above, loose matches on Subject: below --
2002-12-31 22:02 [PATCH] generic device DMA (dma_pool update) Adam J. Richter
2002-12-31 22:41 ` Andrew Morton
2002-12-31 23:23   ` David Brownell
2002-12-31 23:27     ` Andrew Morton
2002-12-31 23:44       ` David Brownell
2002-12-31 23:47     ` James Bottomley
2003-01-01 17:10   ` James Bottomley
2002-12-31 23:35 ` David Brownell
2002-12-31 23:38 Adam J. Richter
2003-01-01  0:02 Adam J. Richter
2003-01-01 19:21 Adam J. Richter
2003-01-01 19:48 ` James Bottomley
2003-01-02  2:11   ` David Brownell
2003-01-02  4:13 Adam J. Richter
2003-01-02 16:41 ` James Bottomley
2003-01-02 18:26 ` David Brownell
2003-01-02 17:04 Adam J. Richter
2003-01-02 22:07 Adam J. Richter
2003-01-03  0:20 ` Russell King
2003-01-03  4:50 ` David Brownell
2003-01-03  6:11 ` David Brownell
2003-01-03  6:46 ` David Brownell
2003-01-03  6:52   ` William Lee Irwin III

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=3E10D297.1090206@pacbell.net \
    --to=david-b@pacbell.net \
    --cc=James.Bottomley@steeleye.com \
    --cc=linux-kernel@vger.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.