kernel: Fix for compiling drm into the kernel.
[dragonfly.git] / usr.sbin / stlstats / stlstats.c
CommitLineData
984263bc
MD
1/*****************************************************************************/
2
3/*
4 * stlstats.c -- stallion intelligent multiport stats display.
5 *
6 * Copyright (c) 1994-1998 Greg Ungerer (gerg@stallion.oz.au).
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Greg Ungerer.
20 * 4. Neither the name of the author nor the names of any co-contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
1de703da
MD
35 *
36 * $FreeBSD: src/usr.sbin/stallion/stlstats/stlstats.c,v 1.9.2.1 2001/08/30 12:29:58 murray Exp $
fc6d0222 37 * $DragonFly: src/usr.sbin/stallion/stlstats/stlstats.c,v 1.4 2006/08/03 16:40:49 swildner Exp $
984263bc
MD
38 */
39
40/*****************************************************************************/
41
984263bc
MD
42#include <err.h>
43#include <fcntl.h>
44#include <ncurses.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <time.h>
49#include <unistd.h>
50#include <sys/stat.h>
51#include <sys/ioctl.h>
52
53#include <machine/cdk.h>
54#include <machine/comstats.h>
55
56/*****************************************************************************/
57
58char *version = "2.0.0";
59char *defdevice = "/dev/staliomem0";
60
61char *ctrldevice;
62int ctrlfd;
63int displaybrdnr = 0;
64int displaypanelnr = 0;
65int displayportnr = 0;
66int displayportbank = 0;
67
68#define MAXBRDS 8
69#define MAXPORTS 32
70
71combrd_t brdstats;
72comstats_t stats[MAXPORTS];
73
74char *line = " ";
75
76/*****************************************************************************/
77
78/*
79 * Declare internal function prototypes here.
80 */
81static void usage(void);
82void useportdevice(char *devname);
83void localexit(int nr);
84void menuport();
85void displayport();
86void menuallports();
87void displayallports();
88void getallstats();
89void getbrdstats();
90void clearportstats();
91void clearallstats();
92
93/*****************************************************************************/
94
36471bd1
SW
95static void
96usage(void)
984263bc
MD
97{
98 fprintf(stderr, "%s\n%s\n",
99 "usage: stlstats [-hVi] [-c control-device] [-b board-number]",
100 " [-p port-number] [-d port-device]");
101 exit(0);
102}
103
104/*****************************************************************************/
105
36471bd1
SW
106void
107useportdevice(char *devname)
984263bc
MD
108{
109 struct stat statinfo;
110 int portnr, portcnt;
111 int i;
112
113 if (stat(devname, &statinfo) < 0)
114 errx(1, "port device %s does not exist", devname);
115 if ((statinfo.st_mode & S_IFMT) != S_IFCHR)
116 errx(1, "port device %s is not a char device", devname);
117
118 displaybrdnr = (statinfo.st_rdev & 0x00700000) >> 20;
119 portnr = (statinfo.st_rdev & 0x1f) |
120 ((statinfo.st_rdev & 0x00010000) >> 11);
121 getbrdstats();
122 if (brdstats.ioaddr == 0)
123 errx(1, "device %s does not exist", devname);
124
125 for (portcnt = 0, i = 0; (i < brdstats.nrpanels); i++) {
126 if ((portnr >= portcnt) &&
127 (portnr < (portcnt + brdstats.panels[i].nrports)))
128 break;
129 portcnt += brdstats.panels[i].nrports;
130 }
131 if (i >= brdstats.nrpanels)
132 errx(1, "device %s does not exist", devname);
133 displaypanelnr = i;
134 displayportnr = portnr - portcnt;
135 if (displayportnr >= 16)
136 displayportbank = 16;
137}
138
139/*****************************************************************************/
140
141/*
142 * Get the board stats for the current display board.
143 */
144
36471bd1
SW
145void
146getbrdstats(void)
984263bc
MD
147{
148 brdstats.brd = displaybrdnr;
149 if (ioctl(ctrlfd, COM_GETBRDSTATS, &brdstats) < 0)
150 memset((combrd_t *) &brdstats, 0, sizeof(combrd_t));
151}
152
153/*****************************************************************************/
154
155/*
156 * Zero out stats for the current display port.
157 */
158
36471bd1
SW
159void
160clearportstats(void)
984263bc
MD
161{
162 stats[displayportnr].brd = displaybrdnr;
163 stats[displayportnr].panel = displaypanelnr;
164 stats[displayportnr].port = displayportnr;
165 ioctl(ctrlfd, COM_CLRPORTSTATS, &stats[displayportnr]);
166}
167
168/*****************************************************************************/
169
170/*
171 * Zero out all stats for all ports on all boards.
172 */
173
36471bd1
SW
174void
175clearallstats(void)
984263bc
MD
176{
177 int brdnr, panelnr, portnr;
178
179 for (brdnr = 0; (brdnr < MAXBRDS); brdnr++) {
180 for (panelnr = 0; (panelnr < COM_MAXPANELS); panelnr++) {
181 for (portnr = 0; (portnr < MAXPORTS); portnr++) {
182 stats[0].brd = brdnr;
183 stats[0].panel = panelnr;
184 stats[0].port = portnr;
185 ioctl(ctrlfd, COM_CLRPORTSTATS, &stats[0]);
186 }
187 }
188 }
189}
190
191/*****************************************************************************/
192
193/*
194 * Get the stats for the current display board/panel.
195 */
196
36471bd1
SW
197void
198getallstats(void)
984263bc
MD
199{
200 int i;
201
202 for (i = 0; (i < brdstats.panels[displaypanelnr].nrports); i++) {
203 stats[i].brd = displaybrdnr;
204 stats[i].panel = displaypanelnr;
205 stats[i].port = i;
206 if (ioctl(ctrlfd, COM_GETPORTSTATS, &stats[i]) < 0) {
207 warn("ioctl(COM_GETPORTSTATS) failed");
208 localexit(1);
209 }
210 }
211}
212
213/*****************************************************************************/
214
215/*
216 * Display the per ports stats screen.
217 */
218
36471bd1
SW
219void
220displayport(void)
984263bc
MD
221{
222 mvprintw(0, 0, "STALLION SERIAL PORT STATISTICS");
223 mvprintw(2, 0,
224 "Board=%d Type=%d HwID=%02x State=%06x TotalPorts=%d",
225 displaybrdnr, brdstats.type, brdstats.hwid, brdstats.state,
226 brdstats.nrports);
227 mvprintw(3, 0, "Panel=%d HwID=%02x Ports=%d", displaypanelnr,
228 brdstats.panels[displaypanelnr].hwid,
229 brdstats.panels[displaypanelnr].nrports);
230
231 attron(A_REVERSE);
232 mvprintw(5, 0, line);
233 mvprintw(5, 0, "Port=%d ", displayportnr);
234 attroff(A_REVERSE);
235
236 mvprintw(7, 0, "STATE: State=%08x", stats[displayportnr].state);
237 mvprintw(7, 29, "Tty=%08x", stats[displayportnr].ttystate);
238 mvprintw(7, 47, "Flags=%08x", stats[displayportnr].flags);
239 mvprintw(7, 65, "HwID=%02x", stats[displayportnr].hwid);
240
241 mvprintw(8, 0, "CONFIG: Cflag=%08x", stats[displayportnr].cflags);
242 mvprintw(8, 29, "Iflag=%08x", stats[displayportnr].iflags);
243 mvprintw(8, 47, "Oflag=%08x", stats[displayportnr].oflags);
244 mvprintw(8, 65, "Lflag=%08x", stats[displayportnr].lflags);
245
246 mvprintw(10, 0, "TX DATA: Total=%d", stats[displayportnr].txtotal);
247 mvprintw(10, 29, "Buffered=%d ", stats[displayportnr].txbuffered);
248 mvprintw(11, 0, "RX DATA: Total=%d", stats[displayportnr].rxtotal);
249 mvprintw(11, 29, "Buffered=%d ", stats[displayportnr].rxbuffered);
250 mvprintw(12, 0, "RX ERRORS: Parity=%d", stats[displayportnr].rxparity);
251 mvprintw(12, 29, "Framing=%d", stats[displayportnr].rxframing);
252 mvprintw(12, 47, "Overrun=%d", stats[displayportnr].rxoverrun);
253 mvprintw(12, 65, "Lost=%d", stats[displayportnr].rxlost);
254
255 mvprintw(14, 0, "FLOW TX: Xoff=%d", stats[displayportnr].txxoff);
256 mvprintw(14, 29, "Xon=%d", stats[displayportnr].txxon);
257#if 0
258 mvprintw(14, 47, "CTSoff=%d", stats[displayportnr].txctsoff);
259 mvprintw(14, 65, "CTSon=%d", stats[displayportnr].txctson);
260#endif
261 mvprintw(15, 0, "FLOW RX: Xoff=%d", stats[displayportnr].rxxoff);
262 mvprintw(15, 29, "Xon=%d", stats[displayportnr].rxxon);
263 mvprintw(15, 47, "RTSoff=%d", stats[displayportnr].rxrtsoff);
264 mvprintw(15, 65, "RTSon=%d", stats[displayportnr].rxrtson);
265
266 mvprintw(17, 0, "OTHER: TXbreaks=%d",
267 stats[displayportnr].txbreaks);
268 mvprintw(17, 29, "RXbreaks=%d", stats[displayportnr].rxbreaks);
269 mvprintw(17, 47, "Modem=%d", stats[displayportnr].modem);
270
271 mvprintw(19, 0, "SIGNALS: DCD=%d DTR=%d CTS=%d RTS=%d "
272 "DSR=%d RI=%d",
273 (stats[displayportnr].signals & TIOCM_CD) ? 1 : 0,
274 (stats[displayportnr].signals & TIOCM_DTR) ? 1 : 0,
275 (stats[displayportnr].signals & TIOCM_CTS) ? 1 : 0,
276 (stats[displayportnr].signals & TIOCM_RTS) ? 1 : 0,
277 (stats[displayportnr].signals & TIOCM_DSR) ? 1 : 0,
278 (stats[displayportnr].signals & TIOCM_RI) ? 1 : 0);
279
280 attron(A_REVERSE);
281 mvprintw(22, 0, line);
282 attroff(A_REVERSE);
283
284 mvprintw(24, 19, "(q=Quit,0123456789abcdef=Port,Z=ZeroStats)");
285 refresh();
286}
287
288/*****************************************************************************/
289
290/*
291 * Continuously update and display the per ports stats screen.
292 * Also checks for keyboard input, and processes it as appropriate.
293 */
294
36471bd1
SW
295void
296menuport(void)
984263bc
MD
297{
298 int ch, done;
299
300 clear();
301 done = 0;
302
303 while ((ch = getch()) != 27) {
304 switch (ch) {
305 case ERR:
306 break;
307 case '\f':
308 refresh();
309 break;
310 case 'a':
311 case 'b':
312 case 'c':
313 case 'd':
314 case 'e':
315 case 'f':
316 ch = (ch - 'a' + '0' + 10);
317 /* fall thru */
318 case '0':
319 case '1':
320 case '2':
321 case '3':
322 case '4':
323 case '5':
324 case '6':
325 case '7':
326 case '8':
327 case '9':
328 ch -= '0';
329 if (ch >= brdstats.panels[displaypanelnr].nrports) {
330 beep();
331 } else {
332 displayportnr = displayportbank + ch;
333 clear();
334 }
335 break;
336 case 'Z':
337 clearportstats();
338 clear();
339 break;
340 case 'q':
341 done = 1;
342 break;
343 default:
344 beep();
345 break;
346 }
347
348 if (done)
349 break;
350
351 getallstats();
352 displayport();
353 }
354}
355
356/*****************************************************************************/
357
358/*
359 * Display the all ports stats screen.
360 */
361
36471bd1
SW
362void
363displayallports(void)
984263bc 364{
fc6d0222 365 int i, nrports, portnr;
984263bc
MD
366
367 nrports = brdstats.panels[displaypanelnr].nrports;
368
369 mvprintw(0, 0, "STALLION SERIAL PORT STATISTICS");
370 mvprintw(2, 0, "Board=%d Type=%d HwID=%02x State=%06x TotalPorts=%d",
371 displaybrdnr, brdstats.type, brdstats.hwid, brdstats.state,
372 brdstats.nrports);
373 mvprintw(3, 0, "Panel=%d HwID=%02x Ports=%d", displaypanelnr,
374 brdstats.panels[displaypanelnr].hwid, nrports);
375
376 attron(A_REVERSE);
377 mvprintw(5, 0, "Port State Tty Flags Cflag Iflag Oflag Lflag "
378 "Sigs TX Total RX Total ");
379 attroff(A_REVERSE);
380
381 if (nrports > 0) {
382 if (nrports > 16)
383 nrports = 16;
384 portnr = displayportbank;
385 for (i = 0; (i < nrports); i++, portnr++) {
386 mvprintw((6 + i), 1, "%2d", portnr);
387 mvprintw((6 + i), 5, "%06x", stats[portnr].state);
388 mvprintw((6 + i), 12, "%06x", stats[portnr].ttystate);
389 mvprintw((6 + i), 19, "%08x", stats[portnr].flags);
390 mvprintw((6 + i), 28, "%05x", stats[portnr].cflags);
391 mvprintw((6 + i), 34, "%05x", stats[portnr].iflags);
392 mvprintw((6 + i), 40, "%05x", stats[portnr].oflags);
393 mvprintw((6 + i), 46, "%05x", stats[portnr].lflags);
394 mvprintw((6 + i), 52, "%04x", stats[portnr].signals);
395 mvprintw((6 + i), 58, "%10d", stats[portnr].txtotal);
396 mvprintw((6 + i), 69, "%10d", stats[portnr].rxtotal);
397 }
398 } else {
399 mvprintw(12, 32, "NO BOARD %d FOUND", displaybrdnr);
400 i = 16;
401 }
402
403 attron(A_REVERSE);
404 mvprintw((6 + i), 0, line);
405 attroff(A_REVERSE);
406
407 mvprintw(24, 14,
408 "(q=Quit,01234567=Board,n=Panels,p=Ports,Z=ZeroStats)");
409 refresh();
410}
411
412/*****************************************************************************/
413
414/*
415 * Continuously update and display the all ports stats screen.
416 * Also checks for keyboard input, and processes it as appropriate.
417 */
418
36471bd1
SW
419void
420menuallports(void)
984263bc
MD
421{
422 int ch, done;
423
424 clear();
425 getbrdstats();
426
427 done = 0;
428 while ((ch = getch()) != 27) {
429 switch (ch) {
430 case ERR:
431 break;
432 case '\f':
433 refresh();
434 break;
435 case '0':
436 case '1':
437 case '2':
438 case '3':
439 case '4':
440 case '5':
441 case '6':
442 case '7':
443 displaybrdnr = ch - '0';
444 displaypanelnr = 0;
445 getbrdstats();
446 if (brdstats.state == 0)
447 beep();
448 clear();
449 break;
450 case 'n':
451 if (brdstats.panels[displaypanelnr].nrports > 16) {
452 if (displayportbank == 0) {
453 displayportbank = 16;
454 clear();
455 break;
456 }
457 }
458 displayportbank = 0;
459 displaypanelnr++;
460 if (displaypanelnr >= brdstats.nrpanels)
461 displaypanelnr = 0;
462 clear();
463 break;
464 case 'p':
465 if (brdstats.panels[displaypanelnr].nrports > 0) {
466 displayportnr = displayportbank;
467 menuport();
468 clear();
469 } else {
470 beep();
471 }
472 break;
473 case 'Z':
474 clearallstats();
475 clear();
476 break;
477 case 'q':
478 done = 1;
479 break;
480 default:
481 beep();
482 break;
483 }
484
485 if (done)
486 break;
487
488 getallstats();
489 displayallports();
490 }
491}
492
493/*****************************************************************************/
494
495/*
496 * A local exit routine - shuts down curses before exiting.
497 */
498
36471bd1
SW
499void
500localexit(int nr)
984263bc
MD
501{
502 refresh();
503 endwin();
504 exit(nr);
505}
506
507/*****************************************************************************/
508
36471bd1
SW
509int
510main(int argc, char *argv[])
984263bc
MD
511{
512 struct stat statinfo;
513 int c, useport;
514 char *portdev;
515
516 ctrldevice = defdevice;
517 useport = 0;
518
519 while ((c = getopt(argc, argv, "hvVb:p:d:c:")) != -1) {
520 switch (c) {
521 case 'V':
522 printf("stlstats version %s\n", version);
523 exit(0);
524 break;
525 case 'h':
526 usage();
527 break;
528 case 'b':
529 displaybrdnr = atoi(optarg);
530 break;
531 case 'p':
532 displaypanelnr = atoi(optarg);
533 break;
534 case 'd':
535 useport++;
536 portdev = optarg;
537 break;
538 case 'c':
539 ctrldevice = optarg;
540 break;
541 case '?':
542 default:
543 usage();
544 break;
545 }
546 }
547
548/*
549 * Check that the control device exits and is a character device.
550 */
551 if (stat(ctrldevice, &statinfo) < 0)
552 errx(1, "control device %s does not exist", ctrldevice);
553 if ((statinfo.st_mode & S_IFMT) != S_IFCHR)
554 errx(1, "control device %s is not a char device", ctrldevice);
555 if ((ctrlfd = open(ctrldevice, O_RDWR)) < 0)
556 errx(1, "open of %s failed", ctrldevice);
557
558/*
559 * Validate the panel number supplied by user. We do this now since we
560 * need to have parsed the entire command line first.
561 */
562 getbrdstats();
563 if (displaypanelnr >= brdstats.nrpanels)
564 displaypanelnr = 0;
565
566 if (useport)
567 useportdevice(portdev);
568
569/*
570 * Everything is now ready, lets go!
571 */
572 initscr();
573 cbreak();
574 halfdelay(5);
575 noecho();
576 clear();
577 if (useport) {
578 menuport();
579 clear();
580 }
581 menuallports();
582 refresh();
583 endwin();
584
585 close(ctrlfd);
586 printf("\n");
587 exit(0);
588}
589
590/*****************************************************************************/