static void i460_free_large_page (struct lp_desc *lp) { kfree(lp->alloced_map); lp->alloced_map = NULL; free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); }
/* 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), AGP_PAGE_DESTROY_UNMAP); bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), AGP_PAGE_DESTROY_FREE); } }
static int __init hp_zx1_ioc_shared(void) { struct _hp_private *hp = &hp_private; printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR shared with sba_iommu\n"); /* * IOC already configured by sba_iommu module; just use * its setup. We assume: * - IOVA space is 1Gb in size * - first 512Mb is IOMMU, second 512Mb is GART */ hp->io_tlb_ps = readq(hp->ioc_regs+HP_ZX1_TCNFG); switch (hp->io_tlb_ps) { case 0: hp->io_tlb_shift = 12; break; case 1: hp->io_tlb_shift = 13; break; case 2: hp->io_tlb_shift = 14; break; case 3: hp->io_tlb_shift = 16; break; default: printk(KERN_ERR PFX "Invalid IOTLB page size " "configuration 0x%x\n", hp->io_tlb_ps); hp->gatt = NULL; hp->gatt_entries = 0; return -ENODEV; } hp->io_page_size = 1 << hp->io_tlb_shift; hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size; hp->iova_base = readq(hp->ioc_regs+HP_ZX1_IBASE) & ~0x1; hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE; hp->gart_size = HP_ZX1_GART_SIZE; hp->gatt_entries = hp->gart_size / hp->io_page_size; hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { /* Normal case when no AGP device in system */ hp->gatt = NULL; hp->gatt_entries = 0; printk(KERN_ERR PFX "No reserved IO PDIR entry found; " "GART disabled\n"); return -ENODEV; } 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); if (bridge->key_list) { 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)); }
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; } 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)); if (got_gatt) bridge->driver->free_gatt_table(bridge); if (got_keylist) { vfree(bridge->key_list); bridge->key_list = NULL; } return rc; }