/* * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ void re_cardbus_attach(struct device *parent, struct device *self, void *aux) { struct re_cardbus_softc *csc = (struct re_cardbus_softc *)self; struct rl_softc *sc = &csc->sc_rl; struct cardbus_attach_args *ca = aux; struct cardbus_softc *psc = (struct cardbus_softc *)sc->sc_dev.dv_parent; cardbus_chipset_tag_t cc = psc->sc_cc; cardbus_function_tag_t cf = psc->sc_cf; cardbus_devfunc_t ct = ca->ca_ct; bus_addr_t adr; char intrstr[16]; sc->sc_dmat = ca->ca_dmat; csc->ct = ct; csc->sc_tag = ca->ca_tag; csc->sc_pc = ca->ca_pc; csc->sc_intrline = ca->ca_intrline; /* * Map control/status registers. */ if (Cardbus_mapreg_map(ct, RL_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->rl_btag, &sc->rl_bhandle, &adr, &csc->sc_mapsize) == 0) { csc->sc_cben = CARDBUS_MEM_ENABLE; csc->sc_csr |= PCI_COMMAND_MEM_ENABLE; csc->sc_bar_reg = RL_PCI_LOMEM; csc->sc_bar_val = adr | PCI_MAPREG_TYPE_MEM; } else { printf(": can't map mem space\n"); return; } /* Enable power */ Cardbus_function_enable(ct); /* Get chip out of powersave mode (if applicable), initialize * config registers */ re_cardbus_setup(sc); /* Allocate interrupt */ csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET, re_intr, sc, sc->sc_dev.dv_xname); if (csc->sc_ih == NULL) { printf(": couldn't establish interrupt at %d", ca->ca_intrline); Cardbus_function_disable(csc->ct); return; } snprintf(intrstr, sizeof(intrstr), "irq %d", ca->ca_intrline); /* Call bus-independent (common) attach routine */ if (re_attach(sc, intrstr)) { cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih); Cardbus_mapreg_unmap(ct, csc->sc_bar_reg, sc->rl_btag, sc->rl_bhandle, csc->sc_mapsize); } }
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); }
/* * PCI-specific attach routine */ void re_pci_attach(struct device *parent, struct device *self, void *aux) { struct re_pci_softc *psc = (struct re_pci_softc *)self; struct rl_softc *sc = &psc->sc_rl; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr = NULL; pcireg_t command; /* * Handle power management nonsense. */ command = pci_conf_read(pc, pa->pa_tag, RL_PCI_CAPID) & 0x000000FF; if (command == 0x01) { u_int32_t iobase, membase, irq; /* Save important PCI config data. */ iobase = pci_conf_read(pc, pa->pa_tag, RL_PCI_LOIO); membase = pci_conf_read(pc, pa->pa_tag, RL_PCI_LOMEM); irq = pci_conf_read(pc, pa->pa_tag, RL_PCI_INTLINE); #if 0 /* Reset the power state. */ printf(": chip is in D%d power mode " "-- setting to D0", command & RL_PSTATE_MASK); #endif command &= 0xFFFFFFFC; /* Restore PCI config data. */ pci_conf_write(pc, pa->pa_tag, RL_PCI_LOIO, iobase); pci_conf_write(pc, pa->pa_tag, RL_PCI_LOMEM, membase); pci_conf_write(pc, pa->pa_tag, RL_PCI_INTLINE, irq); } #ifndef SMALL_KERNEL /* Enable power management for wake on lan. */ pci_conf_write(pc, pa->pa_tag, RL_PCI_PMCSR, RL_PME_EN); #endif /* * Map control/status registers. */ if (pci_mapreg_map(pa, RL_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->rl_btag, &sc->rl_bhandle, NULL, &psc->sc_iosize, 0)) { if (pci_mapreg_map(pa, RL_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, &sc->rl_btag, &sc->rl_bhandle, NULL, &psc->sc_iosize, 0)) { printf(": can't map mem or i/o space\n"); return; } } /* Allocate interrupt */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, re_intr, sc, sc->sc_dev.dv_xname); if (psc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); return; } sc->sc_dmat = pa->pa_dmat; psc->sc_pc = pc; /* * PCI Express check. */ if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, NULL, NULL)) sc->rl_flags |= RL_FLAG_PCIE; /* Call bus-independent attach routine */ if (re_attach(sc, intrstr)) { pci_intr_disestablish(pc, psc->sc_ih); bus_space_unmap(sc->rl_btag, sc->rl_bhandle, psc->sc_iosize); } }