예제 #1
0
static int
tun_clone_create(struct if_clone *ifc, int unit)
{
	struct tun_softc *tp;

	if ((tp = tun_find_zunit(unit)) == NULL) {
		/* Allocate a new instance */
		tp = malloc(sizeof(*tp), M_DEVBUF, M_WAITOK|M_ZERO);

		tp->tun_unit = unit;
		mutex_init(&tp->tun_lock, MUTEX_DEFAULT, IPL_NET);
		selinit(&tp->tun_rsel);
		selinit(&tp->tun_wsel);
	} else {
		/* Revive tunnel instance; clear ifp part */
		(void)memset(&tp->tun_if, 0, sizeof(struct ifnet));
	}

	if_initname(&tp->tun_if, ifc->ifc_name, unit);
	tunattach0(tp);
	tp->tun_flags |= TUN_INITED;
	tp->tun_osih = softint_establish(SOFTINT_CLOCK, tun_o_softintr, tp);
	tp->tun_isih = softint_establish(SOFTINT_CLOCK, tun_i_softintr, tp);

	simple_lock(&tun_softc_lock);
	LIST_INSERT_HEAD(&tun_softc_list, tp, tun_list);
	simple_unlock(&tun_softc_lock);

	return (0);
}
예제 #2
0
void
mgnscattach(device_t parent, device_t self, void *aux)
{
	struct siop_softc *sc = device_private(self);
	struct zbus_args *zap;
	siop_regmap_p rp;
	struct scsipi_adapter *adapt = &sc->sc_adapter;
	struct scsipi_channel *chan = &sc->sc_channel;

	sc->sc_dev = self;

	printf("\n");
	zap = aux;

	sc->sc_siopp = rp = (siop_regmap_p)((char *)zap->va + 0x8000);

	/*
	 * CTEST7 = TT1
	 */
	sc->sc_clock_freq = 33;		/* Clock = 33 MHz */
	sc->sc_ctest7 = SIOP_CTEST7_TT1;
	sc->sc_dcntl = 0x00;

	sc->sc_siop_si = softint_establish(SOFTINT_BIO,
	    (void (*)(void *))siopintr, sc);

	/*
	 * Fill in the scsipi_adapter.
	 */
	memset(adapt, 0, sizeof(*adapt));
	adapt->adapt_dev = self;
	adapt->adapt_nchannels = 1;
	adapt->adapt_openings = 7;
	adapt->adapt_max_periph = 1;
	adapt->adapt_request = siop_scsipi_request;
	adapt->adapt_minphys = siop_minphys;

	/*
	 * Fill in the scsipi_channel.
	 */
	memset(chan, 0, sizeof(*chan));
	chan->chan_adapter = adapt;
	chan->chan_bustype = &scsi_bustype;
	chan->chan_channel = 0;
	chan->chan_ntargets = 8;
	chan->chan_nluns = 8;
	chan->chan_id = 7;

	siopinitialize(sc);

	sc->sc_isr.isr_intr = mgnsc_dmaintr;
	sc->sc_isr.isr_arg = sc;
	sc->sc_isr.isr_ipl = 6;
	add_isr (&sc->sc_isr);

	/*
	 * attach all scsi units on us
	 */
	config_found(self, chan, scsiprint);
}
예제 #3
0
int
testcall(struct lwp *l, void *uap, register_t *retval)
{

	printf("test: initializing\n");

	mutex_init(&test_mutex, MUTEX_DEFAULT, IPL_NONE);
	cv_init(&test_cv, "testcv");
	test_sih = softint_establish(SOFTINT_MPSAFE | SOFTINT_SERIAL,
	    test_softint, NULL);
	callout_init(&test_ch, CALLOUT_MPSAFE);
	callout_setfunc(&test_ch, test_callout, NULL);

	printf("test: firing\n");
	callout_schedule(&test_ch, hz / 10);

	printf("test: waiting\n");
	mutex_enter(&test_mutex);
	while (!test_done) {
		cv_wait(&test_cv, &test_mutex);
	}
	mutex_exit(&test_mutex);

	printf("test: finished\n");

	callout_destroy(&test_ch);
	softint_disestablish(test_sih);
	mutex_destroy(&test_mutex);
	cv_destroy(&test_cv);

	return 0;
}
예제 #4
0
void
audioamd_attach(struct audioamd_softc *sc, int pri)
{

	/*
	 * Set up glue for MI code early; we use some of it here.
	 */
	sc->sc_am7930.sc_glue = &audioamd_glue;
	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);

	am7930_init(&sc->sc_am7930, AUDIOAMD_POLL_MODE);

	auiop = &sc->sc_au;

	/* Copy bus tag & handle for use by am7930_trap */
	sc->sc_au.au_bt = sc->sc_bt;
	sc->sc_au.au_bh = sc->sc_bh;
	(void)bus_intr_establish2(sc->sc_bt, pri, IPL_HIGH,
				  am7930hwintr, sc, amd7930_trap);

	sc->sc_sicookie = softint_establish(SOFTINT_SERIAL, am7930swintr, sc);
	if (sc->sc_sicookie == NULL) {
		printf("\n%s: cannot establish software interrupt\n",
			sc->sc_am7930.sc_dev.dv_xname);
		return;
	}

	printf(" softpri %d\n", IPL_SOFTAUDIO);


	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
	    sc->sc_am7930.sc_dev.dv_xname, "intr");

	audio_attach_mi(&sa_hw_if, sc, &sc->sc_am7930.sc_dev);
}
static void
arcofi_dio_attach(device_t parent, device_t self, void *aux)
{
	struct arcofi_dio_softc *adsc = device_private(self);
	struct arcofi_softc *sc = &adsc->sc_arcofi;
	struct dio_attach_args *da = aux;
	bus_space_tag_t iot = &adsc->sc_tag;
	int ipl;

	sc->sc_dev = self;

	/* XXX is it better to use sc->sc_reg[] to handle odd sparse map? */
	memcpy(iot, da->da_bst, sizeof(struct bus_space_tag));
	dio_set_bus_space_oddbyte(iot);
	sc->sc_iot = iot;

	if (bus_space_map(iot, da->da_addr, DIOII_SIZEOFF, 0,
	    &sc->sc_ioh) != 0) {
		aprint_error(": can't map registers\n");
		return;
	}

	sc->sc_sih = softint_establish(SOFTINT_AUDIO, arcofi_swintr, sc);
	if (sc->sc_sih == NULL) {
		aprint_error(": can't register soft interrupt\n");
		return;
	}
	ipl = da->da_ipl;
	dio_intr_establish(arcofi_hwintr, sc, ipl, IPL_AUDIO);

	aprint_normal("\n");

	arcofi_attach(sc, "dio");
}
예제 #6
0
void
mfcsattach(device_t parent, device_t self, void *aux)
{
	int unit;
	struct mfcs_softc *sc;
	struct mfc_softc *scc;
	struct mfc_args *ma;
	struct mfc_regs *rp;

	sc = device_private(self);
	sc->sc_dev = self;
	scc = device_private(parent);
	ma = aux;

	printf (": input fifo %d output fifo %d\n", SERIBUF_SIZE,
	    SEROBUF_SIZE);

	unit = ma->unit;
	mfcs_active |= 1 << unit;
	sc->rptr = sc->wptr = sc->inbuf;
	sc->sc_mfc = scc;
	sc->sc_regs = rp = scc->sc_regs;
	sc->sc_duart = (struct duart_regs *) ((unit & 1) ? 
	    __UNVOLATILE(&rp->du_mr1b) : __UNVOLATILE(&rp->du_mr1a));
	sc->mfcs_si = softint_establish(SOFTINT_SERIAL, mfcs_intr_soft, sc);
	/*
	 * should have only one vbl routine to handle all ports?
	 */
	sc->vbl_node.function = (void (*) (void *)) mfcsmint;
	sc->vbl_node.data = (void *) unit;
	add_vbl_function(&sc->vbl_node, 1, (void *) unit);
}
예제 #7
0
int
vcons_init(struct vcons_data *vd, void *cookie, struct wsscreen_descr *def,
    struct wsdisplay_accessops *ao)
{

