diff options
Diffstat (limited to 'drivers/char/agp/generic.c')
-rw-r--r-- | drivers/char/agp/generic.c | 69 |
1 files changed, 28 insertions, 41 deletions
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 2224b762b7fb..1e8b461b91f1 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -95,13 +95,13 @@ EXPORT_SYMBOL(agp_flush_chipset); | |||
95 | 95 | ||
96 | void agp_alloc_page_array(size_t size, struct agp_memory *mem) | 96 | void agp_alloc_page_array(size_t size, struct agp_memory *mem) |
97 | { | 97 | { |
98 | mem->memory = NULL; | 98 | mem->pages = NULL; |
99 | mem->vmalloc_flag = false; | 99 | mem->vmalloc_flag = false; |
100 | 100 | ||
101 | if (size <= 2*PAGE_SIZE) | 101 | if (size <= 2*PAGE_SIZE) |
102 | mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); | 102 | mem->pages = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); |
103 | if (mem->memory == NULL) { | 103 | if (mem->pages == NULL) { |
104 | mem->memory = vmalloc(size); | 104 | mem->pages = vmalloc(size); |
105 | mem->vmalloc_flag = true; | 105 | mem->vmalloc_flag = true; |
106 | } | 106 | } |
107 | } | 107 | } |
@@ -110,9 +110,9 @@ EXPORT_SYMBOL(agp_alloc_page_array); | |||
110 | void agp_free_page_array(struct agp_memory *mem) | 110 | void agp_free_page_array(struct agp_memory *mem) |
111 | { | 111 | { |
112 | if (mem->vmalloc_flag) { | 112 | if (mem->vmalloc_flag) { |
113 | vfree(mem->memory); | 113 | vfree(mem->pages); |
114 | } else { | 114 | } else { |
115 | kfree(mem->memory); | 115 | kfree(mem->pages); |
116 | } | 116 | } |
117 | } | 117 | } |
118 | EXPORT_SYMBOL(agp_free_page_array); | 118 | EXPORT_SYMBOL(agp_free_page_array); |
@@ -136,7 +136,7 @@ static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages) | |||
136 | 136 | ||
137 | agp_alloc_page_array(alloc_size, new); | 137 | agp_alloc_page_array(alloc_size, new); |
138 | 138 | ||
139 | if (new->memory == NULL) { | 139 | if (new->pages == NULL) { |
140 | agp_free_key(new->key); | 140 | agp_free_key(new->key); |
141 | kfree(new); | 141 | kfree(new); |
142 | return NULL; | 142 | return NULL; |
@@ -162,7 +162,7 @@ struct agp_memory *agp_create_memory(int scratch_pages) | |||
162 | 162 | ||
163 | agp_alloc_page_array(PAGE_SIZE * scratch_pages, new); | 163 | agp_alloc_page_array(PAGE_SIZE * scratch_pages, new); |
164 | 164 | ||
165 | if (new->memory == NULL) { | 165 | if (new->pages == NULL) { |
166 | agp_free_key(new->key); | 166 | agp_free_key(new->key); |
167 | kfree(new); | 167 | kfree(new); |
168 | return NULL; | 168 | return NULL; |
@@ -206,15 +206,13 @@ void agp_free_memory(struct agp_memory *curr) | |||
206 | } else { | 206 | } else { |
207 | 207 | ||
208 | for (i = 0; i < curr->page_count; i++) { | 208 | for (i = 0; i < curr->page_count; i++) { |
209 | curr->memory[i] = (unsigned long)gart_to_virt( | ||
210 | curr->memory[i]); | ||
211 | curr->bridge->driver->agp_destroy_page( | 209 | curr->bridge->driver->agp_destroy_page( |
212 | (void *)curr->memory[i], | 210 | curr->pages[i], |
213 | AGP_PAGE_DESTROY_UNMAP); | 211 | AGP_PAGE_DESTROY_UNMAP); |
214 | } | 212 | } |
215 | for (i = 0; i < curr->page_count; i++) { | 213 | for (i = 0; i < curr->page_count; i++) { |
216 | curr->bridge->driver->agp_destroy_page( | 214 | curr->bridge->driver->agp_destroy_page( |
217 | (void *)curr->memory[i], | 215 | curr->pages[i], |
218 | AGP_PAGE_DESTROY_FREE); | 216 | AGP_PAGE_DESTROY_FREE); |
219 | } | 217 | } |
220 | } | 218 | } |
@@ -282,13 +280,13 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
282 | } | 280 | } |
283 | 281 | ||
284 | for (i = 0; i < page_count; i++) { | 282 | for (i = 0; i < page_count; i++) { |
285 | void *addr = bridge->driver->agp_alloc_page(bridge); | 283 | struct page *page = bridge->driver->agp_alloc_page(bridge); |
286 | 284 | ||
287 | if (addr == NULL) { | 285 | if (page == NULL) { |
288 | agp_free_memory(new); | 286 | agp_free_memory(new); |
289 | return NULL; | 287 | return NULL; |
290 | } | 288 | } |
291 | new->memory[i] = virt_to_gart(addr); | 289 | new->pages[i] = page; |
292 | new->page_count++; | 290 | new->page_count++; |
293 | } | 291 | } |
294 | new->bridge = bridge; | 292 | new->bridge = bridge; |
@@ -1134,7 +1132,7 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type) | |||
1134 | } | 1132 | } |
1135 | 1133 | ||
1136 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1134 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
1137 | writel(bridge->driver->mask_memory(bridge, mem->memory[i], mask_type), | 1135 | writel(bridge->driver->mask_memory(bridge, mem->pages[i], mask_type), |
1138 | bridge->gatt_table+j); | 1136 | bridge->gatt_table+j); |
1139 | } | 1137 | } |
1140 | readl(bridge->gatt_table+j-1); /* PCI Posting. */ | 1138 | readl(bridge->gatt_table+j-1); /* PCI Posting. */ |
@@ -1204,7 +1202,7 @@ struct agp_memory *agp_generic_alloc_user(size_t page_count, int type) | |||
1204 | return NULL; | 1202 | return NULL; |
1205 | 1203 | ||
1206 | for (i = 0; i < page_count; i++) | 1204 | for (i = 0; i < page_count; i++) |
1207 | new->memory[i] = 0; | 1205 | new->pages[i] = 0; |
1208 | new->page_count = 0; | 1206 | new->page_count = 0; |
1209 | new->type = type; | 1207 | new->type = type; |
1210 | new->num_scratch_pages = pages; | 1208 | new->num_scratch_pages = pages; |
@@ -1237,23 +1235,20 @@ int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *m | |||
1237 | get_page(page); | 1235 | get_page(page); |
1238 | atomic_inc(&agp_bridge->current_memory_agp); | 1236 | atomic_inc(&agp_bridge->current_memory_agp); |
1239 | 1237 | ||
1240 | /* set_memory_array_uc() needs virtual address */ | 1238 | mem->pages[i] = page; |
1241 | mem->memory[i] = (unsigned long)page_address(page); | ||
1242 | mem->page_count++; | 1239 | mem->page_count++; |
1243 | } | 1240 | } |
1244 | 1241 | ||
1245 | #ifdef CONFIG_X86 | 1242 | #ifdef CONFIG_X86 |
1246 | set_memory_array_uc(mem->memory, num_pages); | 1243 | set_pages_array_uc(mem->pages, num_pages); |
1247 | #endif | 1244 | #endif |
1248 | ret = 0; | 1245 | ret = 0; |
1249 | out: | 1246 | out: |
1250 | for (i = 0; i < mem->page_count; i++) | ||
1251 | mem->memory[i] = virt_to_gart((void *)mem->memory[i]); | ||
1252 | return ret; | 1247 | return ret; |
1253 | } | 1248 | } |
1254 | EXPORT_SYMBOL(agp_generic_alloc_pages); | 1249 | EXPORT_SYMBOL(agp_generic_alloc_pages); |
1255 | 1250 | ||
1256 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | 1251 | struct page *agp_generic_alloc_page(struct agp_bridge_data *bridge) |
1257 | { | 1252 | { |
1258 | struct page * page; | 1253 | struct page * page; |
1259 | 1254 | ||
@@ -1265,56 +1260,47 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | |||
1265 | 1260 | ||
1266 | get_page(page); | 1261 | get_page(page); |
1267 | atomic_inc(&agp_bridge->current_memory_agp); | 1262 | atomic_inc(&agp_bridge->current_memory_agp); |
1268 | return page_address(page); | 1263 | return page; |
1269 | } | 1264 | } |
1270 | EXPORT_SYMBOL(agp_generic_alloc_page); | 1265 | EXPORT_SYMBOL(agp_generic_alloc_page); |
1271 | 1266 | ||
1272 | void agp_generic_destroy_pages(struct agp_memory *mem) | 1267 | void agp_generic_destroy_pages(struct agp_memory *mem) |
1273 | { | 1268 | { |
1274 | int i; | 1269 | int i; |
1275 | void *addr; | ||
1276 | struct page *page; | 1270 | struct page *page; |
1277 | 1271 | ||
1278 | if (!mem) | 1272 | if (!mem) |
1279 | return; | 1273 | return; |
1280 | 1274 | ||
1281 | for (i = 0; i < mem->page_count; i++) | ||
1282 | mem->memory[i] = (unsigned long)gart_to_virt(mem->memory[i]); | ||
1283 | |||
1284 | #ifdef CONFIG_X86 | 1275 | #ifdef CONFIG_X86 |
1285 | set_memory_array_wb(mem->memory, mem->page_count); | 1276 | set_pages_array_wb(mem->pages, mem->page_count); |
1286 | #endif | 1277 | #endif |
1287 | 1278 | ||
1288 | for (i = 0; i < mem->page_count; i++) { | 1279 | for (i = 0; i < mem->page_count; i++) { |
1289 | addr = (void *)mem->memory[i]; | 1280 | page = mem->pages[i]; |
1290 | page = virt_to_page(addr); | ||
1291 | 1281 | ||
1292 | #ifndef CONFIG_X86 | 1282 | #ifndef CONFIG_X86 |
1293 | unmap_page_from_agp(page); | 1283 | unmap_page_from_agp(page); |
1294 | #endif | 1284 | #endif |
1295 | |||
1296 | put_page(page); | 1285 | put_page(page); |
1297 | free_page((unsigned long)addr); | 1286 | __free_page(page); |
1298 | atomic_dec(&agp_bridge->current_memory_agp); | 1287 | atomic_dec(&agp_bridge->current_memory_agp); |
1299 | mem->memory[i] = 0; | 1288 | mem->pages[i] = NULL; |
1300 | } | 1289 | } |
1301 | } | 1290 | } |
1302 | EXPORT_SYMBOL(agp_generic_destroy_pages); | 1291 | EXPORT_SYMBOL(agp_generic_destroy_pages); |
1303 | 1292 | ||
1304 | void agp_generic_destroy_page(void *addr, int flags) | 1293 | void agp_generic_destroy_page(struct page *page, int flags) |
1305 | { | 1294 | { |
1306 | struct page *page; | 1295 | if (page == NULL) |
1307 | |||
1308 | if (addr == NULL) | ||
1309 | return; | 1296 | return; |
1310 | 1297 | ||
1311 | page = virt_to_page(addr); | ||
1312 | if (flags & AGP_PAGE_DESTROY_UNMAP) | 1298 | if (flags & AGP_PAGE_DESTROY_UNMAP) |
1313 | unmap_page_from_agp(page); | 1299 | unmap_page_from_agp(page); |
1314 | 1300 | ||
1315 | if (flags & AGP_PAGE_DESTROY_FREE) { | 1301 | if (flags & AGP_PAGE_DESTROY_FREE) { |
1316 | put_page(page); | 1302 | put_page(page); |
1317 | free_page((unsigned long)addr); | 1303 | __free_page(page); |
1318 | atomic_dec(&agp_bridge->current_memory_agp); | 1304 | atomic_dec(&agp_bridge->current_memory_agp); |
1319 | } | 1305 | } |
1320 | } | 1306 | } |
@@ -1361,8 +1347,9 @@ void global_cache_flush(void) | |||
1361 | EXPORT_SYMBOL(global_cache_flush); | 1347 | EXPORT_SYMBOL(global_cache_flush); |
1362 | 1348 | ||
1363 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, | 1349 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, |
1364 | unsigned long addr, int type) | 1350 | struct page *page, int type) |
1365 | { | 1351 | { |
1352 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
1366 | /* memory type is ignored in the generic routine */ | 1353 | /* memory type is ignored in the generic routine */ |
1367 | if (bridge->driver->masks) | 1354 | if (bridge->driver->masks) |
1368 | return addr | bridge->driver->masks[0].mask; | 1355 | return addr | bridge->driver->masks[0].mask; |