diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-28 07:56:42 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-28 07:56:42 -0700 |
commit | c8339002de4fcb6b30c20f8676e92d30d04d5d87 (patch) | |
tree | 118c0c5d3600d935921a9859b802aa8f56649d07 /mm | |
parent | 2ac5f852bd0634c585a6cf55c78bc457f451dcdf (diff) | |
parent | 75e1802f052e595738683a00122ddf9577dcd456 (diff) | |
download | history-c8339002de4fcb6b30c20f8676e92d30d04d5d87.tar.gz |
Merge bk://linux-voyager.bkbits.net/dma-declare-coherent-memory-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'mm')
-rw-r--r-- | mm/vmalloc.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index a4c7c0a17e9617..e9c5fb286899fc 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -179,11 +179,26 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages) return err; } +#define IOREMAP_MAX_ORDER (7 + PAGE_SHIFT) /* 128 pages */ + struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, unsigned long start, unsigned long end) { struct vm_struct **p, *tmp, *area; - unsigned long addr = start; + unsigned long align = 1; + unsigned long addr; + + if (flags & VM_IOREMAP) { + int bit = fls(size); + + if (bit > IOREMAP_MAX_ORDER) + bit = IOREMAP_MAX_ORDER; + else if (bit < PAGE_SHIFT) + bit = PAGE_SHIFT; + + align = 1ul << bit; + } + addr = ALIGN(start, align); area = kmalloc(sizeof(*area), GFP_KERNEL); if (unlikely(!area)) @@ -200,13 +215,17 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, write_lock(&vmlist_lock); for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) { - if ((unsigned long)tmp->addr < addr) + if ((unsigned long)tmp->addr < addr) { + if((unsigned long)tmp->addr + tmp->size >= addr) + addr = ALIGN(tmp->size + + (unsigned long)tmp->addr, align); continue; + } if ((size + addr) < addr) goto out; if (size + addr <= (unsigned long)tmp->addr) goto found; - addr = tmp->size + (unsigned long)tmp->addr; + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align); if (addr > end - size) goto out; } |