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

📄 ibmphp_pci.c

📁 audio driver for hotplug pci on linux 2.6.27
💻 C
📖 第 1 页 / 共 4 页
字号:
				/* pfmem */				debug ("PFMEM SPACE\n");				len[count] = bar[count] & 0xFFFFFFF0;				len[count] = ~len[count] + 1;				debug ("len[count] in PFMEM %x, count %d\n", len[count], count);				pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);				if (!pfmem[count]) {					err ("out of system memory\n");					return -ENOMEM;				}				pfmem[count]->type = PFMEM;				pfmem[count]->busno = func->busno;				pfmem[count]->devfunc = PCI_DEVFN(func->device,							func->function);				pfmem[count]->len = len[count];				pfmem[count]->fromMem = 0;				if (ibmphp_check_resource (pfmem[count], 0) == 0) {					ibmphp_add_resource (pfmem[count]);					func->pfmem[count] = pfmem[count];				} else {					mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);					if (!mem_tmp) {						err ("out of system memory\n");						kfree (pfmem[count]);						return -ENOMEM;					}					mem_tmp->type = MEM;					mem_tmp->busno = pfmem[count]->busno;					mem_tmp->devfunc = pfmem[count]->devfunc;					mem_tmp->len = pfmem[count]->len;					debug ("there's no pfmem... going into mem.\n");					if (ibmphp_check_resource (mem_tmp, 0) == 0) {						ibmphp_add_resource (mem_tmp);						pfmem[count]->fromMem = 1;						pfmem[count]->rangeno = mem_tmp->rangeno;						pfmem[count]->start = mem_tmp->start;						pfmem[count]->end = mem_tmp->end;						ibmphp_add_pfmem_from_mem (pfmem[count]);						func->pfmem[count] = pfmem[count];					} else {						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",						     func->busno, func->device, len[count]);						kfree (mem_tmp);						kfree (pfmem[count]);						return -EIO;					}				}				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);				/*_______________This is for debugging purposes only______________________________*/								debug ("b4 writing, start address is %x\n", func->pfmem[count]->start);				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);				debug ("after writing, start address is %x\n", bar[count]);				/*_________________________________________________________________________________*/				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */					debug ("inside the mem 64 case, count %d\n", count);					count += 1;					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);				}			} else {				/* regular memory */				debug ("REGULAR MEM SPACE\n");				len[count] = bar[count] & 0xFFFFFFF0;				len[count] = ~len[count] + 1;				debug ("len[count] in Mem %x, count %d\n", len[count], count);				mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);				if (!mem[count]) {					err ("out of system memory\n");					return -ENOMEM;				}				mem[count]->type = MEM;				mem[count]->busno = func->busno;				mem[count]->devfunc = PCI_DEVFN(func->device,							func->function);				mem[count]->len = len[count];				if (ibmphp_check_resource (mem[count], 0) == 0) {					ibmphp_add_resource (mem[count]);					func->mem[count] = mem[count];				} else {					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",					     func->busno, func->device, len[count]);					kfree (mem[count]);					return -EIO;				}				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);				/* _______________________This is for debugging purposes only _______________________*/				debug ("b4 writing, start address is %x\n", func->mem[count]->start);				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);				debug ("after writing, the address is %x\n", bar[count]);				/* __________________________________________________________________________________*/				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {					/* takes up another dword */					debug ("inside mem 64 case, reg. mem, count %d\n", count);					count += 1;					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);				}			}		}		/* end of mem */	}			/* end of for */	func->bus = 0;		/* To indicate that this is not a PPB */	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);	if ((irq > 0x00) && (irq < 0x05))		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);	pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);	pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);	return 0;}/****************************************************************************** * This routine configures a PCI-2-PCI bridge and the functions behind it * Parameters: pci_func * Returns:  ******************************************************************************/static int configure_bridge (struct pci_func **func_passed, u8 slotno){	int count;	int i;	int rc;	u8 sec_number;	u8 io_base;	u16 pfmem_base;	u32 bar[2];	u32 len[2];	u8 flag_io = 0;	u8 flag_mem = 0;	u8 flag_pfmem = 0;	u8 need_io_upper = 0;	u8 need_pfmem_upper = 0;	struct res_needed *amount_needed = NULL;	struct resource_node *io = NULL;	struct resource_node *bus_io[2] = {NULL, NULL};	struct resource_node *mem = NULL;	struct resource_node *bus_mem[2] = {NULL, NULL};	struct resource_node *mem_tmp = NULL;	struct resource_node *pfmem = NULL;	struct resource_node *bus_pfmem[2] = {NULL, NULL};	struct bus_node *bus;	u32 address[] = {		PCI_BASE_ADDRESS_0,		PCI_BASE_ADDRESS_1,		0	};	struct pci_func *func = *func_passed;	unsigned int devfn;	u8 irq;	int retval;	debug ("%s - enter\n", __func__);	devfn = PCI_DEVFN(func->function, func->device);	ibmphp_pci_bus->number = func->busno;	/* Configuring necessary info for the bridge so that we could see the devices	 * behind it	 */	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);	/* _____________________For debugging purposes only __________________________	pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);	debug ("primary # written into the bridge is %x\n", pri_number);	 ___________________________________________________________________________*/	/* in EBDA, only get allocated 1 additional bus # per slot */	sec_number = find_sec_number (func->busno, slotno);	if (sec_number == 0xff) {		err ("cannot allocate secondary bus number for the bridged device\n");		return -EINVAL;	}	debug ("after find_sec_number, the number we got is %x\n", sec_number);	debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);		/* __________________For debugging purposes only __________________________________	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);	debug ("sec_number after write/read is %x\n", sec_number);	 ________________________________________________________________________________*/	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);	/* __________________For debugging purposes only ____________________________________	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);	debug ("subordinate number after write/read is %x\n", sec_number);	 __________________________________________________________________________________*/	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);	debug ("func->busno is %x\n", func->busno);	debug ("sec_number after writing is %x\n", sec_number);	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!	   !!!!!!!!!!!!!!!NEED TO ADD!!!  FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!! 	   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/	/* First we need to allocate mem/io for the bridge itself in case it needs it */	for (count = 0; address[count]; count++) {	/* for 2 BARs */		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);		if (!bar[count]) {			/* This BAR is not implemented */			debug ("so we come here then, eh?, count = %d\n", count);			continue;		}		//  tmp_bar = bar[count];		debug ("Bar %d wants %x\n", count, bar[count]);		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {			/* This is IO */			len[count] = bar[count] & 0xFFFFFFFC;			len[count] = ~len[count] + 1;			debug ("len[count] in IO = %x\n", len[count]);			bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);					if (!bus_io[count]) {				err ("out of system memory\n");				retval = -ENOMEM;				goto error;			}			bus_io[count]->type = IO;			bus_io[count]->busno = func->busno;			bus_io[count]->devfunc = PCI_DEVFN(func->device,							func->function);			bus_io[count]->len = len[count];			if (ibmphp_check_resource (bus_io[count], 0) == 0) {				ibmphp_add_resource (bus_io[count]);				func->io[count] = bus_io[count];			} else {				err ("cannot allocate requested io for bus %x, device %x, len %x\n",				     func->busno, func->device, len[count]);				kfree (bus_io[count]);				return -EIO;			}			pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);		} else {			/* This is Memory */			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {				/* pfmem */				len[count] = bar[count] & 0xFFFFFFF0;				len[count] = ~len[count] + 1;				debug ("len[count] in PFMEM = %x\n", len[count]);				bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);				if (!bus_pfmem[count]) {					err ("out of system memory\n");					retval = -ENOMEM;					goto error;				}				bus_pfmem[count]->type = PFMEM;				bus_pfmem[count]->busno = func->busno;				bus_pfmem[count]->devfunc = PCI_DEVFN(func->device,							func->function);				bus_pfmem[count]->len = len[count];				bus_pfmem[count]->fromMem = 0;				if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {					ibmphp_add_resource (bus_pfmem[count]);					func->pfmem[count] = bus_pfmem[count];				} else {					mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);					if (!mem_tmp) {						err ("out of system memory\n");						retval = -ENOMEM;						goto error;					}					mem_tmp->type = MEM;					mem_tmp->busno = bus_pfmem[count]->busno;					mem_tmp->devfunc = bus_pfmem[count]->devfunc;					mem_tmp->len = bus_pfmem[count]->len;					if (ibmphp_check_resource (mem_tmp, 0) == 0) {						ibmphp_add_resource (mem_tmp);						bus_pfmem[count]->fromMem = 1;						bus_pfmem[count]->rangeno = mem_tmp->rangeno;						ibmphp_add_pfmem_from_mem (bus_pfmem[count]);						func->pfmem[count] = bus_pfmem[count];					} else {						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n", 						     func->busno, func->device, len[count]);						kfree (mem_tmp);						kfree (bus_pfmem[count]);						return -EIO;					}				}				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {					/* takes up another dword */					count += 1;					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);				}			} else {				/* regular memory */				len[count] = bar[count] & 0xFFFFFFF0;				len[count] = ~len[count] + 1;				debug ("len[count] in Memory is %x\n", len[count]);				bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);				if (!bus_mem[count]) {					err ("out of system memory\n");					retval = -ENOMEM;					goto error;				}				bus_mem[count]->type = MEM;				bus_mem[count]->busno = func->busno;				bus_mem[count]->devfunc = PCI_DEVFN(func->device,							func->function);				bus_mem[count]->len = len[count];				if (ibmphp_check_resource (bus_mem[count], 0) == 0) {					ibmphp_add_resource (bus_mem[count]);					func->mem[count] = bus_mem[count];				} else {					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",					     func->busno, func->device, len[count]);					kfree (bus_mem[count]);					return -EIO;				}				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {					/* takes up another dword */					count += 1;					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);				}			}		}		/* end of mem */	}			/* end of for  */	/* Now need to see how much space the devices behind the bridge needed */	amount_needed = scan_behind_bridge (func, sec_number);	if (amount_needed == NULL)		return -ENOMEM;	ibmphp_pci_bus->number = func->busno;	debug ("after coming back from scan_behind_bridge\n");	debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);	debug ("amount_needed->io = %x\n", amount_needed->io);	debug ("amount_needed->mem = %x\n", amount_needed->mem);	debug ("amount_needed->pfmem =  %x\n", amount_needed->pfmem);	if (amount_needed->not_correct) {				debug ("amount_needed is not correct\n");		for (count = 0; address[count]; count++) {			/* for 2 BARs */			if (bus_io[count]) {				ibmphp_remove_resource (bus_io[count]);				func->io[count] = NULL;			} else if (bus_pfmem[count]) {				ibmphp_remove_resource (bus_pfmem[count]);				func->pfmem[count] = NULL;			} else if (bus_mem[count]) {				ibmphp_remove_resource (bus_mem[count]);				func->mem[count] = NULL;			}		}		kfree (amount_needed);		return -ENODEV;	}	if (!amount_needed->io) {		debug ("it doesn't want IO?\n");		flag_io = 1;	} else {		debug ("it wants %x IO behind the bridge\n", amount_needed->io);		io = kzalloc(sizeof(*io), GFP_KERNEL);				if (!io) {			err ("out of system memory\n");			retval = -ENOMEM;			goto error;		}		io->type = IO;		io->busno = func->busno;		io->devfunc = PCI_DEVFN(func->device, func->function);		io->len = amount_needed->io;		if (ibmphp_check_resource (io, 1) == 0) {			debug ("were we able to add io\n");			ibmphp_add_resource (io);			flag_io = 1;		}	}	if (!amount_needed->mem) {		debug ("it doesn't want n.e.memory?\n");		flag_mem = 1;	} else {		debug ("it wants %x memory behind the bridge\n", amount_needed->mem);		mem = kzalloc(sizeof(*mem), GFP_KERNEL);		if (!mem) {			err ("out of system memory\n");			retval = -ENOMEM;			goto error;		}		mem->type = MEM;		mem->busno = func->busno;		mem->devfunc = PCI_DEVFN(func->device, func->function);		mem->len = amount_needed->mem;		if (ibmphp_check_resource (mem, 1) == 0) {			ibmphp_add_resource (mem);

⌨️ 快捷键说明

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