diff options
Diffstat (limited to 'drivers/char/agp')
-rw-r--r-- | drivers/char/agp/agp.h | 10 | ||||
-rw-r--r-- | drivers/char/agp/ali-agp.c | 27 | ||||
-rw-r--r-- | drivers/char/agp/amd-k7-agp.c | 11 | ||||
-rw-r--r-- | drivers/char/agp/ati-agp.c | 3 | ||||
-rw-r--r-- | drivers/char/agp/backend.c | 12 | ||||
-rw-r--r-- | drivers/char/agp/efficeon-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/generic.c | 19 | ||||
-rw-r--r-- | drivers/char/agp/hp-agp.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/i460-agp.c | 8 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 27 | ||||
-rw-r--r-- | drivers/char/agp/nvidia-agp.c | 3 | ||||
-rw-r--r-- | drivers/char/agp/via-agp.c | 5 |
12 files changed, 86 insertions, 42 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 35ab1a9f8e8b..b83824c41329 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -58,6 +58,9 @@ struct gatt_mask { * devices this will probably be ignored */ }; +#define AGP_PAGE_DESTROY_UNMAP 1 +#define AGP_PAGE_DESTROY_FREE 2 + struct aper_size_info_8 { int size; int num_entries; @@ -113,7 +116,7 @@ struct agp_bridge_driver { struct agp_memory *(*alloc_by_type) (size_t, int); void (*free_by_type)(struct agp_memory *); void *(*agp_alloc_page)(struct agp_bridge_data *); - void (*agp_destroy_page)(void *); + void (*agp_destroy_page)(void *, int flags); int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); }; @@ -176,7 +179,7 @@ struct agp_bridge_data { #define I830_GMCH_MEM_MASK 0x1 #define I830_GMCH_MEM_64M 0x1 #define I830_GMCH_MEM_128M 0 -#define I830_GMCH_GMS_MASK 0xF0 +#define I830_GMCH_GMS_MASK 0x70 #define I830_GMCH_GMS_DISABLED 0x00 #define I830_GMCH_GMS_LOCAL 0x10 #define I830_GMCH_GMS_STOLEN_512 0x20 @@ -190,6 +193,7 @@ struct agp_bridge_data { #define INTEL_I830_ERRSTS 0x92 /* Intel 855GM/852GM registers */ +#define I855_GMCH_GMS_MASK 0xF0 #define I855_GMCH_GMS_STOLEN_0M 0x0 #define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) #define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) @@ -266,7 +270,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type); struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); void agp_generic_free_by_type(struct agp_memory *curr); void *agp_generic_alloc_page(struct agp_bridge_data *bridge); -void agp_generic_destroy_page(void *addr); +void agp_generic_destroy_page(void *addr, int flags); void agp_free_key(int key); int agp_num_entries(void); u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 4941ddb78939..aa5ddb716ffb 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -156,29 +156,34 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) return addr; } -static void ali_destroy_page(void * addr) +static void ali_destroy_page(void * addr, int flags) { if (addr) { - global_cache_flush(); /* is this really needed? --hch */ - agp_generic_destroy_page(addr); - global_flush_tlb(); + if (flags & AGP_PAGE_DESTROY_UNMAP) { + global_cache_flush(); /* is this really needed? --hch */ + agp_generic_destroy_page(addr, flags); + global_flush_tlb(); + } else + agp_generic_destroy_page(addr, flags); } } -static void m1541_destroy_page(void * addr) +static void m1541_destroy_page(void * addr, int flags) { u32 temp; if (addr == NULL) return; - global_cache_flush(); + if (flags & AGP_PAGE_DESTROY_UNMAP) { + global_cache_flush(); - pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); - pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, - (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); - agp_generic_destroy_page(addr); + pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); + pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, + (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | + virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); + } + agp_generic_destroy_page(addr, flags); } diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index df0ddf14b85c..1405a42585e1 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -100,21 +100,16 @@ static int amd_create_gatt_pages(int nr_tables) for (i = 0; i < nr_tables; i++) { entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL); + tables[i] = entry; if (entry == NULL) { - while (i > 0) { - kfree(tables[i-1]); - i--; - } - kfree(tables); retval = -ENOMEM; break; } - tables[i] = entry; retval = amd_create_page_map(entry); if (retval != 0) break; } - amd_irongate_private.num_tables = nr_tables; + amd_irongate_private.num_tables = i; amd_irongate_private.gatt_pages = tables; if (retval != 0) @@ -223,6 +218,8 @@ static int amd_irongate_configure(void) pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!amd_irongate_private.registers) + return -ENOMEM; /* Write out the address of the gatt table */ writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index da7513d7b4e7..2d46b713c8f2 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -213,6 +213,9 @@ static int ati_configure(void) temp = (temp & 0xfffff000); ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!ati_generic_private.registers) + return -ENOMEM; + if (is_r200()) pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); else diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 1b47c89a1b99..832ded20fe70 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -189,9 +189,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) err_out: if (bridge->driver->needs_scratch_page) { - bridge->driver->agp_destroy_page( - gart_to_virt(bridge->scratch_page_real)); + bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), + AGP_PAGE_DESTROY_UNMAP); flush_agp_mappings(); + bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), + AGP_PAGE_DESTROY_FREE); } if (got_gatt) bridge->driver->free_gatt_table(bridge); @@ -215,9 +217,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) { - bridge->driver->agp_destroy_page( - gart_to_virt(bridge->scratch_page_real)); + bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), + AGP_PAGE_DESTROY_UNMAP); flush_agp_mappings(); + bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), + AGP_PAGE_DESTROY_FREE); } } diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index df8da7262853..d78cd09186aa 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -375,6 +375,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, if (!r->start && r->end) { if (pci_assign_resource(pdev, 0)) { printk(KERN_ERR PFX "could not assign resource 0\n"); + agp_put_bridge(bridge); return -ENODEV; } } @@ -386,6 +387,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, */ if (pci_enable_device(pdev)) { printk(KERN_ERR PFX "Unable to Enable PCI device\n"); + agp_put_bridge(bridge); return -ENODEV; } diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 3db4f4076ed4..64b2f6d7059d 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -195,9 +195,12 @@ void agp_free_memory(struct agp_memory *curr) } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { - curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); + curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]), AGP_PAGE_DESTROY_UNMAP); } flush_agp_mappings(); + for (i = 0; i < curr->page_count; i++) { + curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]), AGP_PAGE_DESTROY_FREE); + } } agp_free_key(curr->key); agp_free_page_array(curr); @@ -1176,7 +1179,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) EXPORT_SYMBOL(agp_generic_alloc_page); -void agp_generic_destroy_page(void *addr) +void agp_generic_destroy_page(void *addr, int flags) { struct page *page; @@ -1184,10 +1187,14 @@ void agp_generic_destroy_page(void *addr) return; page = virt_to_page(addr); - unmap_page_from_agp(page); - put_page(page); - free_page((unsigned long)addr); - atomic_dec(&agp_bridge->current_memory_agp); + if (flags & AGP_PAGE_DESTROY_UNMAP) + unmap_page_from_agp(page); + + if (flags & AGP_PAGE_DESTROY_FREE) { + put_page(page); + free_page((unsigned long)addr); + atomic_dec(&agp_bridge->current_memory_agp); + } } EXPORT_SYMBOL(agp_generic_destroy_page); diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index bcdb149c8179..313a133a1172 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -221,6 +221,7 @@ hp_zx1_lba_init (u64 hpa) if (cap != PCI_CAP_ID_AGP) { printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", cap, hp->lba_cap_offset); + iounmap(hp->lba_regs); return -ENODEV; } diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 53354bf83af7..70117df4d067 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -249,6 +249,10 @@ static int i460_create_gatt_table (struct agp_bridge_data *bridge) num_entries = A_SIZE_8(temp)->num_entries; i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); + if (!i460.gatt) { + printk(KERN_ERR PFX "ioremap failed\n"); + return -ENOMEM; + } /* These are no good, the should be removed from the agp_bridge strucure... */ agp_bridge->gatt_table_real = NULL; @@ -532,10 +536,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge) return page; } -static void i460_destroy_page (void *page) +static void i460_destroy_page (void *page, int flags) { if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) { - agp_generic_destroy_page(page); + agp_generic_destroy_page(page, flags); global_flush_tlb(); } } diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 294cdbf4d44d..d87961993ccf 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -400,9 +400,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr) if (curr->page_count == 4) i8xx_destroy_pages(gart_to_virt(curr->memory[0])); else { - agp_bridge->driver->agp_destroy_page( - gart_to_virt(curr->memory[0])); + agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[0]), + AGP_PAGE_DESTROY_UNMAP); global_flush_tlb(); + agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[0]), + AGP_PAGE_DESTROY_FREE); } agp_free_page_array(curr); } @@ -506,7 +508,7 @@ static void intel_i830_init_gtt_entries(void) break; } } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + switch (gmch_ctrl & I855_GMCH_GMS_MASK) { case I855_GMCH_GMS_STOLEN_1M: gtt_entries = MB(1) - KB(size); break; @@ -914,6 +916,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) struct aper_size_info_fixed *size; int num_entries; u32 temp, temp2; + int gtt_map_size = 256 * 1024; size = agp_bridge->current_size; page_order = size->page_order; @@ -923,15 +926,19 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2); - intel_private.gtt = ioremap(temp2, 256 * 1024); + if (IS_G33) + gtt_map_size = 1024 * 1024; /* 1M on G33 */ + intel_private.gtt = ioremap(temp2, gtt_map_size); if (!intel_private.gtt) return -ENOMEM; temp &= 0xfff80000; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) + if (!intel_private.registers) { + iounmap(intel_private.gtt); return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ @@ -985,13 +992,15 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) temp &= 0xfff00000; intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); - if (!intel_private.gtt) - return -ENOMEM; + if (!intel_private.gtt) + return -ENOMEM; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) - return -ENOMEM; + if (!intel_private.registers) { + iounmap(intel_private.gtt); + return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 6cd7373dcdf4..225ed2a53d45 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -157,6 +157,9 @@ static int nvidia_configure(void) nvidia_private.aperture = (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); + if (!nvidia_private.aperture) + return -ENOMEM; + return 0; } diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 9aaf401a8975..0ecc54d327bc 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -399,6 +399,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = .device_id = PCI_DEVICE_ID_VIA_P4M890, .chipset_name = "P4M890", }, + /* P4M900 */ + { + .device_id = PCI_DEVICE_ID_VIA_VT3364, + .chipset_name = "P4M900", + }, { }, /* dummy final entry, always present */ }; |