	/* zero out everything so we can rely on untouched fields being 0 */
	memset(vd, 0, sizeof(struct vcons_data));
	
	vd->cookie = cookie;

	vd->init_screen = vcons_dummy_init_screen;
	vd->show_screen_cb = NULL;

	/* keep a copy of the accessops that we replace below with our
	 * own wrappers */
	vd->ioctl = ao->ioctl;

	/* configure the accessops */
	ao->ioctl = vcons_ioctl;
	ao->alloc_screen = vcons_alloc_screen;
	ao->free_screen = vcons_free_screen;
	ao->show_screen = vcons_show_screen;
#ifdef WSDISPLAY_SCROLLSUPPORT
	ao->scroll = vcons_scroll;
#endif

	LIST_INIT(&vd->screens);
	vd->active = NULL;
	vd->wanted = NULL;
	vd->currenttype = def;
	callout_init(&vd->switch_callout, 0);
	callout_setfunc(&vd->switch_callout, vcons_do_switch, vd);
#ifdef VCONS_DRAW_INTR
	vd->cells = 0;
	vd->attrs = NULL;
	vd->chars = NULL;
	vd->cursor_offset = -1;
#endif

	/*
	 * a lock to serialize access to the framebuffer.
	 * when switching screens we need to make sure there's no rasops
	 * operation in progress
	 */
#ifdef DIAGNOSTIC
	vd->switch_poll_count = 0;
#endif
#ifdef VCONS_DRAW_INTR
	vd->intr_softint = softint_establish(SOFTINT_SERIAL,
	    vcons_softintr, vd);
	callout_init(&vd->intr, 0);
	callout_setfunc(&vd->intr, vcons_intr, vd);
	vd->intr_valid = 1;

	/* XXX assume that the 'dev' arg is never dereferenced */
	config_interrupts((device_t)vd, vcons_intr_enable);
#endif
	return 0;
}
예제 #8
0
파일: vaudio.c 프로젝트: ryo/netbsd-src
static void
vaudio_attach(device_t parent, device_t self, void *opaque)
{
	struct vaudio_softc *sc = device_private(self);
	struct thunkbus_attach_args *taa = opaque;
	int error;

	aprint_naive("\n");
	aprint_normal(": Virtual Audio (device = %s)\n", taa->u.vaudio.device);

	sc->sc_dev = self;

	pmf_device_register1(self, NULL, NULL, vaudio_shutdown);

	sc->sc_audiopath = taa->u.vaudio.device;
	sc->sc_audiofd = thunk_audio_open(sc->sc_audiopath);
	if (sc->sc_audiofd == -1) {
		aprint_error_dev(self, "couldn't open audio device: %d\n",
		    thunk_geterrno());
		return;
	}

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);

	error = auconv_create_encodings(vaudio_audio_formats,
	    __arraycount(vaudio_audio_formats), &sc->sc_encodings);
	if (error) {
		aprint_error_dev(self, "couldn't create encodings\n");
		return;
	}

	sc->sc_play.st_softc = sc;
	sc->sc_play.st_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
	    vaudio_softintr_play, &sc->sc_play);
	callout_init(&sc->sc_play.st_callout, CALLOUT_MPSAFE);
	callout_setfunc(&sc->sc_play.st_callout, vaudio_intr, &sc->sc_play);

	sc->sc_record.st_softc = sc;
	sc->sc_record.st_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
	    vaudio_softintr_record, &sc->sc_record);
	callout_init(&sc->sc_record.st_callout, CALLOUT_MPSAFE);
	callout_setfunc(&sc->sc_record.st_callout, vaudio_intr, &sc->sc_record);

	sc->sc_audiodev = audio_attach_mi(&vaudio_hw_if, sc, self);
}
예제 #9
0
void
clmpcc_attach(struct clmpcc_softc *sc)
{
	struct clmpcc_chan *ch;
	struct tty *tp;
	int chan;

	if ( cons_sc != NULL &&
	     sc->sc_iot == cons_sc->sc_iot && sc->sc_ioh == cons_sc->sc_ioh )
		cons_sc = sc;

	/* Initialise the chip */
	clmpcc_init(sc);

	printf(": Cirrus Logic CD240%c Serial Controller\n",
		(clmpcc_rd_msvr(sc) & CLMPCC_MSVR_PORT_ID) ? '0' : '1');

	sc->sc_softintr_cookie =
	    softint_establish(SOFTINT_SERIAL, clmpcc_softintr, sc);
	if (sc->sc_softintr_cookie == NULL)
		panic("clmpcc_attach: softintr_establish");
	memset(&(sc->sc_chans[0]), 0, sizeof(sc->sc_chans));

	for (chan = 0; chan < CLMPCC_NUM_CHANS; chan++) {
		ch = &sc->sc_chans[chan];

		ch->ch_sc = sc;
		ch->ch_car = chan;

		tp = tty_alloc();
		tp->t_oproc = clmpcc_start;
		tp->t_param = clmpcc_param;

		ch->ch_tty = tp;

		ch->ch_ibuf = malloc(clmpcc_ibuf_size * 2, M_DEVBUF, M_NOWAIT);
		if ( ch->ch_ibuf == NULL ) {
			aprint_error_dev(sc->sc_dev, "(%d): unable to allocate ring buffer\n",
		    		chan);
			return;
		}

		ch->ch_ibuf_end = &(ch->ch_ibuf[clmpcc_ibuf_size * 2]);
		ch->ch_ibuf_rd = ch->ch_ibuf_wr = ch->ch_ibuf;

		tty_attach(tp);
	}

	aprint_error_dev(sc->sc_dev, "%d channels available",
					    CLMPCC_NUM_CHANS);
	if ( cons_sc == sc ) {
		printf(", console on channel %d.\n", cons_chan);
		SET(sc->sc_chans[cons_chan].ch_flags, CLMPCC_FLG_IS_CONSOLE);
		SET(sc->sc_chans[cons_chan].ch_openflags, TIOCFLAG_SOFTCAR);
	} else
		printf(".\n");
}
예제 #10
0
파일: kern_time.c 프로젝트: ryo/netbsd-src
void
time_init2(void)
{

	TAILQ_INIT(&timer_queue);
	mutex_init(&timer_lock, MUTEX_DEFAULT, IPL_SCHED);
	timer_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
	    timer_intr, NULL);
}
예제 #11
0
/*
 * dmover_process_init:
 *
 *	Initialize the processing engine.
 */
void
dmover_process_initialize(void)
{

	TAILQ_INIT(&dmover_completed_q);
	mutex_init(&dmover_completed_q_lock, MUTEX_DEFAULT, IPL_BIO);

	dmover_completed_si = softint_establish(SOFTINT_CLOCK,
	    dmover_complete, NULL);
}
예제 #12
0
static void
bcmrng_attach(device_t parent, device_t self, void *aux)
{
    struct bcm2835rng_softc *sc = device_private(self);
    struct amba_attach_args *aaa = aux;
    uint32_t ctrl;

    aprint_naive("\n");
    aprint_normal(": RNG\n");

    sc->sc_dev = self;
    sc->sc_iot = aaa->aaa_iot;

    if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_RNG_SIZE, 0,
                      &sc->sc_ioh)) {
        aprint_error_dev(sc->sc_dev, "unable to map device\n");
        goto fail0;
    }

    /* discard initial numbers, broadcom says they are "less random" */
    bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS, 0x40000);

    /* enable rng */
    ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL);
    ctrl |= RNG_CTRL_EN;
    bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL, ctrl);

    /* set up a softint for adding data */
    mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL);
    sc->sc_bytes_wanted = 0;
    sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
                                   &bcmrng_get_intr, sc);
    if (sc->sc_sih == NULL) {
        aprint_error_dev(sc->sc_dev, "unable to establish softint");
        goto fail1;
    }

    /* set up an rndsource */
    mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL);
    rndsource_setcb(&sc->sc_rndsource, &bcmrng_get_cb, sc);
    rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG,
                      RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);

    /* get some initial entropy ASAP */
    bcmrng_get_cb(RND_POOLBITS / NBBY, sc);

    /* Success!  */
    return;

fail1:
    mutex_destroy(&sc->sc_intr_lock);
    bus_space_unmap(aaa->aaa_iot, sc->sc_ioh, BCM2835_RNG_SIZE);
fail0:
    return;
}
예제 #13
0
파일: ucom.c 프로젝트: ryoon/netbsd-xhci
void
ucom_attach(device_t parent, device_t self, void *aux)
{
	struct ucom_softc *sc = device_private(self);
	struct ucom_attach_args *uca = aux;
	struct tty *tp;

	if (uca->info != NULL)
		aprint_normal(": %s", uca->info);
	aprint_normal("\n");

	sc->sc_dev = self;
	sc->sc_udev = uca->device;
	sc->sc_iface = uca->iface;
	sc->sc_bulkout_no = uca->bulkout;
	sc->sc_bulkin_no = uca->bulkin;
	sc->sc_ibufsize = uca->ibufsize;
	sc->sc_ibufsizepad = uca->ibufsizepad;
	sc->sc_obufsize = uca->obufsize;
	sc->sc_opkthdrlen = uca->opkthdrlen;
	sc->sc_methods = uca->methods;
	sc->sc_parent = uca->arg;
	sc->sc_portno = uca->portno;

	sc->sc_lsr = 0;
	sc->sc_msr = 0;
	sc->sc_mcr = 0;
	sc->sc_tx_stopped = 0;
	sc->sc_swflags = 0;
	sc->sc_opening = 0;
	sc->sc_refcnt = 0;
	sc->sc_dying = 0;

	sc->sc_si = softint_establish(SOFTINT_NET, ucom_softintr, sc);

	tp = tty_alloc();
	tp->t_oproc = ucomstart;
	tp->t_param = ucomparam;
	tp->t_hwiflow = ucomhwiflow;
	sc->sc_tty = tp;

	DPRINTF(("ucom_attach: tty_attach %p\n", tp));
	tty_attach(tp);

	rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, RND_FLAG_DEFAULT);

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
	return;
}
예제 #14
0
/* alloc/free pipe */
static usbd_status
alloc_pipe(struct umidi_endpoint *ep)
{
	struct umidi_softc *sc = ep->sc;
	usbd_status err;
	usb_endpoint_descriptor_t *epd;
	
	epd = usbd_get_endpoint_descriptor(sc->sc_iface, ep->addr);
	/*
	 * For output, an improvement would be to have a buffer bigger than
	 * wMaxPacketSize by num_jacks-1 additional packet slots; that would
	 * allow out_solicit to fill the buffer to the full packet size in
	 * all cases. But to use usbd_alloc_buffer to get a slightly larger
	 * buffer would not be a good way to do that, because if the addition
	 * would make the buffer exceed USB_MEM_SMALL then a substantially
	 * larger block may be wastefully allocated. Some flavor of double
	 * buffering could serve the same purpose, but would increase the
	 * code complexity, so for now I will live with the current slight
	 * penalty of reducing max transfer size by (num_open-num_scheduled)
	 * packet slots.
	 */
	ep->buffer_size = UGETW(epd->wMaxPacketSize);
	ep->buffer_size -= ep->buffer_size % UMIDI_PACKET_SIZE;

	DPRINTF(("%s: alloc_pipe %p, buffer size %u\n",
	        USBDEVNAME(sc->sc_dev), ep, ep->buffer_size));
	ep->num_scheduled = 0;
	ep->this_schedule = 0;
	ep->next_schedule = 0;
	ep->soliciting = 0;
	ep->armed = 0;
	ep->xfer = usbd_alloc_xfer(sc->sc_udev);
	if (ep->xfer == NULL) {
	    err = USBD_NOMEM;
	    goto quit;
	}
	ep->buffer = usbd_alloc_buffer(ep->xfer, ep->buffer_size);
	if (ep->buffer == NULL) {
	    usbd_free_xfer(ep->xfer);
	    err = USBD_NOMEM;
	    goto quit;
	}
	ep->next_slot = ep->buffer;
	err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe);
	if (err)
	    usbd_free_xfer(ep->xfer);
	ep->solicit_cookie = softint_establish(SOFTINT_CLOCK, out_solicit, ep);
quit:
	return err;
}
예제 #15
0
static void
wsattach(device_t parent, device_t self, void *aux)
{
    struct ws_softc *sc = device_private(self);
    struct sio_softc *siosc = device_private(parent);
    struct sio_attach_args *args = aux;
    int channel = args->channel;
    struct wskbddev_attach_args a;

    sc->sc_dev = self;
    sc->sc_ctl = &siosc->sc_ctl[channel];
    memcpy(sc->sc_wr, ch1_regs, sizeof(ch1_regs));
    siosc->sc_intrhand[channel].ih_func = wsintr;
    siosc->sc_intrhand[channel].ih_arg = sc;

    setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
    setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
    setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
    setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
    setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
    setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]);

    syscnputc((dev_t)1, 0x20); /* keep quiet mouse */

    sc->sc_rxqhead = 0;
    sc->sc_rxqtail = 0;

    sc->sc_si = softint_establish(SOFTINT_SERIAL, wssoftintr, sc);

    aprint_normal("\n");

    a.console = (args->hwflags == 1);
    a.keymap = &omkbd_keymapdata;
    a.accessops = &omkbd_accessops;
    a.accesscookie = (void *)sc;
    sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint);

#if NWSMOUSE > 0
    {
        struct wsmousedev_attach_args b;
        b.accessops = &omms_accessops;
        b.accesscookie = (void *)sc;
        sc->sc_wsmousedev =
            config_found_ia(self, "wsmousedev", &b, wsmousedevprint);
        sc->sc_msreport = 0;
    }
#endif
}
예제 #16
0
void
lpt_attach_subr(struct lpt_softc *sc)
{
	bus_space_tag_t iot;
	bus_space_handle_t ioh;

	sc->sc_state = 0;

	iot = sc->sc_iot;
	ioh = sc->sc_ioh;

	bus_space_write_1(iot, ioh, lpt_control, LPC_NINIT);

	callout_init(&sc->sc_wakeup_ch, 0);
	sc->sc_sih = softint_establish(SOFTINT_SERIAL, lptsoftintr, sc);

	sc->sc_dev_ok = 1;
}
예제 #17
0
void *
sacc_intr_establish(sacc_chipset_tag_t *ic, int irq, int type, int level,
    int (*ih_fun)(void *), void *ih_arg)
{
	int s;
	struct sacc_softc *sc = (struct sacc_softc *)ic;
	struct sacc_intrhand **p, *ih;

	/* no point in sleeping unless someone can free memory. */
	ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
	if (ih == NULL)
		panic("sacc_intr_establish: can't malloc handler info");

	if (irq < 0 || irq > SACCIC_LEN ||
	    !(type == IST_EDGE_RAISE || type == IST_EDGE_FALL))
		panic("sacc_intr_establish: bogus irq or type");

	if (sc->sc_intrhand[irq] == NULL) {
		sacc_intr_setpolarity(ic, irq, type);
		sc->sc_intrtype[irq] = type;
	} else if (sc->sc_intrtype[irq] != type)
		/* XXX we should be able to share raising and
		 * falling edge intrs */
		panic("sacc_intr_establish: type must be unique");

	/* install intr handler */
	/* map interrupt level to appropriate softinterrupt level */
	level = SOFTINT_SERIAL;
	ih->ih_soft = softint_establish(level, (void (*)(void *)) ih_fun,
					 ih_arg);
	ih->ih_irq = irq;
	ih->ih_next = NULL;

	s = splhigh();
	for (p = &sc->sc_intrhand[irq]; *p; p = &(*p)->ih_next)
		continue;

	*p = ih;

	sacc_intr_calculatemasks(sc);
	splx(s);

	return ih;
}
void *
gemini_ipm_register(uint8_t tag, unsigned int ipl, size_t quota,
        void (*consume)(void *, const void *),
        void (*counter)(void *, size_t),
	void *arg)
{
	gemini_ipm_softc_t *sc = gemini_ipm_sc;
	ipm_dispatch_entry_t *disp;
	void *ipmh = NULL;
	int psw;

	DPRINTFN(1, ("%s:%d: %d %d %ld %p %p %p\n", __FUNCTION__, __LINE__,
		tag, ipl, quota, consume, counter, arg));
	if (sc == NULL)
		return NULL;		/* not attached yet */

	if (tag == 0)
		return NULL;		/* tag #0 is reserved */

	psw = disable_interrupts(I32_bit);
	disp = &sc->sc_dispatch_tab[tag];
	if (disp->consume == 0) {
		if (sc->sc_txqavail >= quota) {
			sc->sc_txqavail -= quota;
			disp->ipl = ipl;
			disp->consume = consume;
			disp->counter = counter;
			disp->arg = arg;
#ifdef NOTYET
			if (ipl > SOFTINT_LVLMASK)
				panic("%s: bad level %d",
					device_xname(sc->sc_dev), ipl);
			disp->sih = softint_establish(ipl, consume, arg);
#endif
			ipmh = disp;
		}
	}
	restore_interrupts(psw);

	return ipmh;
}
예제 #19
0
/* called at boot time */
void
xenevtattach(int n)
{
	struct intrhand *ih;
	int s;
	int level = IPL_HIGH;
#ifdef MULTIPROCESSOR
	bool mpsafe = (level != IPL_VM);
#endif /* MULTIPROCESSOR */

	mutex_init(&devevent_lock, MUTEX_DEFAULT, IPL_HIGH);
	STAILQ_INIT(&devevent_pending);

	devevent_sih = softint_establish(SOFTINT_SERIAL,
	    (void (*)(void *))xenevt_notify, NULL);
	memset(devevent, 0, sizeof(devevent));
	xenevt_ev1 = 0;
	memset(xenevt_ev2, 0, sizeof(xenevt_ev2));

	/* register a handler at splhigh, so that spllower() will call us */
	ih = malloc(sizeof (struct intrhand), M_DEVBUF,
	     M_WAITOK|M_ZERO);
	if (ih == NULL)
		panic("can't allocate xenevt interrupt source");
	ih->ih_level = level;
	ih->ih_fun = ih->ih_realfun = xenevt_processevt;
	ih->ih_arg = ih->ih_realarg = NULL;
	ih->ih_ipl_next = NULL;
	ih->ih_cpu = &cpu_info_primary;
#ifdef MULTIPROCESSOR
	if (!mpsafe) {
		ih->ih_fun = intr_biglock_wrapper;
		ih->ih_arg = ih;
	}
#endif /* MULTIPROCESSOR */

	s = splhigh();
	event_set_iplhandler(ih->ih_cpu, ih, level);
	splx(s);
}
예제 #20
0
void
dt_attach(device_t parent, device_t self, void *aux)
{
	struct ioasicdev_attach_args *d;
	struct dt_attach_args dta;
	struct dt_softc *sc;
	struct dt_msg *msg;
	int i;

	d = aux;
	sc = device_private(self);
	sc->sc_dev = self;

	dt_cninit();

	msg = malloc(sizeof(*msg) * DT_BUF_CNT, M_DEVBUF, M_NOWAIT);
	if (msg == NULL) {
		printf("%s: memory exhausted\n", device_xname(self));
		return;
	}

	sc->sc_sih = softint_establish(SOFTINT_SERIAL, dt_dispatch, sc);
	if (sc->sc_sih == NULL) {
		printf("%s: memory exhausted\n", device_xname(self));
		free(msg, M_DEVBUF);
	}

	SIMPLEQ_INIT(&sc->sc_queue);
	SLIST_INIT(&sc->sc_free);
	for (i = 0; i < DT_BUF_CNT; i++, msg++)
		SLIST_INSERT_HEAD(&sc->sc_free, msg, chain.slist);

	ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_TTY, dt_intr, sc);
	printf("\n");

	dta.dta_addr = DT_ADDR_KBD;
	config_found(self, &dta, dt_print);
	dta.dta_addr = DT_ADDR_MOUSE;
	config_found(self, &dta, dt_print);
}
예제 #21
0
static void
ingenic_rng_attach(device_t parent, device_t self, void *aux)
{
	struct ingenic_rng_softc * const sc = device_private(self);
	struct apbus_attach_args * const aa = aux;
	int error;

	sc->sc_dev = self;
	sc->sc_bst = aa->aa_bst;
	if (aa->aa_addr == 0) {
		aa->aa_addr = JZ_RNG;
	}

	error = bus_space_map(aa->aa_bst, aa->aa_addr, 4, 0, &sc->sc_bsh);
	if (error) {
		aprint_error_dev(self,
			"can't map registers for %s: %d\n", aa->aa_name, error);
		return;
	}

	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL);
	mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL);
	
	aprint_naive(": Ingenic random number generator\n");
	aprint_normal(": Ingenic random number generator\n");

	sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
	    ingenic_rng_get_intr, sc);
	if (sc->sc_sih == NULL) {
		aprint_error_dev(self, "couldn't establish softint\n");
		return;
	}

	rndsource_setcb(&sc->sc_rndsource, ingenic_rng_get_cb, sc);
	rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG,
	    RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);

	ingenic_rng_get_cb(RND_POOLBITS / NBBY, sc);
}
/*
 * callout_init_cpu:
 *
 *	Per-CPU initialization.
 */
void
callout_init_cpu(struct cpu_info *ci)
{
	struct callout_cpu *cc;
	int b;

	CTASSERT(sizeof(callout_impl_t) <= sizeof(callout_t));

	if ((cc = ci->ci_data.cpu_callout) == NULL) {
		cc = kmem_zalloc(sizeof(*cc), KM_SLEEP);
		if (cc == NULL)
			panic("callout_init_cpu (1)");
		cc->cc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SCHED);
		CIRCQ_INIT(&cc->cc_todo);
		for (b = 0; b < BUCKETS; b++)
			CIRCQ_INIT(&cc->cc_wheel[b]);
	} else {
		/* Boot CPU, one time only. */
		callout_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
		    callout_softclock, NULL);
		if (callout_sih == NULL)
			panic("callout_init_cpu (2)");
	}

	sleepq_init(&cc->cc_sleepq);

	snprintf(cc->cc_name1, sizeof(cc->cc_name1), "late/%u",
	    cpu_index(ci));
	evcnt_attach_dynamic(&cc->cc_ev_late, EVCNT_TYPE_MISC,
	    NULL, "callout", cc->cc_name1);

	snprintf(cc->cc_name2, sizeof(cc->cc_name2), "wait/%u",
	    cpu_index(ci));
	evcnt_attach_dynamic(&cc->cc_ev_block, EVCNT_TYPE_MISC,
	    NULL, "callout", cc->cc_name2);

	ci->ci_data.cpu_callout = cc;
}
예제 #23
0
static void
kbdattach(device_t parent, device_t self, void *aux)
{
	struct kbd_softc *sc = device_private(self);
	struct mfp_softc *mfp = device_private(parent);
	int s;

	kbd_attached = 1;

	s = spltty();

	/* MFP interrupt #12 is for USART receive buffer full */
	intio_intr_establish(mfp->sc_intr + 12, "kbd", kbdintr, sc);
	sc->sc_softintr_cookie = softint_establish(SOFTINT_SERIAL,
	    kbdsoftint, sc);

	kbdenable(1);
	sc->sc_event_mode = 0;
	sc->sc_events.ev_io = 0;
	splx(s);

	aprint_normal("\n");
}
예제 #24
0
파일: pckbc_js.c 프로젝트: ryo/netbsd-src
/*
 * Keyboard and mouse share the interrupt
 * so don't install interrupt handler twice.
 */
static void
pckbc_js_intr_establish(struct pckbc_softc *sc, pckbport_slot_t slot)
{
	struct pckbc_js_softc *jsc = (struct pckbc_js_softc *)sc;
	void *res;

	if (jsc->jsc_establised) {
#ifdef DEBUG
		aprint_verbose_dev(sc->sc_dv,
		    "%s slot shares interrupt (already established)\n",
		    pckbc_slot_names[slot]);
#endif
		return;
	}

	/*
	 * We can not choose the devic class interruptlevel freely,
	 * so we debounce via a softinterrupt.
	 */
	jsc->jsc_int_cookie = softint_establish(SOFTINT_SERIAL,
	    pckbcintr_soft, &jsc->jsc_pckbc);
	if (jsc->jsc_int_cookie == NULL) {
		aprint_error_dev(sc->sc_dv,
		    "unable to establish %s soft interrupt\n",
		    pckbc_slot_names[slot]);
		return;
	}
	res = bus_intr_establish(sc->id->t_iot, jsc->jsc_intr,
				 IPL_SERIAL, jsc_pckbdintr, jsc);
	if (res == NULL)
		aprint_error_dev(sc->sc_dv,
		    "unable to establish %s slot interrupt\n",
		    pckbc_slot_names[slot]);
	else
		jsc->jsc_establised = 1;
}
예제 #25
0
void
at91usart_attach_subr(struct at91usart_softc *sc, struct at91bus_attach_args *sa)
{
	struct tty *tp;
	int err;

	printf("\n");

	if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(sc->sc_dev));

	sc->sc_iot = sa->sa_iot;
	sc->sc_hwbase = sa->sa_addr;
	sc->sc_dmat = sa->sa_dmat;
	sc->sc_pid = sa->sa_pid;

	/* allocate fifos */
	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_rx_fifo, AT91USART_RING_SIZE, BUS_DMA_READ | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate rx fifo", device_xname(sc->sc_dev));

	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_tx_fifo, AT91USART_RING_SIZE, BUS_DMA_WRITE | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate tx fifo", device_xname(sc->sc_dev));

	/* initialize uart */
	at91_peripheral_clock(sc->sc_pid, 1);

	at91usart_writereg(sc, US_IDR, -1);
	at91usart_writereg(sc, US_RTOR, 12);	// 12-bit timeout
	at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
	at91_intr_establish(sa->sa_pid, IPL_TTY, INTR_HIGH_LEVEL, at91usart_intr, sc);
	USART_INIT(sc, 115200U);

#ifdef	NOTYET
	if (sc->sc_iot == usart_cn_sc.sc_iot
	    && sc->sc_hwbase == usart_cn_sc.sc_hwbase) {
		usart_cn_sc.sc_attached = 1;
		/* Make sure the console is always "hardwired". */
		delay(10000);	/* wait for output to finish */
		SET(sc->sc_hwflags, COM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
		SET(sc->sc_ier, USART_INT_RXRDY);
		USARTREG(USART_IER) = USART_INT_RXRDY; // @@@@@
	}
#endif	// NOTYET

	tp = tty_alloc();
	tp->t_oproc = at91usart_start;
	tp->t_param = at91usart_param;
	tp->t_hwiflow = at91usart_hwiflow;

	sc->sc_tty = tp;

	tty_attach(tp);

#if	NOTYET
	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&at91usart_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		aprint_normal("%s: console (maj %u  min %u  cn_dev %u)\n",
		    device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev),
		    cn_tab->cn_dev);
	}
#endif	/* NOTYET */

	sc->sc_si = softint_establish(SOFTINT_SERIAL, at91usart_soft, sc);

#ifdef RND_COM
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, RND_FLAG_DEFAULT);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!sc->enable)
		sc->enabled = 1;

	/* XXX configure register */
	/* xxx_config(sc) */

	SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
예제 #26
0
void
zs_sbdio_attach(device_t parent, device_t self, void *aux)
{
	struct zsc_softc *zsc = device_private(self);
	struct sbdio_attach_args *sa = aux;
	struct zsc_attach_args zsc_args;
	struct zschan *zc;
	struct zs_chanstate *cs;
	struct zsdevice *zs_addr;
	int s, channel;

	zsc->zsc_dev = self;
	aprint_normal("\n");

	zs_addr = (void *)MIPS_PHYS_TO_KSEG1(sa->sa_addr1);
	zsc->zsc_flags = sa->sa_flags;

	/*
	 * Initialize software state for each channel.
	 */
	for (channel = 0; channel < 2; channel++) {
		zsc_args.channel = channel;
		zsc_args.hwflags = 0;
		cs = &zsc->zsc_cs_store[channel];
		zsc->zsc_cs[channel] = cs;

		cs->cs_channel = channel;
		cs->cs_private = NULL;
		cs->cs_ops = &zsops_null;

		if (channel == 0)
			zc = &zs_addr->zs_chan_a;
		else
			zc = &zs_addr->zs_chan_b;

		if (zc == zs_consaddr) {
			memcpy(cs, zs_conscs, sizeof(struct zs_chanstate));
			zs_conscs = cs;
			zsc_args.hwflags = ZS_HWFLAG_CONSOLE;
		} else {
			cs->cs_reg_csr  = &zc->zc_csr;
			cs->cs_reg_data = &zc->zc_data;
			memcpy(cs->cs_creg, zs_init_reg, 16);
			memcpy(cs->cs_preg, zs_init_reg, 16);
			cs->cs_defspeed = ZS_DEFSPEED;
			zsc_args.hwflags = 0;
		}

		zs_lock_init(cs);
		cs->cs_brg_clk = PCLK / 16;
		cs->cs_defcflag = zs_def_cflag;

		/* Make these correspond to cs_defcflag (-crtscts) */
		cs->cs_rr0_dcd = ZSRR0_DCD;
		cs->cs_rr0_cts = 0;
		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
		cs->cs_wr5_rts = 0;

		/*
		 * Clear the master interrupt enable.
		 * The INTENA is common to both channels,
		 * so just do it on the A channel.
		 */
		if (channel == 0) {
			zs_write_reg(cs, 9, 0);
		}

		/*
		 * Look for a child driver for this channel.
		 * The child attach will setup the hardware.
		 */
		if (!config_found(self, (void *)&zsc_args, zs_print)) {
			/* No sub-driver.  Just reset it. */
			uint8_t reset = (channel == 0) ?
			    ZSWR9_A_RESET : ZSWR9_B_RESET;
			s = splhigh();
			zs_write_reg(cs, 9, reset);
			splx(s);
		}
	}

	zsc->zsc_si = softint_establish(SOFTINT_SERIAL,
	    (void (*)(void *))zsc_intr_soft, zsc);
	intr_establish(sa->sa_irq, zshard, zsc);

	/*
	 * Set the master interrupt enable and interrupt vector.
	 * (common to both channels, do it on A)
	 */
	cs = zsc->zsc_cs[0];
	s = splhigh();
	/* interrupt vector */
	zs_write_reg(cs, 2, zs_init_reg[2]);
	/* master interrupt control (enable) */
	zs_write_reg(cs, 9, zs_init_reg[9]);
	splx(s);
}
예제 #27
0
static void
at91dbgu_attach(device_t parent, device_t self, void *aux)
{
	struct at91dbgu_softc *sc = device_private(self);
	struct at91bus_attach_args *sa = aux;
	struct tty *tp;

	printf("\n");

	sc->sc_dev = self;
	bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh);
	sc->sc_iot = sa->sa_iot;
	sc->sc_hwbase = sa->sa_addr;

	DBGUREG(DBGU_IDR) = -1;
	at91_intr_establish(sa->sa_pid, IPL_SERIAL, INTR_HIGH_LEVEL, dbgu_intr, sc);
	DBGU_INIT(AT91_MSTCLK, 115200U);

	if (sc->sc_iot == dbgu_cn_sc.sc_iot
	    && sc->sc_hwbase == dbgu_cn_sc.sc_hwbase) {
		dbgu_cn_sc.sc_attached = 1;
		/* Make sure the console is always "hardwired". */
		delay(10000);	/* wait for output to finish */
		SET(sc->sc_hwflags, COM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
		SET(sc->sc_ier, DBGU_INT_RXRDY);
		DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; // @@@@@
	}

	tp = tty_alloc();
	tp->t_oproc = at91dbgu_start;
	tp->t_param = at91dbgu_param;
	tp->t_hwiflow = at91dbgu_hwiflow;

	sc->sc_tty = tp;
	sc->sc_rbuf = malloc(AT91DBGU_RING_SIZE << 1, M_DEVBUF, M_NOWAIT);
	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
	sc->sc_rbavail = AT91DBGU_RING_SIZE;
	if (sc->sc_rbuf == NULL) {
		printf("%s: unable to allocate ring buffer\n",
		    device_xname(sc->sc_dev));
		return;
	}
	sc->sc_ebuf = sc->sc_rbuf + (AT91DBGU_RING_SIZE << 1);
	sc->sc_tbc = 0;

	tty_attach(tp);

	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&at91dbgu_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		aprint_normal("%s: console (maj %u min %u cn_dev %#"PRIx64")\n",
		    device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev),
		    cn_tab->cn_dev);
	}

	sc->sc_si = softint_establish(SOFTINT_SERIAL, at91dbgu_soft, sc);

#ifdef RND_COM
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, 0);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!sc->enable)
		sc->enabled = 1;

	/* XXX configure register */
	/* xxx_config(sc) */

	SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
예제 #28
0
static void
xennet_xenbus_attach(device_t parent, device_t self, void *aux)
{
	struct xennet_xenbus_softc *sc = device_private(self);
	struct xenbusdev_attach_args *xa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	int err;
	RING_IDX i;
	char *val, *e, *p;
	int s;
	extern int ifqmaxlen; /* XXX */
#ifdef XENNET_DEBUG
	char **dir;
	int dir_n = 0;
	char id_str[20];
#endif

	aprint_normal(": Xen Virtual Network Interface\n");
	sc->sc_dev = self;

#ifdef XENNET_DEBUG
	printf("path: %s\n", xa->xa_xbusd->xbusd_path);
	snprintf(id_str, sizeof(id_str), "%d", xa->xa_id);
	err = xenbus_directory(NULL, "device/vif", id_str, &dir_n, &dir);
	if (err) {
		aprint_error_dev(self, "xenbus_directory err %d\n", err);
	} else {
		printf("%s/\n", xa->xa_xbusd->xbusd_path);
		for (i = 0; i < dir_n; i++) {
			printf("\t/%s", dir[i]);
			err = xenbus_read(NULL, xa->xa_xbusd->xbusd_path, dir[i],
			    NULL, &val);
			if (err) {
				aprint_error_dev(self, "xenbus_read err %d\n", err);
			} else {
				printf(" = %s\n", val);
				free(val, M_DEVBUF);
			}
		}
	}
#endif /* XENNET_DEBUG */
	sc->sc_xbusd = xa->xa_xbusd;
	sc->sc_xbusd->xbusd_otherend_changed = xennet_backend_changed;

	/* initialize free RX and RX request lists */
	SLIST_INIT(&sc->sc_txreq_head);
	for (i = 0; i < NET_TX_RING_SIZE; i++) {
		sc->sc_txreqs[i].txreq_id = i;
		SLIST_INSERT_HEAD(&sc->sc_txreq_head, &sc->sc_txreqs[i],
		    txreq_next);
	}
	SLIST_INIT(&sc->sc_rxreq_head);
	s = splvm();
	for (i = 0; i < NET_RX_RING_SIZE; i++) {
		struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i];
		rxreq->rxreq_id = i;
		rxreq->rxreq_sc = sc;
		rxreq->rxreq_va = uvm_km_alloc(kernel_map,
		    PAGE_SIZE, PAGE_SIZE, UVM_KMF_WIRED | UVM_KMF_ZERO);
		if (rxreq->rxreq_va == 0)
			break;
		if (!pmap_extract(pmap_kernel(), rxreq->rxreq_va,
		    &rxreq->rxreq_pa))
			panic("%s: no pa for mapped va ?", device_xname(self));
		rxreq->rxreq_gntref = GRANT_INVALID_REF;
		SLIST_INSERT_HEAD(&sc->sc_rxreq_head, rxreq, rxreq_next);
	}
	splx(s);
	sc->sc_free_rxreql = i;
	if (sc->sc_free_rxreql == 0) {
		aprint_error_dev(self, "failed to allocate rx memory\n");
		return;
	}

	/* read mac address */
	err = xenbus_read(NULL, xa->xa_xbusd->xbusd_path, "mac", NULL, &val);
	if (err) {
		aprint_error_dev(self, "can't read mac address, err %d\n", err);
		return;
	}
	/* read mac address */
	for (i = 0, p = val; i < 6; i++) {
		sc->sc_enaddr[i] = strtoul(p, &e, 16);
		if ((e[0] == '\0' && i != 5) && e[0] != ':') {
			aprint_error_dev(self, "%s is not a valid mac address\n", val);
			free(val, M_DEVBUF);
			return;
		}
		p = &e[1];
	}
	free(val, M_DEVBUF);
	aprint_normal_dev(self, "MAC address %s\n",
	    ether_sprintf(sc->sc_enaddr));
	/* Initialize ifnet structure and attach interface */
	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_start = xennet_start;
	ifp->if_ioctl = xennet_ioctl;
	ifp->if_watchdog = xennet_watchdog;
	ifp->if_init = xennet_init;
	ifp->if_stop = xennet_stop;
	ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
	ifp->if_timer = 0;
	ifp->if_snd.ifq_maxlen = max(ifqmaxlen, NET_TX_RING_SIZE * 2);
	ifp->if_capabilities = IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx;
	IFQ_SET_READY(&ifp->if_snd);
	if_attach(ifp);
	ether_ifattach(ifp, sc->sc_enaddr);
	sc->sc_softintr = softint_establish(SOFTINT_NET, xennet_softstart, sc);
	if (sc->sc_softintr == NULL)
		panic("%s: can't establish soft interrupt",
			device_xname(self));

	/* initialise shared structures and tell backend that we are ready */
	xennet_xenbus_resume(sc);
}
예제 #29
0
/*
 * Attach a found zs.
 */
static void
zs_attach(device_t parent, device_t self, void *aux)
{
	struct zsc_softc *zsc = device_private(self);
	struct intio_attach_args *ia = aux;
	struct zsc_attach_args zsc_args;
	volatile struct zschan *zc;
	struct zs_chanstate *cs;
	int r, s, zs_unit, channel;

	zsc->zsc_dev = self;
	aprint_normal("\n");

	zs_unit = device_unit(self);
	zsc->zsc_addr = (void *)ia->ia_addr;

	ia->ia_size = 8;
	r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE);
#ifdef DIAGNOSTIC
	if (r)
		panic("zs: intio IO map corruption");
