static int filtered_get_chars(uint32_t vtermno, char *buf, int count) { unsigned long got; int i; /* * Vio firmware will read up to SIZE_VIO_GET_CHARS at its own discretion * so we play safe and avoid the situation where got > count which could * overload the flip buffer. */ if (count < SIZE_VIO_GET_CHARS) return -EAGAIN; got = hvc_get_chars(vtermno, buf, count); /* * Work around a HV bug where it gives us a null * after every \r. -- paulus */ for (i = 1; i < got; ++i) { if (buf[i] == 0 && buf[i-1] == '\r') { --got; if (i < got) memmove(&buf[i], &buf[i+1], got - i); } } return got; }
static int hvsi_read(struct hvsi_struct *hp, char *buf, int count) { unsigned long got; got = hvc_get_chars(hp->vtermno, buf, count); return got; }
int hvc_wait_for_keypress(struct console *co) { char c[16] __ALIGNED__; while (hvc_get_chars(co->index, &c[0], 1) < 1) ; return 0; }
static void hvc_poll(int index) { struct hvc_struct *hp = &hvc_struct[index]; struct tty_struct *tty; int i, n; char buf[16] __ALIGNED__; unsigned long flags; spin_lock_irqsave(&hp->lock, flags); if (hp->n_outbuf > 0) hvc_push(hp); tty = hp->tty; if (tty) { for (;;) { if (TTY_FLIPBUF_SIZE - tty->flip.count < sizeof(buf)) break; n = hvc_get_chars(index + hvc_offset, buf, sizeof(buf)); if (n <= 0) break; for (i = 0; i < n; ++i) { #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ if (buf[i] == '\x0f') { /* ^O -- should support a sequence */ sysrq_pressed = 1; continue; } else if (sysrq_pressed) { handle_sysrq(buf[i], NULL, NULL, tty); sysrq_pressed = 0; continue; } #endif tty_insert_flip_char(tty, buf[i], 0); } } if (tty->flip.count) tty_schedule_flip(tty); if (hp->do_wakeup) { hp->do_wakeup = 0; if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); wake_up_interruptible(&tty->write_wait); } } spin_unlock_irqrestore(&hp->lock, flags); }
static int hvterm_raw_get_chars(uint32_t vtermno, char *buf, int count) { struct hvterm_priv *pv = hvterm_privs[vtermno]; unsigned long i; unsigned long flags; int got; if (WARN_ON(!pv)) return 0; spin_lock_irqsave(&pv->buf_lock, flags); if (pv->left == 0) { pv->offset = 0; pv->left = hvc_get_chars(pv->termno, pv->buf, count); /* */ for (i = 1; i < pv->left; ++i) { if (pv->buf[i] == 0 && pv->buf[i-1] == '\r') { --pv->left; if (i < pv->left) { memmove(&pv->buf[i], &pv->buf[i+1], pv->left - i); } } } } got = min(count, pv->left); memcpy(buf, &pv->buf[pv->offset], got); pv->offset += got; pv->left -= got; spin_unlock_irqrestore(&pv->buf_lock, flags); return got; }
static int filtered_get_chars(uint32_t vtermno, char *buf, int count) { unsigned long got; int i; if (count < SIZE_VIO_GET_CHARS) return -EAGAIN; got = hvc_get_chars(vtermno, buf, count); for (i = 1; i < got; ++i) { if (buf[i] == 0 && buf[i-1] == '\r') { --got; if (i < got) memmove(&buf[i], &buf[i+1], got - i); } } return got; }