Example #1
0
caddr_t
xtalk_pio_addr(vertex_hdl_t dev,	/* translate for this device */
	       device_desc_t dev_desc,	/* device descriptor */
	       iopaddr_t addr,		/* starting address (or offset in window) */
	       size_t byte_count,	/* map this many bytes */
	       xtalk_piomap_t *mapp,	/* where to return the map pointer */
	       unsigned flags)
{					/* PIO flags */
    xtalk_piomap_t          map = 0;
    caddr_t                 res;

    if (mapp)
	*mapp = 0;			/* record "no map used" */

    res = xtalk_piotrans_addr
	(dev, dev_desc, addr, byte_count, flags);
    if (res)
	return res;			/* xtalk_piotrans worked */

    map = xtalk_piomap_alloc
	(dev, dev_desc, addr, byte_count, byte_count, flags);
    if (!map)
	return res;			/* xtalk_piomap_alloc failed */

    res = xtalk_piomap_addr
	(map, addr, byte_count);
    if (!res) {
	xtalk_piomap_free(map);
	return res;			/* xtalk_piomap_addr failed */
    }
    if (mapp)
	*mapp = map;			/* pass back map used */

    return res;				/* xtalk_piomap_addr succeeded */
}
Example #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;
}