public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [Patch] DMA mapping API for Alpha
@ 2003-04-28 18:38 Marc Zyngier
  2003-04-28 18:49 ` Jeff Garzik
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Marc Zyngier @ 2003-04-28 18:38 UTC (permalink / raw)
  To: rth, ink; +Cc: linux-kernel

Richard, Ivan,

As part of my effort to get the Jensen up and running on the latest
2.5 kernels, I have introduced some support for the DMA API, rather
than relying on the generic PCI based one (which introduces problems
with the EISA bus).

So this patch implements both dma_* and pci_* operations on the
Jensen, as well as dma_* operations on all the other Alpha
variants. It's been tested it on both of my Alpha/EISA plateforms
(Jensen and Mikasa). Patch is against 2.5.68.

I would appreciate any comment on this stuff.

Thanks,

        M.

===== arch/alpha/kernel/alpha_ksyms.c 1.33 vs edited =====
--- 1.33/arch/alpha/kernel/alpha_ksyms.c	Tue Apr  1 00:29:49 2003
+++ edited/arch/alpha/kernel/alpha_ksyms.c	Mon Apr 28 17:19:36 2003
@@ -17,6 +17,7 @@
 #include <linux/tty.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/console.h>
@@ -259,4 +260,16 @@
 #ifdef CONFIG_ALPHA_IRONGATE
 EXPORT_SYMBOL(irongate_ioremap);
 EXPORT_SYMBOL(irongate_iounmap);
+#endif
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+EXPORT_SYMBOL(dma_free_coherent);
+#ifndef CONFIG_ALPHA_JENSEN
+EXPORT_SYMBOL(dma_supported);
+EXPORT_SYMBOL(dma_map_single);
+EXPORT_SYMBOL(dma_unmap_single);
+EXPORT_SYMBOL(dma_map_page);
+EXPORT_SYMBOL(dma_unmap_page);
+EXPORT_SYMBOL(dma_map_sg);
+EXPORT_SYMBOL(dma_unmap_sg);
 #endif
===== arch/alpha/kernel/pci-noop.c 1.7 vs edited =====
--- 1.7/arch/alpha/kernel/pci-noop.c	Fri Feb 28 08:53:37 2003
+++ edited/arch/alpha/kernel/pci-noop.c	Mon Apr 28 19:43:31 2003
@@ -9,6 +9,8 @@
 #include <linux/bootmem.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
 
 #include "proto.h"
 
@@ -101,22 +103,59 @@
 	else
 		return -ENODEV;
 }
+
+/* Shamelessly picked from arch/i386/kernel/pci-dma.c, as it should
+ * fit the Jensen quite well. The rest of the generic DMA API lives in
+ * asm-alpha/dma-mapping.h. */
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			 dma_addr_t *dma_handle, int gfp)
+{
+        void *ret;
+
+        /* ignore region specifiers */
+        gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+        if (dev == NULL || (*dev->dma_mask < 0xffffffff))
+                gfp |= GFP_DMA;
+        ret = (void *)__get_free_pages(gfp, get_order(size));
+
+        if (ret != NULL) {
+                memset(ret, 0, size);
+                *dma_handle = virt_to_bus(ret);
+        }
+        return ret;
+}
+
+void dma_free_coherent(struct device *dev, size_t size,
+		       void *vaddr, dma_addr_t dma_handle)
+{
+        free_pages((unsigned long)vaddr, get_order(size));
+}
+
 /* stubs for the routines in pci_iommu.c */
 void *
 pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
 {
-	return NULL;
+	if (pdev)		/* Jensen has no PCI ! */
+		return NULL;
+
+	return dma_alloc_coherent (NULL, size, dma_addrp, GFP_ATOMIC);
 }
 void
 pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
 		    dma_addr_t dma_addr)
 {
+	if (pdev)
+		return;
+
+	dma_free_coherent (NULL, size, cpu_addr, 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;
+	return (dma_addr_t) virt_to_bus (cpu_addr);
 }
 void
 pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
@@ -127,7 +166,14 @@
 pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
 	   int direction)
 {
-	return 0;
+	int i;
+
+	for (i = 0; i < nents; i++) {
+		sg_dma_address (sg + i) = (dma_addr_t) virt_to_bus (page_address (sg[i].page) + sg[i].offset);
+		sg_dma_len (sg + i) = sg[i].length;
+	}
+	
+	return nents;
 }
 void
 pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
===== arch/alpha/kernel/pci_iommu.c 1.16 vs edited =====
--- 1.16/arch/alpha/kernel/pci_iommu.c	Fri Apr  4 00:49:57 2003
+++ edited/arch/alpha/kernel/pci_iommu.c	Mon Apr 28 20:32:45 2003
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/hwrpb.h>
@@ -212,17 +213,31 @@
    until either pci_unmap_single or pci_dma_sync_single is performed.  */
 
 static dma_addr_t
-pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
+dma_map_single_1(struct device *dev, void *cpu_addr, size_t size,
 		 int dac_allowed)
 {
-	struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
-	dma_addr_t max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK;
+	struct pci_controller *hose;
+	struct pci_dev *pdev = NULL;
+	dma_addr_t max_dma;
 	struct pci_iommu_arena *arena;
 	long npages, dma_ofs, i;
 	unsigned long paddr;
 	dma_addr_t ret;
 	unsigned int align = 0;
 
+	if (dev) {
+		if (dev->bus == &pci_bus_type) {
+			pdev = to_pci_dev (dev);
+			hose = pdev->sysdata;
+		} else
+			hose = pci_isa_hose;
+
+		max_dma = *dev->dma_mask;
+	} else {
+		hose    = pci_isa_hose;
+		max_dma = ISA_DMA_MASK;
+	}
+	
 	paddr = __pa(cpu_addr);
 
 #if !DEBUG_NODIRECT
@@ -290,6 +305,16 @@
 }
 
 dma_addr_t
+dma_map_single (struct device *dev, void *cpu_addr, size_t size,
+		enum dma_data_direction dir)
+{
+	if (dir == DMA_NONE)
+		BUG();
+
+	return dma_map_single_1(dev, cpu_addr, size, 0);
+}
+
+dma_addr_t
 pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
 {
 	int dac_allowed; 
@@ -298,7 +323,19 @@
 		BUG();
 
 	dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; 
-	return pci_map_single_1(pdev, cpu_addr, size, dac_allowed);
+	return dma_map_single_1(pdev ? &pdev->dev : NULL, cpu_addr,
+				size, dac_allowed);
+}
+
+dma_addr_t
+dma_map_page (struct device *dev, struct page *page, unsigned long offset,
+	      size_t size, enum dma_data_direction dir)
+{
+	if (dir == DMA_NONE)
+		BUG();
+
+	return dma_map_single_1(dev, (char *)page_address(page) + offset,
+				size, 0);
 }
 
 dma_addr_t
@@ -311,7 +348,8 @@
 		BUG();
 
 	dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; 
-	return pci_map_single_1(pdev, (char *)page_address(page) + offset, 
+	return dma_map_single_1(pdev ? &pdev->dev : NULL,
+				(char *)page_address(page) + offset, 
 				size, dac_allowed);
 }
 
@@ -322,17 +360,22 @@
    wrote there.  */
 
 void
-pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
-		 int direction)
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction direction)
 {
 	unsigned long flags;
-	struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
+	struct pci_controller *hose;
 	struct pci_iommu_arena *arena;
 	long dma_ofs, npages;
 
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 		BUG();
 
+	if (dev && dev->bus == &pci_bus_type)
+		hose = to_pci_dev(dev)->sysdata;
+	else
+		hose = pci_isa_hose;
+	
 	if (dma_addr >= __direct_map_base
 	    && dma_addr < __direct_map_base + __direct_map_size) {
 		/* Nothing to do.  */
@@ -381,10 +424,26 @@
 }
 
 void
+pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
+		 int direction)
+{
+	dma_unmap_single (pdev ? &pdev->dev : NULL, dma_addr, size,
+			  (enum dma_data_direction) direction);
+}
+
+void
+dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+	       size_t size, enum dma_data_direction direction)
+{
+	dma_unmap_single(dev, dma_addr, size, direction);
+}
+
+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);
+	dma_unmap_single (pdev ? &pdev->dev : NULL, dma_addr, size,
+			  (enum dma_data_direction) direction);
 }
 
 /* Allocate and map kernel buffer using consistent mode DMA for PCI
@@ -393,11 +452,11 @@
    else DMA_ADDRP is undefined.  */
 
 void *
-pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
+dma_alloc_coherent (struct device *dev, size_t size,
+		    dma_addr_t *dma_addrp, int gfp)
 {
 	void *cpu_addr;
 	long order = get_order(size);
-	int gfp = GFP_ATOMIC;
 
 try_again:
 	cpu_addr = (void *)__get_free_pages(gfp, order);
@@ -411,7 +470,7 @@
 	}
 	memset(cpu_addr, 0, size);
 
-	*dma_addrp = pci_map_single_1(pdev, cpu_addr, size, 0);
+	*dma_addrp = dma_map_single_1(dev, cpu_addr, size, 0);
 	if (*dma_addrp == 0) {
 		free_pages((unsigned long)cpu_addr, order);
 		if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA))
@@ -422,12 +481,19 @@
 		goto try_again;
 	}
 		
-	DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n",
+	DBGA2("dma_alloc_coherent: %lx -> [%p,%x] from %p\n",
 	      size, cpu_addr, *dma_addrp, __builtin_return_address(0));
 
 	return cpu_addr;
 }
 
+void *
+pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
+{
+	return dma_alloc_coherent (pdev ? &pdev->dev : NULL, size,
+				   dma_addrp, 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.
@@ -435,16 +501,23 @@
    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)
+dma_free_coherent (struct device *dev, size_t size, void *cpu_addr,
+		   dma_addr_t dma_addr)
 {
-	pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_single(dev, dma_addr, size, DMA_BIDIRECTIONAL);
 	free_pages((unsigned long)cpu_addr, get_order(size));
 
-	DBGA2("pci_free_consistent: [%x,%lx] from %p\n",
+	DBGA2("dma_free_coherent: [%x,%lx] from %p\n",
 	      dma_addr, size, __builtin_return_address(0));
 }
 
+void
+pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
+		    dma_addr_t dma_addr)
+{
+	dma_free_coherent (pdev ? &pdev->dev : NULL, size, cpu_addr, dma_addr);
+}
+
 
 /* Classify the elements of the scatterlist.  Write dma_address
    of each element with:
@@ -600,25 +673,39 @@
 }
 
 int
-pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
-	   int direction)
+dma_map_sg (struct device *dev, struct scatterlist *sg, int nents,
+	    enum dma_data_direction direction)
 {
 	struct scatterlist *start, *end, *out;
 	struct pci_controller *hose;
 	struct pci_iommu_arena *arena;
+	struct pci_dev *pdev = NULL;
 	dma_addr_t max_dma;
 	int dac_allowed;
 
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 		BUG();
 
+	if (dev) {
+		if (dev->bus == &pci_bus_type) {
+			pdev = to_pci_dev (dev);
+			hose = pdev->sysdata;
+		} else
+			hose = pci_isa_hose;
+
+		max_dma = *dev->dma_mask;
+	} else {
+		hose    = pci_isa_hose;
+		max_dma = ISA_DMA_MASK;
+	}
+	
 	dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
 
 	/* Fast path single entry scatterlists.  */
 	if (nents == 1) {
 		sg->dma_length = sg->length;
 		sg->dma_address
-		  = pci_map_single_1(pdev, SG_ENT_VIRT_ADDRESS(sg),
+		  = dma_map_single_1(dev, SG_ENT_VIRT_ADDRESS(sg),
 				     sg->length, dac_allowed);
 		return sg->dma_address != 0;
 	}
@@ -631,8 +718,6 @@
 
 	/* Second, figure out where we're going to map things.  */
 	if (alpha_mv.mv_pci_tbi) {
-		hose = pdev ? pdev->sysdata : pci_isa_hose;
-		max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK;
 		arena = hose->sg_pci;
 		if (!arena || arena->dma_base + arena->size - 1 > max_dma)
 			arena = hose->sg_isa;
@@ -669,33 +754,53 @@
 	/* Some allocation failed while mapping the scatterlist
 	   entries.  Unmap them now.  */
 	if (out > start)
-		pci_unmap_sg(pdev, start, out - start, direction);
+		dma_unmap_sg(dev, start, out - start, direction);
 	return 0;
 }
 
+int
+pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
+	   int direction)
+{
+	return dma_map_sg (pdev ? &pdev->dev : NULL, sg, nents,
+			   (enum dma_data_direction) direction);
+}
+
 /* 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)
+dma_unmap_sg (struct device *dev, struct scatterlist *sg, int nents,
+	      enum dma_data_direction direction)
 {
 	unsigned long flags;
 	struct pci_controller *hose;
 	struct pci_iommu_arena *arena;
+	struct pci_dev *pdev = NULL;
 	struct scatterlist *end;
 	dma_addr_t max_dma;
 	dma_addr_t fbeg, fend;
 
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 		BUG();
 
 	if (! alpha_mv.mv_pci_tbi)
 		return;
 
-	hose = pdev ? pdev->sysdata : pci_isa_hose;
-	max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK;
+	if (dev) {
+		if (dev->bus == &pci_bus_type) {
+			pdev = to_pci_dev (dev);
+			hose = pdev->sysdata;
+		} else
+			hose = pci_isa_hose;
+
+		max_dma = *dev->dma_mask;
+	} else {
+		hose    = pci_isa_hose;
+		max_dma = ISA_DMA_MASK;
+	}
+	
 	arena = hose->sg_pci;
 	if (!arena || arena->dma_base + arena->size - 1 > max_dma)
 		arena = hose->sg_isa;
@@ -750,15 +855,22 @@
 
 	spin_unlock_irqrestore(&arena->lock, flags);
 
-	DBGA("pci_unmap_sg: %ld entries\n", nents - (end - sg));
+	DBGA("dma_unmap_sg: %ld entries\n", nents - (end - sg));
+}
+
+void
+pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
+	     int direction)
+{
+	dma_unmap_sg (pdev ? &pdev->dev : NULL, sg, nents,
+		      (enum dma_data_direction) direction);
 }
 
 
 /* Return whether the given PCI device DMA address mask can be
    supported properly.  */
 
-int
-pci_dma_supported(struct pci_dev *pdev, u64 mask)
+int dma_supported (struct device *dev, u64 mask)
 {
 	struct pci_controller *hose;
 	struct pci_iommu_arena *arena;
@@ -772,7 +884,10 @@
 		return 1;
 
 	/* Check that we have a scatter-gather arena that fits.  */
-	hose = pdev ? pdev->sysdata : pci_isa_hose;
+	if (dev && dev->bus == &pci_bus_type)
+		hose = to_pci_dev(dev)->sysdata;
+	else
+		hose = pci_isa_hose;
 	arena = hose->sg_isa;
 	if (arena && arena->dma_base + arena->size - 1 <= mask)
 		return 1;
@@ -785,6 +900,12 @@
 		return 1;
 
 	return 0;
+}
+
+int
+pci_dma_supported(struct pci_dev *pdev, u64 mask)
+{
+	return dma_supported (pdev ? &pdev->dev : NULL, mask);
 }
 
 \f
===== include/asm-alpha/dma-mapping.h 1.1 vs edited =====
--- 1.1/include/asm-alpha/dma-mapping.h	Sun Dec 22 05:36:49 2002
+++ edited/include/asm-alpha/dma-mapping.h	Mon Apr 28 19:50:32 2003
@@ -1 +1,159 @@
-#include <asm-generic/dma-mapping.h>
+#ifndef _ASM_ALPHA_DMA_MAPPING_H
+#define _ASM_ALPHA_DMA_MAPPING_H
+
+#include <linux/config.h>
+#include <asm/cache.h>
+
+#ifdef CONFIG_ALPHA_JENSEN
+#include <asm/io.h>
+
+/* Jensen is somewhat x86 like... */
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+	return virt_to_bus(ptr);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	   enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++ ) {
+		BUG_ON(!sg[i].page);
+
+		sg_dma_address (sg + i) = (dma_addr_t) virt_to_bus (page_address (sg[i].page) + sg[i].offset);
+		sg_dma_len (sg + i) = sg[i].length;
+	}
+
+	return nents;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+	     size_t size, enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+	return (dma_addr_t)(page_to_pfn(page)) * PAGE_SIZE + offset;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if(mask < 0x00ffffff)
+                return 0;
+
+	return 1;
+}
+
+#else
+
+/* All other Alphas are using an IOMMU */
+
+dma_addr_t dma_map_single     (struct device *dev, void *cpu_addr, size_t size,
+			       enum dma_data_direction direction);
+void       dma_unmap_single   (struct device *dev, dma_addr_t dma_addr,
+			       size_t size, enum dma_data_direction direction);
+dma_addr_t dma_map_page       (struct device *dev, struct page *page,
+			       unsigned long offset, size_t size,
+			       enum dma_data_direction direction);
+void       dma_unmap_page     (struct device *dev, dma_addr_t dma_address,
+			       size_t size, enum dma_data_direction direction);
+int        dma_map_sg         (struct device *dev, struct scatterlist *sg,
+			       int nents, enum dma_data_direction direction);
+void       dma_unmap_sg       (struct device *dev, struct scatterlist *sg,
+			       int nents, enum dma_data_direction direction);
+int        dma_supported      (struct device *dev, u64 mask);
+
+#endif
+
+/* This is common to all Alphas, at least for the time being... */
+
+#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)	(1)
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, int flag);
+
+void dma_free_coherent(struct device *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle);
+
+static inline void
+dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
+		enum dma_data_direction direction)
+{
+}
+
+static inline void
+dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+}
+
+static inline void
+dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
+	    enum dma_data_direction direction)
+{
+}
+
+static inline void
+dma_cache_sync(void *vaddr, size_t size,
+	       enum dma_data_direction direction)
+{
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+	/* no easy way to get cache size on all processors, so return
+	 * the maximum possible, to be safe */
+	return (1 << L1_CACHE_SHIFT_MAX);
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+	if(!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+#endif

-- 
Places change, faces change. Life is so very strange.

^ permalink raw reply	[flat|nested] 22+ messages in thread
* Re: [Patch] DMA mapping API for Alpha
@ 2003-04-29 20:22 James Bottomley
  2003-04-29 20:46 ` Ivan Kokshaysky
  0 siblings, 1 reply; 22+ messages in thread
