示例#1
0
void
wskbd_input(device_t dev, u_int type, int value)
{
	struct wskbd_softc *sc = device_private(dev);
#if NWSDISPLAY > 0
	int num, i;
#endif

	if (sc->sc_repeating) {
		sc->sc_repeating = 0;
		callout_stop(&sc->sc_repeat_ch);
	}

	device_active(dev, DVA_HARDWARE);

#if NWSDISPLAY > 0
	/*
	 * If /dev/wskbdN is not connected in event mode translate and
	 * send upstream.
	 */
	if (sc->sc_translating) {
		num = wskbd_translate(sc->id, type, value);
		if (num > 0) {
			if (sc->sc_base.me_dispdv != NULL) {
#ifdef WSDISPLAY_SCROLLSUPPORT
				if (sc->id->t_symbols [0] != KS_Print_Screen) {
					wsdisplay_scroll(sc->sc_base.
					me_dispdv, WSDISPLAY_SCROLL_RESET);
				}
#endif
				for (i = 0; i < num; i++)
					wsdisplay_kbdinput(
						sc->sc_base.me_dispdv,
						sc->id->t_symbols[i]);
			}

			if (sc->sc_keyrepeat_data.del1 != 0) {
				sc->sc_repeating = num;
				callout_schedule(&sc->sc_repeat_ch,
				    mstohz(sc->sc_keyrepeat_data.del1));
			}
		}
		return;
	}
#endif

	wskbd_deliver_event(sc, type, value);

#if defined(WSKBD_EVENT_AUTOREPEAT)
	/* Repeat key presses if set. */
	if (type == WSCONS_EVENT_KEY_DOWN && sc->sc_keyrepeat_data.del1 != 0) {
		sc->sc_repeat_type = type;
		sc->sc_repeat_value = value;
		sc->sc_repeating = 1;
		callout_schedule(&sc->sc_repeat_ch,
		    mstohz(sc->sc_keyrepeat_data.del1));
	}
#endif /* defined(WSKBD_EVENT_AUTOREPEAT) */
}
/*
 * reset the PHY and bring it online
 */
uint32_t
sata_reset_interface(struct ata_channel *chp, bus_space_tag_t sata_t,
    bus_space_handle_t scontrol_r, bus_space_handle_t sstatus_r)
{
	uint32_t scontrol, sstatus;
	int i;

	/* bring the PHYs online.
	 * The work-around for errata #1 for the 31244 says that we must
	 * write 0 to the port first to be sure of correctly initializing
	 * the device. It doesn't hurt for other devices.
	 */
	bus_space_write_4(sata_t, scontrol_r, 0, 0);
	scontrol = SControl_IPM_NONE | SControl_SPD_ANY | SControl_DET_INIT;
	bus_space_write_4 (sata_t, scontrol_r, 0, scontrol);

	tsleep(chp, PRIBIO, "sataup", mstohz(50));
	scontrol &= ~SControl_DET_INIT;
	bus_space_write_4(sata_t, scontrol_r, 0, scontrol);

	tsleep(chp, PRIBIO, "sataup", mstohz(50));
	/* wait up to 1s for device to come up */
	for (i = 0; i < 100; i++) {
		sstatus = bus_space_read_4(sata_t, sstatus_r, 0);
		if ((sstatus & SStatus_DET_mask) == SStatus_DET_DEV)
			break;
		tsleep(chp, PRIBIO, "sataup", mstohz(10));
	}

	switch (sstatus & SStatus_DET_mask) {
	case SStatus_DET_NODEV:
		/* No Device; be silent.  */
		break;

	case SStatus_DET_DEV_NE:
		aprint_error("%s port %d: device connected, but "
		    "communication not established\n",
		    device_xname(chp->ch_atac->atac_dev), chp->ch_channel);
		break;

	case SStatus_DET_OFFLINE:
		aprint_error("%s port %d: PHY offline\n",
		    device_xname(chp->ch_atac->atac_dev), chp->ch_channel);
		break;

	case SStatus_DET_DEV:
		aprint_normal("%s port %d: device present, speed: %s\n",
		    device_xname(chp->ch_atac->atac_dev), chp->ch_channel,
		    sata_speed(sstatus));
		break;
	default:
		aprint_error("%s port %d: unknown SStatus: 0x%08x\n",
		    device_xname(chp->ch_atac->atac_dev), chp->ch_channel,
		    sstatus);
	}
	return(sstatus & SStatus_DET_mask);
}
示例#3
0
/*
 * timer_periodic - set periodic timer for the specified thread.
 *
 * The periodic thread can wait the timer period by calling
 * timer_waitperiod(). The unit of start/period is milli-seconds.
 */
int
timer_periodic(thread_t t, u_long start, u_long period)
{
	struct timer *tmr;
	int s;

	if (start != 0 && period == 0)
		return EINVAL;

	sched_lock();
	if (!thread_valid(t)) {
		sched_unlock();
		return ESRCH;
	}
	if (t->task != curtask) {
		sched_unlock();
		return EPERM;
	}

	tmr = t->periodic;
	if (start == 0) {
		/*
		 * Cancel periodic timer.
		 */
		if (tmr == NULL || tmr->state != TM_ACTIVE) {
			sched_unlock();
			return EINVAL;
		}
		timer_stop(tmr);
	} else {
		if (tmr == NULL) {
			/*
			 * Allocate a timer element at first call.
			 * This is to save the data area in the thread
			 * structure.
			 */
			if ((tmr = kmem_alloc(sizeof(tmr))) == NULL) {
				sched_unlock();
				return ENOMEM;
			}
			memset(tmr, 0, sizeof(*tmr));
			event_init(&tmr->event, "periodic");
			t->periodic = tmr;
		}
		/*
		 * Program an interval timer.
		 */
		s = splhigh();
		tmr->interval = mstohz(period);
		if (tmr->interval == 0)
			tmr->interval = 1;
		timer_add(tmr, mstohz(start));
		splx(s);
	}
	sched_unlock();
	return 0;
}
示例#4
0
/*
 * data contains amount of time to sleep, in milliseconds
 */
static int
filt_timerattach(struct knote *kn)
{
	callout_t *calloutp;
	struct kqueue *kq;
	int tticks;

	tticks = mstohz(kn->kn_sdata);

	/* if the supplied value is under our resolution, use 1 tick */
	if (tticks == 0) {
		if (kn->kn_sdata == 0)
			return EINVAL;
		tticks = 1;
	}

	if (atomic_inc_uint_nv(&kq_ncallouts) >= kq_calloutmax ||
	    (calloutp = kmem_alloc(sizeof(*calloutp), KM_NOSLEEP)) == NULL) {
		atomic_dec_uint(&kq_ncallouts);
		return ENOMEM;
	}
	callout_init(calloutp, CALLOUT_MPSAFE);

	kq = kn->kn_kq;
	mutex_spin_enter(&kq->kq_lock);
	kn->kn_flags |= EV_CLEAR;		/* automatically set */
	kn->kn_hook = calloutp;
	mutex_spin_exit(&kq->kq_lock);

	callout_reset(calloutp, tticks, filt_timerexpire, kn);

	return (0);
}
示例#5
0
static void
njata32_init(struct njata32_softc *sc, int nosleep)
{

	/* disable interrupts */
	bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
	    NJATA32_REG_IRQ_SELECT, 0);

	/* bus reset */
	bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_AS,
	    NJATA32_AS_WAIT0 | NJATA32_AS_BUS_RESET);
	if (nosleep)
		delay(50000);
	else
		tsleep(sc, PRIBIO, "njaini", mstohz(50));
	bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_AS,
	    NJATA32_AS_WAIT0);

	/* initial transfer speed */
	bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
	    NJATA32_REG_TIMING, NJATA32_TIMING_PIO0 + sc->sc_atawait);

	/* setup busmaster mode */
	bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc), NJATA32_REG_IOBM,
	    NJATA32_IOBM_DEFAULT);

	/* enable interrupts */
	bus_space_write_1(NJATA32_REGT(sc), NJATA32_REGH(sc),
	    NJATA32_REG_IRQ_SELECT, NJATA32_IRQ_XFER | NJATA32_IRQ_DEV);
}
示例#6
0
static void
u24_start_mbox(struct uha_softc *sc, struct uha_mscp *mscp)
{
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;
	int spincount = 100000;	/* 1s should be enough */

	while (--spincount) {
		if ((bus_space_read_1(iot, ioh, U24_LINT) & U24_LDIP) == 0)
			break;
		delay(100);
	}
	if (!spincount) {
		aprint_error_dev(&sc->sc_dev, "uha_start_mbox, board not responding\n");
		Debugger();
	}

	bus_space_write_4(iot, ioh, U24_OGMPTR,
	    sc->sc_dmamap_mscp->dm_segs[0].ds_addr + UHA_MSCP_OFF(mscp));
	if (mscp->flags & MSCP_ABORT)
		bus_space_write_1(iot, ioh, U24_OGMCMD, 0x80);
	else
		bus_space_write_1(iot, ioh, U24_OGMCMD, 0x01);
	bus_space_write_1(iot, ioh, U24_LINT, U24_OGMFULL);

	if ((mscp->xs->xs_control & XS_CTL_POLL) == 0)
		callout_reset(&mscp->xs->xs_callout,
		    mstohz(mscp->timeout), uha_timeout, mscp);
}
示例#7
0
static void
wskbd_repeat(void *v)
{
	struct wskbd_softc *sc = (struct wskbd_softc *)v;
	int s = spltty();

	if (!sc->sc_repeating) {
		/*
		 * race condition: a "key up" event came in when wskbd_repeat()
		 * was already called but not yet spltty()'d
		 */
		splx(s);
		return;
	}
	if (sc->sc_translating) {
		/* deliver keys */
#if NWSDISPLAY > 0
		if (sc->sc_base.me_dispdv != NULL) {
			int i;
			for (i = 0; i < sc->sc_repeating; i++)
				wsdisplay_kbdinput(sc->sc_base.me_dispdv,
						   sc->id->t_symbols[i]);
		}
#endif
	} else {
#if defined(WSKBD_EVENT_AUTOREPEAT)
		/* queue event */
		wskbd_deliver_event(sc, sc->sc_repeat_type,
				    sc->sc_repeat_value);
#endif /* defined(WSKBD_EVENT_AUTOREPEAT) */
	}
	callout_schedule(&sc->sc_repeat_ch, mstohz(sc->sc_keyrepeat_data.delN));
	splx(s);
}
示例#8
0
文件: vmt.c 项目: goroutines/rumprun
static int
vmt_sysctl_update_clock_sync_period(SYSCTLFN_ARGS)
{
	int error, period;
	struct sysctlnode node;
	struct vmt_softc *sc;

	node = *rnode;
	sc = (struct vmt_softc *)node.sysctl_data;

	period = sc->sc_clock_sync_period_seconds;
	node.sysctl_data = &period;
	error = sysctl_lookup(SYSCTLFN_CALL(&node));
	if (error || newp == NULL)
		return error;

	if (sc->sc_clock_sync_period_seconds != period) {
		callout_halt(&sc->sc_clock_sync_tick, NULL);
		sc->sc_clock_sync_period_seconds = period;
		if (sc->sc_clock_sync_period_seconds > 0)
			callout_schedule(&sc->sc_clock_sync_tick,
			    mstohz(sc->sc_clock_sync_period_seconds * 1000));
	}
	return 0;
}
示例#9
0
void
dme_phy_check_link(void *arg)
{
    struct dme_softc *sc = arg;
    uint32_t reg;
    int s;

    s = splnet();

    reg = dme_read(sc, DM9000_NSR) & DM9000_NSR_LINKST;

    if( reg )
        reg = IFM_ETHER | IFM_AVALID | IFM_ACTIVE;
    else {
        reg = IFM_ETHER | IFM_AVALID;
        sc->sc_media_active = IFM_NONE;
    }

    if ( (sc->sc_media_status != reg) && (reg & IFM_ACTIVE)) {
        dme_phy_reset(sc);
    }

    sc->sc_media_status = reg;

    callout_schedule(&sc->sc_link_callout, mstohz(2000));
    splx(s);
}
示例#10
0
static void
awin_hdmi_thread(void *priv)
{
	struct awin_hdmi_softc *sc = priv;

	for (;;) {
		awin_hdmi_hpd(sc);
		kpause("hdmihotplug", false, mstohz(1000), NULL);
	}
}
示例#11
0
文件: vmt.c 项目: goroutines/rumprun
static void
vmt_clock_sync_tick(void *xarg)
{
	struct vmt_softc *sc = xarg;

	vmt_sync_guest_clock(sc);

	callout_schedule(&sc->sc_clock_sync_tick,
	    mstohz(sc->sc_clock_sync_period_seconds * 1000));
}
示例#12
0
static void mpcsa_leds_timer(void *aux)
{
	int n, s;
	struct mpcsa_leds_softc *sc = aux;
	u_int16_t pins;

	callout_schedule(&sc->sc_c, mstohz(LEDS_UPDATE_INTERVAL));

	s = splserial();
	if (!(sc->sc_spi_transfer.st_flags & SPI_F_DONE)) {
		splx(s);
		return;
	}


	pins = be16toh(sc->sc_pinstate);

	for (n = 0; n < MPCSA_LEDS_NPINS; n++) {
		switch (sc->sc_leds[n].l_mode) {
		default:
			continue;

		case LMODE_COMM:
			if (sc->sc_leds[n].l_comm_cnt > 0) {
				if (sc->sc_leds[n].l_comm_cnt < INFINITE_BLINK)
					sc->sc_leds[n].l_comm_cnt--;
				else
					sc->sc_leds[n].l_comm_cnt ^= 1;
			}
			if ((sc->sc_leds[n].l_conn_cnt > 0) ^ (sc->sc_leds[n].l_comm_cnt & 1))
				pins &= ~(1U << n);
			else
				pins |= (1U << n);
			break;

		case LMODE_BLINK:
			if (--sc->sc_leds[n].l_blink_cnt <= 0) {
				pins ^= (1U << n);
				sc->sc_leds[n].l_blink_cnt = sc->sc_leds[n].l_blink_int;
			}
			break;
		}
	}

	HTOBE16(pins);
	sc->sc_pinstate = pins;
	splx(s);

	spi_transfer_init(&sc->sc_spi_transfer);
	spi_chunk_init(&sc->sc_spi_chunk, 2, (const void *)&sc->sc_pinstate, NULL);
	spi_transfer_add(&sc->sc_spi_transfer, &sc->sc_spi_chunk);
	if (spi_transfer(sc->sc_sh, &sc->sc_spi_transfer) != 0) {
		/* an error occurred! */
	}
}
示例#13
0
static void
wsmouse_repeat(void *v)
{
	int oldspl;
	unsigned int newdelay;
	struct wsmouse_softc *sc;
	struct wscons_event events[2];

	oldspl = spltty();
	sc = (struct wsmouse_softc *)v;

	if (sc->sc_repeat_button == -1) {
		/* Race condition: a "button up" event came in when
		 * this function was already called but did not do
		 * spltty() yet. */
		splx(oldspl);
		return;
	}
	KASSERT(sc->sc_repeat_button >= 0);

	KASSERT(sc->sc_repeat.wr_buttons & (1 << sc->sc_repeat_button));

	newdelay = sc->sc_repeat_delay;

	events[0].type = WSCONS_EVENT_MOUSE_UP;
	events[0].value = sc->sc_repeat_button;
	events[1].type = WSCONS_EVENT_MOUSE_DOWN;
	events[1].value = sc->sc_repeat_button;

	if (wsevent_inject(sc->sc_base.me_evp, events, 2) == 0) {
		sc->sc_ub = 1 << sc->sc_repeat_button;

		if (newdelay - sc->sc_repeat.wr_delay_decrement <
		    sc->sc_repeat.wr_delay_minimum)
			newdelay = sc->sc_repeat.wr_delay_minimum;
		else if (newdelay > sc->sc_repeat.wr_delay_minimum)
			newdelay -= sc->sc_repeat.wr_delay_decrement;
		KASSERT(newdelay >= sc->sc_repeat.wr_delay_minimum &&
		    newdelay <= sc->sc_repeat.wr_delay_first);
	}

	/*
	 * Reprogram the repeating event.
	 */
	sc->sc_repeat_delay = newdelay;
	callout_schedule(&sc->sc_repeat_callout, mstohz(newdelay));

	splx(oldspl);
}
示例#14
0
static void
mpcsa_leds_attach(device_t parent, device_t self, void *aux)
{
	struct mpcsa_leds_softc *sc = device_private(self);
	struct spi_attach_args *sa = aux;
#if NGPIO > 0
	struct gpiobus_attach_args gba;
#endif
	int n;

	aprint_naive(": output buffer\n");
	aprint_normal(": 74HC595 or compatible shift register(s)\n");

	sc->sc_sh = sa->sa_handle;
	sc->sc_pinstate = 0xffff;
	callout_init(&sc->sc_c, 0);

#if NGPIO > 0
	/* initialize and attach gpio(4) */
	for (n = 0; n < MPCSA_LEDS_NPINS; n++) {
		sc->sc_pins[n].pin_num = n;
		sc->sc_pins[n].pin_caps = (GPIO_PIN_OUTPUT
					   | GPIO_PIN_PUSHPULL);
		sc->sc_pins[n].pin_flags = GPIO_PIN_OUTPUT | GPIO_PIN_LOW;
	}

	sc->sc_gpio_chipset.gp_cookie = sc;
	sc->sc_gpio_chipset.gp_pin_read = mpcsa_leds_pin_read;
	sc->sc_gpio_chipset.gp_pin_write = mpcsa_leds_pin_write;
	sc->sc_gpio_chipset.gp_pin_ctl = mpcsa_leds_pin_ctl;
	gba.gba_gc = &sc->sc_gpio_chipset;
	gba.gba_pins = sc->sc_pins;
	gba.gba_npins = MPCSA_LEDS_NPINS;
	config_found_ia(self, "gpiobus", &gba, mpcsa_ledsbus_print);
#endif

	/* attach device */
//	config_search_ia(mpcsa_leds_search, self, "mpcsa_leds", mpcsa_leds_print);

	/* update leds ten times a second or so */
	mpcsa_leds_sc = sc; // @@@@
	sc->sc_spi_transfer.st_flags = SPI_F_DONE;
	callout_reset(&sc->sc_c, mstohz(LEDS_UPDATE_INTERVAL), mpcsa_leds_timer, sc);

	mpcsa_blink_led(LED_HB, 500);
}
示例#15
0
static void
filt_timerexpire(void *knx)
{
	struct knote *kn = knx;
	int tticks;

	mutex_enter(&kqueue_misc_lock);
	kn->kn_data++;
	knote_activate(kn);
	if ((kn->kn_flags & EV_ONESHOT) == 0) {
		tticks = mstohz(kn->kn_sdata);
		if (tticks <= 0)
			tticks = 1;
		callout_schedule((callout_t *)kn->kn_hook, tticks);
	}
	mutex_exit(&kqueue_misc_lock);
}
示例#16
0
/*
 * Schedule a callout function to run after a specified
 * length of time.
 *
 * Note: A device driver can call timer_callout() or
 * timer_stop() from ISR at interrupt level.
 */
void
timer_callout(struct timer *tmr, u_long msec, void (*fn)(void *), void *arg)
{
	int s;

	ASSERT(tmr != NULL);
	ASSERT(fn != NULL);

	s = splhigh();

	if (tmr->state == TM_ACTIVE)
		list_remove(&tmr->link);

	tmr->func = fn;
	tmr->arg = arg;
	tmr->interval = 0;
	timer_add(tmr, mstohz(msec));

	splx(s);
}
示例#17
0
static int
awin_hdmi_i2c_xfer_1_4(void *priv, i2c_addr_t addr, uint8_t block, uint8_t reg,
    size_t len, int type, int flags)
{
	struct awin_hdmi_softc *sc = priv;
	uint32_t val;
	int retry;

	val = HDMI_READ(sc, AWIN_A31_HDMI_DDC_FIFO_CTRL_REG);
	val |= AWIN_A31_HDMI_DDC_FIFO_CTRL_RST;
	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_FIFO_CTRL_REG, val);

	val = __SHIFTIN(block, AWIN_A31_HDMI_DDC_SLAVE_ADDR_SEG_PTR);
	val |= __SHIFTIN(0x60, AWIN_A31_HDMI_DDC_SLAVE_ADDR_DDC_CMD);
	val |= __SHIFTIN(reg, AWIN_A31_HDMI_DDC_SLAVE_ADDR_OFF_ADR);
	val |= __SHIFTIN(addr, AWIN_A31_HDMI_DDC_SLAVE_ADDR_DEV_ADR);
	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_SLAVE_ADDR_REG, val);

	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_COMMAND_REG,
	    __SHIFTIN(len, AWIN_A31_HDMI_DDC_COMMAND_DTC) |
	    __SHIFTIN(type, AWIN_A31_HDMI_DDC_COMMAND_CMD));

	val = HDMI_READ(sc, AWIN_A31_HDMI_DDC_CTRL_REG);
	val |= AWIN_A31_HDMI_DDC_CTRL_ACCESS_CMD_START;
	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_CTRL_REG, val);

	retry = 1000;
	while (--retry > 0) {
		val = HDMI_READ(sc, AWIN_A31_HDMI_DDC_CTRL_REG);
		if ((val & AWIN_A31_HDMI_DDC_CTRL_ACCESS_CMD_START) == 0)
			break;
		if (cold)
			delay(1000);
		else
			kpause("hdmiddc", false, mstohz(10), &sc->sc_ic_lock);
	}
	if (retry == 0)
		return ETIMEDOUT;

	return 0;
}
示例#18
0
/*
 * This interrupt indicates that the DWC_otg controller has detected a
 * resume or remote wakeup sequence. If the DWC_otg controller is in
 * low power mode, the handler must brings the controller out of low
 * power mode. The controller automatically begins resume signaling.
 * The handler schedules a time to stop resume signaling.
 */
static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
{
    int ret;
    dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n");
    dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);

    if (dwc2_is_device_mode(hsotg)) {
        dev_dbg(hsotg->dev, "DSTS=0x%0x\n", DWC2_READ_4(hsotg, DSTS));
        if (hsotg->lx_state == DWC2_L2) {
            u32 dctl = DWC2_READ_4(hsotg, DCTL);

            /* Clear Remote Wakeup Signaling */
            dctl &= ~DCTL_RMTWKUPSIG;
            DWC2_WRITE_4(hsotg, DCTL, dctl);
            ret = dwc2_exit_hibernation(hsotg, true);
            if (ret && (ret != -ENOTSUPP))
                dev_err(hsotg->dev, "exit hibernation failed\n");

            call_gadget(hsotg, resume);
        }
        /* Change to L0 state */
        hsotg->lx_state = DWC2_L0;
    } else {
        if (hsotg->lx_state != DWC2_L1) {
            u32 pcgcctl = DWC2_READ_4(hsotg, PCGCTL);

            /* Restart the Phy Clock */
            pcgcctl &= ~PCGCTL_STOPPCLK;
            DWC2_WRITE_4(hsotg, PCGCTL, pcgcctl);
            callout_reset(&hsotg->wkp_timer, mstohz(71),
                          dwc2_wakeup_detected, hsotg);
        } else {
            /* Change to L0 state */
            hsotg->lx_state = DWC2_L0;
        }
    }

    /* Clear interrupt */
    DWC2_WRITE_4(hsotg, GINTSTS, GINTSTS_WKUPINT);
}
示例#19
0
int
rump_netconfig_ipv6_ifaddr(const char *ifname, const char *addr, int prefixlen)
{
	struct sockaddr_in6 *sin6;
	struct in6_aliasreq ia;
	int rv;

	CHECKDOMAIN(in6so);

	/* pfft, you do the bitnibbling */
	if (prefixlen % 8)
		return EINVAL;

	memset(&ia, 0, sizeof(ia));
	strlcpy(ia.ifra_name, ifname, sizeof(ia.ifra_name));

	ia.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
	ia.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;

	sin6 = (struct sockaddr_in6 *)&ia.ifra_addr;
	sin6->sin6_family = AF_INET6;
	sin6->sin6_len = sizeof(*sin6);
	netconfig_inet_pton6(addr, &sin6->sin6_addr);

	sin6 = (struct sockaddr_in6 *)&ia.ifra_prefixmask;
	sin6->sin6_family = AF_INET6;
	sin6->sin6_len = sizeof(*sin6);
	memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));
	memset(&sin6->sin6_addr, 0xff, prefixlen / 8);

	rv = wrapifioctl(in6so, SIOCAIFADDR_IN6, &ia);
	/*
	 * small pause so that we can assume interface is usable when
	 * we return (ARPs have trickled through, etc.)
	 */
	if (rv == 0)
		kpause("ramasee", false, mstohz(50), NULL);
	return rv;
}
示例#20
0
static usbd_status
open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *))
{
	struct umidi_endpoint *ep = jack->endpoint;
	umidi_packet_bufp end;
	int s;
	int err;

	if (jack->opened)
		return USBD_IN_USE;

	jack->arg = arg;
	jack->u.out.intr = intr;
	jack->midiman_ppkt = NULL;
	end = ep->buffer + ep->buffer_size / sizeof *ep->buffer;
	s = splusb();
	jack->opened = 1;
	ep->num_open++;
	/*
	 * out_solicit maintains an invariant that there will always be
	 * (num_open - num_scheduled) slots free in the buffer. as we have
	 * just incremented num_open, the buffer may be too full to satisfy
	 * the invariant until a transfer completes, for which we must wait.
	 */
	while ( end - ep->next_slot < ep->num_open - ep->num_scheduled ) {
		err = tsleep(ep, PWAIT|PCATCH, "umi op", mstohz(10));
		if ( err ) {
			ep->num_open--;
			jack->opened = 0;
			splx(s);
			return USBD_IOERROR;
		}
	}
	splx(s);

	return USBD_NORMAL_COMPLETION;
}
示例#21
0
static int
cfg_ipv4(const char *ifname, const char *addr, in_addr_t m_addr)
{
	struct ifaliasreq ia;
	struct sockaddr_in *sin;
	int rv;

	CHECKDOMAIN(in4so);

	memset(&ia, 0, sizeof(ia));
	strlcpy(ia.ifra_name, ifname, sizeof(ia.ifra_name));

	sin = (struct sockaddr_in *)&ia.ifra_addr;
	sin->sin_family = AF_INET;
	sin->sin_len = sizeof(*sin);
	sin->sin_addr.s_addr = inet_addr(addr);

	sin = (struct sockaddr_in *)&ia.ifra_mask;
	sin->sin_family = AF_INET;
	sin->sin_len = sizeof(*sin);
	sin->sin_addr.s_addr = m_addr;

	sin = (struct sockaddr_in *)&ia.ifra_broadaddr;
	sin->sin_family = AF_INET;
	sin->sin_len = sizeof(*sin);
	sin->sin_addr.s_addr = inet_addr(addr) | ~m_addr;

	rv = wrapifioctl(in4so, SIOCAIFADDR, &ia);
	/*
	 * small pause so that we can assume interface is usable when
	 * we return (ARPs have trickled through, etc.)
	 */
	if (rv == 0)
		kpause("ramasee", false, mstohz(50), NULL);
	return rv;
}
示例#22
0
static void
close_out_jack(struct umidi_jack *jack)
{
	struct umidi_endpoint *ep;
	int s;
	u_int16_t mask;
	int err;

	if (jack->opened) {
		ep = jack->endpoint;
		mask = 1 << (jack->cable_number);
		s = splusb();
		while ( mask & (ep->this_schedule | ep->next_schedule) ) {
			err = tsleep(ep, PWAIT|PCATCH, "umi dr", mstohz(10));
			if ( err )
				break;
		}
		jack->opened = 0;
		jack->endpoint->num_open--;
		ep->this_schedule &= ~mask;
		ep->next_schedule &= ~mask;
		splx(s);
	}
}
示例#23
0
int
dme_attach(struct dme_softc *sc, const uint8_t *enaddr)
{
    struct ifnet	*ifp = &sc->sc_ethercom.ec_if;
    uint8_t		b[2];
    uint16_t	io_mode;

    dme_read_c(sc, DM9000_VID0, b, 2);
#if BYTE_ORDER == BIG_ENDIAN
    sc->sc_vendor_id = (b[0] << 8) | b[1];
#else
    sc->sc_vendor_id = b[0] | (b[1] << 8);
#endif
    dme_read_c(sc, DM9000_PID0, b, 2);
#if BYTE_ORDER == BIG_ENDIAN
    sc->sc_product_id = (b[0] << 8) | b[1];
#else
    sc->sc_product_id = b[0] | (b[1] << 8);
#endif
    /* TODO: Check the vendor ID as well */
    if (sc->sc_product_id != 0x9000) {
        panic("dme_attach: product id mismatch (0x%hx != 0x9000)",
              sc->sc_product_id);
    }

    /* Initialize ifnet structure. */
    strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    ifp->if_softc = sc;
    ifp->if_start = dme_start_output;
    ifp->if_init = dme_init;
    ifp->if_ioctl = dme_ioctl;
    ifp->if_stop = dme_stop;
    ifp->if_watchdog = NULL;	/* no watchdog at this stage */
    ifp->if_flags = IFF_SIMPLEX | IFF_NOTRAILERS | IFF_BROADCAST |
                    IFF_MULTICAST;
    IFQ_SET_READY(&ifp->if_snd);

    /* Initialize ifmedia structures. */
    ifmedia_init(&sc->sc_media, 0, dme_mediachange, dme_mediastatus);
    ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_AUTO, 0, NULL);
    ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
    ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_T, 0, NULL);
    ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
    ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_100_TX, 0, NULL);

    ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);

    if (enaddr != NULL)
        memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr));
    /* TODO: Support an EEPROM attached to the DM9000 chip */

    callout_init(&sc->sc_link_callout, 0);
    callout_setfunc(&sc->sc_link_callout, dme_phy_check_link, sc);

    sc->sc_media_status = 0;

    /* Configure DM9000 with the MAC address */
    dme_write_c(sc, DM9000_PAB0, sc->sc_enaddr, 6);

