cregit-Linux how code gets into the kernel

Release 4.7 drivers/char/agp/sgi-agp.c

Directory: drivers/char/agp
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2003-2005 Silicon Graphics, Inc.  All Rights Reserved.
 */

/*
 * SGI TIOCA AGPGART routines.
 *
 */

#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/agp_backend.h>
#include <asm/sn/addrs.h>
#include <asm/sn/io.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/tioca_provider.h>
#include "agp.h"

extern int agp_memory_reserved;
extern uint32_t tioca_gart_found;
extern struct list_head tioca_list;

static struct agp_bridge_data **sgi_tioca_agp_bridges;

/*
 * The aperature size and related information is set up at TIOCA init time.
 * Values for this table will be extracted and filled in at
 * sgi_tioca_fetch_size() time.
 */


static struct aper_size_info_fixed sgi_tioca_sizes[] = {
	{0, 0, 0},
};


static struct page *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) { struct page *page; int nid; struct tioca_kernel *info = (struct tioca_kernel *)bridge->dev_private_data; nid = info->ca_closest_node; page = alloc_pages_node(nid, GFP_KERNEL, 0); if (!page) return NULL; get_page(page); atomic_inc(&agp_bridge->current_memory_agp); return page; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones7497.37%266.67%
dave airliedave airlie22.63%133.33%
Total76100.00%3100.00%

/* * Flush GART tlb's. Cannot selectively flush based on memory so the mem * arg is ignored. */
static void sgi_tioca_tlbflush(struct agp_memory *mem) { tioca_tlbflush(mem->bridge->dev_private_data); }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones20100.00%1100.00%
Total20100.00%1100.00%

/* * Given an address of a host physical page, turn it into a valid gart * entry. */
static unsigned long sgi_tioca_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, int type) { return tioca_physpage_to_gart(addr); }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones2291.67%150.00%
david woodhousedavid woodhouse28.33%150.00%
Total24100.00%2100.00%


static void sgi_tioca_agp_enable(struct agp_bridge_data *bridge, u32 mode) { tioca_fastwrite_enable(bridge->dev_private_data); }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones21100.00%1100.00%
Total21100.00%1100.00%

/* * sgi_tioca_configure() doesn't have anything to do since the base CA driver * has alreay set up the GART. */
static int sgi_tioca_configure(void) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones11100.00%1100.00%
Total11100.00%1100.00%

