/*
* AGPGART driver.
* Copyright (C) 2004 Silicon Graphics, Inc.
* Copyright (C) 2002-2005 Dave Jones.
* Copyright (C) 1999 Jeff Hartmann.
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* TODO:
* - Allocate more than order 0 pages to avoid too much linear map splitting.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/miscdevice.h>
#include <linux/pm.h>
#include <linux/agp_backend.h>
#include <linux/vmalloc.h>
#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
#include "agp.h"
__u32 *agp_gatt_table;
int agp_memory_reserved;
/*
* Needed by the Nforce GART driver for the time being. Would be
* nice to do this some other way instead of needing this export.
*/
EXPORT_SYMBOL_GPL(agp_memory_reserved);
/*
* Generic routines for handling agp_memory structures -
* They use the basic page allocation routines to do the brunt of the work.
*/
void agp_free_key(int key)
{
if (key < 0)
return;
if (key < MAXKEY)
clear_bit(key, agp_bridge->key_list);
}
EXPORT_SYMBOL(agp_free_key);
static int agp_get_key(void)
{
int bit;
bit = find_first_zero_bit(agp_bridge->key_list, MAXKEY);
if (bit < MAXKEY) {
set_bit(bit, agp_bridge->key_list);
return bit;
}
return -1;
}
void agp_flush_chipset(struct agp_bridge_data *bridge)
{
if (bridge->driver->chipset_flush)
bridge->driver->chipset_flush(bridge);
}
EXPORT_SYMBOL(agp_flush_chipset);
/*
* 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)<