Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 48646
b: refs/heads/master
c: a030ce4
h: refs/heads/master
v: v3
  • Loading branch information
Thomas Hellstrom authored and Dave Jones committed Feb 3, 2007
1 parent d1775d1 commit c837e3c
Show file tree
Hide file tree
Showing 20 changed files with 297 additions and 76 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0316fe8319ff62e527d0d91a3bc7df1c59eafae8
refs/heads/master: a030ce4477baa06dd9c037ccd3c8d171aac9ed44
10 changes: 10 additions & 0 deletions trunk/drivers/char/agp/agp.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ struct agp_bridge_driver {
void (*free_by_type)(struct agp_memory *);
void *(*agp_alloc_page)(struct agp_bridge_data *);
void (*agp_destroy_page)(void *);
int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
};

struct agp_bridge_data {
Expand Down Expand Up @@ -218,6 +219,7 @@ struct agp_bridge_data {
#define I810_PTE_MAIN_UNCACHED 0x00000000
#define I810_PTE_LOCAL 0x00000002
#define I810_PTE_VALID 0x00000001
#define I830_PTE_SYSTEM_CACHED 0x00000006
#define I810_SMRAM_MISCC 0x70
#define I810_GFX_MEM_WIN_SIZE 0x00010000
#define I810_GFX_MEM_WIN_32M 0x00010000
Expand Down Expand Up @@ -270,8 +272,16 @@ void global_cache_flush(void);
void get_agp_version(struct agp_bridge_data *bridge);
unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge,
unsigned long addr, int type);
int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge,
int type);
struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev);

/* generic functions for user-populated AGP memory types */
struct agp_memory *agp_generic_alloc_user(size_t page_count, int type);
void agp_alloc_page_array(size_t size, struct agp_memory *mem);
void agp_free_page_array(struct agp_memory *mem);


/* generic routines for agp>=3 */
int agp3_generic_fetch_size(void);
void agp3_generic_tlbflush(struct agp_memory *mem);
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/char/agp/ali-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ static struct agp_bridge_driver ali_generic_bridge = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = ali_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

static struct agp_bridge_driver ali_m1541_bridge = {
Expand All @@ -237,6 +238,7 @@ static struct agp_bridge_driver ali_m1541_bridge = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = m1541_alloc_page,
.agp_destroy_page = m1541_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};


Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/char/agp/alpha-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ static int alpha_core_agp_insert_memory(struct agp_memory *mem, off_t pg_start,
int num_entries, status;
void *temp;

if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
return -EINVAL;

temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
if ((pg_start + mem->page_count) > num_entries)
Expand Down Expand Up @@ -142,6 +145,7 @@ struct agp_bridge_driver alpha_core_agp_driver = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

struct agp_bridge_data *alpha_bridge;
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/char/agp/amd-k7-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ static struct agp_bridge_driver amd_irongate_driver = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

static struct agp_device_ids amd_agp_device_ids[] __devinitdata =
Expand Down
11 changes: 9 additions & 2 deletions trunk/drivers/char/agp/amd64-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,18 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i, j, num_entries;
long long tmp;
int mask_type;
struct agp_bridge_data *bridge = mem->bridge;
u32 pte;

num_entries = agp_num_entries();

if (type != 0 || mem->type != 0)
if (type != mem->type)
return -EINVAL;
mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
if (mask_type != 0)
return -EINVAL;


/* Make sure we can fit the range in the gatt table. */
/* FIXME: could wrap */
Expand All @@ -90,7 +96,7 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)

for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
tmp = agp_bridge->driver->mask_memory(agp_bridge,
mem->memory[i], mem->type);
mem->memory[i], mask_type);

BUG_ON(tmp & 0xffffff0000000ffcULL);
pte = (tmp & 0x000000ff00000000ULL) >> 28;
Expand Down Expand Up @@ -247,6 +253,7 @@ static struct agp_bridge_driver amd_8151_driver = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

/* Some basic sanity checks for the aperture. */
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/char/agp/ati-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ static struct agp_bridge_driver ati_generic_bridge = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};


Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/char/agp/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
* fix some real stupidity. It's only by chance we can bump
* past 0.99 at all due to some boolean logic error. */
#define AGPGART_VERSION_MAJOR 0
#define AGPGART_VERSION_MINOR 101
#define AGPGART_VERSION_MINOR 102
static const struct agp_version agp_current_version =
{
.major = AGPGART_VERSION_MAJOR,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/char/agp/efficeon-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ static struct agp_bridge_driver efficeon_driver = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};

static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/char/agp/frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,9 @@ static int agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg)
if (copy_from_user(&alloc, arg, sizeof(struct agp_allocate)))
return -EFAULT;

if (alloc.type >= AGP_USER_TYPES)
return -EINVAL;

memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);

if (memory == NULL)
Expand Down
130 changes: 124 additions & 6 deletions trunk/drivers/char/agp/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,67 @@ static int agp_get_key(void)
return -1;
}

/*
* Use kmalloc if possible for the page list. Otherwise fall back to
* vmalloc. This speeds things up and also saves memory for small AGP
* regions.
*/

void agp_alloc_page_array(size_t size, struct agp_memory *mem)
{
mem->memory = NULL;
mem->vmalloc_flag = 0;

if (size <= 2*PAGE_SIZE) {
mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY);
}
if (mem->memory == NULL) {
mem->memory = vmalloc(size);
mem->vmalloc_flag = 1;
}
}
EXPORT_SYMBOL(agp_alloc_page_array);

