/* * 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/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 <linux/slab.h> #include <asm/io.h> #ifdef CONFIG_X86 #include <asm/set_memory.h> #endif #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(…); /* * 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) { … } EXPORT_SYMBOL(…); static int agp_get_key(void) { … } /* * 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) { … } EXPORT_SYMBOL(…); static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages) { … } struct agp_memory *agp_create_memory(int scratch_pages) { … } EXPORT_SYMBOL(…); /** * agp_free_memory - free memory associated with an agp_memory pointer. * * @curr: agp_memory pointer to be freed. * * It is the only function that can be called when the backend is not owned * by the caller. (So it can free memory on client death.) */ void agp_free_memory(struct agp_memory *curr) { … } EXPORT_SYMBOL(…); #define ENTRIES_PER_PAGE … /** * agp_allocate_memory - allocate a group of pages of a certain type. * * @bridge: an agp_bridge_data struct allocated for the AGP host bridge. * @page_count: size_t argument of the number of pages * @type: u32 argument of the type of memory to be allocated. * * Every agp bridge device will allow you to allocate AGP_NORMAL_MEMORY which * maps to physical ram. Any other type is device dependent. * * It returns NULL whenever memory is unavailable. */ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, size_t page_count, u32 type) { … } EXPORT_SYMBOL(…); /* End - Generic routines for handling agp_memory structures */ static int agp_return_size(void) { … } int agp_num_entries(void) { … } EXPORT_SYMBOL_GPL(…); /** * agp_copy_info - copy bridge state information * * @bridge: an agp_bridge_data struct allocated for the AGP host bridge. * @info: agp_kern_info pointer. The caller should insure that this pointer is valid. * * This function copies information about the agp bridge device and the state of * the agp backend into an agp_kern_info pointer. */ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info) { … } EXPORT_SYMBOL(…); /* End - Routine to copy over information structure */ /* * Routines for handling swapping of agp_memory into the GATT - * These routines take agp_memory and insert them into the GATT. * They call device specific routines to actually write to the GATT. */ /** * agp_bind_memory - Bind an agp_memory structure into the GATT. * * @curr: agp_memory pointer * @pg_start: an offset into the graphics aperture translation table * * It returns -EINVAL if the pointer == NULL. * It returns -EBUSY if the area of the table requested is already in use. */ int agp_bind_memory(struct agp_memory *curr, off_t pg_start) { … } EXPORT_SYMBOL(…); /** * agp_unbind_memory - Removes an agp_memory structure from the GATT * * @curr: agp_memory pointer to be removed from the GATT. * * It returns -EINVAL if this piece of agp_memory is not currently bound to * the graphics aperture translation table or if the agp_memory pointer == NULL */ int agp_unbind_memory(struct agp_memory *curr) { … } EXPORT_SYMBOL(…); /* End - Routines for handling swapping of agp_memory into the GATT */ /* Generic Agp routines - Start */ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_agpstat) { … } /* * requested_mode = Mode requested by (typically) X. * bridge_agpstat = PCI_AGP_STATUS from agp bridge. * vga_agpstat = PCI_AGP_STATUS from graphic card. */ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_agpstat) { … } /** * agp_collect_device_status - determine correct agp_cmd from various agp_stat's * @bridge: an agp_bridge_data struct allocated for the AGP host bridge. * @requested_mode: requested agp_stat from userspace (Typically from X) * @bridge_agpstat: current agp_stat from AGP bridge. * * This function will hunt for an AGP graphics card, and try to match * the requested mode to the capabilities of both the bridge and the card. */ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode, u32 bridge_agpstat) { … } EXPORT_SYMBOL(…); void agp_device_command(u32 bridge_agpstat, bool agp_v3) { … } EXPORT_SYMBOL(…); void get_agp_version(struct agp_bridge_data *bridge) { … } EXPORT_SYMBOL(…); void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) { … } EXPORT_SYMBOL(…); int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) { … } EXPORT_SYMBOL(…); int agp_generic_free_gatt_table(struct agp_bridge_data *bridge) { … } EXPORT_SYMBOL(…); int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type) { … } EXPORT_SYMBOL(…); int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type) { … } EXPORT_SYMBOL(…); struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type) { … } EXPORT_SYMBOL(…); void agp_generic_free_by_type(struct agp_memory *curr) { … } EXPORT_SYMBOL(…); struct agp_memory *agp_generic_alloc_user(size_t page_count, int type) { … } EXPORT_SYMBOL(…); /* * Basic Page Allocation Routines - * These routines handle page allocation and by default they reserve the allocated * memory. They also handle incrementing the current_memory_agp value, Which is checked * against a maximum value. */ int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *mem, size_t num_pages) { … } EXPORT_SYMBOL(…); struct page *agp_generic_alloc_page(struct agp_bridge_data *bridge) { … } EXPORT_SYMBOL(…); void agp_generic_destroy_pages(struct agp_memory *mem) { … } EXPORT_SYMBOL(…); void agp_generic_destroy_page(struct page *page, int flags) { … } EXPORT_SYMBOL(…); /* End Basic Page Allocation Routines */ /** * agp_enable - initialise the agp point-to-point connection. * * @bridge: an agp_bridge_data struct allocated for the AGP host bridge. * @mode: agp mode register value to configure with. */ void agp_enable(struct agp_bridge_data *bridge, u32 mode) { … } EXPORT_SYMBOL(…); /* When we remove the global variable agp_bridge from all drivers * then agp_alloc_bridge and agp_generic_find_bridge need to be updated */ struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev) { … } static void ipi_handler(void *null) { … } void global_cache_flush(void) { … } EXPORT_SYMBOL(…); unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, int type) { … } EXPORT_SYMBOL(…); int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge, int type) { … } EXPORT_SYMBOL(…); /* * These functions are implemented according to the AGPv3 spec, * which covers implementation details that had previously been * left open. */ int agp3_generic_fetch_size(void) { … } EXPORT_SYMBOL(…); void agp3_generic_tlbflush(struct agp_memory *mem) { … } EXPORT_SYMBOL(…); int agp3_generic_configure(void) { … } EXPORT_SYMBOL(…); void agp3_generic_cleanup(void) { … } EXPORT_SYMBOL(…); const struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] = …; EXPORT_SYMBOL(…);