1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18: 19: 20:
21:
22: #include <basic.h>
23: #include <sys/consio.h>
24: #include <tk/tkernel.h>
25: #include <tk/util.h>
26: #include <device/serialio.h>
27: #include <device/rs.h>
28: #include <sys/imalloc.h>
29: #include <sys/util.h>
30: #include <libstr.h>
31: #include <sys/queue.h>
32: #include <sys/debug.h>
33: #include <tm/tmonitor.h>
34: #include <sys/rominfo.h>
35:
36: #include <sys/svc/ifconsio.h>
37:
38:
39: #ifndef DEFAULT_CONSOLE_PORT
40: #define DEFAULT_CONSOLE_PORT CONF_SERIAL_0
41: #endif
42:
43: EXPORT W DebugPort;
44:
45: IMPORT ER con_def_subsys(W svc, W pri, void *svcent, void *brkent);
46:
47: IMPORT ER consMLock(FastMLock *lock, INT no);
48: IMPORT ER consMUnlock(FastMLock *lock, INT no);
49: IMPORT ER consCreateMLock(FastMLock *lock, UB *name);
50: IMPORT ER consDeleteMLock(FastMLock *lock);
51:
52: 53: 54:
55:
56: typedef struct {
57: QUEUE q;
58: W port;
59: W in_use;
60:
61: W conf;
62: FastMLock lock;
63: ID flg;
64:
65: UB *in_buf;
66: UW in_bufsz;
67: UW in_rptr;
68: UW in_wptr;
69:
70: UB *ou_buf;
71: UW ou_bufsz;
72: UW ou_rptr;
73: UW ou_wptr;
74:
75: UB *h_buf;
76:
77: UW rsv:11;
78: UW rcv_xoff:1;
79: UW disable:2;
80: UW echo:1;
81: UW newline:1;
82: UW input:4;
83: UW flowc:4;
84: UW wup_char:8;
85:
86: ID wup_tskid;
87:
88: W snd_tmout;
89: W rcv_tmout;
90: } CONSCB;
91:
92: LOCAL QUEUE ConsPort;
93: LOCAL UH last_port = 0;
94:
95: LOCAL FastLock ConsLock;
96:
97: #define DEF_INBUFSZ 256
98: #define DEF_OUBUFSZ 1024
99: #define MIN_BUFSZ 128
100: #define HIST_BUFSZ 2048
101:
102: #define INPTRMASK(p, ptr) ((ptr) % ((p)->in_bufsz))
103:
104: #define OUPTRMASK(p, ptr) ((ptr) % ((p)->ou_bufsz))
105:
106:
107: #define XOFF_MARGIN 64
108: #define XON_MARGIN 128
109:
110:
111: #define BS ('H'-'@')
112: #define CAN ('X'-'@')
113: #define CTLC ('C'-'@')
114: #define DEL (0x7f)
115: #define CR (0x0d)
116: #define LF (0x0a)
117: #define ERASE ('K'-'@')
118: #define CAN2 ('U'-'@')
119: #define TAB ('I'-'@')
120: #define ESC ('['-'@')
121: #define CUR_UP ('P'-'@')
122: #define CUR_DWN ('N'-'@')
123: #define CUR_FWD ('F'-'@')
124: #define CUR_BWD ('B'-'@')
125: #define XOFF ('S'-'@')
126: #define XON ('Q'-'@')
127:
128: #define OU_LOCK 17
129: #define IN_LOCK 16
130: #define FLG_OU_EVT (1 << 1)
131: #define FLG_IN_EVT (1 << 0)
132:
133: 134: 135:
136: #define CreLock(lock, name) consCreateMLock(lock, name)
137: #define DelLock(lock) consDeleteMLock(lock)
138: #define LockIn(lock, no) consMLock(lock, no)
139: #define LockOut(lock, no) consMUnlock(lock, no)
140:
141: 142: 143:
144: #define Malloc(len) (void*)Imalloc(len)
145: #define Free(ptr) Ifree((void*)(ptr))
146:
147: 148: 149:
150: LOCAL CONSCB *check_port(W port)
151: {
152: QUEUE *q;
153:
154: if (port <= 0) return NULL;
155: q = QueSearch(&ConsPort, &ConsPort, port, offsetof(CONSCB, port));
156: return (q == &ConsPort) ? NULL : (CONSCB*)q;
157: }
158: 159: 160:
161: LOCAL CONSCB *get_port(W port)
162: {
163: CONSCB *p;
164:
165:
166: Lock(&ConsLock);
167: if ((p = check_port(port)) != NULL) p->in_use++;
168: Unlock(&ConsLock);
169: return p;
170: }
171: 172: 173:
174: LOCAL W special_char_proc(CONSCB *p, B c)
175: {
176: if (p->input != RAW && c == p->wup_char) {
177: tk_rel_wai(p->wup_tskid);
178: p->wup_tskid = 0;
179: }
180: return 0;
181: }
182: 183: 184:
185: LOCAL W put_consbuf(CONSCB *p, W c, W tmout)
186: {
187: UW ptr, nptr;
188: UINT flgptn;
189:
190:
191: special_char_proc(p, c);
192:
193:
194: if (p->flowc & IXON) {
195: if (c == XOFF) {
196: p->rcv_xoff = 1;
197: return 0;
198: }
199: if (c == XON || (p->rcv_xoff && (p->flowc & IXANY))) {
200: if (p->rcv_xoff) {
201: if (p->flg) tk_set_flg(p->flg, FLG_OU_EVT);
202: p->rcv_xoff = 0;
203: }
204: return 0;
205: }
206: }
207:
208: ptr = p->in_wptr;
209: nptr = INPTRMASK(p, ptr + 1);
210:
211:
212: while (nptr == p->in_rptr) {
213: if (tk_wai_flg(p->flg, FLG_IN_EVT, TWF_ORW | TWF_BITCLR,
214: &flgptn, tmout)) return -1;
215: }
216:
217:
218: p->in_buf[ptr] = c;
219: p->in_wptr = nptr;
220:
221:
222: if (ptr == p->in_rptr) tk_set_flg(p->flg, FLG_IN_EVT);
223:
224:
225: return 0;
226: }
227: 228: 229:
230: LOCAL W read_consbuf(CONSCB *p)
231: {
232: W c;
233: UINT flgptn;
234: UW ptr;
235:
236: ptr = p->in_rptr;
237:
238:
239: while (ptr == p->in_wptr) {
240: if (tk_wai_flg(p->flg, FLG_IN_EVT, TWF_ORW | TWF_BITCLR,
241: &flgptn, p->rcv_tmout)) return -1;
242: }
243:
244:
245: c = p->in_buf[ptr];
246: p->in_rptr = INPTRMASK(p, ptr + 1);
247:
248:
249: if (ptr == INPTRMASK(p, p->in_wptr + 1)) {
250: tk_set_flg(p->flg, FLG_IN_EVT);
251: }
252:
253:
254: return c;
255: }
256: 257: 258:
259: LOCAL W write_consbuf(CONSCB *p, W c)
260: {
261: UW ptr, nptr;
262: UINT flgptn;
263:
264: ptr = p->ou_wptr;
265: nptr = OUPTRMASK(p, ptr + 1);
266:
267: 268:
269: while (p->rcv_xoff || nptr == p->ou_rptr) {
270: if (tk_wai_flg(p->flg, FLG_OU_EVT, TWF_ORW | TWF_BITCLR,
271: &flgptn, p->snd_tmout)) return -1;
272: }
273: p->ou_buf[ptr] = c;
274: p->ou_wptr = nptr;
275:
276:
277: if (ptr == p->ou_rptr) tk_set_flg(p->flg, FLG_OU_EVT);
278:
279: return 0;
280: }
281: 282: 283:
284: LOCAL W get_consbuf(CONSCB *p, W tmout)
285: {
286: W c;
287: UW ptr;
288: UINT flgptn;
289:
290: ptr = p->ou_rptr;
291:
292:
293: while (ptr == p->ou_wptr) {
294: if (tk_wai_flg(p->flg, FLG_OU_EVT, TWF_ORW | TWF_BITCLR,
295: &flgptn, tmout)) return -1;
296: }
297:
298:
299: c = p->ou_buf[ptr];
300: p->ou_rptr = OUPTRMASK(p, ptr + 1);
301:
302:
303: if (ptr == OUPTRMASK(p, p->ou_wptr + 1)) {
304: tk_set_flg(p->flg, FLG_OU_EVT);
305: }
306:
307: return c;
308: }
309: 310: 311:
312: LOCAL W cons_getch(CONSCB *p)
313: {
314: UB c;
315: W alen;
316:
317: if (p->conf == CONF_BUFIO)
318: return read_consbuf(p);
319:
320:
321: return (serial_in(p->conf, &c, 1, &alen, p->rcv_tmout) < 0)? -1: c;
322: }
323: 324: 325:
326: LOCAL W cons_putch(CONSCB *p, B c)
327: {
328: W alen;
329:
330: if ((p->disable & 0x1) != 0) return 0;
331:
332: if (p->conf == CONF_BUFIO)
333: return write_consbuf(p, c);
334:
335:
336: return (serial_out(p->conf, &c, 1, &alen, p->snd_tmout) < 0)? -1: 0;
337: }
338: 339: 340:
341: LOCAL W edit_input(CONSCB *p, B *buf, W max)
342: {
343: W i, c, c1;
344: W cp, ep, hp, esc;
345: W len;
346: B *hist;
347:
348: cp = ep = esc = 0;
349: c1 = 0;
350: hp = -1;
351: hist = (B*)p->h_buf;
352:
353: for (;;) {
354:
355: if ((c = cons_getch(p)) < 0) break;
356: len = 1;
357: if (c & 0x80) {
358: if (c1 == 0) {c1 = c; continue;}
359: c |= c1 << 8;
360: c1 = 0;
361: len = 2;
362: }
363: if (c == ESC) {esc = 1; continue;}
364: if (esc) {
365: if (esc == 1) {esc = (c == '[') ? 2 : 0; continue;}
366: esc = 0;
367: if (c == 'A') c = CUR_UP;
368: else if (c == 'B') c = CUR_DWN;
369: else if (c == 'C') c = CUR_FWD;
370: else if (c == 'D') c = CUR_BWD;
371: else continue;
372: }
373: if (c == CUR_FWD) {
374: if (cp < ep) {
375: if (buf[cp] & 0x80) cons_putch(p, buf[cp++]);
376: cons_putch(p, buf[cp++]);
377: }
378: continue;
379: }
380: if (c == CUR_BWD) {
381: if (cp > 0) {
382: if (buf[--cp] & 0x80){cons_putch(p, BS); cp--;}
383: cons_putch(p, BS);
384: }
385: continue;
386: }
387: if (c == CUR_UP || c == CUR_DWN) {
388: if (! hist) continue;
389:
390: if (c == CUR_DWN) {
391: if (hp <= 0) continue;
392: for (hp--; (--hp) > 0 && hist[hp];);
393: if (hp) hp++;
394: } else {
395: i = hp < 0 ? 0 : (STRLEN(&hist[hp]) + hp + 1);
396: if (hist[i] == 0) continue;
397: hp = i;
398: }
399: for (; cp > 0; cp--) cons_putch(p, BS);
400: i = STRLEN(&hist[hp]);
401: if (i > max) i = max;
402: for (; cp < i; cp++)
403: cons_putch(p, buf[cp] = hist[hp + cp]);
404: c = ERASE;
405: }
406: if (c == BS || c == DEL) {
407: if (cp <= 0) continue;
408: len = (buf[cp - 1] & 0x80) ? 2 : 1;
409: if (cp < ep) MEMCPY(&buf[cp-len], &buf[cp], ep - cp);
410: for (i = 0; i < len; i++) {
411: buf[--ep] = ' ';
412: cons_putch(p, BS);
413: }
414: cp -= len;
415: for (i = cp; i < ep + len; i++) cons_putch(p, buf[i]);
416: for (; i > cp; i--) cons_putch(p, BS);
417: continue;
418: }
419: if (c == CAN || c == CAN2) {
420: for (; cp > 0; cp--) cons_putch(p, BS);
421: c = ERASE;
422: }
423: if (c == ERASE) {
424: for (i = cp; i < ep; i++) cons_putch(p, ' ');
425: for (; i > cp; i--) cons_putch(p, BS);
426: ep = cp;
427: continue;
428: }
429: if (c == CR || c == LF) {c = LF; break;}
430:
431: if (c == CTLC) {cons_putch(p, c); break;}
432:
433: if (c < ' ' && c != TAB) continue;
434:
435: if (ep + len > max) continue;
436:
437:
438: if (cp < ep) MEMMOVE(&buf[cp+len], &buf[cp], ep - cp);
439: if (len == 2) {
440: buf[cp+1] = c & 0xff;
441: c = (c >> 8) & 0xff;
442: }
443: buf[cp] = c;
444: for (ep += len, i = cp; i < ep; i++) cons_putch(p, buf[i]);
445: for (cp += len; i > cp; i--) cons_putch(p, BS);
446: }
447: if (c == LF) {
448: cons_putch(p, CR);
449: cons_putch(p, LF);
450: }
451: i = ep;
452: if (ep < max && c >= 0) buf[ep++] = c;
453: if (ep < max) buf[ep] = 0;
454: if (i > 0 && c != CTLC) {
455: if (hist) {
456: MEMMOVE(&hist[i+1], hist, HIST_BUFSZ - 1 - i);
457: MEMCPY(hist, buf, i);
458: hist[i] = 0;
459: hist[HIST_BUFSZ - 2] = 0;
460: hist[HIST_BUFSZ - 1] = 0;
461: }
462: }
463: return (c == CTLC) ? -1 : ep;
464: }
465: 466: 467: 468:
469: LOCAL W _console_out(W port, B *buf, UW len)
470: {
471: CONSCB *p;
472: UB c;
473: W alen = 0;
474: ER er;
475:
476:
477: er = ChkSpaceR((void*)buf, len);
478: if (er < E_OK && er != E_RSFN) return 0;
479:
480:
481: if ((p = get_port(port)) != NULL) {
482:
483:
484: if (LockIn(&p->lock, OU_LOCK) < 0) goto EEXIT;
485:
486: for (; alen < len; alen++) {
487: if ((c = *buf++) == LF && p->newline) {
488: if (cons_putch(p, CR)) break;
489: }
490: if (cons_putch(p, c)) break;
491: }
492:
493: LockOut(&p->lock, OU_LOCK);
494: EEXIT:
495: p->in_use--;
496: }
497: return alen;
498: }
499: 500: 501: 502:
503: LOCAL W _console_in(W port, B *buf, UW len)
504: {
505: CONSCB *p;
506: W c;
507: W alen = 0;
508:
509:
510: if (ChkSpaceRW((void*)buf, len)) return 0;
511:
512:
513: if ((p = get_port(port)) != NULL) {
514:
515: if (LockIn(&p->lock, IN_LOCK) < 0) goto EEXIT;
516:
517:
518: if (p->input == EDIT && len > 1) {
519: alen = edit_input(p, buf, len);
520: } else {
521: while (alen < len) {
522: if ((c = cons_getch(p)) < 0) break;
523: if (c == CR && p->input != RAW) c = LF;
524: if (p->echo) {
525: if (c == LF && p->input != RAW)
526: cons_putch(p, CR);
527: cons_putch(p, c);
528: }
529: buf[alen++] = c;
530: if (p->input == RAW || c == LF || c == CTLC)
531: break;
532: }
533: }
534:
535: LockOut(&p->lock, IN_LOCK);
536: EEXIT:
537: p->in_use--;
538: }
539: return alen;
540: }
541: 542: 543:
544: LOCAL W _console_ctl(W port, W req, W arg)
545: {
546: CONSCB *p;
547: W n;
548: W rtn = -1;
549:
550:
551: if ((p = get_port(port)) != NULL) {
552:
553:
554: switch (req) {
555: case ECHO|GETCTL:
556: rtn = p->echo; break;
557: case ECHO:
558: rtn = 0; p->echo = arg; break;
559: case INPUT|GETCTL:
560: rtn = p->input; break;
561: case INPUT:
562: rtn = 0;
563: if ((p->input = arg) == EDIT) {
564: if (!p->h_buf) {
565: if (!(p->h_buf = Malloc(HIST_BUFSZ)))
566: rtn = -1;
567: }
568: if (rtn == 0) p->h_buf[0] = 0;
569: } else if (p->h_buf) {
570: Free(p->h_buf);
571: p->h_buf = NULL;
572: }
573: break;
574: case NEWLINE|GETCTL:
575: rtn = p->newline; break;
576: case NEWLINE:
577: rtn = 0; p->newline = arg; break;
578: case FLOWC|GETCTL:
579: rtn = p->flowc; break;
580: case FLOWC:
581: rtn = 0;
582: p->flowc = arg;
583: if (p->conf >= 0) {
584: RsFlow flow;
585: flow.rsv = 0;
586: flow.rcvxoff = 0;
587: flow.csflow = 0;
588: flow.rsflow = 0;
589: flow.xonany = (arg & IXANY) != 0;
590: flow.sxflow = (arg & IXON ) != 0;
591: flow.rxflow = (arg & IXOFF) != 0;
592: serial_ctl(p->conf, DN_RSFLOW, (void*)&flow);
593: }
594: p->rcv_xoff = 0;
595: break;
596: case SNDTMO|GETCTL:
597: rtn = p->snd_tmout; break;
598: case SNDTMO:
599: rtn = 0;
600: p->snd_tmout = (arg < 0) ? -1 : arg; break;
601: case RCVTMO|GETCTL:
602: rtn = p->rcv_tmout; break;
603: case RCVTMO:
604: rtn = 0;
605: p->rcv_tmout = (arg < 0) ? -1 : arg; break;
606: case RCVBUFSZ|GETCTL:
607: rtn = p->in_bufsz; break;
608: case SNDBUFSZ|GETCTL:
609: rtn = p->ou_bufsz; break;
610: case 0x8f:
611: rtn = 0;
612: p->wup_char = arg;
613: if ((n = p->wup_tskid) > 0) tk_wup_tsk(n);
614: p->wup_tskid = tk_get_tid();
615: break;
616: case 0x8e:
617: rtn = 0; p->disable = arg; break;
618: }
619: p->in_use--;
620: }
621: return rtn;
622: }
623: 624: 625: 626:
627: LOCAL W _console_put(W port, B *buf, UW len, W tmout)
628: {
629: CONSCB *p;
630: W alen = 0;
631:
632:
633: if (ChkSpaceR((void*)buf, len)) return 0;
634:
635:
636: if ((p = get_port(port)) != NULL) {
637:
638: if (p->conf == CONF_BUFIO && (p->disable & 0x2) == 0) {
639: for (; alen < len; alen++) {
640: if (put_consbuf(p, (W)*buf++, tmout)) break;
641: }
642: }
643: p->in_use--;
644: }
645: return alen;
646: }
647: 648: 649: 650:
651: LOCAL W _console_get(W port, B *buf, UW len, W tmout)
652: {
653: CONSCB *p;
654: W c;
655: W alen = 0;
656:
657:
658: if (ChkSpaceRW((void*)buf, len)) return 0;
659:
660:
661: if ((p = get_port(port)) != NULL) {
662:
663: if (p->conf == CONF_BUFIO) {
664: for (; alen < len; alen++) {
665: if ((c = get_consbuf(p, tmout)) < 0) break;
666: *buf++ = c;
667: }
668: }
669: p->in_use--;
670: }
671: return alen;
672: }
673: 674: 675:
676: LOCAL W delete_cons(CONSCB *p)
677: {
678: UW par[2];
679:
680:
681: QueRemove(&p->q);
682:
683:
684: if (p->flg) DelLock(&p->lock);
685:
686:
687: while (p->in_use > 0) {
688: if (p->conf >= 0)
689: serial_ctl(p->conf, RS_ABORT, NULL);
690: tk_dly_tsk(10);
691: }
692:
693:
694: if (p->conf >= 0) {
695: par[0] = par[1] = 0;
696: serial_ctl(p->conf, RS_EXTFUNC, par);
697: }
698:
699:
700: if (p->in_buf) Free(p->in_buf);
701: if (p->ou_buf) Free(p->ou_buf);
702: if (p->h_buf) Free(p->h_buf);
703:
704:
705: Free(p);
706:
707: return 0;
708: }
709: 710: 711:
712: LOCAL W make_cons(W new, W *arg)
713: {
714: static union objname name = {{ "con0" }};
715: CONSCB *p, *old;
716: UH port;
717: W conf, sz, dmy;
718: UW par[2];
719:
720:
721: conf = arg[1];
722: if (conf != CONF_BUFIO) {
723:
724: if (conf < 0 || serial_ctl(conf, -DN_RSMODE, &dmy)) return -1;
725: }
726:
727: if (new) {
728:
729: for (port = ++last_port; QueSearch(&ConsPort, &ConsPort,
730: (W)port, offsetof(CONSCB, port)) != &ConsPort; port++);
731: arg[0] = (W)(last_port = port);
732: old = NULL;
733: } else {
734: port = arg[0];
735: if (!(old = check_port(port))) return -1;
736: }
737:
738:
739: if (!(p = (CONSCB*)Malloc(sizeof(CONSCB)))) return -1;
740: MEMSET((void*)p, 0, sizeof(CONSCB));
741:
742:
743: name.s[3] = '0' + port;
744:
745:
746: if ((p->flg = CreLock(&p->lock, name.s)) < 0) goto EEXIT;
747:
748:
749: if (conf == CONF_BUFIO) {
750: if ((sz = arg[2]) < MIN_BUFSZ)
751: sz = sz ? MIN_BUFSZ : DEF_INBUFSZ;
752: if (!(p->in_buf = Malloc(sz))) goto EEXIT;
753: p->in_bufsz = sz;
754: }
755:
756: if (conf == CONF_BUFIO) {
757: if ((sz = arg[3]) < MIN_BUFSZ)
758: sz = sz ? MIN_BUFSZ : DEF_OUBUFSZ;
759: if (!(p->ou_buf = Malloc(sz))) goto EEXIT;
760: p->ou_bufsz = sz;
761: }
762:
763:
764: if (new == 0) delete_cons(old);
765:
766:
767: p->port = port;
768: p->conf = conf;
769: p->input = CANONICAL;
770: p->snd_tmout = p->rcv_tmout = -1;
771:
772:
773: if (conf >= 0) {
774: par[0] = (UW)special_char_proc;
775: par[1] = (UW)p;
776: serial_ctl(conf, RS_EXTFUNC, par);
777: }
778:
779:
780: QueInsert(&p->q, &ConsPort);
781: return 0;
782:
783: EEXIT:
784: if (p->in_buf) Free(p->in_buf);
785: if (p->ou_buf) Free(p->ou_buf);
786: if (p->flg > 0) DelLock(&p->lock);
787: Free(p);
788: return -1;
789: }
790:
791: 792: 793:
794: LOCAL W _console_conf(W req, UW* arg)
795: {
796: CONSCB *p;
797: W n;
798:
799:
800:
801:
802: Lock(&ConsLock);
803:
804: switch(req) {
805: case CS_CREATE:
806: n = make_cons(1, (W*)arg);
807: break;
808:
809: case CS_DELETE:
810: if (arg[0] > 2 && (p = check_port(arg[0]))) n = delete_cons(p);
811: else n = -1;
812: break;
813:
814: case CS_GETCONF:
815: if ((p = check_port(arg[0])) != NULL) {
816: arg[1] = p->conf;
817: arg[2] = p->in_bufsz;
818: arg[3] = p->ou_bufsz;
819: n = 0;
820: } else n = -1;
821: break;
822:
823: case CS_SRCHPORT:
824: n = 0;
825: p = (CONSCB*)&ConsPort;
826: while ((p = (CONSCB*)QueSearch((QUEUE*)p, &ConsPort, arg[1],
827: offsetof(CONSCB, conf))) != (CONSCB*)&ConsPort) {
828: if (p->port > arg[0]) {
829: arg[0] = n = p->port;
830: break;
831: }
832: }
833: break;
834:
835: case CS_SETCONF:
836: n = make_cons(0, (W*)arg);
837: break;
838:
839: case CS_GETPORT:
840: n = 1;
841: arg[0] = check_port(n) ? n : 1;
842: n = 0;
843: break;
844:
845: case CS_SETPORT:
846: n = -1;
847: break;
848:
849: default:
850: n = -1;
851: }
852:
853: Unlock(&ConsLock);
854: return n;
855: }
856: 857: 858:
859: LOCAL ER console_io_entry(void *para, W fn, void *gp)
860: {
861: switch ( fn ) {
862:
863: case CONSIO_CONSOLE_GET_FN:
864: { CONSIO_CONSOLE_GET_PARA *p = para;
865: return _console_get(p->port, p->buf, p->len, p->tmout); }
866: case CONSIO_CONSOLE_PUT_FN:
867: { CONSIO_CONSOLE_PUT_PARA *p = para;
868: return _console_put(p->port, p->buf, p->len, p->tmout); }
869: case CONSIO_CONSOLE_CONF_FN:
870: { CONSIO_CONSOLE_CONF_PARA *p = para;
871: return _console_conf(p->req, p->arg); }
872:
873:
874: case CONSIO_CONSOLE_IN_FN:
875: { CONSIO_CONSOLE_IN_PARA *p = para;
876: return _console_in(p->port, p->buf, p->len); }
877: case CONSIO_CONSOLE_OUT_FN:
878: { CONSIO_CONSOLE_OUT_PARA *p = para;
879: return _console_out(p->port, p->buf, p->len); }
880: case CONSIO_CONSOLE_CTL_FN:
881: { CONSIO_CONSOLE_CTL_PARA *p = para;
882: return _console_ctl(p->port, p->req, p->arg); }
883: }
884: return E_RSFN;
885: }
886: 887: 888:
889: LOCAL void console_break(ID tskid)
890: {
891: tk_dis_wai(tskid, TTW_FLG|TTX_SVC);
892: }
893: 894: 895:
896: EXPORT ER console_startup( BOOL StartUp )
897: {
898: W n, arg[4];
899:
900: if ( !StartUp ) {
901:
902:
903: con_def_subsys(CONSIO_SVC, CONSIO_PRI, NULL, NULL);
904:
905:
906: while (!isQueEmpty(&ConsPort)) {
907: delete_cons((CONSCB*)ConsPort.next);
908: }
909:
910:
911: DeleteLock(&ConsLock);
912:
913: return E_OK;
914: }
915:
916:
917: QueInit(&ConsPort);
918:
919:
920: CreateLock(&ConsLock, "cons");
921:
922:
923: tk_dly_tsk(50);
924:
925:
926: DebugPort = DEFAULT_CONSOLE_PORT;
927: if ((n = tm_extsvc(0x04, 0, 0, 0)) >= 0) DebugPort = n;
928:
929:
930: arg[1] = _isDebugMode() ? DebugPort : CONF_BUFIO;
931: arg[2] = arg[3] = 0;
932: if (_console_conf(CS_CREATE, (UW*)arg) < E_OK && _isDebugMode()) {
933: 934:
935: last_port = 0;
936: arg[1] = CONF_BUFIO;
937: _console_conf(CS_CREATE, (UW*)arg);
938: _console_ctl(1, 0x8e, 0x3);
939: }
940:
941:
942: arg[1] = DebugPort;
943: _console_conf(CS_CREATE, (UW*)arg);
944:
945:
946: _console_ctl(1, ECHO, 1);
947: _console_ctl(1, INPUT, EDIT);
948: _console_ctl(1, NEWLINE, 1);
949: _console_ctl(1, FLOWC, IXON | IXOFF);
950: if (!_isDebugMode()) _console_ctl(1, 0x8e, 0x3);
951:
952:
953: 954:
955: return con_def_subsys(CONSIO_SVC, CONSIO_PRI,
956: console_io_entry, console_break);
957: }