aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp/generic.c')
-rw-r--r--drivers/char/agp/generic.c69
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
96void agp_alloc_page_array(size_t size, struct agp_memory *mem) 96void 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);
110void agp_free_page_array(struct agp_memory *mem) 110void 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}
118EXPORT_SYMBOL(agp_free_page_array); 118EXPORT_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;
1249out: 1246out:
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}
1254EXPORT_SYMBOL(agp_generic_alloc_pages); 1249EXPORT_SYMBOL(agp_generic_alloc_pages);
1255 1250
1256void *agp_generic_alloc_page(struct agp_bridge_data *bridge) 1251struct 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}
1270EXPORT_SYMBOL(agp_generic_alloc_page); 1265EXPORT_SYMBOL(agp_generic_alloc_page);
1271 1266
1272void agp_generic_destroy_pages(struct agp_memory *mem) 1267void 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}
1302EXPORT_SYMBOL(agp_generic_destroy_pages); 1291EXPORT_SYMBOL(agp_generic_destroy_pages);
1303 1292
1304void agp_generic_destroy_page(void *addr, int flags) 1293void 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)
1361EXPORT_SYMBOL(global_cache_flush); 1347EXPORT_SYMBOL(global_cache_flush);
1362 1348
1363unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, 1349unsigned 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;