| plan 9 kernel history: overview | file list | diff list |
1991/0801/pc/devuart.c (diff list | history)
| 1991/0801/sys/src/9/pc/devuart.c:37,43 – 1991/0803/sys/src/9/pc/devuart.c:37,43 (short | long) | ||
| 1991/0801 | Loop= (1<<4), /* loop bask */ Lstat= 5, /* line status */ Inready=(1<<0), /* receive buffer full */ | |
| 1991/0803 | Outready=(1<<5), /* output buffer full */ | |
| 1991/0801 | Mstat= 6, /* modem status */ Scratch=7, /* scratchpad */ Dlsb= 0, /* divisor lsb */ | |
| 1991/0801/sys/src/9/pc/devuart.c:88,94 – 1991/0803/sys/src/9/pc/devuart.c:88,94 | ||
| 1991/0801 | { ulong brconst; | |
| 1991/0803 | brconst = (UartFREQ+8*rate-1)/(16*rate); | |
| 1991/0801 | uartwrreg(up, Format, Dra); uartwrreg(up, Dmsb, (brconst>>8) & 0xff); | |
| 1991/0801/sys/src/9/pc/devuart.c:178,183 – 1991/0803/sys/src/9/pc/devuart.c:178,184 | ||
| 1991/0801 | { Uart *up = cq->ptr; int st, ch, x; | |
| 1991/0803 | int tries; | |
| 1991/0801 | x = splhi(); lock(cq); | |
| 1991/0801/sys/src/9/pc/devuart.c:187,193 – 1991/0803/sys/src/9/pc/devuart.c:188,195 | ||
| 1991/0801 | print("<start %2.2ux>", ch);/**/ if(ch >= 0){ up->printing = 1; | |
| 1991/0803 | for(tries = 0; tries<10000 && !(uartrdreg(up, Lstat)&Outready); tries++) | |
| 1991/0801 | ; outb(up->port + Data, ch); } | |
| 1991/0801/sys/src/9/pc/devuart.c:202,212 – 1991/0803/sys/src/9/pc/devuart.c:204,216 | ||
| 1991/0801 | void uartintr(Uart *up) { | |
| 1991/0803 | int s; | |
| 1991/0801 |
| |
| 1991/0803 | s = uartrdreg(up, Istat); print("uartintr %lux\n", s); switch(s){ | |
| 1991/0801 | case 3: /* * get any input characters | |
| 1991/0801/sys/src/9/pc/devuart.c:227,236 – 1991/0803/sys/src/9/pc/devuart.c:231,241 | ||
| 1991/0801 | /* * send next output character */ | |
| 1991/0803 | if(uartrdreg(up, Lstat)&Outready){ | |
| 1991/0801 | cq = up->oq; lock(cq); ch = getc(cq); | |
| 1991/0803 | print("<cont %2.2ux>", ch);/**/ | |
| 1991/0801 | if(ch < 0){ up->printing = 0; wakeup(&cq->r); | |
| 1991/0801/sys/src/9/pc/devuart.c:270,275 – 1991/0803/sys/src/9/pc/devuart.c:275,281 | ||
| 1991/0801 | up->iq->ptr = up; up->sticky[Iena] |= Ircv; } | |
| 1991/0803 | up->sticky[Iena] |= (1<<2) | (1<<3); | |
| 1991/0801 | /* * turn on interrupts | |
| 1991/0801/sys/src/9/pc/devuart.c:465,471 – 1991/0803/sys/src/9/pc/devuart.c:471,476 | ||
| 1991/0801 | loop: while ((n = cangetc(cq)) == 0){ | |
| 1991/0801/sys/src/9/pc/devuart.c:505,510 – 1991/0803/sys/src/9/pc/devuart.c:510,518 | ||
| 1991/0801 | uartreset(void) { Uart *up; | |
| 1991/0803 | if(serial(0) < 0) print("can't turn on power\n"); | |
| 1991/0801 | uartsetup(); for(up = uart; up < &uart[2]; up++){ | |
| 1991/0803/sys/src/9/pc/devuart.c:49,55 – 1991/0804/sys/src/9/pc/devuart.c:49,55 (short | long) | ||
| 1991/0801 | { QLock; int port; | |
| 1991/0804 | uchar sticky[8]; /* sticky write register values */ | |
| 1991/0801 | int printing; /* true if printing */ /* console interface */ | |
| 1991/0803/sys/src/9/pc/devuart.c:70,77 – 1991/0804/sys/src/9/pc/devuart.c:70,77 | ||
| 1991/0801 | #define UartFREQ 1846200 | |
| 1991/0804 | #define uartwrreg(u,r,v) outb((u)->port + r, (u)->sticky[r] | (v)) #define uartrdreg(u,r) inb((u)->port + r) | |
| 1991/0801 | void uartintr(Uart*); void uartintr0(Ureg*); | |
| 1991/0803/sys/src/9/pc/devuart.c:91,98 – 1991/0804/sys/src/9/pc/devuart.c:91,98 | ||
| 1991/0803 | brconst = (UartFREQ+8*rate-1)/(16*rate); | |
| 1991/0801 | uartwrreg(up, Format, Dra); | |
| 1991/0804 | outb(up->port+Dmsb, (brconst>>8) & 0xff); outb(up->port+Dlsb, brconst & 0xff); | |
| 1991/0801 | uartwrreg(up, Format, 0); } | |
| 1991/0803/sys/src/9/pc/devuart.c:148,154 – 1991/0804/sys/src/9/pc/devuart.c:148,154 | ||
| 1991/0801 | already = 1; /* | |
| 1991/0804 | * set port addresses | |
| 1991/0801 | */ uart[0].port = 0x3F8; uart[1].port = 0x2F8; | |
| 1991/0804/sys/src/9/pc/devuart.c:206,250 – 1991/0806/sys/src/9/pc/devuart.c:206,245 (short | long) | ||
| 1991/0801 | { int ch; IOQ *cq; | |
| 1991/0803 |
| |
| 1991/0806 | int s, l; | |
| 1991/0801 | ||
| 1991/0806 | l = uartrdreg(up, Lstat); | |
| 1991/0803 | s = uartrdreg(up, Istat); | |
| 1991/0801 |
| |
| 1991/0803 |
| |
| 1991/0801 |
| |
| 1991/0803 |
| |
| 1991/0801 |
| |
| 1991/0806 | cq = up->iq; while(l & Inready){ ch = uartrdreg(up, Data) & 0xff; print("<get %2.2ux>", ch); if(cq->putc) (*cq->putc)(cq, ch); else { putc(cq, ch); if(up->delim[ch/8] & (1<<(ch&7)) ) | |
| 1991/0801 | wakeup(&cq->r); | |
| 1991/0806 | l = uartrdreg(up, Lstat); | |
| 1991/0801 | } | |
| 1991/0806 | /* * send next output character */ if(up->printing && (l&Outready)){ cq = up->oq; lock(cq); ch = getc(cq); print("<put %2.2ux>", ch);/**/ if(ch < 0){ up->printing = 0; wakeup(&cq->r); }else outb(up->port + Data, ch); unlock(cq); } | |
| 1991/0801 | } void uartintr0(Ureg *ur) | |
| 1991/0804/sys/src/9/pc/devuart.c:263,268 – 1991/0806/sys/src/9/pc/devuart.c:258,265 | ||
| 1991/0801 | void uartenable(Uart *up) { | |
| 1991/0806 | int x; | |
| 1991/0801 | /* * set up i/o routines */ | |
| 1991/0804/sys/src/9/pc/devuart.c:287,292 – 1991/0806/sys/src/9/pc/devuart.c:284,298 | ||
| 1991/0801 | */ uartdtr(up, 1); uartrts(up, 1); | |
| 1991/0806 | /* * read interrupt status till there aren't any pending */ while(uartrdreg(up, Istat) != 1){ x = splhi(); uartintr(up); splx(x); } | |
| 1991/0801 | } /* | |
| 1991/0804/sys/src/9/pc/devuart.c:303,308 – 1991/0806/sys/src/9/pc/devuart.c:309,318 | ||
| 1991/0801 | up->iq = iq; uartenable(up); uartsetbaud(up, baud); | |
| 1991/0806 | if(port == 0){ if(serial(0) < 0) print("can't turn on serial port power\n"); } | |
| 1991/0801 | if(iq){ /* | |
| 1991/0804/sys/src/9/pc/devuart.c:366,374 – 1991/0806/sys/src/9/pc/devuart.c:376,389 | ||
| 1991/0801 | Uart *up; char name[NAMELEN]; | |
| 1991/0806 | print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", | |
| 1991/0801 | q, s->inuse, s->type, s->dev, s->id); | |
| 1991/0806 | ||
| 1991/0801 | up = &uart[s->id]; | |
| 1991/0806 | uartenable(up); if(s->id==0 && serial(0)<0) print("can't turn on serial power\n"); | |
| 1991/0801 | qlock(up); up->wq = WR(q); WR(q)->ptr = up; | |
| 1991/0804/sys/src/9/pc/devuart.c:399,404 – 1991/0806/sys/src/9/pc/devuart.c:414,422 | ||
| 1991/0801 | WR(q)->ptr = 0; RD(q)->ptr = 0; qunlock(up); | |
| 1991/0806 | if(serial(1) < 0) print("can't turn off serial power\n"); | |
| 1991/0801 | } static void | |
| 1991/0804/sys/src/9/pc/devuart.c:511,519 – 1991/0806/sys/src/9/pc/devuart.c:529,534 | ||
| 1991/0801 | { Uart *up; | |
| 1991/0803 |
| |
| 1991/0801 |
| |
| 1991/0804/sys/src/9/pc/devuart.c:522,528 – 1991/0806/sys/src/9/pc/devuart.c:537,542 | ||
| 1991/0801 | initq(up->iq); up->oq = ialloc(sizeof(IOQ), 0); initq(up->oq); | |
| 1991/0806/sys/src/9/pc/devuart.c:51,56 – 1991/0807/sys/src/9/pc/devuart.c:51,57 (short | long) | ||
| 1991/0801 | int port; | |
| 1991/0804 | uchar sticky[8]; /* sticky write register values */ | |
| 1991/0801 | int printing; /* true if printing */ | |
| 1991/0807 | int enabled; | |
| 1991/0801 | /* console interface */ int nostream; /* can't use the stream interface */ | |
| 1991/0806/sys/src/9/pc/devuart.c:185,191 – 1991/0807/sys/src/9/pc/devuart.c:186,191 | ||
| 1991/0801 | puts(cq, s, n); if(up->printing == 0){ ch = getc(cq); | |
| 1991/0803 | for(tries = 0; tries<10000 && !(uartrdreg(up, Lstat)&Outready); | |
| 1991/0806/sys/src/9/pc/devuart.c:214,220 – 1991/0807/sys/src/9/pc/devuart.c:214,219 | ||
| 1991/0806 | cq = up->iq; while(l & Inready){ ch = uartrdreg(up, Data) & 0xff; | |
| 1991/0806/sys/src/9/pc/devuart.c:232,238 – 1991/0807/sys/src/9/pc/devuart.c:231,236 | ||
| 1991/0806 | cq = up->oq; lock(cq); ch = getc(cq); | |
| 1991/0806/sys/src/9/pc/devuart.c:244,250 – 1991/0807/sys/src/9/pc/devuart.c:242,249 | ||
| 1991/0801 | void uartintr0(Ureg *ur) { | |
| 1991/0807 | if(uart[0].enabled) uartintr(&uart[0]); | |
| 1991/0801 | } void uartintr1(Ureg *ur) | |
| 1991/0806/sys/src/9/pc/devuart.c:261,266 – 1991/0807/sys/src/9/pc/devuart.c:260,273 | ||
| 1991/0806 | int x; | |
| 1991/0801 | /* | |
| 1991/0807 | * turn on power to the port */ if(up == &uart[0]){ if(serial(0) < 0) print("can't turn on serial port power\n"); } /* | |
| 1991/0801 | * set up i/o routines */ if(up->oq){ | |
| 1991/0806/sys/src/9/pc/devuart.c:272,277 – 1991/0807/sys/src/9/pc/devuart.c:279,285 | ||
| 1991/0801 | up->iq->ptr = up; up->sticky[Iena] |= Ircv; } | |
| 1991/0807 | up->enabled = 1; | |
| 1991/0803 | up->sticky[Iena] |= (1<<2) | (1<<3); | |
| 1991/0801 | /* | |
| 1991/0806/sys/src/9/pc/devuart.c:284,297 – 1991/0807/sys/src/9/pc/devuart.c:292,324 | ||
| 1991/0801 | */ uartdtr(up, 1); uartrts(up, 1); | |
| 1991/0807 | } | |
| 1991/0806 | ||
| 1991/0807 | /* * turn off the uart */ uartdisable(Uart *up) { | |
| 1991/0806 | /* | |
| 1991/0807 | * turn off interrupts | |
| 1991/0806 | */ | |
| 1991/0807 | up->sticky[Iena] = 0; uartwrreg(up, Iena, 0); /* * turn off DTR and RTS */ uartdtr(up, 0); uartrts(up, 0); up->enabled = 0; /* * turn off power */ if(up == &uart[0]){ if(serial(1) < 0) print("can't turn off serial power\n"); | |
| 1991/0806 | } | |
| 1991/0801 | } | |
| 1991/0806/sys/src/9/pc/devuart.c:309,318 – 1991/0807/sys/src/9/pc/devuart.c:336,341 | ||
| 1991/0801 | up->iq = iq; uartenable(up); uartsetbaud(up, baud); | |
| 1991/0806 |
| |
| 1991/0801 | if(iq){ /* | |
| 1991/0806/sys/src/9/pc/devuart.c:381,388 – 1991/0807/sys/src/9/pc/devuart.c:404,409 | ||
| 1991/0806 | ||
| 1991/0801 | up = &uart[s->id]; | |
| 1991/0806 | uartenable(up); | |
| 1991/0801 | qlock(up); up->wq = WR(q); | |
| 1991/0806/sys/src/9/pc/devuart.c:407,412 – 1991/0807/sys/src/9/pc/devuart.c:428,435 | ||
| 1991/0801 | { Uart *up = q->ptr; | |
| 1991/0807 | uartdisable(up); | |
| 1991/0801 | qlock(up); kprint("uartstclose: q=0x%ux, id=%d\n", q, up-uart); up->wq = 0; | |
| 1991/0806/sys/src/9/pc/devuart.c:414,422 – 1991/0807/sys/src/9/pc/devuart.c:437,442 | ||
| 1991/0801 | WR(q)->ptr = 0; RD(q)->ptr = 0; qunlock(up); | |
| 1991/0806 |
| |
| 1991/0801 | } static void | |
| 1991/0807/sys/src/9/pc/devuart.c:1,4 – 1991/0808/sys/src/9/pc/devuart.c:1,4 (short | long) | ||
| 1991/0801 |
| |
| 1991/0808 | #include "u.h" | |
| 1991/0801 | #include "lib.h" #include "mem.h" #include "dat.h" | |
| 1991/0807/sys/src/9/pc/devuart.c:18,26 – 1991/0808/sys/src/9/pc/devuart.c:18,25 | ||
| 1991/0801 | */ Data= 0, /* xmit/rcv buffer */ Iena= 1, /* interrupt enable */ | |
| 1991/0808 | Istat= 2, /* interrupt flag (read) */ Tctl= 2, /* test control (write) */ | |
| 1991/0801 | Format= 3, /* byte format */ Bits8= (3<<0), /* 8 bits/byte */ Stop2= (1<<2), /* 2 stop bits */ | |
| 1991/0807/sys/src/9/pc/devuart.c:42,47 – 1991/0808/sys/src/9/pc/devuart.c:41,49 | ||
| 1991/0801 | Scratch=7, /* scratchpad */ Dlsb= 0, /* divisor lsb */ Dmsb= 1, /* divisor msb */ | |
| 1991/0808 | Serial= 0, Modem= 1, | |
| 1991/0801 | }; typedef struct Uart Uart; | |
| 1991/0807/sys/src/9/pc/devuart.c:62,68 – 1991/0808/sys/src/9/pc/devuart.c:64,69 | ||
| 1991/0801 | Queue *wq; /* write queue */ Rendez r; /* kproc waiting for input */ Alarm *a; /* alarm for waking the kernel process */ | |
| 1991/0807/sys/src/9/pc/devuart.c:248,254 – 1991/0808/sys/src/9/pc/devuart.c:249,256 | ||
| 1991/0801 | void uartintr1(Ureg *ur) { | |
| 1991/0808 | if(uart[1].enabled) uartintr(&uart[1]); | |
| 1991/0801 | } /* | |
| 1991/0807/sys/src/9/pc/devuart.c:262,291 – 1991/0808/sys/src/9/pc/devuart.c:264,297 | ||
| 1991/0801 | /* | |
| 1991/0807 | * turn on power to the port */ | |
| 1991/0808 | if(up == &uart[Serial]){ | |
| 1991/0807 | if(serial(0) < 0) print("can't turn on serial port power\n"); } /* | |
| 1991/0808 | * speed up the clock to poll the uart */ fclockinit(); /* | |
| 1991/0801 | * set up i/o routines */ if(up->oq){ up->oq->puts = uartputs; up->oq->ptr = up; | |
| 1991/0807 | up->enabled = 1; | |
| 1991/0803 |
| |
| 1991/0808 | up->sticky[Iena] = 0xf; | |
| 1991/0801 | /* * turn on interrupts */ uartwrreg(up, Iena, 0); | |
| 1991/0808 | uartwrreg(up, Tctl, 0x0); | |
| 1991/0801 | /* * turn on DTR and RTS | |
| 1991/0807/sys/src/9/pc/devuart.c:292,297 – 1991/0808/sys/src/9/pc/devuart.c:298,305 | ||
| 1991/0801 | */ uartdtr(up, 1); uartrts(up, 1); | |
| 1991/0808 | print("uart enabled: Iena=%lux\n", uartrdreg(up, Iena)); | |
| 1991/0807 | } | |
| 1991/0806 | ||
| 1991/0807 | /* | |
| 1991/0807/sys/src/9/pc/devuart.c:316,325 – 1991/0808/sys/src/9/pc/devuart.c:324,338 | ||
| 1991/0807 | /* * turn off power */ | |
| 1991/0808 | if(up == &uart[Serial]){ | |
| 1991/0807 | if(serial(1) < 0) print("can't turn off serial power\n"); | |
| 1991/0806 | } | |
| 1991/0808 | /* * slow the clock down again */ clockinit(); | |
| 1991/0801 | } /* | |
| 1991/0807/sys/src/9/pc/devuart.c:374,398 – 1991/0808/sys/src/9/pc/devuart.c:387,392 | ||
| 1991/0801 | wakeup(&up->iq->r); } | |
| 1991/0807/sys/src/9/pc/devuart.c:403,408 – 1991/0808/sys/src/9/pc/devuart.c:397,403 | ||
| 1991/0801 | q, s->inuse, s->type, s->dev, s->id); | |
| 1991/0806 | ||
| 1991/0801 | up = &uart[s->id]; | |
| 1991/0808 | up->iq->putc = 0; | |
| 1991/0806 | uartenable(up); | |
| 1991/0801 | qlock(up); | |
| 1991/0807/sys/src/9/pc/devuart.c:409,420 – 1991/0808/sys/src/9/pc/devuart.c:404,413 | ||
| 1991/0801 | up->wq = WR(q); WR(q)->ptr = up; RD(q)->ptr = up; | |
| 1991/0808 | memset(up->delim, 0xff, sizeof(up->delim)); | |
| 1991/0801 | if(up->kstarted == 0){ up->kstarted = 1; | |
| 1991/0807/sys/src/9/pc/devuart.c:468,473 – 1991/0808/sys/src/9/pc/devuart.c:461,478 | ||
| 1991/0801 | case 'd': uartdtr(up, n); break; | |
| 1991/0808 | case 'e': case 'E': /* * the characters in the block are the message * delimiters to use upstream */ memset(up->delim, 0, sizeof(up->delim)); while(++(bp->rptr) < bp->wptr){ m = *bp->rptr; up->delim[m/8] |= 1<<(m&7); } break; | |
| 1991/0801 | case 'K': case 'k': uartbreak(up, n); | |
| 1991/0807/sys/src/9/pc/devuart.c:476,490 – 1991/0808/sys/src/9/pc/devuart.c:481,489 | ||
| 1991/0801 | case 'r': uartrts(up, n); break; | |
| 1991/0807/sys/src/9/pc/devuart.c:507,527 – 1991/0808/sys/src/9/pc/devuart.c:506,528 | ||
| 1991/0801 | Block *bp; int n; | |
| 1991/0808 | if(waserror()) print("uartkproc got an error\n"); for(;;){ | |
| 1991/0801 | sleep(&cq->r, cangetc, cq); | |
| 1991/0808 | qlock(up); if(up->wq == 0){ cq->out = cq->in; }else{ n = cangetc(cq); bp = allocb(n); bp->flags |= S_DELIM; bp->wptr += gets(cq, bp->wptr, n); PUTNEXT(RD(up->wq), bp); } qunlock(up); | |
| 1991/0801 | } | |
| 1991/0808/sys/src/9/pc/devuart.c:32,38 – 1991/0810/sys/src/9/pc/devuart.c:32,38 (short | long) | ||
| 1991/0801 | Dtr= (1<<0), /* data terminal ready */ Rts= (1<<1), /* request to send */ Ri= (1<<2), /* ring */ | |
| 1991/0810 | Inton= (1<<3), /* turn on interrupts */ | |
| 1991/0801 | Loop= (1<<4), /* loop bask */ Lstat= 5, /* line status */ Inready=(1<<0), /* receive buffer full */ | |
| 1991/0808/sys/src/9/pc/devuart.c:164,173 – 1991/0810/sys/src/9/pc/devuart.c:164,176 | ||
| 1991/0801 | * set rate to 9600 baud. * 8 bits/character. * 1 stop bit. | |
| 1991/0810 | * interrupts enabled. | |
| 1991/0801 | */ uartsetbaud(up, 9600); up->sticky[Format] = Bits8; uartwrreg(up, Format, 0); | |
| 1991/0810 | up->sticky[Mctl] |= Inton; uartwrreg(up, Mctl, 0x0); | |
| 1991/0801 | } } | |
| 1991/0808/sys/src/9/pc/devuart.c:209,256 – 1991/0810/sys/src/9/pc/devuart.c:212,269 | ||
| 1991/0801 | IOQ *cq; | |
| 1991/0806 | int s, l; | |
| 1991/0801 | ||
| 1991/0806 |
| |
| 1991/0803 |
| |
| 1991/0806 |
| |
| 1991/0810 | for(;;){ s = uartrdreg(up, Istat); switch(s){ case 6: /* receiver line status */ l = uartrdreg(up, Lstat); break; case 4: /* received data available */ cq = up->iq; ch = uartrdreg(up, Data) & 0xff; if(cq->putc) (*cq->putc)(cq, ch); else { putc(cq, ch); if(up->delim[ch/8] & (1<<(ch&7)) ) wakeup(&cq->r); } break; case 2: /* transmitter empty */ cq = up->oq; lock(cq); ch = getc(cq); if(ch < 0){ up->printing = 0; | |
| 1991/0801 | wakeup(&cq->r); | |
| 1991/0810 | }else outb(up->port + Data, ch); unlock(cq); break; case 0: /* modem status */ l = uartrdreg(up, Mstat); break; default: if(s&1) return; print("weird modem interrupt\n"); break; | |
| 1991/0801 | } | |
| 1991/0806 |
| |
| 1991/0801 | } | |
| 1991/0806 |
| |
| 1991/0801 | } void uartintr0(Ureg *ur) { | |
| 1991/0807 |
| |
| 1991/0810 | uartintr(&uart[0]); | |
| 1991/0801 | } void uartintr1(Ureg *ur) { | |
| 1991/0808 |
| |
| 1991/0810 | uartintr(&uart[1]); | |
| 1991/0801 | } /* | |
| 1991/0808/sys/src/9/pc/devuart.c:271,278 – 1991/0810/sys/src/9/pc/devuart.c:284,291 | ||
| 1991/0807 | /* | |
| 1991/0808 | * speed up the clock to poll the uart | |
| 1991/0810 | */ | |
| 1991/0808 | /* | |
| 1991/0801 | * set up i/o routines | |
| 1991/0808/sys/src/9/pc/devuart.c:285,297 – 1991/0810/sys/src/9/pc/devuart.c:298,309 | ||
| 1991/0801 | up->iq->ptr = up; } | |
| 1991/0807 | up->enabled = 1; | |
| 1991/0808 |
| |
| 1991/0801 | /* * turn on interrupts */ | |
| 1991/0810 | up->sticky[Iena] = 0x7; | |
| 1991/0801 | uartwrreg(up, Iena, 0); | |
| 1991/0808 |
| |
| 1991/0801 | /* * turn on DTR and RTS | |
| 1991/0808/sys/src/9/pc/devuart.c:298,305 – 1991/0810/sys/src/9/pc/devuart.c:310,315 | ||
| 1991/0801 | */ uartdtr(up, 1); uartrts(up, 1); | |
| 1991/0808 |
| |
| 1991/0807 | } | |
| 1991/0806 | ||
| 1991/0807 | /* | |
| 1991/0808/sys/src/9/pc/devuart.c:392,400 – 1991/0810/sys/src/9/pc/devuart.c:402,407 | ||
| 1991/0801 | { Uart *up; char name[NAMELEN]; | |
| 1991/0806 |
| |
| 1991/0801 |
| |
| 1991/0806 | ||
| 1991/0801 | up = &uart[s->id]; | |
| 1991/0808 | up->iq->putc = 0; | |
| 1991/0810/sys/src/9/pc/devuart.c:36,41 – 1991/0822/sys/src/9/pc/devuart.c:36,42 (short | long) | ||
| 1991/0801 | Loop= (1<<4), /* loop bask */ Lstat= 5, /* line status */ Inready=(1<<0), /* receive buffer full */ | |
| 1991/0822 | Overrun=(1<<1), /* we lost an input char */ | |
| 1991/0803 | Outready=(1<<5), /* output buffer full */ | |
| 1991/0801 | Mstat= 6, /* modem status */ Scratch=7, /* scratchpad */ | |
| 1991/0810/sys/src/9/pc/devuart.c:212,217 – 1991/0822/sys/src/9/pc/devuart.c:213,221 | ||
| 1991/0801 | IOQ *cq; | |
| 1991/0806 | int s, l; | |
| 1991/0801 | ||
| 1991/0822 | /* * the for loop takes care of multiple events per interrupt */ | |
| 1991/0810 | for(;;){ s = uartrdreg(up, Istat); switch(s){ | |
| 1991/0810/sys/src/9/pc/devuart.c:229,234 – 1991/0822/sys/src/9/pc/devuart.c:233,241 | ||
| 1991/0810 | if(up->delim[ch/8] & (1<<(ch&7)) ) wakeup(&cq->r); } | |
| 1991/0822 | l = uartrdreg(up, Lstat); if(l & Overrun) screenputc('!'); | |
| 1991/0810 | break; case 2: /* transmitter empty */ | |
| 1991/0810/sys/src/9/pc/devuart.c:281,291 – 1991/0822/sys/src/9/pc/devuart.c:288,293 | ||
| 1991/0807 | if(serial(0) < 0) print("can't turn on serial port power\n"); } | |
| 1991/0808 |
| |
| 1991/0810 |
| |
| 1991/0808 | /* | |
| 1991/0801 | * set up i/o routines | |
| 1991/0822/sys/src/9/pc/devuart.c:1,4 – 1991/0823/sys/src/9/pc/devuart.c:1,4 (short | long) | ||
| 1991/0808 |
| |
| 1991/0823 | #include "u.h" | |
| 1991/0801 | #include "lib.h" #include "mem.h" #include "dat.h" | |
| 1991/0822/sys/src/9/pc/devuart.c:18,23 – 1991/0823/sys/src/9/pc/devuart.c:18,27 | ||
| 1991/0801 | */ Data= 0, /* xmit/rcv buffer */ Iena= 1, /* interrupt enable */ | |
| 1991/0823 | Ircv= (1<<0), /* for char rcv'd */ Ixmt= (1<<1), /* for xmit buffer empty */ Irstat=(1<<2), /* for change in rcv'er status */ Imstat=(1<<3), /* for change in modem status */ | |
| 1991/0808 | Istat= 2, /* interrupt flag (read) */ Tctl= 2, /* test control (write) */ | |
| 1991/0801 | Format= 3, /* byte format */ | |
| 1991/0822/sys/src/9/pc/devuart.c:36,42 – 1991/0823/sys/src/9/pc/devuart.c:40,48 | ||
| 1991/0801 | Loop= (1<<4), /* loop bask */ Lstat= 5, /* line status */ Inready=(1<<0), /* receive buffer full */ | |
| 1991/0822 |
| |
| 1991/0823 | Oerror=(1<<1), /* receiver overrun */ Perror=(1<<2), /* receiver parity error */ Ferror=(1<<3), /* rcv framing error */ | |
| 1991/0803 | Outready=(1<<5), /* output buffer full */ | |
| 1991/0801 | Mstat= 6, /* modem status */ Scratch=7, /* scratchpad */ | |
| 1991/0822/sys/src/9/pc/devuart.c:67,72 – 1991/0823/sys/src/9/pc/devuart.c:73,82 | ||
| 1991/0801 | Alarm *a; /* alarm for waking the kernel process */ int kstarted; /* kproc started */ uchar delim[256/8]; /* characters that act as delimiters */ | |
| 1991/0823 | /* error statistics */ ulong frame; ulong overrun; | |
| 1991/0801 | }; Uart uart[2]; | |
| 1991/0822/sys/src/9/pc/devuart.c:213,226 – 1991/0823/sys/src/9/pc/devuart.c:223,237 | ||
| 1991/0801 | IOQ *cq; | |
| 1991/0806 | int s, l; | |
| 1991/0801 | ||
| 1991/0822 |
| |
| 1991/0810 | for(;;){ s = uartrdreg(up, Istat); switch(s){ case 6: /* receiver line status */ l = uartrdreg(up, Lstat); | |
| 1991/0823 | if(l & Ferror) up->frame++; if(l & Oerror) up->overrun++; | |
| 1991/0810 | break; case 4: /* received data available */ | |
| 1991/0822/sys/src/9/pc/devuart.c:233,241 – 1991/0823/sys/src/9/pc/devuart.c:244,249 | ||
| 1991/0810 | if(up->delim[ch/8] & (1<<(ch&7)) ) wakeup(&cq->r); } | |
| 1991/0822 |
| |
| 1991/0810 | break; case 2: /* transmitter empty */ | |
| 1991/0822/sys/src/9/pc/devuart.c:257,263 – 1991/0823/sys/src/9/pc/devuart.c:265,271 | ||
| 1991/0810 | default: if(s&1) return; | |
| 1991/0823 | /* print("weird modem interrupt\n");/**/ | |
| 1991/0810 | break; | |
| 1991/0801 | } } | |
| 1991/0822/sys/src/9/pc/devuart.c:290,295 – 1991/0823/sys/src/9/pc/devuart.c:298,308 | ||
| 1991/0807 | } | |
| 1991/0808 | /* | |
| 1991/0823 | * speed up the clock to poll the uart fclockinit(); */ /* | |
| 1991/0801 | * set up i/o routines */ if(up->oq){ | |
| 1991/0822/sys/src/9/pc/devuart.c:304,310 – 1991/0823/sys/src/9/pc/devuart.c:317,323 | ||
| 1991/0801 | /* * turn on interrupts */ | |
| 1991/0810 |
| |
| 1991/0823 | up->sticky[Iena] = Ircv | Ixmt | Irstat; | |
| 1991/0801 | uartwrreg(up, Iena, 0); /* | |
| 1991/0822/sys/src/9/pc/devuart.c:514,519 – 1991/0823/sys/src/9/pc/devuart.c:527,533 | ||
| 1991/0801 | IOQ *cq = up->iq; Block *bp; int n; | |
| 1991/0823 | ulong frame, overrun; | |
| 1991/0801 | ||
| 1991/0808 | if(waserror()) print("uartkproc got an error\n"); | |
| 1991/0822/sys/src/9/pc/devuart.c:531,536 – 1991/0823/sys/src/9/pc/devuart.c:545,558 | ||
| 1991/0808 | PUTNEXT(RD(up->wq), bp); } qunlock(up); | |
| 1991/0823 | if(up->frame != frame){ kprint("uart%d: %d framing\n", up-uart, up->frame); frame = up->frame; } if(up->overrun != overrun){ kprint("uart%d: %d overruns\n", up-uart, up->overrun); overrun = up->overrun; } | |
| 1991/0801 | } } | |
| 1991/0823/sys/src/9/pc/devuart.c:259,265 – 1991/0904/sys/src/9/pc/devuart.c:259,265 (short | long) | ||
| 1991/0810 | break; case 0: /* modem status */ | |
| 1991/0904 | uartrdreg(up, Mstat); | |
| 1991/0810 | break; default: | |
| 1991/0823/sys/src/9/pc/devuart.c:528,533 – 1991/0904/sys/src/9/pc/devuart.c:528,536 | ||
| 1991/0801 | Block *bp; int n; | |
| 1991/0823 | ulong frame, overrun; | |
| 1991/0904 | frame = 0; overrun = 0; | |
| 1991/0801 | ||
| 1991/0808 | if(waserror()) print("uartkproc got an error\n"); | |
| 1991/0904/sys/src/9/pc/devuart.c:295,300 – 1991/1001/sys/src/9/pc/devuart.c:295,303 (short | long) | ||
| 1991/0808 | if(up == &uart[Serial]){ | |
| 1991/0807 | if(serial(0) < 0) print("can't turn on serial port power\n"); | |
| 1991/1001 | } else { if(modem(0) < 0) print("can't turn on modem speaker\n"); | |
| 1991/0807 | } | |
| 1991/0808 | /* | |
| 1991/1001/sys/src/9/pc/devuart.c:72,78 – 1991/1113/sys/src/9/pc/devuart.c:72,77 (short | long) | ||
| 1991/0801 | Rendez r; /* kproc waiting for input */ Alarm *a; /* alarm for waking the kernel process */ int kstarted; /* kproc started */ | |
| 1991/0823 | /* error statistics */ ulong frame; | |
| 1991/1001/sys/src/9/pc/devuart.c:239,249 – 1991/1113/sys/src/9/pc/devuart.c:238,245 | ||
| 1991/0810 | ch = uartrdreg(up, Data) & 0xff; if(cq->putc) (*cq->putc)(cq, ch); | |
| 1991/1113 | else | |
| 1991/0810 | putc(cq, ch); | |
| 1991/1001/sys/src/9/pc/devuart.c:281,286 – 1991/1113/sys/src/9/pc/devuart.c:277,296 | ||
| 1991/0810 | uartintr(&uart[1]); | |
| 1991/0801 | } | |
| 1991/1113 | void uartclock(void) { Uart *up; IOQ *cq; for(up = uart; up < &uart[2]; up++){ cq = up->iq; if(up->wq && cangetc(cq)) wakeup(&cq->r); } } | |
| 1991/0801 | /* * turn on a port's interrupts. set DTR and RTS */ | |
| 1991/1001/sys/src/9/pc/devuart.c:301,311 – 1991/1113/sys/src/9/pc/devuart.c:311,316 | ||
| 1991/0807 | } | |
| 1991/0808 | /* | |
| 1991/0823 |
| |
| 1991/0801 | * set up i/o routines */ if(up->oq){ | |
| 1991/1001/sys/src/9/pc/devuart.c:431,439 – 1991/1113/sys/src/9/pc/devuart.c:436,441 | ||
| 1991/0801 | RD(q)->ptr = up; qunlock(up); | |
| 1991/0808 |
| |
| 1991/0801 |
| |
| 1991/1001/sys/src/9/pc/devuart.c:486,503 – 1991/1113/sys/src/9/pc/devuart.c:488,493 | ||
| 1991/0801 | case 'd': uartdtr(up, n); break; | |
| 1991/0808 |
| |
| 1991/0801 | case 'K': case 'k': uartbreak(up, n); | |
| 1991/1001/sys/src/9/pc/devuart.c:531,536 – 1991/1113/sys/src/9/pc/devuart.c:521,527 | ||
| 1991/0801 | Block *bp; int n; | |
| 1991/0823 | ulong frame, overrun; | |
| 1991/1113 | static ulong ints; | |
| 1991/0904 | frame = 0; overrun = 0; | |
| 1991/1001/sys/src/9/pc/devuart.c:540,545 – 1991/1113/sys/src/9/pc/devuart.c:531,538 | ||
| 1991/0808 | for(;;){ | |
| 1991/0801 | sleep(&cq->r, cangetc, cq); | |
| 1991/1113 | if((ints++ & 0x1f) == 0) owl(ints>>5); | |
| 1991/0808 | qlock(up); if(up->wq == 0){ cq->out = cq->in; | |
| 1991/1113/sys/src/9/pc/devuart.c:557,573 – 1991/1115/sys/src/9/pc/devuart.c:557,573 (short | long) | ||
| 1991/0801 | enum{ Qdir= 0, | |
| 1991/1115 | Qeia0= STREAMQID(0, Sdataqid), Qeia0ctl= STREAMQID(0, Sctlqid), Qeia1= STREAMQID(1, Sdataqid), Qeia1ctl= STREAMQID(1, Sctlqid), | |
| 1991/0801 | }; Dirtab uartdir[]={ | |
| 1991/1115 | "eia0", {Qeia0}, 0, 0666, "eia0ctl", {Qeia0ctl}, 0, 0666, "eia1", {Qeia1}, 0, 0666, "eia1ctl", {Qeia1ctl}, 0, 0666, | |
| 1991/0801 | }; #define NUart (sizeof uartdir/sizeof(Dirtab)) | |
| 1991/1113/sys/src/9/pc/devuart.c:618,628 – 1991/1115/sys/src/9/pc/devuart.c:618,628 | ||
| 1991/0801 | uartstat(Chan *c, char *dp) { switch(c->qid.path){ | |
| 1991/1115 | case Qeia0: streamstat(c, dp, "eia0"); | |
| 1991/0801 | break; | |
| 1991/1115 | case Qeia1: streamstat(c, dp, "eia1"); | |
| 1991/0801 | break; default: devstat(c, dp, uartdir, NUart, devgen); | |
| 1991/1113/sys/src/9/pc/devuart.c:636,647 – 1991/1115/sys/src/9/pc/devuart.c:636,647 | ||
| 1991/0801 | Uart *up; switch(c->qid.path){ | |
| 1991/1115 | case Qeia0: case Qeia0ctl: | |
| 1991/0801 | up = &uart[0]; break; | |
| 1991/1115 | case Qeia1: case Qeia1ctl: | |
| 1991/0801 | up = &uart[1]; break; default: | |
| 1991/1113/sys/src/9/pc/devuart.c:676,683 – 1991/1115/sys/src/9/pc/devuart.c:676,683 | ||
| 1991/0801 | switch(c->qid.path&~CHDIR){ case Qdir: return devdirread(c, buf, n, uartdir, NUart, devgen); | |
| 1991/1115 | case Qeia1ctl: case Qeia0ctl: | |
| 1991/0801 | return 0; } return streamread(c, buf, n); | |
| 1991/1115/sys/src/9/pc/devuart.c:303,312 – 1991/1210/sys/src/9/pc/devuart.c:303,312 (short | long) | ||
| 1991/0807 | * turn on power to the port */ | |
| 1991/0808 | if(up == &uart[Serial]){ | |
| 1991/0807 |
| |
| 1991/1210 | if(serial(1) < 0) | |
| 1991/0807 | print("can't turn on serial port power\n"); | |
| 1991/1001 | } else { | |
| 1991/1210 | if(modem(1) < 0) | |
| 1991/1001 | print("can't turn on modem speaker\n"); | |
| 1991/0807 | } | |
| 1991/0808 | ||
| 1991/1115/sys/src/9/pc/devuart.c:358,365 – 1991/1210/sys/src/9/pc/devuart.c:358,368 | ||
| 1991/0807 | * turn off power */ | |
| 1991/0808 | if(up == &uart[Serial]){ | |
| 1991/0807 |
| |
| 1991/1210 | if(serial(0) < 0) | |
| 1991/0807 | print("can't turn off serial power\n"); | |
| 1991/1210 | } else { if(modem(0) < 0) print("can't turn off modem speaker\n"); | |
| 1991/0806 | } | |
| 1991/0808 | /* | |
| 1991/1115/sys/src/9/pc/devuart.c:532,538 – 1991/1210/sys/src/9/pc/devuart.c:535,541 | ||
| 1991/0808 | for(;;){ | |
| 1991/0801 | sleep(&cq->r, cangetc, cq); | |
| 1991/1113 | if((ints++ & 0x1f) == 0) | |
| 1991/1210 | lights((ints>>5)&1); | |
| 1991/0808 | qlock(up); if(up->wq == 0){ cq->out = cq->in; | |
| 1991/1210/sys/src/9/pc/devuart.c:140,145 – 1992/0101/sys/src/9/pc/devuart.c:140,147 (short | long) | ||
| 1991/0801 | void uartbreak(Uart *up, int ms) { | |
| 1992/0101 | if(ms == 0) ms = 200; | |
| 1991/0801 | uartwrreg(up, Format, Break); tsleep(&u->p->sleep, return0, 0, ms); uartwrreg(up, Format, 0); | |
| 1992/0101/sys/src/9/pc/devuart.c:4,10 – 1992/0111/sys/src/9/pc/devuart.c:4,10 (short | long) | ||
| 1991/0801 | #include "dat.h" #include "fns.h" #include "io.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 1991/0801 | #include "devtab.h" | |
| 1992/0111/sys/src/9/pc/devuart.c:655,661 – 1992/0114/sys/src/9/pc/devuart.c:655,661 (short | long) | ||
| 1991/0801 | } if(up && up->nostream) | |
| 1992/0114 | error(Einuse); | |
| 1991/0801 | if((c->qid.path & CHDIR) == 0) streamopen(c, &uartinfo); | |
| 1992/0114/sys/src/9/pc/devuart.c:1,5 – 1992/0321/sys/src/9/pc/devuart.c:1,5 (short | long) | ||
| 1991/0823 | #include "u.h" | |
| 1991/0801 |
| |
| 1992/0321 | #include "../port/lib.h" | |
| 1991/0801 | #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1992/0321/sys/src/9/pc/devuart.c:236,243 – 1992/0409/sys/src/9/pc/devuart.c:236,245 (short | long) | ||
| 1991/0810 | break; case 4: /* received data available */ | |
| 1992/0409 | cq = up->iq; if(cq == 0) break; | |
| 1991/0810 | if(cq->putc) (*cq->putc)(cq, ch); | |
| 1991/1113 | else | |
| 1992/0321/sys/src/9/pc/devuart.c:246,251 – 1992/0409/sys/src/9/pc/devuart.c:248,255 | ||
| 1991/0810 | case 2: /* transmitter empty */ cq = up->oq; | |
| 1992/0409 | if(cq == 0) break; | |
| 1991/0810 | lock(cq); ch = getc(cq); if(ch < 0){ | |
| 1992/0321/sys/src/9/pc/devuart.c:263,269 – 1992/0409/sys/src/9/pc/devuart.c:267,273 | ||
| 1991/0810 | default: if(s&1) return; | |
| 1991/0823 |
| |
| 1992/0409 | print("weird modem interrupt\n"); | |
| 1991/0810 | break; | |
| 1991/0801 | } } | |
| 1992/0409/sys/src/9/pc/devuart.c:70,76 – 1992/0602/sys/src/9/pc/devuart.c:70,75 (short | long) | ||
| 1991/0801 | /* stream interface */ Queue *wq; /* write queue */ Rendez r; /* kproc waiting for input */ | |
| 1991/0823 | /* error statistics */ | |
| 1992/0409/sys/src/9/pc/devuart.c:401,407 – 1992/0602/sys/src/9/pc/devuart.c:400,405 | ||
| 1991/0801 | } } | |
| 1992/0409/sys/src/9/pc/devuart.c:415,433 – 1992/0602/sys/src/9/pc/devuart.c:413,418 | ||
| 1991/0801 | uartstclose, "uart" }; | |
| 1992/0602/sys/src/9/pc/devuart.c:578,586 – 1992/0625/sys/src/9/pc/devuart.c:578,586 (short | long) | ||
| 1991/0801 | for(up = uart; up < &uart[2]; up++){ if(up->nostream) continue; | |
| 1992/0625 | up->iq = xalloc(sizeof(IOQ)); | |
| 1991/0801 | initq(up->iq); | |
| 1992/0625 | up->oq = xalloc(sizeof(IOQ)); | |
| 1991/0801 | initq(up->oq); } } | |
| 1992/0625/sys/src/9/pc/devuart.c:193,199 – 1992/0711/sys/src/9/pc/devuart.c:193,199 (short | long) | ||
| 1991/0801 | uartputs(IOQ *cq, char *s, int n) { Uart *up = cq->ptr; | |
| 1992/0711 | int ch, x; | |
| 1991/0803 | int tries; | |
| 1991/0801 | x = splhi(); | |
| 1992/0625/sys/src/9/pc/devuart.c:274,284 – 1992/0711/sys/src/9/pc/devuart.c:274,286 | ||
| 1991/0801 | void uartintr0(Ureg *ur) { | |
| 1992/0711 | USED(ur); | |
| 1991/0810 | uartintr(&uart[0]); | |
| 1991/0801 | } void uartintr1(Ureg *ur) { | |
| 1992/0711 | USED(ur); | |
| 1991/0810 | uartintr(&uart[1]); | |
| 1991/0801 | } | |
| 1992/0625/sys/src/9/pc/devuart.c:302,309 – 1992/0711/sys/src/9/pc/devuart.c:304,309 | ||
| 1991/0801 | void uartenable(Uart *up) { | |
| 1991/0806 |
| |
| 1991/0801 | /* | |
| 1991/0807 | * turn on power to the port */ | |
| 1992/0625/sys/src/9/pc/devuart.c:343,348 – 1992/0711/sys/src/9/pc/devuart.c:343,349 | ||
| 1991/0807 | /* * turn off the uart */ | |
| 1992/0711 | void | |
| 1991/0807 | uartdisable(Uart *up) { | |
| 1992/0625/sys/src/9/pc/devuart.c:654,659 – 1992/0711/sys/src/9/pc/devuart.c:655,661 | ||
| 1991/0801 | void uartcreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1992/0711 | USED(c, name, omode, perm); | |
| 1991/0801 | error(Eperm); } | |
| 1992/0625/sys/src/9/pc/devuart.c:667,672 – 1992/0711/sys/src/9/pc/devuart.c:669,675 | ||
| 1991/0801 | long uartread(Chan *c, void *buf, long n, ulong offset) { | |
| 1992/0711 | USED(offset); | |
| 1991/0801 | switch(c->qid.path&~CHDIR){ case Qdir: return devdirread(c, buf, n, uartdir, NUart, devgen); | |
| 1992/0625/sys/src/9/pc/devuart.c:680,685 – 1992/0711/sys/src/9/pc/devuart.c:683,689 | ||
| 1991/0801 | long uartwrite(Chan *c, void *va, long n, ulong offset) { | |
| 1992/0711 | USED(offset); | |
| 1991/0801 | return streamwrite(c, va, n, 0); } | |
| 1992/0625/sys/src/9/pc/devuart.c:686,691 – 1992/0711/sys/src/9/pc/devuart.c:690,696 | ||
| 1991/0801 | void uartremove(Chan *c) { | |
| 1992/0711 | USED(c); | |
| 1991/0801 | error(Eperm); } | |
| 1992/0625/sys/src/9/pc/devuart.c:692,696 – 1992/0711/sys/src/9/pc/devuart.c:697,702 | ||
| 1991/0801 | void uartwstat(Chan *c, char *dp) { | |
| 1992/0711 | USED(c, dp); | |
| 1991/0801 | error(Eperm); } | |
| 1992/0711/sys/src/9/pc/devuart.c:614,623 – 1992/0826/sys/src/9/pc/devuart.c:614,623 (short | long) | ||
| 1991/0801 | { switch(c->qid.path){ | |
| 1991/1115 | case Qeia0: | |
| 1992/0826 | streamstat(c, dp, uartdir[0].name, uartdir[0].perm); | |
| 1991/0801 | break; | |
| 1991/1115 | case Qeia1: | |
| 1992/0826 | streamstat(c, dp, uartdir[2].name, uartdir[2].perm); | |
| 1991/0801 | break; default: devstat(c, dp, uartdir, NUart, devgen); | |
| 1992/0826/sys/src/9/pc/devuart.c:37,43 – 1992/1016/sys/src/9/pc/devuart.c:37,43 (short | long) | ||
| 1991/0801 | Rts= (1<<1), /* request to send */ Ri= (1<<2), /* ring */ | |
| 1991/0810 | Inton= (1<<3), /* turn on interrupts */ | |
| 1991/0801 |
| |
| 1992/1016 | Loop= (1<<4), /* loop back */ | |
| 1991/0801 | Lstat= 5, /* line status */ Inready=(1<<0), /* receive buffer full */ | |
| 1991/0823 | Oerror=(1<<1), /* receiver overrun */ | |
| 1992/0826/sys/src/9/pc/devuart.c:147,152 – 1992/1016/sys/src/9/pc/devuart.c:147,204 | ||
| 1991/0801 | } /* | |
| 1992/1016 | * set bits/char */ void uartbits(Uart *up, int bits) { if(bits < 5 || bits > 8) error(Ebadarg); up->sticky[Format] &= ~3; up->sticky[Format] |= bits-5; uartwrreg(up, Format, 0); } /* * set parity */ void uartparity(Uart *up, int c) { switch(c&0xff){ case 'e': up->sticky[Format] |= Pena|Peven; break; case 'o': up->sticky[Format] &= ~Peven; up->sticky[Format] |= Pena; break; default: up->sticky[Format] &= ~(Pena|Peven); break; } uartwrreg(up, Format, 0); } /* * set stop bits */ void uartstop(Uart *up, int n) { switch(n){ case 1: up->sticky[Format] &= ~Stop2; break; case 2: default: up->sticky[Format] |= Stop2; break; } uartwrreg(up, Format, 0); } /* | |
| 1991/0801 | * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, * transmit and receive enabled, interrupts disabled. */ | |
| 1992/0826/sys/src/9/pc/devuart.c:182,187 – 1992/1016/sys/src/9/pc/devuart.c:234,242 | ||
| 1991/0801 | uartwrreg(up, Format, 0); | |
| 1991/0810 | up->sticky[Mctl] |= Inton; uartwrreg(up, Mctl, 0x0); | |
| 1992/1016 | uartdtr(up, 1); uartrts(up, 1); | |
| 1991/0801 | } } | |
| 1992/0826/sys/src/9/pc/devuart.c:355,363 – 1992/1016/sys/src/9/pc/devuart.c:410,418 | ||
| 1991/0807 | /* * turn off DTR and RTS | |
| 1992/1016 | */ | |
| 1991/0807 | up->enabled = 0; /* | |
| 1992/0826/sys/src/9/pc/devuart.c:487,495 – 1992/1016/sys/src/9/pc/devuart.c:542,562 | ||
| 1991/0801 | case 'k': uartbreak(up, n); break; | |
| 1992/1016 | case 'L': case 'l': uartbits(up, n); break; case 'P': case 'p': uartparity(up, *(bp->rptr+1)); break; | |
| 1991/0801 | case 'R': case 'r': uartrts(up, n); | |
| 1992/1016 | break; case 'S': case 's': uartstop(up, n); | |
| 1991/0801 | break; } }else while((m = BLEN(bp)) > 0){ | |
| 1992/1016/sys/src/9/pc/devuart.c:63,69 – 1992/1017/sys/src/9/pc/devuart.c:63,69 (short | long) | ||
| 1991/0807 | int enabled; | |
| 1991/0801 | /* console interface */ | |
| 1992/1017 | int special; /* can't use the stream interface */ | |
| 1991/0801 | IOQ *iq; /* input character queue */ IOQ *oq; /* output character queue */ | |
| 1992/1016/sys/src/9/pc/devuart.c:234,242 – 1992/1017/sys/src/9/pc/devuart.c:234,239 | ||
| 1991/0801 | uartwrreg(up, Format, 0); | |
| 1991/0810 | up->sticky[Mctl] |= Inton; uartwrreg(up, Mctl, 0x0); | |
| 1992/1016 |
| |
| 1991/0801 | } } | |
| 1992/1016/sys/src/9/pc/devuart.c:409,418 – 1992/1017/sys/src/9/pc/devuart.c:406,421 | ||
| 1991/0807 | uartwrreg(up, Iena, 0); /* | |
| 1992/1017 | * revert to default settings */ up->sticky[Format] = Bits8; uartwrreg(up, Format, 0); /* | |
| 1991/0807 | * turn off DTR and RTS | |
| 1992/1017 | */ | |
| 1991/0807 | uartdtr(up, 0); uartrts(up, 0); | |
| 1992/1016 |
| |
| 1991/0807 | up->enabled = 0; /* | |
| 1992/1016/sys/src/9/pc/devuart.c:425,435 – 1992/1017/sys/src/9/pc/devuart.c:428,433 | ||
| 1991/1210 | if(modem(0) < 0) print("can't turn off modem speaker\n"); | |
| 1991/0806 | } | |
| 1991/0808 |
| |
| 1991/0801 | } /* | |
| 1992/1016/sys/src/9/pc/devuart.c:441,451 – 1992/1017/sys/src/9/pc/devuart.c:439,450 | ||
| 1991/0801 | Uart *up = &uart[port]; uartsetup(); | |
| 1992/1017 | up->special = 1; | |
| 1991/0801 | up->oq = oq; up->iq = iq; uartenable(up); | |
| 1992/1017 | if(baud) uartsetbaud(up, baud); | |
| 1991/0801 | if(iq){ /* | |
| 1992/1016/sys/src/9/pc/devuart.c:498,503 – 1992/1017/sys/src/9/pc/devuart.c:497,505 | ||
| 1991/0801 | { Uart *up = q->ptr; | |
| 1992/1017 | if(up->special) return; | |
| 1991/0807 | uartdisable(up); | |
| 1991/0801 | qlock(up); | |
| 1992/1016/sys/src/9/pc/devuart.c:644,650 – 1992/1017/sys/src/9/pc/devuart.c:646,652 | ||
| 1991/0803 | ||
| 1991/0801 | uartsetup(); for(up = uart; up < &uart[2]; up++){ | |
| 1992/1017 | if(up->special) | |
| 1991/0801 | continue; | |
| 1992/0625 | up->iq = xalloc(sizeof(IOQ)); | |
| 1991/0801 | initq(up->iq); | |
| 1992/1016/sys/src/9/pc/devuart.c:711,717 – 1992/1017/sys/src/9/pc/devuart.c:713,719 | ||
| 1991/0801 | break; } | |
| 1992/1017 | if(up && up->special) | |
| 1992/0114 | error(Einuse); | |
| 1991/0801 | if((c->qid.path & CHDIR) == 0) | |
| 1992/1017/sys/src/9/pc/devuart.c:45,50 – 1992/1210/sys/src/9/pc/devuart.c:45,58 (short | long) | ||
| 1991/0823 | Ferror=(1<<3), /* rcv framing error */ | |
| 1991/0803 | Outready=(1<<5), /* output buffer full */ | |
| 1991/0801 | Mstat= 6, /* modem status */ | |
| 1992/1210 | 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 */ | |
| 1991/0801 | Scratch=7, /* scratchpad */ Dlsb= 0, /* divisor lsb */ Dmsb= 1, /* divisor msb */ | |
| 1992/1017/sys/src/9/pc/devuart.c:61,66 – 1992/1210/sys/src/9/pc/devuart.c:69,75 | ||
| 1991/0804 | uchar sticky[8]; /* sticky write register values */ | |
| 1991/0801 | int printing; /* true if printing */ | |
| 1991/0807 | int enabled; | |
| 1992/1210 | int cts; | |
| 1991/0801 | /* console interface */ | |
| 1992/1017 | int special; /* can't use the stream interface */ | |
| 1992/1017/sys/src/9/pc/devuart.c:199,204 – 1992/1210/sys/src/9/pc/devuart.c:208,231 | ||
| 1992/1016 | } /* | |
| 1992/1210 | * 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; } } /* | |
| 1991/0801 | * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, * transmit and receive enabled, interrupts disabled. */ | |
| 1992/1017/sys/src/9/pc/devuart.c:245,255 – 1992/1210/sys/src/9/pc/devuart.c:272,284 | ||
| 1991/0801 | uartputs(IOQ *cq, char *s, int n) { Uart *up = cq->ptr; | |
| 1992/0711 |
| |
| 1992/1210 | int ch, x, multiprocessor; | |
| 1991/0803 | int tries; | |
| 1991/0801 | ||
| 1992/1210 | multiprocessor = active.machs > 1; | |
| 1991/0801 | x = splhi(); | |
| 1992/1210 | if(multiprocessor) lock(cq); | |
| 1991/0801 | puts(cq, s, n); if(up->printing == 0){ ch = getc(cq); | |
| 1992/1017/sys/src/9/pc/devuart.c:261,267 – 1992/1210/sys/src/9/pc/devuart.c:290,297 | ||
| 1991/0801 | outb(up->port + Data, ch); } } | |
| 1992/1210 | if(multiprocessor) unlock(cq); | |
| 1991/0801 | splx(x); } | |
| 1992/1017/sys/src/9/pc/devuart.c:273,280 – 1992/1210/sys/src/9/pc/devuart.c:303,311 | ||
| 1991/0801 | { int ch; IOQ *cq; | |
| 1991/0806 |
| |
| 1992/1210 | int s, l, multiprocessor; | |
| 1991/0801 | ||
| 1992/1210 | multiprocessor = active.machs > 1; | |
| 1991/0810 | for(;;){ s = uartrdreg(up, Istat); switch(s){ | |
| 1992/1017/sys/src/9/pc/devuart.c:301,318 – 1992/1210/sys/src/9/pc/devuart.c:332,373 | ||
| 1991/0810 | cq = up->oq; | |
| 1992/0409 | if(cq == 0) break; | |
| 1991/0810 |
| |
| 1992/1210 | if(multiprocessor) lock(cq); if(up->cts == 0) | |
| 1991/0810 | up->printing = 0; | |
| 1991/0801 |
| |
| 1991/0810 |
| |
| 1992/1210 | else { ch = getc(cq); if(ch < 0){ up->printing = 0; wakeup(&cq->r); }else outb(up->port + Data, ch); } if(multiprocessor) unlock(cq); | |
| 1991/0810 | break; case 0: /* modem status */ | |
| 1991/0904 |
| |
| 1992/1210 | 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); } | |
| 1991/0810 | break; default: | |
| 1992/1017/sys/src/9/pc/devuart.c:390,395 – 1992/1210/sys/src/9/pc/devuart.c:445,455 | ||
| 1991/0801 | */ uartdtr(up, 1); uartrts(up, 1); | |
| 1992/1210 | /* * assume we can send */ up->cts = 1; | |
| 1991/0807 | } | |
| 1991/0806 | ||
| 1991/0807 | /* | |
| 1992/1017/sys/src/9/pc/devuart.c:547,552 – 1992/1210/sys/src/9/pc/devuart.c:607,616 | ||
| 1992/1016 | case 'L': case 'l': uartbits(up, n); | |
| 1992/1210 | break; case 'm': case 'M': uartmflow(up, n); | |
| 1992/1016 | break; case 'P': case 'p': | |
| Too many diffs (26 > 25). Stopping. | ||