diff -bur /usr/src/linux/drivers/char/agp/generic.c agp2/generic.c --- /usr/src/linux/drivers/char/agp/generic.c 2005-06-17 21:48:29.000000000 +0200 +++ agp2/generic.c 2006-01-23 15:55:06.000000000 +0100 @@ -182,6 +182,8 @@ struct agp_memory *new; size_t i; + printk (KERN_ERR PFX "agp allocate memory\n"); + if (!bridge) return NULL; @@ -189,6 +191,7 @@ return NULL; if (type != 0) { + printk (KERN_ERR PFX "driver agp alloc by type\n"); new = bridge->driver->alloc_by_type(page_count, type); if (new) new->bridge = bridge; Only in agp2: generic.c~ Only in /usr/src/linux/drivers/char/agp: generic.o Only in /usr/src/linux/drivers/char/agp: .generic.o.cmd diff -bur /usr/src/linux/drivers/char/agp/intel-agp.c agp2/intel-agp.c --- /usr/src/linux/drivers/char/agp/intel-agp.c 2005-06-17 21:48:29.000000000 +0200 +++ agp2/intel-agp.c 2006-01-23 16:57:41.000000000 +0100 @@ -59,6 +59,10 @@ #define AGP_DCACHE_MEMORY 1 #define AGP_PHYS_MEMORY 2 +#define AGP_USER_MEMORY (1 << 16) +#define AGP_UCACHED_MEMORY (2 << 16) + +#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long)) static struct gatt_mask intel_i810_masks[] = { @@ -300,6 +304,38 @@ return new; } +static struct agp_memory *alloc_agpusermem(size_t pg_count, int type) +{ + struct agp_memory *new; + int i; + int scratch_pages; + + switch(type) { + case AGP_USER_MEMORY: + case AGP_UCACHED_MEMORY: + break; + default: + return NULL; + } + + scratch_pages = (pg_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE; + new = agp_create_memory(scratch_pages); + + if (new == NULL) + return NULL; + + for (i = 0; i < pg_count; i++) { + new->memory[i] = 0; + } + new->page_count = 0; + new->type = type; + new->num_scratch_pages = scratch_pages; + printk (KERN_INFO PFX "Alloced AGP memory %p\n", new); + + return new; +} + + static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type) { struct agp_memory *new; @@ -334,6 +370,10 @@ agp_bridge->driver->agp_destroy_page( gart_to_virt(curr->memory[0])); vfree(curr->memory); + } else if (curr->type == AGP_USER_MEMORY || + curr->type == AGP_UCACHED_MEMORY) { + vfree(curr->memory); + printk (KERN_INFO PFX "Freed AGP memory %p\n", curr); } kfree(curr); } @@ -621,8 +661,12 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) { + printk (KERN_ERR PFX "i830 agp alloc by type\n"); + if (type == AGP_PHYS_MEMORY) return alloc_agpphysmem_i8xx(pg_count, type); + else if (type == AGP_USER_MEMORY || type == AGP_UCACHED_MEMORY) + return alloc_agpusermem(pg_count, type); /* always return NULL for other allocation types for now */ return NULL; @@ -670,6 +714,7 @@ { int i,j,num_entries; void *temp; + int mask_type; temp = agp_bridge->current_size; num_entries = A_SIZE_FIX(temp)->num_entries; @@ -689,11 +734,23 @@ * depend on the caller to make the correct offset decisions. */ - if ((type != 0 && type != AGP_PHYS_MEMORY) || - (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) + if (type != mem->type) { + printk (KERN_INFO PFX "AGP Memory type mismatch\n"); return -EINVAL; - + } + switch(type) { + case 0: + case AGP_PHYS_MEMORY: global_cache_flush(); + mask_type = type; + break; + case AGP_USER_MEMORY: + case AGP_UCACHED_MEMORY: + mask_type = AGP_PHYS_MEMORY; + break; + default: + return -EINVAL; + } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { writel(agp_bridge->driver->mask_memory(agp_bridge, @@ -701,7 +758,13 @@ readl(intel_i830_private.gtt+j); /* PCI Posting. */ } + if (type == 0 || type == AGP_PHYS_MEMORY) { global_cache_flush(); + } + + /* + * FIXME: Needed? + */ agp_bridge->driver->tlb_flush(mem); return 0; } @@ -711,7 +774,14 @@ { int i; + if (type != mem->type) { + printk (KERN_INFO PFX "AGP Memory type mismatch\n"); + return -EINVAL; + } + + if (type == 0 || type == AGP_PHYS_MEMORY) { global_cache_flush(); + } if (pg_start < intel_i830_private.gtt_entries) { printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); @@ -723,7 +793,9 @@ readl(intel_i830_private.gtt+i); } + if (type == 0 || type == AGP_PHYS_MEMORY) { global_cache_flush(); + } agp_bridge->driver->tlb_flush(mem); return 0; }