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

📄 pcibr_slot.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (pcibr_soft->bs_slot[slot].has_host) {        return(EPERM);    }        xconn_vhdl = pcibr_soft->bs_conn;    aa = async_attach_get_info(xconn_vhdl);    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;    for (func = 0; func < nfunc; ++func) {	pcibr_info = pcibr_infoh[func];		if (!pcibr_info)	    continue;	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)	    continue;	conn_vhdl = pcibr_info->f_vertex;#ifdef LATER	/*	 * Activate if and when we support cdl.	 */	if (aa)	    async_attach_add_info(conn_vhdl, aa);#endif	/* LATER */	error_func = pciio_device_attach(conn_vhdl, drv_flags);        pcibr_info->f_att_det_error = error_func;	if (error_func)	    error_slot = error_func;        error = error_slot;    }				/* next func */    if (error) {	if ((error != ENODEV) && (error != EUNATCH))	    pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;    } else {        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;    }            return(error);}/* * pcibr_slot_call_device_detach *	This calls the associated driver detach routine for the PCI * 	card in this slot. */intpcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,			      pciio_slot_t slot,			      int          drv_flags){    pcibr_soft_t	pcibr_soft;    pcibr_info_h	pcibr_infoh;    pcibr_info_t	pcibr_info;    int			func;    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;    int			nfunc;    int                 error_func;    int                 error_slot = 0;    int                 error = ENODEV;    pcibr_soft = pcibr_soft_get(pcibr_vhdl);    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))	return(EINVAL);    if (pcibr_soft->bs_slot[slot].has_host)        return(EPERM);    /* Make sure that we do not detach a system critical function vertex */    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))        return(EPERM);    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;    for (func = 0; func < nfunc; ++func) {	pcibr_info = pcibr_infoh[func];		if (!pcibr_info)	    continue;	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)	    continue;	conn_vhdl = pcibr_info->f_vertex;	error_func = pciio_device_detach(conn_vhdl, drv_flags);        pcibr_info->f_att_det_error = error_func;	if (error_func)	    error_slot = error_func;	error = error_slot;    }				/* next func */    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;    if (error) {	if ((error != ENODEV) && (error != EUNATCH))            pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;    } else {        if (conn_vhdl != GRAPH_VERTEX_NONE)             pcibr_device_unregister(conn_vhdl);        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;    }            return(error);}#ifdef LATER/* * pcibr_slot_attach *	This is a place holder routine to keep track of all the *	slot-specific initialization that needs to be done. *	This is usually called when we want to initialize a new * 	PCI card on the bus. */intpcibr_slot_attach(devfs_handle_t pcibr_vhdl,		  pciio_slot_t slot,		  int          drv_flags,		  char        *l1_msg,                  int         *sub_errorp){    pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);    timespec_t    ts;    int		  error;    if (!(pcibr_soft->bs_slot[slot].slot_status & SLOT_POWER_UP)) {         /* Power-up the slot */        error = pcibr_slot_pwr(pcibr_vhdl, slot, L1_REQ_PCI_UP, l1_msg);        if (error) {            if (sub_errorp)                *sub_errorp = error;            return(PCI_L1_ERR);        } else {            pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_POWER_MASK;            pcibr_soft->bs_slot[slot].slot_status |= SLOT_POWER_UP;        }#ifdef LATER        /*         * Allow cards like the Alteon Gigabit Ethernet Adapter to complete         * on-card initialization following the slot reset         */         ts.tv_sec = 0;                      /* 0 secs */         ts.tv_nsec = 500 * (1000 * 1000);   /* 500 msecs */         nano_delay(&ts);#else#endif#if 0        /* Reset the slot */        error = pcibr_slot_reset(pcibr_vhdl, slot)        if (error) {            if (sub_errorp)                *sub_errorp = error;            return(PCI_SLOT_RESET_ERR);        }#endif        /* Find out what is out there */        error = pcibr_slot_info_init(pcibr_vhdl, slot);        if (error) {            if (sub_errorp)                *sub_errorp = error;            return(PCI_SLOT_INFO_INIT_ERR);        }        /* Set up the address space for this slot in the PCI land */        error = pcibr_slot_addr_space_init(pcibr_vhdl, slot);        if (error) {            if (sub_errorp)                *sub_errorp = error;            return(PCI_SLOT_ADDR_INIT_ERR);        }        /* Setup the device register */        error = pcibr_slot_device_init(pcibr_vhdl, slot);        if (error) {            if (sub_errorp)                *sub_errorp = error;            return(PCI_SLOT_DEV_INIT_ERR);        }        /* Setup host/guest relations */        error = pcibr_slot_guest_info_init(pcibr_vhdl, slot);        if (error) {            if (sub_errorp)                *sub_errorp = error;            return(PCI_SLOT_GUEST_INIT_ERR);        }        /* Initial RRB management */        error = pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);        if (error) {            if (sub_errorp)                *sub_errorp = error;            return(PCI_SLOT_RRB_ALLOC_ERR);        }    }    /* Call the device attach */    error = pcibr_slot_call_device_attach(pcibr_vhdl, slot, drv_flags);    if (error) {        if (sub_errorp)            *sub_errorp = error;        if (error == EUNATCH)            return(PCI_NO_DRIVER);        else            return(PCI_SLOT_DRV_ATTACH_ERR);    }    return(0);}#endif	/* LATER *//* * pcibr_slot_detach *	This is a place holder routine to keep track of all the *	slot-specific freeing that needs to be done. */intpcibr_slot_detach(devfs_handle_t pcibr_vhdl,		  pciio_slot_t slot,		  int          drv_flags){    int		  error;        /* Call the device detach function */    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));    return (error);}/* * pcibr_is_slot_sys_critical *      Check slot for any functions that are system critical. *      Return 1 if any are system critical or 0 otherwise. * *      This function will always return 0 when called by  *      pcibr_attach() because the system critical vertices  *      have not yet been set in the hwgraph. */intpcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,                      pciio_slot_t slot){    pcibr_soft_t        pcibr_soft;    pcibr_info_h        pcibr_infoh;    pcibr_info_t        pcibr_info;    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;    int                 nfunc;    int                 func;    boolean_t		is_sys_critical_vertex(devfs_handle_t);    pcibr_soft = pcibr_soft_get(pcibr_vhdl);    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))        return(0);    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;    for (func = 0; func < nfunc; ++func) {        pcibr_info = pcibr_infoh[func];        if (!pcibr_info)            continue;        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)            continue;        conn_vhdl = pcibr_info->f_vertex;        if (is_sys_critical_vertex(conn_vhdl)) { #if defined(SUPPORT_PRINTING_V_FORMAT)            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);#else            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);#endif            return(1);         }    }    return(0);}/* * 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. */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;}voidpcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot){    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);    pcibr_info_t	pcibr_info;    pciio_function_t	func;    pcibr_soft_slot_t	slotp = &pcibr_soft->bs_slot[slot];    int			nfunc = slotp->bss_ninfo;    int                 bar;    int                 devio_index;    int                 s;    for (func = 0; func < nfunc; func++) {	pcibr_info = slotp->bss_infos[func];	if (!pcibr_info) 	    continue;        s = pcibr_lock(pcibr_soft);        for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) {            if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE)                continue;            /* Get index of the DevIO(x) register used to access this BAR */            devio_index = pcibr_info->f_window[bar].w_devio_index;             /* On last use, clear the DevIO(x) used to access this BAR */            if (! --pcibr_soft->bs_slot[devio_index].bss_devio.bssd_ref_cnt) {               pcibr_soft->bs_slot[devio_index].bss_devio.bssd_space =                                                       PCIIO_SPACE_NONE;                pcibr_soft->bs_slot[devio_index].bss_devio.bssd_base =                                                       PCIBR_D32_BASE_UNSET;               pcibr_soft->bs_slot[devio_index].bss_device = 0;            }        }        pcibr_unlock(pcibr_soft, s);	slotp->bss_infos[func] = 0;	pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);	pciio_device_info_free(&pcibr_info->f_c);	DEL(pcibr_info);    }    /* Reset the mapping usage counters */    slotp->bss_pmu_uctr = 0;    slotp->bss_d32_uctr = 0;    slotp->bss_d64_uctr = 0;    /* Clear the Direct translation info */    slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;    slotp->bss_d64_flags = 0;    slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;    slotp->bss_d32_flags = 0;    /* Clear out shadow info necessary for the external SSRAM workaround */    slotp->bss_ext_ates_active = ATOMIC_INIT(0);    slotp->bss_cmd_pointer = 0;    slotp->bss_cmd_shadow = 0;}

⌨️ 快捷键说明

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