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

📄 pcibr.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    printk("\n\tBase Register Info\n");    printk("\t\tReg#\tBase\t\tSize\t\tSpace\n");    for(win = 0 ; win < 6 ; win++) 	printk("\t\t%d\t0x%lx\t%s0x%lx\t%s%s\n",		win,		pcibr_info->f_window[win].w_base,		pcibr_info->f_window[win].w_base >= 0x100000 ? "": "\t",		pcibr_info->f_window[win].w_size,		pcibr_info->f_window[win].w_size >= 0x100000 ? "": "\t",		pci_space_name[pcibr_info->f_window[win].w_space]);    printk("\t\t7\t0x%x\t%s0x%x\t%sROM\n", 	    pcibr_info->f_rbase,	    pcibr_info->f_rbase > 0x100000 ? "" : "\t",	    pcibr_info->f_rsize,	    pcibr_info->f_rsize > 0x100000 ? "" : "\t");    printk("\n\tInterrupt Bit Map\n");    printk("\t\tPCI Int#\tBridge Pin#\n");    for (win = 0 ; win < 4; win++)	printk("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);    printk("\n");}voidpcibr_slot_info_print(pcibr_soft_t 	pcibr_soft, 		      pciio_slot_t 	slot, 		      int	   	verbose){    pcibr_soft_slot_t	pss;    char		slot_conn_name[MAXDEVNAME];    int			func;    bridge_t		*bridge = pcibr_soft->bs_base;    bridgereg_t		b_resp;    reg_p		b_respp;    int			dev;    bridgereg_t		b_int_device;    bridgereg_t		b_int_host;    bridgereg_t		b_int_enable;    int			pin = 0;    int			int_bits = 0;    pss = &pcibr_soft->bs_slot[slot];        printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot);    if (verbose) {	printk("\tHost Present ? %s ", pss->has_host ? "yes" : "no");	printk("\tHost Slot : %d\n",pss->host_slot);#ifdef SUPPORT_PRINTING_V_FORMAT	sprintf(slot_conn_name, "%v", pss->slot_conn);#endif	printk("\tSlot Conn : %s\n",slot_conn_name);		printk("\t#Functions : %d\n",pss->bss_ninfo);    }    for (func = 0; func < pss->bss_ninfo; func++)	pcibr_slot_func_info_print(pss->bss_infos,func, verbose);    printk("\tDevio[Space:%s,Base:0x%lx,Shadow:0x%x]\n",	    pci_space_name[pss->bss_devio.bssd_space],	    pss->bss_devio.bssd_base,	    pss->bss_device);    if (verbose) {	printk("\tUsage counts : pmu %d d32 %d d64 %d\n",		pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);    	printk("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"		"d32_base 0x%x d32_flags 0x%x\n",		(unsigned int)pss->bss_d64_base, pss->bss_d64_flags,		(unsigned int)pss->bss_d32_base, pss->bss_d32_flags);    	printk("\tExt ATEs active ? %s", 		pss->bss_ext_ates_active ? "yes" : "no");	printk(" Command register : 0x%p ", pss->bss_cmd_pointer);	printk(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);    }    printk("\tSoft RRB Info[Valid %d+%d, Reserved %d]\n",	    pcibr_soft->bs_rrb_valid[slot],	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],	    pcibr_soft->bs_rrb_res[slot]);    if (slot & 1)	b_respp = &bridge->b_odd_resp;    else	b_respp = &bridge->b_even_resp;    b_resp = *b_respp;    printk("\n\tBridge RRB Info\n");    printk("\t\tRRB#\tVirtual\n");    for (dev = 0; dev < 8; dev++) {	if ((b_resp & BRIDGE_RRB_EN) &&	    (b_resp & BRIDGE_RRB_PDEV) == (slot >> 1))	    printk( "\t\t%d\t%s\n", 		    dev,		    (b_resp & BRIDGE_RRB_VDEV) ? "yes" : "no");	b_resp >>= 4;	        }    b_int_device = bridge->b_int_device;    b_int_enable = bridge->b_int_enable;    printk("\n\tBridge Interrupt Info\n"	    "\t\tInt_device 0x%x\n\t\tInt_enable 0x%x "	    "\n\t\tEnabled pin#s for this slot: ",	    b_int_device,	    b_int_enable);    while (b_int_device) {	if (((b_int_device & 7) == slot) &&	    (b_int_enable & (1 << pin))) {	    int_bits |= (1 << pin);	    printk("%d ", pin); 	}	pin++;	b_int_device >>= 3;    }    if (!int_bits)	printk("NONE ");    b_int_host = bridge->b_int_addr[slot].addr;    printk("\n\t\tInt_host_addr 0x%x\n",	    b_int_host);    }int verbose = 0;/* * pcibr_slot_inquiry *	Print information about the pci slot maintained by the infrastructure. *	Current information displayed *		Slot hwgraph name *		Vendor/Device info *		Base register info *		Interrupt mapping from device pins to the bridge pins *		Devio register *		Software RRB info *		RRB register info *	In verbose mode following additional info is displayed *		Host/Gues info *		PCI Bus #,slot #, function # *		Slot provider hwgraph name *		Provider Functions *		Error handler *		DMA mapping usage counters *		DMA direct translation info *		External SSRAM workaround info */intpcibr_slot_inquiry(devfs_handle_t pcibr_vhdl, pciio_slot_t slot){    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);    /* Make sure that we are dealing with a bridge device vertex */    if (!pcibr_soft)	return(EINVAL);    /* Make sure that we have a valid pci slot number or PCIIO_SLOT_NONE */    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE))	return(EINVAL);    /* Print information for the requested pci slot */    if (slot != PCIIO_SLOT_NONE) {	pcibr_slot_info_print(pcibr_soft,slot,verbose);	return(0);    }    /* Print information for all the slots */    for (slot = 0; slot < 8; slot++)	pcibr_slot_info_print(pcibr_soft, slot,verbose);    return(0);}/*ARGSUSED */intpcibr_ioctl(devfs_handle_t dev,	    int cmd,	    void *arg,	    int flag,	    struct cred *cr,	    int *rvalp){    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);#ifdef colin    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);#endif    int                     error = 0;    hwgraph_vertex_unref(pcibr_vhdl);    switch (cmd) {#ifdef colin    case GIOCSETBW:	{	    grio_ioctl_info_t       info;	    pciio_slot_t            slot = 0;	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {		error = EFAULT;		break;	    }#ifdef GRIO_DEBUG	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",		    info.prev_vhdl, info.reqbw);#endif				/* GRIO_DEBUG */	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==		PCIIO_SLOT_NONE) {		error = EIO;		break;	    }	    if (info.reqbw)		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);	    break;	}    case GIOCRELEASEBW:	{	    grio_ioctl_info_t       info;	    pciio_slot_t            slot = 0;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {		error = EFAULT;		break;	    }#ifdef GRIO_DEBUG	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",		    info.prev_vhdl, info.reqbw);#endif				/* GRIO_DEBUG */	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==		PCIIO_SLOT_NONE) {		error = EIO;		break;	    }	    if (info.reqbw)		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);	    break;	}#endif /* colin */    case PCIBR_SLOT_POWERUP:	{	    pciio_slot_t	slot;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    slot = (pciio_slot_t)(uint64_t)arg;	    error = pcibr_slot_powerup(pcibr_vhdl,slot);	    break;	}    case PCIBR_SLOT_SHUTDOWN:	{	    pciio_slot_t	slot;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    slot = (pciio_slot_t)(uint64_t)arg;	    error = pcibr_slot_shutdown(pcibr_vhdl,slot);	    break;	}    case PCIBR_SLOT_INQUIRY:	{	    pciio_slot_t	slot;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    slot = (pciio_slot_t)(uint64_t)arg;	    error = pcibr_slot_inquiry(pcibr_vhdl,slot);	    break;	}    default:	break;    }    return error;}voidpcibr_freeblock_sub(iopaddr_t *free_basep,		    iopaddr_t *free_lastp,		    iopaddr_t base,		    size_t size){    iopaddr_t               free_base = *free_basep;    iopaddr_t               free_last = *free_lastp;    iopaddr_t               last = base + size - 1;    if ((last < free_base) || (base > free_last));	/* free block outside arena */    else if ((base <= free_base) && (last >= free_last))	/* free block contains entire arena */	*free_basep = *free_lastp = 0;    else if (base <= free_base)	/* free block is head of arena */	*free_basep = last + 1;    else if (last >= free_last)	/* free block is tail of arena */	*free_lastp = base - 1;    /*     * We are left with two regions: the free area     * in the arena "below" the block, and the free     * area in the arena "above" the block. Keep     * the one that is bigger.     */    else if ((base - free_base) > (free_last - last))	*free_lastp = base - 1;		/* keep lower chunk */    else	*free_basep = last + 1;		/* keep upper chunk */}#ifdef IRIX/* Convert from ssram_bits in control register to number of SSRAM entries */#define ATE_NUM_ENTRIES(n) _ate_info[n]/* Possible choices for number of ATE entries in Bridge's SSRAM */LOCAL int               _ate_info[] ={    0,					/* 0 entries */    8 * 1024,				/* 8K entries */    16 * 1024,				/* 16K entries */    64 * 1024				/* 64K entries */};#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))#define ATE_PROBE_VALUE 0x0123456789abcdefULL#endif	/* IRIX *//* * Determine the size of this bridge's external mapping SSRAM, and set * the control register appropriately to reflect this size, and initialize * the external SSRAM. */#ifndef BRINGUPLOCAL intpcibr_init_ext_ate_ram(bridge_t *bridge){    int                     largest_working_size = 0;    int                     num_entries, entry;    int                     i, j;    bridgereg_t             old_enable, new_enable;    int                     s;    if (is_xbridge(bridge))	return 0;    /* Probe SSRAM to determine its size. */    old_enable = bridge->b_int_enable;    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;    bridge->b_int_enable = new_enable;    for (i = 1; i < ATE_NUM_SIZES; i++) {	/* Try writing a value */	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;	/* Guard against wrap */	for (j = 1; j < i; j++)	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;	/* See if value was written */	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)	    largest_working_size = i;    }    bridge->b_int_enable = old_enable;    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */    /*     * ensure that we write and read without any interruption.     * The read following the write is required for the Bridge war     */    s = splhi();#ifdef colin    bridge->b_wid_control = (bridge->b_wid_control	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);#endif    bridge->b_wid_control;		/* inval addr bug war */    splx(s);    num_entries = ATE_NUM_ENTRIES(largest_working_size);#if PCIBR_ATE_DEBUG    if (num_entries)	printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries);    else	printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge);#endif    /* Initialize external mapping entries */    for (entry = 0; entry < num_entries; entry++)	bridge->b_ext_ate_ram[entry] = 0;    return (num_entries);}#endif	/* !BRINGUP *//* * Allocate "count" contiguous Bridge Address Translation Entries * on the specified bridge to be used for PCI to XTALK mappings. * Indices in rm map range from 1..num_entries.  Indicies returned

⌨️ 快捷键说明

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