@@ 0,0 1,161 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+#include "devtab.h"
+#include "../port/netif.h"
+
+/*
+ * Stargate's Avanstar serial board. There are ISA, EISA, microchannel versions.
+ * At the moment we only handle the ISA one.
+ */
+typedef struct Astar Astar;
+typedef struct Astarport Astarchan;
+
+enum
+{
+ /* ISA control ports */
+ ISAid= 0, /* Id port and its values */
+ ISAid0= 0xEC,
+ ISAid1= 0x13,
+ ISActl1= 1, /* board control */
+ ISAien= 1<<7, /* interrupt enable */
+ ISAirqm= 4, /* shift for 3 bit irq code */
+ ISAdl= 1<<1, /* download bit (1 == download) */
+ ISApr= 1<<0, /* program ready */
+ ISActl2= 2, /* board control */
+ ISA186ien= 1<<7, /* I186 irq enable bit state */
+ ISA186idata= 1<<6, /* I186 irq data bit state */
+ ISAmemen= 1<<4, /* enable memory to respond to ISA cycles */
+ ISAmembank= 0, /* shift for 4 bit memory bank */
+ ISAmemaddr= 3, /* bits 14-19 of the boards mem address */
+ ISAstat1= 4, /* board status (1 bit per channel) */
+ ISAstat2= 5, /* board status (1 bit per channel) */
+};
+
+/* control program global control block */
+typedef struct GCB GCB;
+struct GCB
+{
+ ushort cmd; /* command word */
+ ushort status; /* status word */
+ ushort serv; /* service request, must be accessed via exchange 'X' */
+ ushort avail; /* available buffer space */
+ ushort type; /* board type */
+ ushort cpvers; /* control program version */
+ ushort ccbc; /* control channel block count */
+ ushort ccbo; /* control channel block offset */
+ ushort ccbc; /* control channel block size */
+ ushort cmd2; /* command word 2 */
+ ushort status2; /* status word 2 */
+ ushort errserv; /* comm error service request 'X' */
+ ushort inserv; /* input buffer service request 'X' */
+ ushort outserv; /* output buffer service request 'X' */
+ ushort modemserv; /* modem change service request 'X' */
+ ushort cmdserv; /* channel command service request 'X' */
+};
+
+/* control program channel control block */
+typedef struct CCB CCB;
+struct CCB
+{
+ ushort baud; /* baud rate */
+ ushort format; /* data format */
+ ushort line; /* line protocol */
+ ushort insize; /* input buffer size */
+ ushort outsize; /* output buffer size */
+ ushort intrigger; /* input buffer trigger rate */
+ ushort outlow; /* output buffer low water mark */
+ ushort xon; /* xon characters */
+ ushort inhigh; /* input buffer high water mark */
+ ushort inlow; /* input buffer low water mark */
+ ushort cmd; /* channel command */
+ ushort status; /* channel status */
+ ushort inbase; /* input buffer start addr */
+ ushort inlim; /* input buffer ending addr */
+ ushort outbase; /* output buffer start addr */
+ ushort outlim; /* output buffer ending addr */
+ ushort inwp; /* input read and write pointers */
+ ushort inrp;
+ ushort outwp; /* output read and write pointers */
+ ushort outrp;
+ ushort errstat; /* error status */
+ ushort badp; /* bad character pointer */
+ ushort mctl; /* modem control */
+ ushort mstat; /* modem status */
+ ushort bstat; /* blocking status */
+ ushort rflag; /* character received flag */
+ ushort xoff; /* xoff characters */
+ ushort status2;
+ uchort strip; /* strip/error characters */
+};
+
+/* host per controller info */
+struct Astar
+{
+ int port; /* number of first port */
+ GCB *gbc; /* board comm area */
+ Astarchan *c; /* channels */
+};
+
+/* host per channel info */
+struct Astarchan
+{
+ QLock;
+
+ /* buffers */
+ int (*putc)(Queue*, int);
+ Queue *iq;
+ Queue *oq;
+
+
+ /* staging areas to avoid some of the per character costs */
+ uchar istage[Stagesize];
+ uchar *ip;
+ uchar *ie;
+
+ uchar ostage[Stagesize];
+ uchar *op;
+ uchar *oe;
+};
+
+/*
+ * Stargate's Avanstar serial port cards. Currently only the ISA version
+ * is supported.
+ */
+void
+avanstarreset(void)
+{
+ int i;
+ Dirtab *dp;
+
+ for(i = 0; i < Maxcard; i++){
+ sc = scard[i] = xalloc(sizeof(Scard));
+ if(isaconfig("serial", i, sc) == 0){
+ xfree(sc);
+ break;
+ }
+
+ ndir = 3*nuart;
+ ns16552dir = xalloc(ndir * sizeof(Dirtab));
+ dp = ns16552dir;
+ for(i = 0; i < nuart; i++){
+ /* 3 directory entries per port */
+ sprint(dp->name, "eia%d", i);
+ dp->qid.path = NETQID(i, Ndataqid);
+ dp->perm = 0660;
+ dp++;
+ sprint(dp->name, "eia%dctl", i);
+ dp->qid.path = NETQID(i, Nctlqid);
+ dp->perm = 0660;
+ dp++;
+ sprint(dp->name, "eia%dstat", i);
+ dp->qid.path = NETQID(i, Nstatqid);
+ dp->perm = 0444;
+ dp++;
+ }
+}
@@ 131,12 131,14 @@ ns16552install(void)
ns16552setup(port, sc->freq);
port += 8;
}
- } else {
+ } else if(strcmp(sc->type, "com") == 0 || strcmp(sc->type, "COM") == 0){
/*
* port gives base port address for the uart
* irq is interrupt
* freq is the baud rate generator frequency
*/
+ if(sc->freq == 0)
+ sc->freq = UartFREQ;
ns16552setup(sc->port, sc->freq);
setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1));
}