diff options
author | Shaohua Li <shaohua.li@intel.com> | 2008-08-21 04:46:11 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-21 13:47:46 +0200 |
commit | 37acee10f49cf3caa323e05675e8dc9221ef4fd8 (patch) | |
tree | 212754bec108fc139d47d3eecaf52bab90cf1603 /drivers/char/agp/generic.c | |
parent | x86, pageattr: introduce APIs to change pageattr of a page array (diff) | |
download | linux-37acee10f49cf3caa323e05675e8dc9221ef4fd8.tar.xz linux-37acee10f49cf3caa323e05675e8dc9221ef4fd8.zip |
agp: generic_alloc_pages()
Add agp_generic_alloc_pages(), it uses new pageattr array interface API.
Signed-off-by: Dave Airlie <airlied@gmail.com>
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/char/agp/generic.c')
-rw-r--r-- | drivers/char/agp/generic.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index eaa1a355bb32..13a5577ee434 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -264,6 +264,15 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, if (new == NULL) return NULL; + if (bridge->driver->agp_alloc_pages) { + if (bridge->driver->agp_alloc_pages(bridge, new, page_count)) { + agp_free_memory(new); + return NULL; + } + new->bridge = bridge; + return new; + } + for (i = 0; i < page_count; i++) { void *addr = bridge->driver->agp_alloc_page(bridge); @@ -1178,6 +1187,39 @@ EXPORT_SYMBOL(agp_generic_alloc_user); * against a maximum value. */ +int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *mem, size_t num_pages) +{ + struct page * page; + int i, ret = -ENOMEM; + + for (i = 0; i < num_pages; i++) { + page = alloc_page(GFP_KERNEL | GFP_DMA32); + /* agp_free_memory() needs gart address */ + if (page == NULL) + goto out; + +#ifndef CONFIG_X86 + map_page_into_agp(page); +#endif + get_page(page); + atomic_inc(&agp_bridge->current_memory_agp); + + /* set_memory_array_uc() needs virtual address */ + mem->memory[i] = (unsigned long)page_address(page); + mem->page_count++; + } + +#ifdef CONFIG_X86 + set_memory_array_uc(mem->memory, num_pages); +#endif + ret = 0; +out: + for (i = 0; i < mem->page_count; i++) + mem->memory[i] = virt_to_gart((void *)mem->memory[i]); + return ret; +} +EXPORT_SYMBOL(agp_generic_alloc_pages); + void *agp_generic_alloc_page(struct agp_bridge_data *bridge) { struct page * page; |