static void njs_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct njsc32_pci_softc *psc = device_private(self); struct njsc32_softc *sc = &psc->sc_njsc32; const struct njsc32_pci_product *prod; pci_intr_handle_t ih; pci_chipset_tag_t pc = pa->pa_pc; pcireg_t reg; const char *str_intr, *str_at; char intrbuf[PCI_INTRSTR_LEN]; aprint_naive(": SCSI controller\n"); if ((prod = njs_pci_lookup(pa)) == NULL) panic("njs_pci_attach"); aprint_normal(": Workbit NinjaSCSI-32 SCSI adapter\n"); sc->sc_dev = self; sc->sc_model = prod->p_model; sc->sc_clk = prod->p_clk; psc->sc_pc = pc; /* enable device and DMA */ reg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); reg |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg); /* * Map registers. * Try memory map first, and then try I/O. */ if (pci_mapreg_map(pa, NJSC32_PCI_BASEADDR_MEM, PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_regt, &psc->sc_regmaph, NULL, &psc->sc_regmap_size) == 0) { if (bus_space_subregion(sc->sc_regt, psc->sc_regmaph, NJSC32_MEMOFFSET_REG, NJSC32_REGSIZE, &sc->sc_regh) != 0) { /* failed -- undo map and try I/O */ bus_space_unmap(sc->sc_regt, psc->sc_regmaph, psc->sc_regmap_size); goto try_io; } #ifdef NJSC32_DEBUG printf("%s: memory space mapped\n", device_xname(self)); #endif sc->sc_flags = NJSC32_MEM_MAPPED; } else { try_io: if (pci_mapreg_map(pa, NJSC32_PCI_BASEADDR_IO, PCI_MAPREG_TYPE_IO, 0, &sc->sc_regt, &sc->sc_regh, NULL, &psc->sc_regmap_size) == 0) { #ifdef NJSC32_DEBUG printf("%s: io space mapped\n", device_xname(self)); #endif sc->sc_flags = NJSC32_IO_MAPPED; } else { aprint_error_dev(self, "unable to map device registers\n"); return; } } sc->sc_dmat = pa->pa_dmat; /* map interrupt */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } str_intr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); str_at = " at "; if (str_intr == NULL) str_at = str_intr = ""; /* setup interrupt handler */ if ((sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, njsc32_intr, sc)) == NULL) { aprint_error_dev(self, "unable to establish interrupt%s%s\n", str_at, str_intr); return; } printf("%s: interrupting%s%s\n", device_xname(self), str_at, str_intr); /* attach */ njsc32_attach(sc); }
static void njs_cardbus_attach(struct device *parent, struct device *self, void *aux) { struct cardbus_attach_args *ca = aux; struct njsc32_cardbus_softc *csc = (void *) self; struct njsc32_softc *sc = &csc->sc_njsc32; const struct njsc32_cardbus_product *prod; cardbus_devfunc_t ct = ca->ca_ct; cardbus_chipset_tag_t cc = ct->ct_cc; cardbus_function_tag_t cf = ct->ct_cf; pcireg_t reg; int csr; u_int8_t latency = 0x20; if ((prod = njs_cardbus_lookup(ca)) == NULL) panic("njs_cardbus_attach"); printf(": Workbit NinjaSCSI-32 SCSI adapter\n"); sc->sc_model = prod->p_model; sc->sc_clk = prod->p_clk; csc->sc_ct = ct; csc->sc_tag = ca->ca_tag; csc->sc_intrline = ca->ca_intrline; /* * Map the device. */ csr = PCI_COMMAND_MASTER_ENABLE; /* * Map registers. * Try memory map first, and then try I/O. */ if (Cardbus_mapreg_map(csc->sc_ct, NJSC32_CARDBUS_BASEADDR_MEM, PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_regt, &csc->sc_regmaph, NULL, &csc->sc_regmap_size) == 0) { if (bus_space_subregion(sc->sc_regt, csc->sc_regmaph, NJSC32_MEMOFFSET_REG, NJSC32_REGSIZE, &sc->sc_regh) != 0) { /* failed -- undo map and try I/O */ Cardbus_mapreg_unmap(csc->sc_ct, NJSC32_CARDBUS_BASEADDR_MEM, sc->sc_regt, csc->sc_regmaph, csc->sc_regmap_size); goto try_io; } #ifdef NJSC32_DEBUG printf("%s: memory space mapped\n", sc->sc_dev.dv_xname); #endif csr |= PCI_COMMAND_MEM_ENABLE; sc->sc_flags = NJSC32_MEM_MAPPED; (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE); } else { try_io: if (Cardbus_mapreg_map(csc->sc_ct, NJSC32_CARDBUS_BASEADDR_IO, PCI_MAPREG_TYPE_IO, 0, &sc->sc_regt, &sc->sc_regh, NULL, &csc->sc_regmap_size) == 0) { #ifdef NJSC32_DEBUG printf("%s: io space mapped\n", sc->sc_dev.dv_xname); #endif csr |= PCI_COMMAND_IO_ENABLE; sc->sc_flags = NJSC32_IO_MAPPED; (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_IO_ENABLE); } else { printf("%s: unable to map device registers\n", sc->sc_dev.dv_xname); return; } } /* Make sure the right access type is on the CardBus bridge. */ (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE); /* Enable the appropriate bits in the PCI CSR. */ reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_COMMAND_STATUS_REG); reg &= ~(PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE); reg |= csr; cardbus_conf_write(cc, cf, ca->ca_tag, PCI_COMMAND_STATUS_REG, reg); /* * Make sure the latency timer is set to some reasonable * value. */ reg = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG); if (CARDBUS_LATTIMER(reg) < latency) { reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT); reg |= (latency << CARDBUS_LATTIMER_SHIFT); cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_BHLC_REG, reg); } sc->sc_dmat = ca->ca_dmat; /* * Establish the interrupt. */ sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline, IPL_BIO, njsc32_intr, sc); if (sc->sc_ih == NULL) { printf("%s: unable to establish interrupt at %d\n", sc->sc_dev.dv_xname, ca->ca_intrline); return; } printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname, ca->ca_intrline); /* CardBus device cannot supply termination power. */ sc->sc_flags |= NJSC32_CANNOT_SUPPLY_TERMPWR; /* attach */ njsc32_attach(sc); }