int siop_pci_match( struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = aux; const struct siop_product_desc *pp; /* look if it's a known product */ pp = siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class)); if (pp) return 1; return 0; }
int siop_pci_attach_common(struct siop_pci_common_softc *pci_sc, struct siop_common_softc *siop_sc, struct pci_attach_args *pa, int (*intr)(void *)) { pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_tag; const char *intrstr; pci_intr_handle_t intrhandle; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; pcireg_t memtype; prop_dictionary_t dict; int memh_valid, ioh_valid; bus_addr_t ioaddr, memaddr; bool use_pciclock; char intrbuf[PCI_INTRSTR_LEN]; aprint_naive(": SCSI controller\n"); pci_sc->sc_pp = siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class)); if (pci_sc->sc_pp == NULL) { aprint_error("sym: broken match/attach!!\n"); return 0; } /* copy interesting infos about the chip */ siop_sc->features = pci_sc->sc_pp->features; #ifdef SIOP_SYMLED /* XXX Should be a devprop! */ siop_sc->features |= SF_CHIP_LED0; #endif dict = device_properties(siop_sc->sc_dev); if (prop_dictionary_get_bool(dict, "use_pciclock", &use_pciclock)) if (use_pciclock) siop_sc->features |= SF_CHIP_USEPCIC; siop_sc->maxburst = pci_sc->sc_pp->maxburst; siop_sc->maxoff = pci_sc->sc_pp->maxoff; siop_sc->clock_div = pci_sc->sc_pp->clock_div; siop_sc->clock_period = pci_sc->sc_pp->clock_period; siop_sc->ram_size = pci_sc->sc_pp->ram_size; siop_sc->sc_reset = siop_pci_reset; aprint_normal(": %s\n", pci_sc->sc_pp->name); pci_sc->sc_pc = pc; pci_sc->sc_tag = tag; siop_sc->sc_dmat = pa->pa_dmat; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x14); switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: memh_valid = (pci_mapreg_map(pa, 0x14, memtype, 0, &memt, &memh, &memaddr, NULL) == 0); break; default: memh_valid = 0; } ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, &ioaddr, NULL) == 0); if (memh_valid) { siop_sc->sc_rt = memt; siop_sc->sc_rh = memh; siop_sc->sc_raddr = memaddr; } else if (ioh_valid) { siop_sc->sc_rt = iot; siop_sc->sc_rh = ioh; siop_sc->sc_raddr = ioaddr; } else { aprint_error_dev(siop_sc->sc_dev, "unable to map device registers\n"); return 0; } if (siop_sc->features & SF_CHIP_RAM) { int bar; switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: bar = 0x18; break; case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: bar = 0x1c; break; default: aprint_error_dev(siop_sc->sc_dev, "invalid memory type %d\n", memtype); return 0; } if (pci_mapreg_map(pa, bar, memtype, 0, &siop_sc->sc_ramt, &siop_sc->sc_ramh, &siop_sc->sc_scriptaddr, NULL) == 0) { aprint_normal_dev(siop_sc->sc_dev, "using on-board RAM\n"); } else { aprint_error_dev(siop_sc->sc_dev, "can't map on-board RAM\n"); siop_sc->features &= ~SF_CHIP_RAM; } } if (pci_intr_map(pa, &intrhandle) != 0) { aprint_error_dev(siop_sc->sc_dev, "couldn't map interrupt\n"); return 0; } intrstr = pci_intr_string(pa->pa_pc, intrhandle, intrbuf, sizeof(intrbuf)); pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, intr, siop_sc); if (pci_sc->sc_ih != NULL) { aprint_normal_dev(siop_sc->sc_dev, "interrupting at %s\n", intrstr ? intrstr : "unknown interrupt"); } else { aprint_error_dev(siop_sc->sc_dev, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return 0; } pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) | PCI_COMMAND_MASTER_ENABLE); return 1; }
int siop_pci_attach_common(struct siop_pci_common_softc *pci_sc, struct siop_common_softc *siop_sc, struct pci_attach_args *pa, int (*intr)(void*)) { pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_tag; const char *intrstr; pci_intr_handle_t intrhandle; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; pcireg_t memtype; int memh_valid, ioh_valid; bus_addr_t ioaddr, memaddr; bus_size_t memsize, iosize; pci_sc->sc_pp = siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class)); if (pci_sc->sc_pp == NULL) { printf(": broken match/attach!\n"); return 0; } /* copy interesting infos about the chip */ siop_sc->features = pci_sc->sc_pp->features; #ifdef SIOP_SYMLED /* XXX Should be a devprop! */ siop_sc->features |= SF_CHIP_LED0; #endif siop_sc->maxburst = pci_sc->sc_pp->maxburst; siop_sc->maxoff = pci_sc->sc_pp->maxoff; siop_sc->clock_div = pci_sc->sc_pp->clock_div; siop_sc->clock_period = pci_sc->sc_pp->clock_period; siop_sc->ram_size = pci_sc->sc_pp->ram_size; siop_sc->sc_reset = siop_pci_reset; pci_sc->sc_pc = pc; pci_sc->sc_tag = tag; siop_sc->sc_dmat = pa->pa_dmat; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x14); switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: memh_valid = (pci_mapreg_map(pa, 0x14, memtype, 0, &memt, &memh, &memaddr, NULL, 0) == 0); break; default: memh_valid = 0; } ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, &ioaddr, &iosize, 0) == 0); if (memh_valid) { siop_sc->sc_rt = memt; siop_sc->sc_rh = memh; siop_sc->sc_raddr = memaddr; } else if (ioh_valid) { siop_sc->sc_rt = iot; siop_sc->sc_rh = ioh; siop_sc->sc_raddr = ioaddr; } else { printf(": unable to map device registers\n"); return 0; } if (pci_intr_map(pa, &intrhandle) != 0) { printf(": couldn't map interrupt\n"); bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize); return 0; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, intr, siop_sc, siop_sc->sc_dev.dv_xname); if (pci_sc->sc_ih != NULL) { printf(": %s", intrstr ? intrstr : "?"); } else { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize); return 0; } if (siop_sc->features & SF_CHIP_RAM) { int bar; switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: bar = 0x18; break; case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: bar = 0x1c; break; default: printf(": invalid memory type %d\n", memtype); return 0; } if (pci_mapreg_map(pa, bar, memtype, 0, &siop_sc->sc_ramt, &siop_sc->sc_ramh, &siop_sc->sc_scriptaddr, &memsize, 0) == 0) { printf(", using %luK of on-board RAM", (u_long)memsize / 1024); } else { printf(", can't map on-board RAM"); siop_sc->features &= ~SF_CHIP_RAM; } } printf("\n"); return 1; }