static boolean_t xcons_putc(int c) { int force_flush = xc_mute || #ifdef DDB kdb_active || #endif panicstr; /* we're not gonna recover, so force * flush */ if ((wp-wc) < (WBUF_SIZE-1)) { if ((wbuf[WBUF_MASK(wp++)] = c) == '\n') { wbuf[WBUF_MASK(wp++)] = '\r'; #ifdef notyet if (force_flush) xcons_force_flush(); #endif } } else if (force_flush) { #ifdef notyet xcons_force_flush(); #endif } __xencons_tx_flush(); /* inform start path that we're pretty full */ return ((wp - wc) >= WBUF_SIZE - 100) ? TRUE : FALSE; }
static inline int __xencons_put_char(int ch) { char _ch = (char)ch; if ((wp - wc) == wbuf_size) return 0; wbuf[WBUF_MASK(wp++)] = _ch; return 1; }
static void kcons_write(struct console *c, const char *s, unsigned int count) { int i = 0; unsigned long flags; spin_lock_irqsave(&xencons_lock, flags); while (i < count) { for (; i < count; i++) { if ((wp - wc) >= (wbuf_size - 1)) break; if ((wbuf[WBUF_MASK(wp++)] = s[i]) == '\n') wbuf[WBUF_MASK(wp++)] = '\r'; } __xencons_tx_flush(); } spin_unlock_irqrestore(&xencons_lock, flags); }
static void __xencons_tx_flush(void) { int sent, sz, work_done = 0; if (x_char) { if (is_initial_xendomain()) kcons_write_dom0(NULL, &x_char, 1); else while (x_char) if (xencons_ring_send(&x_char, 1) == 1) break; x_char = 0; work_done = 1; } while (wc != wp) { sz = wp - wc; if (sz > (wbuf_size - WBUF_MASK(wc))) sz = wbuf_size - WBUF_MASK(wc); if (is_initial_xendomain()) { kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz); wc += sz; } else { sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent == 0) break; wc += sent; } work_done = 1; } if (work_done && (xencons_tty != NULL)) { wake_up_interruptible(&xencons_tty->write_wait); if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && (xencons_tty->ldisc.write_wakeup != NULL)) (xencons_tty->ldisc.write_wakeup)(xencons_tty); } }
static void __xencons_tx_flush(void) { int sz; CN_LOCK(cn_mtx); while (wc != wp) { int sent; sz = wp - wc; if (sz > (WBUF_SIZE - WBUF_MASK(wc))) sz = WBUF_SIZE - WBUF_MASK(wc); if (xen_initial_domain()) { HYPERVISOR_console_io(CONSOLEIO_write, sz, &wbuf[WBUF_MASK(wc)]); wc += sz; } else { sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent == 0) break; wc += sent; } } CN_UNLOCK(cn_mtx); }
/*** Forcibly flush console data before dying. ***/ void xcons_force_flush(void) { int sz; if (xen_initial_domain()) return; /* Spin until console data is flushed through to the domain controller. */ while (wc != wp) { int sent = 0; if ((sz = wp - wc) == 0) continue; sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent > 0) wc += sent; } }
/*** Forcibly flush console data before dying. ***/ void xencons_force_flush(void) { int sz; /* Emergency console is synchronous, so there's nothing to flush. */ if (!is_running_on_xen() || is_initial_xendomain() || !xen_start_info->console.domU.evtchn) return; /* Spin until console data is flushed through to the daemon. */ while (wc != wp) { int sent = 0; if ((sz = wp - wc) == 0) continue; sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); if (sent > 0) wc += sent; } }