1 /*****************************************************************************/
4 * stlstats.c -- stallion intelligent multiport stats display.
6 * Copyright (c) 1994-1998 Greg Ungerer (gerg@stallion.oz.au).
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
36 * $FreeBSD: src/usr.sbin/stallion/stlstats/stlstats.c,v 1.9.2.1 2001/08/30 12:29:58 murray Exp $
37 * $DragonFly: src/usr.sbin/stallion/stlstats/stlstats.c,v 1.2 2003/06/17 04:30:03 dillon Exp $
40 /*****************************************************************************/
51 #include <sys/ioctl.h>
53 #include <machine/cdk.h>
54 #include <machine/comstats.h>
56 /*****************************************************************************/
58 char *version = "2.0.0";
59 char *defdevice = "/dev/staliomem0";
64 int displaypanelnr = 0;
65 int displayportnr = 0;
66 int displayportbank = 0;
72 comstats_t stats[MAXPORTS];
76 /*****************************************************************************/
79 * Declare internal function prototypes here.
81 static void usage(void);
82 void useportdevice(char *devname);
83 void localexit(int nr);
87 void displayallports();
90 void clearportstats();
93 /*****************************************************************************/
97 fprintf(stderr, "%s\n%s\n",
98 "usage: stlstats [-hVi] [-c control-device] [-b board-number]",
99 " [-p port-number] [-d port-device]");
103 /*****************************************************************************/
105 void useportdevice(char *devname)
107 struct stat statinfo;
111 if (stat(devname, &statinfo) < 0)
112 errx(1, "port device %s does not exist", devname);
113 if ((statinfo.st_mode & S_IFMT) != S_IFCHR)
114 errx(1, "port device %s is not a char device", devname);
116 displaybrdnr = (statinfo.st_rdev & 0x00700000) >> 20;
117 portnr = (statinfo.st_rdev & 0x1f) |
118 ((statinfo.st_rdev & 0x00010000) >> 11);
120 if (brdstats.ioaddr == 0)
121 errx(1, "device %s does not exist", devname);
123 for (portcnt = 0, i = 0; (i < brdstats.nrpanels); i++) {
124 if ((portnr >= portcnt) &&
125 (portnr < (portcnt + brdstats.panels[i].nrports)))
127 portcnt += brdstats.panels[i].nrports;
129 if (i >= brdstats.nrpanels)
130 errx(1, "device %s does not exist", devname);
132 displayportnr = portnr - portcnt;
133 if (displayportnr >= 16)
134 displayportbank = 16;
137 /*****************************************************************************/
140 * Get the board stats for the current display board.
145 brdstats.brd = displaybrdnr;
146 if (ioctl(ctrlfd, COM_GETBRDSTATS, &brdstats) < 0)
147 memset((combrd_t *) &brdstats, 0, sizeof(combrd_t));
150 /*****************************************************************************/
153 * Zero out stats for the current display port.
156 void clearportstats()
158 stats[displayportnr].brd = displaybrdnr;
159 stats[displayportnr].panel = displaypanelnr;
160 stats[displayportnr].port = displayportnr;
161 ioctl(ctrlfd, COM_CLRPORTSTATS, &stats[displayportnr]);
164 /*****************************************************************************/
167 * Zero out all stats for all ports on all boards.
172 int brdnr, panelnr, portnr;
174 for (brdnr = 0; (brdnr < MAXBRDS); brdnr++) {
175 for (panelnr = 0; (panelnr < COM_MAXPANELS); panelnr++) {
176 for (portnr = 0; (portnr < MAXPORTS); portnr++) {
177 stats[0].brd = brdnr;
178 stats[0].panel = panelnr;
179 stats[0].port = portnr;
180 ioctl(ctrlfd, COM_CLRPORTSTATS, &stats[0]);
186 /*****************************************************************************/
189 * Get the stats for the current display board/panel.
196 for (i = 0; (i < brdstats.panels[displaypanelnr].nrports); i++) {
197 stats[i].brd = displaybrdnr;
198 stats[i].panel = displaypanelnr;
200 if (ioctl(ctrlfd, COM_GETPORTSTATS, &stats[i]) < 0) {
201 warn("ioctl(COM_GETPORTSTATS) failed");
207 /*****************************************************************************/
210 * Display the per ports stats screen.
215 mvprintw(0, 0, "STALLION SERIAL PORT STATISTICS");
217 "Board=%d Type=%d HwID=%02x State=%06x TotalPorts=%d",
218 displaybrdnr, brdstats.type, brdstats.hwid, brdstats.state,
220 mvprintw(3, 0, "Panel=%d HwID=%02x Ports=%d", displaypanelnr,
221 brdstats.panels[displaypanelnr].hwid,
222 brdstats.panels[displaypanelnr].nrports);
225 mvprintw(5, 0, line);
226 mvprintw(5, 0, "Port=%d ", displayportnr);
229 mvprintw(7, 0, "STATE: State=%08x", stats[displayportnr].state);
230 mvprintw(7, 29, "Tty=%08x", stats[displayportnr].ttystate);
231 mvprintw(7, 47, "Flags=%08x", stats[displayportnr].flags);
232 mvprintw(7, 65, "HwID=%02x", stats[displayportnr].hwid);
234 mvprintw(8, 0, "CONFIG: Cflag=%08x", stats[displayportnr].cflags);
235 mvprintw(8, 29, "Iflag=%08x", stats[displayportnr].iflags);
236 mvprintw(8, 47, "Oflag=%08x", stats[displayportnr].oflags);
237 mvprintw(8, 65, "Lflag=%08x", stats[displayportnr].lflags);
239 mvprintw(10, 0, "TX DATA: Total=%d", stats[displayportnr].txtotal);
240 mvprintw(10, 29, "Buffered=%d ", stats[displayportnr].txbuffered);
241 mvprintw(11, 0, "RX DATA: Total=%d", stats[displayportnr].rxtotal);
242 mvprintw(11, 29, "Buffered=%d ", stats[displayportnr].rxbuffered);
243 mvprintw(12, 0, "RX ERRORS: Parity=%d", stats[displayportnr].rxparity);
244 mvprintw(12, 29, "Framing=%d", stats[displayportnr].rxframing);
245 mvprintw(12, 47, "Overrun=%d", stats[displayportnr].rxoverrun);
246 mvprintw(12, 65, "Lost=%d", stats[displayportnr].rxlost);
248 mvprintw(14, 0, "FLOW TX: Xoff=%d", stats[displayportnr].txxoff);
249 mvprintw(14, 29, "Xon=%d", stats[displayportnr].txxon);
251 mvprintw(14, 47, "CTSoff=%d", stats[displayportnr].txctsoff);
252 mvprintw(14, 65, "CTSon=%d", stats[displayportnr].txctson);
254 mvprintw(15, 0, "FLOW RX: Xoff=%d", stats[displayportnr].rxxoff);
255 mvprintw(15, 29, "Xon=%d", stats[displayportnr].rxxon);
256 mvprintw(15, 47, "RTSoff=%d", stats[displayportnr].rxrtsoff);
257 mvprintw(15, 65, "RTSon=%d", stats[displayportnr].rxrtson);
259 mvprintw(17, 0, "OTHER: TXbreaks=%d",
260 stats[displayportnr].txbreaks);
261 mvprintw(17, 29, "RXbreaks=%d", stats[displayportnr].rxbreaks);
262 mvprintw(17, 47, "Modem=%d", stats[displayportnr].modem);
264 mvprintw(19, 0, "SIGNALS: DCD=%d DTR=%d CTS=%d RTS=%d "
266 (stats[displayportnr].signals & TIOCM_CD) ? 1 : 0,
267 (stats[displayportnr].signals & TIOCM_DTR) ? 1 : 0,
268 (stats[displayportnr].signals & TIOCM_CTS) ? 1 : 0,
269 (stats[displayportnr].signals & TIOCM_RTS) ? 1 : 0,
270 (stats[displayportnr].signals & TIOCM_DSR) ? 1 : 0,
271 (stats[displayportnr].signals & TIOCM_RI) ? 1 : 0);
274 mvprintw(22, 0, line);
277 mvprintw(24, 19, "(q=Quit,0123456789abcdef=Port,Z=ZeroStats)");
281 /*****************************************************************************/
284 * Continuously update and display the per ports stats screen.
285 * Also checks for keyboard input, and processes it as appropriate.
295 while ((ch = getch()) != 27) {
308 ch = (ch - 'a' + '0' + 10);
321 if (ch >= brdstats.panels[displaypanelnr].nrports) {
324 displayportnr = displayportbank + ch;
348 /*****************************************************************************/
351 * Display the all ports stats screen.
354 void displayallports()
356 int i, nrports, portnr;;
358 nrports = brdstats.panels[displaypanelnr].nrports;
360 mvprintw(0, 0, "STALLION SERIAL PORT STATISTICS");
361 mvprintw(2, 0, "Board=%d Type=%d HwID=%02x State=%06x TotalPorts=%d",
362 displaybrdnr, brdstats.type, brdstats.hwid, brdstats.state,
364 mvprintw(3, 0, "Panel=%d HwID=%02x Ports=%d", displaypanelnr,
365 brdstats.panels[displaypanelnr].hwid, nrports);
368 mvprintw(5, 0, "Port State Tty Flags Cflag Iflag Oflag Lflag "
369 "Sigs TX Total RX Total ");
375 portnr = displayportbank;
376 for (i = 0; (i < nrports); i++, portnr++) {
377 mvprintw((6 + i), 1, "%2d", portnr);
378 mvprintw((6 + i), 5, "%06x", stats[portnr].state);
379 mvprintw((6 + i), 12, "%06x", stats[portnr].ttystate);
380 mvprintw((6 + i), 19, "%08x", stats[portnr].flags);
381 mvprintw((6 + i), 28, "%05x", stats[portnr].cflags);
382 mvprintw((6 + i), 34, "%05x", stats[portnr].iflags);
383 mvprintw((6 + i), 40, "%05x", stats[portnr].oflags);
384 mvprintw((6 + i), 46, "%05x", stats[portnr].lflags);
385 mvprintw((6 + i), 52, "%04x", stats[portnr].signals);
386 mvprintw((6 + i), 58, "%10d", stats[portnr].txtotal);
387 mvprintw((6 + i), 69, "%10d", stats[portnr].rxtotal);
390 mvprintw(12, 32, "NO BOARD %d FOUND", displaybrdnr);
395 mvprintw((6 + i), 0, line);
399 "(q=Quit,01234567=Board,n=Panels,p=Ports,Z=ZeroStats)");
403 /*****************************************************************************/
406 * Continuously update and display the all ports stats screen.
407 * Also checks for keyboard input, and processes it as appropriate.
418 while ((ch = getch()) != 27) {
433 displaybrdnr = ch - '0';
436 if (brdstats.state == 0)
441 if (brdstats.panels[displaypanelnr].nrports > 16) {
442 if (displayportbank == 0) {
443 displayportbank = 16;
450 if (displaypanelnr >= brdstats.nrpanels)
455 if (brdstats.panels[displaypanelnr].nrports > 0) {
456 displayportnr = displayportbank;
483 /*****************************************************************************/
486 * A local exit routine - shuts down curses before exiting.
489 void localexit(int nr)
496 /*****************************************************************************/
498 int main(int argc, char *argv[])
500 struct stat statinfo;
504 ctrldevice = defdevice;
507 while ((c = getopt(argc, argv, "hvVb:p:d:c:")) != -1) {
510 printf("stlstats version %s\n", version);
517 displaybrdnr = atoi(optarg);
520 displaypanelnr = atoi(optarg);
537 * Check that the control device exits and is a character device.
539 if (stat(ctrldevice, &statinfo) < 0)
540 errx(1, "control device %s does not exist", ctrldevice);
541 if ((statinfo.st_mode & S_IFMT) != S_IFCHR)
542 errx(1, "control device %s is not a char device", ctrldevice);
543 if ((ctrlfd = open(ctrldevice, O_RDWR)) < 0)
544 errx(1, "open of %s failed", ctrldevice);
547 * Validate the panel number supplied by user. We do this now since we
548 * need to have parsed the entire command line first.
551 if (displaypanelnr >= brdstats.nrpanels)
555 useportdevice(portdev);
558 * Everything is now ready, lets go!
578 /*****************************************************************************/