void rl_pci_attach(struct device *parent, struct device *self, void *aux) { struct rl_pci_softc *psc = (void *)self; struct rl_softc *sc = &psc->psc_softc; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; /* * Map control/status registers. */ #ifdef RL_USEIOSPACE if (pci_mapreg_map(pa, RL_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, &sc->rl_btag, &sc->rl_bhandle, NULL, &psc->psc_mapsize, 0)) { printf(": can't map i/o space\n"); return; } #else if (pci_mapreg_map(pa, RL_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->rl_btag, &sc->rl_bhandle, NULL, &psc->psc_mapsize, 0)){ printf(": can't map mem space\n"); return; } #endif /* * Allocate our interrupt. */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); bus_space_unmap(sc->rl_btag, sc->rl_bhandle, psc->psc_mapsize); return; } psc->psc_pc = pa->pa_pc; intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, rl_intr, sc, self->dv_xname); if (sc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->rl_btag, sc->rl_bhandle, psc->psc_mapsize); return; } printf(": %s", intrstr); sc->sc_dmat = pa->pa_dmat; if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RT8129) sc->rl_type = RL_8129; else sc->rl_type = RL_8139; rl_attach(sc); }
void ral_pci_attach(struct device *parent, struct device *self, void *aux) { struct ral_pci_softc *psc = (struct ral_pci_softc *)self; struct rt2560_softc *sc = &psc->sc_sc; struct pci_attach_args *pa = aux; const char *intrstr; pci_intr_handle_t ih; pcireg_t memtype; int error; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RALINK) { switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_RALINK_RT2560: psc->sc_opns = &ral_rt2560_opns; break; case PCI_PRODUCT_RALINK_RT2561: case PCI_PRODUCT_RALINK_RT2561S: case PCI_PRODUCT_RALINK_RT2661: psc->sc_opns = &ral_rt2661_opns; break; default: psc->sc_opns = &ral_rt2860_opns; break; } } else { /* all other vendors are RT2860 only */ psc->sc_opns = &ral_rt2860_opns; } sc->sc_dmat = pa->pa_dmat; psc->sc_pc = pa->pa_pc; /* map control/status registers */ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RAL_PCI_BAR0); error = pci_mapreg_map(pa, RAL_PCI_BAR0, memtype, 0, &sc->sc_st, &sc->sc_sh, NULL, &psc->sc_mapsize, 0); if (error != 0) { printf(": can't map mem space\n"); return; } if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); return; } intrstr = pci_intr_string(psc->sc_pc, ih); psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET, psc->sc_opns->intr, sc, sc->sc_dev.dv_xname); if (psc->sc_ih == NULL) { printf(": can't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s", intrstr); (*psc->sc_opns->attach)(sc, PCI_PRODUCT(pa->pa_id)); }
void amdiic_attach(struct device *parent, struct device *self, void *aux) { struct amdiic_softc *sc = (struct amdiic_softc *)self; struct pci_attach_args *pa = aux; struct i2cbus_attach_args iba; pcireg_t conf; bus_size_t iosize; pci_intr_handle_t ih; const char *intrstr = NULL; /* Map I/O space */ if (pci_mapreg_map(pa, AMD8111_SMB_BASE, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &iosize, 0)) { printf(": can't map i/o space\n"); return; } /* Read configuration */ conf = pci_conf_read(pa->pa_pc, pa->pa_tag, AMD8111_SMB_MISC); DPRINTF((": conf 0x%08x", conf)); sc->sc_poll = 1; if (conf & AMD8111_SMB_MISC_SCIEN) { /* No PCI IRQ */ printf(": SCI"); } else if (conf & AMD8111_SMB_MISC_INTEN) { /* Install interrupt handler */ if (pci_intr_map(pa, &ih) == 0) { intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, amdiic_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih != NULL) { printf(": %s", intrstr); sc->sc_poll = 0; } } if (sc->sc_poll) printf(": polling"); } printf("\n"); /* Attach I2C bus */ rw_init(&sc->sc_i2c_lock, "iiclk"); sc->sc_i2c_tag.ic_cookie = sc; sc->sc_i2c_tag.ic_acquire_bus = amdiic_i2c_acquire_bus; sc->sc_i2c_tag.ic_release_bus = amdiic_i2c_release_bus; sc->sc_i2c_tag.ic_exec = amdiic_i2c_exec; bzero(&iba, sizeof(iba)); iba.iba_name = "iic"; iba.iba_tag = &sc->sc_i2c_tag; config_found(self, &iba, iicbus_print); return; }
void ral_pci_attach(device_t parent, device_t self, void *aux) { struct ral_pci_softc *psc = device_private(self); struct rt2560_softc *sc = &psc->sc_sc; const struct pci_attach_args *pa = aux; const char *intrstr; bus_addr_t base; pci_intr_handle_t ih; pcireg_t reg; int error; pci_aprint_devinfo(pa, NULL); psc->sc_opns = (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RALINK_RT2560) ? &ral_rt2560_opns : &ral_rt2661_opns; sc->sc_dev = self; sc->sc_dmat = pa->pa_dmat; psc->sc_pc = pa->pa_pc; /* enable the appropriate bits in the PCI CSR */ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg); /* map control/status registers */ error = pci_mapreg_map(pa, RAL_PCI_BAR0, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_st, &sc->sc_sh, &base, &psc->sc_mapsize); if (error != 0) { aprint_error(": could not map memory space\n"); return; } if (pci_intr_map(pa, &ih) != 0) { aprint_error(": could not map interrupt\n"); return; } intrstr = pci_intr_string(psc->sc_pc, ih); psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET, psc->sc_opns->intr, sc); if (psc->sc_ih == NULL) { aprint_error(": could not establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); (*psc->sc_opns->attach)(sc, PCI_PRODUCT(pa->pa_id)); }
void mfi_pci_attach(struct device *parent, struct device *self, void *aux) { struct mfi_softc *sc = (struct mfi_softc *)self; struct pci_attach_args *pa = aux; const struct mfi_pci_device *mpd; pci_intr_handle_t ih; bus_size_t size; pcireg_t reg; int regbar; mpd = mfi_pci_find_device(pa); if (mpd == NULL) { printf(": can't find matching pci device\n"); return; } if (mpd->mpd_iop == MFI_IOP_GEN2 || mpd->mpd_iop == MFI_IOP_SKINNY) regbar = MFI_BAR_GEN2; else regbar = MFI_BAR; reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, regbar); if (pci_mapreg_map(pa, regbar, reg, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) { printf(": can't map controller pci space\n"); return; } sc->sc_dmat = pa->pa_dmat; if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); goto unmap; } printf(": %s\n", pci_intr_string(pa->pa_pc, ih)); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc, sc->sc_dev.dv_xname); if (!sc->sc_ih) { printf("%s: can't establish interrupt\n", DEVNAME(sc)); goto unmap; } if (mfi_attach(sc, mpd->mpd_iop)) { printf("%s: can't attach\n", DEVNAME(sc)); goto unintr; } return; unintr: pci_intr_disestablish(pa->pa_pc, sc->sc_ih); sc->sc_ih = NULL; unmap: bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); }
void pgt_pci_attach(struct device *parent, struct device *self, void *aux) { struct pgt_pci_softc *psc = (struct pgt_pci_softc *)self; struct pgt_softc *sc = &psc->sc_pgt; struct pci_attach_args *pa = aux; const char *intrstr = NULL; pci_intr_handle_t ih; int error; sc->sc_dmat = pa->pa_dmat; psc->sc_pc = pa->pa_pc; /* remember chipset */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTERSIL_ISL3877) sc->sc_flags |= SC_ISL3877; /* map control / status registers */ error = pci_mapreg_map(pa, PGT_PCI_BAR0, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_iotag, &sc->sc_iohandle, NULL, &psc->sc_mapsize, 0); if (error != 0) { printf(": can't map mem space\n"); return; } /* map interrupt */ if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); return; } /* disable all interrupts */ bus_space_write_4(sc->sc_iotag, sc->sc_iohandle, PGT_REG_INT_EN, 0); (void)bus_space_read_4(sc->sc_iotag, sc->sc_iohandle, PGT_REG_INT_EN); DELAY(PGT_WRITEIO_DELAY); /* establish interrupt */ intrstr = pci_intr_string(psc->sc_pc, ih); psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET, pgt_intr, sc, sc->sc_dev.dv_xname); if (psc->sc_ih == NULL) { printf(": can't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s\n", intrstr); if (rootvp == NULL) mountroothook_establish(pgt_attach, sc); else pgt_attach(sc); }
void mfi_pci_attach(struct device *parent, struct device *self, void *aux) { struct mfi_softc *sc = (struct mfi_softc *)self; struct pci_attach_args *pa = aux; const char *intrstr; pci_intr_handle_t ih; bus_size_t size; pcireg_t csr; uint32_t subsysid, i; subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); for (i = 0; mfi_pci_devices[i].mpd_vendor; i++) if (mfi_pci_devices[i].mpd_subvendor == PCI_VENDOR(subsysid) && mfi_pci_devices[i].mpd_subproduct == PCI_PRODUCT(subsysid)){ printf(", %s", mfi_pci_devices[i].mpd_model); break; } csr = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MFI_BAR); csr |= PCI_MAPREG_MEM_TYPE_32BIT; if (pci_mapreg_map(pa, MFI_BAR, csr, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) { printf(": can't map controller pci space\n"); return; } sc->sc_dmat = pa->pa_dmat; if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc, sc->sc_dev.dv_xname); if (!sc->sc_ih) { printf(": can't establish interrupt"); if (intrstr) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); return; } printf(": %s\n", intrstr); if (mfi_attach(sc)) { printf("%s: can't attach", DEVNAME(sc)); pci_intr_disestablish(pa->pa_pc, sc->sc_ih); sc->sc_ih = NULL; bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); } }
void bwi_pci_attach(struct device *parent, struct device *self, void *aux) { struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self; struct pci_attach_args *pa = aux; struct bwi_softc *sc = &psc->psc_bwi; const char *intrstr = NULL; pci_intr_handle_t ih; pcireg_t memtype, reg; sc->sc_dmat = pa->pa_dmat; psc->psc_pc = pa->pa_pc; psc->psc_pcitag = pa->pa_tag; /* map control / status registers */ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BWI_PCI_BAR0); if (pci_mapreg_map(pa, BWI_PCI_BAR0, memtype, 0, &sc->sc_mem_bt, &sc->sc_mem_bh, NULL, &psc->psc_mapsize, 0)) { printf(": can't map mem space\n"); return; } /* map interrupt */ if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); return; } /* establish interrupt */ intrstr = pci_intr_string(psc->psc_pc, ih); psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc, sc->sc_dev.dv_xname); if (psc->psc_ih == NULL) { printf(": can't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s", intrstr); /* we need to access PCI config space from the driver */ sc->sc_conf_write = bwi_pci_conf_write; sc->sc_conf_read = bwi_pci_conf_read; reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); sc->sc_pci_revid = PCI_REVISION(pa->pa_class); sc->sc_pci_did = PCI_PRODUCT(pa->pa_id); sc->sc_pci_subvid = PCI_VENDOR(reg); sc->sc_pci_subdid = PCI_PRODUCT(reg); bwi_attach(sc); }
void rtsx_pci_attach(struct device *parent, struct device *self, void *aux) { struct rtsx_pci_softc *sc = (struct rtsx_pci_softc *)self; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; char const *intrstr; bus_space_tag_t iot; bus_space_handle_t ioh; bus_size_t size; int flags; if ((pci_conf_read(pa->pa_pc, pa->pa_tag, RTSX_CFG_PCI) & RTSX_CFG_ASIC) != 0) { printf("%s: no asic\n", sc->sc.sc_dev.dv_xname); return; } if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_SDMMC, rtsx_intr, sc, sc->sc.sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": can't establish interrupt\n"); return; } printf(": %s\n", intrstr); if (pci_mem_find(pa->pa_pc, pa->pa_tag, RTSX_PCI_BAR, NULL, NULL, NULL) != 0) { printf("%s: can't find registers\n", sc->sc.sc_dev.dv_xname); return; } if (pci_mapreg_map(pa, RTSX_PCI_BAR, PCI_MAPREG_TYPE_MEM, 0, &iot, &ioh, NULL, &size, 0)) { printf("%s: can't map registers\n", sc->sc.sc_dev.dv_xname); return; } pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RTS5209) flags = RTSX_F_5209; else flags = RTSX_F_5229; if (rtsx_attach(&sc->sc, iot, ioh, size, pa->pa_dmat, flags) != 0) printf("%s: can't initialize chip\n", sc->sc.sc_dev.dv_xname); }
static void ahci_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct ahci_pci_softc *psc = device_private(self); struct ahci_softc *sc = &psc->ah_sc; bus_size_t size; char devinfo[256]; const char *intrstr; pci_intr_handle_t intrhandle; void *ih; sc->sc_atac.atac_dev = self; if (pci_mapreg_map(pa, AHCI_PCI_ABAR, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_ahcit, &sc->sc_ahcih, NULL, &size) != 0) { aprint_error_dev(self, "can't map ahci registers\n"); return; } psc->sc_pc = pa->pa_pc; psc->sc_pcitag = pa->pa_tag; pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_naive(": AHCI disk controller\n"); aprint_normal(": %s\n", devinfo); if (pci_intr_map(pa, &intrhandle) != 0) { aprint_error("%s: couldn't map interrupt\n", AHCINAME(sc)); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc); if (ih == NULL) { aprint_error("%s: couldn't establish interrupt", AHCINAME(sc)); return; } aprint_normal("%s: interrupting at %s\n", AHCINAME(sc), intrstr ? intrstr : "unknown interrupt"); sc->sc_dmat = pa->pa_dmat; if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) { AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE); sc->sc_atac_capflags = ATAC_CAP_RAID; } else { AHCIDEBUG_PRINT(("%s: SATA mode\n", AHCINAME(sc)), DEBUG_PROBE); } ahci_attach(sc); if (!pmf_device_register(self, NULL, ahci_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
void ahci_pci_attach(struct device *parent, struct device *self, void *aux) { struct ahci_pci_softc *psc = (struct ahci_pci_softc *)self; struct ahci_softc *sc = &psc->psc_ahci; struct pci_attach_args *pa = aux; const struct ahci_device *ad; pci_intr_handle_t ih; int mapped = 0; psc->psc_pc = pa->pa_pc; psc->psc_tag = pa->pa_tag; sc->sc_dmat = pa->pa_dmat; ad = ahci_lookup_device(pa); if (ad != NULL && ad->ad_attach != NULL) { if (ad->ad_attach(sc, pa) != 0) { /* error should be printed by ad_attach */ return; } } if (!(sc->sc_flags & AHCI_F_NO_MSI)) mapped = pci_intr_map_msi(pa, &ih) != 0 ? 0 : 1; if (!mapped && pci_intr_map(pa, &ih) != 0) { printf(": unable to map interrupt\n"); return; } printf(": %s,", pci_intr_string(pa->pa_pc, ih)); if (ahci_map_regs(psc, pa) != 0) { /* error already printed by ahci_map_regs */ return; } if (ahci_map_intr(psc, pa, ih) != 0) { /* error already printed by ahci_map_intr */ goto unmap; } if (ahci_attach(sc) != 0) { /* error printed by ahci_attach */ goto unmap; } return; unmap: ahci_unmap_regs(psc); return; }
static void mtd_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args * const pa = aux; struct mtd_softc * const sc = device_private(self); pci_intr_handle_t ih; const char *intrstring = NULL; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; int io_valid, mem_valid; sc->dev = self; pci_aprint_devinfo(pa, NULL); io_valid = (pci_mapreg_map(pa, PCI_IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) == 0); mem_valid = (pci_mapreg_map(pa, PCI_MEM_MAP_REG, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, NULL, NULL) == 0); if (mem_valid) { sc->bus_tag = memt; sc->bus_handle = memh; } else if (io_valid) { sc->bus_tag = iot; sc->bus_handle = ioh; } else { aprint_error_dev(sc->dev, "could not map memory or i/o space\n"); return; } sc->dma_tag = pa->pa_dmat; /* Do generic attach. Seems this must be done before setting IRQ */ mtd_config(sc); if (pci_intr_map(pa, &ih)) { aprint_error_dev(sc->dev, "could not map interrupt\n"); return; } intrstring = pci_intr_string(pa->pa_pc, ih); if (pci_intr_establish(pa->pa_pc, ih, IPL_NET, mtd_irq_h, sc) == NULL) { aprint_error_dev(sc->dev, "could not establish interrupt"); if (intrstring != NULL) aprint_error(" at %s", intrstring); aprint_error("\n"); return; } else { aprint_normal_dev(sc->dev, "using %s for interrupt\n", intrstring ? intrstring : "unknown interrupt"); } }
static void mtd_pci_attach(struct device *parent, struct device *self, void *aux) { struct mtd_softc *sc = (void *)self; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; const char *intrstr = NULL; bus_size_t iosize; #ifndef MTD_USE_IO if (pci_mapreg_map(pa, MTD_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->bus_tag, &sc->bus_handle, NULL, &iosize, 0)) { printf(": can't map mem space\n"); return; } #else /* MTD_USE_IO */ if (pci_mapreg_map(pa, MTD_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, &sc->bus_tag, &sc->bus_handle, NULL, &iosize, 0)) { printf(": can't map io space\n"); return; } #endif /* MTD_USE_IO */ /* * Allocate our interrupt. */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); bus_space_unmap(sc->bus_tag, sc->bus_handle, iosize); return; } intrstr = pci_intr_string(pa->pa_pc, ih); if (pci_intr_establish(pa->pa_pc, ih, IPL_NET, mtd_irq_h, sc, self->dv_xname) == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->bus_tag, sc->bus_handle, iosize); return; } printf(": %s", intrstr); sc->dma_tag = pa->pa_dmat; mtd_config(sc); }
int pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihpp) { pci_intr_handle_t *ihp; ihp = kmem_alloc(sizeof(*ihp), KM_SLEEP); if (ihp == NULL) return ENOMEM; if (pci_intr_map(pa, ihp)) { kmem_free(ihp, sizeof(*ihp)); return EINVAL; } *ihpp = ihp; return 0; }
void an_pci_attach(struct device *parent, struct device *self, void *aux) { struct an_softc *sc = (struct an_softc *)self; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; bus_space_handle_t ioh; bus_space_tag_t iot = pa->pa_iot; pci_chipset_tag_t pc = pa->pa_pc; const char *intrstr; /* Map the I/O ports. */ if (pci_mapreg_map(pa, AN_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL, 0) != 0) { printf(": can't map i/o space\n"); return; } sc->sc_iot = iot; sc->sc_ioh = ioh; /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { printf("\n%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, an_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf("\n%s: couldn't establish interrupt", sc->sc_dev.dv_xname); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s", intrstr); sc->sc_enabled = 1; an_attach(sc); }
int genppc_pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps) { pci_intr_handle_t *handle; int error; handle = kmem_zalloc(sizeof(*handle), KM_SLEEP); if (handle == NULL) return ENOMEM; error = pci_intr_map(pa, handle); if (error != 0) { kmem_free(handle, sizeof(*handle)); return error; } *ihps = handle; return 0; }
int pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihp) { pci_intr_handle_t *pih; if (ihp == NULL) return EINVAL; pih = kmem_alloc(sizeof(*pih), KM_SLEEP); if (pih == NULL) return ENOMEM; if (pci_intr_map(pa, pih)) { kmem_free(pih, sizeof(*pih)); return EINVAL; } *ihp = pih; return 0; }
int genppc_pci_intr_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, int *counts, pci_intr_type_t max_type) { pci_intr_handle_t *ihp; if (counts != NULL && counts[PCI_INTR_TYPE_INTX] == 0) return EINVAL; ihp = kmem_alloc(sizeof(*ihp), KM_SLEEP); if (ihp == NULL) return ENOMEM; if (pci_intr_map(pa, ihp)) { kmem_free(ihp, sizeof(*ihp)); return EINVAL; } *ihps = ihp; return 0; }
int pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **pih) { struct intrsource *isp; pci_intr_handle_t *handle; int error; char intrstr_buf[INTRIDBUF]; const char *intrstr; handle = kmem_zalloc(sizeof(*handle), KM_SLEEP); if (handle == NULL) { aprint_normal("cannot allocate pci_intr_handle_t\n"); return ENOMEM; } if (pci_intr_map(pa, handle) != 0) { aprint_normal("cannot set up pci_intr_handle_t\n"); error = EINVAL; goto error; } intrstr = pci_intr_string(pa->pa_pc, *handle, intrstr_buf, sizeof(intrstr_buf)); mutex_enter(&cpu_lock); isp = intr_allocate_io_intrsource(intrstr); mutex_exit(&cpu_lock); if (isp == NULL) { aprint_normal("can't allocate io_intersource\n"); error = ENOMEM; goto error; } *pih = handle; return 0; error: kmem_free(handle, sizeof(*handle)); return error; }
/* * Attach a supported board. * * XXX This doesn't fail gracefully. */ static void twe_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa; struct twe_softc *sc; pci_chipset_tag_t pc; pci_intr_handle_t ih; pcireg_t csr; const char *intrstr; int s, size, i, rv, rseg; size_t max_segs, max_xfer; bus_dma_segment_t seg; const struct sysctlnode *node; struct twe_cmd *tc; struct twe_ccb *ccb; sc = device_private(self); sc->sc_dev = self; pa = aux; pc = pa->pa_pc; sc->sc_dmat = pa->pa_dmat; SIMPLEQ_INIT(&sc->sc_ccb_queue); SLIST_INIT(&sc->sc_ccb_freelist); aprint_naive(": RAID controller\n"); aprint_normal(": 3ware Escalade\n"); if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot, &sc->sc_ioh, NULL, NULL)) { aprint_error_dev(self, "can't map i/o space\n"); return; } /* Enable the device. */ csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE); /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "can't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, twe_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "can't establish interrupt%s%s\n", (intrstr) ? " at " : "", (intrstr) ? intrstr : ""); return; } if (intrstr != NULL) aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* * Allocate and initialise the command blocks and CCBs. */ size = sizeof(struct twe_cmd) * TWE_MAX_QUEUECNT; if ((rv = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(self, "unable to allocate commands, rv = %d\n", rv); return; } if ((rv = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size, (void **)&sc->sc_cmds, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { aprint_error_dev(self, "unable to map commands, rv = %d\n", rv); return; } if ((rv = bus_dmamap_create(sc->sc_dmat, size, size, 1, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { aprint_error_dev(self, "unable to create command DMA map, rv = %d\n", rv); return; } if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_cmds, size, NULL, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(self, "unable to load command DMA map, rv = %d\n", rv); return; } ccb = malloc(sizeof(*ccb) * TWE_MAX_QUEUECNT, M_DEVBUF, M_NOWAIT); if (ccb == NULL) { aprint_error_dev(self, "unable to allocate memory for ccbs\n"); return; } sc->sc_cmds_paddr = sc->sc_dmamap->dm_segs[0].ds_addr; memset(sc->sc_cmds, 0, size); sc->sc_ccbs = ccb; tc = (struct twe_cmd *)sc->sc_cmds; max_segs = twe_get_maxsegs(); max_xfer = twe_get_maxxfer(max_segs); for (i = 0; i < TWE_MAX_QUEUECNT; i++, tc++, ccb++) { ccb->ccb_cmd = tc; ccb->ccb_cmdid = i; ccb->ccb_flags = 0; rv = bus_dmamap_create(sc->sc_dmat, max_xfer, max_segs, PAGE_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap_xfer); if (rv != 0) { aprint_error_dev(self, "can't create dmamap, rv = %d\n", rv); return; } /* Save the first CCB for AEN retrieval. */ if (i != 0) SLIST_INSERT_HEAD(&sc->sc_ccb_freelist, ccb, ccb_chain.slist); } /* Wait for the controller to become ready. */ if (twe_status_wait(sc, TWE_STS_MICROCONTROLLER_READY, 6)) { aprint_error_dev(self, "microcontroller not ready\n"); return; } twe_outl(sc, TWE_REG_CTL, TWE_CTL_DISABLE_INTRS); /* Reset the controller. */ s = splbio(); rv = twe_reset(sc); splx(s); if (rv) { aprint_error_dev(self, "reset failed\n"); return; } /* Initialise connection with controller. */ twe_init_connection(sc); twe_describe_controller(sc); /* Find and attach RAID array units. */ sc->sc_nunits = 0; for (i = 0; i < TWE_MAX_UNITS; i++) (void) twe_add_unit(sc, i); /* ...and finally, enable interrupts. */ twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR | TWE_CTL_UNMASK_RESP_INTR | TWE_CTL_ENABLE_INTRS); /* sysctl set-up for 3ware cli */ if (sysctl_createv(NULL, 0, NULL, NULL, CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, NULL, 0, NULL, 0, CTL_HW, CTL_EOL) != 0) { aprint_error_dev(self, "could not create %s sysctl node\n", "hw"); return; } if (sysctl_createv(NULL, 0, NULL, &node, 0, CTLTYPE_NODE, device_xname(self), SYSCTL_DESCR("twe driver information"), NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL) != 0) { aprint_error_dev(self, "could not create %s.%s sysctl node\n", "hw", device_xname(self)); return; } if ((i = sysctl_createv(NULL, 0, NULL, NULL, 0, CTLTYPE_STRING, "driver_version", SYSCTL_DESCR("twe0 driver version"), NULL, 0, __UNCONST(&twever), 0, CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL)) != 0) { aprint_error_dev(self, "could not create %s.%s.driver_version sysctl\n", "hw", device_xname(self)); return; } }
void nfe_attach(struct device *parent, struct device *self, void *aux) { struct nfe_softc *sc = (struct nfe_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr; struct ifnet *ifp; bus_size_t memsize; pcireg_t memtype; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA); if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt, &sc->sc_memh, NULL, &memsize, 0)) { printf(": can't map mem space\n"); return; } if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": could not establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s", intrstr); sc->sc_dmat = pa->pa_dmat; sc->sc_flags = 0; switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5: sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP51_LAN1: case PCI_PRODUCT_NVIDIA_MCP51_LAN2: sc->sc_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP61_LAN1: case PCI_PRODUCT_NVIDIA_MCP61_LAN2: case PCI_PRODUCT_NVIDIA_MCP61_LAN3: case PCI_PRODUCT_NVIDIA_MCP61_LAN4: case PCI_PRODUCT_NVIDIA_MCP67_LAN1: case PCI_PRODUCT_NVIDIA_MCP67_LAN2: case PCI_PRODUCT_NVIDIA_MCP67_LAN3: case PCI_PRODUCT_NVIDIA_MCP67_LAN4: case PCI_PRODUCT_NVIDIA_MCP73_LAN1: case PCI_PRODUCT_NVIDIA_MCP73_LAN2: case PCI_PRODUCT_NVIDIA_MCP73_LAN3: case PCI_PRODUCT_NVIDIA_MCP73_LAN4: sc->sc_flags |= NFE_40BIT_ADDR | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP77_LAN1: case PCI_PRODUCT_NVIDIA_MCP77_LAN2: case PCI_PRODUCT_NVIDIA_MCP77_LAN3: case PCI_PRODUCT_NVIDIA_MCP77_LAN4: sc->sc_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP79_LAN1: case PCI_PRODUCT_NVIDIA_MCP79_LAN2: case PCI_PRODUCT_NVIDIA_MCP79_LAN3: case PCI_PRODUCT_NVIDIA_MCP79_LAN4: case PCI_PRODUCT_NVIDIA_MCP89_LAN: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_CK804_LAN1: case PCI_PRODUCT_NVIDIA_CK804_LAN2: case PCI_PRODUCT_NVIDIA_MCP04_LAN1: case PCI_PRODUCT_NVIDIA_MCP04_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP65_LAN1: case PCI_PRODUCT_NVIDIA_MCP65_LAN2: case PCI_PRODUCT_NVIDIA_MCP65_LAN3: case PCI_PRODUCT_NVIDIA_MCP65_LAN4: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP55_LAN1: case PCI_PRODUCT_NVIDIA_MCP55_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_HW_VLAN | NFE_PWR_MGMT; break; } if (sc->sc_flags & NFE_PWR_MGMT) { NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_RESET | NFE_RXTX_BIT2); NFE_WRITE(sc, NFE_MAC_RESET, NFE_MAC_RESET_MAGIC); DELAY(100); NFE_WRITE(sc, NFE_MAC_RESET, 0); DELAY(100); NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT2); NFE_WRITE(sc, NFE_PWR2_CTL, NFE_READ(sc, NFE_PWR2_CTL) & ~NFE_PWR2_WAKEUP_MASK); } nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr); printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); /* * Allocate Tx and Rx rings. */ if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) { printf("%s: could not allocate Tx ring\n", sc->sc_dev.dv_xname); return; } if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) { printf("%s: could not allocate Rx ring\n", sc->sc_dev.dv_xname); nfe_free_tx_ring(sc, &sc->txq); return; } ifp = &sc->sc_arpcom.ac_if; ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = nfe_ioctl; ifp->if_start = nfe_start; ifp->if_watchdog = nfe_watchdog; IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN); IFQ_SET_READY(&ifp->if_snd); strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); ifp->if_capabilities = IFCAP_VLAN_MTU; #ifndef SMALL_KERNEL ifp->if_capabilities |= IFCAP_WOL; ifp->if_wol = nfe_wol; nfe_wol(ifp, 0); #endif #if NVLAN > 0 if (sc->sc_flags & NFE_HW_VLAN) ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; #endif if (sc->sc_flags & NFE_HW_CSUM) { ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4; } sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = nfe_miibus_readreg; sc->sc_mii.mii_writereg = nfe_miibus_writereg; sc->sc_mii.mii_statchg = nfe_miibus_statchg; ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd, nfe_ifmedia_sts); mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 0, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); if_attach(ifp); ether_ifattach(ifp); timeout_set(&sc->sc_tick_ch, nfe_tick, sc); }
static void iavc_pci_attach(device_t parent, device_t self, void *aux) { struct iavc_pci_softc *psc = device_private(self); struct iavc_softc *sc = &psc->sc_iavc; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; const struct iavc_pci_product *pp; pci_intr_handle_t ih; const char *intrstr; int ret; char intrbuf[PCI_INTRSTR_LEN]; pp = find_cardname(pa); if (pp == NULL) return; sc->sc_dev = self; sc->sc_t1 = 0; sc->sc_dma = 0; sc->dmat = pa->pa_dmat; if (pci_mapreg_map(pa, IAVC_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0, &sc->sc_io_bt, &sc->sc_io_bh, &psc->io_base, &psc->io_size)) { aprint_error(": unable to map i/o registers\n"); return; } if (pci_mapreg_map(pa, IAVC_PCI_MMBA, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_mem_bt, &sc->sc_mem_bh, &psc->mem_base, &psc->mem_size)) { aprint_error(": unable to map mem registers\n"); return; } aprint_normal(": %s\n", pp->name); iavc_b1dma_reset(sc); if (pp->npp_product == PCI_PRODUCT_AVM_T1) { aprint_error_dev(sc->sc_dev, "sorry, PRI not yet supported\n"); return; #if 0 sc->sc_capi.card_type = CARD_TYPEC_AVM_T1_PCI; sc->sc_capi.sc_nbch = NBCH_PRI; ret = iavc_t1_detect(sc); if (ret) { if (ret < 6) { aprint_error_dev(sc->sc_dev, "no card detected?\n"); } else { aprint_error_dev(sc->sc_dev, "black box not on\n"); } return; } else { sc->sc_dma = 1; sc->sc_t1 = 1; } #endif } else if (pp->npp_product == PCI_PRODUCT_AVM_B1) { sc->sc_capi.card_type = CARD_TYPEC_AVM_B1_PCI; sc->sc_capi.sc_nbch = NBCH_BRI; ret = iavc_b1dma_detect(sc); if (ret) { ret = iavc_b1_detect(sc); if (ret) { aprint_error_dev(sc->sc_dev, "no card detected?\n"); return; } } else { sc->sc_dma = 1; } } if (sc->sc_dma) iavc_b1dma_reset(sc); #if 0 /* * XXX: should really be done this way, but this freezes the card */ if (sc->sc_t1) iavc_t1_reset(sc); else iavc_b1_reset(sc); #endif if (pci_intr_map(pa, &ih)) { aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, iavc_pci_intr, psc); if (psc->sc_ih == NULL) { aprint_error_dev(sc->sc_dev, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } psc->sc_pc = pc; aprint_normal("%s: interrupting at %s\n", device_xname(sc->sc_dev), intrstr); memset(&sc->sc_txq, 0, sizeof(struct ifqueue)); sc->sc_txq.ifq_maxlen = sc->sc_capi.sc_nbch * 4; sc->sc_intr = 0; sc->sc_state = IAVC_DOWN; sc->sc_blocked = 0; /* setup capi link */ sc->sc_capi.load = iavc_load; sc->sc_capi.reg_appl = iavc_register; sc->sc_capi.rel_appl = iavc_release; sc->sc_capi.send = iavc_send; sc->sc_capi.ctx = (void *) sc; /* lock & load DMA for TX */ if ((ret = bus_dmamem_alloc(sc->dmat, IAVC_DMA_SIZE, PAGE_SIZE, 0, &sc->txseg, 1, &sc->ntxsegs, BUS_DMA_ALLOCNOW)) != 0) { aprint_error_dev(sc->sc_dev, "can't allocate tx DMA memory, error = %d\n", ret); goto fail1; } if ((ret = bus_dmamem_map(sc->dmat, &sc->txseg, sc->ntxsegs, IAVC_DMA_SIZE, &sc->sc_sendbuf, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "can't map tx DMA memory, error = %d\n", ret); goto fail2; } if ((ret = bus_dmamap_create(sc->dmat, IAVC_DMA_SIZE, 1, IAVC_DMA_SIZE, 0, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, &sc->tx_map)) != 0) { aprint_error_dev(sc->sc_dev, "can't create tx DMA map, error = %d\n", ret); goto fail3; } if ((ret = bus_dmamap_load(sc->dmat, sc->tx_map, sc->sc_sendbuf, IAVC_DMA_SIZE, NULL, BUS_DMA_WRITE | BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "can't load tx DMA map, error = %d\n", ret); goto fail4; } /* do the same for RX */ if ((ret = bus_dmamem_alloc(sc->dmat, IAVC_DMA_SIZE, PAGE_SIZE, 0, &sc->rxseg, 1, &sc->nrxsegs, BUS_DMA_ALLOCNOW)) != 0) { aprint_error_dev(sc->sc_dev, "can't allocate rx DMA memory, error = %d\n", ret); goto fail5; } if ((ret = bus_dmamem_map(sc->dmat, &sc->rxseg, sc->nrxsegs, IAVC_DMA_SIZE, &sc->sc_recvbuf, BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "can't map rx DMA memory, error = %d\n", ret); goto fail6; } if ((ret = bus_dmamap_create(sc->dmat, IAVC_DMA_SIZE, 1, IAVC_DMA_SIZE, 0, BUS_DMA_ALLOCNOW | BUS_DMA_NOWAIT, &sc->rx_map)) != 0) { aprint_error_dev(sc->sc_dev, "can't create rx DMA map, error = %d\n", ret); goto fail7; } if ((ret = bus_dmamap_load(sc->dmat, sc->rx_map, sc->sc_recvbuf, IAVC_DMA_SIZE, NULL, BUS_DMA_READ | BUS_DMA_NOWAIT)) != 0) { aprint_error_dev(sc->sc_dev, "can't load rx DMA map, error = %d\n", ret); goto fail8; } if (capi_ll_attach(&sc->sc_capi, device_xname(sc->sc_dev), pp->name)) { aprint_error_dev(sc->sc_dev, "capi attach failed\n"); goto fail9; } return; /* release resources in case of failed attach */ fail9: bus_dmamap_unload(sc->dmat, sc->rx_map); fail8: bus_dmamap_destroy(sc->dmat, sc->rx_map); fail7: bus_dmamem_unmap(sc->dmat, sc->sc_recvbuf, IAVC_DMA_SIZE); fail6: bus_dmamem_free(sc->dmat, &sc->rxseg, sc->nrxsegs); fail5: bus_dmamap_unload(sc->dmat, sc->tx_map); fail4: bus_dmamap_destroy(sc->dmat, sc->tx_map); fail3: bus_dmamem_unmap(sc->dmat, sc->sc_sendbuf, IAVC_DMA_SIZE); fail2: bus_dmamem_free(sc->dmat, &sc->txseg, sc->ntxsegs); fail1: pci_intr_disestablish(psc->sc_pc, psc->sc_ih); return; }
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 univ_pci_attach(struct univ_pci_data *d, struct pci_attach_args *pa, const char *name, void (*inthdl)(void *, int, int), void *intcookie) { pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; u_int32_t reg; int i; d->pc = pc; strncpy(d->devname, name, sizeof(d->devname)); d->devname[sizeof(d->devname) - 1] = '\0'; if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &d->csrt, &d->csrh, NULL, NULL) && pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &d->csrt, &d->csrh, NULL, NULL) && pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &d->csrt, &d->csrh, NULL, NULL) && pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_IO, 0, &d->csrt, &d->csrh, NULL, NULL)) return (-1); /* name sure the chip is in a sane state */ write_csr_4(d, lint_en, 0); /* mask all PCI interrupts */ write_csr_4(d, vint_en, 0); /* mask all VME interrupts */ write_csr_4(d, dgcs, 0x40000000); /* stop DMA activity */ for (i = 0; i < 8; i++) { univ_pci_unmapvme(d, i); univ_pci_unmappci(d, i); } write_csr_4(d, slsi, 0); /* disable "special PCI slave image" */ /* enable DMA */ pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) | PCI_COMMAND_MASTER_ENABLE); reg = read_csr_4(d, misc_ctl); aprint_normal("%s: ", name); if (reg & 0x00020000) /* SYSCON */ aprint_normal("VME bus controller, "); reg = read_csr_4(d, mast_ctl); aprint_normal("requesting at VME bus level %d\n", (reg >> 22) & 3); /* Map and establish the PCI interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error("%s: couldn't map interrupt\n", name); return (-1); } intrstr = pci_intr_string(pc, ih); /* * Use a low interrupt level (the lowest?). * We will raise before calling a subdevice's handler. */ d->ih = pci_intr_establish(pc, ih, IPL_BIO, univ_pci_intr, d); if (d->ih == NULL) { aprint_error("%s: couldn't establish interrupt", name); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return (-1); } aprint_normal("%s: interrupting at %s\n", name, intrstr); /* handle all VME interrupts (XXX should be configurable) */ d->vmeinthandler = inthdl; d->vmeintcookie = intcookie; write_csr_4(d, lint_stat, 0x00ff37ff); /* ack all pending IRQs */ write_csr_4(d, lint_en, 0x000000fe); /* enable VME IRQ 1..7 */ return (0); }
/* * Attach this instance, and then all the sub-devices */ void pcscp_attach(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; struct pcscp_softc *esc = (void *)self; struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; bus_space_tag_t iot; bus_space_handle_t ioh; pci_intr_handle_t ih; const char *intrstr; bus_dma_segment_t seg; int error, rseg; if (pci_mapreg_map(pa, IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL, 0)) { printf("%s: unable to map registers\n", sc->sc_dev.dv_xname); return; } sc->sc_glue = &pcscp_glue; esc->sc_st = iot; esc->sc_sh = ioh; esc->sc_dmat = pa->pa_dmat; /* * XXX More of this should be in ncr53c9x_attach(), but * XXX should we really poke around the chip that much in * XXX the MI code? Think about this more... */ /* * Set up static configuration info. */ /* * XXX should read configuration from EEPROM? * * MI ncr53c9x driver does not support configuration * per each target device, though... */ sc->sc_id = 7; sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE; sc->sc_cfg3 = NCRAMDCFG3_IDM | NCRAMDCFG3_FCLK; sc->sc_cfg4 = NCRAMDCFG4_GE12NS | NCRAMDCFG4_RADE; sc->sc_rev = NCR_VARIANT_AM53C974; sc->sc_features = NCR_F_FASTSCSI; sc->sc_cfg3_fscsi = NCRAMDCFG3_FSCSI; sc->sc_freq = 40; /* MHz */ /* * XXX minsync and maxxfer _should_ be set up in MI code, * XXX but it appears to have some dependency on what sort * XXX of DMA we're hooked up to, etc. */ /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = 1000 / sc->sc_freq; /* Really no limit, but since we want to fit into the TCR... */ sc->sc_maxxfer = 16 * 1024 * 1024; /* * Create the DMA maps for the data transfers. */ #define MDL_SEG_SIZE 0x1000 /* 4kbyte per segment */ #define MDL_SEG_OFFSET 0x0FFF #define MDL_SIZE (MAXPHYS / MDL_SEG_SIZE + 1) /* no hardware limit? */ if (bus_dmamap_create(esc->sc_dmat, MAXPHYS, MDL_SIZE, MDL_SEG_SIZE, MDL_SEG_SIZE, BUS_DMA_NOWAIT, &esc->sc_xfermap)) { printf("%s: can't create dma maps\n", sc->sc_dev.dv_xname); return; } /* * Allocate and map memory for the MDL. */ if ((error = bus_dmamem_alloc(esc->sc_dmat, sizeof(u_int32_t) * MDL_SIZE, PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf("%s: unable to allocate memory for the MDL, " "error = %d\n", sc->sc_dev.dv_xname, error); goto fail_0; } if ((error = bus_dmamem_map(esc->sc_dmat, &seg, rseg, sizeof(u_int32_t) * MDL_SIZE , (caddr_t *)&esc->sc_mdladdr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { printf("%s: unable to map the MDL memory, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_1; } if ((error = bus_dmamap_create(esc->sc_dmat, sizeof(u_int32_t) * MDL_SIZE, 1, sizeof(u_int32_t) * MDL_SIZE, 0, BUS_DMA_NOWAIT, &esc->sc_mdldmap)) != 0) { printf("%s: unable to map_create for the MDL, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_2; } if ((error = bus_dmamap_load(esc->sc_dmat, esc->sc_mdldmap, esc->sc_mdladdr, sizeof(u_int32_t) * MDL_SIZE, NULL, BUS_DMA_NOWAIT)) != 0) { printf("%s: unable to load for the MDL, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_3; } /* map and establish interrupt */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); goto fail_4; } intrstr = pci_intr_string(pa->pa_pc, ih); esc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ncr53c9x_intr, esc, sc->sc_dev.dv_xname); if (esc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto fail_4; } if (intrstr != NULL) printf(": %s\n", intrstr); /* Do the common parts of attachment. */ printf("%s", sc->sc_dev.dv_xname); ncr53c9x_attach(sc, &pcscp_adapter); /* Turn on target selection using the `dma' method */ sc->sc_features |= NCR_F_DMASELECT; return; fail_4: bus_dmamap_unload(esc->sc_dmat, esc->sc_mdldmap); fail_3: bus_dmamap_destroy(esc->sc_dmat, esc->sc_mdldmap); fail_2: bus_dmamem_unmap(esc->sc_dmat, (caddr_t)esc->sc_mdldmap, sizeof(uint32_t) * MDL_SIZE); fail_1: bus_dmamem_free(esc->sc_dmat, &seg, rseg); fail_0: bus_dmamap_destroy(esc->sc_dmat, esc->sc_xfermap); }
void cas_attach(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; struct cas_softc *sc = (void *)self; pci_intr_handle_t ih; #ifdef __sparc64__ /* XXX the following declarations should be elsewhere */ extern void myetheraddr(u_char *); #endif const char *intrstr = NULL; bus_size_t size; int gotenaddr = 0; sc->sc_rev = PCI_REVISION(pa->pa_class); sc->sc_dmatag = pa->pa_dmat; #define PCI_CAS_BASEADDR 0x10 if (pci_mapreg_map(pa, PCI_CAS_BASEADDR, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_memt, &sc->sc_memh, NULL, &size, 0) != 0) { printf(": could not map registers\n"); return; } if (cas_pci_enaddr(sc, pa) == 0) gotenaddr = 1; #ifdef __sparc64__ if (!gotenaddr) { if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address", sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0) myetheraddr(sc->sc_arpcom.ac_enaddr); gotenaddr = 1; } #endif #ifdef __powerpc__ if (!gotenaddr) { pci_ether_hw_addr(pa->pa_pc, sc->sc_arpcom.ac_enaddr); gotenaddr = 1; } #endif sc->sc_burst = 16; /* XXX */ if (pci_intr_map(pa, &ih) != 0) { printf(": couldn't map interrupt\n"); bus_space_unmap(sc->sc_memt, sc->sc_memh, size); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, cas_intr, sc, self->dv_xname); if (sc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->sc_memt, sc->sc_memh, size); return; } printf(": %s", intrstr); /* * call the main configure */ cas_config(sc); }
static void ahci_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct ahci_pci_softc *psc = device_private(self); struct ahci_softc *sc = &psc->ah_sc; const char *intrstr; bool ahci_cap_64bit; bool ahci_bad_64bit; pci_intr_handle_t intrhandle; sc->sc_atac.atac_dev = self; if (pci_mapreg_map(pa, AHCI_PCI_ABAR, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_ahcit, &sc->sc_ahcih, NULL, &sc->sc_ahcis) != 0) { aprint_error_dev(self, "can't map ahci registers\n"); return; } psc->sc_pc = pa->pa_pc; psc->sc_pcitag = pa->pa_tag; pci_aprint_devinfo(pa, "AHCI disk controller"); if (pci_intr_map(pa, &intrhandle) != 0) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); psc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc); if (psc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr ? intrstr : "unknown interrupt"); sc->sc_dmat = pa->pa_dmat; sc->sc_ahci_quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); ahci_cap_64bit = (AHCI_READ(sc, AHCI_CAP) & AHCI_CAP_64BIT) != 0; ahci_bad_64bit = ((sc->sc_ahci_quirks & AHCI_PCI_QUIRK_BAD64) != 0); if (pci_dma64_available(pa) && ahci_cap_64bit) { if (!ahci_bad_64bit) sc->sc_dmat = pa->pa_dmat64; aprint_verbose_dev(self, "64-bit DMA%s\n", (sc->sc_dmat == pa->pa_dmat) ? " unavailable" : ""); } if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) { AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE); sc->sc_atac_capflags = ATAC_CAP_RAID; } else { AHCIDEBUG_PRINT(("%s: SATA mode\n", AHCINAME(sc)), DEBUG_PROBE); } ahci_attach(sc); if (!pmf_device_register(self, NULL, ahci_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
void ti_pci_attach(struct device *parent, struct device *self, void *aux) { struct ti_softc *sc = (struct ti_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; bus_size_t size; /* * Map control/status registers. */ if (pci_mapreg_map(pa, TI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) { printf(": can't map registers\n"); return; } sc->sc_dmatag = pa->pa_dmat; if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); goto unmap; } intrstr = pci_intr_string(pc, ih); sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc, self->dv_xname); if (sc->ti_intrhand == NULL) { printf(": can't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto unmap; } printf(": %s", intrstr); /* * We really need a better way to tell a 1000baseTX card * from a 1000baseSX one, since in theory there could be * OEMed 1000baseTX cards from lame vendors who aren't * clever enough to change the PCI ID. For the moment * though, the AceNIC is the only copper card available. */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT) sc->ti_copper = 1; /* Ok, it's not the only copper card available */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T) sc->ti_copper = 1; if (ti_attach(sc) == 0) return; pci_intr_disestablish(pc, sc->ti_intrhand); unmap: bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size); }
static void uhci_pci_attach(device_t parent, device_t self, void *aux) { struct uhci_pci_softc *sc = device_private(self); struct pci_attach_args *pa = (struct pci_attach_args *)aux; pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_tag; char const *intrstr; pci_intr_handle_t ih; pcireg_t csr; usbd_status r; int s; char intrbuf[PCI_INTRSTR_LEN]; sc->sc.sc_dev = self; sc->sc.sc_bus.hci_private = sc; pci_aprint_devinfo(pa, NULL); /* Map I/O registers */ if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) { aprint_error_dev(self, "can't map i/o space\n"); return; } /* * Disable interrupts, so we don't get any spurious ones. * Acknowledge all pending interrupts. */ bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0); bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_STS, bus_space_read_2(sc->sc.iot, sc->sc.ioh, UHCI_STS)); sc->sc_pc = pc; sc->sc_tag = tag; sc->sc.sc_bus.dmatag = pa->pa_dmat; /* Enable the device. */ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE); /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(self, "couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, uhci_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* * Set LEGSUP register to its default value. * This can re-enable or trigger interrupts, so protect against * them and explicitly disable and ACK them afterwards. */ s = splhardusb(); pci_conf_write(pc, tag, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN); bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_INTR, 0); bus_space_write_2(sc->sc.iot, sc->sc.ioh, UHCI_STS, bus_space_read_2(sc->sc.iot, sc->sc.ioh, UHCI_STS)); splx(s); switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: sc->sc.sc_bus.usbrev = USBREV_PRE_1_0; break; case PCI_USBREV_1_0: sc->sc.sc_bus.usbrev = USBREV_1_0; break; case PCI_USBREV_1_1: sc->sc.sc_bus.usbrev = USBREV_1_1; break; default: sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; break; } /* Figure out vendor for root hub descriptor. */ sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id); pci_findvendor(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), sc->sc.sc_id_vendor); r = uhci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { aprint_error_dev(self, "init failed, error=%d\n", r); return; } sc->sc_initialized = SC_INIT_UHCI; #if NEHCI > 0 usb_pci_add(&sc->sc_pci, pa, self); #endif if (!pmf_device_register(self, uhci_suspend, uhci_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); else sc->sc_initialized |= SC_INIT_PMF; /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); }
static void cy_pci_attach(device_t parent, device_t self, void *aux) { struct cy_pci_softc *psc = device_private(self); struct cy_softc *sc = &psc->sc_cy; struct pci_attach_args *pa = aux; pci_intr_handle_t ih; const struct cy_pci_product *cp; const char *intrstr; int plx_ver; char intrbuf[PCI_INTRSTR_LEN]; sc->sc_dev = self; aprint_naive(": Multi-port serial controller\n"); sc->sc_bustype = CY_BUSTYPE_PCI; cp = cy_pci_lookup(pa); if (cp == NULL) panic("cy_pci_attach: impossible"); aprint_normal(": Cyclades-Y multiport serial\n"); if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_IO, 0, &psc->sc_iot, &psc->sc_ioh, NULL, NULL) != 0) { aprint_error_dev(sc->sc_dev, "unable to map PLX registers\n"); return; } if (pci_mapreg_map(pa, 0x18, cp->cp_memtype, 0, &sc->sc_memt, &sc->sc_bsh, NULL, NULL) != 0) { aprint_error_dev(sc->sc_dev,"unable to map device registers\n"); return; } if (cy_find(sc) == 0) { aprint_error_dev(sc->sc_dev, "unable to find CD1400s\n"); return; } /* * XXX Like the Cyclades-Z, we should really check the EEPROM to * determine the "poll or interrupt" setting. For now, we always * map the interrupt and enable it in the PLX. */ /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih) != 0) { aprint_error_dev(sc->sc_dev, "unable to map interrupt\n"); return; } intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY, cy_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(sc->sc_dev, "unable to establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); cy_attach(sc); plx_ver = bus_space_read_1(sc->sc_memt, sc->sc_bsh, CY_PLX_VER) & 0x0f; /* Enable PCI card interrupts */ switch (plx_ver) { case CY_PLX_9050: bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA_9050, bus_space_read_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA_9050) | 0x40); break; case CY_PLX_9060: case CY_PLX_9080: default: bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA, bus_space_read_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA) | 0x900); } }