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); }
/* * 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; }
/* * 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); }
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); }
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); }
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); }
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 = . 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; }
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); }
static void awin_hdmi_thread(void *priv) { struct awin_hdmi_softc *sc = priv; for (;;) { awin_hdmi_hpd(sc); kpause("hdmihotplug", false, mstohz(1000), NULL); } }
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)); }
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! */ } }
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); }
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); }
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); }
/* * 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); }
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; }
/* * 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); }
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; }
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; }
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; }
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); } }
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; }
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 } }
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; }
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); }
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); }
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! */ }