Commit d353084e authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-voyager.bkbits.net/dma-generic-mapping-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 2f4c2749 0a88e772
...@@ -22,7 +22,7 @@ To get the dma_ API, you must #include <linux/dma-mapping.h> ...@@ -22,7 +22,7 @@ To get the dma_ API, you must #include <linux/dma-mapping.h>
void * void *
dma_alloc_coherent(struct device *dev, size_t size, dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle, int flag)
void * void *
pci_alloc_consistent(struct pci_dev *dev, size_t size, pci_alloc_consistent(struct pci_dev *dev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle)
...@@ -43,6 +43,12 @@ Note: consistent memory can be expensive on some platforms, and the ...@@ -43,6 +43,12 @@ Note: consistent memory can be expensive on some platforms, and the
minimum allocation length may be as big as a page, so you should 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 consistent memory as much as possible.
The flag parameter (dma_alloc_coherent only) allows the caller to
specify the GFP_ flags (see kmalloc) for the allocation (the
implementation may chose to ignore flags that affect the location of
the returned memory, like GFP_DMA). For pci_alloc_consistent, you
must assume GFP_ATOMIC behaviour.
void void
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr dma_free_coherent(struct device *dev, size_t size, void *cpu_addr
dma_addr_t dma_handle) dma_addr_t dma_handle)
...@@ -261,7 +267,7 @@ API at all. ...@@ -261,7 +267,7 @@ API at all.
void * void *
dma_alloc_noncoherent(struct device *dev, size_t size, dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle, int flag)
Identical to dma_alloc_coherent() except that the platform will Identical to dma_alloc_coherent() except that the platform will
choose to return either consistent or non-consistent memory as it sees choose to return either consistent or non-consistent memory as it sees
......
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
#include <asm/io.h> #include <asm/io.h>
void *dma_alloc_coherent(struct device *dev, size_t size, void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle, int gfp)
{ {
void *ret; void *ret;
int gfp = GFP_ATOMIC; /* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
if (dev == NULL || (*dev->dma_mask < 0xffffffff)) if (dev == NULL || (*dev->dma_mask < 0xffffffff))
gfp |= GFP_DMA; gfp |= GFP_DMA;
......
...@@ -349,7 +349,7 @@ pcxl_dma_init(void) ...@@ -349,7 +349,7 @@ pcxl_dma_init(void)
__initcall(pcxl_dma_init); __initcall(pcxl_dma_init);
static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle) static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
{ {
unsigned long vaddr; unsigned long vaddr;
unsigned long paddr; unsigned long paddr;
...@@ -358,7 +358,7 @@ static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_ad ...@@ -358,7 +358,7 @@ static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_ad
order = get_order(size); order = get_order(size);
size = 1 << (order + PAGE_SHIFT); size = 1 << (order + PAGE_SHIFT);
vaddr = pcxl_alloc_range(size); vaddr = pcxl_alloc_range(size);
paddr = __get_free_pages(GFP_ATOMIC, order); paddr = __get_free_pages(flag, order);
flush_kernel_dcache_range(paddr, size); flush_kernel_dcache_range(paddr, size);
paddr = __pa(paddr); paddr = __pa(paddr);
map_uncached_pages(vaddr, size, paddr); map_uncached_pages(vaddr, size, paddr);
...@@ -482,18 +482,18 @@ struct hppa_dma_ops pcxl_dma_ops = { ...@@ -482,18 +482,18 @@ struct hppa_dma_ops pcxl_dma_ops = {
}; };
static void *fail_alloc_consistent(struct device *dev, size_t size, static void *fail_alloc_consistent(struct device *dev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle, int flag)
{ {
return NULL; return NULL;
} }
static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size, static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle, int flag)
{ {
void *addr = NULL; void *addr = NULL;
/* rely on kmalloc to be cacheline aligned */ /* rely on kmalloc to be cacheline aligned */
addr = kmalloc(size, GFP_KERNEL); addr = kmalloc(size, flag);
if(addr) if(addr)
*dma_handle = (dma_addr_t)virt_to_phys(addr); *dma_handle = (dma_addr_t)virt_to_phys(addr);
......
...@@ -728,7 +728,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size, ...@@ -728,7 +728,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* This function implements the pci_alloc_consistent function. * This function implements the pci_alloc_consistent function.
*/ */
static void * static void *
ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle) ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
{ {
void *ret; void *ret;
#if 0 #if 0
...@@ -741,7 +741,7 @@ ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle) ...@@ -741,7 +741,7 @@ ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle)
return 0; return 0;
} }
#endif #endif
ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); ret = (void *) __get_free_pages(flag, get_order(size));
if (ret) { if (ret) {
memset(ret, 0, size); memset(ret, 0, size);
......
...@@ -246,7 +246,7 @@ NCR_700_detect(Scsi_Host_Template *tpnt, ...@@ -246,7 +246,7 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
int j; int j;
memory = dma_alloc_noncoherent(hostdata->dev, TOTAL_MEM_SIZE, memory = dma_alloc_noncoherent(hostdata->dev, TOTAL_MEM_SIZE,
&pScript); &pScript, GFP_KERNEL);
if(memory == NULL) { if(memory == NULL) {
printk(KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n"); printk(KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n");
return NULL; return NULL;
......
...@@ -797,7 +797,7 @@ static m_addr_t ___dma_getp(m_pool_s *mp) ...@@ -797,7 +797,7 @@ static m_addr_t ___dma_getp(m_pool_s *mp)
dma_addr_t daddr; dma_addr_t daddr;
vp = (m_addr_t) dma_alloc_coherent(mp->bush, vp = (m_addr_t) dma_alloc_coherent(mp->bush,
PAGE_SIZE<<MEMO_PAGE_ORDER, PAGE_SIZE<<MEMO_PAGE_ORDER,
&daddr); &daddr, GFP_KERNEL);
if (vp) { if (vp) {
int hc = VTOB_HASH_CODE(vp); int hc = VTOB_HASH_CODE(vp);
vbp->vaddr = vp; vbp->vaddr = vp;
......
...@@ -82,10 +82,8 @@ static inline int dma_is_consistent(dma_addr_t handle) ...@@ -82,10 +82,8 @@ static inline int dma_is_consistent(dma_addr_t handle)
* device-viewed address. * device-viewed address.
*/ */
static inline void * static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle) dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
{ {
int gfp = GFP_ATOMIC;
if (dev == NULL || dmadev_is_sa1111(dev) || *dev->dma_mask != 0xffffffff) if (dev == NULL || dmadev_is_sa1111(dev) || *dev->dma_mask != 0xffffffff)
gfp |= GFP_DMA; gfp |= GFP_DMA;
......
...@@ -30,7 +30,8 @@ dma_set_mask(struct device *dev, u64 dma_mask) ...@@ -30,7 +30,8 @@ dma_set_mask(struct device *dev, u64 dma_mask)
} }
static inline void * static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle) dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
int flag)
{ {
BUG_ON(dev->bus != &pci_bus_type); BUG_ON(dev->bus != &pci_bus_type);
...@@ -121,7 +122,7 @@ dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, ...@@ -121,7 +122,7 @@ dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
/* Now for the API extensions over the pci_ one */ /* Now for the API extensions over the pci_ one */
#define dma_alloc_noncoherent(d, s, h) dma_alloc_coherent(d, s, h) #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_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
#define dma_is_consistent(d) (1) #define dma_is_consistent(d) (1)
......
...@@ -19,7 +19,7 @@ static inline void * ...@@ -19,7 +19,7 @@ static inline void *
pci_alloc_consistent(struct pci_dev *hwdev, size_t size, pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle)
{ {
return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle); return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, GFP_ATOMIC);
} }
static inline void static inline void
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
#include <asm/cache.h> #include <asm/cache.h>
#define dma_alloc_noncoherent(d, s, h) dma_alloc_coherent(d, s, h) #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_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
void *dma_alloc_coherent(struct device *dev, size_t size, void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle); dma_addr_t *dma_handle, int flag);
void dma_free_coherent(struct device *dev, size_t size, void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle); void *vaddr, dma_addr_t dma_handle);
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
*/ */
struct hppa_dma_ops { struct hppa_dma_ops {
int (*dma_supported)(struct device *dev, u64 mask); int (*dma_supported)(struct device *dev, u64 mask);
void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova); void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova); void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova); void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction); dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction); void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
...@@ -46,15 +46,17 @@ extern struct hppa_dma_ops pcx_dma_ops; ...@@ -46,15 +46,17 @@ extern struct hppa_dma_ops pcx_dma_ops;
extern struct hppa_dma_ops *hppa_dma_ops; extern struct hppa_dma_ops *hppa_dma_ops;
static inline void * static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle) dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
int flag)
{ {
return hppa_dma_ops->alloc_consistent(dev, size, dma_handle); return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag);
} }
static inline void * static inline void *
dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle) dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
int flag)
{ {
return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle); return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag);
} }
static inline void static inline void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment