1 /* Serial console layer, layered on top of sercomm HDLC */
3 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <asm/system.h>
29 #include <calypso/uart.h>
32 #include <osmocore/msgb.h>
33 #include <comm/sercomm.h>
34 #include <comm/sercomm_cons.h>
40 static void raw_puts(const char *s)
44 uart_putchar_wait(SERCOMM_UART_NR, *s++);
48 #define raw_putd(x) raw_puts(x)
53 int sercomm_puts(const char *s)
56 const int len = strlen(s);
57 unsigned int bytes_left = len;
59 if (!sercomm_initialized()) {
60 raw_putd("sercomm not initialized: ");
65 /* This function is called from any context: Supervisor, IRQ, FIQ, ...
66 * as such, we need to ensure re-entrant calls are either supported or
68 local_irq_save(flags);
71 while (bytes_left > 0) {
72 unsigned int write_num, space_left, flush;
76 scons.cur_msg = sercomm_alloc_msgb(SERCOMM_CONS_ALLOC);
79 raw_putd("cannot allocate sercomm msgb: ");
84 /* space left in the current msgb */
85 space_left = msgb_tailroom(scons.cur_msg);
87 if (space_left <= bytes_left) {
88 write_num = space_left;
89 /* flush buffer when it is full */
92 write_num = bytes_left;
96 /* obtain pointer where to copy the data */
97 data = msgb_put(scons.cur_msg, write_num);
99 /* copy data while looking for \n line termination */
102 for (i = 0; i < write_num; i++) {
103 /* flush buffer at end of line, but skip
104 * flushing if we have a backlog in order to
105 * increase efficiency of msgb filling */
107 sercomm_tx_queue_depth(SC_DLCI_CONSOLE) < 4)
112 bytes_left -= write_num;
115 sercomm_sendmsg(SC_DLCI_CONSOLE, scons.cur_msg);
116 /* reset scons.cur_msg pointer to ensure we allocate
117 * a new one next round */
118 scons.cur_msg = NULL;
122 local_irq_restore(flags);
127 int sercomm_putchar(int c)
135 rc = sercomm_puts(s);