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

📄 pcibr.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    /* some conflicts can be resolved by	     * forcing the bit on. this may cause	     * some performance degredation in	     * the stream(s) that want the bit off,	     * but the alternative is not allowing	     * the new stream at all.	     */            if ( (fix = bad & (BRIDGE_DEV_PRECISE |                             BRIDGE_DEV_BARRIER)) ){		bad &= ~fix;		/* don't change these bits if		 * they are already set in "old"		 */		chg &= ~(fix & old);	    }	    /* some conflicts can be resolved by	     * forcing the bit off. this may cause	     * some performance degredation in	     * the stream(s) that want the bit on,	     * but the alternative is not allowing	     * the new stream at all.	     */	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |			     BRIDGE_DEV_PREF)) ) {		bad &= ~fix;		/* don't change these bits if		 * we wanted to turn them on.		 */		chg &= ~(fix & new);	    }	    /* conflicts in other bits mean	     * we can not establish this DMA	     * channel while the other(s) are	     * still present.	     */	    if (bad) {		pcibr_unlock(pcibr_soft, s);#if (DEBUG && PCIBR_DEV_DEBUG)		printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits);#endif		return bad;	    }	}    }    if (mask == BRIDGE_DEV_PMU_BITS)	slotp->bss_pmu_uctr++;    if (mask == BRIDGE_DEV_D32_BITS)	slotp->bss_d32_uctr++;    if (mask == BRIDGE_DEV_D64_BITS)	slotp->bss_d64_uctr++;    /* the value we want to write is the     * original value, with the bits for     * our selected changes flipped, and     * with any disabled features turned off.     */    new = old ^ chg;			/* only change what we want to change */    if (slotp->bss_device == new) {	pcibr_unlock(pcibr_soft, s);	return 0;    }    bridge->b_device[slot].reg = new;    slotp->bss_device = new;    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */    pcibr_unlock(pcibr_soft, s);#if DEBUG && PCIBR_DEV_DEBUG    printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg);#endif    return 0;}voidpcibr_release_device(pcibr_soft_t pcibr_soft,		     pciio_slot_t slot,		     bridgereg_t mask){    pcibr_soft_slot_t       slotp;    unsigned long           s;    slotp = &pcibr_soft->bs_slot[slot];    s = pcibr_lock(pcibr_soft);    if (mask == BRIDGE_DEV_PMU_BITS)	slotp->bss_pmu_uctr--;    if (mask == BRIDGE_DEV_D32_BITS)	slotp->bss_d32_uctr--;    if (mask == BRIDGE_DEV_D64_BITS)	slotp->bss_d64_uctr--;    pcibr_unlock(pcibr_soft, s);}/* * flush write gather buffer for slot */LOCAL voidpcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft,              pciio_slot_t slot){    bridge_t               *bridge;    unsigned long          s;    volatile uint32_t     wrf;    s = pcibr_lock(pcibr_soft);    bridge = pcibr_soft->bs_base;    wrf = bridge->b_wr_req_buf[slot].reg;    pcibr_unlock(pcibr_soft, s);}/* ===================================================================== *    Bridge (pcibr) "Device Driver" entry points *//* * pcibr_probe_slot: read a config space word * while trapping any errors; reutrn zero if * all went OK, or nonzero if there was an error. * The value read, if any, is passed back * through the valp parameter. */LOCAL intpcibr_probe_slot(bridge_t *bridge,		 cfg_p cfg,		 unsigned *valp){    int                     rv;    bridgereg_t             old_enable, new_enable;    int badaddr_val(volatile void *, int, volatile void *);    old_enable = bridge->b_int_enable;    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;    bridge->b_int_enable = new_enable;	/*	 * The xbridge doesn't clear b_err_int_view unless	 * multi-err is cleared...	 */	if (is_xbridge(bridge))	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;	    }    if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;	(void) bridge->b_wid_tflush;	/* flushbus */    }    rv = badaddr_val((void *) cfg, 4, valp);	/*	 * The xbridge doesn't set master timeout in b_int_status	 * here.  Fortunately it's in error_interrupt_view.	 */	if (is_xbridge(bridge))	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;		rv = 1;		/* unoccupied slot */	    }    bridge->b_int_enable = old_enable;    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */    return rv;}/* *    pcibr_init: called once during system startup or *      when a loadable driver is loaded. * *      The driver_register function should normally *      be in _reg, not _init.  But the pcibr driver is *      required by devinit before the _reg routines *      are called, so this is an exception. */voidpcibr_init(void){#if DEBUG && ATTACH_DEBUG    printk("pcibr_init\n");#endif    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,			    XBRIDGE_WIDGET_MFGR_NUM,			    "pcibr_",			    0);    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,			    BRIDGE_WIDGET_MFGR_NUM,			    "pcibr_",			    0);}/* * open/close mmap/munmap interface would be used by processes * that plan to map the PCI bridge, and muck around with the * registers. This is dangerous to do, and will be allowed * to a select brand of programs. Typically these are * diagnostics programs, or some user level commands we may * write to do some weird things. * To start with expect them to have root priveleges. * We will ask for more later. *//* ARGSUSED */intpcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp){    return 0;}/*ARGSUSED */intpcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp){    return 0;}/*ARGSUSED */intpcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot){    int                     error;    devfs_handle_t            vhdl = dev_to_vhdl(dev);    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);    bridge_t               *bridge = pcibr_soft->bs_base;    hwgraph_vertex_unref(pcibr_vhdl);    ASSERT(pcibr_soft);    len = ctob(btoc(len));		/* Make len page aligned */    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);    /*     * If the offset being mapped corresponds to the flash prom     * base, and if the mapping succeeds, and if the user     * has requested the protections to be WRITE, enable the     * flash prom to be written.     *     * XXX- deprecate this in favor of using the     * real flash driver ...     */    if (!error &&	((off == BRIDGE_EXTERNAL_FLASH) ||	 (len > BRIDGE_EXTERNAL_FLASH))) {	int                     s;	/*	 * ensure that we write and read without any interruption.	 * The read following the write is required for the Bridge war	 */	s = splhi();	bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;	bridge->b_wid_control;		/* inval addr bug war */	splx(s);    }    return error;}/*ARGSUSED */intpcibr_unmap(devfs_handle_t dev, vhandl_t *vt){    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);    bridge_t               *bridge = pcibr_soft->bs_base;    hwgraph_vertex_unref(pcibr_vhdl);    /*     * If flashprom write was enabled, disable it, as     * this is the last unmap.     */    if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {	int                     s;	/*	 * ensure that we write and read without any interruption.	 * The read following the write is required for the Bridge war	 */	s = splhi();	bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;	bridge->b_wid_control;		/* inval addr bug war */	splx(s);    }    return 0;}/* This is special case code used by grio. There are plans to make * this a bit more general in the future, but till then this should * be sufficient. */pciio_slot_tpcibr_device_slot_get(devfs_handle_t dev_vhdl){    char                    devname[MAXDEVNAME];    devfs_handle_t            tdev;    pciio_info_t            pciio_info;    pciio_slot_t            slot = PCIIO_SLOT_NONE;    vertex_to_name(dev_vhdl, devname, MAXDEVNAME);    /* run back along the canonical path     * until we find a PCI connection point.     */    tdev = hwgraph_connectpt_get(dev_vhdl);    while (tdev != GRAPH_VERTEX_NONE) {	pciio_info = pciio_info_chk(tdev);	if (pciio_info) {	    slot = pciio_info_slot_get(pciio_info);	    break;	}	hwgraph_vertex_unref(tdev);	tdev = hwgraph_connectpt_get(tdev);    }    hwgraph_vertex_unref(tdev);    return slot;}/*========================================================================== *	BRIDGE PCI SLOT RELATED IOCTLs */char *pci_space_name[] = {"NONE", 			  "ROM",			  "IO",			  "",			  "MEM",			  "MEM32",			  "MEM64",			  "CFG",			  "WIN0",			  "WIN1",			  "WIN2",			  "WIN3",			  "WIN4",			  "WIN5",			  "",			  "BAD"};#ifdef LATERvoidpcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,                            int func,                            pcibr_slot_func_info_resp_t funcp){    pcibr_info_t                 pcibr_info = pcibr_infoh[func];    int                          win;    funcp->resp_f_status = 0;    if (!pcibr_info) {        return;    }    funcp->resp_f_status |= FUNC_IS_VALID;#ifdef SUPPORT_PRINTING_V_FORMAT    sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);#else    sprintf(funcp->resp_f_slot_name, "%x", pcibr_info->f_vertex);#endif    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;    }    funcp->resp_f_bus = pcibr_info->f_bus;    funcp->resp_f_slot = pcibr_info->f_slot;    funcp->resp_f_func = pcibr_info->f_func;#ifdef SUPPORT_PRINTING_V_FORMAT    sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);#else    sprintf(funcp->resp_f_master_name, "%x", pcibr_info->f_master);#endif    funcp->resp_f_pops = pcibr_info->f_pops;    funcp->resp_f_efunc = pcibr_info->f_efunc;    funcp->resp_f_einfo = pcibr_info->f_einfo;    funcp->resp_f_vendor = pcibr_info->f_vendor;    funcp->resp_f_device = pcibr_info->f_device;    for(win = 0 ; win < 6 ; win++) {        funcp->resp_f_window[win].resp_w_base =                                  pcibr_info->f_window[win].w_base;        funcp->resp_f_window[win].resp_w_size =                                  pcibr_info->f_window[win].w_size;        sprintf(funcp->resp_f_window[win].resp_w_space,                "%s",                pci_space_name[pcibr_info->f_window[win].w_space]);    }    funcp->resp_f_rbase = pcibr_info->f_rbase;    funcp->resp_f_rsize = pcibr_info->f_rsize;    for (win = 0 ; win < 4; win++) {        funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];    }    funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;}intpcibr_slot_info_return(pcibr_soft_t             pcibr_soft,                       pciio_slot_t             slot,                       pcibr_slot_info_resp_t   respp){    pcibr_soft_slot_t            pss;    int                          func;    bridge_t                    *bridge = pcibr_soft->bs_base;    reg_p                        b_respp;    pcibr_slot_info_resp_t       slotp;    pcibr_slot_func_info_resp_t  funcp;    slotp = snia_kmem_zalloc(sizeof(*slotp), KM_SLEEP);    if (slotp == NULL) {        return(ENOMEM);    }    pss = &pcibr_soft->bs_slot[slot];        printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot);    slotp->resp_has_host = pss->has_host;    slotp->resp_host_slot = pss->host_slot;

⌨️ 快捷键说明

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