110045Speter/* 210045Speter * Device driver for Specialix range (SLXOS) of serial line multiplexors. 310045Speter * SLXOS configuration and debug interface 410045Speter * 510045Speter * Copyright (C) 1990, 1992 Specialix International, 610045Speter * Copyright (C) 1993, Andy Rutter <andy@acronym.co.uk> 7179450Speter * Copyright (C) 1995, Peter Wemm 810045Speter * 910045Speter * Derived from: SunOS 4.x version 1010045Speter * 1110045Speter * Redistribution and use in source and binary forms, with or without 1210045Speter * modification, are permitted provided that the following conditions 1310045Speter * are met: 1410045Speter * 1. Redistributions of source code must retain the above copyright 1510045Speter * notices, this list of conditions and the following disclaimer. 1610045Speter * 2. Redistributions in binary form must reproduce the above copyright 1710045Speter * notices, this list of conditions and the following disclaimer in the 1810045Speter * documentation and/or other materials provided with the distribution. 1910045Speter * 4. Neither the name of Advanced Methods and Tools, nor Specialix 2010045Speter * International may be used to endorse or promote products derived from 2110045Speter * this software without specific prior written permission. 2210045Speter * 2310045Speter * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED 2410045Speter * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2510045Speter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 2610045Speter * NO EVENT SHALL THE AUTHORS BE LIABLE. 2710045Speter */ 2810045Speter 2930427Scharnier#ifndef lint 3030427Scharnierstatic const char rcsid[] = 3150479Speter "$FreeBSD$"; 3230427Scharnier#endif /* not lint */ 3330427Scharnier 3430427Scharnier#include <ctype.h> 3530427Scharnier#include <err.h> 3630427Scharnier#include <fcntl.h> 3769793Sobrien#include <paths.h> 3810045Speter#include <stdio.h> 3930427Scharnier#include <stdlib.h> 4030427Scharnier#include <string.h> 4110045Speter#include <sys/types.h> 4210045Speter#include <sys/param.h> 4310045Speter#include <sys/stat.h> 4410045Speter#include <sys/ioctl.h> 4510045Speter#include <sys/tty.h> 4610045Speter 47136063Sphk#define SI_DEBUG 4856509Speter#include <dev/si/si.h> 49136063Sphk#include <dev/si/sivar.h> 5010045Speter 5110045Speterstruct lv { 5210045Speter char *lv_name; 5310045Speter int lv_bit; 5410045Speter} lv[] = { 5530427Scharnier {"entry", DBG_ENTRY}, 5630427Scharnier {"open", DBG_OPEN}, 5730427Scharnier {"close", DBG_CLOSE}, 5830427Scharnier {"read", DBG_READ}, 5930427Scharnier {"write", DBG_WRITE}, 6030427Scharnier {"param", DBG_PARAM}, 6130427Scharnier {"modem", DBG_MODEM}, 6230427Scharnier {"select", DBG_SELECT}, 6330427Scharnier {"optim", DBG_OPTIM}, 6430427Scharnier {"intr", DBG_INTR}, 6530427Scharnier {"start", DBG_START}, 6630427Scharnier {"lstart", DBG_LSTART}, 6730427Scharnier {"ioctl", DBG_IOCTL}, 6830427Scharnier {"fail", DBG_FAIL}, 6930427Scharnier {"autoboot", DBG_AUTOBOOT}, 7030427Scharnier {"download", DBG_DOWNLOAD}, 7130427Scharnier {"drain", DBG_DRAIN}, 7230427Scharnier {"poll", DBG_POLL}, 7330427Scharnier {0, 0} 7410045Speter}; 7510045Speter 7610045Speterstatic int alldev = 0; 7710045Speter 7856520Spetervoid ccb_stat(int, char **); 79179590Spetervoid port_stat(int, char **); 8056520Spetervoid debug(int, char **); 8156520Spetervoid dostat(void); 8256520Speterint getnum(char *); 8356520Speterint islevel(char *); 8456520Speterint lvls2bits(char *); 8556520Spetervoid mstate(int, char **); 8656520Spetervoid nport(int, char **); 8756520Spetervoid onoff(int, char **, int, char *, char *, int); 8856520Speterint opencontrol(void); 8956520Spetervoid prlevels(int); 9056520Spetervoid prusage(int, int); 9156520Spetervoid rxint(int, char **); 9256520Spetervoid txint(int, char **); 9330427Scharnier 9410045Speterstruct opt { 9510045Speter char *o_name; 9656520Speter void (*o_func)(int, char **); 9710045Speter} opt[] = { 9830427Scharnier {"debug", debug}, 9930427Scharnier {"rxint_throttle", rxint}, 10030427Scharnier {"int_throttle", txint}, 10130427Scharnier {"nport", nport}, 10230427Scharnier {"mstate", mstate}, 10330427Scharnier {"ccbstat", ccb_stat}, 104179590Speter {"portstat", port_stat}, 10530427Scharnier {0, 0} 10610045Speter}; 10710045Speter 10810045Speterstruct stat_list { 10956520Speter void (*st_func)(int, char **); 11010045Speter} stat_list[] = { 11130427Scharnier {mstate}, 11230427Scharnier {0} 11310045Speter}; 11410045Speter 11510045Speter#define U_DEBUG 0 11610045Speter#define U_TXINT 1 11710045Speter#define U_RXINT 2 11811098Speter#define U_NPORT 3 11911098Speter#define U_MSTATE 4 12010045Speter#define U_STAT_CCB 5 121179590Speter#define U_STAT_PORT 6 12210045Speter 123179668Sed#define U_MAX 7 12410045Speter#define U_ALL -1 12510045Speterchar *usage[] = { 12610045Speter "debug [[add|del|set debug_levels] | [off]]\n", 12710045Speter "int_throttle [newvalue]\n", 12810045Speter "rxint_throttle [newvalue]\n", 12911098Speter "nport\n", 13010045Speter "mstate\n", 13110045Speter "ccbstat\n", 132179590Speter "portstat\n", 13310045Speter 0 13410045Speter}; 13510045Speter 13610045Speterint ctlfd; 13710045Speterchar *Devname; 13810045Speterstruct si_tcsi tc; 13910045Speter 14030427Scharnierint 14156520Spetermain(int argc, char **argv) 14210045Speter{ 14310045Speter struct opt *op; 14456520Speter void (*func)(int, char **) = NULL; 14510045Speter 14610045Speter if (argc < 2) 14710045Speter prusage(U_ALL, 1); 14810045Speter Devname = argv[1]; 14910045Speter if (strcmp(Devname, "-") == 0) { 15010045Speter alldev = 1; 15110045Speter } else { 15210045Speter sidev_t dev; 153179590Speter int n; 154179590Speter int card, port; 15510045Speter 156179590Speter n = sscanf(Devname, "%d:%d", &card, &port); 157179590Speter if (n != 2) 158179590Speter errx(1, "Devname must be in form card:port. eg: 0:7"); 159179590Speter dev.sid_card = card; 160179590Speter dev.sid_port = port; 16110045Speter tc.tc_dev = dev; 16210045Speter } 16310045Speter ctlfd = opencontrol(); 16410045Speter if (argc == 2) { 16510045Speter dostat(); 16610045Speter exit(0); 16710045Speter } 16810045Speter 16910045Speter argc--; argv++; 17010045Speter for (op = opt; op->o_name; op++) { 17110045Speter if (strcmp(argv[1], op->o_name) == 0) { 17210045Speter func = op->o_func; 17310045Speter break; 17410045Speter } 17510045Speter } 17610045Speter if (func == NULL) 17710045Speter prusage(U_ALL, 1); 17810045Speter 17910045Speter argc -= 2; 18010045Speter argv += 2; 18110045Speter (*func)(argc, argv); 18210045Speter exit(0); 18310045Speter} 18410045Speter 18530427Scharnierint 18656520Speteropencontrol(void) 18710045Speter{ 18810045Speter int fd; 18910045Speter 19010045Speter fd = open(CONTROLDEV, O_RDWR|O_NDELAY); 19130427Scharnier if (fd < 0) 19230427Scharnier err(1, "open on %s", CONTROLDEV); 19310045Speter return(fd); 19410045Speter} 19510045Speter 19610045Speter/* 19710045Speter * Print a usage message - this relies on U_DEBUG==0 and U_BOOT==1. 19810045Speter * Don't print the DEBUG usage string unless explicity requested. 19910045Speter */ 20030427Scharniervoid 20156520Speterprusage(int strn, int eflag) 20210045Speter{ 20310045Speter char **cp; 20410045Speter 20510045Speter if (strn == U_ALL) { 20630427Scharnier fprintf(stderr, "usage: sicontrol %s", usage[1]); 20730427Scharnier fprintf(stderr, " sicontrol %s", usage[2]); 20830427Scharnier fprintf(stderr, " sicontrol %s", usage[3]); 20911098Speter fprintf(stderr, " sicontrol devname %s", usage[4]); 21011098Speter for (cp = &usage[5]; *cp; cp++) 21111098Speter fprintf(stderr, " sicontrol devname %s", *cp); 21210045Speter } 21310045Speter else if (strn >= 0 && strn <= U_MAX) 21430427Scharnier fprintf(stderr, "usage: sicontrol devname %s", usage[strn]); 21510045Speter else 21610052Speter fprintf(stderr, "sicontrol: usage ???\n"); 21710045Speter exit(eflag); 21810045Speter} 21910045Speter 22010045Speter/* print port status */ 22130427Scharniervoid 22256520Speterdostat(void) 22310045Speter{ 22410045Speter char *av[1], *acp; 22510045Speter struct stat_list *stp; 22610045Speter struct si_tcsi stc; 22710045Speter int donefirst = 0; 22810045Speter 22910045Speter printf("%s: ", alldev ? "ALL" : Devname); 23010045Speter acp = malloc(strlen(Devname) + 3); 23110045Speter memset(acp, ' ', strlen(Devname)); 23210045Speter strcat(acp, " "); 23310045Speter stc = tc; 23410045Speter for (stp = stat_list; stp->st_func != NULL; stp++) { 23510045Speter if (donefirst) 23610045Speter fputs(acp, stdout); 23710045Speter else 23810045Speter donefirst++; 23910045Speter av[0] = NULL; 24010045Speter tc = stc; 24110045Speter (*stp->st_func)(-1, av); 24210045Speter } 24310045Speter} 24410045Speter 24510045Speter/* 24610045Speter * debug 24710045Speter * debug [[set|add|del debug_lvls] | [off]] 24810045Speter */ 24930427Scharniervoid 25056520Speterdebug(int ac, char **av) 25110045Speter{ 25230427Scharnier int level; 25310045Speter 25410045Speter if (ac > 2) 25510045Speter prusage(U_DEBUG, 1); 25610045Speter if (alldev) { 25710045Speter if (ioctl(ctlfd, TCSIGDBG_ALL, &tc.tc_dbglvl) < 0) 25830427Scharnier err(1, "TCSIGDBG_ALL on %s", Devname); 25910045Speter } else { 26010045Speter if (ioctl(ctlfd, TCSIGDBG_LEVEL, &tc) < 0) 26130427Scharnier err(1, "TCSIGDBG_LEVEL on %s", Devname); 26210045Speter } 26310045Speter 26410045Speter switch (ac) { 26510045Speter case 0: 26610045Speter printf("%s: debug levels - ", Devname); 26710045Speter prlevels(tc.tc_dbglvl); 26810045Speter return; 26910045Speter case 1: 27010045Speter if (strcmp(av[0], "off") == 0) { 27110045Speter tc.tc_dbglvl = 0; 27210045Speter break; 27310045Speter } 27410045Speter prusage(U_DEBUG, 1); 27510045Speter /* no return */ 27610045Speter case 2: 27710045Speter level = lvls2bits(av[1]); 27810045Speter if (strcmp(av[0], "add") == 0) 27910045Speter tc.tc_dbglvl |= level; 28010045Speter else if (strcmp(av[0], "del") == 0) 28110045Speter tc.tc_dbglvl &= ~level; 28210045Speter else if (strcmp(av[0], "set") == 0) 28310045Speter tc.tc_dbglvl = level; 28410045Speter else 28510045Speter prusage(U_DEBUG, 1); 28610045Speter } 28710045Speter if (alldev) { 28810045Speter if (ioctl(ctlfd, TCSISDBG_ALL, &tc.tc_dbglvl) < 0) 28930427Scharnier err(1, "TCSISDBG_ALL on %s", Devname); 29010045Speter } else { 29110045Speter if (ioctl(ctlfd, TCSISDBG_LEVEL, &tc) < 0) 29230427Scharnier err(1, "TCSISDBG_LEVEL on %s", Devname); 29310045Speter } 29410045Speter} 29510045Speter 29630427Scharniervoid 29756520Speterrxint(int ac, char **av) 29810045Speter{ 29910045Speter tc.tc_port = 0; 30010045Speter switch (ac) { 30110045Speter case 0: 30210045Speter printf("%s: ", Devname); 30310045Speter case -1: 30410045Speter if (ioctl(ctlfd, TCSIGRXIT, &tc) < 0) 30530427Scharnier err(1, "TCSIGRXIT"); 30610045Speter printf("RX interrupt throttle: %d msec\n", tc.tc_int*10); 30710045Speter break; 30810045Speter case 1: 30910045Speter tc.tc_int = getnum(av[0]) / 10; 31010045Speter if (tc.tc_int == 0) 31110045Speter tc.tc_int = 1; 31210045Speter if (ioctl(ctlfd, TCSIRXIT, &tc) < 0) 31330427Scharnier err(1, "TCSIRXIT on %s at %d msec", 31430427Scharnier Devname, tc.tc_int*10); 31510045Speter break; 31610045Speter default: 31710045Speter prusage(U_RXINT, 1); 31810045Speter } 31910045Speter} 32010045Speter 32130427Scharniervoid 32256520Spetertxint(int ac, char **av) 32310045Speter{ 32410045Speter 32510045Speter tc.tc_port = 0; 32610045Speter switch (ac) { 32710045Speter case 0: 32810045Speter printf("%s: ", Devname); 32910045Speter case -1: 33010045Speter if (ioctl(ctlfd, TCSIGIT, &tc) < 0) 33130427Scharnier err(1, "TCSIGIT"); 33210045Speter printf("aggregate interrupt throttle: %d\n", tc.tc_int); 33310045Speter break; 33410045Speter case 1: 33510045Speter tc.tc_int = getnum(av[0]); 33610045Speter if (ioctl(ctlfd, TCSIIT, &tc) < 0) 33730427Scharnier err(1, "TCSIIT on %s at %d", Devname, tc.tc_int); 33810045Speter break; 33910045Speter default: 34010045Speter prusage(U_TXINT, 1); 34110045Speter } 34210045Speter} 34310045Speter 34430427Scharniervoid 34556520Speteronoff(int ac, char **av, int cmd, char *cmdstr, char *prstr, int usage) 34610045Speter{ 34710045Speter if (ac > 1) 34810045Speter prusage(usage, 1); 34910045Speter if (ac == 1) { 35010045Speter if (strcmp(av[0], "on") == 0) 35110045Speter tc.tc_int = 1; 35210045Speter else if (strcmp(av[0], "off") == 0) 35310045Speter tc.tc_int = 0; 35410045Speter else 35510045Speter prusage(usage, 1); 35610045Speter } else 35710045Speter tc.tc_int = -1; 35810045Speter if (ioctl(ctlfd, cmd, &tc) < 0) 35930427Scharnier err(1, "%s on %s", cmdstr, Devname); 36010045Speter switch (ac) { 36110045Speter case 0: 36210045Speter printf("%s: ", Devname); 36310045Speter case -1: 36410045Speter printf("%s ", prstr); 36510045Speter if (tc.tc_int) 36610045Speter printf("on\n"); 36710045Speter else 36810045Speter printf("off\n"); 36910045Speter } 37010045Speter} 37110045Speter 37230427Scharniervoid 37356520Spetermstate(int ac, char **av) 37410045Speter{ 37510045Speter switch (ac) { 37610045Speter case 0: 37710045Speter printf("%s: ", Devname); 37810045Speter case -1: 37910045Speter break; 38010045Speter default: 38110045Speter prusage(U_MSTATE, 1); 38210045Speter } 38310045Speter if (ioctl(ctlfd, TCSISTATE, &tc) < 0) 38430427Scharnier err(1, "TCSISTATE on %s", Devname); 38510045Speter printf("modem bits state - (0x%x)", tc.tc_int); 38610045Speter if (tc.tc_int & IP_DCD) printf(" DCD"); 38710045Speter if (tc.tc_int & IP_DTR) printf(" DTR"); 38810045Speter if (tc.tc_int & IP_RTS) printf(" RTS"); 38910045Speter printf("\n"); 39010045Speter} 39110045Speter 39230427Scharniervoid 39356520Speternport(int ac, char **av) 39410045Speter{ 39510045Speter int ports; 39610045Speter 39710045Speter if (ac != 0) 39810045Speter prusage(U_NPORT, 1); 39910045Speter if (ioctl(ctlfd, TCSIPORTS, &ports) < 0) 40030427Scharnier err(1, "TCSIPORTS on %s", Devname); 40110045Speter printf("SLXOS: total of %d ports\n", ports); 40210045Speter} 40310045Speter 404179590Speterconst char *s_stat(int stat) 405179590Speter{ 406179590Speter switch (stat) { 407179590Speter case IDLE_OPEN: return "IDLE_OPEN"; 408179590Speter case LOPEN: return "LOPEN"; 409179590Speter case MOPEN: return "MOPEN"; 410179590Speter case MPEND: return "MPEND"; 411179590Speter case CONFIG: return "CONFIG"; 412179590Speter case CLOSE: return "CLOSE"; 413179590Speter case SBREAK: return "SBREAK"; 414179590Speter case EBREAK: return "EBREAK"; 415179590Speter case IDLE_CLOSE:return "IDLE_CLOSE"; 416179590Speter case IDLE_BREAK:return "IDLE_BREAK"; 417179590Speter case FCLOSE: return "FCLOSE"; 418179590Speter case RESUME: return "RESUME"; 419179590Speter case WFLUSH: return "WFLUSH"; 420179590Speter case RFLUSH: return "RFLUSH"; 421179590Speter default: return "??"; 422179590Speter } 423179590Speter} 424179590Speterconst char *s_mr1(int mr1) 425179590Speter{ 426179590Speter static char msg[200]; 427179590Speter 428179590Speter sprintf(msg, "%dbit, %s, parity:[", 5 + (mr1 & MR1_8_BITS), mr1 & MR1_ODD ? "odd" : "even"); 429179590Speter if (mr1 & MR1_WITH) 430179590Speter strcat(msg, "with;"); 431179590Speter if (mr1 & MR1_FORCE) 432179590Speter strcat(msg, "force;"); 433179590Speter if (mr1 & MR1_NONE) 434179590Speter strcat(msg, "none;"); 435179590Speter if (mr1 & MR1_SPECIAL) 436179590Speter strcat(msg, "special;"); 437179590Speter strcpy(msg + strlen(msg) - 1, "]"); 438179590Speter sprintf(msg + strlen(msg), ", err: %s", mr1 & MR1_BLOCK ? "block" : "none"); 439179590Speter sprintf(msg + strlen(msg), ", cts: %s", mr1 & MR1_CTSCONT ? "auto" : "none"); 440179590Speter return (msg); 441179590Speter} 442179590Speterconst char *s_mr2(int mr2) 443179590Speter{ 444179590Speter static char msg[200]; 445179590Speter 446179590Speter switch (mr2 & 0xf) { 447179590Speter case MR2_1_STOP: strcpy(msg, "1stop"); break; 448179590Speter case MR2_2_STOP: strcpy(msg, "2stop"); break; 449179590Speter default: sprintf(msg, "??stop (0x%x)", mr2 & 0xf); break; 450179590Speter } 451179590Speter if (mr2 & MR2_RTSCONT) strcat(msg, ", rtscont"); 452179590Speter if (mr2 & MR2_CTSCONT) strcat(msg, ", ctscont"); 453179590Speter switch (mr2 & 0xc0) { 454179590Speter case MR2_NORMAL: strcat(msg, ", mode:normal"); break; 455179590Speter case MR2_AUTO: strcat(msg, ", mode:auto"); break; 456179590Speter case MR2_LOCAL: strcat(msg, ", mode:local"); break; 457179590Speter case MR2_REMOTE: strcat(msg, ", mode:remote"); break; 458179590Speter } 459179590Speter return (msg); 460179590Speter} 461179590Speterconst char *s_clk(int clk) 462179590Speter{ 463179590Speter switch (clk & 0xf) { 464179590Speter case 0x0: return "75"; 465179590Speter case 0x1: return "110/115200"; 466179590Speter case 0x2: return "38400"; 467179590Speter case 0x3: return "150"; 468179590Speter case 0x4: return "300"; 469179590Speter case 0x5: return "600"; 470179590Speter case 0x6: return "1200"; 471179590Speter case 0x7: return "2000"; 472179590Speter case 0x8: return "2400"; 473179590Speter case 0x9: return "4800"; 474179590Speter case 0xa: return "7200"; 475179590Speter case 0xb: return "9600"; 476179590Speter case 0xc: return "19200"; 477179590Speter case 0xd: return "57600"; 478179590Speter case 0xe: return "?0xe"; 479179590Speter case 0xf: return "?0xf"; 480179590Speter } 481179590Speter return ("gcc sucks"); 482179590Speter} 483179590Speterconst char *s_op(int op) 484179590Speter{ 485179590Speter static char msg[200]; 486179590Speter 487179590Speter sprintf(msg, "cts:%s", (op & OP_CTS) ? "on" : "off"); 488179590Speter sprintf(msg + strlen(msg), ", dsr:%s", (op & OP_DSR) ? "on" : "off"); 489179590Speter return (msg); 490179590Speter} 491179590Speter 492179590Speterconst char *s_ip(int ip) 493179590Speter{ 494179590Speter static char msg[200]; 495179590Speter 496179590Speter sprintf(msg, "rts:%s", (ip & IP_RTS) ? "on" : "off"); 497179590Speter sprintf(msg + strlen(msg), ", dcd:%s", (ip & IP_DCD) ? "on" : "off"); 498179590Speter sprintf(msg + strlen(msg), ", dtr:%s", (ip & IP_DTR) ? "on" : "off"); 499179590Speter sprintf(msg + strlen(msg), ", ri:%s", (ip & IP_RI) ? "on" : "off"); 500179590Speter return (msg); 501179590Speter} 502179590Speter 503179590Speterconst char *s_state(int state) 504179590Speter{ 505179590Speter return (state & ST_BREAK ? "break:on" : "break:off"); 506179590Speter} 507179590Speter 508179590Speterconst char *s_prtcl(int pr) 509179590Speter{ 510179590Speter static char msg[200]; 511179590Speter 512179590Speter sprintf(msg, "tx xon any:%s", (pr & SP_TANY) ? "on" : "off"); 513179590Speter sprintf(msg + strlen(msg), ", tx xon/xoff:%s", (pr & SP_TXEN) ? "on" : "off"); 514179590Speter sprintf(msg + strlen(msg), ", cooking:%s", (pr & SP_CEN) ? "on" : "off"); 515179590Speter sprintf(msg + strlen(msg), ", rx xon/xoff:%s", (pr & SP_RXEN) ? "on" : "off"); 516179590Speter sprintf(msg + strlen(msg), ", dcd/dsr check:%s", (pr & SP_DCEN) ? "on" : "off"); 517179590Speter sprintf(msg + strlen(msg), ", parity check:%s", (pr & SP_PAEN) ? "on" : "off"); 518179590Speter return (msg); 519179590Speter} 520179590Speterconst char *s_break(int br) 521179590Speter{ 522179590Speter static char msg[200]; 523179590Speter 524179590Speter sprintf(msg, "ignore rx brk:%s", (br & BR_IGN) ? "on" : "off"); 525179590Speter sprintf(msg + strlen(msg), ", brk interrupt:%s", (br & BR_INT) ? "on" : "off"); 526179590Speter sprintf(msg + strlen(msg), ", parmrking:%s", (br & BR_PARMRK) ? "on" : "off"); 527179590Speter sprintf(msg + strlen(msg), ", parign:%s", (br & BR_PARIGN) ? "on" : "off"); 528179590Speter return (msg); 529179590Speter} 530179590Speter 531179590Speterconst char * 532179590Speters_xstat(int xs) 533179590Speter{ 534179590Speter static char msg[200]; 535179590Speter 536179590Speter msg[0] = 0; 537179590Speter /* MTA definitions, not TA */ 538179590Speter if (xs & 0x01) strcat(msg, "TION "); /* Tx interrupts on (MTA only) */ 539179590Speter if (xs & 0x02) strcat(msg, "RTSEN "); /* RTS FLOW enabled (MTA only) */ 540179590Speter if (xs & 0x04) strcat(msg, "RTSLOW "); /* XOFF received (TA only) */ 541179590Speter if (xs & 0x08) strcat(msg, "RXEN "); /* Rx XON/XOFF enabled */ 542179590Speter if (xs & 0x10) strcat(msg, "ANYXO "); /* XOFF pending/sent or RTS dropped */ 543179590Speter if (xs & 0x20) strcat(msg, "RXSE "); /* Rx XOFF sent */ 544179590Speter if (xs & 0x40) strcat(msg, "NPEND "); /* Rx XON pending or XOFF pending */ 545179590Speter if (xs & 0x40) strcat(msg, "FPEND "); /* Rx XOFF pending */ 546179590Speter return (msg); 547179590Speter} 548179590Speter 549179590Speterconst char * 550179590Speters_cstat(int cs) 551179590Speter{ 552179590Speter static char msg[200]; 553179590Speter 554179590Speter msg[0] = 0; 555179590Speter /* MTA definitions, not TA */ 556179590Speter if (cs & 0x01) strcat(msg, "TEMR "); /* Tx empty requested (MTA only) */ 557179590Speter if (cs & 0x02) strcat(msg, "TEMA "); /* Tx empty acked (MTA only) */ 558179590Speter if (cs & 0x04) strcat(msg, "EN "); /* Cooking enabled (on MTA means port is also || */ 559179590Speter if (cs & 0x08) strcat(msg, "HIGH "); /* Buffer previously hit high water */ 560179590Speter if (cs & 0x10) strcat(msg, "CTSEN "); /* CTS automatic flow-control enabled */ 561179590Speter if (cs & 0x20) strcat(msg, "DCDEN "); /* DCD/DTR checking enabled */ 562179590Speter if (cs & 0x40) strcat(msg, "BREAK "); /* Break detected */ 563179590Speter if (cs & 0x80) strcat(msg, "RTSEN "); /* RTS automatic flow control enabled (MTA only) */ 564179590Speter return (msg); 565179590Speter} 566179590Speter 56730427Scharniervoid 56856520Speterccb_stat(int ac, char **av) 56910045Speter{ 57010045Speter struct si_pstat sip; 57110045Speter#define CCB sip.tc_ccb 57210045Speter 57310045Speter if (ac != 0) 57430427Scharnier prusage(U_STAT_CCB, 1); 57510045Speter sip.tc_dev = tc.tc_dev; 57610045Speter if (ioctl(ctlfd, TCSI_CCB, &sip) < 0) 57730427Scharnier err(1, "TCSI_CCB on %s", Devname); 57810045Speter printf("%s: ", Devname); 57910045Speter 58010045Speter /* WORD next - Next Channel */ 58110045Speter /* WORD addr_uart - Uart address */ 58210045Speter /* WORD module - address of module struct */ 58310045Speter printf("\tuart_type 0x%x\n", CCB.type); /* BYTE type - Uart type */ 58410045Speter /* BYTE fill - */ 585179590Speter printf("\tx_status 0x%x %s\n", CCB.x_status, s_xstat(CCB.x_status)); /* BYTE x_status - XON / XOFF status */ 586179590Speter printf("\tc_status 0x%x %s\n", CCB.c_status, s_cstat(CCB.c_status)); /* BYTE c_status - cooking status */ 58710045Speter printf("\thi_rxipos 0x%x\n", CCB.hi_rxipos); /* BYTE hi_rxipos - stuff into rx buff */ 58810045Speter printf("\thi_rxopos 0x%x\n", CCB.hi_rxopos); /* BYTE hi_rxopos - stuff out of rx buffer */ 58910045Speter printf("\thi_txopos 0x%x\n", CCB.hi_txopos); /* BYTE hi_txopos - Stuff into tx ptr */ 59010045Speter printf("\thi_txipos 0x%x\n", CCB.hi_txipos); /* BYTE hi_txipos - ditto out */ 591179590Speter printf("\thi_stat 0x%x %s\n", CCB.hi_stat, s_stat(CCB.hi_stat));/* BYTE hi_stat - Command register */ 59210045Speter printf("\tdsr_bit 0x%x\n", CCB.dsr_bit); /* BYTE dsr_bit - Magic bit for DSR */ 59310045Speter printf("\ttxon 0x%x\n", CCB.txon); /* BYTE txon - TX XON char */ 59410045Speter printf("\ttxoff 0x%x\n", CCB.txoff); /* BYTE txoff - ditto XOFF */ 59510045Speter printf("\trxon 0x%x\n", CCB.rxon); /* BYTE rxon - RX XON char */ 59610045Speter printf("\trxoff 0x%x\n", CCB.rxoff); /* BYTE rxoff - ditto XOFF */ 597179590Speter printf("\thi_mr1 0x%x %s\n", CCB.hi_mr1, s_mr1(CCB.hi_mr1)); /* BYTE hi_mr1 - mode 1 image */ 598179590Speter printf("\thi_mr2 0x%x %s\n", CCB.hi_mr2, s_mr2(CCB.hi_mr2)); /* BYTE hi_mr2 - mode 2 image */ 599179590Speter printf("\thi_csr 0x%x in:%s out:%s\n", CCB.hi_csr, s_clk(CCB.hi_csr >> 4), s_clk(CCB.hi_csr)); /* BYTE hi_csr - clock register */ 600179590Speter printf("\thi_op 0x%x %s\n", CCB.hi_op, s_op(CCB.hi_op)); /* BYTE hi_op - Op control */ 601179590Speter printf("\thi_ip 0x%x %s\n", CCB.hi_ip, s_ip(CCB.hi_ip)); /* BYTE hi_ip - Input pins */ 602179590Speter printf("\thi_state 0x%x %s\n", CCB.hi_state, s_state(CCB.hi_state)); /* BYTE hi_state - status */ 603179590Speter printf("\thi_prtcl 0x%x %s\n", CCB.hi_prtcl, s_prtcl(CCB.hi_prtcl)); /* BYTE hi_prtcl - Protocol */ 60410045Speter printf("\thi_txon 0x%x\n", CCB.hi_txon); /* BYTE hi_txon - host copy tx xon stuff */ 60510045Speter printf("\thi_txoff 0x%x\n", CCB.hi_txoff); /* BYTE hi_txoff - */ 60610045Speter printf("\thi_rxon 0x%x\n", CCB.hi_rxon); /* BYTE hi_rxon - */ 60710045Speter printf("\thi_rxoff 0x%x\n", CCB.hi_rxoff); /* BYTE hi_rxoff - */ 60810045Speter printf("\tclose_prev 0x%x\n", CCB.close_prev); /* BYTE close_prev - Was channel previously closed */ 609179590Speter printf("\thi_break 0x%x %s\n", CCB.hi_break, s_break(CCB.hi_break)); /* BYTE hi_break - host copy break process */ 61010045Speter printf("\tbreak_state 0x%x\n", CCB.break_state); /* BYTE break_state - local copy ditto */ 61110045Speter printf("\thi_mask 0x%x\n", CCB.hi_mask); /* BYTE hi_mask - Mask for CS7 etc. */ 61210045Speter printf("\tmask_z280 0x%x\n", CCB.mask_z280); /* BYTE mask_z280 - Z280's copy */ 61310045Speter /* BYTE res[0x60 - 36] - */ 61410045Speter /* BYTE hi_txbuf[SLXOS_BUFFERSIZE] - */ 61510045Speter /* BYTE hi_rxbuf[SLXOS_BUFFERSIZE] - */ 61610045Speter /* BYTE res1[0xA0] - */ 61710045Speter} 61810045Speter 619179590Speterconst char *sp_state(int st) 620179590Speter{ 621179590Speter 622179590Speter if (st & SS_LSTART) 623179590Speter return("lstart "); 624179590Speter else 625179590Speter return(""); 626179590Speter} 627179590Speter 62830427Scharniervoid 629179590Speterport_stat(int ac, char **av) 630179590Speter{ 631179590Speter struct si_pstat sip; 632179590Speter#define PRT sip.tc_siport 633179590Speter 634179590Speter if (ac != 0) 635179590Speter prusage(U_STAT_PORT, 1); 636179590Speter sip.tc_dev = tc.tc_dev; 637179590Speter if (ioctl(ctlfd, TCSI_PORT, &sip) < 0) 638179590Speter err(1, "TCSI_PORT on %s", Devname); 639179590Speter printf("%s: ", Devname); 640179590Speter 641179590Speter printf("\tsp_pend 0x%x %s\n", PRT.sp_pend, s_stat(PRT.sp_pend)); 642179590Speter printf("\tsp_last_hi_ip 0x%x %s\n", PRT.sp_last_hi_ip, s_ip(PRT.sp_last_hi_ip)); 643179590Speter printf("\tsp_state 0x%x %s\n", PRT.sp_state, sp_state(PRT.sp_state)); 644179590Speter printf("\tsp_delta_overflows 0x%d\n", PRT.sp_delta_overflows); 645179590Speter} 646179590Speter 64730427Scharnierint 64856520Speterislevel(char *tk) 64910045Speter{ 65056520Speter struct lv *lvp; 65156520Speter char *acp; 65210045Speter 65310045Speter for (acp = tk; *acp; acp++) 65410045Speter if (isupper(*acp)) 65510045Speter *acp = tolower(*acp); 65610045Speter for (lvp = lv; lvp->lv_name; lvp++) 65710045Speter if (strcmp(lvp->lv_name, tk) == 0) 65810045Speter return(lvp->lv_bit); 65910045Speter return(0); 66010045Speter} 66110045Speter 66210045Speter/* 66310045Speter * Convert a string consisting of tokens separated by white space, commas 66410045Speter * or `|' into a bitfield - flag any unrecognised tokens. 66510045Speter */ 66630427Scharnierint 66756520Speterlvls2bits(char *str) 66810045Speter{ 66910045Speter int i, bits = 0; 67010045Speter int errflag = 0; 67110045Speter char token[20]; 67210045Speter 67310045Speter while (sscanf(str, "%[^,| \t]", token) == 1) { 67410045Speter str += strlen(token); 67510045Speter while (isspace(*str) || *str==',' || *str=='|') 67610045Speter str++; 67710045Speter if (strcmp(token, "all") == 0) 67810045Speter return(0xffffffff); 67910045Speter if ((i = islevel(token)) == 0) { 68030427Scharnier warnx("unknown token '%s'", token); 68110045Speter errflag++; 68210045Speter } else 68310045Speter bits |= i; 68410045Speter } 68510045Speter if (errflag) 68610045Speter exit(1); 68710045Speter 68810045Speter return(bits); 68910045Speter} 69010045Speter 69110045Speterint 69210045Spetergetnum(char *str) 69310045Speter{ 69410045Speter int x; 69556520Speter char *acp = str; 69610045Speter 69710045Speter x = 0; 69810045Speter while (*acp) { 69930427Scharnier if (!isdigit(*acp)) 70030427Scharnier errx(1, "%s is not a number", str); 70110045Speter x *= 10; 70210045Speter x += (*acp - '0'); 70310045Speter acp++; 70410045Speter } 70510045Speter return(x); 70610045Speter} 70710045Speter 70830427Scharniervoid 70956520Speterprlevels(int x) 71010045Speter{ 71110045Speter struct lv *lvp; 71210045Speter 71310045Speter switch (x) { 71410045Speter case 0: 71510045Speter printf("(none)\n"); 71610045Speter break; 71710045Speter case 0xffffffff: 71810045Speter printf("all\n"); 71910045Speter break; 72010045Speter default: 72110045Speter for (lvp = lv; lvp->lv_name; lvp++) 72210045Speter if (x & lvp->lv_bit) 72310045Speter printf(" %s", lvp->lv_name); 72410045Speter printf("\n"); 72510045Speter } 72610045Speter} 727