📄 agpgart_be.c
字号:
PCI_VENDOR_ID_AMD, AMD_IRONGATE, "AMD", "Irongate", amd_irongate_setup }, { 0, PCI_VENDOR_ID_AMD, AMD_GENERIC, "AMD", "Generic", amd_irongate_setup },#endif /* CONFIG_AGP_AMD */#ifdef CONFIG_AGP_INTEL { PCI_DEVICE_ID_INTEL_82443LX_0, PCI_VENDOR_ID_INTEL, INTEL_LX, "Intel", "440LX", intel_generic_setup }, { PCI_DEVICE_ID_INTEL_82443BX_0, PCI_VENDOR_ID_INTEL, INTEL_BX, "Intel", "440BX", intel_generic_setup }, { PCI_DEVICE_ID_INTEL_82443GX_0, PCI_VENDOR_ID_INTEL, INTEL_GX, "Intel", "440GX", intel_generic_setup }, /* could we add support for PCI_DEVICE_ID_INTEL_815_1 too ? */ { PCI_DEVICE_ID_INTEL_815_0, PCI_VENDOR_ID_INTEL, INTEL_I815, "Intel", "i815", intel_generic_setup }, { PCI_DEVICE_ID_INTEL_840_0, PCI_VENDOR_ID_INTEL, INTEL_I840, "Intel", "i840", intel_840_setup }, { PCI_DEVICE_ID_INTEL_850_0, PCI_VENDOR_ID_INTEL, INTEL_I850, "Intel", "i850", intel_850_setup }, { 0, PCI_VENDOR_ID_INTEL, INTEL_GENERIC, "Intel", "Generic", intel_generic_setup },#endif /* CONFIG_AGP_INTEL */#ifdef CONFIG_AGP_SIS { PCI_DEVICE_ID_SI_630, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "630", sis_generic_setup }, { PCI_DEVICE_ID_SI_540, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "540", sis_generic_setup }, { PCI_DEVICE_ID_SI_620, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "620", sis_generic_setup }, { PCI_DEVICE_ID_SI_530, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "530", sis_generic_setup }, { PCI_DEVICE_ID_SI_630, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "Generic", sis_generic_setup }, { PCI_DEVICE_ID_SI_540, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "Generic", sis_generic_setup }, { PCI_DEVICE_ID_SI_620, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "Generic", sis_generic_setup }, { PCI_DEVICE_ID_SI_530, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "Generic", sis_generic_setup }, { 0, PCI_VENDOR_ID_SI, SIS_GENERIC, "SiS", "Generic", sis_generic_setup },#endif /* CONFIG_AGP_SIS */#ifdef CONFIG_AGP_VIA { PCI_DEVICE_ID_VIA_8501_0, PCI_VENDOR_ID_VIA, VIA_MVP4, "Via", "MVP4", via_generic_setup }, { PCI_DEVICE_ID_VIA_82C597_0, PCI_VENDOR_ID_VIA, VIA_VP3, "Via", "VP3", via_generic_setup }, { PCI_DEVICE_ID_VIA_82C598_0, PCI_VENDOR_ID_VIA, VIA_MVP3, "Via", "MVP3", via_generic_setup }, { PCI_DEVICE_ID_VIA_82C691_0, PCI_VENDOR_ID_VIA, VIA_APOLLO_PRO, "Via", "Apollo Pro", via_generic_setup }, { PCI_DEVICE_ID_VIA_8371_0, PCI_VENDOR_ID_VIA, VIA_APOLLO_KX133, "Via", "Apollo Pro KX133", via_generic_setup }, { PCI_DEVICE_ID_VIA_8363_0, PCI_VENDOR_ID_VIA, VIA_APOLLO_KT133, "Via", "Apollo Pro KT133", via_generic_setup }, { 0, PCI_VENDOR_ID_VIA, VIA_GENERIC, "Via", "Generic", via_generic_setup },#endif /* CONFIG_AGP_VIA */ { 0, }, /* dummy final entry, always present */};/* scan table above for supported devices */static int __init agp_lookup_host_bridge (struct pci_dev *pdev){ int i; for (i = 0; i < ARRAY_SIZE (agp_bridge_info); i++) if (pdev->vendor == agp_bridge_info[i].vendor_id) break; if (i >= ARRAY_SIZE (agp_bridge_info)) { printk (KERN_DEBUG PFX "unsupported bridge\n"); return -ENODEV; } while ((i < ARRAY_SIZE (agp_bridge_info)) && (agp_bridge_info[i].vendor_id == pdev->vendor)) { if (pdev->device == agp_bridge_info[i].device_id) { printk (KERN_INFO PFX "Detected %s %s chipset\n", agp_bridge_info[i].vendor_name, agp_bridge_info[i].chipset_name); agp_bridge.type = agp_bridge_info[i].chipset; return agp_bridge_info[i].chipset_setup (pdev); } i++; } i--; /* point to vendor generic entry (device_id == 0) */ /* try init anyway, if user requests it AND * there is a 'generic' bridge entry for this vendor */ if (agp_try_unsupported && agp_bridge_info[i].device_id == 0) { printk(KERN_WARNING PFX "Trying generic %s routines" " for device id: %04x\n", agp_bridge_info[i].vendor_name, pdev->device); agp_bridge.type = agp_bridge_info[i].chipset; return agp_bridge_info[i].chipset_setup (pdev); } printk(KERN_ERR PFX "Unsupported %s chipset (device id: %04x)," " you might want to try agp_try_unsupported=1.\n", agp_bridge_info[i].vendor_name, pdev->device); return -ENODEV;}/* Supported Device Scanning routine */static int __init agp_find_supported_device(void){ struct pci_dev *dev = NULL; u8 cap_ptr = 0x00; u32 cap_id, scratch; if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) == NULL) return -ENODEV; agp_bridge.dev = dev; /* Need to test for I810 here */#ifdef CONFIG_AGP_I810 if (dev->vendor == PCI_VENDOR_ID_INTEL) { struct pci_dev *i810_dev; switch (dev->device) { case PCI_DEVICE_ID_INTEL_810_0: i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_810_1, NULL); if (i810_dev == NULL) { printk(KERN_ERR PFX "Detected an Intel i810," " but could not find the secondary" " device.\n"); return -ENODEV; } printk(KERN_INFO PFX "Detected an Intel " "i810 Chipset.\n"); agp_bridge.type = INTEL_I810; return intel_i810_setup (i810_dev); case PCI_DEVICE_ID_INTEL_810_DC100_0: i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_810_DC100_1, NULL); if (i810_dev == NULL) { printk(KERN_ERR PFX "Detected an Intel i810 " "DC100, but could not find the " "secondary device.\n"); return -ENODEV; } printk(KERN_INFO PFX "Detected an Intel i810 " "DC100 Chipset.\n"); agp_bridge.type = INTEL_I810; return intel_i810_setup(i810_dev); case PCI_DEVICE_ID_INTEL_810_E_0: i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_810_E_1, NULL); if (i810_dev == NULL) { printk(KERN_ERR PFX "Detected an Intel i810 E" ", but could not find the secondary " "device.\n"); return -ENODEV; } printk(KERN_INFO PFX "Detected an Intel i810 E " "Chipset.\n"); agp_bridge.type = INTEL_I810; return intel_i810_setup(i810_dev); case PCI_DEVICE_ID_INTEL_815_0: /* The i815 can operate either as an i810 style * integrated device, or as an AGP4X motherboard. * * This only addresses the first mode: */ i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_815_1, NULL); if (i810_dev == NULL) { printk(KERN_ERR PFX "agpgart: Detected an " "Intel i815, but could not find the" " secondary device.\n"); agp_bridge.type = NOT_SUPPORTED; return -ENODEV; } printk(KERN_INFO PFX "agpgart: Detected an Intel i815 " "Chipset.\n"); agp_bridge.type = INTEL_I810; return intel_i810_setup(i810_dev); default: break; } }#endif /* CONFIG_AGP_I810 */ /* find capndx */ pci_read_config_dword(dev, 0x04, &scratch); if (!(scratch & 0x00100000)) return -ENODEV; pci_read_config_byte(dev, 0x34, &cap_ptr); if (cap_ptr != 0x00) { do { pci_read_config_dword(dev, cap_ptr, &cap_id); if ((cap_id & 0xff) != 0x02) cap_ptr = (cap_id >> 8) & 0xff; } while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00)); } if (cap_ptr == 0x00) return -ENODEV; agp_bridge.capndx = cap_ptr; /* Fill in the mode register */ pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &agp_bridge.mode); /* probe for known chipsets */ return agp_lookup_host_bridge (dev);}struct agp_max_table { int mem; int agp;};static struct agp_max_table maxes_table[9] __initdata ={ {0, 0}, {32, 4}, {64, 28}, {128, 96}, {256, 204}, {512, 440}, {1024, 942}, {2048, 1920}, {4096, 3932}};static int __init agp_find_max (void){ long memory, index, result; memory = virt_to_phys(high_memory) >> 20; index = 1; while ((memory > maxes_table[index].mem) && (index < 8)) { index++; } result = maxes_table[index - 1].agp + ( (memory - maxes_table[index - 1].mem) * (maxes_table[index].agp - maxes_table[index - 1].agp)) / (maxes_table[index].mem - maxes_table[index - 1].mem); printk(KERN_INFO PFX "Maximum main memory to use " "for agp memory: %ldM\n", result); result = result << (20 - PAGE_SHIFT); return result;}#define AGPGART_VERSION_MAJOR 0#define AGPGART_VERSION_MINOR 99static agp_version agp_current_version ={ AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR};static int __init agp_backend_initialize(void){ int size_value, rc, got_gatt=0, got_keylist=0; memset(&agp_bridge, 0, sizeof(struct agp_bridge_data)); agp_bridge.type = NOT_SUPPORTED; agp_bridge.max_memory_agp = agp_find_max(); agp_bridge.version = &agp_current_version; rc = agp_find_supported_device(); if (rc) { /* not KERN_ERR because error msg should have already printed */ printk(KERN_DEBUG PFX "no supported devices found.\n"); return rc; } if (agp_bridge.needs_scratch_page == TRUE) { agp_bridge.scratch_page = agp_alloc_page(); if (agp_bridge.scratch_page == 0) { printk(KERN_ERR PFX "unable to get memory for " "scratch page.\n"); return -ENOMEM; } agp_bridge.scratch_page = virt_to_phys((void *) agp_bridge.scratch_page); agp_bridge.scratch_page = agp_bridge.mask_memory(agp_bridge.scratch_page, 0); } size_value = agp_bridge.fetch_size(); if (size_value == 0) { printk(KERN_ERR PFX "unable to detrimine aperture size.\n"); rc = -EINVAL; goto err_out; } if (agp_bridge.create_gatt_table()) { printk(KERN_ERR PFX "unable to get memory for graphics " "translation table.\n"); rc = -ENOMEM; goto err_out; } got_gatt = 1; agp_bridge.key_list = vmalloc(PAGE_SIZE * 4); if (agp_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(agp_bridge.key_list, 0, PAGE_SIZE * 4); if (agp_bridge.configure()) { printk(KERN_ERR PFX "error configuring host chipset.\n"); rc = -EINVAL; goto err_out; } printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n", size_value, agp_bridge.gart_bus_addr); return 0;err_out: if (agp_bridge.needs_scratch_page == TRUE) { agp_bridge.scratch_page &= ~(0x00000fff); agp_destroy_page((unsigned long) phys_to_virt(agp_bridge.scratch_page)); } if (got_gatt) agp_bridge.free_gatt_table(); if (got_keylist) vfree(agp_bridge.key_list); return rc;}/* cannot be __exit b/c as it could be called from __init code */static void agp_backend_cleanup(void){ agp_bridge.cleanup(); agp_bridge.free_gatt_table(); vfree(agp_bridge.key_list); if (agp_bridge.needs_scratch_page == TRUE) { agp_bridge.scratch_page &= ~(0x00000fff); agp_destroy_page((unsigned long) phys_to_virt(agp_bridge.scratch_page)); }}extern int agp_frontend_initialize(void);extern void agp_frontend_cleanup(void);static const drm_agp_t drm_agp = { &agp_free_memory, &agp_allocate_memory, &agp_bind_memory, &agp_unbind_memory, &agp_enable, &agp_backend_acquire, &agp_backend_release, &agp_copy_info};static int __init agp_init(void){ int ret_val; printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Jeff Hartmann\n", AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR); ret_val = agp_backend_initialize(); if (ret_val) { agp_bridge.type = NOT_SUPPORTED; return ret_val; } ret_val = agp_frontend_initialize(); if (ret_val) { agp_bridge.type = NOT_SUPPORTED; agp_backend_cleanup(); return ret_val; } inter_module_register("drm_agp", THIS_MODULE, &drm_agp); return 0;}static void __exit agp_cleanup(void){ agp_frontend_cleanup(); agp_backend_cleanup(); inter_module_unregister("drm_agp");}module_init(agp_init);module_exit(agp_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -