patch-1.3.73 linux/drivers/char/istallion.c
Next file: linux/drivers/char/stallion.c
Previous file: linux/drivers/char/README.stallion
Back to the patch index
Back to the overall index
- Lines: 287
- Date:
Mon Mar 11 11:20:32 1996
- Orig file:
v1.3.72/linux/drivers/char/istallion.c
- Orig date:
Fri Feb 16 11:34:06 1996
diff -u --recursive --new-file v1.3.72/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
@@ -38,6 +38,7 @@
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/cdk.h>
+#include <linux/comstats.h>
#include <linux/string.h>
#include <linux/malloc.h>
#include <linux/ioport.h>
@@ -179,7 +180,7 @@
* all the local structures required by a serial tty driver.
*/
static char *stli_drvname = "Stallion Intelligent Multiport Serial Driver";
-static char *stli_drvversion = "1.0.2";
+static char *stli_drvversion = "1.0.6";
static char *stli_serialname = "ttyE";
static char *stli_calloutname = "cue";
@@ -228,6 +229,14 @@
INIT_C_CC
};
+/*
+ * Define global stats structures. Not used often, and can be
+ * re-used for each stats call.
+ */
+static comstats_t stli_comstats;
+static combrd_t stli_brdstats;
+static asystats_t stli_cdkstats;
+
/*****************************************************************************/
/*
@@ -270,6 +279,7 @@
struct termios normaltermios;
struct termios callouttermios;
asysigs_t asig;
+ comstats_t stats;
unsigned long addr;
unsigned long rxoffset;
unsigned long txoffset;
@@ -302,6 +312,7 @@
int slaveoffset;
int bitsize;
int panels[STL_MAXPANELS];
+ int panelids[STL_MAXPANELS];
void (*init)(struct stlbrd *brdp);
void (*enable)(struct stlbrd *brdp);
void (*reenable)(struct stlbrd *brdp);
@@ -661,6 +672,9 @@
static void stli_read(stlibrd_t *brdp, stliport_t *portp);
static void stli_getserial(stliport_t *portp, struct serial_struct *sp);
static int stli_setserial(stliport_t *portp, struct serial_struct *sp);
+static int stli_getbrdstats(combrd_t *bp);
+static int stli_getportstats(stliport_t *portp, comstats_t *cp);
+static int stli_clrportstats(stliport_t *portp, comstats_t *cp);
static void *stli_memalloc(int len);
static void stli_ecpinit(stlibrd_t *brdp);
@@ -696,6 +710,8 @@
static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
static void stli_stalreset(stlibrd_t *brdp);
+static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
+
#if STLI_HIMEMORY
static void *stli_mapbrdmem(unsigned long physaddr, unsigned int size);
#endif
@@ -1938,6 +1954,14 @@
stli_setport(portp);
}
break;
+ case COM_GETPORTSTATS:
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
+ rc = stli_getportstats(portp, (comstats_t *) arg);
+ break;
+ case COM_CLRPORTSTATS:
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
+ rc = stli_clrportstats(portp, (comstats_t *) arg);
+ break;
case TIOCSERCONFIG:
case TIOCSERGWILD:
case TIOCSERSWILD:
@@ -3543,6 +3567,7 @@
brdp->nrports += 8;
nxtid++;
}
+ brdp->panelids[panelnr] = status;
brdp->nrpanels++;
}
@@ -3692,6 +3717,7 @@
}
brdp->nrports = i;
}
+ brdp->panels[0] = brdp->nrports;
request_region(brdp->iobase, ONB_IOSIZE, "serial(ONB/BBY)");
brdp->state |= BST_FOUND;
@@ -4244,6 +4270,169 @@
/*****************************************************************************/
/*
+ * Return the board stats structure to user app.
+ */
+
+static int stli_getbrdstats(combrd_t *bp)
+{
+ stlibrd_t *brdp;
+ int i;
+
+ memcpy_fromfs(&stli_brdstats, bp, sizeof(combrd_t));
+ if (stli_brdstats.brd >= STL_MAXBRDS)
+ return(-ENODEV);
+ brdp = stli_brds[stli_brdstats.brd];
+ if (brdp == (stlibrd_t *) NULL)
+ return(-ENODEV);
+
+ memset(&stli_brdstats, 0, sizeof(combrd_t));
+ stli_brdstats.brd = brdp->brdnr;
+ stli_brdstats.type = brdp->brdtype;
+ stli_brdstats.hwid = 0;
+ stli_brdstats.state = brdp->state;
+ stli_brdstats.ioaddr = brdp->iobase;
+ stli_brdstats.memaddr = brdp->memaddr;
+ stli_brdstats.nrpanels = brdp->nrpanels;
+ stli_brdstats.nrports = brdp->nrports;
+ for (i = 0; (i < brdp->nrpanels); i++) {
+ stli_brdstats.panels[i].panel = i;
+ stli_brdstats.panels[i].hwid = brdp->panelids[i];
+ stli_brdstats.panels[i].nrports = brdp->panels[i];
+ }
+
+ memcpy_tofs(bp, &stli_brdstats, sizeof(combrd_t));
+ return(0);
+}
+
+/*****************************************************************************/
+
+/*
+ * Resolve the referenced port number into a port struct pointer.
+ */
+
+static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
+{
+ stlibrd_t *brdp;
+ int i;
+
+ if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
+ return((stliport_t *) NULL);
+ brdp = stli_brds[brdnr];
+ if (brdp == (stlibrd_t *) NULL)
+ return((stliport_t *) NULL);
+ for (i = 0; (i < panelnr); i++)
+ portnr += brdp->panels[i];
+ if ((portnr < 0) || (portnr >= brdp->nrports))
+ return((stliport_t *) NULL);
+ return(brdp->ports[portnr]);
+}
+
+/*****************************************************************************/
+
+/*
+ * Return the port stats structure to user app. A NULL port struct
+ * pointer passed in means that we need to find out from the app
+ * what port to get stats for (used through board control device).
+ */
+
+static int stli_getportstats(stliport_t *portp, comstats_t *cp)
+{
+ stlibrd_t *brdp;
+ int rc;
+
+ if (portp == (stliport_t *) NULL) {
+ memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
+ portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
+ if (portp == (stliport_t *) NULL)
+ return(-ENODEV);
+ }
+
+ brdp = stli_brds[portp->brdnr];
+ if (brdp == (stlibrd_t *) NULL)
+ return(-ENODEV);
+
+ portp->stats.state = portp->state;
+ portp->stats.flags = portp->flags;
+ if (portp->tty != (struct tty_struct *) NULL) {
+ portp->stats.ttystate = portp->tty->flags;
+ portp->stats.cflags = portp->tty->termios->c_cflag;
+ portp->stats.iflags = portp->tty->termios->c_iflag;
+ portp->stats.oflags = portp->tty->termios->c_oflag;
+ portp->stats.lflags = portp->tty->termios->c_lflag;
+ portp->stats.rxbuffered = portp->tty->flip.count;
+ } else {
+ portp->stats.ttystate = 0;
+ portp->stats.cflags = 0;
+ portp->stats.iflags = 0;
+ portp->stats.oflags = 0;
+ portp->stats.lflags = 0;
+ portp->stats.rxbuffered = 0;
+ }
+
+ if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
+ return(rc);
+
+ portp->stats.txtotal = stli_cdkstats.txchars;
+ portp->stats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover;
+ portp->stats.txbuffered = stli_cdkstats.txringq;
+ portp->stats.rxbuffered += stli_cdkstats.rxringq;
+ portp->stats.rxoverrun = stli_cdkstats.overruns;
+ portp->stats.rxparity = stli_cdkstats.parity;
+ portp->stats.rxframing = stli_cdkstats.framing;
+ portp->stats.rxlost = stli_cdkstats.ringover;
+ portp->stats.rxbreaks = stli_cdkstats.rxbreaks;
+ portp->stats.txbreaks = stli_cdkstats.txbreaks;
+ portp->stats.txxon = stli_cdkstats.txstart;
+ portp->stats.txxoff = stli_cdkstats.txstop;
+ portp->stats.rxxon = stli_cdkstats.rxstart;
+ portp->stats.rxxoff = stli_cdkstats.rxstop;
+ portp->stats.rxrtsoff = stli_cdkstats.rtscnt / 2;
+ portp->stats.rxrtson = stli_cdkstats.rtscnt - portp->stats.rxrtsoff;
+ portp->stats.modem = stli_cdkstats.dcdcnt;
+ portp->stats.hwid = stli_cdkstats.hwid;
+ portp->stats.signals = stli_mktiocm(stli_cdkstats.signals);
+
+ memcpy_tofs(cp, &portp->stats, sizeof(comstats_t));
+ return(0);
+}
+
+/*****************************************************************************/
+
+/*
+ * Clear the port stats structure. We also return it zeroed out...
+ */
+
+static int stli_clrportstats(stliport_t *portp, comstats_t *cp)
+{
+ stlibrd_t *brdp;
+ int rc;
+
+ if (portp == (stliport_t *) NULL) {
+ memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
+ portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
+ if (portp == (stliport_t *) NULL)
+ return(-ENODEV);
+ }
+
+ brdp = stli_brds[portp->brdnr];
+ if (brdp == (stlibrd_t *) NULL)
+ return(-ENODEV);
+
+ memset(&portp->stats, 0, sizeof(comstats_t));
+ portp->stats.brd = portp->brdnr;
+ portp->stats.panel = portp->panelnr;
+ portp->stats.port = portp->portnr;
+
+ if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, 0, 0, 0)) < 0)
+ return(rc);
+
+ memcpy_tofs(cp, &portp->stats, sizeof(comstats_t));
+ return(0);
+}
+
+/*****************************************************************************/
+
+/*
* The "staliomem" device is also required to do some special operations on
* the board. We need to be able to send an interrupt to the board,
* reset it, and start/stop it.
@@ -4286,6 +4475,18 @@
if (brdp->reenable != NULL)
(* brdp->reenable)(brdp);
}
+ break;
+ case COM_GETPORTSTATS:
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
+ rc = stli_getportstats((stliport_t *) NULL, (comstats_t *) arg);
+ break;
+ case COM_CLRPORTSTATS:
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
+ rc = stli_clrportstats((stliport_t *) NULL, (comstats_t *) arg);
+ break;
+ case COM_GETBRDSTATS:
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(combrd_t))) == 0)
+ rc = stli_getbrdstats((combrd_t *) arg);
break;
default:
rc = -ENOIOCTLCMD;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this