Added lance entry to drivers.conf.
[minix3-old.git] / servers / pm / kputc.c
blobb0c53b0992b11fce359aa6e3ba7724ba0d8b9b9e
1 /* A server must occasionally print some message. It uses a simple version of
2 * printf() found in the system lib that calls kputc() to output characters.
3 * Printing is done with a call to the kernel, and not by going through FS.
5 * This routine can only be used by servers and device drivers. The kernel
6 * must define its own kputc(). Note that the log driver also defines its own
7 * kputc() to directly call the TTY instead of going through this library.
8 */
10 #include "pm.h"
11 #include <string.h>
12 #include <minix/com.h>
14 #define OVERFLOW_STR "[...]\n"
16 #define PRINTPROCS (sizeof(procs)/sizeof(procs[0]))
18 static char print_buf[80]; /* output is buffered here */
20 int kputc_use_private_grants= 0;
22 static int buf_count = 0; /* # characters in the buffer */
23 static int buf_offset = 0; /* Start of current line in buffer */
24 static int procs[] = OUTPUT_PROCS_ARRAY;
25 static cp_grant_id_t printgrants[PRINTPROCS];
26 static int procbusy[PRINTPROCS];
27 static int do_flush = FALSE;
28 static int overflow = FALSE;
30 /*===========================================================================*
31 * kputc *
32 *===========================================================================*/
33 void kputc(c)
34 int c;
36 /* Accumulate another character. If 0 or buffer full, print it. */
37 int p;
38 message m;
40 static int firstprint = 1;
42 if (c == 0)
44 if (buf_count > buf_offset)
45 do_flush= TRUE;
47 else if (buf_count >= sizeof(print_buf))
49 overflow= TRUE;
50 if (buf_count > buf_offset)
51 do_flush= TRUE;
53 else
54 print_buf[buf_count++] = c;
56 if (!do_flush || buf_offset != 0)
57 return;
59 buf_offset= buf_count;
60 if (kputc_use_private_grants)
62 for (p= 0; p<PRINTPROCS; p++)
63 printgrants[p]= GRANT_INVALID;
64 firstprint= 0;
66 if(firstprint) {
67 for(p = 0; procs[p] != NONE; p++) {
68 printgrants[p] = GRANT_INVALID;
71 firstprint = 0;
73 /* First time? Initialize grant table;
74 * Grant printing processes read copy access to our
75 * print buffer forever. (So buffer can't be on stack!)
77 for(p = 0; procs[p] != NONE; p++) {
78 printgrants[p] = cpf_grant_direct(procs[p],
79 (vir_bytes) print_buf,
80 sizeof(print_buf), CPF_READ);
84 do_flush= FALSE;
85 for(p = 0; procs[p] != NONE; p++) {
86 /* Send the buffer to this output driver. */
87 m.DIAG_BUF_COUNT = buf_count;
88 if(GRANT_VALID(printgrants[p])) {
89 m.m_type = DIAGNOSTICS_S;
90 m.DIAG_PRINT_BUF_G = (char *) printgrants[p];
91 } else {
92 m.m_type = DIAGNOSTICS;
93 m.DIAG_PRINT_BUF_G = print_buf;
95 if (procs[p] == LOG_PROC_NR)
97 procbusy[p]= TRUE;
98 (void) asynsend(procs[p], &m);
100 else
102 sendrec(procs[p], &m);
107 PUBLIC void diag_repl()
109 endpoint_t driver_e;
110 int p;
112 driver_e= m_in.m_source;
114 /* Find busy flag to clear */
115 for(p = 0; procs[p] != NONE; p++)
117 if (procs[p] == driver_e)
118 break;
120 if (procs[p] == NONE)
122 /* Message from wrong source */
123 return;
125 procbusy[p]= FALSE;
127 /* Wait for more replies? */
128 for(p = 0; procs[p] != NONE; p++)
130 if (procbusy[p])
131 return;
133 if (buf_count > buf_offset)
135 memmove(&print_buf[0], &print_buf[buf_offset],
136 buf_count-buf_offset);
138 buf_count -= buf_offset;
139 buf_offset= 0;
140 if (overflow)
142 if (buf_count + sizeof(OVERFLOW_STR) > sizeof(print_buf))
143 buf_count= sizeof(print_buf)-sizeof(OVERFLOW_STR);
144 overflow= FALSE;
145 do_flush= FALSE;
146 printf("%s", OVERFLOW_STR);
148 kputc(0);