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.4 2006/08/03 16:40:49 swildner 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 /*****************************************************************************/
98 fprintf(stderr
, "%s\n%s\n",
99 "usage: stlstats [-hVi] [-c control-device] [-b board-number]",
100 " [-p port-number] [-d port-device]");
104 /*****************************************************************************/
107 useportdevice(char *devname
)
109 struct stat statinfo
;
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
);
118 displaybrdnr
= (statinfo
.st_rdev
& 0x00700000) >> 20;
119 portnr
= (statinfo
.st_rdev
& 0x1f) |
120 ((statinfo
.st_rdev
& 0x00010000) >> 11);
122 if (brdstats
.ioaddr
== 0)
123 errx(1, "device %s does not exist", devname
);
125 for (portcnt
= 0, i
= 0; (i
< brdstats
.nrpanels
); i
++) {
126 if ((portnr
>= portcnt
) &&
127 (portnr
< (portcnt
+ brdstats
.panels
[i
].nrports
)))
129 portcnt
+= brdstats
.panels
[i
].nrports
;
131 if (i
>= brdstats
.nrpanels
)
132 errx(1, "device %s does not exist", devname
);
134 displayportnr
= portnr
- portcnt
;
135 if (displayportnr
>= 16)
136 displayportbank
= 16;
139 /*****************************************************************************/
142 * Get the board stats for the current display board.
148 brdstats
.brd
= displaybrdnr
;
149 if (ioctl(ctrlfd
, COM_GETBRDSTATS
, &brdstats
) < 0)
150 memset((combrd_t
*) &brdstats
, 0, sizeof(combrd_t
));
153 /*****************************************************************************/
156 * Zero out stats for the current display port.
162 stats
[displayportnr
].brd
= displaybrdnr
;
163 stats
[displayportnr
].panel
= displaypanelnr
;
164 stats
[displayportnr
].port
= displayportnr
;
165 ioctl(ctrlfd
, COM_CLRPORTSTATS
, &stats
[displayportnr
]);
168 /*****************************************************************************/
171 * Zero out all stats for all ports on all boards.
177 int brdnr
, panelnr
, portnr
;
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]);
191 /*****************************************************************************/
194 * Get the stats for the current display board/panel.
202 for (i
= 0; (i
< brdstats
.panels
[displaypanelnr
].nrports
); i
++) {
203 stats
[i
].brd
= displaybrdnr
;
204 stats
[i
].panel
= displaypanelnr
;
206 if (ioctl(ctrlfd
, COM_GETPORTSTATS
, &stats
[i
]) < 0) {
207 warn("ioctl(COM_GETPORTSTATS) failed");
213 /*****************************************************************************/
216 * Display the per ports stats screen.
222 mvprintw(0, 0, "STALLION SERIAL PORT STATISTICS");
224 "Board=%d Type=%d HwID=%02x State=%06x TotalPorts=%d",
225 displaybrdnr
, brdstats
.type
, brdstats
.hwid
, brdstats
.state
,
227 mvprintw(3, 0, "Panel=%d HwID=%02x Ports=%d", displaypanelnr
,
228 brdstats
.panels
[displaypanelnr
].hwid
,
229 brdstats
.panels
[displaypanelnr
].nrports
);
232 mvprintw(5, 0, line
);
233 mvprintw(5, 0, "Port=%d ", displayportnr
);
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
);
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
);
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
);
255 mvprintw(14, 0, "FLOW TX: Xoff=%d", stats
[displayportnr
].txxoff
);
256 mvprintw(14, 29, "Xon=%d", stats
[displayportnr
].txxon
);
258 mvprintw(14, 47, "CTSoff=%d", stats
[displayportnr
].txctsoff
);
259 mvprintw(14, 65, "CTSon=%d", stats
[displayportnr
].txctson
);
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
);
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
);
271 mvprintw(19, 0, "SIGNALS: DCD=%d DTR=%d CTS=%d RTS=%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);
281 mvprintw(22, 0, line
);
284 mvprintw(24, 19, "(q=Quit,0123456789abcdef=Port,Z=ZeroStats)");
288 /*****************************************************************************/
291 * Continuously update and display the per ports stats screen.
292 * Also checks for keyboard input, and processes it as appropriate.
303 while ((ch
= getch()) != 27) {
316 ch
= (ch
- 'a' + '0' + 10);
329 if (ch
>= brdstats
.panels
[displaypanelnr
].nrports
) {
332 displayportnr
= displayportbank
+ ch
;
356 /*****************************************************************************/
359 * Display the all ports stats screen.
363 displayallports(void)
365 int i
, nrports
, portnr
;
367 nrports
= brdstats
.panels
[displaypanelnr
].nrports
;
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
,
373 mvprintw(3, 0, "Panel=%d HwID=%02x Ports=%d", displaypanelnr
,
374 brdstats
.panels
[displaypanelnr
].hwid
, nrports
);
377 mvprintw(5, 0, "Port State Tty Flags Cflag Iflag Oflag Lflag "
378 "Sigs TX Total RX Total ");
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
);
399 mvprintw(12, 32, "NO BOARD %d FOUND", displaybrdnr
);
404 mvprintw((6 + i
), 0, line
);
408 "(q=Quit,01234567=Board,n=Panels,p=Ports,Z=ZeroStats)");
412 /*****************************************************************************/
415 * Continuously update and display the all ports stats screen.
416 * Also checks for keyboard input, and processes it as appropriate.
428 while ((ch
= getch()) != 27) {
443 displaybrdnr
= ch
- '0';
446 if (brdstats
.state
== 0)
451 if (brdstats
.panels
[displaypanelnr
].nrports
> 16) {
452 if (displayportbank
== 0) {
453 displayportbank
= 16;
460 if (displaypanelnr
>= brdstats
.nrpanels
)
465 if (brdstats
.panels
[displaypanelnr
].nrports
> 0) {
466 displayportnr
= displayportbank
;
493 /*****************************************************************************/
496 * A local exit routine - shuts down curses before exiting.
507 /*****************************************************************************/
510 main(int argc
, char *argv
[])
512 struct stat statinfo
;
516 ctrldevice
= defdevice
;
519 while ((c
= getopt(argc
, argv
, "hvVb:p:d:c:")) != -1) {
522 printf("stlstats version %s\n", version
);
529 displaybrdnr
= atoi(optarg
);
532 displaypanelnr
= atoi(optarg
);
549 * Check that the control device exits and is a character device.
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
);
559 * Validate the panel number supplied by user. We do this now since we
560 * need to have parsed the entire command line first.
563 if (displaypanelnr
>= brdstats
.nrpanels
)
567 useportdevice(portdev
);
570 * Everything is now ready, lets go!
590 /*****************************************************************************/