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

📄 xbow.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * is not listed here, it is not on.	 */	xbow->xb_link(port).link_control =	    ( (xbow->xb_link(port).link_control	/*	 * Turn off these bits; they are non-fatal,	 * but we might want to save some statistics	 * on the frequency of these errors.	 * XXX FIXME XXX	 */	    & ~XB_CTRL_RCV_CNT_OFLOW_IE	    & ~XB_CTRL_XMT_CNT_OFLOW_IE	    & ~XB_CTRL_BNDWDTH_ALLOC_IE	    & ~XB_CTRL_RCV_IE)	/*	 * These are the ones we want to turn on.	 */	    | (XB_CTRL_ILLEGAL_DST_IE	    | XB_CTRL_OALLOC_IBUF_IE	    | XB_CTRL_XMT_MAX_RTRY_IE	    | XB_CTRL_MAXREQ_TOUT_IE	    | XB_CTRL_XMT_RTRY_IE	    | XB_CTRL_SRC_TOUT_IE) );    }    xswitch_provider_register(busv, &xbow_provider);    return 0;				/* attach successful */}/*ARGSUSED */intxbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp){    return 0;}/*ARGSUSED */intxbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp){    return 0;}/*ARGSUSED */intxbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot){    devfs_handle_t            vhdl = dev_to_vhdl(dev);    xbow_soft_t             soft = xbow_soft_get(vhdl);    int                     error;    ASSERT(soft);    len = ctob(btoc(len));    /* XXX- this ignores the offset!!! */    error = v_mapphys(vt, (void *) soft->base, len);    return error;}/*ARGSUSED */intxbow_unmap(devfs_handle_t dev, vhandl_t *vt){    return 0;}/* This contains special-case code for grio. There are plans to make * this general sometime in the future, but till then this should * be good enough. */xwidgetnum_txbow_widget_num_get(devfs_handle_t dev){	devfs_handle_t	tdev;	char		devname[MAXDEVNAME];	xwidget_info_t	xwidget_info;	int		i;	vertex_to_name(dev, devname, MAXDEVNAME);	/* If this is a pci controller vertex, traverse up using	 * the ".." links to get to the widget.	 */	if (strstr(devname, EDGE_LBL_PCI) &&			strstr(devname, EDGE_LBL_CONTROLLER)) {		tdev = dev;		for (i=0; i< 2; i++) {			if (hwgraph_edge_get(tdev,				HWGRAPH_EDGELBL_DOTDOT, &tdev) !=					GRAPH_SUCCESS)				return XWIDGET_NONE;		}		if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) {			return (xwidget_info_id_get(xwidget_info));		} else {			return XWIDGET_NONE;		}	}	return XWIDGET_NONE;}intxbow_ioctl(devfs_handle_t dev,	   int cmd,	   void *arg,	   int flag,	   struct cred *cr,	   int *rvalp){    devfs_handle_t            vhdl;    int                     error = 0;#if defined (DEBUG)    int                     rc;    devfs_handle_t            conn;    struct xwidget_info_s  *xwidget_info;    xbow_soft_t             xbow_soft;#endif    *rvalp = 0;    vhdl = dev_to_vhdl(dev);#if defined (DEBUG)    xbow_soft = xbow_soft_get(vhdl);    conn = xbow_soft->conn;    xwidget_info = xwidget_info_get(conn);    ASSERT_ALWAYS(xwidget_info != NULL);    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);    ASSERT_ALWAYS(rc != 0);#endif    switch (cmd) {    case XBOWIOC_LLP_ERROR_ENABLE:	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)	    error = EINVAL;	break;    case XBOWIOC_LLP_ERROR_DISABLE:	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)	    error = EINVAL;	break;    default:	break;    }    return error;}/* * xbow_widget_present: See if a device is present * on the specified port of this crossbow. */intxbow_widget_present(xbow_t *xbow, int port){	if ( IS_RUNNING_ON_SIMULATOR() ) {		if ( (port == 14) || (port == 15) ) {			return 1;		}		else {			return 0;		}	}	else {		/* WAR: port 0xf on PIC is missing present bit */		if (XBOW_WAR_ENABLED(PV854827, xbow->xb_wid_id) &&					IS_PIC_XBOW(xbow->xb_wid_id) && port==0xf) {			return 1;		}		return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;	}}static intxbow_link_alive(xbow_t * xbow, int port){    xbwX_stat_t             xbow_linkstat;    xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;    return (xbow_linkstat.link_alive);}/* * xbow_widget_lookup *      Lookup the edges connected to the xbow specified, and *      retrieve the handle corresponding to the widgetnum *      specified. *      If not found, return 0. */devfs_handle_txbow_widget_lookup(devfs_handle_t vhdl,		   int widgetnum){    xswitch_info_t          xswitch_info;    devfs_handle_t            conn;    xswitch_info = xswitch_info_get(vhdl);    conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);    return conn;}/* * xbow_setwidint: called when xtalk * is establishing or migrating our * interrupt service. */static voidxbow_setwidint(xtalk_intr_t intr){    xwidgetnum_t            targ = xtalk_intr_target_get(intr);    iopaddr_t               addr = xtalk_intr_addr_get(intr);    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);    xbow_t                 *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr);    xbow_intr_preset((void *) xbow, 0, targ, addr, vect);}/* * xbow_intr_preset: called during mlreset time * if the platform specific code needs to route * an xbow interrupt before the xtalk infrastructure * is available for use. * * Also called from xbow_setwidint, so we don't * replicate the guts of the routine. * * XXX- probably should be renamed xbow_wid_intr_set or * something to reduce confusion. *//*ARGSUSED3 */voidxbow_intr_preset(void *which_widget,		 int which_widget_intr,		 xwidgetnum_t targ,		 iopaddr_t addr,		 xtalk_intr_vector_t vect){    xbow_t                 *xbow = (xbow_t *) which_widget;    xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |			      (0x000F0000 & (targ << 16)) |			      XTALK_ADDR_TO_UPPER(addr));    xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);#ifdef BRINGUP2printk("xbow_intr_preset: xb_wid_int_upper 0x%lx xb_wid_int_lower 0x%lx\n",	(long)(((0xFF000000 & (vect << 24)) | (0x000F0000 & (targ << 16)) |XTALK_ADDR_TO_UPPER(addr))), (long)XTALK_ADDR_TO_LOWER(addr));#endif}#define	XEM_ADD_STR(s)		printk("%s", (s))#define	XEM_ADD_NVAR(n,v)	printk("\t%20s: 0x%llx\n", (n), ((unsigned long long)v))#define	XEM_ADD_VAR(v)		XEM_ADD_NVAR(#v,(v))#define XEM_ADD_IOEF(p,n)	if (IOERROR_FIELDVALID(ioe,n)) {	\				    IOERROR_GETVALUE(p,ioe,n);		\				    XEM_ADD_NVAR("ioe." #n, p);		\				}#ifdef LATERstatic voidxem_add_ioe(ioerror_t *ioe){    union tmp {	ushort stmp;	unsigned long long lltmp;	cpuid_t cputmp;	cnodeid_t cntmp;	iopaddr_t iotmp;	caddr_t catmp;	paddr_t patmp;    } tmp;    XEM_ADD_IOEF(tmp.stmp, errortype);    XEM_ADD_IOEF(tmp.stmp, widgetnum);    XEM_ADD_IOEF(tmp.stmp, widgetdev);    XEM_ADD_IOEF(tmp.cputmp, srccpu);    XEM_ADD_IOEF(tmp.cntmp, srcnode);    XEM_ADD_IOEF(tmp.cntmp, errnode);    XEM_ADD_IOEF(tmp.iotmp, sysioaddr);    XEM_ADD_IOEF(tmp.iotmp, xtalkaddr);    XEM_ADD_IOEF(tmp.iotmp, busspace);    XEM_ADD_IOEF(tmp.iotmp, busaddr);    XEM_ADD_IOEF(tmp.catmp, vaddr);    XEM_ADD_IOEF(tmp.patmp, memaddr);    XEM_ADD_IOEF(tmp.catmp, epc);    XEM_ADD_IOEF(tmp.catmp, ef);    XEM_ADD_IOEF(tmp.stmp, tnum);}#define XEM_ADD_IOE()   (xem_add_ioe(ioe))#endif	/* LATER */int                     xbow_xmit_retry_errors = 0;intxbow_xmit_retry_error(xbow_soft_t soft,		      int port){    xswitch_info_t          info;    devfs_handle_t            vhdl;    widget_cfg_t           *wid;    widgetreg_t             id;    int                     part;    int                     mfgr;    wid = soft->wpio[port - BASE_XBOW_PORT];    if (wid == NULL) {	/* If we can't track down a PIO	 * pointer to our widget yet,	 * leave our caller knowing that	 * we are interested in this	 * interrupt if it occurs in	 * the future.	 */	info = xswitch_info_get(soft->busv);	if (!info)	    return 1;	vhdl = xswitch_info_vhdl_get(info, port);	if (vhdl == GRAPH_VERTEX_NONE)	    return 1;	wid = (widget_cfg_t *) xtalk_piotrans_addr	    (vhdl, 0, 0, sizeof *wid, 0);	if (!wid)	    return 1;	soft->wpio[port - BASE_XBOW_PORT] = wid;    }    id = wid->w_id;    part = XWIDGET_PART_NUM(id);    mfgr = XWIDGET_MFG_NUM(id);    /* If this thing is not a Bridge,     * do not activate the WAR, and     * tell our caller we do not need     * to be called again.     */    if ((part != BRIDGE_WIDGET_PART_NUM) ||	(mfgr != BRIDGE_WIDGET_MFGR_NUM)) {		/* FIXME: add Xbridge to the WAR.		 * Shouldn't hurt anything.  Later need to		 * check if we can remove this.                 */    		if ((part != XBRIDGE_WIDGET_PART_NUM) ||		    (mfgr != XBRIDGE_WIDGET_MFGR_NUM))			return 0;    }    /* count how many times we     * have picked up after     * LLP Transmit problems.     */    xbow_xmit_retry_errors++;    /* rewrite the control register     * to fix things up.     */    wid->w_control = wid->w_control;    wid->w_control;    return 1;}/* * xbow_errintr_handler will be called if the xbow * sends an interrupt request to report an error. */static voidxbow_errintr_handler(int irq, void *arg, struct pt_regs *ep){    ioerror_t               ioe[1];    xbow_soft_t             soft = (xbow_soft_t) arg;    xbow_t                 *xbow = soft->base;    xbowreg_t               wid_control;    xbowreg_t               wid_stat;    xbowreg_t               wid_err_cmdword;    xbowreg_t               wid_err_upper;    xbowreg_t               wid_err_lower;    w_err_cmd_word_u        wid_err;    unsigned long long      wid_err_addr;    int                     fatal = 0;    int                     dump_ioe = 0;    static int xbow_error_handler(void *, int, ioerror_mode_t, ioerror_t *);    wid_control = xbow->xb_wid_control;    wid_stat = xbow->xb_wid_stat_clr;    wid_err_cmdword = xbow->xb_wid_err_cmdword;    wid_err_upper = xbow->xb_wid_err_upper;    wid_err_lower = xbow->xb_wid_err_lower;    xbow->xb_wid_err_cmdword = 0;    wid_err_addr = wid_err_lower | (((iopaddr_t) wid_err_upper & WIDGET_ERR_UPPER_ADDR_ONLY) << 32);    if (wid_stat & XB_WID_STAT_LINK_INTR_MASK) {	int                     port;	wid_err.r = wid_err_cmdword;	for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;	     port < MAX_PORT_NUM; port++) {	    if (wid_stat & XB_WID_STAT_LINK_INTR(port)) {		xb_linkregs_t          *link = &(xbow->xb_link(port));		xbowreg_t               link_control = link->link_control;		xbowreg_t               link_status = link->link_status_clr;		xbowreg_t               link_aux_status = link->link_aux_status;

⌨️ 快捷键说明

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