linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] Wean NCR_Q720 off the dma_declare_coherent_memory interface
@ 2007-10-30 19:43 Matthew Wilcox
  2007-10-30 19:43 ` [PATCH 2/2] Remove dma_coherent_mem interface Matthew Wilcox
  0 siblings, 1 reply; 5+ messages in thread
From: Matthew Wilcox @ 2007-10-30 19:43 UTC (permalink / raw)
  To: linux-arch, tglx, mingo, hpa, linux-scsi, jejb
  Cc: Matthew Wilcox, Matthew Wilcox

By restructuring the ncr53c8xx driver a little, we can provide
the same functionality as the dma_declare_coherent_memory interface
without touching the generic dma paths.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
---
 drivers/scsi/NCR_Q720.c  |   45 ++++++++-----------
 drivers/scsi/ncr53c8xx.c |  113 +++++++++++++++++++++++++++++++++++++---------
 drivers/scsi/ncr53c8xx.h |   13 +++++
 3 files changed, 124 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c
index a8bbdc2..8db20a6 100644
--- a/drivers/scsi/NCR_Q720.c
+++ b/drivers/scsi/NCR_Q720.c
@@ -36,9 +36,10 @@ MODULE_LICENSE("GPL");
 
 #define NCR_Q720_VERSION		"0.9"
 
-/* We needs this helper because we have up to four hosts per struct device */
+/* We have up to four hosts per struct device */
 struct NCR_Q720_private {
 	struct device		*dev;
+	struct ncr_mem		ncr_mem;
 	void __iomem *		mem_base;
 	__u32			phys_mem_base;
 	__u32			mem_size;
@@ -105,6 +106,7 @@ NCR_Q720_probe_one(struct NCR_Q720_private *p, int siop,
 	device.slot.base_v	= vaddr;
 	device.slot.irq		= irq;
 	device.differential	= differential ? 2 : 0;
+	device.ncr_mem		= &p->ncr_mem;
 	printk("Q720 probe unit %d (siop%d) at 0x%lx, diff = %d, vers = %d\n", unit, siop,
 	       (unsigned long)paddr, differential, version);
 
@@ -214,28 +216,21 @@ NCR_Q720_probe(struct device *dev)
 		       (unsigned long)(base_addr + mem_size));
 		goto out_free;
 	}
-	
-	if (dma_declare_coherent_memory(dev, base_addr, base_addr,
-					mem_size, DMA_MEMORY_MAP)
-	    != DMA_MEMORY_MAP) {
-		printk(KERN_ERR "NCR_Q720: DMA declare memory failed\n");
-		goto out_release_region;
-	}
 
-	/* The first 1k of the memory buffer is a memory map of the registers
-	 */
-	mem_base = dma_mark_declared_memory_occupied(dev, base_addr,
-							    1024);
-	if (IS_ERR(mem_base)) {
-		printk("NCR_Q720 failed to reserve memory mapped region\n");
-		goto out_release;
-	}
+	mem_base = ioremap(base_addr, mem_size);
+	if (!mem_base)
+		goto out_free;
+
+	p->ncr_mem.virt_base = mem_base;
+	p->ncr_mem.device_base = base_addr;
+	ncr_declare_coherent_memory(&p->ncr_mem, mem_size);
+
+	/* The first 1k of the memory buffer are the registers */
+	ncr_reserve_declared_memory(&p->ncr_mem, 0, 1024);
 
 	/* now also enable accesses in asr 2 */
 	asr2 = inb(io_base + 0x0a);
-
 	asr2 |= 0x01;
-
 	outb(asr2, io_base + 0x0a);
 
 	/* get the number of SIOPs (this should be 2 or 4) */
@@ -250,7 +245,6 @@ NCR_Q720_probe(struct device *dev)
 
 	irq = readb(mem_base + 5) & 0x0f;
 	
-	
 	/* now do the bus related transforms */
 	irq = mca_device_transform_irq(mca_dev, irq);
 
@@ -297,10 +291,8 @@ NCR_Q720_probe(struct device *dev)
 			found++;
 	}
 
-	if (!found) {
-		kfree(p);
-		return -ENODEV;
-	}
+	if (!found)
+		goto out_release;
 
 	mca_device_set_claim(mca_dev, 1);
 	mca_device_set_name(mca_dev, "NCR_Q720");
@@ -309,8 +301,8 @@ NCR_Q720_probe(struct device *dev)
 	return 0;
 
  out_release:
-	dma_release_declared_memory(dev);
- out_release_region:
+	ncr_release_declared_memory(&p->ncr_mem);
+	iounmap(mem_base);
 	release_mem_region(base_addr, mem_size);
  out_free:
 	kfree(p);
@@ -335,7 +327,8 @@ NCR_Q720_remove(struct device *dev)
 		if(p->hosts[i])
 			NCR_Q720_remove_one(p->hosts[i]);
 
-	dma_release_declared_memory(dev);
+	ncr_release_declared_memory(&p->ncr_mem);
+	iounmap(p->ncr_mem.virt_base);
 	release_mem_region(p->phys_mem_base, p->mem_size);
 	free_irq(p->irq, p);
 	kfree(p);
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index 016c462..149a42b 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -128,6 +128,14 @@
 
 #define NAME53C8XX		"ncr53c8xx"
 
+/* Linux host data structure */
+
+struct host_data {
+	struct ncb *ncb;
+	struct ncr_mem *ncr_mem;
+	struct device *dev;
+};
+
 /*==========================================================
 **
 **	Debugging tags
@@ -172,6 +180,74 @@ static inline struct list_head *ncr_list_pop(struct list_head *head)
 	return NULL;
 }
 
+/*
+ * Support the onboard memory on the NCR Q720
+ *
+ * XXX: This is only coherent because it's only present on x86.
+ */
+
+int ncr_declare_coherent_memory(struct ncr_mem *mem, unsigned size)
+{
+	int pages = size >> PAGE_SHIFT;
+	int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
+
+	mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+	if (!mem->bitmap)
+		return -ENOMEM;
+
+	mem->size = pages;
+	return 0;
+}
+EXPORT_SYMBOL(ncr_declare_coherent_memory);
+
+void ncr_release_declared_memory(struct ncr_mem *mem)
+{
+	kfree(mem->bitmap);
+}
+EXPORT_SYMBOL(ncr_release_declared_memory);
+
+void ncr_reserve_declared_memory(struct ncr_mem *mem, unsigned start,
+								unsigned len)
+{
+	int pages = (start & ~PAGE_MASK) + len + PAGE_SIZE - 1;
+	start >>= PAGE_SHIFT;
+	bitmap_allocate_region(mem->bitmap, start, get_order(pages));
+}
+EXPORT_SYMBOL(ncr_reserve_declared_memory);
+
+static void *ncr_alloc_coherent(struct host_data *hd, size_t size,
+					dma_addr_t *dma_handle, gfp_t gfp)
+{
+	struct ncr_mem *mem = hd->ncr_mem;
+	if (mem) { 
+		unsigned order = get_order(size);
+		int page = bitmap_find_free_region(mem->bitmap,
+						mem->size, order);
+		if (page >= 0) {
+			void *addr = mem->virt_base + (page << PAGE_SHIFT);
+			*dma_handle = mem->device_base + (page << PAGE_SHIFT);
+			memset(addr, 0, size);
+			return addr;
+		}
+	}
+
+	return dma_alloc_coherent(hd->dev, size, dma_handle, gfp);
+}
+
+static void ncr_free_coherent(struct host_data *hd, size_t size,
+			void *vaddr, dma_addr_t dma_handle)
+{
+	struct ncr_mem *mem = hd->ncr_mem;
+	if (mem && (vaddr >= mem->virt_base) &&
+	    (vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT)))) {
+		unsigned order = get_order(size);
+		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
+		bitmap_release_region(mem->bitmap, page, order);
+	} else {
+		dma_free_coherent(hd->dev, size, vaddr, dma_handle);
+	}
+}
+
 /*==========================================================
 **
 **	Simple power of two buddy-like allocator.
@@ -204,7 +280,7 @@ static inline struct list_head *ncr_list_pop(struct list_head *head)
 #define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
 
 typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
-typedef struct device *m_bush_t;	/* Something that addresses DMAable */
+typedef struct host_data *m_bush_t;	/* Something that addresses DMAable */
 
 typedef struct m_link {		/* Link between free memory chunks */
 	struct m_link *next;
@@ -388,7 +464,7 @@ static m_addr_t ___dma_getp(m_pool_s *mp)
 	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
 	if (vbp) {
 		dma_addr_t daddr;
-		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
+		vp = (m_addr_t) ncr_alloc_coherent(mp->bush,
 						PAGE_SIZE<<MEMO_PAGE_ORDER,
 						&daddr, GFP_ATOMIC);
 		if (vp) {
@@ -417,7 +493,7 @@ static void ___dma_freep(m_pool_s *mp, m_addr_t m)
 	if (*vbpp) {
 		vbp = *vbpp;
 		*vbpp = (*vbpp)->next;
-		dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
+		ncr_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
 				  (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
 		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
 		--mp->nump;
@@ -510,11 +586,11 @@ static m_addr_t __vtobus(m_bush_t bush, void *m)
 	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
 }
 
-#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)
-#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)
+#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->hd, s, n)
+#define _m_free_dma(np, p, s, n)	__m_free_dma(np->hd, p, s, n)
 #define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
 #define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
-#define _vtobus(np, p)			__vtobus(np->dev, p)
+#define _vtobus(np, p)			__vtobus(np->hd, p)
 #define vtobus(p)			_vtobus(np, p)
 
 /*
@@ -525,7 +601,7 @@ static m_addr_t __vtobus(m_bush_t bush, void *m)
 #define __data_mapped	SCp.phase
 #define __data_mapping	SCp.have_data_in
 
-static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
+static void __unmap_scsi_data(struct scsi_cmnd *cmd)
 {
 	switch(cmd->__data_mapped) {
 	case 2:
@@ -535,7 +611,7 @@ static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
 	cmd->__data_mapped = 0;
 }
 
-static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
+static int __map_scsi_sg_data(struct scsi_cmnd *cmd)
 {
 	int use_sg;
 
@@ -549,8 +625,8 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
 	return use_sg;
 }
 
-#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)
-#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)
+#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(cmd)
+#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(cmd)
 
 /*==========================================================
 **
@@ -1679,7 +1755,8 @@ struct ncb {
 	**	General controller parameters and configuration.
 	**----------------------------------------------------------------
 	*/
-	struct device	*dev;
+	struct host_data *hd;
+
 	u_char		revision_id;	/* PCI device revision id	*/
 	u32		irq;		/* IRQ level			*/
 	u32		features;	/* Chip features map		*/
@@ -3666,14 +3743,6 @@ ncr_script_copy_and_bind (struct ncb *np, ncrcmd *src, ncrcmd *dst, int len)
 	}
 }
 
-/*
-**	Linux host data structure
-*/
-
-struct host_data {
-     struct ncb *ncb;
-};
-
 #define PRINT_ADDR(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg)
 
 static void ncr_print_msg(struct ccb *cp, char *label, u_char *msg)
@@ -8324,12 +8393,14 @@ struct Scsi_Host * __init ncr_attach(struct scsi_host_template *tpnt,
 	if (!instance)
 	        goto attach_error;
 	host_data = (struct host_data *) instance->hostdata;
+	host_data->dev = device->dev;
+	host_data->ncr_mem = device->ncr_mem;
 
-	np = __m_calloc_dma(device->dev, sizeof(struct ncb), "NCB");
+	np = __m_calloc_dma(host_data, sizeof(struct ncb), "NCB");
 	if (!np)
 		goto attach_error;
 	spin_lock_init(&np->smp_lock);
-	np->dev = device->dev;
+	np->hd = host_data;
 	np->p_ncb = vtobus(np);
 	host_data->ncb = np;
 
diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h
index 0e008da..23d2f6c 100644
--- a/drivers/scsi/ncr53c8xx.h
+++ b/drivers/scsi/ncr53c8xx.h
@@ -1314,6 +1314,7 @@ struct ncr_slot {
 */
 struct ncr_device {
 	struct device  *dev;
+	struct ncr_mem *ncr_mem;
 	struct ncr_slot  slot;
 	struct ncr_chip  chip;
 	u_char host_id;
@@ -1326,4 +1327,16 @@ irqreturn_t ncr53c8xx_intr(int irq, void *dev_id);
 extern int ncr53c8xx_init(void);
 extern void ncr53c8xx_exit(void);
 
+struct ncr_mem {
+	void *virt_base;
+	unsigned long *bitmap;
+	dma_addr_t device_base;
+	int size;
+};
+
+extern int ncr_declare_coherent_memory(struct ncr_mem *mem, unsigned size);
+extern void ncr_release_declared_memory(struct ncr_mem *mem);
+extern void ncr_reserve_declared_memory(struct ncr_mem *mem, unsigned start,
+					unsigned len);
+
 #endif /* NCR53C8XX_H */
-- 
1.5.3.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] Remove dma_coherent_mem interface
  2007-10-30 19:43 [PATCH 1/2] Wean NCR_Q720 off the dma_declare_coherent_memory interface Matthew Wilcox
@ 2007-10-30 19:43 ` Matthew Wilcox
  2007-10-30 20:26   ` James Bottomley
  0 siblings, 1 reply; 5+ messages in thread
From: Matthew Wilcox @ 2007-10-30 19:43 UTC (permalink / raw)
  To: linux-arch, tglx, mingo, hpa, linux-scsi, jejb
  Cc: Matthew Wilcox, Matthew Wilcox

This interface only had one user (and two implementations).
It complicates other work, so remove it.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
---
 Documentation/DMA-API.txt             |   78 ------------------------
 Documentation/driver-model/devres.txt |    1 -
 arch/cris/arch-v32/drivers/pci/dma.c  |  106 +--------------------------------
 arch/x86/kernel/pci-dma_32.c          |  108 +--------------------------------
 drivers/base/dma-mapping.c            |   55 -----------------
 include/asm-cris/dma-mapping.h        |   14 ----
 include/asm-mips/dma-mapping.h        |   10 ---
 include/asm-x86/dma-mapping_32.h      |   12 ----
 include/linux/device.h                |    2 -
 include/linux/dma-mapping.h           |   39 ------------
 10 files changed, 2 insertions(+), 423 deletions(-)

diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index b939ebb..9cebf5b 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -469,81 +469,3 @@ 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.
-
-int
-dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-			    dma_addr_t device_addr, size_t size, int
-			    flags)
-
-Declare region of memory to be handed out by dma_alloc_coherent when
-it's asked for coherent memory for this device.
-
-bus_addr is the physical address to which the memory is currently
-assigned in the bus responding region (this will be used by the
-platform to perform the mapping).
-
-device_addr is the physical address the device needs to be programmed
-with actually to address this memory (this will be handed out as the
-dma_addr_t in dma_alloc_coherent()).
-
-size is the size of the area (must be multiples of PAGE_SIZE).
-
-flags can be or'd together and are:
-
-DMA_MEMORY_MAP - request that the memory returned from
-dma_alloc_coherent() be directly writable.
-
-DMA_MEMORY_IO - request that the memory returned from
-dma_alloc_coherent() be addressable using read/write/memcpy_toio etc.
-
-One or both of these flags must be present.
-
-DMA_MEMORY_INCLUDES_CHILDREN - make the declared memory be allocated by
-dma_alloc_coherent of any child devices of this one (for memory residing
-on a bridge).
-
-DMA_MEMORY_EXCLUSIVE - only allocate memory from the declared regions. 
-Do not allow dma_alloc_coherent() to fall back to system memory when
-it's out of memory in the declared region.
-
-The return value will be either DMA_MEMORY_MAP or DMA_MEMORY_IO and
-must correspond to a passed in flag (i.e. no returning DMA_MEMORY_IO
-if only DMA_MEMORY_MAP were passed in) for success or zero for
-failure.
-
-Note, for DMA_MEMORY_IO returns, all subsequent memory returned by
-dma_alloc_coherent() may no longer be accessed directly, but instead
-must be accessed using the correct bus functions.  If your driver
-isn't prepared to handle this contingency, it should not specify
-DMA_MEMORY_IO in the input flags.
-
-As a simplification for the platforms, only *one* such region of
-memory may be declared per device.
-
-For reasons of efficiency, most platforms choose to track the declared
-region only at the granularity of a page.  For smaller allocations,
-you should use the dma_pool() API.
-
-void
-dma_release_declared_memory(struct device *dev)
-
-Remove the memory region previously declared from the system.  This
-API performs *no* in-use checking for this region and will return
-unconditionally having removed all the required structures.  It is the
-driver's job to ensure that no parts of this memory region are
-currently in use.
-
-void *
-dma_mark_declared_memory_occupied(struct device *dev,
-				  dma_addr_t device_addr, size_t size)
-
-This is used to occupy specific regions of the declared space
-(dma_alloc_coherent() will hand out the first free region it finds).
-
-device_addr is the *device* address of the region requested.
-
-size is the size (and should be a page-sized multiple).
-
-The return value will be either a pointer to the processor virtual
-address of the memory, or an error (via PTR_ERR()) if any part of the
-region is occupied.
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 387b8a7..24d74e9 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -248,7 +248,6 @@ DMA
   dmam_free_coherent()
   dmam_alloc_noncoherent()
   dmam_free_noncoherent()
-  dmam_declare_coherent_memory()
   dmam_pool_create()
   dmam_pool_destroy()
 
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
index 66f9500..88954fd 100644
--- a/arch/cris/arch-v32/drivers/pci/dma.c
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -15,36 +15,14 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 
-struct dma_coherent_mem {
-	void		*virt_base;
-	u32		device_base;
-	int		size;
-	int		flags;
-	unsigned long	*bitmap;
-};
-
 void *dma_alloc_coherent(struct device *dev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret;
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
 	int order = get_order(size);
 	/* ignore region specifiers */
 	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
-	if (mem) {
-		int page = bitmap_find_free_region(mem->bitmap, mem->size,
-						     order);
-		if (page >= 0) {
-			*dma_handle = mem->device_base + (page << PAGE_SHIFT);
-			ret = mem->virt_base + (page << PAGE_SHIFT);
-			memset(ret, 0, size);
-			return ret;
-		}
-		if (mem->flags & DMA_MEMORY_EXCLUSIVE)
-			return NULL;
-	}
-
 	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 
@@ -60,88 +38,6 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 void dma_free_coherent(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
 {
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
 	int order = get_order(size);
-
-	if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
-		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
-
-		bitmap_release_region(mem->bitmap, page, order);
-	} else
-		free_pages((unsigned long)vaddr, order);
-}
-
-int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-				dma_addr_t device_addr, size_t size, int flags)
-{
-	void __iomem *mem_base;
-	int pages = size >> PAGE_SHIFT;
-	int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
-
-	if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
-		goto out;
-	if (!size)
-		goto out;
-	if (dev->dma_mem)
-		goto out;
-
-	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
-
-	mem_base = ioremap(bus_addr, size);
-	if (!mem_base)
-		goto out;
-
-	dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
-	if (!dev->dma_mem)
-		goto out;
-	dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!dev->dma_mem->bitmap)
-		goto free1_out;
-
-	dev->dma_mem->virt_base = mem_base;
-	dev->dma_mem->device_base = device_addr;
-	dev->dma_mem->size = pages;
-	dev->dma_mem->flags = flags;
-
-	if (flags & DMA_MEMORY_MAP)
-		return DMA_MEMORY_MAP;
-
-	return DMA_MEMORY_IO;
-
- free1_out:
-	kfree(dev->dma_mem);
- out:
-	return 0;
-}
-EXPORT_SYMBOL(dma_declare_coherent_memory);
-
-void dma_release_declared_memory(struct device *dev)
-{
-	struct dma_coherent_mem *mem = dev->dma_mem;
-
-	if(!mem)
-		return;
-	dev->dma_mem = NULL;
-	iounmap(mem->virt_base);
-	kfree(mem->bitmap);
-	kfree(mem);
-}
-EXPORT_SYMBOL(dma_release_declared_memory);
-
-void *dma_mark_declared_memory_occupied(struct device *dev,
-					dma_addr_t device_addr, size_t size)
-{
-	struct dma_coherent_mem *mem = dev->dma_mem;
-	int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	int pos, err;
-
-	if (!mem)
-		return ERR_PTR(-EINVAL);
-
-	pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
-	err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
-	if (err != 0)
-		return ERR_PTR(err);
-	return mem->virt_base + (pos << PAGE_SHIFT);
+	free_pages((unsigned long)vaddr, order);
 }
-EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index 5133032..028cbd5 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -14,36 +14,13 @@
 #include <linux/module.h>
 #include <asm/io.h>
 
-struct dma_coherent_mem {
-	void		*virt_base;
-	u32		device_base;
-	int		size;
-	int		flags;
-	unsigned long	*bitmap;
-};
-
 void *dma_alloc_coherent(struct device *dev, size_t size,
 			   dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret;
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
 	int order = get_order(size);
 	/* ignore region specifiers */
 	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
-	if (mem) {
-		int page = bitmap_find_free_region(mem->bitmap, mem->size,
-						     order);
-		if (page >= 0) {
-			*dma_handle = mem->device_base + (page << PAGE_SHIFT);
-			ret = mem->virt_base + (page << PAGE_SHIFT);
-			memset(ret, 0, size);
-			return ret;
-		}
-		if (mem->flags & DMA_MEMORY_EXCLUSIVE)
-			return NULL;
-	}
-
 	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 
@@ -60,96 +37,13 @@ EXPORT_SYMBOL(dma_alloc_coherent);
 void dma_free_coherent(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
 {
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
 	int order = get_order(size);
 
 	WARN_ON(irqs_disabled());	/* for portability */
-	if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
-		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
-
-		bitmap_release_region(mem->bitmap, page, order);
-	} else
-		free_pages((unsigned long)vaddr, order);
+	free_pages((unsigned long)vaddr, order);
 }
 EXPORT_SYMBOL(dma_free_coherent);
 
-int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-				dma_addr_t device_addr, size_t size, int flags)
-{
-	void __iomem *mem_base = NULL;
-	int pages = size >> PAGE_SHIFT;
-	int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
-
-	if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
-		goto out;
-	if (!size)
-		goto out;
-	if (dev->dma_mem)
-		goto out;
-
-	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
-
-	mem_base = ioremap(bus_addr, size);
-	if (!mem_base)
-		goto out;
-
-	dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
-	if (!dev->dma_mem)
-		goto out;
-	dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!dev->dma_mem->bitmap)
-		goto free1_out;
-
-	dev->dma_mem->virt_base = mem_base;
-	dev->dma_mem->device_base = device_addr;
-	dev->dma_mem->size = pages;
-	dev->dma_mem->flags = flags;
-
-	if (flags & DMA_MEMORY_MAP)
-		return DMA_MEMORY_MAP;
-
-	return DMA_MEMORY_IO;
-
- free1_out:
-	kfree(dev->dma_mem);
- out:
-	if (mem_base)
-		iounmap(mem_base);
-	return 0;
-}
-EXPORT_SYMBOL(dma_declare_coherent_memory);
-
-void dma_release_declared_memory(struct device *dev)
-{
-	struct dma_coherent_mem *mem = dev->dma_mem;
-	
-	if(!mem)
-		return;
-	dev->dma_mem = NULL;
-	iounmap(mem->virt_base);
-	kfree(mem->bitmap);
-	kfree(mem);
-}
-EXPORT_SYMBOL(dma_release_declared_memory);
-
-void *dma_mark_declared_memory_occupied(struct device *dev,
-					dma_addr_t device_addr, size_t size)
-{
-	struct dma_coherent_mem *mem = dev->dma_mem;
-	int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	int pos, err;
-
-	if (!mem)
-		return ERR_PTR(-EINVAL);
-
-	pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
-	err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
-	if (err != 0)
-		return ERR_PTR(err);
-	return mem->virt_base + (pos << PAGE_SHIFT);
-}
-EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
-
 #ifdef CONFIG_PCI
 /* Many VIA bridges seem to corrupt data for DAC. Disable it here */
 
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index ca9186f..7778ef7 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -161,58 +161,3 @@ void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr,
 				&match_data));
 }
 EXPORT_SYMBOL(dmam_free_noncoherent);
-
-#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-
-static void dmam_coherent_decl_release(struct device *dev, void *res)
-{
-	dma_release_declared_memory(dev);
-}
-
-/**
- * dmam_declare_coherent_memory - Managed dma_declare_coherent_memory()
- * @dev: Device to declare coherent memory for
- * @bus_addr: Bus address of coherent memory to be declared
- * @device_addr: Device address of coherent memory to be declared
- * @size: Size of coherent memory to be declared
- * @flags: Flags
- *
- * Managed dma_declare_coherent_memory().
- *
- * RETURNS:
- * 0 on success, -errno on failure.
- */
-int dmam_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-				 dma_addr_t device_addr, size_t size, int flags)
-{
-	void *res;
-	int rc;
-
-	res = devres_alloc(dmam_coherent_decl_release, 0, GFP_KERNEL);
-	if (!res)
-		return -ENOMEM;
-
-	rc = dma_declare_coherent_memory(dev, bus_addr, device_addr, size,
-					 flags);
-	if (rc == 0)
-		devres_add(dev, res);
-	else
-		devres_free(res);
-
-	return rc;
-}
-EXPORT_SYMBOL(dmam_declare_coherent_memory);
-
-/**
- * dmam_release_declared_memory - Managed dma_release_declared_memory().
- * @dev: Device to release declared coherent memory for
- *
- * Managed dmam_release_declared_memory().
- */
-void dmam_release_declared_memory(struct device *dev)
-{
-	WARN_ON(devres_destroy(dev, dmam_coherent_decl_release, NULL, NULL));
-}
-EXPORT_SYMBOL(dmam_release_declared_memory);
-
-#endif
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index 662cea7..5f17836 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -163,17 +163,3 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 	       enum dma_data_direction direction)
 {
 }
-
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-extern int
-dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-			    dma_addr_t device_addr, size_t size, int flags);
-
-extern void
-dma_release_declared_memory(struct device *dev);
-
-extern void *
-dma_mark_declared_memory_occupied(struct device *dev,
-				  dma_addr_t device_addr, size_t size);
-
-#endif
diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
index 230b3f1..8364dce 100644
--- a/include/asm-mips/dma-mapping.h
+++ b/include/asm-mips/dma-mapping.h
@@ -68,14 +68,4 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr);
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 	       enum dma_data_direction direction);
 
-#if 0
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-
-extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-	dma_addr_t device_addr, size_t size, int flags);
-extern void dma_release_declared_memory(struct device *dev);
-extern void * dma_mark_declared_memory_occupied(struct device *dev,
-	dma_addr_t device_addr, size_t size);
-#endif
-
 #endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 55f01bd..215eced 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -172,16 +172,4 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 	flush_write_buffers();
 }
 
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-extern int
-dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-			    dma_addr_t device_addr, size_t size, int flags);
-
-extern void
-dma_release_declared_memory(struct device *dev);
-
-extern void *
-dma_mark_declared_memory_occupied(struct device *dev,
-				  dma_addr_t device_addr, size_t size);
-
 #endif
diff --git a/include/linux/device.h b/include/linux/device.h
index 2e15822..a2775ff 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -434,8 +434,6 @@ struct device {
 
 	struct list_head	dma_pools;	/* dma pools (if dma'ble) */
 
-	struct dma_coherent_mem	*dma_mem; /* internal for coherent mem
-					     override */
 	/* arch specific additions */
 	struct dev_archdata	archdata;
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 101a2d4..b672c89 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -66,27 +66,6 @@ extern u64 dma_get_required_mask(struct device *dev);
 #define DMA_MEMORY_INCLUDES_CHILDREN	0x04
 #define DMA_MEMORY_EXCLUSIVE		0x08
 
-#ifndef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-static inline int
-dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-			    dma_addr_t device_addr, size_t size, int flags)
-{
-	return 0;
-}
-
-static inline void
-dma_release_declared_memory(struct device *dev)
-{
-}
-
-static inline void *
-dma_mark_declared_memory_occupied(struct device *dev,
-				  dma_addr_t device_addr, size_t size)
-{
-	return ERR_PTR(-EBUSY);
-}
-#endif
-
 /*
  * Managed DMA API
  */
@@ -98,22 +77,4 @@ extern void *dmam_alloc_noncoherent(struct device *dev, size_t size,
 				    dma_addr_t *dma_handle, gfp_t gfp);
 extern void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr,
 				  dma_addr_t dma_handle);
-#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-extern int dmam_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-					dma_addr_t device_addr, size_t size,
-					int flags);
-extern void dmam_release_declared_memory(struct device *dev);
-#else /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
-static inline int dmam_declare_coherent_memory(struct device *dev,
-				dma_addr_t bus_addr, dma_addr_t device_addr,
-				size_t size, gfp_t gfp)
-{
-	return 0;
-}
-
-static inline void dmam_release_declared_memory(struct device *dev)
-{
-}
-#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
-
 #endif
-- 
1.5.3.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] Remove dma_coherent_mem interface
  2007-10-30 19:43 ` [PATCH 2/2] Remove dma_coherent_mem interface Matthew Wilcox
