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

📄 pci_bus_cvlink.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 2 页
字号:
			device_dev->resource[PCI_ROM_RESOURCE].start;		if (size) {			device_dev->resource[PCI_ROM_RESOURCE].start =			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;			device_dev->resource[PCI_ROM_RESOURCE].end =			device_dev->resource[PCI_ROM_RESOURCE].start + size;		}#endif		/*		 * Update the Command Word on the Card.		 */		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */					   /* bit gets dropped .. no harm */		pci_write_config_word(device_dev, PCI_COMMAND, cmd);		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {				lines = 1;		} 		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;		device_vertex = device_sysdata->vhdl; 		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);		bit = intr_handle->pi_irq;		cpuid = intr_handle->pi_cpu;		irq = bit;		irq = irq + (cpuid << 8);		pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);		device_dev->irq = irq;#ifdef ajmtestintr		{			int slot = PCI_SLOT(device_dev->devfn);			static int timer_set = 0;			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;			extern void intr_test_handle_intr(int, void*, struct pt_regs *);			if (!timer_set) {				intr_test_set_timer();				timer_set = 1;			}			intr_test_register_irq(irq, pcibr_soft, slot);			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);		}#endif	}	for (cnode = 0; cnode < numnodes; cnode++) {		if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )			io_sh_swapper((cnodeid_to_nasid(cnode)), 1);	}}/* * linux_bus_cvlink() Creates a link between the Linux PCI Bus number  *	to the actual hardware component that it represents: *	/dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci */voidlinux_bus_cvlink(void){	char name[8];	int index;		for (index=0; index < MAX_PCI_XWIDGET; index++) {		if (!busnum_to_pcibr_vhdl[index])			continue;		sprintf(name, "%d", index);		(void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 				name);	}}/* * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. * *	Linux PCI Bus numbers are assigned from lowest module_id numbers *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to  *	HUB_WIDGET_ID_MIN: *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc. * *	Given 2 modules 001c01 and 001c02 we get the following mappings: *		001c01, widgetnum 15 = Bus number 0 *		001c01, widgetnum 14 = Bus number 1 *		001c02, widgetnum 15 = Bus number 3 *		001c02, widgetnum 14 = Bus number 4 *		etc. * * The rational for starting Bus Number 0 with Widget number 15 is because  * the system boot disks are always connected via Widget 15 Slot 0 of the  * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0  * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest  * module id(Master Cnode) of the system. *	 */static int pci_bus_map_create(devfs_handle_t xtalk){	devfs_handle_t master_node_vertex = NULL;	devfs_handle_t xwidget = NULL;	devfs_handle_t pci_bus = NULL;	hubinfo_t hubinfo = NULL;	xwidgetnum_t widgetnum;	char pathname[128];	graph_error_t rv;	int bus;	/*	 * Loop throught this vertex and get the Xwidgets ..	 */	/* PCI devices */	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {#if  0        {                int pos;                char dname[256];                pos = devfs_generate_path(xtalk, dname, 256);                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);        }#endif		sprintf(pathname, "%d", widgetnum);		xwidget = NULL;				/*		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device		 */		rv = hwgraph_traverse(xtalk, pathname, &xwidget);		if ( (rv != GRAPH_SUCCESS) ) {			if (!xwidget) {				continue;}		}		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);		pci_bus = NULL;		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)			if (!pci_bus) {				continue;}		/*		 * Assign the correct bus number and also the nasid of this 		 * pci Xwidget.		 * 		 * Should not be any race here ...		 */		num_bridges++;		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;		/*		 * Get the master node and from there get the NASID.		 */		master_node_vertex = device_master_get(xwidget);		if (!master_node_vertex) {			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);		}			hubinfo_get(master_node_vertex, &hubinfo);		if (!hubinfo) {			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);			return(1);		} else {			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;		}		/*		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.		 */		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);		if (!busnum_to_atedmamaps[num_bridges - 1])			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);	}	/*	 * PCIX devices	 * We number busses differently for PCI-X devices.	 * We start from Lowest Widget on up ..	 */	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {		/* Do both buses */		for ( bus = 0; bus < 2; bus++ ) {			sprintf(pathname, "%d", widgetnum);			xwidget = NULL;						/*			 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device			 */			rv = hwgraph_traverse(xtalk, pathname, &xwidget);			if ( (rv != GRAPH_SUCCESS) ) {				if (!xwidget) {					continue;				}			}				if ( bus == 0 )				sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);			else				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);			pci_bus = NULL;			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)				if (!pci_bus) {					continue;				}				/*			 * Assign the correct bus number and also the nasid of this 			 * pci Xwidget.			 * 			 * Should not be any race here ...			 */			num_bridges++;			busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;				/*			 * Get the master node and from there get the NASID.			 */			master_node_vertex = device_master_get(xwidget);			if (!master_node_vertex) {				printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);			}					hubinfo_get(master_node_vertex, &hubinfo);			if (!hubinfo) {				printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);				return(1);			} else {				busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;			}				/*			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.			 */			busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);			if (!busnum_to_atedmamaps[num_bridges - 1])				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);				memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);		}	}        return(0);}/* * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure    *      initialization has completed to set up the mappings between Xbridge *      and logical pci bus numbers.  We also set up the NASID for each of these *      xbridges. * *      Must be called before pci_init() is invoked. */intpci_bus_to_hcl_cvlink(void) {	devfs_handle_t devfs_hdl = NULL;	devfs_handle_t xtalk = NULL;	int rv = 0;	char name[256];	char tmp_name[256];	int master_iobrick;	slabid_t master_slab;	int i, ii;	extern nasid_t master_baseio_nasid;	extern nasid_t get_master_baseio_nasid(void);	/*	 * Iterate throught each xtalk links in the system ..	 * /hw/module/001c01/slab/0/node/xtalk/ 8|9|10|11|12|13|14|15 	 *	 * /hw/module/001c01/slab/0/node/xtalk/15 -> /hw/module/001c01/slab/0/Ibrick/xtalk/15	 *	 * What if it is not pci?	 */	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");	/*	 * To provide consistent(not persistent) device naming, we need to start 	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 	 * with an attached I-Brick.  Find the master_iobrick.	 */	master_baseio_nasid = get_master_baseio_nasid();	master_iobrick = -1;	master_slab = -1;	if ( master_baseio_nasid >= 0 ) {		/* Valid nasid, need the slab ID */		for (i = 0; i < nummodules; i++) {			extern int iobrick_module_get_nasid(nasid_t);			moduleid_t iobrick_id; 			nasid_t nasid = -1;			int n = 0;			for ( n = 0; n < modules[i]->nodecnt; n++ ) {				nasid = cnodeid_to_nasid(modules[i]->nodes[n]);				iobrick_id = iobrick_module_get_nasid(nasid);				if (iobrick_id > 0) { /* Valid module id */					if ( master_baseio_nasid == nasid ) {						master_iobrick = i;						master_slab = geo_slab(modules[i]->geoid[n]);						printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Base I/O nasid %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_baseio_nasid, master_iobrick, master_slab);						break;					}				}			}			if (master_slab >= 0)				break;		}	}	else {		/* Not sure which nasid it is - call failed, so make a guess */		for (i = 0; i < nummodules; i++) {			extern int iobrick_module_get_nasid(nasid_t);			moduleid_t iobrick_id; 			nasid_t nasid = -1;			int n = 0;			for ( n = 0; n < modules[i]->nodecnt; n++ ) {				nasid = cnodeid_to_nasid(modules[i]->nodes[n]);				iobrick_id = iobrick_module_get_nasid(nasid);				if (iobrick_id > 0) { /* Valid module id */					if ( (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) || 					   		(MODULE_GET_BTYPE(iobrick_id) == MODULE_PXBRICK) ||				   			(MODULE_GET_BTYPE(iobrick_id) == MODULE_PBRICK) ) {						master_iobrick = i;						master_baseio_nasid = nasid;						master_slab = geo_slab(modules[i]->geoid[n]);						printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_iobrick, master_slab);						break;					}				}			}			if (master_iobrick >= 0)				break;		}	}	if (master_iobrick == -1) {		panic("Unable to find the Master BaseIO PCI/PCIX Bus\n");	}	/*	 * The master_iobrick gets bus 0 and 1.	 */	if (master_iobrick >= 0) {		memset(name, 0, 256);		memset(tmp_name, 0, 256);		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);		sprintf(tmp_name, "/slab/%d/node/xtalk", master_slab);		strcat(name, tmp_name);		xtalk = NULL;		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);		pci_bus_map_create(xtalk);	}			/*	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 	 * module id, remembering to skip the master_iobrick, which was done above.	 */	for (i = 0; i < nummodules ; i++) {		for ( ii = 0; ii < MAX_SLABS; ii++ ) {			if ((i == master_iobrick) && (master_slab == ii))				continue; /* Did the master_iobrick/slab already. */			memset(name, 0, 256);			memset(tmp_name, 0, 256);			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);			sprintf(tmp_name, "/slab/%d/node/xtalk", ii);			strcat(name, tmp_name);			xtalk = NULL;			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);			pci_bus_map_create(xtalk);		}	}	/*	 * Create the Linux PCI bus number vertex link.	 */	(void)linux_bus_cvlink();	return(0);}

⌨️ 快捷键说明

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