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; }
void ubsec_attach(struct device *parent, struct device *self, void *aux) { struct ubsec_softc *sc = (struct ubsec_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; pcireg_t memtype; const char *intrstr = NULL; struct ubsec_dma *dmap; bus_size_t iosize; u_int32_t i; int algs[CRYPTO_ALGORITHM_MAX + 1]; SIMPLEQ_INIT(&sc->sc_queue); SIMPLEQ_INIT(&sc->sc_qchip); SIMPLEQ_INIT(&sc->sc_queue2); SIMPLEQ_INIT(&sc->sc_qchip2); SIMPLEQ_INIT(&sc->sc_queue4); SIMPLEQ_INIT(&sc->sc_qchip4); sc->sc_statmask = BS_STAT_MCR1_DONE | BS_STAT_DMAERR; sc->sc_maxaggr = UBS_MIN_AGGR; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BLUESTEEL && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BLUESTEEL_5601) sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5802 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5805)) sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5820 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5822)) sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY; if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5821) || (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SCA1K || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_5821))) { sc->sc_statmask |= BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY; sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY; } if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5823 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5825)) sc->sc_flags |= UBS_FLAGS_KEY | UBS_FLAGS_RNG | UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY | UBS_FLAGS_AES; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5860 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5861 || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_5862)) { sc->sc_maxaggr = UBS_MAX_AGGR; sc->sc_statmask |= BS_STAT_MCR1_ALLEMPTY | BS_STAT_MCR2_ALLEMPTY | BS_STAT_MCR3_ALLEMPTY | BS_STAT_MCR4_ALLEMPTY; sc->sc_flags |= UBS_FLAGS_MULTIMCR | UBS_FLAGS_HWNORM | UBS_FLAGS_LONGCTX | UBS_FLAGS_AES | UBS_FLAGS_KEY | UBS_FLAGS_BIGKEY; #if 0 /* The RNG is not yet supported */ sc->sc_flags |= UBS_FLAGS_RNG | UBS_FLAGS_RNG4; #endif } memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BS_BAR); if (pci_mapreg_map(pa, BS_BAR, memtype, 0, &sc->sc_st, &sc->sc_sh, NULL, &iosize, 0)) { printf(": can't find mem space\n"); return; } sc->sc_dmat = pa->pa_dmat; if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ubsec_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_st, sc->sc_sh, iosize); return; } sc->sc_cid = crypto_get_driverid(0); if (sc->sc_cid < 0) { pci_intr_disestablish(pc, sc->sc_ih); bus_space_unmap(sc->sc_st, sc->sc_sh, iosize); return; } SIMPLEQ_INIT(&sc->sc_freequeue); dmap = sc->sc_dmaa; for (i = 0; i < UBS_MAX_NQUEUE; i++, dmap++) { struct ubsec_q *q; q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q), M_DEVBUF, M_NOWAIT); if (q == NULL) { printf(": can't allocate queue buffers\n"); break; } if (ubsec_dma_malloc(sc, sizeof(struct ubsec_dmachunk), &dmap->d_alloc, 0)) { printf(": can't allocate dma buffers\n"); free(q, M_DEVBUF, 0); break; } dmap->d_dma = (struct ubsec_dmachunk *)dmap->d_alloc.dma_vaddr; q->q_dma = dmap; sc->sc_queuea[i] = q; SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); } bzero(algs, sizeof(algs)); algs[CRYPTO_3DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; if (sc->sc_flags & UBS_FLAGS_AES) algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; crypto_register(sc->sc_cid, algs, ubsec_newsession, ubsec_freesession, ubsec_process); /* * Reset Broadcom chip */ ubsec_reset_board(sc); /* * Init Broadcom specific PCI settings */ ubsec_init_pciregs(pa); /* * Init Broadcom chip */ ubsec_init_board(sc); printf(": 3DES MD5 SHA1"); if (sc->sc_flags & UBS_FLAGS_AES) printf(" AES"); #ifndef UBSEC_NO_RNG if (sc->sc_flags & UBS_FLAGS_RNG) { if (sc->sc_flags & UBS_FLAGS_RNG4) sc->sc_statmask |= BS_STAT_MCR4_DONE; else sc->sc_statmask |= BS_STAT_MCR2_DONE; if (ubsec_dma_malloc(sc, sizeof(struct ubsec_mcr), &sc->sc_rng.rng_q.q_mcr, 0)) goto skip_rng; if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rngbypass), &sc->sc_rng.rng_q.q_ctx, 0)) { ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); goto skip_rng; } if (ubsec_dma_malloc(sc, sizeof(u_int32_t) * UBSEC_RNG_BUFSIZ, &sc->sc_rng.rng_buf, 0)) { ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx); ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); goto skip_rng; } timeout_set(&sc->sc_rngto, ubsec_rng, sc); if (hz >= 100) sc->sc_rnghz = hz / 100; else sc->sc_rnghz = 1; timeout_add(&sc->sc_rngto, sc->sc_rnghz); printf(" RNG"); skip_rng: ; } #endif /* UBSEC_NO_RNG */ if (sc->sc_flags & UBS_FLAGS_KEY) { sc->sc_statmask |= BS_STAT_MCR2_DONE; } printf(", %s\n", intrstr); }
static void malo_pci_attach(device_t parent, device_t self, void *aux) { struct malo_pci_softc *psc = device_private(self); struct pci_attach_args *pa = aux; struct malo_softc *sc = &psc->sc_malo; const char *intrstr = NULL; pci_intr_handle_t ih; pcireg_t memtype1, memtype2; int error; sc->sc_dev = self; sc->sc_dmat = pa->pa_dmat; psc->sc_pc = pa->pa_pc; aprint_normal("\n"); aprint_normal_dev(self,"Marvell Libertas Wireless\n"); /* map control / status registers */ memtype1 = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MALO_PCI_BAR1); switch (memtype1) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: break; default: aprint_error_dev(self, "invalid base address register\n"); return; } error = pci_mapreg_map(pa, MALO_PCI_BAR1, memtype1, 0, &sc->sc_mem1_bt, &sc->sc_mem1_bh, NULL, &psc->sc_mapsize1); if (error != 0) { aprint_error_dev(self, "can't map 1st mem space\n"); return; } /* map control / status registers */ memtype2 = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MALO_PCI_BAR1); switch (memtype2) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: break; default: aprint_error_dev(self, "invalid base address register\n"); return; } error = pci_mapreg_map(pa, MALO_PCI_BAR2, memtype2, 0, &sc->sc_mem2_bt, &sc->sc_mem2_bh, NULL, &psc->sc_mapsize2); if (error != 0) { aprint_error_dev(self, "can't map 2nd mem space\n"); return; } /* map interrupt */ if (pci_intr_map(pa, &ih) != 0) { aprint_error_dev(self, "can't map interrupt\n"); return; } /* establish interrupt */ intrstr = pci_intr_string(psc->sc_pc, ih); psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET, malo_intr, sc); if (psc->sc_ih == NULL) { aprint_error_dev(self, "could not establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); malo_attach(sc); if (pmf_device_register(self, malo_pci_suspend, malo_pci_resume)) pmf_class_network_register(self, &sc->sc_if); else aprint_error_dev(self, "couldn't establish power handler\n"); }
/** * radeon_driver_load_kms - Main load function for KMS. * * @dev: drm dev pointer * @flags: device flags * * This is the main load function for KMS (all asics). * It calls radeon_device_init() to set up the non-display * parts of the chip (asic init, CP, writeback, etc.), and * radeon_modeset_init() to set up the display parts * (crtcs, encoders, hotplug detect, etc.). * Returns 0 on success, error on failure. */ void radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) { struct radeon_device *rdev = (struct radeon_device *)self; struct drm_device *dev; struct pci_attach_args *pa = aux; const struct drm_pcidev *id_entry; int is_agp; pcireg_t type; uint8_t iobar; #if !defined(__sparc64__) pcireg_t addr, mask; int s; #endif #if defined(__sparc64__) || defined(__macppc__) extern int fbnode; #endif id_entry = drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist); rdev->flags = id_entry->driver_data; rdev->pc = pa->pa_pc; rdev->pa_tag = pa->pa_tag; rdev->iot = pa->pa_iot; rdev->memt = pa->pa_memt; rdev->dmat = pa->pa_dmat; #if defined(__sparc64__) || defined(__macppc__) if (fbnode == PCITAG_NODE(rdev->pa_tag)) rdev->console = 1; #else if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { rdev->console = 1; #if NVGA > 0 vga_console_attached = 1; #endif } #if NEFIFB > 0 if (efifb_is_console(pa)) { rdev->console = 1; efifb_cndetach(); } #endif #endif #define RADEON_PCI_MEM 0x10 #define RADEON_PCI_IO 0x14 #define RADEON_PCI_MMIO 0x18 #define RADEON_PCI_IO2 0x20 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_info(pa->pa_pc, pa->pa_tag, RADEON_PCI_MEM, type, &rdev->fb_aper_offset, &rdev->fb_aper_size, NULL)) { printf(": can't get frambuffer info\n"); return; } if (PCI_MAPREG_MEM_TYPE(type) != PCI_MAPREG_MEM_TYPE_64BIT) iobar = RADEON_PCI_IO; else iobar = RADEON_PCI_IO2; if (pci_mapreg_map(pa, iobar, PCI_MAPREG_TYPE_IO, 0, NULL, &rdev->rio_mem, NULL, &rdev->rio_mem_size, 0)) { printf(": can't map IO space\n"); return; } type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RADEON_PCI_MMIO); if (PCI_MAPREG_TYPE(type) != PCI_MAPREG_TYPE_MEM || pci_mapreg_map(pa, RADEON_PCI_MMIO, type, 0, NULL, &rdev->rmmio, &rdev->rmmio_base, &rdev->rmmio_size, 0)) { printf(": can't map mmio space\n"); return; } #if !defined(__sparc64__) /* * Make sure we have a base address for the ROM such that we * can map it later. */ s = splhigh(); addr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE); mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, addr); splx(s); if (addr == 0 && PCI_ROM_SIZE(mask) != 0 && pa->pa_memex) { bus_size_t size, start, end; bus_addr_t base; size = PCI_ROM_SIZE(mask); start = max(PCI_MEM_START, pa->pa_memex->ex_start); end = min(PCI_MEM_END, pa->pa_memex->ex_end); if (extent_alloc_subregion(pa->pa_memex, start, end, size, size, 0, 0, 0, &base) == 0) pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, base); } #endif #ifdef notyet mtx_init(&rdev->swi_lock, IPL_TTY); #endif /* update BUS flag */ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)) { rdev->flags |= RADEON_IS_AGP; } else if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, NULL, NULL)) { rdev->flags |= RADEON_IS_PCIE; } else { rdev->flags |= RADEON_IS_PCI; } DRM_DEBUG("%s card detected\n", ((rdev->flags & RADEON_IS_AGP) ? "AGP" : (((rdev->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); is_agp = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL); printf("\n"); kms_driver.num_ioctls = radeon_max_kms_ioctl; dev = (struct drm_device *)drm_attach_pci(&kms_driver, pa, is_agp, rdev->console, self); rdev->ddev = dev; rdev->pdev = dev->pdev; rdev->family = rdev->flags & RADEON_FAMILY_MASK; if (!radeon_msi_ok(rdev)) pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED; rdev->msi_enabled = 0; if (pci_intr_map_msi(pa, &rdev->intrh) == 0) rdev->msi_enabled = 1; else if (pci_intr_map(pa, &rdev->intrh) != 0) { printf(": couldn't map interrupt\n"); return; } printf("%s: %s\n", rdev->dev.dv_xname, pci_intr_string(pa->pa_pc, rdev->intrh)); rdev->irqh = pci_intr_establish(pa->pa_pc, rdev->intrh, IPL_TTY, radeon_driver_irq_handler_kms, rdev->ddev, rdev->dev.dv_xname); if (rdev->irqh == NULL) { printf("%s: couldn't establish interrupt\n", rdev->dev.dv_xname); return; } #ifdef __sparc64__ { struct rasops_info *ri; int node, console; node = PCITAG_NODE(pa->pa_tag); console = (fbnode == node); fb_setsize(&rdev->sf, 8, 1152, 900, node, 0); /* * The firmware sets up the framebuffer such that at starts at * an offset from the start of video memory. */ rdev->fb_offset = bus_space_read_4(rdev->memt, rdev->rmmio, RADEON_CRTC_OFFSET); if (bus_space_map(rdev->memt, rdev->fb_aper_offset + rdev->fb_offset, rdev->sf.sf_fbsize, BUS_SPACE_MAP_LINEAR, &rdev->memh)) { printf("%s: can't map video memory\n", rdev->dev.dv_xname); return; } ri = &rdev->sf.sf_ro; ri->ri_bits = bus_space_vaddr(rdev->memt, rdev->memh); ri->ri_hw = rdev; ri->ri_updatecursor = NULL; fbwscons_init(&rdev->sf, RI_VCONS | RI_WRONLY | RI_BSWAP, console); if (console) fbwscons_console_init(&rdev->sf, -1); } #endif rdev->shutdown = true; config_mountroot(self, radeondrm_attachhook); }
void sili_pci_attach(struct device *parent, struct device *self, void *aux) { struct sili_pci_softc *psc = (void *)self; struct sili_softc *sc = &psc->psc_sili; struct pci_attach_args *pa = aux; const struct sili_device *sd; pcireg_t memtype; pci_intr_handle_t ih; const char *intrstr; sd = sili_lookup(pa); psc->psc_pc = pa->pa_pc; psc->psc_tag = pa->pa_tag; psc->psc_ih = NULL; sc->sc_dmat = pa->pa_dmat; sc->sc_ios_global = 0; sc->sc_ios_port = 0; sc->sc_nports = sd->sd_nports; memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, SILI_PCI_BAR_GLOBAL); if (pci_mapreg_map(pa, SILI_PCI_BAR_GLOBAL, memtype, 0, &sc->sc_iot_global, &sc->sc_ioh_global, NULL, &sc->sc_ios_global, 0) != 0) { printf(": unable to map global registers\n"); return; } memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, SILI_PCI_BAR_PORT); if (pci_mapreg_map(pa, SILI_PCI_BAR_PORT, memtype, 0, &sc->sc_iot_port, &sc->sc_ioh_port, NULL, &sc->sc_ios_port, 0) != 0) { printf(": unable to map port registers\n"); goto unmap_global; } /* hook up the interrupt */ if (pci_intr_map(pa, &ih)) { printf(": unable to map interrupt\n"); goto unmap_port; } intrstr = pci_intr_string(psc->psc_pc, ih); psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO, sili_intr, sc, sc->sc_dev.dv_xname); if (psc->psc_ih == NULL) { printf(": unable to map interrupt%s%s\n", intrstr == NULL ? "" : " at ", intrstr == NULL ? "" : intrstr); goto unmap_port; } printf(": %s", intrstr); if (sili_attach(sc) != 0) { /* error printed by sili_attach */ goto deintr; } return; deintr: pci_intr_disestablish(psc->psc_pc, psc->psc_ih); psc->psc_ih = NULL; unmap_port: bus_space_unmap(sc->sc_iot_port, sc->sc_ioh_port, sc->sc_ios_port); sc->sc_ios_port = 0; unmap_global: bus_space_unmap(sc->sc_iot_global, sc->sc_ioh_global, sc->sc_ios_global); sc->sc_ios_global = 0; }
void ath_pci_attach(struct device *parent, struct device *self, void *aux) { struct ath_pci_softc *psc = (struct ath_pci_softc *)self; struct ath_softc *sc = &psc->sc_sc; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pcitag_t pt = pa->pa_tag; pci_intr_handle_t ih; pcireg_t mem_type; const char *intrstr = NULL; psc->sc_pc = pc; psc->sc_pcitag = pt; /* * Setup memory-mapping of PCI registers. */ mem_type = pci_mapreg_type(pc, pa->pa_tag, ATH_BAR0); if (mem_type != PCI_MAPREG_TYPE_MEM && mem_type != PCI_MAPREG_MEM_TYPE_64BIT) { printf(": bad PCI register type %d\n", (int)mem_type); goto fail; } if (pci_mapreg_map(pa, ATH_BAR0, mem_type, 0, &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_ss, 0)) { printf(": can't map register space\n"); goto fail; } /* * PCI Express check. */ if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, NULL, NULL) != 0) sc->sc_pcie = 1; sc->sc_invalid = 1; /* * Arrange interrupt line. */ if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); goto unmap; } intrstr = pci_intr_string(pc, ih); psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ath_intr, sc, sc->sc_dev.dv_xname); if (psc->sc_ih == NULL) { printf(": can't map interrupt\n"); goto unmap; } printf(": %s\n", intrstr); sc->sc_dmat = pa->pa_dmat; if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) == 0) return; pci_intr_disestablish(pc, psc->sc_ih); unmap: bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_ss); fail: return; }
static void siisata_pci_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct siisata_pci_softc *psc = device_private(self); struct siisata_softc *sc = &psc->si_sc; char devinfo[256]; const char *intrstr; pci_intr_handle_t intrhandle; pcireg_t csr, memtype; const struct siisata_pci_product *spp; void *ih; bus_space_tag_t memt; bus_space_handle_t memh; uint32_t gcreg; int memh_valid; bus_size_t grsize, prsize; sc->sc_atac.atac_dev = self; psc->sc_pc = pa->pa_pc; psc->sc_pcitag = pa->pa_tag; pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo)); aprint_naive(": SATA-II HBA\n"); aprint_normal(": %s\n", devinfo); /* map bar0 */ #if 1 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR0); #else memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; #endif 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, SIISATA_PCI_BAR0, memtype, 0, &memt, &memh, NULL, &grsize) == 0); break; default: memh_valid = 0; } if (memh_valid) { sc->sc_grt = memt; sc->sc_grh = memh; } else { aprint_error("%s: unable to map device global registers\n", SIISATANAME(sc)); return; } /* map bar1 */ #if 1 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR1); #else memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT; #endif 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, SIISATA_PCI_BAR1, memtype, 0, &memt, &memh, NULL, &prsize) == 0); break; default: memh_valid = 0; } if (memh_valid) { sc->sc_prt = memt; sc->sc_prh = memh; } else { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); aprint_error("%s: unable to map device port registers\n", SIISATANAME(sc)); return; } if (pci_dma64_available(pa)) { sc->sc_dmat = pa->pa_dmat64; sc->sc_have_dma64 = 1; aprint_debug("64-bit PCI DMA available\n"); } else { sc->sc_dmat = pa->pa_dmat; sc->sc_have_dma64 = 0; } /* map interrupt */ if (pci_intr_map(pa, &intrhandle) != 0) { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize); aprint_error("%s: couldn't map interrupt\n", SIISATANAME(sc)); return; } intrstr = pci_intr_string(pa->pa_pc, intrhandle); ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, siisata_intr, sc); if (ih == NULL) { bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize); bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize); aprint_error("%s: couldn't establish interrupt" "at %s\n", SIISATANAME(sc), intrstr); return; } aprint_normal("%s: interrupting at %s\n", SIISATANAME(sc), intrstr ? intrstr : "unknown interrupt"); /* fill in number of ports on this device */ spp = siisata_pci_lookup(pa); if (spp != NULL) { sc->sc_atac.atac_nchannels = spp->spp_ports; sc->sc_chip = spp->spp_chip; } else /* _match() should prevent us from getting here */ panic("siisata: the universe might be falling apart!\n"); gcreg = GRREAD(sc, GR_GC); aprint_normal("%s: SiI%d on ", SIISATANAME(sc), sc->sc_chip); if (sc->sc_chip == 3124) { aprint_normal("%d-bit, ", (gcreg & GR_GC_REQ64) ? 64 : 32); switch (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) { case 0: aprint_normal("%d", (gcreg & GR_GC_M66EN) ? 66 : 33); break; case GR_GC_TRDY: aprint_normal("%d", 66); break; case GR_GC_STOP: aprint_normal("%d", 100); break; case GR_GC_STOP | GR_GC_TRDY: aprint_normal("%d", 133); break; default: break; } aprint_normal("MHz PCI%s bus.", (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) ? "-X" : ""); } else { /* XXX - but only x1 devices so far */ aprint_normal("PCI-Express x1 port."); } if (gcreg & GR_GC_3GBPS) aprint_normal(" 3.0Gb/s capable.\n"); else aprint_normal("\n"); /* enable bus mastering in case the firmware didn't */ csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); csr |= PCI_COMMAND_MASTER_ENABLE; csr |= PCI_COMMAND_MEM_ENABLE; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr); siisata_attach(sc); if (!pmf_device_register(self, NULL, siisata_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
void rtwn_pci_attach(struct device *parent, struct device *self, void *aux) { struct rtwn_pci_softc *sc = (struct rtwn_pci_softc*)self; struct pci_attach_args *pa = aux; struct ifnet *ifp; int i, error; pcireg_t memtype; pci_intr_handle_t ih; const char *intrstr; sc->sc_dmat = pa->pa_dmat; sc->sc_pc = pa->pa_pc; sc->sc_tag = pa->pa_tag; timeout_set(&sc->calib_to, rtwn_calib_to, sc); timeout_set(&sc->scan_to, rtwn_scan_to, sc); pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); /* Map control/status registers. */ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, RTWN_PCI_MMBA); error = pci_mapreg_map(pa, RTWN_PCI_MMBA, memtype, 0, &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_mapsize, 0); if (error != 0) { printf(": can't map mem space\n"); return; } if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); return; } intrstr = pci_intr_string(sc->sc_pc, ih); sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_NET, rtwn_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": can't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s\n", intrstr); /* Disable PCIe Active State Power Management (ASPM). */ if (pci_get_capability(sc->sc_pc, sc->sc_tag, PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL)) { uint32_t lcsr = pci_conf_read(sc->sc_pc, sc->sc_tag, sc->sc_cap_off + PCI_PCIE_LCSR); lcsr &= ~(PCI_PCIE_LCSR_ASPM_L0S | PCI_PCIE_LCSR_ASPM_L1); pci_conf_write(sc->sc_pc, sc->sc_tag, sc->sc_cap_off + PCI_PCIE_LCSR, lcsr); } /* Allocate Tx/Rx buffers. */ error = rtwn_alloc_rx_list(sc); if (error != 0) { printf("%s: could not allocate Rx buffers\n", sc->sc_dev.dv_xname); return; } for (i = 0; i < RTWN_NTXQUEUES; i++) { error = rtwn_alloc_tx_list(sc, i); if (error != 0) { printf("%s: could not allocate Tx buffers\n", sc->sc_dev.dv_xname); rtwn_free_rx_list(sc); return; } } /* Attach the bus-agnostic driver. */ sc->sc_sc.sc_ops.cookie = sc; sc->sc_sc.sc_ops.write_1 = rtwn_pci_write_1; sc->sc_sc.sc_ops.write_2 = rtwn_pci_write_2; sc->sc_sc.sc_ops.write_4 = rtwn_pci_write_4; sc->sc_sc.sc_ops.read_1 = rtwn_pci_read_1; sc->sc_sc.sc_ops.read_2 = rtwn_pci_read_2; sc->sc_sc.sc_ops.read_4 = rtwn_pci_read_4; sc->sc_sc.sc_ops.tx = rtwn_tx; sc->sc_sc.sc_ops.power_on = rtwn_power_on; sc->sc_sc.sc_ops.dma_init = rtwn_dma_init; sc->sc_sc.sc_ops.load_firmware = rtwn_pci_load_firmware; sc->sc_sc.sc_ops.fw_loadpage = rtwn_fw_loadpage; sc->sc_sc.sc_ops.mac_init = rtwn_mac_init; sc->sc_sc.sc_ops.bb_init = rtwn_bb_init; sc->sc_sc.sc_ops.alloc_buffers = rtwn_alloc_buffers; sc->sc_sc.sc_ops.init = rtwn_pci_init; sc->sc_sc.sc_ops.stop = rtwn_pci_stop; sc->sc_sc.sc_ops.is_oactive = rtwn_is_oactive; sc->sc_sc.sc_ops.next_calib = rtwn_next_calib; sc->sc_sc.sc_ops.cancel_calib = rtwn_cancel_calib; sc->sc_sc.sc_ops.next_scan = rtwn_pci_next_scan; sc->sc_sc.sc_ops.cancel_scan = rtwn_cancel_scan; sc->sc_sc.sc_ops.wait_async = rtwn_wait_async; error = rtwn_attach(&sc->sc_dev, &sc->sc_sc, RTWN_CHIP_88C | RTWN_CHIP_PCI); if (error != 0) { rtwn_free_rx_list(sc); for (i = 0; i < RTWN_NTXQUEUES; i++) rtwn_free_tx_list(sc, i); return; } /* ifp is now valid */ ifp = &sc->sc_sc.sc_ic.ic_if; #if NBPFILTER > 0 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO, sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN); sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(RTWN_RX_RADIOTAP_PRESENT); sc->sc_txtap_len = sizeof(sc->sc_txtapu); sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(RTWN_TX_RADIOTAP_PRESENT); #endif }
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); }
static void bwi_pci_attach(device_t parent, device_t self, void *aux) { struct bwi_pci_softc *psc = device_private(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; int error = 0; char intrbuf[PCI_INTRSTR_LEN]; aprint_naive("\n"); aprint_normal(": Broadcom Wireless\n"); sc->sc_dev = self; 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); switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: break; default: aprint_error_dev(self, "invalid base address register\n"); return; } if (pci_mapreg_map(pa, BWI_PCI_BAR0, memtype, 0, &sc->sc_mem_bt, &sc->sc_mem_bh, NULL, &psc->psc_mapsize) != 0) { aprint_error_dev(self, "could not map mem space\n"); return; } /* map interrupt */ if (pci_intr_map(pa, &ih) != 0) { aprint_error_dev(self, "could not map interrupt\n"); goto fail; } /* establish interrupt */ intrstr = pci_intr_string(psc->psc_pc, ih, intrbuf, sizeof(intrbuf)); sc->sc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "could not establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); goto fail; } aprint_normal_dev(self, "interrupting at %s\n", 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); if (!pmf_device_register(self, bwi_suspend, bwi_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); error = bwi_attach(sc); if (error) goto fail; return; fail: if (sc->sc_ih) { pci_intr_disestablish(psc->psc_pc, sc->sc_ih); sc->sc_ih = NULL; } if (psc->psc_mapsize) { bus_space_unmap(sc->sc_mem_bt, sc->sc_mem_bh, psc->psc_mapsize); psc->psc_mapsize = 0; } return; }
void vte_attach(struct device *parent, struct device *self, void *aux) { struct vte_softc *sc = (struct vte_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; pcireg_t memtype; int error = 0; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, VTE_PCI_LOMEM); if (pci_mapreg_map(pa, VTE_PCI_LOMEM, memtype, 0, &sc->sc_mem_bt, &sc->sc_mem_bh, NULL, &sc->sc_mem_size, 0)) { printf(": can't map mem space\n"); return; } if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); goto fail; } /* * Allocate IRQ */ intrstr = pci_intr_string(pc, ih); sc->sc_irq_handle = pci_intr_establish(pc, ih, IPL_NET, vte_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_irq_handle == NULL) { printf(": could not establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto fail; } printf(": %s", intrstr); sc->sc_dmat = pa->pa_dmat; sc->sc_pct = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; /* Reset the ethernet controller. */ vte_reset(sc); error = vte_dma_alloc(sc); if (error) goto fail; /* Load station address. */ vte_get_macaddr(sc); ifp = &sc->sc_arpcom.ac_if; ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = vte_ioctl; ifp->if_start = vte_start; ifp->if_watchdog = vte_watchdog; IFQ_SET_MAXLEN(&ifp->if_snd, VTE_TX_RING_CNT - 1); IFQ_SET_READY(&ifp->if_snd); bcopy(sc->vte_eaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_capabilities = IFCAP_VLAN_MTU; printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); /* * Set up MII bus. * BIOS would have initialized VTE_MPSCCR to catch PHY * status changes so driver may be able to extract * configured PHY address. Since it's common to see BIOS * fails to initialize the register(including the sample * board I have), let mii(4) probe it. This is more * reliable than relying on BIOS's initialization. * * Advertising flow control capability to mii(4) was * intentionally disabled due to severe problems in TX * pause frame generation. See vte_rxeof() for more * details. */ sc->sc_miibus.mii_ifp = ifp; sc->sc_miibus.mii_readreg = vte_miibus_readreg; sc->sc_miibus.mii_writereg = vte_miibus_writereg; sc->sc_miibus.mii_statchg = vte_miibus_statchg; ifmedia_init(&sc->sc_miibus.mii_media, 0, vte_mediachange, vte_mediastatus); mii_attach(self, &sc->sc_miibus, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_miibus.mii_phys) == NULL) { printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); ifmedia_add(&sc->sc_miibus.mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_miibus.mii_media, IFM_ETHER | IFM_MANUAL); } else ifmedia_set(&sc->sc_miibus.mii_media, IFM_ETHER | IFM_AUTO); if_attach(ifp); ether_ifattach(ifp); timeout_set(&sc->vte_tick_ch, vte_tick, sc); return; fail: vte_detach(&sc->sc_dev, 0); }
void mpi_pci_attach(struct device *parent, struct device *self, void *aux) { struct mpi_pci_softc *psc = (void *)self; struct mpi_softc *sc = &psc->psc_mpi; struct pci_attach_args *pa = aux; pcireg_t memtype; int r; pci_intr_handle_t ih; const char *intrstr; #ifdef __sparc64__ int node; #endif psc->psc_pc = pa->pa_pc; psc->psc_tag = pa->pa_tag; psc->psc_ih = NULL; sc->sc_dmat = pa->pa_dmat; sc->sc_ios = 0; sc->sc_target = -1; /* find the appropriate memory base */ for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) { memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, r); if ((memtype & PCI_MAPREG_TYPE_MASK) == PCI_MAPREG_TYPE_MEM) break; } if (r >= PCI_MAPREG_END) { printf(": unable to locate system interface registers\n"); return; } if (pci_mapreg_map(pa, r, memtype, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) { printf(": unable to map system interface registers\n"); return; } /* disable the expansion rom */ PWRITE(psc, PCI_ROM_REG, PREAD(psc, PCI_ROM_REG) & ~PCI_ROM_ENABLE); /* hook up the interrupt */ if (pci_intr_map(pa, &ih)) { printf(": unable to map interrupt\n"); goto unmap; } intrstr = pci_intr_string(psc->psc_pc, ih); psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO, mpi_intr, sc, sc->sc_dev.dv_xname); if (psc->psc_ih == NULL) { printf(": unable to map interrupt%s%s\n", intrstr == NULL ? "" : " at ", intrstr == NULL ? "" : intrstr); goto unmap; } printf(": %s", intrstr); if (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG) == PCI_ID_CODE(PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_1030)) { sc->sc_flags |= MPI_F_SPI; #ifdef __sparc64__ /* * Walk up the Open Firmware device tree until we find a * "scsi-initiator-id" property. */ node = PCITAG_NODE(pa->pa_tag); while (node) { if (OF_getprop(node, "scsi-initiator-id", &sc->sc_target, sizeof(sc->sc_target)) == sizeof(sc->sc_target)) break; node = OF_parent(node); } #endif } if (mpi_attach(sc) != 0) { /* error printed by mpi_attach */ goto deintr; } return; deintr: pci_intr_disestablish(psc->psc_pc, psc->psc_ih); psc->psc_ih = NULL; unmap: bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); sc->sc_ios = 0; }
Static void athn_pci_attach(device_t parent, device_t self, void *aux) { struct athn_pci_softc *psc = device_private(self); struct athn_softc *sc = &psc->psc_sc; struct ieee80211com *ic = &sc->sc_ic; struct pci_attach_args *pa = aux; const char *intrstr; pcireg_t memtype, reg; pci_product_id_t subsysid; int error; sc->sc_dev = self; sc->sc_dmat = pa->pa_dmat; psc->psc_pc = pa->pa_pc; psc->psc_tag = pa->pa_tag; sc->sc_ops.read = athn_pci_read; sc->sc_ops.write = athn_pci_write; sc->sc_ops.write_barrier = athn_pci_write_barrier; /* * Get the offset of the PCI Express Capability Structure in PCI * Configuration Space (Linux hardcodes it as 0x60.) */ error = pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, &psc->psc_cap_off, NULL); if (error != 0) { /* Found. */ sc->sc_disable_aspm = athn_pci_disable_aspm; sc->sc_flags |= ATHN_FLAG_PCIE; } /* * Noone knows why this shit is necessary but there are claims that * not doing this may cause very frequent PCI FATAL interrupts from * the card: http://bugzilla.kernel.org/show_bug.cgi?id=13483 */ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40); if (reg & 0xff00) pci_conf_write(pa->pa_pc, pa->pa_tag, 0x40, reg & ~0xff00); /* Change latency timer; default value yields poor results. */ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); reg &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT); reg |= 168 << PCI_LATTIMER_SHIFT; pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, reg); /* Determine if bluetooth is also supported (combo chip.) */ reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); subsysid = PCI_PRODUCT(reg); if (subsysid == PCI_SUBSYSID_ATHEROS_COEX3WIRE_SA || subsysid == PCI_SUBSYSID_ATHEROS_COEX3WIRE_DA) sc->sc_flags |= ATHN_FLAG_BTCOEX3WIRE; else if (subsysid == PCI_SUBSYSID_ATHEROS_COEX2WIRE) sc->sc_flags |= ATHN_FLAG_BTCOEX2WIRE; /* * Setup memory-mapping of PCI registers. */ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, ATHN_PCI_MMBA); if (memtype != PCI_MAPREG_TYPE_MEM && memtype != PCI_MAPREG_MEM_TYPE_64BIT) { aprint_error_dev(self, "bad pci register type %d\n", (int)memtype); goto fail; } error = pci_mapreg_map(pa, ATHN_PCI_MMBA, memtype, 0, &psc->psc_iot, &psc->psc_ioh, NULL, &psc->psc_mapsz); if (error != 0) { aprint_error_dev(self, "cannot map register space\n"); goto fail; } /* * Arrange interrupt line. */ if (pci_intr_map(pa, &psc->psc_pih) != 0) { aprint_error_dev(self, "couldn't map interrupt\n"); goto fail1; } intrstr = pci_intr_string(psc->psc_pc, psc->psc_pih); psc->psc_ih = pci_intr_establish(psc->psc_pc, psc->psc_pih, IPL_NET, athn_intr, sc); if (psc->psc_ih == NULL) { aprint_error_dev(self, "couldn't map interrupt\n"); goto fail1; } ic->ic_ifp = &sc->sc_if; if (athn_attach(sc) != 0) goto fail2; aprint_verbose_dev(self, "interrupting at %s\n", intrstr); if (pmf_device_register(self, athn_pci_suspend, athn_pci_resume)) { pmf_class_network_register(self, &sc->sc_if); pmf_device_suspend(self, &sc->sc_qual); } else aprint_error_dev(self, "couldn't establish power handler\n"); ieee80211_announce(ic); return; fail2: pci_intr_disestablish(psc->psc_pc, psc->psc_ih); psc->psc_ih = NULL; fail1: bus_space_unmap(psc->psc_iot, psc->psc_ioh, psc->psc_mapsz); psc->psc_mapsz = 0; fail: return; }
static void xhci_pci_attach(device_t parent, device_t self, void *aux) { struct xhci_pci_softc * const psc = device_private(self); struct xhci_softc * const sc = &psc->sc_xhci; struct pci_attach_args *const pa = (struct pci_attach_args *)aux; const pci_chipset_tag_t pc = pa->pa_pc; const pcitag_t tag = pa->pa_tag; char const *intrstr; pci_intr_handle_t ih; pcireg_t csr, memtype; int err; //const char *vendor; uint32_t hccparams; char intrbuf[PCI_INTRSTR_LEN]; sc->sc_dev = self; sc->sc_bus.hci_private = sc; pci_aprint_devinfo(pa, "USB Controller"); /* Check for quirks */ sc->sc_xhci_quirks = xhci_pci_has_quirk(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); /* check if memory space access is enabled */ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); #ifdef DEBUG printf("csr: %08x\n", csr); #endif if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) { aprint_error_dev(self, "memory access is disabled\n"); return; } /* map MMIO registers */ memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_CBMEM); switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: if (pci_mapreg_map(pa, PCI_CBMEM, memtype, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) { sc->sc_ios = 0; aprint_error_dev(self, "can't map mem space\n"); return; } break; default: aprint_error_dev(self, "BAR not 64 or 32-bit MMIO\n"); return; break; } psc->sc_pc = pc; psc->sc_tag = tag; hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0x10); if (pci_dma64_available(pa) && ((hccparams&1)==1)) sc->sc_bus.dmatag = pa->pa_dmat64; else sc->sc_bus.dmatag = pa->pa_dmat; /* Enable the device. */ 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"); goto fail; } /* * Allocate IRQ */ intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, xhci_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"); goto fail; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); #if 0 /* Figure out vendor for root hub descriptor. */ vendor = pci_findvendor(pa->pa_id); sc->sc_id_vendor = PCI_VENDOR(pa->pa_id); if (vendor) strlcpy(sc->sc_vendor, vendor, sizeof(sc->sc_vendor)); else snprintf(sc->sc_vendor, sizeof(sc->sc_vendor), "vendor 0x%04x", PCI_VENDOR(pa->pa_id)); #endif err = xhci_init(sc); if (err) { aprint_error_dev(self, "init failed, error=%d\n", err); goto fail; } /* Intel chipset requires SuperSpeed enable and USB2 port routing */ switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_INTEL: xhci_pci_port_route(psc); break; default: break; } if (!pmf_device_register1(self, xhci_suspend, xhci_resume, xhci_shutdown)) aprint_error_dev(self, "couldn't establish power handler\n"); /* Attach usb device. */ sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); return; fail: if (sc->sc_ih) { pci_intr_disestablish(psc->sc_pc, sc->sc_ih); sc->sc_ih = NULL; } if (sc->sc_ios) { bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); sc->sc_ios = 0; } return; }