@ 2007-10-30 20:26   ` James Bottomley
  2007-10-30 20:35     ` Matthew Wilcox
  0 siblings, 1 reply; 5+ messages in thread
From: James Bottomley @ 2007-10-30 20:26 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-arch, tglx, mingo, hpa, linux-scsi, jejb, Matthew Wilcox

On Tue, 2007-10-30 at 15:43 -0400, Matthew Wilcox wrote:
> This interface only had one user (and two implementations).
> It complicates other work, so remove it.

Its design was basically to facilitate the use of bus remote memory.
There's a long thread somewhere discussing this with the ARM people.
They had some type of SoC implementation that needed to allocate local
memory for device descriptors.  The Q720 is pretty much the same way, so
I used it to build the implementation when I created it for the ARM
people.  This is the original thread:

http://marc.info/?t=108757862100001

They said they were implementing this system, so I've no idea what
happened.  However, what are the problems the API is causing?  it seems
useful, so there should be a preference in its favour of existence
unless it's causing a problem.

James



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] Remove dma_coherent_mem interface
  2007-10-30 20:26   ` James Bottomley
@ 2007-10-30 20:35     ` Matthew Wilcox
  2007-10-31  5:49       ` Paul Mundt
  0 siblings, 1 reply; 5+ messages in thread
From: Matthew Wilcox @ 2007-10-30 20:35 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-arch, tglx, mingo, hpa, linux-scsi, jejb, Matthew Wilcox

On Tue, Oct 30, 2007 at 03:26:31PM -0500, James Bottomley wrote:
> Its design was basically to facilitate the use of bus remote memory.
> There's a long thread somewhere discussing this with the ARM people.
> They had some type of SoC implementation that needed to allocate local
> memory for device descriptors.  The Q720 is pretty much the same way, so
> I used it to build the implementation when I created it for the ARM
> people.  This is the original thread:
> 
> http://marc.info/?t=108757862100001
> 
> They said they were implementing this system, so I've no idea what
> happened.

It's been over three years, and it hasn't happened.

> However, what are the problems the API is causing?  it seems
> useful, so there should be a preference in its favour of existence
> unless it's causing a problem.

What I'm currently looking at is the dmapool allocator.  It's not
exactly fast (a spinlock for each allocation ... no concept of cpu
affinity, etc), and some drivers (eg qla2xxx) use it in the performance
path.

One of the suggestions in the existing dmapool driver is to share the
guts of slab.  Well, slab is probably going away, so I took a look
at slub.  Slub really, *really* needs the struct page associated
with the page of memory allocated, so I'm currently working my way
through the architectures trying to turn dma_alloc_coherent into
dma_alloc_coherent_pages.

The dma_coherent_mem API is one of the things which gets in the way of
doing this.  So I deleted it, then sent the patch out for comments early.

-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] Remove dma_coherent_mem interface
  2007-10-30 20:35     ` Matthew Wilcox
