1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <mach_kdb.h>
30
31#include <types.h>
32#include <device/buf.h>
33#include <device/conf.h>
34#include <device/errno.h>
35#include <device/misc_protos.h>
36#include <device/ds_routines.h>
37#include <device/cirbuf.h>
38#include <ppc/console_feed_entries.h>
39#include <ppc/serial_io.h>
40
41#if MACH_KDB
42#include <ppc/db_machdep.h>
43#endif
44
45static struct cirbuf cons_feed_cb;
46static int cons_feed_count = 0;
47io_req_t cons_feed_queued = 0;
48
49
50decl_simple_lock_data(,cons_feed_lock)
51
52boolean_t cons_feed_read_done(io_req_t ior);
53
54io_return_t
55console_feed_open(
56 dev_t dev,
57 dev_mode_t flag,
58 io_req_t ior)
59{
60 spl_t s;
61
62 simple_lock_init(&cons_feed_lock, 0);
63#if MACH_KDB
64 if (console_is_serial()) {
65 return D_DEVICE_DOWN;
66 }
67#endif
68 cb_alloc(&cons_feed_cb, CONSOLE_FEED_BUFSIZE);
69 s = splhigh();
70 simple_lock(&cons_feed_lock);
71 cons_feed_count++;
72 simple_unlock(&cons_feed_lock);
73 splx(s);
74 return D_SUCCESS;
75}
76
77void
78console_feed_close(
79 dev_t dev)
80{
81 spl_t s;
82
83 s = splhigh();
84 simple_lock(&cons_feed_lock);
85 cons_feed_count--;
86 simple_unlock(&cons_feed_lock);
87 splx(s);
88
89 console_feed_cancel_and_flush();
90 cb_free(&cons_feed_cb);
91
92 return;
93}
94
95
96
97
98
99
100
101
102void console_feed_cancel_and_flush(void)
103{
104 int c;
105 spl_t s;
106
107#if NCONSFEED > 0
108#if MACH_KDB
109 if (console_is_serial()) {
110 return;
111 }
112#endif
113
114 s = splhigh();
115 simple_lock(&cons_feed_lock);
116 if (cons_feed_count == 0) {
117 simple_unlock(&cons_feed_lock);
118 splx(s);
119 return;
120 }
121 cons_feed_count = 0;
122 simple_unlock(&cons_feed_lock);
123 splx(s);
124
125 do {
126 c = getc(&cons_feed_cb);
127 if (c == -1)
128 break;
129 cnputc(c);
130 } while (1);
131#endif
132}
133
134io_return_t
135console_feed_read(
136 dev_t dev,
137 io_req_t ior)
138{
139 spl_t s;
140 kern_return_t rc;
141 int count;
142
143 rc = device_read_alloc(ior, (vm_size_t) ior->io_count);
144 if (rc != KERN_SUCCESS)
145 return rc;
146
147 s = splhigh();
148 simple_lock(&cons_feed_lock);
149
150 ior->io_residual = ior->io_count;
151
152 count = q_to_b(&cons_feed_cb, (char *) ior->io_data, ior->io_count);
153 if (count == 0) {
154 if (ior->io_mode & D_NOWAIT) {
155 rc = D_WOULD_BLOCK;
156 }
157 if (cons_feed_queued == NULL) {
158 ior->io_done = cons_feed_read_done;
159 cons_feed_queued = ior;
160 rc = D_IO_QUEUED;
161 } else {
162
163 rc = D_INVALID_OPERATION;
164 }
165 simple_unlock(&cons_feed_lock);
166 splx(s);
167 return rc;
168 }
169
170 simple_unlock(&cons_feed_lock);
171 splx(s);
172
173 ior->io_residual -= count;
174
175 iodone(ior);
176
177 if (ior->io_op & IO_SYNC) {
178 iowait(ior);
179 }
180
181 return D_SUCCESS;
182}
183
184
185boolean_t cons_feed_read_done(io_req_t ior)
186{
187 spl_t s;
188 int count;
189
190 s = splhigh();
191 simple_lock(&cons_feed_lock);
192
193 count = q_to_b(&cons_feed_cb, (char *) ior->io_data, ior->io_count);
194 if (count == 0) {
195 if (cons_feed_queued == NULL) {
196 ior->io_done = cons_feed_read_done;
197 cons_feed_queued = ior;
198 }
199 simple_unlock(&cons_feed_lock);
200 splx(s);
201 return FALSE;
202 }
203
204 simple_unlock(&cons_feed_lock);
205 splx(s);
206
207 ior->io_residual -= count;
208 ds_read_done(ior);
209
210 return TRUE;
211}
212
213
214
215
216
217
218
219boolean_t console_feed_putc(char c)
220{
221 spl_t s;
222 io_req_t ior;
223 boolean_t retval;
224
225#if MACH_KDB
226 if (db_active) {
227 return TRUE;
228 }
229#endif
230
231 retval=TRUE;
232 if (!cons_feed_count) {
233 return TRUE;
234 }
235 s = splhigh();
236 simple_lock(&cons_feed_lock);
237 if (!cons_feed_count) {
238 simple_unlock(&cons_feed_lock);
239 splx(s);
240 return TRUE;
241 }
242
243 if (!putc(c, &cons_feed_cb)) {
244
245 retval = FALSE;
246 }
247 if (cons_feed_queued != NULL) {
248
249 ior = cons_feed_queued;
250 cons_feed_queued = NULL;
251 simple_unlock(&cons_feed_lock);
252 splx(s);
253 iodone(ior);
254 retval=FALSE;
255 } else {
256 simple_unlock(&cons_feed_lock);
257 splx(s);
258 }
259 return retval;
260}
261