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

📄 pcibr_dvr.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
    picreg_t                int_enable_64;    unsigned                rrb_fixed = 0;    int                     spl_level;#if PCI_FBBE    int                     fast_back_to_back_enable;#endif    nasid_t		    nasid;    int	                    iobrick_type_get_nasid(nasid_t nasid);    int                     iobrick_module_get_nasid(nasid_t nasid);    extern unsigned char    Is_pic_on_this_nasid[512];    async_attach_t          aa = NULL;    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,	        "pcibr_attach2: bridge=0x%p, busnum=%d\n", bridge, busnum));    aa = async_attach_get_info(xconn_vhdl);    ctlr_vhdl = NULL;    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,                0, DEVFS_FL_AUTO_DEVNUM,                0, 0,                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,                &pcibr_fops, NULL);    ASSERT(ctlr_vhdl != NULL);    /*     * Get the hint structure; if some NIC callback     * marked this vertex as "hands-off" then we     * just return here, before doing anything else.     */    pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);    if (pcibr_hints && pcibr_hints->ph_hands_off)	return -1;			/* generic operations disabled */    id = bridge->b_wid_id;    rev = XWIDGET_PART_REV_NUM(id);    hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev);    /*     * allocate soft state structure, fill in some     * fields, and hook it up to our vertex.     */    NEW(pcibr_soft);    if (ret_softp)	*ret_softp = pcibr_soft;    BZERO(pcibr_soft, sizeof *pcibr_soft);    pcibr_soft_set(pcibr_vhdl, pcibr_soft);    pcibr_soft->bs_conn = xconn_vhdl;    pcibr_soft->bs_vhdl = pcibr_vhdl;    pcibr_soft->bs_base = bridge;    pcibr_soft->bs_rev_num = rev;    pcibr_soft->bs_intr_bits = (pcibr_intr_bits_f *)pcibr_intr_bits;    pcibr_soft->bs_min_slot = 0;		/* lowest possible slot# */    pcibr_soft->bs_max_slot = 7;		/* highest possible slot# */    pcibr_soft->bs_busnum = busnum;    if (is_xbridge(bridge)) {	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_XBRIDGE;    } else if (is_pic(bridge)) {	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;    } else {	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_BRIDGE;    }    switch(pcibr_soft->bs_bridge_type) {    case PCIBR_BRIDGETYPE_BRIDGE:	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;	pcibr_soft->bs_bridge_mode = 0;	/* speed is not available in bridge */	break;    case PCIBR_BRIDGETYPE_PIC:        pcibr_soft->bs_min_slot = 0;	pcibr_soft->bs_max_slot = 3;	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;	pcibr_soft->bs_bridge_mode = 	   (((bridge->p_wid_stat_64 & PIC_STAT_PCIX_SPEED) >> 33) |	    ((bridge->p_wid_stat_64 & PIC_STAT_PCIX_ACTIVE) >> 33));	/* We have to clear PIC's write request buffer to avoid parity	 * errors.  See PV#854845.	 */	{	int i;	for (i=0; i < PIC_WR_REQ_BUFSIZE; i++) {		bridge->p_wr_req_lower[i] = 0;		bridge->p_wr_req_upper[i] = 0;		bridge->p_wr_req_parity[i] = 0;	}	}	break;    case PCIBR_BRIDGETYPE_XBRIDGE:	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;	pcibr_soft->bs_bridge_mode = 	   ((bridge->b_wid_control & BRIDGE_CTRL_PCI_SPEED) >> 3);	break;    }    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,		"pcibr_attach2: pcibr_soft=0x%x, mode=0x%x\n",                pcibr_soft, pcibr_soft->bs_bridge_mode));    pcibr_soft->bsi_err_intr = 0;    /* Bridges up through REV C     * are unable to set the direct     * byteswappers to BYTE_STREAM.     */    if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) {	pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES;	pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES;    }#if PCIBR_SOFT_LIST    /*     * link all the pcibr_soft structs     */    {	pcibr_list_p            self;	NEW(self);	self->bl_soft = pcibr_soft;	self->bl_vhdl = pcibr_vhdl;	self->bl_next = pcibr_list;	pcibr_list = self;    }#endif /* PCIBR_SOFT_LIST */    /*     * get the name of this bridge vertex and keep the info. Use this     * only where it is really needed now: like error interrupts.     */    s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);    pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);    strcpy(pcibr_soft->bs_name, s);    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,		"pcibr_attach2: %s ASIC: rev %s (code=0x%x)\n",		IS_XBRIDGE_SOFT(pcibr_soft) ? "XBridge" :			IS_PIC_SOFT(pcibr_soft) ? "PIC" : "Bridge", 		(rev == BRIDGE_PART_REV_A) ? "A" :                 (rev == BRIDGE_PART_REV_B) ? "B" :                (rev == BRIDGE_PART_REV_C) ? "C" :                (rev == BRIDGE_PART_REV_D) ? "D" :                (rev == XBRIDGE_PART_REV_A) ? "A" :                (rev == XBRIDGE_PART_REV_B) ? "B" :                (IS_PIC_PART_REV_A(rev)) ? "A" :                 "unknown", rev, pcibr_soft->bs_name));    info = xwidget_info_get(xconn_vhdl);    pcibr_soft->bs_xid = xwidget_info_id_get(info);    pcibr_soft->bs_master = xwidget_info_master_get(info);    pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);    pcibr_soft->bs_first_slot = pcibr_soft->bs_min_slot;    pcibr_soft->bs_last_slot = pcibr_soft->bs_max_slot;    /*     * Bridge can only reset slots 0, 1, 2, and 3.  Ibrick internal     * slots 4, 5, 6, and 7 must be reset as a group, so do not     * reset them.     */    pcibr_soft->bs_last_reset = 3;    nasid = NASID_GET(bridge);    /* set whether it is a PIC or not */    Is_pic_on_this_nasid[nasid] = (IS_PIC_SOFT(pcibr_soft)) ? 1 : 0;    if ((pcibr_soft->bs_bricktype = iobrick_type_get_nasid(nasid)) < 0)	printk(KERN_WARNING "0x%p: Unknown bricktype : 0x%x\n", (void *)xconn_vhdl,				(unsigned int)pcibr_soft->bs_bricktype);    pcibr_soft->bs_moduleid = iobrick_module_get_nasid(nasid);    if (pcibr_soft->bs_bricktype > 0) {	switch (pcibr_soft->bs_bricktype) {	case MODULE_PXBRICK:	    pcibr_soft->bs_first_slot = 0;	    pcibr_soft->bs_last_slot = 1;	    pcibr_soft->bs_last_reset = 1;	    break;	case MODULE_PEBRICK:	case MODULE_PBRICK:            pcibr_soft->bs_first_slot = 1;            pcibr_soft->bs_last_slot = 2;            pcibr_soft->bs_last_reset = 2;            break;        case MODULE_IBRICK:	    /*	     * Here's the current baseio layout for SN1 style systems:	     *	     *    0    1    2    3    4    5    6    7		slot#	     *	     *    x    scsi x    x    ioc3 usb  x    x  	O300 Ibrick	     *             * x == never occupied             * E == external (add-in) slot	     *	     */            pcibr_soft->bs_first_slot = 1;	/* Ibrick first slot == 1 */            if (pcibr_soft->bs_xid == 0xe) {                 pcibr_soft->bs_last_slot = 2;                pcibr_soft->bs_last_reset = 2;            } else {		pcibr_soft->bs_last_slot = 6;	    }            break;	default:	    break;        }	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,		    "pcibr_attach2: %cbrick, slots %d-%d\n",		    MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid),		    pcibr_soft->bs_first_slot, pcibr_soft->bs_last_slot));    }    /*     * Initialize bridge and bus locks     */    spin_lock_init(&pcibr_soft->bs_lock);#ifdef PIC_LATER    mrinit(pcibr_soft->bs_bus_lock, "bus_lock");#endif    /*     * If we have one, process the hints structure.     */    if (pcibr_hints) {	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, pcibr_vhdl,                    "pcibr_attach2: pcibr_hints=0x%x\n", pcibr_hints));	rrb_fixed = pcibr_hints->ph_rrb_fixed;	pcibr_soft->bs_rrb_fixed = rrb_fixed;	if (pcibr_hints->ph_intr_bits) {	    pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;	}	for (slot = pcibr_soft->bs_min_slot; 				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	    int hslot = pcibr_hints->ph_host_slot[slot] - 1;	    if (hslot < 0) {		pcibr_soft->bs_slot[slot].host_slot = slot;	    } else {		pcibr_soft->bs_slot[slot].has_host = 1;		pcibr_soft->bs_slot[slot].host_slot = hslot;	    }	}    }    /*     * Set-up initial values for state fields     */    for (slot = pcibr_soft->bs_min_slot; 				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;	pcibr_soft->bs_slot[slot].bss_devio.bssd_ref_cnt = 0;	pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;	pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;	pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0);	pcibr_soft->bs_rrb_valid_dflt[slot][VCHAN0] = -1;    }    for (ibit = 0; ibit < 8; ++ibit) {	pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = 							&(bridge->b_int_status);	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_ibit = ibit;	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;    }    /*     * connect up our error handler.  PIC has 2 busses (thus resulting in 2     * pcibr_soft structs under 1 widget), so only register a xwidget error     * handler for PIC's bus0.  NOTE: for PIC pcibr_error_handler_wrapper()     * is a wrapper routine we register that will call the real error handler     * pcibr_error_handler() with the correct pcibr_soft struct.     */    if (IS_PIC_SOFT(pcibr_soft)) {	if (busnum == 0) {	    xwidget_error_register(xconn_vhdl, pcibr_error_handler_wrapper, pcibr_soft);	}    } else {	xwidget_error_register(xconn_vhdl, pcibr_error_handler, pcibr_soft);    }    /*     * Initialize various Bridge registers.     */      /*     * On pre-Rev.D bridges, set the PCI_RETRY_CNT     * to zero to avoid dropping stores. (#475347)     */    if (rev < BRIDGE_PART_REV_D)	bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK;    /*     * Clear all pending interrupts.     */    bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);    /* Initialize some PIC specific registers. */    if (IS_PIC_SOFT(pcibr_soft)) {	picreg_t pic_ctrl_reg = bridge->p_wid_control_64;	/* Bridges Requester ID: bus = busnum, dev = 0, func = 0 */	pic_ctrl_reg &= ~PIC_CTRL_BUS_NUM_MASK;	pic_ctrl_reg |= PIC_CTRL_BUS_NUM(busnum);	pic_ctrl_reg &= ~PIC_CTRL_DEV_NUM_MASK;	pic_ctrl_reg &= ~PIC_CTRL_FUN_NUM_MASK;	pic_ctrl_reg &= ~PIC_CTRL_NO_SNOOP;	pic_ctrl_reg &= ~PIC_CTRL_RELAX_ORDER;	/* enable parity checking on PICs internal RAM */	pic_ctrl_reg |= PIC_CTRL_PAR_EN_RESP;	pic_ctrl_reg |= PIC_CTRL_PAR_EN_ATE;	/* PIC BRINGUP WAR (PV# 862253): dont enable write request	 * parity checking.	 */	if (!PCIBR_WAR_ENABLED(PV862253, pcibr_soft)) {	    pic_ctrl_reg |= PIC_CTRL_PAR_EN_REQ;	}	bridge->p_wid_control_64 = pic_ctrl_reg;    }    /*     * Until otherwise set up,     * assume all interrupts are     * from slot 7(Bridge/Xbridge) or 3(PIC).     * XXX. Not sure why we're doing this, made change for PIC     * just to avoid setting reserved bits.     */    if (IS_PIC_SOFT(pcibr_soft))	bridge->b_int_device = (uint32_t) 0x006db6db;    else	bridge->b_int_device = (uint32_t) 0xffffffff;    {	bridgereg_t             dirmap;	paddr_t                 paddr;	iopaddr_t               xbase;	xwidgetnum_t            xport;	iopaddr_t               offset;	int                     num_entries = 0;	int                     entry;	cnodeid_t		cnodeid;	nasid_t			nasid;#ifdef PIC_LATER	char		       *node_val;	devfs_handle_t		node_vhdl;	char			vname[MAXDEVNAME];#endif	/* Set the Bridge's 32-bit PCI to XTalk	 * Direct Map register to the most useful	 * value we can determine.  Note that we	 * must use a single xid for all of:	 *      direct-mapped 32-bit DMA accesses	 *      direct-mapped 64-bit DMA accesses	 *      DMA accesses through the PMU	 *      interrupts	 * This is the only way to guarantee that	 * completion interrupts will reach a CPU	 * after all DMA data has reached memory.	 * (Of course, there may be a few special	 * drivers/controlers that explicitly manage	 * this ordering problem.)	 */	cnodeid = 0;  /* default node id */	/*	 * Determine the base address node id to be used for all 32-bit	 * Direct Mapping I/O. The default is node 0, but this can be changed	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE	 * attribute in the irix.sm config file. A device driver can obtain	 * this node value via a call to pcibr_get_dmatrans_node().	 */#ifdef PIC_LATER// This probably needs to be addressed - pfg	node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE);	if (node_val != NULL) {	    node_vhdl = hwgraph_path_to_vertex(node_val);	    if (node_vhdl != GRAPH_VERTEX_NONE) {		cnodeid = nodevertex_to_cnodeid(node_vhdl);	    }	    if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) {

⌨️ 快捷键说明

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