static void atkbd_timeout(void *arg) { atkbd_state_t *state; keyboard_t *kbd; int s; /* * The original text of the following comments are extracted * from syscons.c (1.287) * * With release 2.1 of the Xaccel server, the keyboard is left * hanging pretty often. Apparently an interrupt from the * keyboard is lost, and I don't know why (yet). * This ugly hack calls the low-level interrupt routine if input * is ready for the keyboard and conveniently hides the problem. XXX * * Try removing anything stuck in the keyboard controller; whether * it's a keyboard scan code or mouse data. The low-level * interrupt routine doesn't read the mouse data directly, * but the keyboard controller driver will, as a side effect. */ /* * And here is bde's original comment about this: * * This is necessary to handle edge triggered interrupts - if we * returned when our IRQ is high due to unserviced input, then there * would be no more keyboard IRQs until the keyboard is reset by * external powers. * * The keyboard apparently unwedges the irq in most cases. */ s = spltty(); kbd = (keyboard_t *)arg; if (kbdd_lock(kbd, TRUE)) { /* * We have seen the lock flag is not set. Let's reset * the flag early, otherwise the LED update routine fails * which may want the lock during the interrupt routine. */ kbdd_lock(kbd, FALSE); if (kbdd_check_char(kbd)) kbdd_intr(kbd, NULL); } splx(s); state = (atkbd_state_t *)kbd->kb_data; callout_reset(&state->ks_timer, hz / 10, atkbd_timeout, arg); }
int xb_write(const void *data, unsigned len) { struct xenstore_domain_interface *intf = xenstore_domain_interface(); XENSTORE_RING_IDX cons, prod; int s = spltty(); while (len != 0) { void *dst; unsigned int avail; while ((intf->req_prod - intf->req_cons) == XENSTORE_RING_SIZE) { XENPRINTF(("xb_write tsleep\n")); tsleep(&xenstore_interface, PRIBIO, "wrst", 0); XENPRINTF(("xb_write tsleep done\n")); } /* Read indexes, then verify. */ cons = intf->req_cons; prod = intf->req_prod; x86_lfence(); if (!check_indexes(cons, prod)) { splx(s); return EIO; } dst = get_output_chunk(cons, prod, intf->req, &avail); if (avail == 0) continue; if (avail > len) avail = len; memcpy(dst, data, avail); data = (const char *)data + avail; len -= avail; /* Other side must not see new header until data is there. */ x86_lfence(); intf->req_prod += avail; x86_lfence(); hypervisor_notify_via_evtchn(xen_start_info.store_evtchn); } splx(s); return 0; }
int ptcpoll(dev_t dev, int events, struct proc *p) { struct pt_softc *pti = pt_softc[minor(dev)]; struct tty *tp = pti->pt_tty; int revents = 0, s; if (!ISSET(tp->t_state, TS_ISOPEN) && ISSET(tp->t_state, TS_CARR_ON)) goto notopen; if (events & (POLLIN | POLLRDNORM)) { /* * Need to protect access to t_outq */ s = spltty(); if ((tp->t_outq.c_cc && !ISSET(tp->t_state, TS_TTSTOP)) || ((pti->pt_flags & PF_PKT) && pti->pt_send) || ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) revents |= events & (POLLIN | POLLRDNORM); splx(s); } /* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */ if (!ISSET(tp->t_state, TS_CARR_ON)) { revents |= POLLHUP; } else if (events & (POLLOUT | POLLWRNORM)) { if ((pti->pt_flags & PF_REMOTE) ? (tp->t_canq.c_cc == 0) : ((tp->t_rawq.c_cc + tp->t_canq.c_cc < TTYHOG(tp) - 2) || (tp->t_canq.c_cc == 0 && ISSET(tp->t_lflag, ICANON)))) revents |= events & (POLLOUT | POLLWRNORM); } if (events & (POLLPRI | POLLRDBAND)) { /* If in packet or user control mode, check for data. */ if (((pti->pt_flags & PF_PKT) && pti->pt_send) || ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) revents |= events & (POLLPRI | POLLRDBAND); } if (revents == 0) { notopen: if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) selrecord(p, &pti->pt_selr); if (events & (POLLOUT | POLLWRNORM)) selrecord(p, &pti->pt_selw); } return (revents); }
void sabstop(struct tty *tp, int flag) { struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(tp->t_dev)); int s; s = spltty(); if (tp->t_state & TS_BUSY) { if ((tp->t_state & TS_TTSTOP) == 0) tp->t_state |= TS_FLUSH; sc->sc_flags |= SABTTYF_STOP; sc->sc_imr1 &= ~SAB_IMR1_ALLS; SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); } splx(s); }
/* * Stop output on a line. */ void at91usart_stop(struct tty *tp, int flag) { struct at91usart_softc *sc = device_lookup_private(&at91usart_cd, COMUNIT(tp->t_dev)); int s; s = spltty(); if (ISSET(tp->t_state, TS_BUSY)) { /* Stop transmitting at the next chunk. */ sc->sc_tbc = 0; if (!ISSET(tp->t_state, TS_TTSTOP)) SET(tp->t_state, TS_FLUSH); } splx(s); }
void stty_stop(struct tty *tp, int flags) { struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(tp->t_dev)); struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)]; int s; s = spltty(); if (ISSET(tp->t_state, TS_BUSY)) { if (!ISSET(tp->t_state, TS_TTSTOP)) SET(tp->t_state, TS_FLUSH); SET(sp->sp_flags, STTYF_STOP); } splx(s); }
void dnkbd_bellstop(void *v) { struct dnkbd_softc *sc = v; int s; s = spltty(); dnkbd_pollout(sc->sc_regs, DNCMD_PREFIX); dnkbd_pollout(sc->sc_regs, DNCMD_BELL); dnkbd_pollout(sc->sc_regs, DNCMD_BELL_OFF); CLR(sc->sc_flags, SF_BELL); CLR(sc->sc_flags, SF_BELL_TMO); splx(s); }
void sscomstart(struct tty *tp) { struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(tp->t_dev)); int s; if (SSCOM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); (void)splserial(); SSCOM_LOCK(sc); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Output the first chunk of the contiguous buffer. */ sscom_output_chunk(sc); /* Enable transmit completion interrupts if necessary. */ if ((sc->sc_hwflags & SSCOM_HW_TXINT) == 0) sscom_enable_txint(sc); SSCOM_UNLOCK(sc); out: splx(s); return; }
int mbpp_recv(struct mbpp_port *mp, caddr_t ptr, int len) { int s; struct cd1400 *cd = mp->mp_cd1400; /* set up io information */ mp->mp_ptr = ptr; mp->mp_cnt = len; /* start receiving */ s = spltty(); if (cd) { int rcor, rbpr; CD1400_WRITE_REG(cd, CD1400_CAR, 0); /* input strobe at 100kbaud (10microseconds) */ cd1400_compute_baud(100000, cd->cd_clock, &rcor, &rbpr); CD1400_WRITE_REG(cd, CD1400_RCOR, rcor); CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr); /* rx threshold */ CD1400_WRITE_REG(cd, CD1400_COR3, MBPP_RX_FIFO_THRESHOLD); cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3); /* enable channel */ cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVEN); CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_RXDATA); } /* ZZzzz... */ tsleep(mp, PCATCH | PZERO, "mbpp_recv", 0); /* stop receiving */ if (cd) { CD1400_WRITE_REG(cd, CD1400_CAR, 0); /* disable receiving */ CD1400_WRITE_REG(cd, CD1400_SRER, 0); cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVDIS); } splx(s); /* return number of chars received */ return (len - mp->mp_cnt); }
static void btms_input(struct bthidev *hidev, uint8_t *data, int len) { struct btms_softc *sc = (struct btms_softc *)hidev; int dx, dy, dz, dw; uint32_t buttons; int i, s; if (sc->sc_wsmouse == NULL || sc->sc_enabled == 0) return; #ifdef BTMS_DEBUG if (btms_debug > 9) { printf("%s: data: ", __func__); for (i = 0; i < len; ++i) { printf("%02x", data[i]); } printf("\n"); } #endif dx = hid_get_data(data, &sc->sc_loc_x); dy = -hid_get_data(data, &sc->sc_loc_y); dz = hid_get_data(data, &sc->sc_loc_z); dw = hid_get_data(data, &sc->sc_loc_w); if (sc->sc_flags & BTMS_REVZ) dz = -dz; buttons = 0; for (i = 0 ; i < sc->sc_num_buttons ; i++) if (hid_get_data(data, &sc->sc_loc_button[i])) buttons |= BUTTON(i); BTMSDBGN(9,("%s: dx=%d, dy=%d, dz=%d, dw=%d, buttons=0x%08x\n", __func__, dx, dy, dz, dw, buttons)); if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || buttons != sc->sc_buttons) { sc->sc_buttons = buttons; s = spltty(); wsmouse_input(sc->sc_wsmouse, buttons, dx, dy, dz, dw, WSMOUSE_INPUT_DELTA); splx(s); } }
static int write_kbd(KBDC kbdc, int command, int data) { int s; /* prevent the timeout routine from polling the keyboard */ if (!kbdc_lock(kbdc, TRUE)) return EBUSY; /* disable the keyboard and mouse interrupt */ s = spltty(); #if 0 c = get_controller_command_byte(kbdc); if ((c == -1) || !set_controller_command_byte(kbdc, kbdc_get_device_mask(kbdc), KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { /* CONTROLLER ERROR */ kbdc_lock(kbdc, FALSE); splx(s); return EIO; } /* * Now that the keyboard controller is told not to generate * the keyboard and mouse interrupts, call `splx()' to allow * the other tty interrupts. The clock interrupt may also occur, * but the timeout routine (`scrn_timer()') will be blocked * by the lock flag set via `kbdc_lock()' */ splx(s); #endif if (send_kbd_command_and_data(kbdc, command, data) != KBD_ACK) send_kbd_command(kbdc, KBDC_ENABLE_KBD); #if 0 /* restore the interrupts */ if (!set_controller_command_byte(kbdc, kbdc_get_device_mask(kbdc), c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) { /* CONTROLLER ERROR */ } #else splx(s); #endif kbdc_lock(kbdc, FALSE); return 0; }
int dz_ebus_cngetc(dev_t dev) { int c, s; c = 0; s = spltty(); while ((dzcn->ChannelStatus & USI_RXRDY) == 0) DELAY(10); c = dzcn->RxData; splx(s); if (c == 13) /* map cr->ln */ c = 10; return c; }
static int wzero3kbd_poll1(void *arg) { struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; int row, col, data; int keycol; int keydown; int i; int s; if (!sc->sc_enabled) { DPRINTF(("wzero3kbd_poll: disabled\n")); return 0; } s = spltty(); for (col = 0; col < sc->sc_ncolumn; col++) { /* deselect column# and charge */ CSR_WRITE1(KBDCOL_L, 0); CSR_WRITE1(KBDCOL_U, 0); CSR_WRITE1(KBDCHARGE, 1); delay(KEYWAIT); CSR_WRITE1(KBDCHARGE, 0); /* select scan column# */ keycol = 1 << col; CSR_WRITE1(KBDCOL_L, keycol & 0xff); CSR_WRITE1(KBDCOL_U, keycol >> 8); delay(KEYWAIT); CSR_WRITE1(KBDCHARGE, 0); /* read key data */ data = CSR_READ1(KBDDATA); for (row = 0; row < sc->sc_nrow; row++) { #ifdef KEYTEST2 if (!(sc->sc_enabled & 2)) { #endif sc->sc_keystat[row + col * sc->sc_nrow] = (data >> row) & 1; #ifdef KEYTEST2 } else if (data & (1 << row)) { printf("col = %d, row = %d, idx = %d, data = 0x%02x\n", col, row, row + col * sc->sc_nrow, data); } #endif }
void ucomstop(struct tty *tp, int flag) { #if 0 /*struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(tp->t_dev));*/ int s; s = spltty(); if (ISSET(tp->t_state, TS_BUSY)) { /* sc->sc_tx_stopped = 1; */ if (!ISSET(tp->t_state, TS_TTSTOP)) SET(tp->t_state, TS_FLUSH); } splx(s); #endif }
/* * This is the autorepeat callout function scheduled by kbd_input() above. * Called at splsoftclock(). */ static void kbd_repeat(void *arg) { struct kbd_softc *k = arg; int s; s = spltty(); if (k->k_repeating && k->k_repeatsym >= 0) { /* feed typematic keysym to the console */ (void)kbd_input_keysym(k, k->k_repeatsym); /* reschedule next repeat */ callout_reset(&k->k_repeat_ch, k->k_repeat_step, kbd_repeat, k); } splx(s); }
/* * Detach a mouse. To keep track of users of the softc we keep * a reference count that's incremented while inside, e.g., read. * If the mouse is active and the reference count is > 0 (0 is the * normal state) we post an event and then wait for the process * that had the reference to wake us up again. Then we blow away the * vnode and return (which will deallocate the softc). */ int wsmouse_detach(device_t self, int flags) { struct wsmouse_softc *sc = device_private(self); struct wseventvar *evar; int maj, mn; int s; #if NWSMUX > 0 /* Tell parent mux we're leaving. */ if (sc->sc_base.me_parent != NULL) { DPRINTF(("wsmouse_detach:\n")); wsmux_detach_sc(&sc->sc_base); } #endif /* If we're open ... */ evar = sc->sc_base.me_evp; if (evar != NULL && evar->io != NULL) { s = spltty(); if (--sc->sc_refcnt >= 0) { struct wscons_event event; /* Wake everyone by generating a dummy event. */ event.type = 0; event.value = 0; if (wsevent_inject(evar, &event, 1) != 0) wsevent_wakeup(evar); /* Wait for processes to go away. */ if (tsleep(sc, PZERO, "wsmdet", hz * 60)) printf("wsmouse_detach: %s didn't detach\n", device_xname(self)); } splx(s); } /* locate the major number */ maj = cdevsw_lookup_major(&wsmouse_cdevsw); /* Nuke the vnodes for any open instances (calls close). */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); return (0); }
int fb_detach(dev_t dev, video_adapter_t *adp, struct cdevsw *cdevsw) { int s; if (adp->va_index >= adapters) return EINVAL; if (adapter[adp->va_index] != adp) return EINVAL; if (vidcdevsw[adp->va_index] != cdevsw) return EINVAL; s = spltty(); vidcdevsw[adp->va_index] = NULL; splx(s); return 0; }
void iteattach(struct device *pdp, struct device *dp, void *auxp) { struct grf_softc *gp; struct ite_softc *ip; int s; gp = (struct grf_softc *)auxp; if (dp) { ip = (struct ite_softc *)dp; s = spltty(); if (con_itesoftc.grf != NULL && con_itesoftc.grf->g_unit == gp->g_unit) { /* * console reinit copy params over. * and console always gets keyboard */ bcopy(&con_itesoftc.grf, &ip->grf, (char *)&ip[1] - (char *)&ip->grf); con_itesoftc.grf = NULL; kbd_ite = ip; } ip->grf = gp; splx(s); alloc_sicallback(); iteinit(gp->g_itedev); printf(": rows %d cols %d", ip->rows, ip->cols); printf(" repeat at (%d/100)s next at (%d/100)s", start_repeat_timeo, next_repeat_timeo); if (kbd_ite == NULL) kbd_ite = ip; if (kbd_ite == ip) printf(" has keyboard"); printf("\n"); ip->flags |= ITE_ATTACHED; } else { if (con_itesoftc.grf != NULL && con_itesoftc.grf->g_conpri > gp->g_conpri) return; con_itesoftc.grf = gp; con_itesoftc.tabs = cons_tabs; } }
/* move mouse */ void sc_mouse_move(scr_stat *scp, int x, int y) { int s; s = spltty(); scp->mouse_xpos = scp->mouse_oldxpos = x; scp->mouse_ypos = scp->mouse_oldypos = y; if (scp->font_size <= 0 || scp->font_width <= 0) scp->mouse_pos = scp->mouse_oldpos = 0; else scp->mouse_pos = scp->mouse_oldpos = (y/scp->font_size - scp->yoff)*scp->xsize + x/scp->font_width - scp->xoff; scp->status |= MOUSE_MOVED; splx(s); }
void dzkbd_cngetc(void *v, u_int *type, int *data) { struct dzkbd_internal *dzi = v; #if 0 int line = dzi->dzi_ls != NULL ? dzi->dzi_ls->dz_line : 0; #else int line = 0; /* keyboard */ #endif int c, s; do { s = spltty(); c = dzcngetc_internal(line); splx(s); } while (lk201_decode(&dzi->dzi_ks, 1, 0, c, type, data) == LKD_NODATA); }
/* * Read from the ac97 codec */ static int au88x0_codec_read(kobj_t obj, void *arg, int reg) { struct au88x0_info *aui = arg; uint32_t data; int sl; sl = spltty(); au88x0_codec_wait(aui); au88x0_write(aui, AU88X0_CODEC_IO, AU88X0_CDIO_READ(reg), 4); DELAY(1000); data = au88x0_read(aui, AU88X0_CODEC_IO, 4); splx(sl); data &= AU88X0_CDIO_DATA_MASK; data >>= AU88X0_CDIO_DATA_SHIFT; return (data); }
void mutex_lock(mutex_t *m, const char *file, const char *func, int line, const char *descr) { // KASSERT(CIPL==0); spinlock_lock(&m->mtx_slock); if ( atomic_change_int(&m->mtx_locked, MUTEX_LOCKED) == MUTEX_UNLOCKED) { m->mtx_owner = curthread; spinlock_unlock(&m->mtx_slock); } else { list_insert_tail(&m->mtx_locking, curthread); int x = spltty(); spinlock_unlock(&m->mtx_slock); sched_wait(file,func,line,descr); splx(x); } }
int vioconhwiflow(struct tty *tp, int stop) { struct viocon_port *vp = dev2port(tp->t_dev); int s; s = spltty(); vp->vp_iflow = stop; if (stop) { virtio_stop_vq_intr(vp->vp_sc->sc_virtio, vp->vp_rx); } else { virtio_start_vq_intr(vp->vp_sc->sc_virtio, vp->vp_rx); softintr_schedule(vp->vp_si); } splx(s); return 1; }
int pms_enable(void *v) { struct pms_softc *sc = v; int s; if (sc->sc_enabled) return EBUSY; do_enable(sc); s = spltty(); sc->sc_enabled = 1; splx(s); return 0; }
void vconsstart(struct tty *tp) { int s; s = spltty(); if (tp->t_state & (TS_TTSTOP | TS_BUSY)) { splx(s); return; } ttwakeupwr(tp); tp->t_state |= TS_BUSY; while (tp->t_outq.c_cc != 0) vcons_cnputc(tp->t_dev, getc(&tp->t_outq)); tp->t_state &= ~TS_BUSY; splx(s); }
/* test the interface to the device */ static int atkbd_test_if(keyboard_t *kbd) { int error; int s; error = 0; empty_both_buffers(((atkbd_state_t *)kbd->kb_data)->kbdc, 10); s = spltty(); if (!test_controller(((atkbd_state_t *)kbd->kb_data)->kbdc)) error = EIO; else if (test_kbd_port(((atkbd_state_t *)kbd->kb_data)->kbdc) != 0) error = EIO; splx(s); return error; }
static void oj6sh_poll(void *arg) { struct oj6sh_softc *sc = (struct oj6sh_softc *)arg; struct oj6sh_delta delta = {0, 0}; uint32_t buttons = 0; int s; int x, y; mutex_enter(&sc->sc_lock); if (oj6sh_motion(sc->sc_sh) == false) goto out; else if ((oj6sh_squal(sc->sc_sh) == true) && (oj6sh_shuttrer(sc->sc_sh) == true)) goto out; oj6sh_readdelta(sc->sc_sh, &delta); DPRINTF(3,("%s: x = %d, y = %d\n", device_xname(sc->sc_dev), delta.x, delta.y)); #if defined(J6SH_DOWN_Y_LEFT_X) y = -delta.y; x = -delta.x; #elif defined(OJ6SH_UP_X_LEFT_Y) y = delta.x; x = -delta.y; #elif defined(OJ6SH_DOWN_X_RIGHT_Y) y = -delta.x; x = delta.y; #else /* OJ6SH_UP_Y_RIGHT_X */ y = delta.y; x = delta.x; #endif s = spltty(); wsmouse_input(sc->sc_wsmousedev, buttons, x, y, 0, 0, WSMOUSE_INPUT_DELTA); splx(s); out: mutex_exit(&sc->sc_lock); if (sc->sc_enabled) callout_reset(&sc->sc_c, POLLRATE, oj6sh_poll, sc); return; }
void kbdsoftint(void *arg) /* what if ite is not configured? */ { struct kbd_softc *sc = arg; int s; s = spltty(); if (sc->sc_event_mode) EV_WAKEUP(&sc->sc_events); while(kbdgetoff < kbdputoff) ite_filter(kbdbuf[kbdgetoff++ & KBDBUFMASK]); kbdgetoff = kbdputoff = 0; splx(s); }
static void at91usart_start(struct tty *tp) { struct at91usart_softc *sc = device_lookup_private(&at91usart_cd, COMUNIT(tp->t_dev)); int s; if (COM_ISALIVE(sc) == 0) { DPRINTFN(5, ("%s: %s / COM_ISALIVE == 0\n", device_xname(sc->sc_dev), __FUNCTION__)); return; } s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) { DPRINTFN(5, ("%s: %s: TS_BUSY || TS_TIMEOUT || TS_TTSTOP\n", device_xname(sc->sc_dev), __FUNCTION__)); goto out; } if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); /* Output the first chunk of the contiguous buffer. */ at91usart_filltx(sc); at91usart_writereg(sc, US_IER, sc->sc_ier); DPRINTFN(5, ("%s: %s, ier=%08x (csr=%08x)\n", device_xname(sc->sc_dev), __FUNCTION__, sc->sc_ier, at91usart_readreg(sc, US_CSR))); out: splx(s); return; }
static void at91dbgu_start(struct tty *tp) { struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); (void)splserial(); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Output the first chunk of the contiguous buffer. */ at91dbgu_filltx(sc); SET(sc->sc_ier, DBGU_INT_TXRDY); DBGUREG(DBGU_IER) = DBGU_INT_TXRDY; out: splx(s); return; }