#endif

	/*
	 * Initialize software state for each channel.
	 */
	for (channel = 0; channel < 2; channel++) {
		device_t child;

		zsc_args.channel = channel;
		zsc_args.hwflags = 0;
		cs = &zsc->zsc_cs_store[channel];
		zsc->zsc_cs[channel] = cs;

		zs_lock_init(cs);
		cs->cs_channel = channel;
		cs->cs_private = NULL;
		cs->cs_ops = &zsops_null;
		cs->cs_brg_clk = PCLK / 16;

		if (channel == 0)
			zc = (volatile void *)IIOV(&zsc->zsc_addr->zs_chan_a);
		else
			zc = (volatile void *)IIOV(&zsc->zsc_addr->zs_chan_b);
		cs->cs_reg_csr  = &zc->zc_csr;
		cs->cs_reg_data = &zc->zc_data;

		zs_init_reg[2] = ia->ia_intr;
		memcpy(cs->cs_creg, zs_init_reg, 16);
		memcpy(cs->cs_preg, zs_init_reg, 16);

		if (zc == conschan) {
			zsc_args.hwflags |= ZS_HWFLAG_CONSOLE;
			cs->cs_defspeed = zs_get_speed(cs);
			cs->cs_defcflag = zscn_def_cflag;
		} else {
			cs->cs_defspeed = 9600;
			cs->cs_defcflag = zs_def_cflag;
		}

		/* Make these correspond to cs_defcflag (-crtscts) */
		cs->cs_rr0_dcd = ZSRR0_DCD;
		cs->cs_rr0_cts = 0;
		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
		cs->cs_wr5_rts = 0;

		/*
		 * Clear the master interrupt enable.
		 * The INTENA is common to both channels,
		 * so just do it on the A channel.
		 */
		if (channel == 0) {
			s = splzs();
			zs_write_reg(cs, 9, 0);
			splx(s);
		}

		/*
		 * Look for a child driver for this channel.
		 * The child attach will setup the hardware.
		 */
		child = config_found(self, (void *)&zsc_args, zs_print);
#if ZSTTY > 0
		if (zc == conschan &&
		    ((child && strcmp(device_xname(child), "zstty0")) ||
		     child == NULL)) /* XXX */
			panic("%s: console device mismatch", __func__);
#endif
		if (child == NULL) {
			/* No sub-driver.  Just reset it. */
			uint8_t reset = (channel == 0) ?
				ZSWR9_A_RESET : ZSWR9_B_RESET;
			s = splzs();
			zs_write_reg(cs,  9, reset);
			splx(s);
		}
	}

	/*
	 * Now safe to install interrupt handlers.
	 */
	if (intio_intr_establish(ia->ia_intr, "zs", zshard, zsc))
		panic("%s: interrupt vector busy", __func__);
	zsc->zsc_softintr_cookie = softint_establish(SOFTINT_SERIAL,
	    (void (*)(void *))zsc_intr_soft, zsc);
	/* XXX; evcnt_attach() ? */

	/*
	 * Set the master interrupt enable and interrupt vector.
	 * (common to both channels, do it on A)
	 */
	cs = zsc->zsc_cs[0];
	s = splzs();
	/* interrupt vector */
	zs_write_reg(cs, 2, ia->ia_intr);
	/* master interrupt control (enable) */
	zs_write_reg(cs, 9, zs_init_reg[9]);
	splx(s);
}
예제 #30
0
void
bppattach(device_t parent, device_t self, void *aux)
{
	struct bpp_softc *dsc = device_private(self);
	struct lsi64854_softc *sc = &dsc->sc_lsi64854;
	struct sbus_softc *sbsc = device_private(parent);
	struct sbus_attach_args *sa = aux;
	int burst, sbusburst;
	int node;

	sc->sc_dev = self;

	selinit(&dsc->sc_rsel);
	selinit(&dsc->sc_wsel);
	dsc->sc_sih = softint_establish(SOFTINT_CLOCK, bppsoftintr, dsc);

	sc->sc_bustag = sa->sa_bustag;
	sc->sc_dmatag = sa->sa_dmatag;
	node = sa->sa_node;

	/* Map device registers */
	if (sbus_bus_map(sa->sa_bustag,
			 sa->sa_slot, sa->sa_offset, sa->sa_size,
			 0, &sc->sc_regs) != 0) {
		aprint_error(": cannot map registers\n");
		return;
	}

	/*
	 * Get transfer burst size from PROM and plug it into the
	 * controller registers. This is needed on the Sun4m; do
	 * others need it too?
	 */
	sbusburst = sbsc->sc_burst;
	if (sbusburst == 0)
		sbusburst = SBUS_BURST_32 - 1; /* 1->16 */

	burst = prom_getpropint(node, "burst-sizes", -1);
	if (burst == -1)
		/* take SBus burst sizes */
		burst = sbusburst;

	/* Clamp at parent's burst sizes */
	burst &= sbusburst;
	sc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
		       (burst & SBUS_BURST_16) ? 16 : 0;

	/* Join the Sbus device family */
	dsc->sc_sd.sd_reset = NULL;
	sbus_establish(&dsc->sc_sd, self);

	/* Initialize the DMA channel */
	sc->sc_channel = L64854_CHANNEL_PP;
	lsi64854_attach(sc);

	/* Establish interrupt handler */
	if (sa->sa_nintr) {
		sc->sc_intrchain = bppintr;
		sc->sc_intrchainarg = dsc;
		(void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY,
		    bppintr, sc);
	}

	/* Allocate buffer XXX - should actually use dmamap_uio() */
	dsc->sc_bufsz = 1024;
	dsc->sc_buf = malloc(dsc->sc_bufsz, M_DEVBUF, M_NOWAIT);

	/* XXX read default state */
	{
	bus_space_handle_t h = sc->sc_regs;
	struct hwstate *hw = &dsc->sc_hwdefault;
	int ack_rate = sa->sa_frequency / 1000000;

	hw->hw_hcr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_HCR);
	hw->hw_ocr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_OCR);
	hw->hw_tcr = bus_space_read_1(sc->sc_bustag, h, L64854_REG_TCR);
	hw->hw_or = bus_space_read_1(sc->sc_bustag, h, L64854_REG_OR);

	DPRINTF(("bpp: hcr %x ocr %x tcr %x or %x\n",
	    hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or));
	/* Set these to sane values */
	hw->hw_hcr = ((ack_rate<<BPP_HCR_DSS_SHFT)&BPP_HCR_DSS_MASK)
	    | ((ack_rate<<BPP_HCR_DSW_SHFT)&BPP_HCR_DSW_MASK);
	hw->hw_ocr |= BPP_OCR_ACK_OP;
	}
}