From b9d6bb3e76f933d9db1d044630a9ee36d63abd54 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 10 Dec 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-12-10 --- pc/devuart.c | 88 +++++++++++++++++++++++++++++++++++++++++++++------- power/scsi.c | 21 ++++++++++++- 2 files changed, 96 insertions(+), 13 deletions(-) diff --git a/pc/devuart.c b/pc/devuart.c index 20b336b222519b3203f9859f8f7ae2da7d3221be..c9931e5b6ceb6bfd7d45426cf13b2a37a25dffa6 100644 --- a/pc/devuart.c +++ b/pc/devuart.c @@ -45,6 +45,14 @@ enum Ferror=(1<<3), /* rcv framing error */ Outready=(1<<5), /* output buffer full */ Mstat= 6, /* modem status */ + Ctsc= (1<<0), /* clear to send changed */ + Dsrc= (1<<1), /* data set ready changed */ + Rire= (1<<2), /* rising edge of ring indicator */ + Dcdc= (1<<3), /* data carrier detect changed */ + Cts= (1<<4), /* complement of clear to send line */ + Dsr= (1<<5), /* complement of data set ready line */ + Ring= (1<<6), /* complement of ring indicator line */ + Dcd= (1<<7), /* complement of data carrier detect line */ Scratch=7, /* scratchpad */ Dlsb= 0, /* divisor lsb */ Dmsb= 1, /* divisor msb */ @@ -61,6 +69,7 @@ struct Uart uchar sticky[8]; /* sticky write register values */ int printing; /* true if printing */ int enabled; + int cts; /* console interface */ int special; /* can't use the stream interface */ @@ -198,6 +207,24 @@ uartstop(Uart *up, int n) uartwrreg(up, Format, 0); } +/* + * modem flow control on/off (rts/cts) + */ +void +uartmflow(Uart *up, int n) +{ + if(n){ + up->sticky[Iena] |= Imstat; + uartwrreg(up, Iena, 0); + up->cts = uartrdreg(up, Mstat) & Cts; + } else { + up->sticky[Iena] &= ~Imstat; + uartwrreg(up, Iena, 0); + up->cts = 1; + } +} + + /* * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, * transmit and receive enabled, interrupts disabled. @@ -245,11 +272,13 @@ void uartputs(IOQ *cq, char *s, int n) { Uart *up = cq->ptr; - int ch, x; + int ch, x, multiprocessor; int tries; + multiprocessor = active.machs > 1; x = splhi(); - lock(cq); + if(multiprocessor) + lock(cq); puts(cq, s, n); if(up->printing == 0){ ch = getc(cq); @@ -261,7 +290,8 @@ uartputs(IOQ *cq, char *s, int n) outb(up->port + Data, ch); } } - unlock(cq); + if(multiprocessor) + unlock(cq); splx(x); } @@ -273,8 +303,9 @@ uartintr(Uart *up) { int ch; IOQ *cq; - int s, l; + int s, l, multiprocessor; + multiprocessor = active.machs > 1; for(;;){ s = uartrdreg(up, Istat); switch(s){ @@ -301,18 +332,42 @@ uartintr(Uart *up) cq = up->oq; if(cq == 0) break; - lock(cq); - ch = getc(cq); - if(ch < 0){ + if(multiprocessor) + lock(cq); + if(up->cts == 0) up->printing = 0; - wakeup(&cq->r); - }else - outb(up->port + Data, ch); - unlock(cq); + else { + ch = getc(cq); + if(ch < 0){ + up->printing = 0; + wakeup(&cq->r); + }else + outb(up->port + Data, ch); + } + if(multiprocessor) + unlock(cq); break; case 0: /* modem status */ - uartrdreg(up, Mstat); + ch = uartrdreg(up, Mstat); + if(ch & Ctsc){ + up->cts = ch & Cts; + cq = up->oq; + if(cq == 0) + break; + if(multiprocessor) + lock(cq); + if(up->cts && up->printing == 0){ + ch = getc(cq); + if(ch >= 0){ + up->printing = 1; + outb(up->port + Data, getc(cq)); + } else + wakeup(&cq->r); + } + if(multiprocessor) + unlock(cq); + } break; default: @@ -390,6 +445,11 @@ uartenable(Uart *up) */ uartdtr(up, 1); uartrts(up, 1); + + /* + * assume we can send + */ + up->cts = 1; } /* @@ -548,6 +608,10 @@ uartoput(Queue *q, Block *bp) case 'l': uartbits(up, n); break; + case 'm': + case 'M': + uartmflow(up, n); + break; case 'P': case 'p': uartparity(up, *(bp->rptr+1)); diff --git a/power/scsi.c b/power/scsi.c index 736ec0f7099acee02495f59bd28ee356b18c5c41..f80af12379ce077ea3b05ea7a4c8f8b62301aed2 100644 --- a/power/scsi.c +++ b/power/scsi.c @@ -210,6 +210,20 @@ done(void *arg) return (((Target*)arg)->flags & Fbusy) == 0; } +static void +scsiregs(Target *ctlr) +{ + int x; + + print("scsi aux status #%.2ux\n", *ctlr->addr & 0xFF); + for(*ctlr->addr = 0x00, x = 0x00; x < 0x19; x++){ + if((x & 0x07) == 0x07) + print("#%.2ux: #%.2ux\n", x, *ctlr->data & 0xFF); + else + print("#%.2ux: #%.2ux ", x, *ctlr->data & 0xFF); + } +} + static int scsiio(int nbus, Scsi *p, int rw) { @@ -257,7 +271,12 @@ scsiio(int nbus, Scsi *p, int rw) * Wait for the request to complete * and return the status. */ - sleep(tp, done, tp); + tsleep(tp, done, tp, 60*5*1000); + + if(!done(tp)) { + print("scsi%d: Timeout! cmd=#%2.2lux\n", nbus, tp->cdb[0]); + scsiregs(ctlr); + } status = tp->status; p->data.ptr += tp->dmatx;