diff options
author | Shaohua Li <shaohua.li@intel.com> | 2008-08-20 22:46:11 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-21 07:47:46 -0400 |
commit | 37acee10f49cf3caa323e05675e8dc9221ef4fd8 (patch) | |
tree | 212754bec108fc139d47d3eecaf52bab90cf1603 /drivers/char/agp/generic.c | |
parent | d75586ad01e6c5a30e7337fb87d61e03556a1ecb (diff) |
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, | |||
264 | if (new == NULL) | 264 | if (new == NULL) |
265 | return NULL; | 265 | return NULL; |
266 | 266 | ||
267 | if (bridge->driver->agp_alloc_pages) { | ||
268 | if (bridge->driver->agp_alloc_pages(bridge, new, page_count)) { | ||
269 | agp_free_memory(new); | ||
270 | return NULL; | ||
271 | } | ||
272 | new->bridge = bridge; | ||
273 | return new; | ||
274 | } | ||
275 | |||
267 | for (i = 0; i < page_count; i++) { | 276 | for (i = 0; i < page_count; i++) { |
268 | void *addr = bridge->driver->agp_alloc_page(bridge); | 277 | void *addr = bridge->driver->agp_alloc_page(bridge); |
269 | 278 | ||
@@ -1178,6 +1187,39 @@ EXPORT_SYMBOL(agp_generic_alloc_user); | |||
1178 | * against a maximum value. | 1187 | * against a maximum value. |
1179 | */ | 1188 | */ |
1180 | 1189 | ||
1190 | int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *mem, size_t num_pages) | ||
1191 | { | ||
1192 | struct page * page; | ||
1193 | int i, ret = -ENOMEM; | ||
1194 | |||
1195 | for (i = 0; i < num_pages; i++) { | ||
1196 | page = alloc_page(GFP_KERNEL | GFP_DMA32); | ||
1197 | /* agp_free_memory() needs gart address */ | ||
1198 | if (page == NULL) | ||
1199 | goto out; | ||
1200 | |||
1201 | #ifndef CONFIG_X86 | ||
1202 | map_page_into_agp(page); | ||
1203 | #endif | ||
1204 | get_page(page); | ||
1205 | atomic_inc(&agp_bridge->current_memory_agp); | ||
1206 | |||
1207 | /* set_memory_array_uc() needs virtual address */ | ||
1208 | mem->memory[i] = (unsigned long)page_address(page); | ||
1209 | mem->page_count++; | ||
1210 | } | ||
1211 | |||
1212 | #ifdef CONFIG_X86 | ||
1213 | set_memory_array_uc(mem->memory, num_pages); | ||
1214 | #endif | ||
1215 | ret = 0; | ||
1216 | out: | ||
1217 | for (i = 0; i < mem->page_count; i++) | ||
1218 | mem->memory[i] = virt_to_gart((void *)mem->memory[i]); | ||
1219 | return ret; | ||
1220 | } | ||
1221 | EXPORT_SYMBOL(agp_generic_alloc_pages); | ||
1222 | |||
1181 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | 1223 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) |
1182 | { | 1224 | { |
1183 | struct page * page; | 1225 | struct page * page; |