static int drm_set_caching(struct drm_ttm *ttm, int noncached) { int i; struct page **cur_page; int do_tlbflush = 0; if ((ttm->page_flags & DRM_TTM_PAGE_UNCACHED) == noncached) return 0; if (noncached) drm_ttm_cache_flush(); for (i = 0; i < ttm->num_pages; ++i) { cur_page = ttm->pages + i; if (*cur_page) { if (!PageHighMem(*cur_page)) { if (noncached) { map_page_into_agp(*cur_page); } else { unmap_page_from_agp(*cur_page); } do_tlbflush = 1; } } } #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) if (do_tlbflush) { flush_agp_mappings(); } #endif DRM_FLAG_MASKED(ttm->page_flags, noncached, DRM_TTM_PAGE_UNCACHED); return 0; }
/* cannot be __exit b/c as it could be called from __init code */ static void agp_backend_cleanup(struct agp_bridge_data *bridge) { if (bridge->driver->cleanup) bridge->driver->cleanup(); if (bridge->driver->free_gatt_table) bridge->driver->free_gatt_table(bridge); vfree(bridge->key_list); bridge->key_list = NULL; if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) { bridge->driver->agp_destroy_page( gart_to_virt(bridge->scratch_page_real)); flush_agp_mappings(); } }
static int agp_backend_initialize(struct agp_bridge_data *bridge) { int size_value, rc, got_gatt=0, got_keylist=0; bridge->max_memory_agp = agp_find_max(); bridge->version = &agp_current_version; if (bridge->driver->needs_scratch_page) { void *addr = bridge->driver->agp_alloc_page(bridge); if (!addr) { printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); return -ENOMEM; } flush_agp_mappings(); bridge->scratch_page_real = virt_to_gart(addr); bridge->scratch_page = bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); } size_value = bridge->driver->fetch_size(); if (size_value == 0) { printk(KERN_ERR PFX "unable to determine aperture size.\n"); rc = -EINVAL; goto err_out; } if (bridge->driver->create_gatt_table(bridge)) { printk(KERN_ERR PFX "unable to get memory for graphics translation table.\n"); rc = -ENOMEM; goto err_out; } got_gatt = 1; bridge->key_list = vmalloc(PAGE_SIZE * 4); if (bridge->key_list == NULL) { printk(KERN_ERR PFX "error allocating memory for key lists.\n"); rc = -ENOMEM; goto err_out; } got_keylist = 1; /* FIXME vmalloc'd memory not guaranteed contiguous */ memset(bridge->key_list, 0, PAGE_SIZE * 4); if (bridge->driver->configure()) { printk(KERN_ERR PFX "error configuring host chipset.\n"); rc = -EINVAL; goto err_out; } return 0; err_out: if (bridge->driver->needs_scratch_page) { bridge->driver->agp_destroy_page( gart_to_virt(bridge->scratch_page_real)); flush_agp_mappings(); } if (got_gatt) bridge->driver->free_gatt_table(bridge); if (got_keylist) { vfree(bridge->key_list); bridge->key_list = NULL; } return rc; }