#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++; } }