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); }
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; }
static int bwi_pci_attach(device_t dev) { struct bwi_pci_softc *psc = device_get_softc(dev); struct bwi_softc *sc = &psc->sc_sc; int error = ENXIO; sc->sc_dev = dev; /* * Enable bus mastering. */ pci_enable_busmaster(dev); /* * Setup memory-mapping of PCI registers. */ sc->sc_mem_rid = BWI_PCIR_BAR; sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE); if (sc->sc_mem_res == NULL) { device_printf(dev, "cannot map register space\n"); goto bad; } sc->sc_mem_bt = rman_get_bustag(sc->sc_mem_res); sc->sc_mem_bh = rman_get_bushandle(sc->sc_mem_res); /* * Mark device invalid so any interrupts (shared or otherwise) * that arrive before the card is setup are discarded. */ sc->sc_invalid = 1; /* * Arrange interrupt line. */ sc->sc_irq_rid = 0; sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irq_rid, RF_SHAREABLE|RF_ACTIVE); if (sc->sc_irq_res == NULL) { device_printf(dev, "could not map interrupt\n"); goto bad1; } if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, bwi_intr, sc, &sc->sc_irq_handle)) { device_printf(dev, "could not establish interrupt\n"); goto bad2; } /* Get more PCI information */ sc->sc_pci_did = pci_get_device(dev); sc->sc_pci_revid = pci_get_revid(dev); sc->sc_pci_subvid = pci_get_subvendor(dev); sc->sc_pci_subdid = pci_get_subdevice(dev); error = bwi_attach(sc); if (error == 0) /* success */ return 0; bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle); bad2: bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); bad1: bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, sc->sc_mem_res); bad: return (error); }