void dnkbd_attach_subdevices(struct dnkbd_softc *sc) { struct wskbddev_attach_args ka; #if NWSMOUSE > 0 struct wsmousedev_attach_args ma; #endif #if NHILKBD > 0 extern int hil_is_console; #endif extern struct consdev wsdisplay_cons; /* * If both hilkbd and dnkbd are configured, prefer the Domain * keyboard as console (if we are here, we know the keyboard is * plugged), unless the console keyboard has been claimed already * (i.e. late hotplug with hil keyboard plugged first). */ if (cn_tab == &wsdisplay_cons) { #if NHILKBD > 0 if (hil_is_console == -1) { ka.console = 1; hil_is_console = 0; } else ka.console = 0; #else ka.console = 1; #endif } else ka.console = 0; ka.keymap = &dnkbd_keymapdata; ka.accessops = &dnkbd_accessops; ka.accesscookie = sc; #ifndef DKKBD_LAYOUT dnkbd_keymapdata.layout = sc->sc_layout; #endif if (ka.console) { sc->sc_flags = SF_PLUGGED | SF_CONSOLE | SF_ENABLED; wskbd_cnattach(&dnkbd_consops, sc, &dnkbd_keymapdata); } else { sc->sc_flags = SF_PLUGGED; } sc->sc_wskbddev = config_found_sm(&sc->sc_dev, &ka, wskbddevprint, dnsubmatch_kbd); #if NWSMOUSE > 0 ma.accessops = &dnmouse_accessops; ma.accesscookie = sc; sc->sc_wsmousedev = config_found_sm(&sc->sc_dev, &ma, wsmousedevprint, dnsubmatch_mouse); #endif SET(sc->sc_flags, SF_ATTACHED); }
/* * Attach the mainbus. */ void mainbus_attach(struct device *parent, struct device *self, void *aux) { struct mainbus_attach_args maa; printf(": Artesyn PM/PPC\n"); printf("%s: %sPCI bus Monarch\n", self->dv_xname, a_config.a_is_monarch ? "" : "not"); printf("%s: boot from %s, %sECC, %s L2 cache\n", self->dv_xname, a_config.a_boot_device == A_BOOT_ROM ? "ROM" : "flash", a_config.a_has_ecc ? "" : "no ", a_config.a_l2_cache == A_CACHE_PARITY ? "parity" : a_config.a_l2_cache == A_CACHE_NO_PARITY ? "no-parity" : "no"); maa.mb_bt = &pmppc_mem_tag; maa.mb_name = "cpu"; maa.mb_addr = MAINBUSCF_ADDR_DEFAULT; maa.mb_irq = MAINBUSCF_IRQ_DEFAULT; config_found(self, &maa, mainbus_print); if (a_config.a_has_rtc) { maa.mb_name = "rtc"; maa.mb_addr = PMPPC_RTC; maa.mb_irq = PMPPC_I_RTC_INT; config_found_sm(self, &maa, mainbus_print, mainbus_submatch); } if (a_config.a_has_eth) { maa.mb_name = "cs"; maa.mb_addr = PMPPC_CS_IO_BASE; maa.mb_irq = PMPPC_I_ETH_INT; config_found_sm(self, &maa, mainbus_print, mainbus_submatch); maa.mb_bt = &pmppc_mem_tag; } if (a_config.a_flash_width != 0) { maa.mb_name = "flash"; maa.mb_addr = PMPPC_FLASH_BASE; maa.mb_irq = MAINBUSCF_IRQ_DEFAULT; maa.u.mb_flash.size = a_config.a_flash_size; maa.u.mb_flash.width = a_config.a_flash_width; config_found_sm(self, &maa, mainbus_print, mainbus_submatch); } maa.mb_name = "cpc"; maa.mb_addr = MAINBUSCF_ADDR_DEFAULT; maa.mb_irq = MAINBUSCF_IRQ_DEFAULT; config_found(self, &maa, mainbus_print); }
STATIC void cardslotattach(struct device *parent, struct device *self, void *aux) { struct cardslot_softc *sc = (struct cardslot_softc *)self; struct cardslot_attach_args *caa = aux; struct cbslot_attach_args *cba = caa->caa_cb_attach; struct pcmciabus_attach_args *pa = caa->caa_16_attach; struct cardbus_softc *csc; struct pcmcia_softc *psc; sc->sc_slot = sc->sc_dev.dv_unit; sc->sc_cb_softc = NULL; sc->sc_16_softc = NULL; SIMPLEQ_INIT(&sc->sc_events); sc->sc_th_enable = 0; printf(" slot %d flags %x\n", sc->sc_slot, sc->sc_dev.dv_cfdata->cf_flags); DPRINTF(("%s attaching CardBus bus...\n", sc->sc_dev.dv_xname)); if (cba != NULL) { if ((csc = (void *)config_found(self, cba, cardslot_cb_print)) != NULL) { /* cardbus found */ DPRINTF(("cardslotattach: found cardbus on %s\n", sc->sc_dev.dv_xname)); sc->sc_cb_softc = csc; } } if (pa != NULL) { if ((psc = (void *)config_found_sm(self, pa, cardslot_16_print, cardslot_16_submatch)) != NULL) { /* pcmcia 16-bit bus found */ DPRINTF(("cardslotattach: found 16-bit pcmcia bus\n")); sc->sc_16_softc = psc; /* XXX: dirty. This code should be removed * to achieve MI */ caa->caa_ph->pcmcia = (struct device *)psc; } } if (csc != NULL || psc != NULL) kthread_create_deferred(create_slot_manager, (void *)sc); if (csc && (csc->sc_cf->cardbus_ctrl)(csc->sc_cc, CARDBUS_CD)) { DPRINTF(("cardslotattach: CardBus card found\n")); /* attach deferred */ cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_CB); } if (psc && (psc->pct->card_detect)(psc->pch)) { DPRINTF(("cardbusattach: 16-bit card found\n")); /* attach deferred */ cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_16); } }
void mpbios_cpu(const u_int8_t *ent, struct device *self) { const struct mpbios_proc *entry = (const struct mpbios_proc *)ent; struct device *mainbus = self->dv_parent->dv_parent; struct cpu_attach_args caa; /* XXX move this into the CPU attachment goo. */ /* check for usability */ if (!(entry->cpu_flags & PROCENTRY_FLAG_EN)) return; /* check for BSP flag */ if (entry->cpu_flags & PROCENTRY_FLAG_BP) caa.cpu_role = CPU_ROLE_BP; else { caa.cpu_role = CPU_ROLE_AP; ncpusfound++; } caa.caa_name = "cpu"; caa.cpu_number = entry->apic_id; #ifdef MULTIPROCESSOR caa.cpu_func = &mp_cpu_funcs; #endif config_found_sm(mainbus, &caa, mp_print, mp_match); }
int pckbc_attach_slot(struct pckbc_softc *sc, pckbc_slot_t slot, int force) { struct pckbc_internal *t = sc->id; struct pckbc_attach_args pa; int found; pa.pa_tag = t; pa.pa_slot = slot; found = (config_found_sm((struct device *)sc, &pa, pckbcprint, force ? pckbc_submatch_locators : pckbc_submatch) != NULL); if ((found || slot == PCKBC_AUX_SLOT) && !t->t_slotdata[slot]) { t->t_slotdata[slot] = malloc(sizeof(struct pckbc_slotdata), M_DEVBUF, M_NOWAIT); if (t->t_slotdata[slot] == NULL) return 0; pckbc_init_slotdata(t->t_slotdata[slot]); if (!found && slot == PCKBC_AUX_SLOT) { /* * Some machines don't handle disabling the aux slot * completely and still generate data when the mouse is * moved, so setup a dummy interrupt handler to discard * this slot's data. */ pckbc_set_inputhandler(t, PCKBC_AUX_SLOT, NULL, sc, NULL); found = 1; } } return (found); }
void iobusattach(struct device *parent, struct device *self, void *aux) { uint i; /* * Map and setup CRIME control registers. */ if (bus_space_map(&iobus_tag, OCTEON_CIU_BASE, OCTEON_CIU_SIZE, 0, &iobus_h)) { printf(": can't map CIU control registers\n"); return; } printf("\n"); octeon_intr_init(); /* * Attach subdevices. */ for (i = 0; i < nitems(iobus_children); i++) config_found_sm(self, iobus_children + i, iobusprint, iobussubmatch); }
void obioattach(struct device *parent, struct device *self, void *aux) { uint i; /* * Map and setup CRIME control registers. */ if (bus_space_map(&obio_tag, OCTEON_CIU_BASE, OCTEON_CIU_SIZE, 0, &obio_h)) { printf(": can't map CIU control registers\n"); return; } printf("\n"); obio_intr_init(); set_intr(INTPRI_CIU_0, CR_INT_0, obio_iointr); register_splx_handler(obio_splx); /* * Attach subdevices. */ for (i = 0; i < nitems(obio_children); i++) config_found_sm(self, obio_children + i, obioprint, obiosubmatch); }
void armv7_attach(struct device *parent, struct device *self, void *aux) { struct armv7_softc *sc = (struct armv7_softc *)self; struct board_dev *bd; sc->sc_board_devs = platform_board_devs(); if (hw_prod) printf(": %s\n", hw_prod); else printf(": UNKNOWN BOARD %u\n", board_id); /* Directly configure on-board devices (dev* in config file). */ for (bd = sc->sc_board_devs; bd->name != NULL; bd++) { struct armv7_dev *ad = armv7_find_dev(bd->name, bd->unit); struct armv7_attach_args aa; if (ad == NULL) { printf("%s: device %s unit %d not found\n", DEVNAME(sc), bd->name, bd->unit); continue; } memset(&aa, 0, sizeof(aa)); aa.aa_dev = ad; aa.aa_iot = &armv7_bs_tag; aa.aa_dmat = &armv7_bus_dma_tag; if (config_found_sm(self, &aa, NULL, armv7_submatch) == NULL) printf("%s: device %s unit %d not configured\n", DEVNAME(sc), bd->name, bd->unit); } }
void iobusattach(struct device *parent, struct device *self, void *aux) { struct octeon_config oc; uint i; /* * Map and setup CRIME control registers. */ if (bus_space_map(&iobus_tag, OCTEON_CIU_BASE, OCTEON_CIU_SIZE, 0, &iobus_h)) { printf(": can't map CIU control registers\n"); return; } printf("\n"); octeon_intr_init(); /* XXX */ oc.mc_iobus_bust = &iobus_tag; oc.mc_iobus_dmat = &iobus_bus_dma_tag; void cn30xxfpa_bootstrap(struct octeon_config *); cn30xxfpa_bootstrap(&oc); void cn30xxpow_bootstrap(struct octeon_config *); cn30xxpow_bootstrap(&oc); /* * Attach subdevices. */ for (i = 0; i < nitems(iobus_children); i++) config_found_sm(self, iobus_children + i, iobusprint, iobussubmatch); }
/* * Attach the peripheral bus. */ static void pbus_attach(struct device *parent, struct device *self, void *aux) { struct plb_attach_args *paa = aux; struct pbus_attach_args pba; int i; #if NPCKBC > 0 bus_space_handle_t ioh_fpga; bus_space_tag_t iot_fpga = &pbus_tag; uint8_t fpga_reg; #endif printf("\n"); if (bus_space_init(&pbus_tag, "pbus", NULL, 0)) panic("pbus_attach: can't init tag"); for (i = 0; pbus_devs[i].name != NULL; i++) { pba.pb_name = pbus_devs[i].name; pba.pb_addr = pbus_devs[i].addr; pba.pb_irq = pbus_devs[i].irq; pba.pb_bt = &pbus_tag; pba.pb_dmat = paa->plb_dmat; (void) config_found_sm(self, &pba, pbus_print, pbus_submatch); } #if NPCKBC > 0 /* Configure FPGA */ if (bus_space_map(iot_fpga, FPGA_BASE, FPGA_SIZE, 0, &ioh_fpga)) { printf("pbus_attach: can't map FPGA\n"); /* XXX - disable keyboard probe? */ } else { /* Use separate interrupts for keyboard and mouse */ fpga_reg = bus_space_read_1(iot_fpga, ioh_fpga, FPGA_BRDC); fpga_reg |= FPGA_BRDC_INT; bus_space_write_1(iot_fpga, ioh_fpga, FPGA_BRDC, fpga_reg); /* Set interrupts to active high */ fpga_reg = bus_space_read_1(iot_fpga, ioh_fpga, FPGA_INT_POL); fpga_reg |= (FPGA_IRQ_KYBD | FPGA_IRQ_MOUSE); bus_space_write_1(iot_fpga, ioh_fpga, FPGA_INT_POL, fpga_reg); /* Set interrupts to level triggered */ fpga_reg = bus_space_read_1(iot_fpga, ioh_fpga, FPGA_INT_TRIG); fpga_reg |= (FPGA_IRQ_KYBD | FPGA_IRQ_MOUSE); bus_space_write_1(iot_fpga, ioh_fpga, FPGA_INT_TRIG, fpga_reg); /* Enable interrupts */ fpga_reg = bus_space_read_1(iot_fpga, ioh_fpga, FPGA_INT_ENABLE); fpga_reg |= (FPGA_IRQ_KYBD | FPGA_IRQ_MOUSE); bus_space_write_1(iot_fpga, ioh_fpga, FPGA_INT_ENABLE, fpga_reg); bus_space_unmap(&iot_fpga, ioh_fpga, 2); } #endif }
void pxapcic_attach(struct pxapcic_softc *sc, void (*socket_setup_hook)(struct pxapcic_socket *)) { struct pcmciabus_attach_args paa; struct pxapcic_socket *so; int i; printf(": %d slot%s\n", sc->sc_nslots, sc->sc_nslots==1 ? "" : "s"); if (bus_space_map(sc->sc_iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &sc->sc_memctl_ioh)) { printf("%s: failed to map MEMCTL\n", sc->sc_dev.dv_xname); return; } /* Clear CIT (card present) and set NOS correctly. */ bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR, sc->sc_nslots == 2 ? MECR_NOS : 0); /* zaurus: configure slot 1 first to make internal drive be wd0. */ for (i = sc->sc_nslots-1; i >= 0; i--) { so = &sc->sc_socket[i]; so->sc = sc; so->socket = i; so->flags = 0; socket_setup_hook(so); paa.paa_busname = "pcmcia"; paa.pct = (pcmcia_chipset_tag_t)&pxapcic_pcmcia_functions; paa.pch = (pcmcia_chipset_handle_t)so; paa.iobase = 0; paa.iosize = 0x4000000; so->pcmcia = config_found_sm(&sc->sc_dev, &paa, pxapcic_print, pxapcic_submatch); pxa2x0_gpio_set_function(sc->sc_irqpin[i], GPIO_IN); pxa2x0_gpio_set_function(sc->sc_irqcfpin[i], GPIO_IN); /* Card slot interrupt */ so->irq = pxa2x0_gpio_intr_establish(sc->sc_irqcfpin[i], IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr, so, sc->sc_dev.dv_xname); /* GPIO pin for interrupt */ so->irqpin = sc->sc_irqpin[i]; #ifdef DO_CONFIG_PENDING config_pending_incr(); #endif kthread_create_deferred(pxapcic_create_event_thread, so); } }
void macebusattach(struct device *parent, struct device *self, void *aux) { u_int32_t creg; uint i; /* * Map and setup CRIME control registers. */ if (bus_space_map(&crimebus_tag, 0x00000000, 0x400, 0, &crime_h)) { printf(": can't map CRIME control registers\n"); return; } creg = bus_space_read_8(&crimebus_tag, crime_h, CRIME_REVISION); printf(": crime rev %d.%d\n", (creg & 0xf0) >> 4, creg & 0xf); bus_space_write_8(&crimebus_tag, crime_h, CRIME_CPU_ERROR_STAT, 0); bus_space_write_8(&crimebus_tag, crime_h, CRIME_MEM_ERROR_STAT, 0); bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, 0); bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_SOFT, 0); bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_HARD, 0); bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_STAT, 0); /* * Map and setup MACE ISA control registers. */ if (bus_space_map(&macebus_tag, MACE_ISA_OFFS, 0x400, 0, &mace_h)) { printf("%s: can't map MACE control registers\n", self->dv_xname); return; } bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_INT_MASK, 0); bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_INT_STAT, 0); /* * On O2 systems all interrupts are handled by the macebus interrupt * handler. Register all except clock. */ set_intr(INTPRI_MACEIO, CR_INT_0, macebus_iointr); register_splx_handler(macebus_splx); /* Set up a handler called when clock interrupts go off. */ set_intr(INTPRI_MACEAUX, CR_INT_5, macebus_aux); /* * Attach subdevices. */ for (i = 0; i < nitems(macebus_children); i++) config_found_sm(self, macebus_children + i, macebusprint, macebussubmatch); }
void puc_common_attach(struct puc_softc *sc, struct puc_attach_args *paa) { const struct puc_device_description *desc = sc->sc_desc; int i, bar; /* Configure each port. */ for (i = 0; i < PUC_MAX_PORTS; i++) { if (desc->ports[i].type == 0) /* neither com or lpt */ continue; /* make sure the base address register is mapped */ bar = PUC_PORT_BAR_INDEX(desc->ports[i].bar); if (!sc->sc_bar_mappings[bar].mapped) { printf("%s: %s port uses unmapped BAR (0x%x)\n", sc->sc_dev.dv_xname, puc_port_type_name(desc->ports[i].type), desc->ports[i].bar); continue; } /* set up to configure the child device */ paa->port = i; paa->a = sc->sc_bar_mappings[bar].a; paa->t = sc->sc_bar_mappings[bar].t; paa->type = desc->ports[i].type; if (desc->ports[i].offset >= sc->sc_bar_mappings[bar].s || bus_space_subregion(sc->sc_bar_mappings[bar].t, sc->sc_bar_mappings[bar].h, desc->ports[i].offset, sc->sc_bar_mappings[bar].s - desc->ports[i].offset, &paa->h)) { printf("%s: couldn't get subregion for port %d\n", sc->sc_dev.dv_xname, i); continue; } #if 0 if (autoconf_verbose) printf("%s: port %d: %s @ (index %d) 0x%x " "(0x%lx, 0x%lx)\n", sc->sc_dev.dv_xname, paa->port, puc_port_type_name(paa->type), bar, (int)paa->a, (long)paa->t, (long)paa->h); #endif /* and configure it */ sc->sc_ports[i].dev = config_found_sm(&sc->sc_dev, paa, puc_print, puc_submatch); } }
void xbow_enumerate(struct device *self, int skip, int (*sm)(struct device *, void *, void *), cfprint_t print) { int16_t nasid = 0; /* XXX for now... */ struct xbow_attach_args xaa; int widget; uint32_t wid; for (widget = 8; widget <= 15; widget++) { struct mips_bus_space *bs, *bl; if (widget == skip) continue; if (xbow_widget_id(nasid, widget, &wid) != 0) continue; /* * Build a pair of bus_space_t suitable for this widget. */ bs = malloc(sizeof (*bs), M_DEVBUF, M_NOWAIT); if (bs == NULL) continue; bl = malloc(sizeof (*bl), M_DEVBUF, M_NOWAIT); if (bl == NULL) { free(bs, M_DEVBUF); continue; } xbow_build_bus_space(bs, nasid, widget, 0); xbow_build_bus_space(bl, nasid, widget, 1); xaa.xaa_widget = widget; xaa.xaa_vendor = (wid & WIDGET_ID_VENDOR_MASK) >> WIDGET_ID_VENDOR_SHIFT; xaa.xaa_product = (wid & WIDGET_ID_PRODUCT_MASK) >> WIDGET_ID_PRODUCT_SHIFT; xaa.xaa_revision = (wid & WIDGET_ID_REV_MASK) >> WIDGET_ID_REV_SHIFT; xaa.xaa_short_tag = bs; xaa.xaa_long_tag = bl; if (config_found_sm(self, &xaa, print, sm) == NULL) { /* nothing attached, no need to keep the bus_space */ free(bs, M_DEVBUF); free(bl, M_DEVBUF); } } }
void combusattach(struct device *parent, struct device *self, void *aux) { uint i; printf("\n"); /* * Attach subdevices. */ for (i = 0; i < nitems(combus_children); i++) config_found_sm(self, combus_children + i, combusprint, combussubmatch); }
static void gsc_module_callback(struct device *self, struct confargs *ca) { struct gsc_softc *sc = (struct gsc_softc *)self; struct gsc_attach_args ga; /* Make the GSC attach args. */ ga = sc->sc_ga; ga.ga_ca = *ca; ga.ga_iot = sc->sc_ga.ga_iot; ga.ga_dmatag = sc->sc_ga.ga_dmatag; (*sc->sc_ga.ga_fix_args)(sc->sc_ga.ga_fix_args_cookie, &ga); config_found_sm(self, &ga, mbprint, mbsubmatch); }
static void sbobio_attach(struct device *parent, struct device *self, void *aux) { struct sbobio_attach_args sa; int i; printf("\n"); for (i = 0; i < sb1250_sbobio_dev_count; i++) { memset(&sa, 0, sizeof sa); sa.sa_base = 0x10060000; /* XXXCGD */ sa.sa_locs = sb1250_sbobio_devs[i]; config_found_sm(self, &sa, sbobio_print, sbobio_submatch); } return; }
void mpbios_cpu(const u_int8_t *ent, struct device *self) { const struct mpbios_proc *entry = (const struct mpbios_proc *)ent; struct device *mainbus = self->dv_parent->dv_parent; struct cpu_attach_args caa; /* XXX move this into the CPU attachment goo. */ /* check for usability */ if (!(entry->cpu_flags & PROCENTRY_FLAG_EN)) return; /* check for BSP flag */ if (entry->cpu_flags & PROCENTRY_FLAG_BP) caa.cpu_role = CPU_ROLE_BP; else { caa.cpu_role = CPU_ROLE_AP; ncpusfound++; } caa.caa_name = "cpu"; caa.cpu_number = entry->apic_id; #ifdef MULTIPROCESSOR caa.cpu_func = &mp_cpu_funcs; #endif #if 1 /* XXX Will be removed when the real stuff is probed */ caa.cpu_signature = entry->cpu_signature; /* * XXX this is truncated to just contain the low-order 16 bits * of the flags on at least some MP bioses */ caa.feature_flags = entry->feature_flags; /* * XXX some MP bioses don't specify a valid CPU signature; use * the result of the 'cpuid' instruction for the processor * we're running on */ if ((caa.cpu_signature & 0x00000fff) == 0) { caa.cpu_signature = cpu_id; caa.feature_flags = cpu_feature; } #endif config_found_sm(mainbus, &caa, mp_print, mp_match); }
void iof_attach_child(struct device *iof, const char *name, bus_addr_t base, uint dev) { struct iof_softc *sc = (struct iof_softc *)iof; struct iof_attach_args iaa; iaa.iaa_name = name; pci_get_device_location(sc->sc_pc, sc->sc_tag, &iaa.iaa_location); iaa.iaa_memt = sc->sc_memt; iaa.iaa_memh = sc->sc_memh; iaa.iaa_dmat = sc->sc_dmat; iaa.iaa_base = base; iaa.iaa_dev = dev; iaa.iaa_clock = sc->sc_mcr & IOC4_MCR_PCI_66MHZ ? 66666667 : 33333333; config_found_sm(iof, &iaa, iof_print, iof_search); }
static void zbbus_attach(struct device *parent, struct device *self, void *aux) { struct zbbus_attach_args za; int i; printf("\n"); zbbus_attached = 1; sb1250_icu_init(); for (i = 0; i < sb1250_zbbus_dev_count; i++) { memset(&za, 0, sizeof za); za.za_locs = sb1250_zbbus_devs[i]; config_found_sm(self, &za, zbbus_print, zbbus_submatch); } return; }
static void smbus_attach(struct device *parent, struct device *self, void *aux) { struct smbus_attach_args sa; int i; found++; printf("\n"); for (i = 0; i < smbus_dev_count; i++) { if (self->dv_unit != smbus_devs[i].sa_interface) continue; memset(&sa, 0, sizeof sa); sa.sa_interface = smbus_devs[i].sa_interface; sa.sa_device = smbus_devs[i].sa_device; config_found_sm(self, &sa, smbus_print, smbus_submatch); } }
void mpbios_cpu(const u_int8_t *ent, struct device *self) { const struct mpbios_proc *entry = (const struct mpbios_proc *)ent; struct cpu_attach_args caa; /* XXX move this into the CPU attachment goo. */ /* check for usability */ if (!(entry->cpu_flags & PROCENTRY_FLAG_EN)) return; /* check for BSP flag */ if (entry->cpu_flags & PROCENTRY_FLAG_BP) caa.cpu_role = CPU_ROLE_BP; else caa.cpu_role = CPU_ROLE_AP; caa.caa_name = "cpu"; caa.cpu_number = entry->apic_id; caa.cpu_func = &mp_cpu_funcs; config_found_sm(self, &caa, mp_print, mp_match); }
/* * Called after the loop has reconfigured. Here we need to: * - determine how many devices are on the loop * (some may have been added or removed) * - make sure all keyboards are in raw mode * * Note that our device state is now potentially invalid as * devices may no longer be where they were. What we should * do here is either track where the devices went and move * state around accordingly... * * Note that it is necessary that we operate the loop with the keyboards * in raw mode: they won't cause the loop to generate an NMI if the * ``reset'' key combination is pressed, and we do not handle the hil * NMI interrupt... */ void hilconfig(struct hil_softc *sc, u_int knowndevs) { struct hil_attach_args ha; u_int8_t db; int id, s; s = splhil(); /* * Determine how many devices are on the loop. */ db = 0; send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db); sc->sc_maxdev = db & LPS_DEVMASK; #ifdef HILDEBUG printf("%s: %d device(s)\n", sc->sc_dev.dv_xname, sc->sc_maxdev); #endif /* * Put all keyboards in raw mode now. */ db = 0; send_hil_cmd(sc, HIL_WRITEKBDSADR, &db, 1, NULL); /* * If the loop grew, attach new devices. */ for (id = knowndevs + 1; id <= sc->sc_maxdev; id++) { int len; const struct hildevice *hd; if (send_device_cmd(sc, id, HIL_IDENTIFY) != 0) { printf("%s: no answer from device %d\n", sc->sc_dev.dv_xname, id); continue; } len = sc->sc_cmdbp - sc->sc_cmdbuf; if (len == 0) { #ifdef HILDEBUG printf("%s: no device at code %d\n", sc->sc_dev.dv_xname, id); #endif continue; } /* Identify and attach device */ for (hd = hildevs; hd->minid >= 0; hd++) if (sc->sc_cmdbuf[0] >= hd->minid && sc->sc_cmdbuf[0] <= hd->maxid) { ha.ha_console = *sc->sc_console; ha.ha_code = id; ha.ha_type = hd->type; ha.ha_descr = hd->descr; ha.ha_infolen = len; bcopy(sc->sc_cmdbuf, ha.ha_info, len); sc->sc_devices[id] = (struct hildev_softc *) config_found_sm(&sc->sc_dev, &ha, hildevprint, hilsubmatch); #if NHILKBD > 0 /* * If we just attached a keyboard as console, * console choice is not indeterminate anymore. */ if (sc->sc_devices[id] != NULL && ha.ha_type == HIL_DEVICE_KEYBOARD && ha.ha_console != 0) *sc->sc_console = 1; #endif } } /* * Detach remaining devices, if the loop has shrunk. */ for (id = sc->sc_maxdev + 1; id < NHILD; id++) { if (sc->sc_devices[id] != NULL) config_detach((struct device *)sc->sc_devices[id], DETACH_FORCE); sc->sc_devices[id] = NULL; } sc->sc_cmdbp = sc->sc_cmdbuf; splx(s); }
void uftdi_attach(struct device *parent, struct device *self, void *aux) { struct uftdi_softc *sc = (struct uftdi_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; struct usbd_interface *iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devname = sc->sc_dev.dv_xname; int i; usbd_status err; struct ucom_attach_args uca; DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc)); sc->sc_udev = dev; if (uaa->iface == NULL) { /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration, err=%s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); goto bad; } err = usbd_device2interface_handle(dev, UFTDI_IFACE_INDEX, &iface); if (err) { printf("%s: failed to get interface, err=%s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); goto bad; } } else iface = uaa->iface; id = usbd_get_interface_descriptor(iface); sc->sc_iface = iface; if (uaa->release < 0x0200) { sc->sc_type = UFTDI_TYPE_SIO; sc->sc_hdrlen = 1; } else if (uaa->release == 0x0700 || uaa->release == 0x0800) { sc->sc_type = UFTDI_TYPE_2232H; sc->sc_hdrlen = 0; } else { sc->sc_type = UFTDI_TYPE_8U232AM; sc->sc_hdrlen = 0; } uca.bulkin = uca.bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { int addr, dir, attr; ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { printf("%s: could not read endpoint descriptor\n", devname); goto bad; } addr = ed->bEndpointAddress; dir = UE_GET_DIR(ed->bEndpointAddress); attr = ed->bmAttributes & UE_XFERTYPE; if (dir == UE_DIR_IN && attr == UE_BULK) { uca.bulkin = addr; uca.ibufsize = (UGETW(ed->wMaxPacketSize) > 0) ? UGETW(ed->wMaxPacketSize) : UFTDIIBUFSIZE; } else if (dir == UE_DIR_OUT && attr == UE_BULK) { uca.bulkout = addr; uca.obufsize = (UGETW(ed->wMaxPacketSize) > 0) ? UGETW(ed->wMaxPacketSize) : UFTDIOBUFSIZE; uca.obufsize-= sc->sc_hdrlen; } else { printf("%s: unexpected endpoint\n", devname); goto bad; } } if (uca.bulkin == -1) { printf("%s: Could not find data bulk in\n", sc->sc_dev.dv_xname); goto bad; } if (uca.bulkout == -1) { printf("%s: Could not find data bulk out\n", sc->sc_dev.dv_xname); goto bad; } if (uaa->iface == NULL) uca.portno = FTDI_PIT_SIOA; else uca.portno = FTDI_PIT_SIOA + id->bInterfaceNumber; /* bulkin, bulkout set above */ uca.ibufsizepad = uca.ibufsize; uca.opkthdrlen = sc->sc_hdrlen; uca.device = dev; uca.iface = iface; uca.methods = &uftdi_methods; uca.arg = sc; uca.info = NULL; DPRINTF(("uftdi: in=0x%x out=0x%x\n", uca.bulkin, uca.bulkout)); sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); return; bad: DPRINTF(("uftdi_attach: ATTACH ERROR\n")); usbd_deactivate(sc->sc_udev); }
void armv7_attach(struct device *parent, struct device *self, void *aux) { struct armv7_softc *sc = (struct armv7_softc *)self; struct board_dev *bd; uint32_t issunxi = 0; bus_space_handle_t ioh; switch (board_id) { #if NEXYNOS > 0 case BOARD_ID_EXYNOS5_CHROMEBOOK: printf(": Exynos 5 Chromebook\n"); exynos5_init(); sc->sc_board_devs = chromebook_devs; break; #endif #if NIMX > 0 case BOARD_ID_IMX6_HUMMINGBOARD: printf(": SolidRun HummingBoard\n"); imx6_init(); sc->sc_board_devs = hummingboard_devs; break; case BOARD_ID_IMX6_SABRELITE: printf(": i.MX6 SABRE Lite\n"); imx6_init(); sc->sc_board_devs = sabrelite_devs; break; case BOARD_ID_IMX6_UDOO: printf(": i.MX6 UDOO\n"); imx6_init(); sc->sc_board_devs = udoo_devs; break; case BOARD_ID_IMX6_UTILITE: printf(": i.MX6 Utilite\n"); imx6_init(); sc->sc_board_devs = utilite_devs; break; case BOARD_ID_IMX6_WANDBOARD: printf(": i.MX6 Wandboard\n"); imx6_init(); sc->sc_board_devs = wandboard_devs; break; #endif #if NOMAP > 0 case BOARD_ID_OMAP3_BEAGLE: printf(": BeagleBoard\n"); omap3_init(); sc->sc_board_devs = beagleboard_devs; break; case BOARD_ID_AM335X_BEAGLEBONE: printf(": BeagleBone\n"); am335x_init(); sc->sc_board_devs = beaglebone_devs; break; case BOARD_ID_OMAP3_OVERO: printf(": Gumstix Overo\n"); omap3_init(); sc->sc_board_devs = overo_devs; break; case BOARD_ID_OMAP4_PANDA: printf(": PandaBoard\n"); omap4_init(); sc->sc_board_devs = pandaboard_devs; break; #endif #if NSUNXI > 0 case BOARD_ID_SUN4I_A10: printf(": A1X\n"); sxia1x_init(); sc->sc_board_devs = sun4i_devs; issunxi = 1; break; case BOARD_ID_SUN7I_A20: printf(": A20\n"); sxia20_init(); sc->sc_board_devs = sun7i_devs; issunxi = 1; break; #endif default: printf("\n"); panic("%s: board type 0x%x unknown", __func__, board_id); } if (issunxi) { /* * XXX think of a better place to do this, as there might * be need for access by other drivers later. */ if (bus_space_map(&armv7_bs_tag, SYSCTRL_ADDR, SYSCTRL_SIZE, 0, &ioh)) panic("sunxi_attach: bus_space_map failed!"); /* map the part of SRAM dedicated to EMAC to EMAC */ bus_space_write_4(&armv7_bs_tag, ioh, 4, bus_space_read_4(&armv7_bs_tag, ioh, 4) | (5 << 2)); } /* Directly configure on-board devices (dev* in config file). */ for (bd = sc->sc_board_devs; bd->name != NULL; bd++) { struct armv7_dev *ad = armv7_find_dev(bd->name, bd->unit); struct armv7_attach_args aa; if (ad == NULL) { printf("%s: device %s unit %d not found\n", DEVNAME(sc), bd->name, bd->unit); continue; } memset(&aa, 0, sizeof(aa)); aa.aa_dev = ad; aa.aa_iot = &armv7_bs_tag; aa.aa_dmat = &armv7_bus_dma_tag; if (config_found_sm(self, &aa, NULL, armv7_submatch) == NULL) printf("%s: device %s unit %d not configured\n", DEVNAME(sc), bd->name, bd->unit); } }
void gio_attach(struct device *parent, struct device *self, void *aux) { struct gio_softc *sc = (struct gio_softc *)self; struct imc_attach_args *iaa = (struct imc_attach_args *)aux; struct gio_attach_args ga; uint32_t gfx[GIO_MAX_FB], id; uint i, j, ngfx; int sys_type; printf("\n"); sc->sc_iot = iaa->iaa_st; sc->sc_dmat = iaa->iaa_dmat; switch (sys_config.system_type) { case SGI_IP20: sys_type = SGI_IP20; break; default: case SGI_IP22: case SGI_IP26: case SGI_IP28: sys_type = SGI_IP22; break; } ngfx = 0; memset(gfx, 0, sizeof(gfx)); /* * Try and attach graphics devices first. * Unfortunately, they - not being GIO devices after all - do not * contain a Product Identification Word, nor have a slot number. * * Record addresses to which graphics devices attach so that * we do not confuse them with expansion slots, should the * addresses coincide. * * If only the ARCBios component tree would be so kind as to give * us the address of the frame buffer components... */ if (sys_type != SGI_IP22 || sys_config.system_subtype != IP22_CHALLS) { for (i = 0; gfx_bases[i].base != 0; i++) { /* skip slots that don't apply to us */ if (gfx_bases[i].mach_type != sys_type) continue; if (gfx_bases[i].mach_subtype != -1 && gfx_bases[i].mach_subtype != sys_config.system_subtype) continue; ga.ga_addr = gfx_bases[i].base; ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC); /* no need to probe a glass console again */ if (ga.ga_addr == giofb_consaddr && giofb_consid != 0) id = giofb_consid; else { id = gio_id(ga.ga_ioh, ga.ga_addr, 1); if (!gio_is_framebuffer_id(id)) continue; } ga.ga_iot = sc->sc_iot; ga.ga_dmat = sc->sc_dmat; ga.ga_slot = -1; ga.ga_product = id; /* * Note that this relies upon ARCBios listing frame * buffers in ascending address order, which seems * to be the case so far on multihead Indigo2 systems. */ if (ngfx < GIO_MAX_FB) ga.ga_descr = giofb_names[ngfx]; else ga.ga_descr = NULL; /* shouldn't happen */ if (config_found_sm(self, &ga, gio_print_fb, gio_submatch)) gfx[ngfx] = gfx_bases[i].base; ngfx++; } } /* * Now attach any GIO expansion cards. * * Be sure to skip any addresses to which a graphics device has * already been attached. */ for (i = 0; slot_bases[i].base != 0; i++) { int skip = 0; /* skip slots that don't apply to us */ if (slot_bases[i].mach_type != sys_type) continue; if (slot_bases[i].mach_subtype != -1 && slot_bases[i].mach_subtype != sys_config.system_subtype) continue; for (j = 0; j < ngfx; j++) { if (slot_bases[i].base == gfx[j]) { skip = 1; break; } } if (skip) continue; ga.ga_addr = slot_bases[i].base; ga.ga_iot = sc->sc_iot; ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC); id = gio_id(ga.ga_ioh, ga.ga_addr, 0); if (id == 0) continue; ga.ga_dmat = sc->sc_dmat; ga.ga_slot = slot_bases[i].slot; ga.ga_product = id; ga.ga_descr = NULL; config_found_sm(self, &ga, gio_print, gio_submatch); } config_search(gio_search, self, aux); }
void umct_attach(struct device *parent, struct device *self, void *aux) { struct umct_softc *sc = (struct umct_softc *)self; struct usb_attach_arg *uaa = aux; usbd_device_handle dev = uaa->device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devname = sc->sc_dev.dv_xname; usbd_status err; int i; struct ucom_attach_args uca; sc->sc_udev = dev; sc->sc_product = uaa->product; DPRINTF(("\n\numct attach: sc=%p\n", sc)); /* initialize endpoints */ uca.bulkin = uca.bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1); if (err) { printf("\n%s: failed to set configuration, err=%s\n", devname, usbd_errstr(err)); sc->sc_dying = 1; return; } /* get the config descriptor */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } /* get the interface */ err = usbd_device2interface_handle(dev, UMCT_IFACE_INDEX, &sc->sc_iface); if (err) { printf("\n%s: failed to get interface, err=%s\n", devname, usbd_errstr(err)); sc->sc_dying = 1; return; } /* Find the bulk{in,out} and interrupt endpoints */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); sc->sc_dying = 1; return; } /* * The Bulkin endpoint is marked as an interrupt. Since * we can't rely on the endpoint descriptor order, we'll * check the wMaxPacketSize field to differentiate. */ if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT && UGETW(ed->wMaxPacketSize) != 0x2) { uca.bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; sc->sc_isize = UGETW(ed->wMaxPacketSize); } } if (uca.bulkin == -1) { printf("%s: Could not find data bulk in\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } if (uca.bulkout == -1) { printf("%s: Could not find data bulk out\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } if (sc->sc_intr_number== -1) { printf("%s: Could not find interrupt in\n", sc->sc_dev.dv_xname); sc->sc_dying = 1; return; } sc->sc_dtr = sc->sc_rts = 0; uca.portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ uca.ibufsize = UMCTIBUFSIZE; if (sc->sc_product == USB_PRODUCT_MCT_SITECOM_USB232) uca.obufsize = 16; /* device is broken */ else uca.obufsize = UMCTOBUFSIZE; uca.ibufsizepad = UMCTIBUFSIZE; uca.opkthdrlen = 0; uca.device = dev; uca.iface = sc->sc_iface; uca.methods = &umct_methods; uca.arg = sc; uca.info = NULL; umct_init(sc); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, &sc->sc_dev); DPRINTF(("umct: in=0x%x out=0x%x intr=0x%x\n", uca.bulkin, uca.bulkout, sc->sc_intr_number )); sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); }
void ubsa_attach(struct device *parent, struct device *self, void *aux) { struct ubsa_softc *sc = (struct ubsa_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; const char *devname = sc->sc_dev.dv_xname; usbd_status err; struct ucom_attach_args uca; int i; sc->sc_udev = dev; /* * initialize rts, dtr variables to something * different from boolean 0, 1 */ sc->sc_dtr = -1; sc->sc_rts = -1; DPRINTF(("ubsa attach: sc = %p\n", sc)); /* initialize endpoints */ uca.bulkin = uca.bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UBSA_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", devname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); goto error; } /* get the config descriptor */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", devname); usbd_deactivate(sc->sc_udev); goto error; } /* get the first interface */ err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX, &sc->sc_iface); if (err) { printf("%s: failed to get interface: %s\n", devname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); goto error; } /* Find the endpoints */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); goto error; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; sc->sc_isize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkin = ed->bEndpointAddress; uca.ibufsize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; uca.obufsize = UGETW(ed->wMaxPacketSize); } } if (sc->sc_intr_number == -1) { printf("%s: Could not find interrupt in\n", devname); usbd_deactivate(sc->sc_udev); goto error; } if (uca.bulkin == -1) { printf("%s: Could not find data bulk in\n", devname); usbd_deactivate(sc->sc_udev); goto error; } if (uca.bulkout == -1) { printf("%s: Could not find data bulk out\n", devname); usbd_deactivate(sc->sc_udev); goto error; } uca.portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ uca.ibufsizepad = uca.ibufsize; uca.opkthdrlen = 0; uca.device = dev; uca.iface = sc->sc_iface; uca.methods = &ubsa_methods; uca.arg = sc; uca.info = NULL; DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n", uca.bulkin, uca.bulkout, sc->sc_intr_number)); sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); error: return; }
void uticom_attach_hook(void *arg) { struct uticom_softc *sc = arg; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_status err; int status, i; usb_device_descriptor_t *dd; struct ucom_attach_args uca; /* Initialize endpoints. */ uca.bulkin = uca.bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; dd = usbd_get_device_descriptor(sc->sc_udev); DPRINTF(("%s: uticom_attach: num of configurations %d\n", sc->sc_dev.dv_xname, dd->bNumConfigurations)); /* The device without firmware has single configuration with single * bulk out interface. */ if (dd->bNumConfigurations > 1) goto fwload_done; /* Loading firmware. */ DPRINTF(("%s: uticom_attach: starting loading firmware\n", sc->sc_dev.dv_xname)); err = usbd_set_config_index(sc->sc_udev, UTICOM_CONFIG_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Get the config descriptor. */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } err = usbd_device2interface_handle(sc->sc_udev, UTICOM_IFACE_INDEX, &sc->sc_iface); if (err) { printf("%s: failed to get interface: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Find the bulk out interface used to upload firmware. */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; DPRINTF(("%s: uticom_attach: data bulk out num: %d\n", sc->sc_dev.dv_xname, ed->bEndpointAddress)); } if (uca.bulkout == -1) { printf("%s: could not find data bulk out\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } } status = uticom_download_fw(sc, uca.bulkout, sc->sc_udev); if (status) { printf("%s: firmware download failed\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } else { DPRINTF(("%s: firmware download succeeded\n", sc->sc_dev.dv_xname)); } status = usbd_reload_device_desc(sc->sc_udev); if (status) { printf("%s: error reloading device descriptor\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } fwload_done: dd = usbd_get_device_descriptor(sc->sc_udev); DPRINTF(("%s: uticom_attach: num of configurations %d\n", sc->sc_dev.dv_xname, dd->bNumConfigurations)); err = usbd_set_config_index(sc->sc_udev, UTICOM_ACTIVE_INDEX, 1); if (err) { printf("%s: failed to set configuration: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Get the config descriptor. */ cdesc = usbd_get_config_descriptor(sc->sc_udev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } /* Get the interface (XXX: multiport chips are not supported yet). */ err = usbd_device2interface_handle(sc->sc_udev, UTICOM_IFACE_INDEX, &sc->sc_iface); if (err) { printf("%s: failed to get interface: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } /* Find the interrupt endpoints. */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; sc->sc_isize = UGETW(ed->wMaxPacketSize); } } if (sc->sc_intr_number == -1) { printf("%s: could not find interrupt in\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } /* Keep interface for interrupt. */ sc->sc_intr_iface = sc->sc_iface; /* Find the bulk{in,out} endpoints. */ id = usbd_get_interface_descriptor(sc->sc_iface); sc->sc_iface_number = id->bInterfaceNumber; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { uca.bulkout = ed->bEndpointAddress; } } if (uca.bulkin == -1) { printf("%s: could not find data bulk in\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } if (uca.bulkout == -1) { printf("%s: could not find data bulk out\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } sc->sc_dtr = sc->sc_rts = -1; uca.portno = UCOM_UNK_PORTNO; uca.ibufsize = UTICOM_IBUFSZ; uca.obufsize = UTICOM_OBUFSZ; uca.ibufsizepad = UTICOM_IBUFSZ; uca.device = sc->sc_udev; uca.iface = sc->sc_iface; uca.opkthdrlen = 0; uca.methods = &uticom_methods; uca.arg = sc; uca.info = NULL; err = uticom_reset(sc); if (err) { printf("%s: reset failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); usbd_deactivate(sc->sc_udev); return; } DPRINTF(("%s: uticom_attach: in = 0x%x, out = 0x%x, intr = 0x%x\n", sc->sc_dev.dv_xname, uca.bulkin, uca.bulkout, sc->sc_intr_number)); sc->sc_subdev = config_found_sm((struct device *)sc, &uca, ucomprint, ucomsubmatch); }
void umsm_attach(struct device *parent, struct device *self, void *aux) { struct umsm_softc *sc = (struct umsm_softc *)self; struct usb_attach_arg *uaa = aux; struct ucom_attach_args uca; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; bzero(&uca, sizeof(uca)); sc->sc_udev = uaa->device; sc->sc_iface = uaa->iface; sc->sc_flag = umsm_lookup(uaa->vendor, uaa->product)->umsm_flag; id = usbd_get_interface_descriptor(sc->sc_iface); /* * Some 3G modems have multiple interfaces and some of them * are umass class. Don't claim ownership in such case. */ if (id == NULL || id->bInterfaceClass == UICLASS_MASS) { /* * Some 3G modems require a special request to * enable their modem function. */ if ((sc->sc_flag & DEV_HUAWEI) && uaa->ifaceno == 0) { umsm_huawei_changemode(uaa->device); printf("%s: umass only mode. need to reattach\n", sc->sc_dev.dv_xname); } else if ((sc->sc_flag & DEV_TRUINSTALL) && uaa->ifaceno == 0) { umsm_truinstall_changemode(uaa->device); printf("%s: truinstall mode. need to reattach\n", sc->sc_dev.dv_xname); } else if ((sc->sc_flag & DEV_UMASS) && uaa->ifaceno == 0) { umsm_umass_changemode(sc); } /* * The device will reset its own bus from the device side * when its mode was changed, so just return. */ return; } sc->sc_iface_no = id->bInterfaceNumber; uca.bulkin = uca.bulkout = -1; sc->sc_intr_number = sc->sc_isize = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { printf("%s: no endpoint descriptor found for %d\n", sc->sc_dev.dv_xname, i); usbd_deactivate(sc->sc_udev); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; sc->sc_isize = UGETW(ed->wMaxPacketSize); DPRINTF(("%s: find interrupt endpoint for %s\n", __func__, sc->sc_dev.dv_xname)); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) uca.bulkin = ed->bEndpointAddress; else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) uca.bulkout = ed->bEndpointAddress; } if (uca.bulkin == -1 || uca.bulkout == -1) { printf("%s: missing endpoint\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } sc->sc_dtr = sc->sc_rts = -1; /* We need to force size as some devices lie */ uca.ibufsize = UMSMBUFSZ; uca.obufsize = UMSMBUFSZ; uca.ibufsizepad = UMSMBUFSZ; uca.opkthdrlen = 0; uca.device = sc->sc_udev; uca.iface = sc->sc_iface; uca.methods = &umsm_methods; uca.arg = sc; uca.info = NULL; uca.portno = UCOM_UNK_PORTNO; sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); }