void sf_pci_attach(struct device *parent, struct device *self, void *aux) { struct sf_pci_softc *psc = (void *) self; struct sf_softc *sc = &psc->sc_starfire; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; const char *intrstr = NULL; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; pcireg_t reg; int pmreg, ioh_valid, memh_valid; if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) { reg = pci_conf_read(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR); switch (reg & PCI_PMCSR_STATE_MASK) { case PCI_PMCSR_STATE_D1: case PCI_PMCSR_STATE_D2: printf(": waking up from power state D%d\n%s", reg & PCI_PMCSR_STATE_MASK, sc->sc_dev.dv_xname); pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR, (reg & ~PCI_PMCSR_STATE_MASK) | PCI_PMCSR_STATE_D0); break; case PCI_PMCSR_STATE_D3: printf("%s: unable to wake up from power state D3\n", sc->sc_dev.dv_xname); pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR, (reg & ~PCI_PMCSR_STATE_MASK) | PCI_PMCSR_STATE_D0); return; } } /* * Map the device. */ reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SF_PCI_MEMBA); switch (reg) { 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, SF_PCI_MEMBA, reg, 0, &memt, &memh, NULL, NULL, 0) == 0); break; default: memh_valid = 0; } ioh_valid = (pci_mapreg_map(pa, (reg == (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) ? SF_PCI_IOBA : SF_PCI_IOBA - 0x04, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL, 0) == 0); if (memh_valid) { sc->sc_st = memt; sc->sc_sh = memh; sc->sc_iomapped = 0; } else if (ioh_valid) { sc->sc_st = iot; sc->sc_sh = ioh; sc->sc_iomapped = 1; } else { printf("%s: unable to map device registers\n", sc->sc_dev.dv_xname); return; } sc->sc_dmat = pa->pa_dmat; /* Make sure bus mastering is enabled. */ 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); /* * Map and establish our interrupt. */ if (pci_intr_map(pa, &ih)) { printf("%s: unable to map interrupt\n", sc->sc_dev.dv_xname); return; } intrstr = pci_intr_string(pa->pa_pc, ih); psc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, sf_intr, sc, self->dv_xname); if (psc->sc_ih == NULL) { printf("%s: unable to establish interrupt", sc->sc_dev.dv_xname); if (intrstr != NULL) printf(" at %s", intrstr); return; } printf(": %s", intrstr); /* * Finish off the attach. */ sf_attach(sc); }
static void sf_pci_attach(device_t parent, device_t self, void *aux) { struct sf_pci_softc *psc = device_private(self); struct sf_softc *sc = &psc->sc_starfire; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; const char *intrstr = NULL; const struct sf_pci_product *spp; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; pcireg_t reg; int error, ioh_valid, memh_valid; char intrbuf[PCI_INTRSTR_LEN]; sc->sc_dev = self; spp = sf_pci_lookup(pa); if (spp == NULL) { printf("\n"); panic("sf_pci_attach: impossible"); } printf(": %s, rev. %d\n", spp->spp_name, PCI_REVISION(pa->pa_class)); /* power up chip */ if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self, NULL)) && error != EOPNOTSUPP) { aprint_error_dev(self, "cannot activate %d\n", error); return; } /* * Map the device. */ reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SF_PCI_MEMBA); switch (reg) { 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, SF_PCI_MEMBA, reg, 0, &memt, &memh, NULL, NULL) == 0); break; default: memh_valid = 0; } ioh_valid = (pci_mapreg_map(pa, (reg == (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) ? SF_PCI_IOBA : SF_PCI_IOBA - 0x04, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) == 0); if (memh_valid) { sc->sc_st = memt; sc->sc_sh = memh; sc->sc_iomapped = 0; } else if (ioh_valid) { sc->sc_st = iot; sc->sc_sh = ioh; sc->sc_iomapped = 1; } else { aprint_error_dev(self, "unable to map device registers\n"); return; } sc->sc_dmat = pa->pa_dmat; /* Make sure bus mastering is enabled. */ 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); /* * Map and establish our interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "unable to map interrupt\n"); return; } intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); psc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, sf_intr, sc); if (psc->sc_ih == NULL) { aprint_error_dev(self, "unable to establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* * Finish off the attach. */ sf_attach(sc); }
void sf_pci_attach(struct device *parent, struct device *self, void *aux) { struct sf_pci_softc *psc = (void *) self; struct sf_softc *sc = &psc->sc_starfire; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; const char *intrstr = NULL; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; int state, ioh_valid, memh_valid; bus_size_t iosize, memsize; pcireg_t reg; state = pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); if (state == PCI_PMCSR_STATE_D3) { printf(": unable to wake up from power state D3, " "reboot required.\n"); return; } /* * Map the device. */ reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SF_PCI_MEMBA); switch (reg) { 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, SF_PCI_MEMBA, reg, 0, &memt, &memh, &memsize, NULL, 0) == 0); break; default: memh_valid = 0; } ioh_valid = (pci_mapreg_map(pa, (reg == (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) ? SF_PCI_IOBA : SF_PCI_IOBA - 0x04, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, &iosize, NULL, 0) == 0); if (memh_valid) { sc->sc_st = memt; sc->sc_sh = memh; sc->sc_iomapped = 0; } else if (ioh_valid) { sc->sc_st = iot; sc->sc_sh = ioh; sc->sc_iomapped = 1; } else { printf(": unable to map device registers\n"); return; } sc->sc_dmat = pa->pa_dmat; /* * Map and establish our interrupt. */ if (pci_intr_map(pa, &ih)) { printf(": unable to map interrupt\n"); goto out; } intrstr = pci_intr_string(pa->pa_pc, ih); psc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, sf_intr, sc, self->dv_xname); if (psc->sc_ih == NULL) { printf(": unable to establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto out; } printf(": %s", intrstr); /* * Finish off the attach. */ sf_attach(sc); return; out: if (ioh_valid) bus_space_unmap(iot, ioh, iosize); if (memh_valid) bus_space_unmap(memt, memh, memsize); }