/*---------------------------------------------------------------------------* * PCI attach *---------------------------------------------------------------------------*/ static void iwic_pci_attach(device_t parent, device_t dev, void *aux) { struct iwic_softc *sc = device_private(dev); struct iwic_bchan *bchan; pci_intr_handle_t ih; const char *intrstr; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; char intrbuf[PCI_INTRSTR_LEN]; sc->sc_dev = dev; sc->sc_cardname = iwic_find_card(pa); if (!sc->sc_cardname) return; /* Huh? */ printf(": %s\n", sc->sc_cardname); if (pci_mapreg_map(pa, IWIC_PCI_IOBA, PCI_MAPREG_TYPE_IO, 0, &sc->sc_io_bt, &sc->sc_io_bh, &sc->sc_iobase, &sc->sc_iosize)) { aprint_error_dev(sc->sc_dev, "unable to map registers\n"); return; } 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)); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, iwic_pci_intr, sc); if (sc->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; } sc->sc_pc = pc; aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); /* disable interrupts */ IWIC_WRITE(sc, IWIC_IMASK, 0xff); IWIC_READ(sc, ISTA); iwic_dchan_init(sc); bchan = &sc->sc_bchan[IWIC_BCH_A]; bchan->offset = B1_CHAN_OFFSET; bchan->channel = IWIC_BCH_A; bchan->state = ST_IDLE; iwic_bchannel_setup(sc, IWIC_BCH_A, BPROT_NONE, 0); bchan = &sc->sc_bchan[IWIC_BCH_B]; bchan->offset = B2_CHAN_OFFSET; bchan->channel = IWIC_BCH_B; bchan->state = ST_IDLE; iwic_bchannel_setup(sc, IWIC_BCH_B, BPROT_NONE, 0); iwic_init_linktab(sc); iwic_attach_bri(sc); }
/*---------------------------------------------------------------------------* * PCI attach *---------------------------------------------------------------------------*/ static int iwic_pci_attach(device_t dev) { unsigned short iobase; struct iwic_softc *sc; void *ih = 0; int unit = device_get_unit(dev); struct iwic_bchan *bchan; /* check max unit range */ if(unit >= IWIC_MAXUNIT) { printf("iwic%d: Error, unit %d >= IWIC_MAXUNIT!\n", unit, unit); return(ENXIO); } sc = iwic_find_sc(unit); /* get softc */ sc->sc_unit = unit; /* use the i/o mapped base address */ sc->sc_resources.io_rid[0] = BADDR1; if(!(sc->sc_resources.io_base[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_resources.io_rid[0], 0UL, ~0UL, 1, RF_ACTIVE))) { printf("iwic%d: Couldn't alloc io port!\n", unit); return(ENXIO); } iobase = rman_get_start(sc->sc_resources.io_base[0]); if(!(sc->sc_resources.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_resources.irq_rid, 0UL, ~0UL, 1, RF_SHAREABLE|RF_ACTIVE))) { printf("iwic%d: Couldn't alloc irq!\n",unit); return(ENXIO); } /* setup card type */ sc->sc_cardtyp = CARD_TYPEP_WINB6692; sc->sc_iobase = (u_int32_t) iobase; sc->sc_trace = TRACE_OFF; sc->sc_I430state = ST_F3N; /* Deactivated */ sc->enabled = FALSE; if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET, (void(*)(void*))iwic_pci_intr, sc, &ih)) { printf("iwic%d: Couldn't set up irq!\n", unit); return(ENXIO); } /* disable interrupts */ IWIC_WRITE(sc, IMASK, 0xff); iwic_dchan_init(sc); bchan = &sc->sc_bchan[IWIC_BCH_A]; bchan->unit = unit; bchan->offset = B1_CHAN_OFFSET; bchan->channel = IWIC_BCH_A; bchan->state = ST_IDLE; iwic_bchannel_setup(unit, IWIC_BCH_A, BPROT_NONE, 0); bchan = &sc->sc_bchan[IWIC_BCH_B]; bchan->unit = unit; bchan->offset = B2_CHAN_OFFSET; bchan->channel = IWIC_BCH_B; bchan->state = ST_IDLE; iwic_bchannel_setup(unit, IWIC_BCH_B, BPROT_NONE, 0); iwic_init_linktab(sc); if(bootverbose) { int ver = IWIC_READ(sc, D_RBCH); printf("iwic%d: W6692 chip version = %d\n", unit, D_RBCH_VN(ver)); } i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &iwic_l1mux_func); IWIC_READ(sc, ISTA); /* Enable interrupts */ IWIC_WRITE(sc, IMASK, IMASK_XINT0 | IMASK_XINT1); return(0); }