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

📄 cpqphp_pci.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	unsigned int devfn;	if (!func->is_a_board)		return(ADD_NOT_SUPPORTED);	func = cpqhp_slot_find(func->bus, func->device, index++);	while (func != NULL) {		pci_bus->number = func->bus;		devfn = PCI_DEVFN(func->device, func->function);		pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);		// No adapter present		if (temp_register == 0xFFFFFFFF)			return(NO_ADAPTER_PRESENT);		if (temp_register != func->config_space[0])			return(ADAPTER_NOT_SAME);		// Check for same revision number and class code		pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);		// Adapter not the same		if (temp_register != func->config_space[0x08 >> 2])			return(ADAPTER_NOT_SAME);		// Check for Bridge		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge			// In order to continue checking, we must program the			// bus registers in the bridge to respond to accesses			// for it's subordinate bus(es)			temp_register = func->config_space[0x18 >> 2];			pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);			secondary_bus = (temp_register >> 8) & 0xFF;			next = cpqhp_slot_list[secondary_bus];			while (next != NULL) {				rc = cpqhp_valid_replace(ctrl, next);				if (rc)					return rc;				next = next->next;			}		}		// Check to see if it is a standard config header		else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {			// Check subsystem vendor and ID			pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);			if (temp_register != func->config_space[0x2C >> 2]) {				// If it's a SMART-2 and the register isn't filled				// in, ignore the difference because				// they just have an old rev of the firmware				if (!((func->config_space[0] == 0xAE100E11)				      && (temp_register == 0x00L)))					return(ADAPTER_NOT_SAME);			}			// Figure out IO and memory base lengths			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {				temp_register = 0xFFFFFFFF;				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);				if (base) {	  // If this register is implemented					if (base & 0x01L) {						// IO base						// set base = amount of IO space requested						base = base & 0xFFFFFFFE;						base = (~base) + 1;						type = 1;					} else {						// memory base						base = base & 0xFFFFFFF0;						base = (~base) + 1;						type = 0;					}				} else {					base = 0x0L;					type = 0;				}				// Check information in slot structure				if (func->base_length[(cloop - 0x10) >> 2] != base)					return(ADAPTER_NOT_SAME);				if (func->base_type[(cloop - 0x10) >> 2] != type)					return(ADAPTER_NOT_SAME);			}	// End of base register loop		}		// End of (type 0 config space) else		else {			// this is not a type 0 or 1 config space header so			// we don't know how to do it			return(DEVICE_TYPE_NOT_SUPPORTED);		}		// Get the next function		func = cpqhp_slot_find(func->bus, func->device, index++);	}	return 0;}/* * cpqhp_find_available_resources * * Finds available memory, IO, and IRQ resources for programming * devices which may be added to the system * this function is for hot plug ADD! * * returns 0 if success */  int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start){	u8 temp;	u8 populated_slot;	u8 bridged_slot;	void *one_slot;	struct pci_func *func = NULL;	int i = 10, index;	u32 temp_dword, rc;	struct pci_resource *mem_node;	struct pci_resource *p_mem_node;	struct pci_resource *io_node;	struct pci_resource *bus_node;	void *rom_resource_table;	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);	dbg("rom_resource_table = %p\n", rom_resource_table);	if (rom_resource_table == NULL) {		return -ENODEV;	}	// Sum all resources and setup resource maps	unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);	dbg("unused_IRQ = %x\n", unused_IRQ);	temp = 0;	while (unused_IRQ) {		if (unused_IRQ & 1) {			cpqhp_disk_irq = temp;			break;		}		unused_IRQ = unused_IRQ >> 1;		temp++;	}	dbg("cpqhp_disk_irq= %d\n", cpqhp_disk_irq);	unused_IRQ = unused_IRQ >> 1;	temp++;	while (unused_IRQ) {		if (unused_IRQ & 1) {			cpqhp_nic_irq = temp;			break;		}		unused_IRQ = unused_IRQ >> 1;		temp++;	}	dbg("cpqhp_nic_irq= %d\n", cpqhp_nic_irq);	unused_IRQ = readl(rom_resource_table + PCIIRQ);	temp = 0;	if (!cpqhp_nic_irq) {		cpqhp_nic_irq = ctrl->cfgspc_irq;	}	if (!cpqhp_disk_irq) {		cpqhp_disk_irq = ctrl->cfgspc_irq;	}	dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);	rc = compaq_nvram_load(rom_start, ctrl);	if (rc)		return rc;	one_slot = rom_resource_table + sizeof (struct hrt);	i = readb(rom_resource_table + NUMBER_OF_ENTRIES);	dbg("number_of_entries = %d\n", i);	if (!readb(one_slot + SECONDARY_BUS))		return 1;	dbg("dev|IO base|length|Mem base|length|Pre base|length|PB SB MB\n");	while (i && readb(one_slot + SECONDARY_BUS)) {		u8 dev_func = readb(one_slot + DEV_FUNC);		u8 primary_bus = readb(one_slot + PRIMARY_BUS);		u8 secondary_bus = readb(one_slot + SECONDARY_BUS);		u8 max_bus = readb(one_slot + MAX_BUS);		u16 io_base = readw(one_slot + IO_BASE);		u16 io_length = readw(one_slot + IO_LENGTH);		u16 mem_base = readw(one_slot + MEM_BASE);		u16 mem_length = readw(one_slot + MEM_LENGTH);		u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);		u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);		dbg("%2.2x | %4.4x  | %4.4x | %4.4x   | %4.4x | %4.4x   | %4.4x |%2.2x %2.2x %2.2x\n",		    dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,		    primary_bus, secondary_bus, max_bus);		// If this entry isn't for our controller's bus, ignore it		if (primary_bus != ctrl->bus) {			i--;			one_slot += sizeof (struct slot_rt);			continue;		}		// find out if this entry is for an occupied slot		ctrl->pci_bus->number = primary_bus;		pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);		dbg("temp_D_word = %x\n", temp_dword);		if (temp_dword != 0xFFFFFFFF) {			index = 0;			func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);			while (func && (func->function != (dev_func & 0x07))) {				dbg("func = %p (bus, dev, fun) = (%d, %d, %d)\n", func, primary_bus, dev_func >> 3, index);				func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);			}			// If we can't find a match, skip this table entry			if (!func) {				i--;				one_slot += sizeof (struct slot_rt);				continue;			}			// this may not work and shouldn't be used			if (secondary_bus != primary_bus)				bridged_slot = 1;			else				bridged_slot = 0;			populated_slot = 1;		} else {			populated_slot = 0;			bridged_slot = 0;		}		// If we've got a valid IO base, use it		temp_dword = io_base + io_length;		if ((io_base) && (temp_dword < 0x10000)) {			io_node = kmalloc(sizeof(*io_node), GFP_KERNEL);			if (!io_node)				return -ENOMEM;			io_node->base = io_base;			io_node->length = io_length;			dbg("found io_node(base, length) = %x, %x\n",					io_node->base, io_node->length);			dbg("populated slot =%d \n", populated_slot);			if (!populated_slot) {				io_node->next = ctrl->io_head;				ctrl->io_head = io_node;			} else {				io_node->next = func->io_head;				func->io_head = io_node;			}		}		// If we've got a valid memory base, use it		temp_dword = mem_base + mem_length;		if ((mem_base) && (temp_dword < 0x10000)) {			mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);			if (!mem_node)				return -ENOMEM;			mem_node->base = mem_base << 16;			mem_node->length = mem_length << 16;			dbg("found mem_node(base, length) = %x, %x\n",					mem_node->base, mem_node->length);			dbg("populated slot =%d \n", populated_slot);			if (!populated_slot) {				mem_node->next = ctrl->mem_head;				ctrl->mem_head = mem_node;			} else {				mem_node->next = func->mem_head;				func->mem_head = mem_node;			}		}		// If we've got a valid prefetchable memory base, and		// the base + length isn't greater than 0xFFFF		temp_dword = pre_mem_base + pre_mem_length;		if ((pre_mem_base) && (temp_dword < 0x10000)) {			p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);			if (!p_mem_node)				return -ENOMEM;			p_mem_node->base = pre_mem_base << 16;			p_mem_node->length = pre_mem_length << 16;			dbg("found p_mem_node(base, length) = %x, %x\n",					p_mem_node->base, p_mem_node->length);			dbg("populated slot =%d \n", populated_slot);			if (!populated_slot) {				p_mem_node->next = ctrl->p_mem_head;				ctrl->p_mem_head = p_mem_node;			} else {				p_mem_node->next = func->p_mem_head;				func->p_mem_head = p_mem_node;			}		}		// If we've got a valid bus number, use it		// The second condition is to ignore bus numbers on		// populated slots that don't have PCI-PCI bridges		if (secondary_bus && (secondary_bus != primary_bus)) {			bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);			if (!bus_node)				return -ENOMEM;			bus_node->base = secondary_bus;			bus_node->length = max_bus - secondary_bus + 1;			dbg("found bus_node(base, length) = %x, %x\n",					bus_node->base, bus_node->length);			dbg("populated slot =%d \n", populated_slot);			if (!populated_slot) {				bus_node->next = ctrl->bus_head;				ctrl->bus_head = bus_node;			} else {				bus_node->next = func->bus_head;				func->bus_head = bus_node;			}		}		i--;		one_slot += sizeof (struct slot_rt);	}	// If all of the following fail, we don't have any resources for	// hot plug add	rc = 1;	rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));	rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));	rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));	rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));	return rc;}/* * cpqhp_return_board_resources * * this routine returns all resources allocated to a board to * the available pool. * * returns 0 if success */int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * resources){	int rc = 0;	struct pci_resource *node;	struct pci_resource *t_node;	dbg("%s\n", __FUNCTION__);	if (!func)		return 1;	node = func->io_head;	func->io_head = NULL;	while (node) {		t_node = node->next;		return_resource(&(resources->io_head), node);		node = t_node;	}	node = func->mem_head;	func->mem_head = NULL;	while (node) {		t_node = node->next;		return_resource(&(resources->mem_head), node);		node = t_node;	}	node = func->p_mem_head;	func->p_mem_head = NULL;	while (node) {		t_node = node->next;		return_resource(&(resources->p_mem_head), node);		node = t_node;	}	node = func->bus_head;	func->bus_head = NULL;	while (node) {		t_node = node->next;		return_resource(&(resources->bus_head), node);		node = t_node;	}	rc |= cpqhp_resource_sort_and_combine(&(resources->mem_head));	rc |= cpqhp_resource_sort_and_combine(&(resources->p_mem_head));	rc |= cpqhp_resource_sort_and_combine(&(resources->io_head));	rc |= cpqhp_resource_sort_and_combine(&(resources->bus_head));	return rc;}/* * cpqhp_destroy_resource_list * * Puts node back in the resource list pointed to by head */void cpqhp_destroy_resource_list (struct resource_lists * resources){	struct pci_resource *res, *tres;	res = resources->io_head;	resources->io_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}	res = resources->mem_head;	resources->mem_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}	res = resources->p_mem_head;	resources->p_mem_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}	res = resources->bus_head;	resources->bus_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}}/* * cpqhp_destroy_board_resources * * Puts node back in the resource list pointed to by head */void cpqhp_destroy_board_resources (struct pci_func * func){	struct pci_resource *res, *tres;	res = func->io_head;	func->io_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}	res = func->mem_head;	func->mem_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}	res = func->p_mem_head;	func->p_mem_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}	res = func->bus_head;	func->bus_head = NULL;	while (res) {		tres = res;		res = res->next;		kfree(tres);	}}

⌨️ 快捷键说明

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