From: James Bottomley @ 2003-04-29 20:22 UTC (permalink / raw)
  To: Ivan Kokshaysky; +Cc: Linux Kernel



> Ok, for clean dma_* implementation on alpha (and others, I guess) we need
> to move root level IO controller data from struct pci_dev (pdev->sysdata)
> to struct dev. Actually, the latter already has such field (platform_data)
> but right now it's kind of parisc specific. ;-)
> I'll look into it after short vacation (4-5 days).

Well, it (platform_data) predates the parisc conversion to the dma_
API.  I just assumed that was what it was there fore.  I had to do it
this way because parisc has a rather nasty set up in that there are
usually two PCI (and several other busses) which connect to two
different IO-MMUs.  I use the platform_data field to cache the
particular IO-MMU the device is connected to.  I assume this is the same
in alpha?

Previously parisc was using the sysdata field of the pci_dev (and
constructing fake pci_devs for other busses).  The conversion wasn't
actually that complex (although it was made easier on parisc because the
IO-MMU lives above the PCI busses, so in the generic device model we can
simply now traverse parents to find it).

James



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

end of thread, other threads:[~2003-05-02  0:02 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-28 18:38 [Patch] DMA mapping API for Alpha Marc Zyngier
2003-04-28 18:49 ` Jeff Garzik
2003-04-28 18:52   ` Marc Zyngier
2003-04-28 22:20     ` Alan Cox
2003-04-29  6:59 ` Christoph Hellwig
2003-04-29 11:05 ` Ivan Kokshaysky
2003-04-29 11:20   ` Christoph Hellwig
2003-04-29 12:08     ` Ivan Kokshaysky
2003-04-29 12:32       ` Christoph Hellwig
2003-04-29 12:59         ` Ivan Kokshaysky
2003-04-29 11:58   ` Marc Zyngier
2003-04-29 12:23     ` Ivan Kokshaysky
2003-04-29 12:37       ` Marc Zyngier
2003-04-29 12:41       ` Christoph Hellwig
2003-04-29 20:08         ` Ivan Kokshaysky
2003-05-01 10:56           ` David S. Miller
2003-04-30 12:07   ` Maciej W. Rozycki
2003-04-30 14:12     ` Jeff Garzik
2003-04-30 14:18       ` Marc Zyngier
2003-04-30 19:25         ` Maciej W. Rozycki
  -- strict thread matches above, loose matches on Subject: below --
2003-04-29 20:22 James Bottomley
2003-04-29 20:46 ` Ivan Kokshaysky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox