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 */ }
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; }