⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generic.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
				case U32_APER_SIZE:					bridge->current_size = A_IDX32(bridge);					break;					/* This case will never really happen. */				case FIXED_APER_SIZE:				case LVL2_APER_SIZE:				default:					bridge->current_size =					    bridge->current_size;					break;				}				temp = bridge->current_size;			} else {				bridge->aperture_size_idx = i;			}		} while (!table && (i < bridge->driver->num_aperture_sizes));	} else {		size = ((struct aper_size_info_fixed *) temp)->size;		page_order = ((struct aper_size_info_fixed *) temp)->page_order;		num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;		table = alloc_gatt_pages(page_order);	}	if (table == NULL)		return -ENOMEM;	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)		SetPageReserved(page);	bridge->gatt_table_real = (u32 *) table;	agp_gatt_table = (void *)table;	bridge->driver->cache_flush();	bridge->gatt_table = ioremap_nocache(virt_to_gart(table),					(PAGE_SIZE * (1 << page_order)));	bridge->driver->cache_flush();	if (bridge->gatt_table == NULL) {		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)			ClearPageReserved(page);		free_gatt_pages(table, page_order);		return -ENOMEM;	}	bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real);	/* AK: bogus, should encode addresses > 4GB */	for (i = 0; i < num_entries; i++) {		writel(bridge->scratch_page, bridge->gatt_table+i);		readl(bridge->gatt_table+i);	/* PCI Posting. */	}	return 0;}EXPORT_SYMBOL(agp_generic_create_gatt_table);int agp_generic_free_gatt_table(struct agp_bridge_data *bridge){	int page_order;	char *table, *table_end;	void *temp;	struct page *page;	temp = bridge->current_size;	switch (bridge->driver->size_type) {	case U8_APER_SIZE:		page_order = A_SIZE_8(temp)->page_order;		break;	case U16_APER_SIZE:		page_order = A_SIZE_16(temp)->page_order;		break;	case U32_APER_SIZE:		page_order = A_SIZE_32(temp)->page_order;		break;	case FIXED_APER_SIZE:		page_order = A_SIZE_FIX(temp)->page_order;		break;	case LVL2_APER_SIZE:		/* The generic routines can't deal with 2 level gatt's */		return -EINVAL;		break;	default:		page_order = 0;		break;	}	/* Do not worry about freeing memory, because if this is	 * called, then all agp memory is deallocated and removed	 * from the table. */	iounmap(bridge->gatt_table);	table = (char *) bridge->gatt_table_real;	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)		ClearPageReserved(page);	free_gatt_pages(bridge->gatt_table_real, page_order);	agp_gatt_table = NULL;	bridge->gatt_table = NULL;	bridge->gatt_table_real = NULL;	bridge->gatt_bus_addr = 0;	return 0;}EXPORT_SYMBOL(agp_generic_free_gatt_table);int agp_generic_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;	bridge = mem->bridge;	if (!bridge)		return -EINVAL;	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:		/* The generic routines can't deal with 2 level gatt's */		return -EINVAL;		break;	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) {		/* The generic routines know nothing of memory types */		return -EINVAL;	}	/* AK: could wrap */	if ((pg_start + mem->page_count) > num_entries)		return -EINVAL;	j = pg_start;	while (j < (pg_start + mem->page_count)) {		if (!PGE_EMPTY(bridge, readl(bridge->gatt_table+j)))			return -EBUSY;		j++;	}	if (mem->is_flushed == FALSE) {		bridge->driver->cache_flush();		mem->is_flushed = TRUE;	}	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {		writel(bridge->driver->mask_memory(bridge, mem->memory[i], mem->type), bridge->gatt_table+j);		readl(bridge->gatt_table+j);	/* PCI Posting. */	}	bridge->driver->tlb_flush(mem);	return 0;}EXPORT_SYMBOL(agp_generic_insert_memory);int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type){	size_t i;	struct agp_bridge_data *bridge;	bridge = mem->bridge;	if (!bridge)		return -EINVAL;	if (type != 0 || mem->type != 0) {		/* The generic routines know nothing of memory types */		return -EINVAL;	}	/* AK: bogus, should encode addresses > 4GB */	for (i = pg_start; i < (mem->page_count + pg_start); i++) {		writel(bridge->scratch_page, bridge->gatt_table+i);		readl(bridge->gatt_table+i);	/* PCI Posting. */	}	global_cache_flush();	bridge->driver->tlb_flush(mem);	return 0;}EXPORT_SYMBOL(agp_generic_remove_memory);struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type){	return NULL;}EXPORT_SYMBOL(agp_generic_alloc_by_type);void agp_generic_free_by_type(struct agp_memory *curr){	vfree(curr->memory);	agp_free_key(curr->key);	kfree(curr);}EXPORT_SYMBOL(agp_generic_free_by_type);/* * Basic Page Allocation Routines - * These routines handle page allocation and by default they reserve the allocated * memory.  They also handle incrementing the current_memory_agp value, Which is checked * against a maximum value. */void *agp_generic_alloc_page(struct agp_bridge_data *bridge){	struct page * page;	page = alloc_page(GFP_KERNEL);	if (page == NULL)		return NULL;	map_page_into_agp(page);	get_page(page);	SetPageLocked(page);	atomic_inc(&agp_bridge->current_memory_agp);	return page_address(page);}EXPORT_SYMBOL(agp_generic_alloc_page);void agp_generic_destroy_page(void *addr){	struct page *page;	if (addr == NULL)		return;	page = virt_to_page(addr);	unmap_page_from_agp(page);	put_page(page);	unlock_page(page);	free_page((unsigned long)addr);	atomic_dec(&agp_bridge->current_memory_agp);}EXPORT_SYMBOL(agp_generic_destroy_page);/* End Basic Page Allocation Routines *//** * agp_enable  -  initialise the agp point-to-point connection. * * @mode:	agp mode register value to configure with. */void agp_enable(struct agp_bridge_data *bridge, u32 mode){	if (!bridge)		return;	bridge->driver->agp_enable(bridge, mode);}EXPORT_SYMBOL(agp_enable);/* When we remove the global variable agp_bridge from all drivers * then agp_alloc_bridge and agp_generic_find_bridge need to be updated */struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev){	if (list_empty(&agp_bridges))		return NULL;	return agp_bridge;}static void ipi_handler(void *null){	flush_agp_cache();}void global_cache_flush(void){	if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0)		panic(PFX "timed out waiting for the other CPUs!\n");}EXPORT_SYMBOL(global_cache_flush);unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge,	unsigned long addr, int type){	/* memory type is ignored in the generic routine */	if (bridge->driver->masks)		return addr | bridge->driver->masks[0].mask;	else		return addr;}EXPORT_SYMBOL(agp_generic_mask_memory);/* * These functions are implemented according to the AGPv3 spec, * which covers implementation details that had previously been * left open. */int agp3_generic_fetch_size(void){	u16 temp_size;	int i;	struct aper_size_info_16 *values;	pci_read_config_word(agp_bridge->dev, agp_bridge->capndx+AGPAPSIZE, &temp_size);	values = A_SIZE_16(agp_bridge->driver->aperture_sizes);	for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {		if (temp_size == values[i].size_value) {			agp_bridge->previous_size =				agp_bridge->current_size = (void *) (values + i);			agp_bridge->aperture_size_idx = i;			return values[i].size;		}	}	return 0;}EXPORT_SYMBOL(agp3_generic_fetch_size);void agp3_generic_tlbflush(struct agp_memory *mem){	u32 ctrl;	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &ctrl);	pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, ctrl & ~AGPCTRL_GTLBEN);	pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, ctrl);}EXPORT_SYMBOL(agp3_generic_tlbflush);int agp3_generic_configure(void){	u32 temp;	struct aper_size_info_16 *current_size;	current_size = A_SIZE_16(agp_bridge->current_size);	pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);	/* set aperture size */	pci_write_config_word(agp_bridge->dev, agp_bridge->capndx+AGPAPSIZE, current_size->size_value);	/* set gart pointer */	pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPGARTLO, agp_bridge->gatt_bus_addr);	/* enable aperture and GTLB */	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &temp);	pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, temp | AGPCTRL_APERENB | AGPCTRL_GTLBEN);	return 0;}EXPORT_SYMBOL(agp3_generic_configure);void agp3_generic_cleanup(void){	u32 ctrl;	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, &ctrl);	pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+AGPCTRL, ctrl & ~AGPCTRL_APERENB);}EXPORT_SYMBOL(agp3_generic_cleanup);struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] ={	{4096, 1048576, 10,0x000},	{2048,  524288, 9, 0x800},	{1024,  262144, 8, 0xc00},	{ 512,  131072, 7, 0xe00},	{ 256,   65536, 6, 0xf00},	{ 128,   32768, 5, 0xf20},	{  64,   16384, 4, 0xf30},	{  32,    8192, 3, 0xf38},	{  16,    4096, 2, 0xf3c},	{   8,    2048, 1, 0xf3e},	{   4,    1024, 0, 0xf3f}};EXPORT_SYMBOL(agp3_generic_sizes);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -