/* called with callback_lock held */ static int srmcons_do_write(struct tty_port *port, const char *buf, int count) { static char str_cr[1] = "\r"; long c, remaining = count; srmcons_result result; char *cur; int need_cr; for (cur = (char *)buf; remaining > 0; ) { need_cr = 0; /* * Break it up into reasonable size chunks to allow a chance * for input to get in */ for (c = 0; c < min_t(long, 128L, remaining) && !need_cr; c++) if (cur[c] == '\n') need_cr = 1; while (c > 0) { result.as_long = callback_puts(0, cur, c); c -= result.bits.c; remaining -= result.bits.c; cur += result.bits.c; /* * Check for pending input iff a tty port was provided */ if (port) srmcons_do_receive_chars(port); } while (need_cr) { result.as_long = callback_puts(0, str_cr, 1); if (result.bits.c > 0) need_cr = 0; } } return count; }
static void srmcons_receive_chars(unsigned long data) { struct srmcons_private *srmconsp = (struct srmcons_private *)data; struct tty_port *port = &srmconsp->port; unsigned long flags; int incr = 10; local_irq_save(flags); if (spin_trylock(&srmcons_callback_lock)) { if (!srmcons_do_receive_chars(port)) incr = 100; spin_unlock(&srmcons_callback_lock); } spin_lock(&port->lock); if (port->tty) mod_timer(&srmconsp->timer, jiffies + incr); spin_unlock(&port->lock); local_irq_restore(flags); }
static void srmcons_receive_chars(unsigned long data) { struct srmcons_private *srmconsp = (struct srmcons_private *)data; unsigned long flags; int incr = 10; local_irq_save(flags); if (spin_trylock(&srmcons_callback_lock)) { if (!srmcons_do_receive_chars(srmconsp->tty)) incr = 100; spin_unlock(&srmcons_callback_lock); } spin_lock(&srmconsp->lock); if (srmconsp->tty) { srmconsp->timer.expires = jiffies + incr; add_timer(&srmconsp->timer); } spin_unlock(&srmconsp->lock); local_irq_restore(flags); }