void agp_free_page_array(struct agp_memory *mem)
{
if (mem->vmalloc_flag) {
vfree(mem->memory);
} else {
kfree(mem->memory);
}
}
EXPORT_SYMBOL(agp_free_page_array);


static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages)
{
struct agp_memory *new;
unsigned long alloc_size = num_agp_pages*sizeof(struct page *);

new = kmalloc(sizeof(struct agp_memory), GFP_KERNEL);

if (new == NULL)
return NULL;

memset(new, 0, sizeof(struct agp_memory));
new->key = agp_get_key();

if (new->key < 0) {
kfree(new);
return NULL;
}

agp_alloc_page_array(alloc_size, new);

if (new->memory == NULL) {
agp_free_key(new->key);
kfree(new);
return NULL;
}
new->num_scratch_pages = 0;
return new;
}


struct agp_memory *agp_create_memory(int scratch_pages)
{
Expand All @@ -116,14 +177,16 @@ struct agp_memory *agp_create_memory(int scratch_pages)
kfree(new);
return NULL;
}
new->memory = vmalloc(PAGE_SIZE * scratch_pages);

agp_alloc_page_array(PAGE_SIZE * scratch_pages, new);

if (new->memory == NULL) {
agp_free_key(new->key);
kfree(new);
return NULL;
}
new->num_scratch_pages = scratch_pages;
new->type = AGP_NORMAL_MEMORY;
return new;
}
EXPORT_SYMBOL(agp_create_memory);
Expand All @@ -146,6 +209,11 @@ void agp_free_memory(struct agp_memory *curr)
if (curr->is_bound == TRUE)
agp_unbind_memory(curr);

if (curr->type >= AGP_USER_TYPES) {
agp_generic_free_by_type(curr);
return;
}

if (curr->type != 0) {
curr->bridge->driver->free_by_type(curr);
return;
Expand All @@ -157,7 +225,7 @@ void agp_free_memory(struct agp_memory *curr)
flush_agp_mappings();
}
agp_free_key(curr->key);
vfree(curr->memory);
agp_free_page_array(curr);
kfree(curr);
}
EXPORT_SYMBOL(agp_free_memory);
Expand Down Expand Up @@ -188,6 +256,13 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp)
return NULL;

if (type >= AGP_USER_TYPES) {
new = agp_generic_alloc_user(page_count, type);
if (new)
new->bridge = bridge;
return new;
}

if (type != 0) {
new = bridge->driver->alloc_by_type(page_count, type);
if (new)
Expand Down Expand Up @@ -960,6 +1035,7 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
off_t j;
void *temp;
struct agp_bridge_data *bridge;
int mask_type;

bridge = mem->bridge;
if (!bridge)
Expand Down Expand Up @@ -995,7 +1071,12 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
num_entries -= agp_memory_reserved/PAGE_SIZE;
if (num_entries < 0) num_entries = 0;

if (type != 0 || mem->type != 0) {
if (type != mem->type) {
return -EINVAL;
}

mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
if (mask_type != 0) {
/* The generic routines know nothing of memory types */
return -EINVAL;
}
Expand All @@ -1018,7 +1099,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
}

for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j);
writel(bridge->driver->mask_memory(bridge, mem->memory[i], mask_type),
bridge->gatt_table+j);
}
readl(bridge->gatt_table+j-1); /* PCI Posting. */

Expand All @@ -1032,6 +1114,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
{
size_t i;
struct agp_bridge_data *bridge;
int mask_type;

bridge = mem->bridge;
if (!bridge)
Expand All @@ -1040,7 +1123,11 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
if (mem->page_count == 0)
return 0;

if (type != 0 || mem->type != 0) {
if (type != mem->type)
return -EINVAL;

mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
if (mask_type != 0) {
/* The generic routines know nothing of memory types */
return -EINVAL;
}
Expand All @@ -1066,12 +1153,34 @@ EXPORT_SYMBOL(agp_generic_alloc_by_type);

void agp_generic_free_by_type(struct agp_memory *curr)
{
vfree(curr->memory);
agp_free_page_array(curr);
agp_free_key(curr->key);
kfree(curr);
}
EXPORT_SYMBOL(agp_generic_free_by_type);

struct agp_memory *agp_generic_alloc_user(size_t page_count, int type)
{
struct agp_memory *new;
int i;
int pages;

pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
new = agp_create_user_memory(page_count);
if (new == NULL)
return NULL;

for (i = 0; i < page_count; i++) {
new->memory[i] = 0;
}
new->page_count = 0;
new->type = type;
new->num_scratch_pages = pages;

return new;
}
EXPORT_SYMBOL(agp_generic_alloc_user);


/*
* Basic Page Allocation Routines -
Expand Down Expand Up @@ -1165,6 +1274,15 @@ unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge,
}
EXPORT_SYMBOL(agp_generic_mask_memory);

int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge,
int type)
{
if (type >= AGP_USER_TYPES)
return 0;
return type;
}
EXPORT_SYMBOL(agp_generic_type_to_mask_type);

/*
* These functions are implemented according to the AGPv3 spec,
* which covers implementation details that had previously been
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/char/agp/hp-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ struct agp_bridge_driver hp_zx1_driver = {
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
.cant_use_aperture = 1,
};

Expand Down
Loading

0 comments on commit c837e3c

Please sign in to comment.