Beispiel #1
0
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);
}
Beispiel #2
0
/*
 * 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);
}
Beispiel #3
0
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);
	}
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
}
Beispiel #10
0
/*
 * 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

}
Beispiel #11
0
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);
	}
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
	}
}
Beispiel #14
0
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);
        }
    }
}
Beispiel #15
0
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);
}
Beispiel #16
0
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);
}
Beispiel #17
0
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;
}
Beispiel #18
0
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);
}
Beispiel #19
0
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);
}
Beispiel #20
0
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;
}
Beispiel #21
0
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);
	}
}
Beispiel #22
0
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);
}
Beispiel #23
0
/*
 * 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);
}
Beispiel #24
0
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);
}
Beispiel #25
0
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);
	}
}
Beispiel #26
0
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);
}
Beispiel #27
0
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);
}
Beispiel #28
0
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;
}
Beispiel #29
0
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);
}
Beispiel #30
0
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);
}