/* * Determine gfx aperature size. This has already been determined by the * CA driver init, so just need to set agp_bridge values accordingly. */
static int sgi_tioca_fetch_size(void) { struct tioca_kernel *info = (struct tioca_kernel *)agp_bridge->dev_private_data; sgi_tioca_sizes[0].size = info->ca_gfxap_size / MB(1); sgi_tioca_sizes[0].num_entries = info->ca_gfxgart_entries; return sgi_tioca_sizes[0].size; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones57100.00%1100.00%
Total57100.00%1100.00%


static int sgi_tioca_create_gatt_table(struct agp_bridge_data *bridge) { struct tioca_kernel *info = (struct tioca_kernel *)bridge->dev_private_data; bridge->gatt_table_real = (u32 *) info->ca_gfxgart; bridge->gatt_table = bridge->gatt_table_real; bridge->gatt_bus_addr = info->ca_gfxgart_base; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones56100.00%1100.00%
Total56100.00%1100.00%


static int sgi_tioca_free_gatt_table(struct agp_bridge_data *bridge) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones14100.00%1100.00%
Total14100.00%1100.00%


static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, int type) { int num_entries; size_t i; off_t j; void *temp; struct agp_bridge_data *bridge; u64 *table; bridge = mem->bridge; if (!bridge) return -EINVAL; table = (u64 *)bridge->gatt_table; temp = bridge->current_size; switch (bridge->driver->size_type) { case U8_APER_SIZE: num_entries = A_SIZE_8(temp)->num_entries; break; case U16_APER_SIZE: num_entries = A_SIZE_16(temp)->num_entries; break; case U32_APER_SIZE: num_entries = A_SIZE_32(temp)->num_entries; break; case FIXED_APER_SIZE: num_entries = A_SIZE_FIX(temp)->num_entries; break; case LVL2_APER_SIZE: return -EINVAL; default: num_entries = 0; break; } num_entries -= agp_memory_reserved / PAGE_SIZE; if (num_entries < 0) num_entries = 0; if (type != 0 || mem->type != 0) { return -EINVAL; } if ((pg_start + mem->page_count) > num_entries) return -EINVAL; j = pg_start; while (j < (pg_start + mem->page_count)) { if (table[j]) return -EBUSY; j++; } if (!mem->is_flushed) { bridge->driver->cache_flush(); mem->is_flushed = true; } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { table[j] = bridge->driver->mask_memory(bridge, page_to_phys(mem->pages[i]), mem->type); } bridge->driver->tlb_flush(mem); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones28791.69%120.00%
michael wernermichael werner206.39%120.00%
david woodhousedavid woodhouse30.96%120.00%
joe perchesjoe perches20.64%120.00%
dave airliedave airlie10.32%120.00%
Total313100.00%5100.00%


static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, int type) { size_t i; struct agp_bridge_data *bridge; u64 *table; bridge = mem->bridge; if (!bridge) return -EINVAL; if (type != 0 || mem->type != 0) { return -EINVAL; } table = (u64 *)bridge->gatt_table; for (i = pg_start; i < (mem->page_count + pg_start); i++) { table[i] = 0; } bridge->driver->tlb_flush(mem); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones9584.82%150.00%
michael wernermichael werner1715.18%150.00%
Total112100.00%2100.00%


static void sgi_tioca_cache_flush(void) { }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones7100.00%1100.00%
Total7100.00%1100.00%

/* * Cleanup. Nothing to do as the CA driver owns the GART. */
static void sgi_tioca_cleanup(void) { }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones7100.00%1100.00%
Total7100.00%1100.00%


static struct agp_bridge_data *sgi_tioca_find_bridge(struct pci_dev *pdev) { struct agp_bridge_data *bridge; list_for_each_entry(bridge, &agp_bridges, list) { if (bridge->dev->bus == pdev->bus) break; } return bridge; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones44100.00%1100.00%
Total44100.00%1100.00%

const struct agp_bridge_driver sgi_tioca_driver = { .owner = THIS_MODULE, .size_type = U16_APER_SIZE, .configure = sgi_tioca_configure, .fetch_size = sgi_tioca_fetch_size, .cleanup = sgi_tioca_cleanup, .tlb_flush = sgi_tioca_tlbflush, .mask_memory = sgi_tioca_mask_memory, .agp_enable = sgi_tioca_agp_enable, .cache_flush = sgi_tioca_cache_flush, .create_gatt_table = sgi_tioca_create_gatt_table, .free_gatt_table = sgi_tioca_free_gatt_table, .insert_memory = sgi_tioca_insert_memory, .remove_memory = sgi_tioca_remove_memory, .alloc_by_type = agp_generic_alloc_by_type, .free_by_type = agp_generic_free_by_type, .agp_alloc_page = sgi_tioca_alloc_page, .agp_destroy_page = agp_generic_destroy_page, .agp_type_to_mask_type = agp_generic_type_to_mask_type, .cant_use_aperture = true, .needs_scratch_page = false, .num_aperture_sizes = 1, };
static int agp_sgi_init(void) { unsigned int j; struct tioca_kernel *info; struct pci_dev *pdev = NULL; if (tioca_gart_found) printk(KERN_INFO PFX "SGI TIO CA GART driver initialized.\n"); else return 0; sgi_tioca_agp_bridges = kmalloc(tioca_gart_found * sizeof(struct agp_bridge_data *), GFP_KERNEL); if (!sgi_tioca_agp_bridges) return -ENOMEM; j = 0; list_for_each_entry(info, &tioca_list, ca_list) { if (list_empty(info->ca_devices)) continue; list_for_each_entry(pdev, info->ca_devices, bus_list) { u8 cap_ptr; if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8)) continue; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); if (!cap_ptr) continue; } sgi_tioca_agp_bridges[j] = agp_alloc_bridge(); printk(KERN_INFO PFX "bridge %d = 0x%p\n", j, sgi_tioca_agp_bridges[j]); if (sgi_tioca_agp_bridges[j]) { sgi_tioca_agp_bridges[j]->dev = pdev; sgi_tioca_agp_bridges[j]->dev_private_data = info; sgi_tioca_agp_bridges[j]->driver = &sgi_tioca_driver; sgi_tioca_agp_bridges[j]->gart_bus_addr = info->ca_gfxap_base; sgi_tioca_agp_bridges[j]->mode = (0x7D << 24) | /* 126 requests */ (0x1 << 9) | /* SBA supported */ (0x1 << 5) | /* 64-bit addresses supported */ (0x1 << 4) | /* FW supported */ (0x1 << 3) | /* AGP 3.0 mode */ 0x2; /* 8x transfer only */ sgi_tioca_agp_bridges[j]->current_size = sgi_tioca_agp_bridges[j]->previous_size = (void *)&sgi_tioca_sizes[0]; agp_add_bridge(sgi_tioca_agp_bridges[j]); } j++; } agp_find_bridge = &sgi_tioca_find_bridge; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones26995.39%250.00%
andrew mortonandrew morton93.19%125.00%
bjorn helgaasbjorn helgaas41.42%125.00%
Total282100.00%4100.00%


static void agp_sgi_cleanup(void) { kfree(sgi_tioca_agp_bridges); sgi_tioca_agp_bridges = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones17100.00%1100.00%
Total17100.00%1100.00%

module_init(agp_sgi_init); module_exit(agp_sgi_cleanup); MODULE_LICENSE("GPL and additional rights");

Overall Contributors

PersonTokensPropCommitsCommitProp
dave jonesdave jones119194.15%323.08%
michael wernermichael werner372.92%17.69%
andrew mortonandrew morton90.71%17.69%
thomas hellstromthomas hellstrom50.40%17.69%
david woodhousedavid woodhouse50.40%17.69%
bjorn helgaasbjorn helgaas40.32%17.69%
joe perchesjoe perches40.32%17.69%
tejun heotejun heo30.24%17.69%
dave airliedave airlie30.24%17.69%
tony lucktony luck30.24%17.69%
ryusuke konishiryusuke konishi10.08%17.69%
Total1265100.00%13100.00%
Directory: drivers/char/agp
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}