From c0e72a1b896ef769641a2c796768486f6c08c1d7 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 15 Mar 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-03-15 --- pc/devastar.c | 74 +++++++++++++++++++++++--------- port/devns16552.c | 107 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 137 insertions(+), 44 deletions(-) diff --git a/pc/devastar.c b/pc/devastar.c index 103503e7111df76d25c6bd59fb5ce117c6d28f39..7f6ed1ee1e8ad598b79dc779eac20826ec3286d8 100644 --- a/pc/devastar.c +++ b/pc/devastar.c @@ -278,8 +278,12 @@ struct Astarchan int baud; /* baud rate */ int framing; /* framing errors */ int overrun; /* overruns */ + int hup_dsr; /* hangup when dsr goes away */ + int hup_dcd; /* hangup when dcd goes away */ int dtr; /* non-zero means dtr on */ int rts; /* non-zero means rts on */ + int dsr; /* non-zero means dsr on */ + int dcd; /* non-zero means dcd on */ Queue *iq; Queue *oq; @@ -761,31 +765,37 @@ bctlread(Astar *a, void *buf, long n, ulong offset) static long statread(Astarchan *ac, void *buf, long n, ulong offset) { - char s[128]; - int mstat, bstat; + char s[256]; + int mstat, bstat, fstat; LOCKPAGE(ac->a, 0); mstat = LEUS(ac->ccb->mstat); bstat = LEUS(ac->ccb->bstat); + fstat = LEUS(ac->ccb->format); UNLOCKPAGE(ac->a); - /* CCB.mstat fields */ - sprint(s, "opens %d ferr %d oerr %d baud %d", ac->opens, ac->framing, - ac->overrun, ac->baud); - if(mstat & Cctsstat) - strcat(s, " cts"); - if(mstat & Cdsrstat) - strcat(s, " dsr"); - if(mstat & Cristat) - strcat(s, " ring"); - if(mstat & Cdcdstat) - strcat(s, " dcd"); - if(ac->dtr) - strcat(s, " dtr"); - if(ac->rts && (bstat & Crbrts) == 0) - strcat(s, " rts"); - strcat(s, "\n"); - + snprint(s, sizeof s, + "b%d c%d d%d e%d l%d m%d p%c r%d s%d\n" + "%ld %d %d%s%s%s%s\n", + + ac->baud, + ac->hup_dcd, + ac->dtr, + ac->hup_dsr, + (fstat & Clenmask), + 0, /* change in modem status? */ + (fstat & Cparmask) ? ((fstat & Cevenpar) == Cevenpar ? 'e' : 'o') : 'n', + (bstat & Crbrts) ? 1 : 0, + (fstat & C2stop) ? 2 : 1, + + ac - ac->a->c, + ac->framing, + ac->overrun, + (mstat & Cctsstat) ? " cts" : "", + (mstat & Cdsrstat) ? " dsr" : "", + (mstat & Cdcdstat) ? " dcd" : "", + (mstat & Cristat) ? " ring" : "" + ); return readstr(offset, buf, n, s); } @@ -1184,6 +1194,7 @@ disable(Astarchan *ac) ac->ccb->proto = LEUS(n); UNLOCKPAGE(ac->a); chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall); + ac->dsr = ac->dcd = 0; } /* @@ -1543,6 +1554,24 @@ astarkickin(Astarchan *ac) iunlock(&ac->a->pagelock); } +static void +astarmodemchange(Astarchan *ac) +{ + Astar *a = ac->a; + int mstat; + + if(a->needpage) + setpage(a, 0); + mstat = LEUS(ac->ccb->mstat); + if(ac->hup_dsr && ac->dsr == 1 && (mstat & Cdsrstat) == 0 + || ac->hup_dcd && ac->dcd == 1 && (mstat & Cdcdstat) == 0){ + qhangup(ac->iq, nil); + qhangup(ac->oq, nil); + } + ac->dsr = mstat & Cdsrstat; + ac->dcd = mstat & Cdcdstat; +} + /* * handle an interrupt */ @@ -1571,7 +1600,6 @@ astarintr(Ureg *ur, void *arg) errvec = LEUS(xchgw(&a->gcb->errserv, 0)); mvec = LEUS(xchgw(&a->gcb->modemserv, 0)); cmdvec = LEUS(xchgw(&a->gcb->cmdserv, 0)); - USED(mvec); /* reenable interrupts */ if(a->pci){ @@ -1606,6 +1634,12 @@ astarintr(Ureg *ur, void *arg) ac++; } ac = a->c; + for(vec = mvec; vec; vec >>= 1){ + if(vec&1) + astarmodemchange(ac); + ac++; + } + ac = a->c; for(vec = errvec; vec; vec >>= 1){ c = LEUS(ac->ccb->errstat); if(c & Cframing) diff --git a/port/devns16552.c b/port/devns16552.c index 9cf223b3a2c03425317779ec4e58d99bb0c09e82..e865141a39ae13b0a03504473403be4c6eb33f9e 100644 --- a/port/devns16552.c +++ b/port/devns16552.c @@ -113,8 +113,10 @@ struct Uart int modem; /* hardware flow control on */ int xonoff; /* software flow control on */ int blocked; - int cts; + int cts, dsr, dcd; /* keep track of modem status */ int ctsbackoff; + int hup_dsr, hup_dcd; /* send hangup upstream? */ + int dohup; Rendez r; }; @@ -157,6 +159,21 @@ ns16552setbaud(Uart *p, int rate) p->baud = rate; } +/* + * decide if we should hangup when dsr or dcd drops. + */ +static void +ns16552dsrhup(Uart *p, int n) +{ + p->hup_dsr = n; +} + +static void +ns16552dcdhup(Uart *p, int n) +{ + p->hup_dcd = n; +} + static void ns16552parity(Uart *p, char type) { @@ -311,6 +328,9 @@ ns16552enable(Uart *p) uartpower(p->dev, 1); + p->hup_dsr = p->hup_dcd = 0; + p->cts = p->dsr = p->dcd = 0; + /* * turn on interrupts */ @@ -594,6 +614,24 @@ ns16552intr(int dev) p->ctsbackoff = 2; /* clock gets output going again */ iunlock(&p->tlock); } + if (ch & Dsrc) { + l = ch & Dsr; + if(p->hup_dsr && p->dsr && !l){ + ilock(&p->rlock); + p->dohup = 1; + iunlock(&p->rlock); + } + p->dsr = l; + } + if (ch & Dcdc) { + l = ch & Dcd; + if(p->hup_dcd && p->dcd && !l){ + ilock(&p->rlock); + p->dohup = 1; + iunlock(&p->rlock); + } + p->dcd = l; + } break; default: @@ -641,6 +679,15 @@ uartclock(void) } iunlock(&p->rlock); } + if(p->dohup){ + ilock(&p->rlock); + if(p->dohup){ + qhangup(p->iq, 0); + qhangup(p->oq, 0); + } + p->dohup = 0; + iunlock(&p->rlock); + } /* this adds hysteresis to hardware flow control */ if(p->ctsbackoff){ @@ -767,6 +814,7 @@ ns16552close(Chan *c) qclose(p->iq); qclose(p->oq); p->ip = p->istage; + p->dcd = p->dsr = p->dohup = 0; } qunlock(p); break; @@ -776,34 +824,37 @@ ns16552close(Chan *c) static long uartstatus(Chan*, Uart *p, void *buf, long n, long offset) { - uchar mstat; - uchar tstat; + uchar mstat, fstat, istat, tstat; char str[256]; str[0] = 0; tstat = p->sticky[Mctl]; mstat = uartrdreg(p, Mstat); - sprint(str, "opens %d ferr %d oerr %d baud %d", p->opens, - p->frame, p->overrun, p->baud); - if(mstat & Cts) - strcat(str, " cts"); - if(mstat & Dsr) - strcat(str, " dsr"); - if(mstat & Ring) - strcat(str, " ring"); - if(mstat & Dcd) - strcat(str, " dcd"); - if(tstat & Dtr) - strcat(str, " dtr"); - if(tstat & Rts) - strcat(str, " rts"); -{ -int i, j; - -i = strlen(str); -for(j = 0; j < 8; j++) i+=sprint(str+i, " %ux", uartrdreg(p, j)); -} - strcat(str, "\n"); + istat = p->sticky[Iena]; + fstat = p->sticky[Format]; + snprint(str, sizeof str, + "b%d c%d d%d e%d l%d m%d p%c r%d s%d\n" + "%d %d %d%s%s%s%s%s\n", + + p->baud, + p->hup_dcd, + (tstat & Dtr) != 0, + p->hup_dsr, + (fstat & Bits8) + 5, + (istat & Imstat) != 0, + (fstat & Pena) ? ((fstat & Peven) ? 'e' : 'o') : 'n', + (tstat & Rts) != 0, + (fstat & Stop2) ? 2 : 1, + + p->dev, + p->frame, + p->overrun, + p->fifoon ? " fifo" : "", + (mstat & Cts) ? " cts" : "", + (mstat & Dsr) ? " dsr" : "", + (mstat & Dcd) ? " dcd" : "", + (mstat & Ring) ? " ring" : "" + ); return readstr(offset, buf, n, str); } @@ -852,10 +903,18 @@ ns16552ctl(Uart *p, char *cmd) case 'b': ns16552setbaud(p, n); break; + case 'C': + case 'c': + ns16552dcdhup(p, n); + break; case 'D': case 'd': ns16552dtr(p, n); break; + case 'E': + case 'e': + ns16552dsrhup(p, n); + break; case 'f': case 'F': qflush(p->oq);