#ifdef DM9000_DEBUG
    {
        uint8_t macAddr[6];
        dme_read_c(sc, DM9000_PAB0, macAddr, 6);
        printf("DM9000 configured with MAC address: ");
        for (int i = 0; i < 6; i++) {
            printf("%02X:", macAddr[i]);
        }
        printf("\n");
    }
#endif

    if_attach(ifp);
    ether_ifattach(ifp, sc->sc_enaddr);

#ifdef DM9000_DEBUG
    {
        uint8_t network_state;
        network_state = dme_read(sc, DM9000_NSR);
        printf("DM9000 Link status: ");
        if (network_state & DM9000_NSR_LINKST) {
            if (network_state & DM9000_NSR_SPEED)
                printf("10Mbps");
            else
                printf("100Mbps");
        } else {
            printf("Down");
        }
        printf("\n");
    }
#endif

    io_mode = (dme_read(sc, DM9000_ISR) &
               DM9000_IOMODE_MASK) >> DM9000_IOMODE_SHIFT;
    if (io_mode != DM9000_MODE_16BIT )
        panic("DM9000: Only 16-bit mode is supported!\n");

    DPRINTF(("DM9000 Operation Mode: "));
    switch( io_mode) {
    case DM9000_MODE_16BIT:
        DPRINTF(("16-bit mode"));
        sc->sc_data_width = 2;
        sc->sc_pkt_write = dme_pkt_write_2;
        sc->sc_pkt_read = dme_pkt_read_2;
        break;
    case DM9000_MODE_32BIT:
        DPRINTF(("32-bit mode"));
        sc->sc_data_width = 4;
        break;
    case DM9000_MODE_8BIT:
        DPRINTF(("8-bit mode"));
        sc->sc_data_width = 1;
        break;
    default:
        DPRINTF(("Invalid mode"));
        break;
    }
    DPRINTF(("\n"));

    callout_schedule(&sc->sc_link_callout, mstohz(2000));

    return 0;
}
示例#24
0
void
wsmouse_input(device_t wsmousedev, u_int btns /* 0 is up */,
	int x, int y, int z, int w, u_int flags)
{
	struct wsmouse_softc *sc = device_private(wsmousedev);
	struct wseventvar *evar;
	int mb, ub, d, nevents;
	/* one for each dimension (4) + a bit for each button */
	struct wscons_event events[4 + sizeof(d) * 8];

        /*
         * Discard input if not open.
         */
	evar = sc->sc_base.me_evp;
	if (evar == NULL)
		return;

#ifdef DIAGNOSTIC
	if (evar->q == NULL) {
		printf("wsmouse_input: evar->q=NULL\n");
		return;
	}
#endif

#if NWSMUX > 0
	DPRINTFN(5,("wsmouse_input: %s mux=%p, evar=%p\n",
		    device_xname(sc->sc_base.me_dv),
		    sc->sc_base.me_parent, evar));
#endif

	sc->sc_mb = btns;
	if (!(flags & WSMOUSE_INPUT_ABSOLUTE_X))
		sc->sc_dx += x;
	if (!(flags & WSMOUSE_INPUT_ABSOLUTE_Y))
		sc->sc_dy += y;
	if (!(flags & WSMOUSE_INPUT_ABSOLUTE_Z))
		sc->sc_dz += z;
	if (!(flags & WSMOUSE_INPUT_ABSOLUTE_W))
		sc->sc_dw += w;

	/*
	 * We have at least one event (mouse button, delta-X, or
	 * delta-Y; possibly all three, and possibly three separate
	 * button events).  Deliver these events until we are out
	 * of changes or out of room.  As events get delivered,
	 * mark them `unchanged'.
	 */
	ub = sc->sc_ub;
	nevents = 0;

	if (flags & WSMOUSE_INPUT_ABSOLUTE_X) {
		if (sc->sc_x != x) {
			events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_X;
			events[nevents].value = x;
			nevents++;
		}
	} else {
		if (sc->sc_dx) {
			events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_X;
			events[nevents].value = sc->sc_dx;
			nevents++;
		}
	}
	if (flags & WSMOUSE_INPUT_ABSOLUTE_Y) {
		if (sc->sc_y != y) {
			events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_Y;
			events[nevents].value = y;
			nevents++;
		}
	} else {
		if (sc->sc_dy) {
			events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_Y;
			events[nevents].value = sc->sc_dy;
			nevents++;
		}
	}
	if (flags & WSMOUSE_INPUT_ABSOLUTE_Z) {
		if (sc->sc_z != z) {
			events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_Z;
			events[nevents].value = z;
			nevents++;
		}
	} else {
		if (sc->sc_dz) {
			events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_Z;
			events[nevents].value = sc->sc_dz;
			nevents++;
		}
	}
	if (flags & WSMOUSE_INPUT_ABSOLUTE_W) {
		if (sc->sc_w != w) {
			events[nevents].type = WSCONS_EVENT_MOUSE_ABSOLUTE_W;
			events[nevents].value = w;
			nevents++;
		}
	} else {
		if (sc->sc_dw) {
			events[nevents].type = WSCONS_EVENT_MOUSE_DELTA_W;
			events[nevents].value = sc->sc_dw;
			nevents++;
		}
	}

	mb = sc->sc_mb;
	while ((d = mb ^ ub) != 0) {
		int btnno;

		/*
		 * Cancel button repeating if button status changed.
		 */
		if (sc->sc_repeat_button != -1) {
			KASSERT(sc->sc_repeat_button >= 0);
			KASSERT(sc->sc_repeat.wr_buttons &
                            (1 << sc->sc_repeat_button));
			ub &= ~(1 << sc->sc_repeat_button);
			sc->sc_repeat_button = -1;
			callout_stop(&sc->sc_repeat_callout);
		}

		/*
		 * Mouse button change.  Find the first change and drop
		 * it into the event queue.
		 */
		btnno = ffs(d) - 1;
		KASSERT(btnno >= 0);

		if (nevents >= sizeof(events) / sizeof(events[0])) {
			aprint_error_dev(sc->sc_base.me_dv,
			    "Event queue full (button status mb=0x%x"
			    " ub=0x%x)\n", mb, ub);
			break;
		}

		events[nevents].type =
		    (mb & d) ? WSCONS_EVENT_MOUSE_DOWN : WSCONS_EVENT_MOUSE_UP;
		events[nevents].value = btnno;
		nevents++;

		ub ^= (1 << btnno);

		/*
		 * Program button repeating if configured for this button.
		 */
		if ((mb & d) && (sc->sc_repeat.wr_buttons & (1 << btnno)) &&
		    sc->sc_repeat.wr_delay_first > 0) {
			sc->sc_repeat_button = btnno;
			sc->sc_repeat_delay = sc->sc_repeat.wr_delay_first;
			callout_schedule(&sc->sc_repeat_callout,
			    mstohz(sc->sc_repeat_delay));
		}
	}

	if (nevents == 0 || wsevent_inject(evar, events, nevents) == 0) {
		/* All events were correctly injected into the queue.
		 * Synchronize the mouse's status with what the user
		 * has received. */
		sc->sc_x = x; sc->sc_dx = 0;
		sc->sc_y = y; sc->sc_dy = 0;
		sc->sc_z = z; sc->sc_dz = 0;
		sc->sc_w = w; sc->sc_dw = 0;
		sc->sc_ub = ub;
#if NWSMUX > 0
		DPRINTFN(5,("wsmouse_input: %s wakeup evar=%p\n",
			    device_xname(sc->sc_base.me_dv), evar));
#endif
	}
}
示例#25
0
static void
wdc_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer)
{
	struct atac_softc *atac = chp->ch_atac;
	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
	struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
	int wait_flags = (sc_xfer->xs_control & XS_CTL_POLL) ? AT_POLL : 0;
	const char *errstring;

	ATADEBUG_PRINT(("wdc_atapi_start %s:%d:%d, scsi flags 0x%x \n",
	    device_xname(atac->atac_dev), chp->ch_channel, drvp->drive,
	    sc_xfer->xs_control), DEBUG_XFERS);
#if NATA_DMA
	if ((xfer->c_flags & C_DMA) && (drvp->n_xfers <= NXFER))
		drvp->n_xfers++;
#endif
	/* Do control operations specially. */
	if (__predict_false(drvp->state < READY)) {
		/* If it's not a polled command, we need the kernel thread */
		if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 &&
		    (chp->ch_flags & ATACH_TH_RUN) == 0) {
			chp->ch_queue->queue_freeze++;
			wakeup(&chp->ch_thread);
			return;
		}
		/*
		 * disable interrupts, all commands here should be quick
		 * enough to be able to poll, and we don't go here that often
		 */
		bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
		     WDCTL_4BIT | WDCTL_IDS);
		if (wdc->select)
			wdc->select(chp, xfer->c_drive);
		bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
		    WDSD_IBM | (xfer->c_drive << 4));
		/* Don't try to set mode if controller can't be adjusted */
		if (atac->atac_set_modes == NULL)
			goto ready;
		/* Also don't try if the drive didn't report its mode */
		if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0)
			goto ready;
		errstring = "unbusy";
		if (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags))
			goto timeout;
		wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
		    0x08 | drvp->PIO_mode, WDSF_SET_MODE);
		errstring = "piomode";
		if (wdc_wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags))
			goto timeout;
		if (chp->ch_status & WDCS_ERR) {
			if (chp->ch_error == WDCE_ABRT) {
				/*
				 * Some ATAPI drives reject PIO settings.
				 * Fall back to PIO mode 3 since that's the
				 * minimum for ATAPI.
				 */
				printf("%s:%d:%d: PIO mode %d rejected, "
				    "falling back to PIO mode 3\n",
				    device_xname(atac->atac_dev),
				    chp->ch_channel, xfer->c_drive,
				    drvp->PIO_mode);
				if (drvp->PIO_mode > 3)
					drvp->PIO_mode = 3;
			} else
				goto error;
		}
#if NATA_DMA
#if NATA_UDMA
		if (drvp->drive_flags & ATA_DRIVE_UDMA) {
			wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
			    0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
		} else
#endif
		if (drvp->drive_flags & ATA_DRIVE_DMA) {
			wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
			    0x20 | drvp->DMA_mode, WDSF_SET_MODE);
		} else {
			goto ready;
		}
		errstring = "dmamode";
		if (wdc_wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags))
			goto timeout;
		if (chp->ch_status & WDCS_ERR) {
			if (chp->ch_error == WDCE_ABRT) {
#if NATA_UDMA
				if (drvp->drive_flags & ATA_DRIVE_UDMA)
					goto error;
				else
#endif
				{
					/*
					 * The drive rejected our DMA setting.
					 * Fall back to mode 1.
					 */
					printf("%s:%d:%d: DMA mode %d rejected, "
					    "falling back to DMA mode 0\n",
					    device_xname(atac->atac_dev),
					    chp->ch_channel, xfer->c_drive,
					    drvp->DMA_mode);
					if (drvp->DMA_mode > 0)
						drvp->DMA_mode = 0;
				}
			} else
				goto error;
		}
#endif	/* NATA_DMA */
ready:
		drvp->state = READY;
		bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
		    WDCTL_4BIT);
		delay(10); /* some drives need a little delay here */
	}
	/* start timeout machinery */
	if ((sc_xfer->xs_control & XS_CTL_POLL) == 0)
		callout_reset(&chp->ch_callout, mstohz(sc_xfer->timeout),
		    wdctimeout, chp);

	if (wdc->select)
		wdc->select(chp, xfer->c_drive);
	bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
	    WDSD_IBM | (xfer->c_drive << 4));
	switch (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags)) {
	case WDCWAIT_OK:
		break;
	case WDCWAIT_TOUT:
		printf("wdc_atapi_start: not ready, st = %02x\n",
		    chp->ch_status);
		sc_xfer->error = XS_TIMEOUT;
		wdc_atapi_reset(chp, xfer);
		return;
	case WDCWAIT_THR:
		return;
	}

	/*
	 * Even with WDCS_ERR, the device should accept a command packet
	 * Limit length to what can be stuffed into the cylinder register
	 * (16 bits).  Some CD-ROMs seem to interpret '0' as 65536,
	 * but not all devices do that and it's not obvious from the
	 * ATAPI spec that that behaviour should be expected.  If more
	 * data is necessary, multiple data transfer phases will be done.
	 */

	wdccommand(chp, xfer->c_drive, ATAPI_PKT_CMD,
	    xfer->c_bcount <= 0xffff ? xfer->c_bcount : 0xffff,
	    0, 0, 0,
#if NATA_DMA
	    (xfer->c_flags & C_DMA) ? ATAPI_PKT_CMD_FTRE_DMA :
#endif
	    0
	    );

#if NATA_PIOBM
	if (xfer->c_flags & C_PIOBM) {
		int error;
		int dma_flags = (sc_xfer->xs_control & XS_CTL_DATA_IN)
		    ?  WDC_DMA_READ : 0;
		if (xfer->c_flags & C_POLL) {
			/* XXX not supported yet --- fall back to PIO */
			xfer->c_flags &= ~C_PIOBM;
		} else {
			/* Init the DMA channel. */
			error = (*wdc->dma_init)(wdc->dma_arg,
			    chp->ch_channel, xfer->c_drive,
			    (char *)xfer->c_databuf,
			    xfer->c_bcount,
			    dma_flags | WDC_DMA_PIOBM_ATAPI);
			if (error) {
				if (error == EINVAL) {
					/*
					 * We can't do DMA on this transfer
					 * for some reason.  Fall back to
					 * PIO.
					 */
					xfer->c_flags &= ~C_PIOBM;
					error = 0;
				} else {
					sc_xfer->error = XS_DRIVER_STUFFUP;
					errstring = "piobm";
					goto error;
				}
			}
		}
	}
#endif
	/*
	 * If there is no interrupt for CMD input, busy-wait for it (done in
	 * the interrupt routine. If it is a polled command, call the interrupt
	 * routine until command is done.
	 */
	if ((sc_xfer->xs_periph->periph_cap & ATAPI_CFG_DRQ_MASK) !=
	    ATAPI_CFG_IRQ_DRQ || (sc_xfer->xs_control & XS_CTL_POLL)) {
		/* Wait for at last 400ns for status bit to be valid */
		DELAY(1);
		wdc_atapi_intr(chp, xfer, 0);
	} else {
		chp->ch_flags |= ATACH_IRQ_WAIT;
	}
	if (sc_xfer->xs_control & XS_CTL_POLL) {
#if NATA_DMA
		if (chp->ch_flags & ATACH_DMA_WAIT) {
			wdc_dmawait(chp, xfer, sc_xfer->timeout);
			chp->ch_flags &= ~ATACH_DMA_WAIT;
		}
#endif
		while ((sc_xfer->xs_status & XS_STS_DONE) == 0) {
			/* Wait for at last 400ns for status bit to be valid */
			DELAY(1);
			wdc_atapi_intr(chp, xfer, 0);
		}
	}
	return;
timeout:
	printf("%s:%d:%d: %s timed out\n",
	    device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
	    errstring);
	sc_xfer->error = XS_TIMEOUT;
	bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
	delay(10); /* some drives need a little delay here */
	wdc_atapi_reset(chp, xfer);
	return;
error:
	printf("%s:%d:%d: %s ",
	    device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
	    errstring);
	printf("error (0x%x)\n", chp->ch_error);
	sc_xfer->error = XS_SHORTSENSE;
	sc_xfer->sense.atapi_sense = chp->ch_error;
	bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
	delay(10); /* some drives need a little delay here */
	wdc_atapi_reset(chp, xfer);
	return;
}
示例#26
0
文件: vmt.c 项目: goroutines/rumprun
static void
vmt_attach(device_t parent, device_t self, void *aux)
{
	int rv;
	struct vmt_softc *sc = device_private(self);

	aprint_naive("\n");
	aprint_normal(": %s\n", vmt_type());

	sc->sc_dev = self;
	sc->sc_log = NULL;

	callout_init(&sc->sc_tick, 0);
	callout_init(&sc->sc_tclo_tick, 0);
	callout_init(&sc->sc_clock_sync_tick, 0);

	sc->sc_clock_sync_period_seconds = VMT_CLOCK_SYNC_PERIOD_SECONDS;

	rv = vmt_sysctl_setup_root(self);
	if (rv != 0) {
		aprint_error_dev(self, "failed to initialize sysctl "
		    "(err %d)\n", rv);
		goto free;
	}

	sc->sc_rpc_buf = kmem_alloc(VMT_RPC_BUFLEN, KM_SLEEP);
	if (sc->sc_rpc_buf == NULL) {
		aprint_error_dev(self, "unable to allocate buffer for RPC\n");
		goto free;
	}

	if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) {
		aprint_error_dev(self, "failed to open backdoor RPC channel (TCLO protocol)\n");
		goto free;
	}
	sc->sc_tclo_rpc_open = true;

	/* don't know if this is important at all yet */
	if (vm_rpc_send_rpci_tx(sc, "tools.capability.hgfs_server toolbox 1") != 0) {
		aprint_error_dev(self, "failed to set HGFS server capability\n");
		goto free;
	}

	pmf_device_register1(self, NULL, NULL, vmt_shutdown);

	sysmon_task_queue_init();

	sc->sc_ev_power.ev_smpsw.smpsw_type = PSWITCH_TYPE_POWER;
	sc->sc_ev_power.ev_smpsw.smpsw_name = device_xname(self);
	sc->sc_ev_power.ev_code = PSWITCH_EVENT_PRESSED;
	sysmon_pswitch_register(&sc->sc_ev_power.ev_smpsw);
	sc->sc_ev_reset.ev_smpsw.smpsw_type = PSWITCH_TYPE_RESET;
	sc->sc_ev_reset.ev_smpsw.smpsw_name = device_xname(self);
	sc->sc_ev_reset.ev_code = PSWITCH_EVENT_PRESSED;
	sysmon_pswitch_register(&sc->sc_ev_reset.ev_smpsw);
	sc->sc_ev_sleep.ev_smpsw.smpsw_type = PSWITCH_TYPE_SLEEP;
	sc->sc_ev_sleep.ev_smpsw.smpsw_name = device_xname(self);
	sc->sc_ev_sleep.ev_code = PSWITCH_EVENT_RELEASED;
	sysmon_pswitch_register(&sc->sc_ev_sleep.ev_smpsw);
	sc->sc_smpsw_valid = true;

	callout_setfunc(&sc->sc_tick, vmt_tick, sc);
	callout_schedule(&sc->sc_tick, hz);

	callout_setfunc(&sc->sc_tclo_tick, vmt_tclo_tick, sc);
	callout_schedule(&sc->sc_tclo_tick, hz);
	sc->sc_tclo_ping = 1;

	callout_setfunc(&sc->sc_clock_sync_tick, vmt_clock_sync_tick, sc);
	callout_schedule(&sc->sc_clock_sync_tick,
	    mstohz(sc->sc_clock_sync_period_seconds * 1000));

	vmt_sync_guest_clock(sc);

	return;

