void mpcpcibrattach(struct device *parent, struct device *self, void *aux) { struct pcibr_softc *sc = (struct pcibr_softc *)self; struct confargs *ca = aux; struct pcibr_config *lcp; struct pcibus_attach_args pba; int node; int of_node = 0; char compat[32]; u_int32_t addr_offset; u_int32_t data_offset; int i; int len; int rangesize; u_int32_t range_store[32]; if (ca->ca_node == 0) { printf("invalid node on mpcpcibr config\n"); return; } len=OF_getprop(ca->ca_node, "name", compat, sizeof (compat)); compat[len] = '\0'; if (len > 0) printf(" %s", compat); len=OF_getprop(ca->ca_node, "compatible", compat, sizeof (compat)); if (len <= 0 ) { len=OF_getprop(ca->ca_node, "name", compat, sizeof (compat)); if (len <= 0) { printf(" compatible and name not found\n"); return; } compat[len] = 0; if (strcmp (compat, "bandit") != 0) { printf(" compatible not found and name %s found\n", compat); return; } } compat[len] = 0; if ((rangesize = OF_getprop(ca->ca_node, "ranges", range_store, sizeof (range_store))) <= 0) { if (strcmp(compat, "u3-ht") == 0) { range_store[0] = 0xabb10113; /* appl U3; */ } else printf("range lookup failed, node %x\n", ca->ca_node); } /* translate byte(s) into item count*/ lcp = sc->sc_pcibr = &sc->pcibr_config; if (ppc_proc_is_64b) mpcpcibus_find_ranges_64 (sc, range_store, rangesize); else mpcpcibus_find_ranges_32 (sc, range_store, rangesize); addr_offset = 0; for (i = 0; config_offsets[i].compat != NULL; i++) { struct config_type *co = &config_offsets[i]; if (strcmp(co->compat, compat) == 0) { addr_offset = co->addr; data_offset = co->data; lcp->config_type = co->config_type; break; } } if (addr_offset == 0) { printf("unable to find match for" " compatible %s\n", compat); return; } #ifdef DEBUG_FIXUP printf(" mem base %x sz %x io base %x sz %x\n" " config addr %x config data %x\n", sc->sc_membus_space.bus_base, sc->sc_membus_space.bus_size, sc->sc_iobus_space.bus_base, sc->sc_iobus_space.bus_size, addr_offset, data_offset); #endif if ( bus_space_map(&(sc->sc_iobus_space), addr_offset, NBPG, 0, &lcp->ioh_cf8) != 0 ) panic("mpcpcibus: unable to map self"); if ( bus_space_map(&(sc->sc_iobus_space), data_offset, NBPG, 0, &lcp->ioh_cfc) != 0 ) panic("mpcpcibus: unable to map self"); of_node = ca->ca_node; lcp->node = ca->ca_node; lcp->lc_pc.pc_conf_v = lcp; lcp->lc_pc.pc_attach_hook = mpc_attach_hook; lcp->lc_pc.pc_bus_maxdevs = mpc_bus_maxdevs; lcp->lc_pc.pc_make_tag = mpc_make_tag; lcp->lc_pc.pc_decompose_tag = mpc_decompose_tag; lcp->lc_pc.pc_conf_read = mpc_conf_read; lcp->lc_pc.pc_conf_write = mpc_conf_write; lcp->lc_pc.pc_ether_hw_addr = of_ether_hw_addr; lcp->lc_iot = &sc->sc_iobus_space; lcp->lc_memt = &sc->sc_membus_space; lcp->lc_pc.pc_intr_v = lcp; lcp->lc_pc.pc_intr_map = mpc_intr_map; lcp->lc_pc.pc_intr_string = mpc_intr_string; lcp->lc_pc.pc_intr_line = mpc_intr_line; lcp->lc_pc.pc_intr_establish = mpc_intr_establish; lcp->lc_pc.pc_intr_disestablish = mpc_intr_disestablish; printf(": %s, Revision 0x%x\n", compat, mpc_cfg_read_1(lcp, MPC106_PCI_REVID)); if ((strcmp(compat, "bandit")) != 0) pci_addr_fixup(sc, &lcp->lc_pc, 32); pba.pba_dmat = &pci_bus_dma_tag; pba.pba_busname = "pci"; pba.pba_iot = &sc->sc_iobus_space; pba.pba_memt = &sc->sc_membus_space; pba.pba_pc = &lcp->lc_pc; pba.pba_domain = pci_ndomains++; pba.pba_bus = 0; pba.pba_bridgetag = NULL; /* we want to check pci irq settings */ if (of_node != 0) { int nn; for (node = OF_child(of_node); node; node = nn) { char name[32]; int len; len = OF_getprop(node, "name", name, sizeof(name)); name[len] = 0; fix_node_irq(node, &pba); /* iterate section */ if ((nn = OF_child(node)) != 0) continue; while ((nn = OF_peer(node)) == 0) { node = OF_parent(node); if (node == of_node) { nn = 0; /* done */ break; } } } } config_found(self, &pba, mpcpcibrprint); }
void mpcpcibrattach(struct device *parent, struct device *self, void *aux) { struct pcibr_softc *sc = (struct pcibr_softc *)self; struct confargs *ca = aux; struct pcibr_config *lcp; struct pcibus_attach_args pba; int of_node = 0; char compat[32]; u_int32_t addr_offset; u_int32_t data_offset; int i; int len; int rangesize; u_int32_t range_store[32]; if (ca->ca_node == 0) { printf("invalid node on mpcpcibr config\n"); return; } len=OF_getprop(ca->ca_node, "name", compat, sizeof (compat)); compat[len] = '\0'; if (len > 0) printf(" %s", compat); len=OF_getprop(ca->ca_node, "compatible", compat, sizeof (compat)); if (len <= 0 ) { len=OF_getprop(ca->ca_node, "name", compat, sizeof (compat)); if (len <= 0) { printf(" compatible and name not found\n"); return; } compat[len] = 0; if (strcmp (compat, "bandit") != 0) { printf(" compatible not found and name %s found\n", compat); return; } } compat[len] = 0; if ((rangesize = OF_getprop(ca->ca_node, "ranges", range_store, sizeof (range_store))) <= 0) { if (strcmp(compat, "u3-ht") == 0) { range_store[0] = 0xabb10113; /* appl U3; */ } else printf("range lookup failed, node %x\n", ca->ca_node); } /* translate byte(s) into item count*/ lcp = &sc->pcibr_config; snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name), "%s pciio", sc->sc_dev.dv_xname); sc->sc_ioex = extent_create(sc->sc_ioex_name, 0x00000000, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name), "%s pcimem", sc->sc_dev.dv_xname); sc->sc_memex = extent_create(sc->sc_memex_name, 0x00000000, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); if (ppc_proc_is_64b) mpcpcibus_find_ranges_64 (sc, range_store, rangesize); else mpcpcibus_find_ranges_32 (sc, range_store, rangesize); addr_offset = 0; for (i = 0; config_offsets[i].compat != NULL; i++) { struct config_type *co = &config_offsets[i]; if (strcmp(co->compat, compat) == 0) { addr_offset = co->addr; data_offset = co->data; lcp->config_type = co->config_type; break; } } if (addr_offset == 0) { printf("unable to find match for" " compatible %s\n", compat); return; } #ifdef DEBUG_FIXUP printf(" mem base %x sz %x io base %x sz %x\n" " config addr %x config data %x\n", sc->sc_membus_space.bus_base, sc->sc_membus_space.bus_size, sc->sc_iobus_space.bus_base, sc->sc_iobus_space.bus_size, addr_offset, data_offset); #endif if ( bus_space_map(&(sc->sc_iobus_space), addr_offset, NBPG, 0, &lcp->ioh_cf8) != 0 ) panic("mpcpcibus: unable to map self"); if ( bus_space_map(&(sc->sc_iobus_space), data_offset, NBPG, 0, &lcp->ioh_cfc) != 0 ) panic("mpcpcibus: unable to map self"); of_node = ca->ca_node; lcp->lc_pc.pc_conf_v = lcp; lcp->lc_pc.pc_node = ca->ca_node; lcp->lc_pc.pc_conf_read = mpc_conf_read; lcp->lc_pc.pc_conf_write = mpc_conf_write; lcp->lc_iot = &sc->sc_iobus_space; lcp->lc_memt = &sc->sc_membus_space; printf(": %s\n", compat); bzero(&pba, sizeof(pba)); pba.pba_dmat = &pci_bus_dma_tag; pba.pba_busname = "pci"; pba.pba_iot = &sc->sc_iobus_space; pba.pba_memt = &sc->sc_membus_space; pba.pba_ioex = sc->sc_ioex; pba.pba_memex = sc->sc_memex; pba.pba_pc = &lcp->lc_pc; pba.pba_domain = pci_ndomains++; pba.pba_bus = 0; config_found(self, &pba, mpcpcibrprint); }