void ath_cardbus_attach(device_t parent, device_t self, void *aux) { struct ath_cardbus_softc *csc = device_private(self); struct ath_softc *sc = &csc->sc_ath; struct cardbus_attach_args *ca = aux; cardbus_devfunc_t ct = ca->ca_ct; bus_addr_t adr; sc->sc_dev = self; sc->sc_dmat = ca->ca_dmat; csc->sc_ct = ct; csc->sc_tag = ca->ca_tag; aprint_normal("\n"); /* * Map the device. */ if (Cardbus_mapreg_map(ct, ATH_PCI_MMBA, PCI_MAPREG_TYPE_MEM, 0, &csc->sc_iot, &csc->sc_ioh, &adr, &csc->sc_mapsize) == 0) { #if rbus #else (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize); #endif csc->sc_bar_val = adr | PCI_MAPREG_TYPE_MEM; } else { aprint_error_dev(self, "unable to map device registers\n"); return; } sc->sc_st = HALTAG(csc->sc_iot); sc->sc_sh = HALHANDLE(csc->sc_ioh); /* * Set up the PCI configuration registers. */ ath_cardbus_setup(csc); /* Remember which interrupt line. */ csc->sc_intrline = ca->ca_intrline; ATH_LOCK_INIT(sc); /* * Finish off the attach. */ if (ath_attach(PCI_PRODUCT(ca->ca_id), sc) != 0) return; if (!pmf_device_register(self, ath_cardbus_suspend, ath_cardbus_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); else { pmf_class_network_register(self, &sc->sc_if); pmf_device_suspend_self(self); } }
static void fxp_cardbus_attach(struct device *parent, struct device *self, void *aux) { struct fxp_cardbus_softc *csc = device_private(self); struct fxp_softc *sc = &csc->sc; struct cardbus_attach_args *ca = aux; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; bus_addr_t adr; bus_size_t size; sc->sc_dev = self; csc->ct = ca->ca_ct; /* * Map control/status registers. */ if (Cardbus_mapreg_map(csc->ct, CARDBUS_BASE1_REG, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, &adr, &size) == 0) { csc->base1_reg = adr | 1; sc->sc_st = iot; sc->sc_sh = ioh; csc->size = size; } else if (Cardbus_mapreg_map(csc->ct, CARDBUS_BASE0_REG, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, &adr, &size) == 0) { csc->base0_reg = adr; sc->sc_st = memt; sc->sc_sh = memh; csc->size = size; } else panic("%s: failed to allocate mem and io space", __func__); if (ca->ca_cis.cis1_info[0] && ca->ca_cis.cis1_info[1]) printf(": %s %s\n", ca->ca_cis.cis1_info[0], ca->ca_cis.cis1_info[1]); else printf("\n"); sc->sc_dmat = ca->ca_dmat; sc->sc_enable = fxp_cardbus_enable; sc->sc_disable = fxp_cardbus_disable; sc->sc_enabled = 0; fxp_enable(sc); fxp_attach(sc); fxp_disable(sc); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); else pmf_class_network_register(self, &sc->sc_ethercom.ec_if); }
void re_cardbus_attach(device_t parent, device_t self, void *aux) { struct re_cardbus_softc *csc = device_private(self); struct rtk_softc *sc = &csc->sc_rtk; struct cardbus_attach_args *ca = aux; cardbus_devfunc_t ct = ca->ca_ct; const struct rtk_type *t; bus_addr_t adr; sc->sc_dev = self; sc->sc_dmat = ca->ca_dmat; csc->sc_ct = ct; csc->sc_tag = ca->ca_tag; csc->sc_intrline = ca->ca_intrline; t = re_cardbus_lookup(ca); if (t == NULL) { aprint_error("\n"); panic("%s: impossible", __func__); } aprint_normal(": %s\n", t->rtk_name); /* * Power management hooks. */ sc->sc_enable = re_cardbus_enable; sc->sc_disable = re_cardbus_disable; /* * Map control/status registers. */ csc->sc_csr = CARDBUS_COMMAND_MASTER_ENABLE; #ifdef RTK_USEIOSPACE if (Cardbus_mapreg_map(ct, RTK_PCI_LOIO, CARDBUS_MAPREG_TYPE_IO, 0, &sc->rtk_btag, &sc->rtk_bhandle, &adr, &csc->sc_mapsize) == 0) { #if rbus #else (*ct->ct_cf->cardbus_io_open)(cc, 0, adr, adr+csc->sc_mapsize); #endif csc->sc_cben = CARDBUS_IO_ENABLE; csc->sc_csr |= CARDBUS_COMMAND_IO_ENABLE; csc->sc_bar_reg = RTK_PCI_LOIO; csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_IO; } #else if (Cardbus_mapreg_map(ct, RTK_PCI_LOMEM, CARDBUS_MAPREG_TYPE_MEM, 0, &sc->rtk_btag, &sc->rtk_bhandle, &adr, &csc->sc_mapsize) == 0) { #if rbus #else (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize); #endif csc->sc_cben = CARDBUS_MEM_ENABLE; csc->sc_csr |= CARDBUS_COMMAND_MEM_ENABLE; csc->sc_bar_reg = RTK_PCI_LOMEM; csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_MEM; } #endif else { aprint_error_dev(self, "unable to map deviceregisters\n"); return; } /* * Handle power management nonsense and initialize the * configuration registers. */ re_cardbus_setup(csc); sc->sc_dmat = ca->ca_dmat; re_attach(sc); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); else pmf_class_network_register(self, &sc->ethercom.ec_if); /* * Power down the socket. */ Cardbus_function_disable(csc->sc_ct); }
static void bce_attach(device_t parent, device_t self, void *aux) { struct bce_softc *sc = device_private(self); struct pci_attach_args *pa = aux; const struct bce_product *bp; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; uint32_t command; pcireg_t memtype, pmode; bus_addr_t memaddr; bus_size_t memsize; void *kva; bus_dma_segment_t seg; int error, i, pmreg, rseg; struct ifnet *ifp; char intrbuf[PCI_INTRSTR_LEN]; sc->bce_dev = self; bp = bce_lookup(pa); KASSERT(bp != NULL); sc->bce_pa = *pa; /* BCM440x can only address 30 bits (1GB) */ if (bus_dmatag_subregion(pa->pa_dmat, 0, (1 << 30), &(sc->bce_dmatag), BUS_DMA_NOWAIT) != 0) { aprint_error_dev(self, "WARNING: failed to restrict dma range," " falling back to parent bus dma range\n"); sc->bce_dmatag = pa->pa_dmat; } aprint_naive(": Ethernet controller\n"); aprint_normal(": %s\n", bp->bp_name); /* * Map control/status registers. */ command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command); command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); if (!(command & PCI_COMMAND_MEM_ENABLE)) { aprint_error_dev(self, "failed to enable memory mapping!\n"); return; } memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BCE_PCI_BAR0); 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, BCE_PCI_BAR0, memtype, 0, &sc->bce_btag, &sc->bce_bhandle, &memaddr, &memsize) == 0) break; default: aprint_error_dev(self, "unable to find mem space\n"); return; } /* Get it out of power save mode if needed. */ if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, NULL)) { pmode = pci_conf_read(pc, pa->pa_tag, pmreg + 4) & 0x3; if (pmode == 3) { /* * The card has lost all configuration data in * this state, so punt. */ aprint_error_dev(self, "unable to wake up from power state D3\n"); return; } if (pmode != 0) { aprint_normal_dev(self, "waking up from power state D%d\n", pmode); pci_conf_write(pc, pa->pa_tag, pmreg + 4, 0); } } 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->bce_intrhand = pci_intr_establish(pc, ih, IPL_NET, bce_intr, sc); if (sc->bce_intrhand == NULL) { aprint_error_dev(self, "couldn't establish interrupt\n"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* reset the chip */ bce_reset(sc); /* * Allocate DMA-safe memory for ring descriptors. * The receive, and transmit rings can not share the same * 4k space, however both are allocated at once here. */ /* * XXX PAGE_SIZE is wasteful; we only need 1KB + 1KB, but * due to the limition above. ?? */ if ((error = bus_dmamem_alloc(sc->bce_dmatag, 2 * PAGE_SIZE, PAGE_SIZE, 2 * PAGE_SIZE, &seg, 1, &rseg, BUS_DMA_NOWAIT))) { aprint_error_dev(self, "unable to alloc space for ring descriptors, error = %d\n", error); return; } /* map ring space to kernel */ if ((error = bus_dmamem_map(sc->bce_dmatag, &seg, rseg, 2 * PAGE_SIZE, &kva, BUS_DMA_NOWAIT))) { aprint_error_dev(self, "unable to map DMA buffers, error = %d\n", error); bus_dmamem_free(sc->bce_dmatag, &seg, rseg); return; } /* create a dma map for the ring */ if ((error = bus_dmamap_create(sc->bce_dmatag, 2 * PAGE_SIZE, 1, 2 * PAGE_SIZE, 0, BUS_DMA_NOWAIT, &sc->bce_ring_map))) { aprint_error_dev(self, "unable to create ring DMA map, error = %d\n", error); bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE); bus_dmamem_free(sc->bce_dmatag, &seg, rseg); return; } /* connect the ring space to the dma map */ if (bus_dmamap_load(sc->bce_dmatag, sc->bce_ring_map, kva, 2 * PAGE_SIZE, NULL, BUS_DMA_NOWAIT)) { bus_dmamap_destroy(sc->bce_dmatag, sc->bce_ring_map); bus_dmamem_unmap(sc->bce_dmatag, kva, 2 * PAGE_SIZE); bus_dmamem_free(sc->bce_dmatag, &seg, rseg); return; } /* save the ring space in softc */ sc->bce_rx_ring = (struct bce_dma_slot *) kva; sc->bce_tx_ring = (struct bce_dma_slot *) ((char *)kva + PAGE_SIZE); /* Create the transmit buffer DMA maps. */ for (i = 0; i < BCE_NTXDESC; i++) { if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES, BCE_NTXFRAGS, MCLBYTES, 0, 0, &sc->bce_cdata.bce_tx_map[i])) != 0) { aprint_error_dev(self, "unable to create tx DMA map, error = %d\n", error); } sc->bce_cdata.bce_tx_chain[i] = NULL; } /* Create the receive buffer DMA maps. */ for (i = 0; i < BCE_NRXDESC; i++) { if ((error = bus_dmamap_create(sc->bce_dmatag, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->bce_cdata.bce_rx_map[i])) != 0) { aprint_error_dev(self, "unable to create rx DMA map, error = %d\n", error); } sc->bce_cdata.bce_rx_chain[i] = NULL; } /* Set up ifnet structure */ ifp = &sc->ethercom.ec_if; strcpy(ifp->if_xname, device_xname(self)); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = bce_ioctl; ifp->if_start = bce_start; ifp->if_watchdog = bce_watchdog; ifp->if_init = bce_init; ifp->if_stop = bce_stop; IFQ_SET_READY(&ifp->if_snd); /* Initialize our media structures and probe the MII. */ sc->bce_mii.mii_ifp = ifp; sc->bce_mii.mii_readreg = bce_mii_read; sc->bce_mii.mii_writereg = bce_mii_write; sc->bce_mii.mii_statchg = bce_statchg; sc->ethercom.ec_mii = &sc->bce_mii; ifmedia_init(&sc->bce_mii.mii_media, 0, ether_mediachange, ether_mediastatus); mii_attach(sc->bce_dev, &sc->bce_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG|MIIF_DOPAUSE); if (LIST_FIRST(&sc->bce_mii.mii_phys) == NULL) { ifmedia_add(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE, 0, NULL); ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_NONE); } else ifmedia_set(&sc->bce_mii.mii_media, IFM_ETHER | IFM_AUTO); /* get the phy */ sc->bce_phy = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_PHY) & 0x1f; /* * Enable activity led. * XXX This should be in a phy driver, but not currently. */ bce_mii_write(sc->bce_dev, 1, 26, /* MAGIC */ bce_mii_read(sc->bce_dev, 1, 26) & 0x7fff); /* MAGIC */ /* enable traffic meter led mode */ bce_mii_write(sc->bce_dev, 1, 27, /* MAGIC */ bce_mii_read(sc->bce_dev, 1, 27) | (1 << 6)); /* MAGIC */ /* Attach the interface */ if_attach(ifp); sc->enaddr[0] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET0); sc->enaddr[1] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET1); sc->enaddr[2] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET2); sc->enaddr[3] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET3); sc->enaddr[4] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET4); sc->enaddr[5] = bus_space_read_1(sc->bce_btag, sc->bce_bhandle, BCE_MAGIC_ENET5); aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(sc->enaddr)); ether_ifattach(ifp, sc->enaddr); rnd_attach_source(&sc->rnd_source, device_xname(self), RND_TYPE_NET, 0); callout_init(&sc->bce_timeout, 0); if (pmf_device_register(self, NULL, bce_resume)) pmf_class_network_register(self, ifp); else aprint_error_dev(self, "couldn't establish power handler\n"); }
static void wi_pci_attach(device_t parent, device_t self, void *aux) { struct wi_pci_softc *psc = device_private(self); struct wi_softc *sc = &psc->psc_wi; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; const char *intrstr; const struct wi_pci_product *wpp; pci_intr_handle_t ih; bus_space_tag_t memt, iot, plxt, tmdt; bus_space_handle_t memh, ioh, plxh, tmdh; char intrbuf[PCI_INTRSTR_LEN]; sc->sc_dev = self; psc->psc_pc = pc; psc->psc_pcitag = pa->pa_tag; wpp = wi_pci_lookup(pa); #ifdef DIAGNOSTIC if (wpp == NULL) { printf("\n"); panic("wi_pci_attach: impossible"); } #endif switch (wpp->wpp_chip) { case CHIP_PLX_OTHER: case CHIP_PLX_9052: /* Map memory and I/O registers. */ if (pci_mapreg_map(pa, WI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, &memt, &memh, NULL, NULL) != 0) { aprint_error(": can't map mem space\n"); return; } if (pci_mapreg_map(pa, WI_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) != 0) { aprint_error(": can't map I/O space\n"); return; } if (wpp->wpp_chip == CHIP_PLX_OTHER) { /* The PLX 9052 doesn't have IO at 0x14. Perhaps other chips have, so we'll make this conditional. */ if (pci_mapreg_map(pa, WI_PCI_PLX_LOIO, PCI_MAPREG_TYPE_IO, 0, &plxt, &plxh, NULL, NULL) != 0) { aprint_error(": can't map PLX\n"); return; } } break; case CHIP_TMD_7160: /* Used instead of PLX on at least one revision of * the National Datacomm Corporation NCP130. Values * for registers acquired from OpenBSD, which in * turn got them from a Linux driver. */ /* Map COR and I/O registers. */ if (pci_mapreg_map(pa, WI_TMD_COR, PCI_MAPREG_TYPE_IO, 0, &tmdt, &tmdh, NULL, NULL) != 0) { aprint_error(": can't map TMD\n"); return; } if (pci_mapreg_map(pa, WI_TMD_IO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) != 0) { aprint_error(": can't map I/O space\n"); return; } break; default: if (pci_mapreg_map(pa, WI_PCI_CBMA, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &iot, &ioh, NULL, NULL) != 0) { aprint_error(": can't map mem space\n"); return; } memt = iot; memh = ioh; sc->sc_pci = 1; break; } pci_aprint_devinfo(pa, NULL); sc->sc_enabled = 1; sc->sc_enable = wi_pci_enable; sc->sc_iot = iot; sc->sc_ioh = ioh; /* Make sure interrupts are disabled. */ CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); if (wpp->wpp_chip == CHIP_PLX_OTHER) { uint32_t command; #define WI_LOCAL_INTCSR 0x4c #define WI_LOCAL_INTEN 0x40 /* poke this into INTCSR */ command = bus_space_read_4(plxt, plxh, WI_LOCAL_INTCSR); command |= WI_LOCAL_INTEN; bus_space_write_4(plxt, plxh, WI_LOCAL_INTCSR, command); } /* 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)); psc->psc_ih = ih; sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wi_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); switch (wpp->wpp_chip) { case CHIP_PLX_OTHER: case CHIP_PLX_9052: /* * Setup the PLX chip for level interrupts and config index 1 * XXX - should really reset the PLX chip too. */ bus_space_write_1(memt, memh, WI_PLX_COR_OFFSET, WI_PLX_COR_VALUE); break; case CHIP_TMD_7160: /* Enable I/O mode and level interrupts on the embedded * card. The card's COR is the first byte of BAR 0. */ bus_space_write_1(tmdt, tmdh, 0, WI_COR_IOMODE); break; default: /* reset HFA3842 MAC core */ wi_pci_reset(sc); break; } printf("%s:", device_xname(self)); if (wi_attach(sc, 0) != 0) { aprint_error_dev(self, "failed to attach controller\n"); pci_intr_disestablish(pa->pa_pc, sc->sc_ih); return; } if (!wpp->wpp_chip) sc->sc_reset = wi_pci_reset; if (pmf_device_register(self, NULL, NULL)) pmf_class_network_register(self, &sc->sc_if); else aprint_error_dev(self, "couldn't establish power handler\n"); }
static void wi_pcmcia_attach(device_t parent, device_t self, void *aux) { struct wi_pcmcia_softc *psc = device_private(self); struct wi_softc *sc = &psc->sc_wi; struct pcmcia_attach_args *pa = aux; struct pcmcia_config_entry *cfe; int haveaddr; int error; aprint_naive("\n"); sc->sc_dev = self; psc->sc_pf = pa->pf; error = pcmcia_function_configure(pa->pf, wi_pcmcia_validate_config); if (error) { aprint_error_dev(self, "configure failed, error=%d\n", error); return; } cfe = pa->pf->cfe; sc->sc_iot = cfe->iospace[0].handle.iot; sc->sc_ioh = cfe->iospace[0].handle.ioh; if (pa->manufacturer == PCMCIA_VENDOR_SYMBOL && pa->product == PCMCIA_PRODUCT_SYMBOL_LA4100) psc->sc_symbol_cf = 1; /* * XXX: Sony PEGA-WL100 CF card has a same vendor/product id as * Intel PCMCIA card. It may be incorrect to detect by the * initial value of COR register. */ if (pa->manufacturer == PCMCIA_VENDOR_INTEL && pa->product == PCMCIA_PRODUCT_INTEL_PRO_WLAN_2011 && CSR_READ_2(sc, WI_COR) == WI_COR_IOMODE) psc->sc_symbol_cf = 1; error = wi_pcmcia_enable(self, 1); if (error) goto fail; sc->sc_pci = 0; sc->sc_enable = wi_pcmcia_enable; printf("%s:", device_xname(self)); haveaddr = pa->pf->pf_funce_lan_nidlen == IEEE80211_ADDR_LEN; if (wi_attach(sc, haveaddr ? pa->pf->pf_funce_lan_nid : 0) != 0) { aprint_error_dev(self, "failed to attach controller\n"); goto fail2; } if (pmf_device_register(self, NULL, NULL)) pmf_class_network_register(self, &sc->sc_if); else aprint_error_dev(self, "couldn't establish power handler\n"); wi_pcmcia_enable(self, 0); psc->sc_state = WI_PCMCIA_ATTACHED; return; fail2: wi_pcmcia_enable(self, 0); fail: pcmcia_function_unconfigure(pa->pf); }
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"); }
static void atw_pci_attach(device_t parent, device_t self, void *aux) { struct atw_pci_softc *psc = device_private(self); struct atw_softc *sc = &psc->psc_atw; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; const char *intrstr = NULL; bus_space_tag_t iot, memt; bus_space_handle_t ioh, memh; int ioh_valid, memh_valid; const struct atw_pci_product *app; int error; sc->sc_dev = self; psc->psc_pc = pa->pa_pc; psc->psc_pcitag = pa->pa_tag; app = atw_pci_lookup(pa); if (app == NULL) { printf("\n"); panic("atw_pci_attach: impossible"); } /* * Get revision info, and set some chip-specific variables. */ sc->sc_rev = PCI_REVISION(pa->pa_class); printf(": %s, revision %d.%d\n", app->app_product_name, (sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf); /* power up chip */ if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self, NULL)) && error != EOPNOTSUPP) { aprint_error_dev(self, "cannot activate %d\n", error); return; } /* * Map the device. */ ioh_valid = (pci_mapreg_map(pa, ATW_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh, NULL, NULL) == 0); memh_valid = (pci_mapreg_map(pa, ATW_PCI_MMBA, PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, NULL, NULL) == 0); if (memh_valid) { sc->sc_st = memt; sc->sc_sh = memh; } else if (ioh_valid) { sc->sc_st = iot; sc->sc_sh = ioh; } else { printf(": unable to map device registers\n"); return; } sc->sc_dmat = pa->pa_dmat; /* * Make sure bus mastering is enabled. */ 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); /* * Get the cacheline size. */ sc->sc_cacheline = PCI_CACHELINE(pci_conf_read(pc, pa->pa_tag, PCI_BHLC_REG)); /* * Get PCI data moving command info. */ if (pa->pa_flags & PCI_FLAGS_MRL_OKAY) /* read line */ sc->sc_flags |= ATWF_MRL; if (pa->pa_flags & PCI_FLAGS_MRM_OKAY) /* read multiple */ sc->sc_flags |= ATWF_MRM; if (pa->pa_flags & PCI_FLAGS_MWI_OKAY) /* write invalidate */ sc->sc_flags |= ATWF_MWI; /* * Map and establish our interrupt. */ if (pci_intr_map(pa, &psc->psc_ih)) { aprint_error_dev(self, "unable to map interrupt\n"); return; } intrstr = pci_intr_string(pc, psc->psc_ih); psc->psc_intrcookie = pci_intr_establish(pc, psc->psc_ih, IPL_NET, atw_intr, sc); if (psc->psc_intrcookie == NULL) { aprint_error_dev(self, "unable to establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); aprint_error("\n"); return; } aprint_normal_dev(self, "interrupting at %s\n", intrstr); /* * Bus-independent attach. */ atw_attach(sc); if (pmf_device_register1(sc->sc_dev, atw_pci_suspend, atw_pci_resume, atw_shutdown)) pmf_class_network_register(sc->sc_dev, &sc->sc_if); else aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n"); /* * Power down the socket. */ pmf_device_suspend(sc->sc_dev, &sc->sc_qual); }
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; }