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

📄 pcibr_rrb.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 3 页
字号:
	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]	    + pcibr_soft->bs_rrb_res[pciio_slot]	    - delta_vchan0	    - delta_vchan1;	pcibr_soft->bs_rrb_res[pciio_slot] = 0;        /*         * Reserve enough RRBs so this slot's RRB configuration can be         * reset to its boot-time default following a hot-plug shut-down         */	res_rrbs = (pcibr_soft->bs_rrb_res_dflt[pciio_slot] -		    pcibr_soft->bs_rrb_res[pciio_slot]);	for (vchan = 0; vchan < vchan_total; vchan++) {	    res_rrbs += (pcibr_soft->bs_rrb_valid_dflt[pciio_slot][vchan] -			 pcibr_soft->bs_rrb_valid[pciio_slot][vchan]);	}	if (res_rrbs > 0) {            pcibr_soft->bs_rrb_res[pciio_slot] = res_rrbs;            pcibr_soft->bs_rrb_avail[pciio_slot & 1] =                pcibr_soft->bs_rrb_avail[pciio_slot & 1]                - res_rrbs;        } 	pcibr_rrb_debug("pcibr_rrb_alloc", pcibr_soft);	error = 0;    }    pcibr_unlock(pcibr_soft, s);    return error;}/* * Device driver interface to check the current state * of the RRB allocations. * *   pconn_vhdl is your PCI connection point (specifies which *      PCI bus and which slot). * *   count_vchan0 points to where to return the number of RRBs *      assigned to the primary DMA channel, used by all DMA *      that does not explicitly ask for the alternate virtual *      channel. * *   count_vchan1 points to where to return the number of RRBs *      assigned to the secondary DMA channel, used when *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified. * *   count_reserved points to where to return the number of RRBs *      that have been automatically reserved for your device at *      startup, but which have not been assigned to a *      channel. RRBs must be assigned to a channel to be used; *      this can be done either with an explicit pcibr_rrb_alloc *      call, or automatically by the infrastructure when a DMA *      translation is constructed. Any call to pcibr_rrb_alloc *      will release any unassigned reserved RRBs back to the *      free pool. * *   count_pool points to where to return the number of RRBs *      that are currently unassigned and unreserved. This *      number can (and will) change as other drivers make calls *      to pcibr_rrb_alloc, or automatically allocate RRBs for *      DMA beyond their initial reservation. * * NULL may be passed for any of the return value pointers * the caller is not interested in. * * The return value is "0" if all went well, or "-1" if * there is a problem. Additionally, if the wrong vertex * is passed in, one of the subsidiary support functions * could panic with a "bad pciio fingerprint." */intpcibr_rrb_check(devfs_handle_t pconn_vhdl,		int *count_vchan0,		int *count_vchan1,		int *count_reserved,		int *count_pool){    pciio_info_t            pciio_info;    pciio_slot_t            pciio_slot;    pcibr_soft_t            pcibr_soft;    unsigned long                s;    int                     error = -1;    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&	((pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info)) < PCIBR_NUM_SLOTS(pcibr_soft))) {	s = pcibr_lock(pcibr_soft);	if (count_vchan0)	    *count_vchan0 =		pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN0];	if (count_vchan1)	    *count_vchan1 =		pcibr_soft->bs_rrb_valid[pciio_slot][VCHAN1];	if (count_reserved)	    *count_reserved =		pcibr_soft->bs_rrb_res[pciio_slot];	if (count_pool)	    *count_pool =		pcibr_soft->bs_rrb_avail[pciio_slot & 1];	error = 0;	pcibr_unlock(pcibr_soft, s);    }    return error;}/* * pcibr_slot_initial_rrb_alloc *	Allocate a default number of rrbs for this slot on  * 	the two channels.  This is dictated by the rrb allocation * 	strategy routine defined per platform. */intpcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,			     pciio_slot_t slot){    pcibr_soft_t	 pcibr_soft;    pcibr_info_h	 pcibr_infoh;    pcibr_info_t	 pcibr_info;    bridge_t		*bridge;    int 		 vchan_total;    int			 vchan;    int                  chan[4];    pcibr_soft = pcibr_soft_get(pcibr_vhdl);    if (!pcibr_soft)	return(EINVAL);    if (!PCIBR_VALID_SLOT(pcibr_soft, slot))	return(EINVAL);    bridge = pcibr_soft->bs_base;    /* How many RRBs are on this slot? */    vchan_total = NUMBER_VCHANNELS(bridge);    for (vchan = 0; vchan < vchan_total; vchan++)         chan[vchan] = do_pcibr_rrb_count_valid(bridge, slot, vchan);    if (IS_PIC_SOFT(pcibr_soft)) { 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_vhdl,	    "pcibr_slot_initial_rrb_alloc: slot %d started with %d+%d+%d+%d\n",	    PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), 	    chan[VCHAN0], chan[VCHAN1], chan[VCHAN2], chan[VCHAN3]));    } else {	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_vhdl,	    "pcibr_slot_initial_rrb_alloc: slot %d started with %d+%d\n",	    PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), 	    chan[VCHAN0], chan[VCHAN1]));    }    /* Do we really need any?     */    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;    pcibr_info = pcibr_infoh[0];    if (PCIBR_WAR_ENABLED(PV856866, pcibr_soft) && IS_PIC_SOFT(pcibr_soft) &&                        (slot == 2 || slot == 3) &&                        (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&                        !pcibr_soft->bs_slot[slot].has_host) {        for (vchan = 0; vchan < 2; vchan++) {            do_pcibr_rrb_free(bridge, slot, vchan, 8);            pcibr_soft->bs_rrb_valid[slot][vchan] = 0;        }        pcibr_soft->bs_rrb_valid[slot][3] = chan[3];        return(ENODEV);    }    for (vchan = 0; vchan < vchan_total; vchan++)        pcibr_soft->bs_rrb_valid[slot][vchan] = chan[vchan];    return(0);}voidrrb_reserved_free(pcibr_soft_t pcibr_soft, int slot){        int res = pcibr_soft->bs_rrb_res[slot];        if (res) {                 pcibr_soft->bs_rrb_avail[slot & 1] += res;                 pcibr_soft->bs_rrb_res[slot] = 0;        }}/* * pcibr_initial_rrb *      Assign an equal total number of RRBs to all candidate slots,  *      where the total is the sum of the number of RRBs assigned to *      the normal channel, the number of RRBs assigned to the virtual *      channels, and the number of RRBs assigned as reserved.  * *      A candidate slot is any existing (populated or empty) slot. *      Empty SN1 slots need RRBs to support hot-plug operations. */intpcibr_initial_rrb(devfs_handle_t pcibr_vhdl,			     pciio_slot_t first, pciio_slot_t last){    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);    bridge_t               *bridge = pcibr_soft->bs_base;    pciio_slot_t            slot;    int			    rrb_total;    int			    vchan_total;    int			    vchan;    int                     have[2][3];    int                     res[2];    int                     eo;    have[0][0] = have[0][1] = have[0][2] = 0;    have[1][0] = have[1][1] = have[1][2] = 0;    res[0] = res[1] = 0;    vchan_total = NUMBER_VCHANNELS(bridge);    for (slot = pcibr_soft->bs_min_slot; 			slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {        /* Initial RRB management; give back RRBs in all non-existent slots */        (void) pcibr_slot_initial_rrb_alloc(pcibr_vhdl, slot);        /* Base calculations only on existing slots */        if ((slot >= first) && (slot <= last)) {	    rrb_total = 0;	    for (vchan = 0; vchan < vchan_total; vchan++) 		rrb_total += pcibr_soft->bs_rrb_valid[slot][vchan];            if (rrb_total < 3)                have[slot & 1][rrb_total]++;        }    }    /* Initialize even/odd slot available RRB counts */    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);    /*     * Calculate reserved RRBs for slots based on current RRB usage     */    for (eo = 0; eo < 2; eo++) {        if ((3 * have[eo][0] + 2 * have[eo][1] + have[eo][2]) <= pcibr_soft->bs_rrb_avail[eo])            res[eo] = 3;        else if ((2 * have[eo][0] + have[eo][1]) <= pcibr_soft->bs_rrb_avail[eo])            res[eo] = 2;        else if (have[eo][0] <= pcibr_soft->bs_rrb_avail[eo])            res[eo] = 1;        else            res[eo] = 0;    }    /* Assign reserved RRBs to existing slots */    for (slot = first; slot <= last; ++slot) {        int                     r;	rrb_total = 0;	for (vchan = 0; vchan < vchan_total; vchan++)		rrb_total += pcibr_soft->bs_rrb_valid[slot][vchan];        r = res[slot & 1] - (rrb_total);        if (r > 0) {            pcibr_soft->bs_rrb_res[slot] = r;            pcibr_soft->bs_rrb_avail[slot & 1] -= r;        }    }    pcibr_rrb_debug("pcibr_initial_rrb", pcibr_soft);    return 0;}/* * Dump the pcibr_soft_t RRB state variable */voidpcibr_rrb_debug(char *calling_func, pcibr_soft_t pcibr_soft){    pciio_slot_t slot;    char tmp_str[256];        if (pcibr_debug_mask & PCIBR_DEBUG_RRB) {        PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,                    "%s: rrbs available, even=%d, odd=%d\n", calling_func,                    pcibr_soft->bs_rrb_avail[0], pcibr_soft->bs_rrb_avail[1]));        if (IS_PIC_SOFT(pcibr_soft)) {            PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,                        "\tslot\tvchan0\tvchan1\tvchan2\tvchan3\treserved\n"));        } else {	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,		        "\tslot\tvchan0\tvchan1\treserved\n"));        }        for (slot=0; slot < PCIBR_NUM_SLOTS(pcibr_soft); slot++) {	    /*             * The kernel only allows functions to have so many variable args,             * attempting to call PCIBR_DEBUG_ALWAYS() with more than 5 printf             * arguments fails so sprintf() it into a temporary string.             */	    if (IS_PIC_SOFT(pcibr_soft)) {                sprintf(tmp_str, "\t %d\t  %d\t  %d\t  %d\t  %d\t  %d\n", 		        PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),                        0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN0],                        0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN1],                        0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN2],                        0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN3],                        pcibr_soft->bs_rrb_res[slot]);	    } else {	        sprintf(tmp_str, "\t %d\t  %d\t  %d\t  %d\n", 		        PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot),		        0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN0],		        0xFFF & pcibr_soft->bs_rrb_valid[slot][VCHAN1],		        pcibr_soft->bs_rrb_res[slot]);	    }                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_RRB, pcibr_soft->bs_vhdl,                        "%s", tmp_str));        }    }}

⌨️ 快捷键说明

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