示例#1
0
文件: pic.c 项目: 12019/hg556a_source
/*
 * PIC has two buses under a single widget.  pic_attach() calls pic_attach2()
 * to attach each of those buses.
 */
int
pic_attach(vertex_hdl_t conn_v)
{
	int		rc;
	void	*bridge0, *bridge1 = (void *)0;
	vertex_hdl_t	pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
	pcibr_soft_t	bus0_soft, bus1_soft = (pcibr_soft_t)0;
	vertex_hdl_t  conn_v0, conn_v1, peer_conn_v;
	int		bricktype;
	int		iobrick_type_get_nasid(nasid_t nasid);

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));

	bridge0 = pcibr_bridge_ptr_get(conn_v, 0);
	bridge1 = pcibr_bridge_ptr_get(conn_v, 1);

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
		    "pic_attach: bridge0=0x%lx, bridge1=0x%lx\n", 
		    bridge0, bridge1));

	conn_v0 = conn_v1 = conn_v;

	/* If dual-ported then split the two PIC buses across both Cbricks */
	peer_conn_v = pic_bus1_redist(NASID_GET(bridge0), conn_v);
	if (peer_conn_v)
		conn_v1 = peer_conn_v;

	/*
	 * Create the vertex for the PCI buses, 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.
	 */
	bricktype = iobrick_type_get_nasid(NASID_GET(bridge0));
	if ( bricktype == MODULE_CGBRICK ) {
		rc = hwgraph_path_add(conn_v0, EDGE_LBL_AGP_0, &pcibr_vhdl0);
		ASSERT(rc == GRAPH_SUCCESS);
		rc = hwgraph_path_add(conn_v1, EDGE_LBL_AGP_1, &pcibr_vhdl1);
		ASSERT(rc == GRAPH_SUCCESS);
	} else {
		rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
		ASSERT(rc == GRAPH_SUCCESS);
		rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
		ASSERT(rc == GRAPH_SUCCESS);
	}

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
		    "pic_attach: pcibr_vhdl0=0x%lx, pcibr_vhdl1=0x%lx\n",
		    pcibr_vhdl0, pcibr_vhdl1));

	/* register pci provider array */
	pciio_provider_register(pcibr_vhdl0, &pci_pic_provider);
	pciio_provider_register(pcibr_vhdl1, &pci_pic_provider);

	pciio_provider_startup(pcibr_vhdl0);
	pciio_provider_startup(pcibr_vhdl1);

	pic_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft);
	pic_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft);

	{
	    /* If we're dual-ported finish duplicating the peer info structure.
	     * The error handler and arg are done in pic_attach2().
	     */
	    xwidget_info_t info0, info1;
		if (conn_v0 != conn_v1) {	/* dual ported */
			info0 = xwidget_info_get(conn_v0);
			info1 = xwidget_info_get(conn_v1);
			if (info1->w_efunc == (error_handler_f *)NULL)
				info1->w_efunc = info0->w_efunc;
			if (info1->w_einfo == (error_handler_arg_t)0)
				info1->w_einfo = bus1_soft;
		}
	}

	/* save a pointer to the PIC's other bus's soft struct */
        bus0_soft->bs_peers_soft = bus1_soft;
        bus1_soft->bs_peers_soft = bus0_soft;

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
		    "pic_attach: bus0_soft=0x%lx, bus1_soft=0x%lx\n",
		    bus0_soft, bus1_soft));

	return 0;
}
示例#2
0
int
pic_attach(vertex_hdl_t conn_v)
{
    int		rc;
    bridge_t	*bridge0, *bridge1 = (bridge_t *)0;
    vertex_hdl_t	pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
    pcibr_soft_t	bus0_soft, bus1_soft = (pcibr_soft_t)0;
    vertex_hdl_t  conn_v0, conn_v1, peer_conn_v;

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));

    bridge0 = (bridge_t *) xtalk_piotrans_addr(conn_v, NULL,
              0, sizeof(bridge_t), 0);
    bridge1 = (bridge_t *)((char *)bridge0 + PIC_BUS1_OFFSET);

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
                        "pic_attach: bridge0=0x%x, bridge1=0x%x\n",
                        bridge0, bridge1));

    conn_v0 = conn_v1 = conn_v;

    /* If dual-ported then split the two PIC buses across both Cbricks */
    if ((peer_conn_v = (pic_bus1_redist(NASID_GET(bridge0), conn_v))))
        conn_v1 = peer_conn_v;

    /*
     * Create the vertex for the PCI buses, 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.
     */
    /* FIXME: what should the hwgraph path look like ? */
    rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
    ASSERT(rc == GRAPH_SUCCESS);
    rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
    ASSERT(rc == GRAPH_SUCCESS);

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
                        "pic_attach: pcibr_vhdl0=%v, pcibr_vhdl1=%v\n",
                        pcibr_vhdl0, pcibr_vhdl1));

    /* register pci provider array */
    pciio_provider_register(pcibr_vhdl0, &pci_pic_provider);
    pciio_provider_register(pcibr_vhdl1, &pci_pic_provider);

    pciio_provider_startup(pcibr_vhdl0);
    pciio_provider_startup(pcibr_vhdl1);

    pcibr_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft);
    pcibr_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft);

    /* save a pointer to the PIC's other bus's soft struct */
    bus0_soft->bs_peers_soft = bus1_soft;
    bus1_soft->bs_peers_soft = bus0_soft;

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
                        "pic_attach: bus0_soft=0x%x, bus1_soft=0x%x\n",
                        bus0_soft, bus1_soft));

    return 0;
}