@ 2007-10-31  5:49       ` Paul Mundt
  0 siblings, 0 replies; 5+ messages in thread
From: Paul Mundt @ 2007-10-31  5:49 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: James Bottomley, linux-arch, tglx, mingo, hpa, linux-scsi, jejb,
	Matthew Wilcox

On Tue, Oct 30, 2007 at 02:35:14PM -0600, Matthew Wilcox wrote:
> On Tue, Oct 30, 2007 at 03:26:31PM -0500, James Bottomley wrote:
> > Its design was basically to facilitate the use of bus remote memory.
> > There's a long thread somewhere discussing this with the ARM people.
> > They had some type of SoC implementation that needed to allocate local
> > memory for device descriptors.  The Q720 is pretty much the same way, so
> > I used it to build the implementation when I created it for the ARM
> > people.  This is the original thread:
> > 
> > http://marc.info/?t=108757862100001
> > 
> > They said they were implementing this system, so I've no idea what
> > happened.
> 
> It's been over three years, and it hasn't happened.
> 
> > However, what are the problems the API is causing?  it seems
> > useful, so there should be a preference in its favour of existence
> > unless it's causing a problem.
> 
> What I'm currently looking at is the dmapool allocator.  It's not
> exactly fast (a spinlock for each allocation ... no concept of cpu
> affinity, etc), and some drivers (eg qla2xxx) use it in the performance
> path.
> 
> One of the suggestions in the existing dmapool driver is to share the
> guts of slab.  Well, slab is probably going away, so I took a look
> at slub.  Slub really, *really* needs the struct page associated
> with the page of memory allocated, so I'm currently working my way
> through the architectures trying to turn dma_alloc_coherent into
> dma_alloc_coherent_pages.
> 
> The dma_coherent_mem API is one of the things which gets in the way of
> doing this.  So I deleted it, then sent the patch out for comments early.
> 
We have some out-of-tree users for this on SH as well, particularly the
SM501 MFD USB driver which needs to do 8051-local allocations. We have an
in-tree hack for this now, I never bothered pushing the
dma_declare_coherent_memory() bits due to the fact the driver hadn't been
merged yet, but I had planned on merging both for 2.6.25.

We can continue using the in-tree hack if there aren't going to be any
other users of this API and it's causing problems elsewhere, but I do
expect that we will continue to see devices with a need for this sort of
API. I would imagine that the ARM case is similar, even if it's been a
low priority item.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-10-31  6:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-30 19:43 [PATCH 1/2] Wean NCR_Q720 off the dma_declare_coherent_memory interface Matthew Wilcox
2007-10-30 19:43 ` [PATCH 2/2] Remove dma_coherent_mem interface Matthew Wilcox
2007-10-30 20:26   ` James Bottomley
2007-10-30 20:35     ` Matthew Wilcox
2007-10-31  5:49       ` Paul Mundt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).