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

📄 pcibr_dvr.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
    while (tdev != GRAPH_VERTEX_NONE) {	pciio_info = pciio_info_chk(tdev);	if (pciio_info) {	    slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);	    break;	}	hwgraph_vertex_unref(tdev);	tdev = hwgraph_connectpt_get(tdev);    }    hwgraph_vertex_unref(tdev);    return slot;}/*ARGSUSED */intpcibr_ioctl(devfs_handle_t dev,	    int cmd,	    void *arg,	    int flag,	    struct cred *cr,	    int *rvalp){    return 0;}pcibr_info_tpcibr_info_get(devfs_handle_t vhdl){    return (pcibr_info_t) pciio_info_get(vhdl);}pcibr_info_tpcibr_device_info_new(			 pcibr_soft_t pcibr_soft,			 pciio_slot_t slot,			 pciio_function_t rfunc,			 pciio_vendor_id_t vendor,			 pciio_device_id_t device){    pcibr_info_t            pcibr_info;    pciio_function_t        func;    int                     ibit;    func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc;    /*     * Create a pciio_info_s for this device.  pciio_device_info_new()     * will set the c_slot (which is suppose to represent the external     * slot (i.e the slot number silk screened on the back of the I/O     * brick)).  So for PIC we need to adjust this "internal slot" num     * passed into us, into it's external representation.  See comment     * for the PCIBR_DEVICE_TO_SLOT macro for more information.     */    NEW(pcibr_info);    pciio_device_info_new(&pcibr_info->f_c, pcibr_soft->bs_vhdl,			  PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),			  rfunc, vendor, device);    pcibr_info->f_dev = slot;    /* Set PCI bus number */    pcibr_info->f_bus = pcibr_widget_to_bus(pcibr_soft->bs_vhdl);    if (slot != PCIIO_SLOT_NONE) {	/*	 * Currently favored mapping from PCI	 * slot number and INTA/B/C/D to Bridge	 * PCI Interrupt Bit Number:	 *	 *     SLOT     A B C D	 *      0       0 4 0 4	 *      1       1 5 1 5	 *      2       2 6 2 6	 *      3       3 7 3 7	 *      4       4 0 4 0	 *      5       5 1 5 1	 *      6       6 2 6 2	 *      7       7 3 7 3	 *	 * XXX- allow pcibr_hints to override default	 * XXX- allow ADMIN to override pcibr_hints	 */	for (ibit = 0; ibit < 4; ++ibit)	    pcibr_info->f_ibit[ibit] =		(slot + 4 * ibit) & 7;	/*	 * Record the info in the sparse func info space.	 */	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;    }    return pcibr_info;}/* * pcibr_device_unregister *	This frees up any hardware resources reserved for this PCI device * 	and removes any PCI infrastructural information setup for it. *	This is usually used at the time of shutting down of the PCI card. */intpcibr_device_unregister(devfs_handle_t pconn_vhdl){    pciio_info_t	 pciio_info;    devfs_handle_t	 pcibr_vhdl;    pciio_slot_t	 slot;    pcibr_soft_t	 pcibr_soft;    bridge_t		*bridge;    int                  count_vchan0, count_vchan1;    unsigned             s;    int			 error_call;    int			 error = 0;    pciio_info = pciio_info_get(pconn_vhdl);    pcibr_vhdl = pciio_info_master_get(pciio_info);    slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);    pcibr_soft = pcibr_soft_get(pcibr_vhdl);    bridge = pcibr_soft->bs_base;    /* Clear all the hardware xtalk resources for this device */    xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot);    /* Flush all the rrbs */    pcibr_rrb_flush(pconn_vhdl);    /*     * If the RRB configuration for this slot has changed, set it      * back to the boot-time default     */    if (pcibr_soft->bs_rrb_valid_dflt[slot][VCHAN0] >= 0) {        s = pcibr_lock(pcibr_soft);	/* PIC NOTE: If this is a BRIDGE, VCHAN2 & VCHAN3 will be zero so	 * no need to conditionalize this (ie. "if (IS_PIC_SOFT())" ).	 */        pcibr_soft->bs_rrb_res[slot] = pcibr_soft->bs_rrb_res[slot] +                                       pcibr_soft->bs_rrb_valid[slot][VCHAN0] +                                       pcibr_soft->bs_rrb_valid[slot][VCHAN1] +                                       pcibr_soft->bs_rrb_valid[slot][VCHAN2] +                                       pcibr_soft->bs_rrb_valid[slot][VCHAN3];        /* Free the rrbs allocated to this slot, both the normal & virtual */	do_pcibr_rrb_free_all(pcibr_soft, bridge, slot);        count_vchan0 = pcibr_soft->bs_rrb_valid_dflt[slot][VCHAN0];        count_vchan1 = pcibr_soft->bs_rrb_valid_dflt[slot][VCHAN1];        pcibr_unlock(pcibr_soft, s);        pcibr_rrb_alloc(pconn_vhdl, &count_vchan0, &count_vchan1);    }    /* Flush the write buffers !! */    error_call = pcibr_wrb_flush(pconn_vhdl);    if (error_call)        error = error_call;    /* Clear the information specific to the slot */    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);    if (error_call)        error = error_call;    return(error);    }/* * pcibr_driver_reg_callback *      CDL will call this function for each device found in the PCI *      registry that matches the vendor/device IDs supported by  *      the driver being registered.  The device's connection vertex *      and the driver's attach function return status enable the *      slot's device status to be set. */voidpcibr_driver_reg_callback(devfs_handle_t pconn_vhdl,			  int key1, int key2, int error){    pciio_info_t	 pciio_info;    pcibr_info_t         pcibr_info;    devfs_handle_t	 pcibr_vhdl;    pciio_slot_t	 slot;    pcibr_soft_t	 pcibr_soft;    /* Do not set slot status for vendor/device ID wildcard drivers */    if ((key1 == -1) || (key2 == -1))        return;    pciio_info = pciio_info_get(pconn_vhdl);    pcibr_info = pcibr_info_get(pconn_vhdl);    pcibr_vhdl = pciio_info_master_get(pciio_info);    slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);    pcibr_soft = pcibr_soft_get(pcibr_vhdl);#ifdef PIC_LATER    /* This may be a loadable driver so lock out any pciconfig actions */    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);#endif    pcibr_info->f_att_det_error = error;    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;    if (error) {        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;    } else {        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;    }        #ifdef PIC_LATER    /* Release the bus lock */    mrunlock(pcibr_soft->bs_bus_lock);#endif}/* * pcibr_driver_unreg_callback *      CDL will call this function for each device found in the PCI *      registry that matches the vendor/device IDs supported by  *      the driver being unregistered.  The device's connection vertex *      and the driver's detach function return status enable the *      slot's device status to be set. */voidpcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl,                             int key1, int key2, int error){    pciio_info_t	 pciio_info;    pcibr_info_t         pcibr_info;    devfs_handle_t	 pcibr_vhdl;    pciio_slot_t	 slot;    pcibr_soft_t	 pcibr_soft;    /* Do not set slot status for vendor/device ID wildcard drivers */    if ((key1 == -1) || (key2 == -1))        return;    pciio_info = pciio_info_get(pconn_vhdl);    pcibr_info = pcibr_info_get(pconn_vhdl);    pcibr_vhdl = pciio_info_master_get(pciio_info);    slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);    pcibr_soft = pcibr_soft_get(pcibr_vhdl);#ifdef PIC_LATER    /* This may be a loadable driver so lock out any pciconfig actions */    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);#endif    pcibr_info->f_att_det_error = error;    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;    if (error) {        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;    } else {        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;    }#ifdef PIC_LATER    /* Release the bus lock */    mrunlock(pcibr_soft->bs_bus_lock);#endif}/*  * build a convenience link path in the * form of ".../<iobrick>/bus/<busnum>" *  * returns 1 on success, 0 otherwise * * depends on hwgraph separator == '/' */intpcibr_bus_cnvlink(devfs_handle_t f_c){        char dst[MAXDEVNAME];	char *dp = dst;        char *cp, *xp;        int widgetnum;        char pcibus[8];	devfs_handle_t nvtx, svtx;	int rv;	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, f_c, "pcibr_bus_cnvlink\n"));	if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME))		return 0;	/* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */	/* find the widget number */	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");	if (xp == NULL)		return 0;	widgetnum = atoi(xp+7);	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)		return 0;	/* remove "/pci/direct" from path */	cp = strstr(dst, "/" EDGE_LBL_PCI "/" EDGE_LBL_DIRECT);	if (cp == NULL)		return 0;	*cp = (char)NULL;	/* get the vertex for the widget */	if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx))			return 0;	*xp = (char)NULL;		/* remove "/xtalk/..." from path */	/* dst example now == /hw/module/001c02/Pbrick */	/* get the bus number */        strcat(dst, "/");        strcat(dst, EDGE_LBL_BUS);        sprintf(pcibus, "%d", p_busnum[widgetnum]);	/* link to bus to widget */	rv = hwgraph_path_add(NULL, dp, &nvtx);	if (GRAPH_SUCCESS == rv)		rv = hwgraph_edge_add(nvtx, svtx, pcibus);	return (rv == GRAPH_SUCCESS);}/* *    pcibr_attach: called every time the crosstalk *      infrastructure is asked to initialize a widget *      that matches the part number we handed to the *      registration routine above. *//*ARGSUSED */intpcibr_attach(devfs_handle_t xconn_vhdl){    /* REFERENCED */    graph_error_t           rc;    devfs_handle_t            pcibr_vhdl;    bridge_t               *bridge;    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, xconn_vhdl, "pcibr_attach\n"));    bridge = (bridge_t *)	xtalk_piotrans_addr(xconn_vhdl, NULL,			    0, sizeof(bridge_t), 0);    /*     * Create the vertex for the PCI bus, which we     * will also use to hold the pcibr_soft and     * which will be the "master" vertex for all the     * pciio connection points we will hang off it.     * This needs to happen before we call nic_bridge_vertex_info     * as we are some of the *_vmc functions need access to the edges.     *     * Opening this vertex will provide access to     * the Bridge registers themselves.     */    rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);    ASSERT(rc == GRAPH_SUCCESS);    pciio_provider_register(pcibr_vhdl, &pcibr_provider);    pciio_provider_startup(pcibr_vhdl);    return pcibr_attach2(xconn_vhdl, bridge, pcibr_vhdl, 0, NULL);}/*ARGSUSED */intpcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, 	      devfs_handle_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp){    /* REFERENCED */    devfs_handle_t            ctlr_vhdl;    bridgereg_t             id;    int                     rev;    pcibr_soft_t            pcibr_soft;    pcibr_info_t            pcibr_info;    xwidget_info_t          info;    xtalk_intr_t            xtalk_intr;    int                     slot;    int                     ibit;    devfs_handle_t            noslot_conn;    char                    devnm[MAXDEVNAME], *s;    pcibr_hints_t           pcibr_hints;    uint64_t              int_enable;    bridgereg_t             int_enable_32;

⌨️ 快捷键说明

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