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

📄 pcibr_dvr.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
	    struct pcibr_slot_req_s        req;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }            if (COPYIN(arg, &req, sizeof(req))) {                error = EFAULT;                break;            }	    error = pcibr_slot_startup(pcibr_vhdl, &req);	    break;	}    case PCIBR_SLOT_SHUTDOWN:	{	    struct pcibr_slot_req_s        req;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }            if (COPYIN(arg, &req, sizeof(req))) {                error = EFAULT;                break;            }	    error = pcibr_slot_shutdown(pcibr_vhdl, &req);	    break;	}    case PCIBR_SLOT_QUERY:	{	    struct pcibr_slot_req_s        req;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }            if (COPYIN(arg, &req, sizeof(req))) {                error = EFAULT;                break;            }            error = pcibr_slot_query(pcibr_vhdl, &req);	    break;	}#endif	/* LATER */    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 */}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;    NEW(pcibr_info);    pciio_device_info_new(&pcibr_info->f_c,			  pcibr_soft->bs_vhdl,			  slot, rfunc,			  vendor, device);/* pfg - this is new ..... */    /* Set PCI bus number */    pcibr_info->f_bus = io_path_map_widget(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;}/* FIXME:  for now this is needed by both pcibr.c and * pcibr_slot.c.  Need to find a better way, the least * of which would be to move it to pcibr_private.h *//* * PCI_ADDR_SPACE_LIMITS_STORE *	Sets the current values of *		pci io base,  *		pci io last, *		pci low memory base, *		pci low memory last, *		pci high memory base, * 		pci high memory last */#define PCI_ADDR_SPACE_LIMITS_STORE()			\    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;/* * 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 = pciio_info_slot_get(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] >= 0) {        s = pcibr_lock(pcibr_soft);        /* Free the rrbs allocated to this slot */        error_call = do_pcibr_rrb_free(bridge, slot, 		                       pcibr_soft->bs_rrb_valid[slot] +		                       pcibr_soft->bs_rrb_valid[slot +                                        PCIBR_RRB_SLOT_VIRTUAL]);        if (error_call)            error = ERANGE;            pcibr_soft->bs_rrb_res[slot] = pcibr_soft->bs_rrb_res[slot] +                                        pcibr_soft->bs_rrb_valid[slot] +                                        pcibr_soft->bs_rrb_valid[slot +                                        PCIBR_RRB_SLOT_VIRTUAL];        count_vchan0 = pcibr_soft->bs_rrb_valid_dflt[slot];        count_vchan1 = pcibr_soft->bs_rrb_valid_dflt[slot +                                                     PCIBR_RRB_SLOT_VIRTUAL];        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 = pciio_info_slot_get(pciio_info);    pcibr_soft = pcibr_soft_get(pcibr_vhdl);    /* This may be a loadable driver so lock out any pciconfig actions */    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);    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;    }            /* Release the bus lock */    mrunlock(pcibr_soft->bs_bus_lock);}/* * 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 = pciio_info_slot_get(pciio_info);    pcibr_soft = pcibr_soft_get(pcibr_vhdl);    /* This may be a loadable driver so lock out any pciconfig actions */    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);    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;    }            /* Release the bus lock */    mrunlock(pcibr_soft->bs_bus_lock);}/*  * 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, int slot){        char dst[MAXDEVNAME];	char *dp = dst;        char *cp, *xp;        int widgetnum;        char pcibus[8];	devfs_handle_t nvtx, svtx;	int rv;#if DEBUG	printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", 		slot, f_c);	{		int pos;		char dname[256];		pos = devfs_generate_path(f_c, dname, 256);		printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);	}#endif	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 "/" "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, "/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);}

⌨️ 快捷键说明

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