free:
	if (sc->sc_rpc_buf)
		kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN);
	pmf_device_register(self, NULL, NULL);
	if (sc->sc_log)
		sysctl_teardown(&sc->sc_log);
}
示例#27
0
static void
wdc_atapi_phase_complete(struct ata_xfer *xfer)
{
	struct ata_channel *chp = xfer->c_chp;
	struct atac_softc *atac = chp->ch_atac;
#if NATA_DMA || NATA_PIOBM
	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
#endif
	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];

	/* wait for DSC if needed */
	if (drvp->drive_flags & ATA_DRIVE_ATAPIDSCW) {
		ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) "
		    "polldsc %d\n", device_xname(atac->atac_dev),
		    chp->ch_channel,
		    xfer->c_drive, xfer->c_dscpoll), DEBUG_XFERS);
#if 1
		if (cold)
			panic("wdc_atapi_phase_complete: cold");
#endif
		if (wdcwait(chp, WDCS_DSC, WDCS_DSC, 10,
		    AT_POLL) == WDCWAIT_TOUT) {
			/* 10ms not enough, try again in 1 tick */
			if (xfer->c_dscpoll++ >
			    mstohz(sc_xfer->timeout)) {
				printf("%s:%d:%d: wait_for_dsc "
				    "failed\n",
				    device_xname(atac->atac_dev),
				    chp->ch_channel, xfer->c_drive);
				sc_xfer->error = XS_TIMEOUT;
				wdc_atapi_reset(chp, xfer);
				return;
			} else
				callout_reset(&chp->ch_callout, 1,
				    wdc_atapi_polldsc, xfer);
			return;
		}
	}

	/*
	 * Some drive occasionally set WDCS_ERR with
	 * "ATA illegal length indication" in the error
	 * register. If we read some data the sense is valid
	 * anyway, so don't report the error.
	 */
	if (chp->ch_status & WDCS_ERR &&
	    ((sc_xfer->xs_control & XS_CTL_REQSENSE) == 0 ||
	    sc_xfer->resid == sc_xfer->datalen)) {
		/* save the short sense */
		sc_xfer->error = XS_SHORTSENSE;
		sc_xfer->sense.atapi_sense = chp->ch_error;
		if ((sc_xfer->xs_periph->periph_quirks &
		    PQUIRK_NOSENSE) == 0) {
			/* ask scsipi to send a REQUEST_SENSE */
			sc_xfer->error = XS_BUSY;
			sc_xfer->status = SCSI_CHECK;
		}
#if NATA_DMA || NATA_PIOBM
		else if (wdc->dma_status &
		    (WDC_DMAST_NOIRQ | WDC_DMAST_ERR)) {
#if NATA_DMA
			ata_dmaerr(drvp,
			    (xfer->c_flags & C_POLL) ? AT_POLL : 0);
#endif
			sc_xfer->error = XS_RESET;
			wdc_atapi_reset(chp, xfer);
			return;
		}
#endif
	}
	if (xfer->c_bcount != 0) {
		ATADEBUG_PRINT(("wdc_atapi_intr: bcount value is "
		    "%d after io\n", xfer->c_bcount), DEBUG_XFERS);
	}
#ifdef DIAGNOSTIC
	if (xfer->c_bcount < 0) {
		printf("wdc_atapi_intr warning: bcount value "
		    "is %d after io\n", xfer->c_bcount);
	}
#endif
	ATADEBUG_PRINT(("wdc_atapi_phase_complete: wdc_atapi_done(), "
	    "error 0x%x sense 0x%x\n", sc_xfer->error,
	    sc_xfer->sense.atapi_sense), DEBUG_INTR);
	wdc_atapi_done(chp, xfer);
}
示例#28
0
void
dbau1550_slot_enable(int slot)
{
	uint16_t	status;
	uint16_t	vcc, vpp;
	int		shift;

	status = GET16(DBAU1550_STATUS);
	switch (slot) {
	case 0:
		status >>= DBAU1550_STATUS_PCMCIA0_VS_SHIFT;
		shift = DBAU1550_PCMCIA_PC0_SHIFT;
		break;
	case 1:
		status >>= DBAU1550_STATUS_PCMCIA1_VS_SHIFT;
		shift = DBAU1550_PCMCIA_PC1_SHIFT;
		break;
	default:
		return;
	}

	status &= DBAU1550_STATUS_PCMCIA_VS_MASK;
	switch (status) {
	case DBAU1550_STATUS_PCMCIA_VS_GND:
		vcc = DBAU1550_PCMCIA_VCC_GND;
		vpp = DBAU1550_PCMCIA_VPP_GND;
		break;
	case DBAU1550_STATUS_PCMCIA_VS_5V:
		vcc = DBAU1550_PCMCIA_VCC_5V;
		vpp = DBAU1550_PCMCIA_VPP_VCC;
		break;
	default:	/* covers both 3.3v cases */
		vcc = DBAU1550_PCMCIA_VCC_3V;
		vpp = DBAU1550_PCMCIA_VPP_VCC;
		break;
	}

	status = GET16(DBAU1550_PCMCIA);

	/* this clears all bits for this slot */
	status &= ~(DBAU1550_PCMCIA_MASK << shift);

	status |= vcc << shift;
	status |= vpp << shift;

	PUT16(DBAU1550_PCMCIA, status);
	wbflush();
	tsleep(&status, PWAIT, "pcmcia_reset_0", mstohz(100));

	status |= (DBAU1550_PCMCIA_DRV_EN << shift);
	PUT16(DBAU1550_PCMCIA, status);
	wbflush();
	tsleep(&status, PWAIT, "pcmcia_reset_start", mstohz(300));

	/* take it out of reset */
	status |= (DBAU1550_PCMCIA_RST << shift);
	PUT16(DBAU1550_PCMCIA, status);
	wbflush();

	/* spec says 20 msec, but experience shows even 200 is not enough */
	tsleep(&status, PWAIT, "pcmcia_reset_finish", mstohz(1000));

	/* NOTE: WE DO NOT SUPPORT DIFFERENT VCC/VPP LEVELS! */
	/* This means that 12V cards are not supported! */
}