## diffname gnot/devincon.c 1990/0312
## diff -e /dev/null /n/bootesdump/1990/0312/sys/src/9/68020/devincon.c
0a
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "errno.h"
#include "devtab.h"
#include "io.h"
typedef struct Incon Incon;
typedef struct Device Device;
#define NOW (MACHP(0)->ticks*MS2HZ)
#define DPRINT if(0)
enum {
Minstation= 2, /* lowest station # to poll */
Maxstation= 15, /* highest station # to poll */
Nincon= 1, /* number of incons */
Nraw= 1024, /* size of raw input buffer */
};
/*
* incon datakit board
*/
struct Device {
uchar cdata;
#define cpolln cdata
uchar u0;
uchar cstatus;
uchar u1;
uchar creset;
uchar u2;
uchar csend;
uchar u3;
ushort data_cntl; /* data is high byte, cntl is low byte */
uchar status;
#define cmd status
uchar u5;
uchar reset;
uchar u6;
uchar send;
uchar u7;
};
#define INCON ((Device *)0x40700000)
struct Incon {
QLock;
QLock xmit; /* transmit lock */
QLock reslock; /* reset lock */
Device *dev;
int station; /* station number */
int state; /* chip state */
Rendez r; /* output process */
Rendez kr; /* input kernel process */
ushort chan; /* current input channel */
Queue *rq; /* read queue */
uchar buf[1024]; /* bytes being collected */
uchar *wptr; /* pointer into buf */
int kstarted; /* true if kernel process started */
ushort raw[Nraw];
ushort *rp;
ushort *wp;
/* statistics */
ulong overflow; /* overflow errors */
ulong pack0; /* channel 0 */
ulong crc; /* crc errors */
ulong in; /* bytes in */
ulong out; /* bytes out */
};
Incon incon[Nincon];
/*
* chip state
*/
enum {
Selecting,
Selected,
Dead,
};
/*
* internal chip registers
*/
#define sel_polln 0
#define sel_station 1
#define sel_poll0 2
#define sel_rcv_cnt 3
#define sel_rcv_tim 4
#define sel_tx_cnt 5
/*
* CSR bits
*/
#define INCON_RUN 0x80
#define INCON_STOP 0x00
#define ENABLE_IRQ 0x40
#define ENABLE_TX_IRQ 0x20
#define INCON_ALIVE 0x80
#define TX_FULL 0x10
#define TX_EMPTY 0x08
#define RCV_EMPTY 0x04
#define OVERFLOW 0x02
#define CRC_ERROR 0x01
/*
* polling constants
*/
#define HT_GNOT 0x30
#define ST_UNIX 0x04
#define NCHAN 16
static void inconkproc(void*);
/*
* incon stream module definition
*/
static void inconoput(Queue*, Block*);
static void inconstopen(Queue*, Stream*);
static void inconstclose(Queue*);
Qinfo inconinfo = { nullput, inconoput, inconstopen, inconstclose, "incon" };
/*
* set the incon parameters
*/
void
inconset(Incon *ip, int cnt, int delay)
{
Device *dev;
if (cnt<1 || cnt>14 || delay<1 || delay>15)
error(0, Ebadarg);
dev = ip->dev;
dev->cmd = sel_rcv_cnt | INCON_RUN;
*(uchar *)&dev->data_cntl = cnt;
dev->cmd = sel_rcv_tim | INCON_RUN;
*(uchar *)&dev->data_cntl = delay;
dev->cmd = INCON_RUN | ENABLE_IRQ;
}
static void
nop(void)
{
}
/*
* poll for a station number
*/
void
inconpoll(Incon *ip, int station)
{
ulong timer;
Device *dev;
dev = ip->dev;
/*
* get us to a known state
*/
ip->state = Dead;
dev->cmd = INCON_STOP;
/*
* try a station number
*/
dev->cmd = sel_station;
*(uchar *)&dev->data_cntl = station;
dev->cmd = sel_poll0;
*(uchar *)&dev->data_cntl = HT_GNOT;
dev->cmd = sel_rcv_cnt;
*(uchar *)&dev->data_cntl = 3;
dev->cmd = sel_rcv_tim;
*(uchar *)&dev->data_cntl = 15;
dev->cmd = sel_tx_cnt;
*(uchar *)&dev->data_cntl = 1;
dev->cmd = sel_polln;
*(uchar *)&dev->data_cntl = 0x00;
*(uchar *)&dev->data_cntl = ST_UNIX;
*(uchar *)&dev->data_cntl = NCHAN;
*(uchar *)&dev->data_cntl = 'g';
*(uchar *)&dev->data_cntl = 'n';
*(uchar *)&dev->data_cntl = 'o';
*(uchar *)&dev->data_cntl = 't';
dev->cpolln = 0;
/*
* poll and wait for ready (or 1/4 second)
*/
ip->state = Selecting;
dev->cmd = INCON_RUN | ENABLE_IRQ;
timer = NOW + 250;
while (NOW < timer) {
nop();
if(dev->status & INCON_ALIVE){
ip->station = station;
ip->state = Selected;
break;
}
}
}
/*
* reset the chip and find a new staion number
*/
void
inconrestart(Incon *ip)
{
Device *dev;
int i;
if(!canqlock(&ip->reslock))
return;
/*
* poll for incon station numbers
*/
for(i = Minstation; i <= Maxstation; i++){
inconpoll(ip, i);
if(ip->state == Selected)
break;
}
switch(ip->state) {
case Selecting:
print("incon[%d] not polled\n", ip-incon);
break;
case Selected:
print("incon[%d] station %d\n", ip-incon, ip->station);
inconset(ip, 8, 9);
break;
default:
print("incon[%d] bollixed\n", ip-incon);
break;
}
qunlock(&ip->reslock);
}
/*
* reset all incon chips.
*/
void
inconreset(void)
{
int i;
Incon *ip;
incon[0].dev = INCON;
incon[0].state = Selected;
incon[0].rp = incon[0].wp = incon[0].raw;
for(i=1; i<Nincon; i++){
incon[i].dev = INCON+i;
incon[i].state = Dead;
incon[i].dev->cmd = INCON_STOP;
incon[i].rp = incon[i].wp = incon[i].raw;
}
}
void
inconinit(void)
{
}
/*
* enable the device for interrupts, spec is the device number
*/
Chan*
inconattach(char *spec)
{
Incon *ip;
int i;
Chan *c;
i = strtoul(spec, 0, 0);
if(i >= Nincon)
error(0, Ebadarg);
ip = &incon[i];
if(ip->state != Selected)
inconrestart(ip);
c = devattach('i', spec);
c->dev = i;
c->qid = CHDIR;
return c;
}
Chan*
inconclone(Chan *c, Chan *nc)
{
return devclone(c, nc);
}
int
inconwalk(Chan *c, char *name)
{
return devwalk(c, name, 0, 0, streamgen);
}
void
inconstat(Chan *c, char *dp)
{
devstat(c, dp, 0, 0, streamgen);
}
Chan*
inconopen(Chan *c, int omode)
{
if(c->qid == CHDIR){
if(omode != OREAD)
error(0, Eperm);
}else
streamopen(c, &inconinfo);
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
return c;
}
void
inconcreate(Chan *c, char *name, int omode, ulong perm)
{
error(0, Eperm);
}
void
inconclose(Chan *c)
{
if(c->qid != CHDIR)
streamclose(c);
}
long
inconread(Chan *c, void *buf, long n)
{
return streamread(c, buf, n);
}
long
inconwrite(Chan *c, void *buf, long n)
{
return streamwrite(c, buf, n, 0);
}
void
inconremove(Chan *c)
{
error(0, Eperm);
}
void
inconwstat(Chan *c, char *dp)
{
error(0, Eperm);
}
void
inconuserstr(Error *e, char *buf)
{
consuserstr(e, buf);
}
void
inconerrstr(Error *e, char *buf)
{
rooterrstr(e, buf);
}
/*
* the stream routines
*/
/*
* create the kernel process for input
*/
static void
inconstopen(Queue *q, Stream *s)
{
Incon *ip;
char name[32];
ip = &incon[s->dev];
sprint(name, "**incon%d**", s->dev);
q->ptr = q->other->ptr = ip;
ip->rq = q;
kproc(name, inconkproc, ip);
}
/*
* kill off the kernel process
*/
static int
kDead(void *arg)
{
Incon *ip;
ip = (Incon *)arg;
return ip->kstarted == 0;
}
static void
inconstclose(Queue * q)
{
Incon *ip;
ip = (Incon *)q->ptr;
qlock(ip);
ip->rq = 0;
qunlock(ip);
wakeup(&ip->kr);
sleep(&ip->r, kDead, ip);
}
/*
* free all blocks of a message in `q', `bp' is the first block
* of the message
*/
static void
freemsg(Queue *q, Block *bp)
{
for(; bp; bp = getq(q)){
if(bp->flags & S_DELIM){
freeb(bp);
return;
}
freeb(bp);
}
}
/*
* output a block
*
* the first 2 bytes of every message are the channel number,
* low order byte first. the third is a possible trailing control
* character.
*/
void
inconoput(Queue *q, Block *bp)
{
Device *dev;
Incon *ip;
ulong end;
int chan;
int ctl;
int n, size;
if(bp->type != M_DATA){
freeb(bp);
return;
}
/*
* get a whole message before handing bytes to the device
*/
if(!putq(q, bp))
return;
/*
* one transmitter at a time
*/
ip = (Incon *)q->ptr;
qlock(&ip->xmit);
dev = ip->dev;
/*
* parse message
*/
bp = getq(q);
if(bp->wptr - bp->rptr < 3){
freemsg(q, bp);
qunlock(&ip->xmit);
return;
}
chan = bp->rptr[0] | (bp->rptr[1]<<8);
ctl = bp->rptr[2];
bp->rptr += 3;
/*
* make sure there's an incon out there
*/
if(!(dev->status&INCON_ALIVE) || ip->state==Dead){
inconrestart(ip);
freemsg(q, bp);
qunlock(&ip->xmit);
return;
}
/*
* send the 8 bit data
*/
for(;;){
/*
* spin till there is room
*/
for(end = NOW+1000; dev->status & TX_FULL;){
nop(); /* make sure we don't optimize too much */
if(NOW > end){
print("incon output stuck\n");
freemsg(q, bp);
qunlock(&ip->xmit);
return;
}
}
/*
* put in next packet
*/
n = bp->wptr - bp->rptr;
if(n > 16)
n = 16;
size = n;
dev->cdata = chan;
DPRINT("CH|%uo->\n", chan);
while(n--){
DPRINT("->%uo\n", *bp->rptr);
*(uchar *)&dev->data_cntl = *bp->rptr++;
}
/*
* get next block
*/
if(bp->rptr >= bp->wptr){
if(bp->flags & S_DELIM){
freeb(bp);
break;
}
freeb(bp);
bp = getq(q);
if(bp==0)
break;
}
/*
* end packet
*/
dev->cdata = 0;
}
/*
* send the control byte if there is one
*/
if(ctl){
if(size >= 16){
dev->cdata = 0;
DPRINT("CH|%uo->\n", chan);
dev->cdata = chan;
}
DPRINT("CTL|%uo->\n", ctl);
dev->cdata = ctl;
}
dev->cdata = 0;
qunlock(&ip->xmit);
return;
}
/*
* return true if the raw fifo is non-empty
*/
static int
notempty(void *arg)
{
Incon *ip;
ip = (Incon *)arg;
return ip->wp!=ip->rp;
}
/*
* fill a block with what is currently buffered and send it upstream
*/
static void
upstream(Incon *ip, unsigned int ctl)
{
int n;
Block *bp;
n = ip->wptr - ip->buf;
bp = allocb(3 + n);
bp->wptr[0] = ip->chan;
bp->wptr[1] = ip->chan>>8;
bp->wptr[2] = ctl;
if(n)
memcpy(&bp->wptr[3], ip->buf, n);
bp->wptr += 3 + n;
bp->flags |= S_DELIM;
PUTNEXT(ip->rq, bp);
ip->wptr = ip->buf;
}
/*
* Read bytes from the raw input circular buffer.
*/
static void
inconkproc(void *arg)
{
Incon *ip;
unsigned int c;
uchar *lim;
ushort *p, *e;
ip = (Incon *)arg;
ip->kstarted = 1;
ip->wptr = ip->buf;
e = &ip->raw[Nraw];
for(;;){
/*
* die if the device is closed
*/
qlock(ip);
if(ip->rq == 0){
qunlock(ip);
ip->kstarted = 0;
wakeup(&ip->r);
return;
}
/*
* sleep if input fifo empty
*/
while(!notempty(ip))
sleep(&ip->kr, notempty, ip);
p = ip->rp;
/*
* get channel number
*/
c = (*p++)>>8;
if(p == e)
p = ip->raw;
DPRINT("<-CH|%uo\n", c);
if(ip->chan != c){
if(ip->wptr - ip->buf != 0)
upstream(ip, 0);
ip->chan = c;
}
/*
* null byte marks end of packet
*/
for(lim = &ip->buf[sizeof ip->buf];;){
if((c=*p++)&1) {
/*
* data byte, put in local buffer
*/
c = *ip->wptr++ = c>>8;
DPRINT("<-%uo\n", c);
if(ip->wptr >= lim)
upstream(ip, 0);
} else if (c>>=8) {
/*
* control byte ends block
*/
DPRINT("<-CTL|%uo\n", c);
upstream(ip, c);
} else {
/* end of packet */
break;
}
if(p == e)
p = ip->raw;
}
ip->rp = p;
qunlock(ip);
}
}
/*
* read the packets from the device into the raw input buffer.
* we have to do this at interrupt tevel to turn off the interrupts.
*/
static
rdpackets(Incon *ip)
{
Device *dev;
unsigned int c;
ushort *p, *e;
int n;
dev = ip->dev;
while(!(dev->status & RCV_EMPTY)){
n = ip->rp - ip->wp;
if(n <= 0)
n += Nraw;
if(n < 19){
/*
* no room in the raw queue, throw it away
*/
c = (dev->data_cntl)>>8;
for(c=0;c<18;c++){
if(dev->data_cntl == 0)
break;
}
} else {
/*
* put packet in the raw queue
*/
p = ip->wp;
e = &ip->raw[Nraw];
*p++ = dev->data_cntl;
if(p == e)
p = ip->raw;
do {
*p++ = c = dev->data_cntl;
if(p == e)
p = ip->raw;
} while(c);
ip->wp = p;
}
}
wakeup(&ip->kr);
}
/*
* Receive an incon interrupt. One entry point
* for all types of interrupt. Until we figure out
* how to use more than one incon, this routine only
* is for incon[0].
*/
inconintr(Ureg *ur)
{
uchar status;
Incon *ip;
ip = &incon[0];
status = ip->dev->status;
if(!(status & RCV_EMPTY))
rdpackets(ip);
/* check for exceptional conditions */
if(status&(OVERFLOW|CRC_ERROR)){
if(status&OVERFLOW){
print("incon overflow\n");
ip->overflow++;
}
if(status&CRC_ERROR){
print("incon crc error\n");
ip->crc++;
}
}
/* see if it died underneath us */
if(!(status&INCON_ALIVE)){
switch(ip->state){
case Selected:
ip->dev->cmd = INCON_STOP;
print("Incon died\n");
break;
case Selecting:
print("rejected\n");
break;
default:
ip->dev->cmd = INCON_STOP;
break;
}
ip->state = Dead;
}
}
.
## diffname gnot/devincon.c 1990/0315
## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/devincon.c /n/bootesdump/1990/0315/sys/src/9/68020/devincon.c
665,713d
660c
bp = nextin(ip, c);
if(bp == 0)
continue;
.
653,654c
if(bp->wptr >= bp->lim){
bp = nextin(ip, 0);
if(bp == 0)
continue;
}
.
651c
c = *bp->wptr++ = c>>8;
.
646,647c
for(;;){
if((c=dev->data_cntl)&1) {
.
638,639c
if(bp->wptr - bp->rptr > 3){
bp = nextin(ip, 0);
if(bp == 0)
continue;
}
.
633,635c
c = (dev->data_cntl)>>8;
.
629a
/*
* drop an input packet on the floor
*/
static void
droppacket(Device *dev)
{
int i;
int c;
for(i = 0; i < 17; i++){
c = dev->data_cntl;
if(c==0)
break;
}
}
/*
* advance the queue. if we've run out of staged input blocks,
* drop the packet and return 0. otherwise return the next input
* block to fill.
*/
static Block *
nextin(Incon *ip, unsigned int c)
{
Block *bp = ip->inb[ip->wi];
bp->base[0] = ip->chan;
bp->base[1] = ip->chan>>8;
bp->base[2] = c;
ip->wi = (ip->wi + 1) % Nin;
if(((ip->wi+1)%Nin) == ip->ri){
droppacket(ip->dev);
return 0;
}
return ip->inb[ip->wi];
}
/*
* read the packets from the device into the staged input blocks.
* we have to do this at interrupt tevel to turn off the interrupts.
*/
static void
rdpackets(Incon *ip)
{
Block *bp;
unsigned int c;
Device *dev;
dev = ip->dev;
while(!(dev->status & RCV_EMPTY)){
bp = ip->inb[ip->wi];
if(((ip->wi+1)%Nin) == ip->ri || bp==0){
c = dev->data_cntl;
droppacket(dev);
continue;
}
.
626,628c
while(ip->ri != ip->wi){
PUTNEXT(ip->rq, ip->inb[ip->ri]);
bp = ip->inb[ip->ri] = allocb(128);
bp->wptr += 3;
ip->ri = (ip->ri+1)%Nin;
}
qunlock(ip);
}
}
.
624c
* send blocks upstream and stage new blocks
.
612a
* sleep if input fifo empty
*/
sleep(&ip->kr, notempty, ip);
/*
.
610c
/*
* create a number of blocks for input
*/
for(i = 0; i < Nin; i++){
bp = ip->inb[i] = allocb(128);
bp->wptr += 3;
}
.
608d
602,604c
Block *bp;
int i;
.
574,595d
570c
return ip->ri!=ip->wi;
.
553a
MICROSECOND;
.
261c
incon[i].ri = incon[i].wi = 0;
.
256c
incon[0].ri = incon[0].wi = 0;
inconset(&incon[0], 8, 9);
.
145c
MICROSECOND;
*(uchar *)&dev->data_cntl = del;
MICROSECOND;
.
143a
MICROSECOND;
.
142a
MICROSECOND;
.
138c
if (cnt<1 || cnt>14 || del<1 || del>15)
.
134c
inconset(Incon *ip, int cnt, int del)
.
68a
Block *inb[Nin];
ushort wi;
ushort ri;
.
65,67c
/* input blocks */
.
61,62d
22c
Nin= 32, /* size of raw input buffer */
.
15a
static int SpEcIaL;
#define MICROSECOND SpEcIaL = 0
.
## diffname gnot/devincon.c 1990/0320
## diff -e /n/bootesdump/1990/0315/sys/src/9/68020/devincon.c /n/bootesdump/1990/0320/sys/src/9/68020/devincon.c
761c
screenputc('+');
.
757c
screenputc('^');
.
733,734c
/*
* pass a block on if it doesn't have room for one more
* packet. this way we don't have to check per byte.
*/
if(p + 16 > bp->lim){
bp->wptr = p;
bp = nextin(ip, 0);
if(bp == 0)
goto done;
p = bp->wptr;
}
}
bp->wptr = p;
done:
if(first != ip->wi)/**/
wakeup(&ip->kr);
.
727c
goto done;
p = bp->wptr;
.
724c
bp->wptr = p;
.
713,719c
*p++ = c>>8;
.
700c
goto done;
p = bp->wptr;
.
697c
if(p - bp->rptr > 3){
bp->wptr = p;
.
695d
684,690d
682a
bp = ip->inb[ip->wi];
if(bp==0){
droppacket(ip->dev);
goto done;
}
p = bp->wptr;
.
680a
uchar *p;
int first = ip->wi;
.
664,667d
662c
ip->wi = next;
.
658a
next = (ip->wi+1)%Nin;
if(next == ip->ri){
bp->wptr = bp->base+3;
droppacket(ip->dev);
return 0;
}
.
657a
int next;
.
642,645c
screenputc('!');
while(!(dev->status & RCV_EMPTY)){
for(i = 0; i < 17; i++){
c = dev->data_cntl;
if(c==0)
break;
}
.
625c
bp = ip->inb[ip->ri] = allocb(Bsize);
.
599c
bp = ip->inb[i] = allocb(Bsize);
.
563a
MICROSECOND;
.
562d
560d
558a
MICROSECOND;
.
557c
MICROSECOND;
.
527d
525d
25c
Nin= 16, /* Blocks in the input ring */
Bsize= 128, /* size of an input ring block */
.
9a
#include "ureg.h"
.
## diffname gnot/devincon.c 1990/0321
## diff -e /n/bootesdump/1990/0320/sys/src/9/68020/devincon.c /n/bootesdump/1990/0321/sys/src/9/68020/devincon.c
751d
744,745d
728,729d
706,707d
701a
if(c == 0){
droppacket(dev);
continue;
}
.
693,694c
flushfifo(ip->dev);
return;
.
673a
next = (ip->wi+3)%Nin;
if(next == ip->ri){
bp->wptr = bp->base+3;
return bp;
}
ip->wi = (ip->wi+1)%Nin;
.
672d
663,668c
bp = ip->inb[ip->wi];
.
660c
Block *bp;
.
652a
* flush the input fifo
*/
static void
flushfifo(Device *dev)
{
while(!(dev->status & RCV_EMPTY))
droppacket(dev);
}
/*
.
642,648c
for(i = 0; i < 17; i++){
c = dev->data_cntl;
if(c==0)
break;
.
634c
* drop a single packet
.
27a
Mfifo= 0xff /* a mask, must be 2^n-1, must be > Nin */
.
26c
Nin= 64, /* Blocks in the input ring */
.
## diffname gnot/devincon.c 1990/0322
## diff -e /n/bootesdump/1990/0321/sys/src/9/68020/devincon.c /n/bootesdump/1990/0322/sys/src/9/68020/devincon.c
625c
bp = ip->inb[ip->ri];
n = BLEN(bp);
if(n <= 64){
nbp = allocb(n);
memcpy(nbp->wptr, bp->rptr, n);
nbp->wptr += n;
freeb(bp);
PUTNEXT(ip->rq, nbp);
} else {
PUTNEXT(ip->rq, bp);
}
.
622c
* send blocks upstream and stage new blocks. if the block is small
* (< 64 bytes) copy into a smaller buffer.
.
590,591c
Block *bp, *nbp;
int i, n;
.
26c
Nin= 32, /* Blocks in the input ring */
.
## diffname gnot/devincon.c 1990/0330
## diff -e /n/bootesdump/1990/0322/sys/src/9/68020/devincon.c /n/bootesdump/1990/0330/sys/src/9/68020/devincon.c
267c
/* inconset(&incon[0], 8, 9); /**/
.
## diffname gnot/devincon.c 1990/0331
## diff -e /n/bootesdump/1990/0330/sys/src/9/68020/devincon.c /n/bootesdump/1990/0331/sys/src/9/68020/devincon.c
628,636c
PUTNEXT(ip->rq, bp);
.
267c
/* inconset(&incon[0], 3, 15); /**/
.
246c
inconset(ip, 3, 15);
.
## diffname gnot/devincon.c 1990/05312
## diff -e /n/bootesdump/1990/0331/sys/src/9/68020/devincon.c /n/bootesdump/1990/05312/sys/src/9/68020/devincon.c
759a
if(bp->wptr != bp->base+3)
nextin(ip, 0);
.
## diffname gnot/devincon.c 1990/0619
## diff -e /n/bootesdump/1990/05312/sys/src/9/68020/devincon.c /n/bootesdump/1990/0619/sys/src/9/68020/devincon.c
793d
789,791c
if(status&CRC_ERROR)
.
786,787c
if(status&OVERFLOW)
.
## diffname gnot/devincon.c 1990/0623
## diff -e /n/bootesdump/1990/0619/sys/src/9/68020/devincon.c /n/bootesdump/1990/0623/sys/src/9/68020/devincon.c
231a
print("inconrestart\n");
.
## diffname gnot/devincon.c 1990/0629
## diff -e /n/bootesdump/1990/0623/sys/src/9/68020/devincon.c /n/bootesdump/1990/0629/sys/src/9/68020/devincon.c
809a
}
incontoggle()
{
incondebug ^= 1;
.
679a
if(incondebug)
print("<-(%d)%uo %d\n", ip->chan, c, bp->wptr-bp->rptr)-3;
.
494a
if(incondebug)
print("->(%d)%uo %d\n", chan, ctl, bp->wptr - bp->rptr);
.
135a
int incondebug;
.
## diffname gnot/devincon.c 1990/0725
## diff -e /n/bootesdump/1990/0629/sys/src/9/68020/devincon.c /n/bootesdump/1990/0725/sys/src/9/68020/devincon.c
815c
ip->state = Notliving;
.
503c
if(!(dev->status&INCON_ALIVE) || ip->state==Notliving){
.
430c
sleep(&ip->r, kNotliving, ip);
.
413c
kNotliving(void *arg)
.
403c
sprint(name, "incon%d", s->dev);
.
274c
incon[i].state = Notliving;
.
180c
ip->state = Notliving;
.
92c
Notliving,
.
## diffname gnot/devincon.c 1990/0731
## diff -e /n/bootesdump/1990/0725/sys/src/9/68020/devincon.c /n/bootesdump/1990/0731/sys/src/9/68020/devincon.c
693c
ip->wi = next;
.
688c
next = (ip->wi+1)%Nin;
.
686c
print("<-(%d)%uo %d\n", ip->chan, c, bp->wptr-bp->rptr);
.
## diffname gnot/devincon.c 1990/0802
## diff -e /n/bootesdump/1990/0731/sys/src/9/68020/devincon.c /n/bootesdump/1990/0802/sys/src/9/68020/devincon.c
495a
if(chan<=0)
print("bad channel %d\n", chan);
.
## diffname gnot/devincon.c 1990/1024
## diff -e /n/bootesdump/1990/0802/sys/src/9/68020/devincon.c /n/bootesdump/1990/1024/sys/src/9/68020/devincon.c
612a
/*
* ignore errors
*/
if(waserror())
;
.
## diffname gnot/devincon.c 1990/1101
## diff -e /n/bootesdump/1990/1024/sys/src/9/68020/devincon.c /n/bootesdump/1990/1101/sys/src/9/68020/devincon.c
648a
locked = 0;
.
627a
locked = 1;
.
613,617c
locked = 0;
if(waserror()){
if(locked)
qunlock(ip);
ip->kstarted = 0;
wakeup(&ip->r);
return;
}
.
600a
int locked;
.
480d
467c
if(streamparse("inconset", bp))
inconsetctl(ip, bp);
else
freeb(bp);
.
465a
ip = (Incon *)q->ptr;
.
160a
/*
* parse a set request
*/
void
inconsetctl(Incon *ip, Block *bp)
{
char *field[3];
int n;
int del;
int cnt;
del = 15;
n = getfields((char *)bp->rptr, field, 3, ' ');
switch(n){
default:
freeb(bp);
error(0, Ebadarg);
case 2:
del = strtol(field[1], 0, 0);
if(del<0 || del>15){
freeb(bp);
error(0, Ebadarg);
}
/* fall through */
case 1:
cnt = strtol(field[0], 0, 0);
if(cnt<0 || cnt>15){
freeb(bp);
error(0, Ebadarg);
}
}
inconset(ip, cnt, del);
freeb(bp);
}
.
## diffname gnot/devincon.c 1990/11151
## diff -e /n/bootesdump/1990/1101/sys/src/9/68020/devincon.c /n/bootesdump/1990/11151/sys/src/9/68020/devincon.c
134c
Qinfo inconinfo =
{
nullput,
inconoput,
inconstopen,
inconstclose,
"incon"
};
.
## diffname gnot/devincon.c 1990/11211
## diff -e /n/bootesdump/1990/11151/sys/src/9/68020/devincon.c /n/bootesdump/1990/11211/sys/src/9/68020/devincon.c
416,428c
error(Eperm);
.
410c
error(Eperm);
.
391c
if(c->qid.path != CHDIR)
.
385c
error(Eperm);
.
373c
error(Eperm);
.
371c
if(c->qid.path == CHDIR){
.
346c
c->qid.path = CHDIR;
c->qid.vers = 0;
.
339c
error(Ebadarg);
.
196c
error(Ebadarg);
.
189c
error(Ebadarg);
.
184c
error(Ebadarg);
.
154c
error(Ebadarg);
.
## diffname gnot/devincon.c 1990/1212
## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devincon.c /n/bootesdump/1990/1212/sys/src/9/68020/devincon.c
605a
if(dev->status & TX_FULL)
print("inconfull\n");
.
602a
for(end = NOW+1000; dev->status & TX_FULL;){
nop(); /* make sure we don't optimize too much */
if(NOW > end){
print("incon output stuck\n");
freemsg(q, bp);
qunlock(&ip->xmit);
return;
}
}
.
## diffname gnot/devincon.c 1990/1214
## diff -e /n/bootesdump/1990/1212/sys/src/9/68020/devincon.c /n/bootesdump/1990/1214/sys/src/9/68020/devincon.c
698a
USED(locked);
.
693d
683a
poperror();
.
679a
locked = 1;
.
678c
USED(locked);
.
646c
int i;
.
17,18c
#define MICROSECOND USED(NOW)
.
## diffname gnot/devincon.c 1991/0115
## diff -e /n/bootesdump/1990/1214/sys/src/9/68020/devincon.c /n/bootesdump/1991/0115/sys/src/9/68020/devincon.c
880c
void
incontoggle(void)
.
## diffname gnot/devincon.c 1991/0411
## diff -e /n/bootesdump/1991/0201/sys/src/9/68020/devincon.c /n/bootesdump/1991/0411/sys/src/9/gnot/devincon.c
402c
inconwrite(Chan *c, void *buf, long n, ulong offset)
.
396c
inconread(Chan *c, void *buf, long n, ulong offset)
.
## diffname gnot/devincon.c 1991/0419
## diff -e /n/bootesdump/1991/0411/sys/src/9/gnot/devincon.c /n/bootesdump/1991/0419/sys/src/9/gnot/devincon.c
361a
Chan*
inconclwalk(Chan *c, char *name)
{
return devclwalk(c, name);
}
.
## diffname gnot/devincon.c 1991/0427
## diff -e /n/bootesdump/1991/0419/sys/src/9/gnot/devincon.c /n/bootesdump/1991/0427/sys/src/9/gnot/devincon.c
362,367d
## diffname gnot/devincon.c 1991/0906
## diff -e /n/bootesdump/1991/0427/sys/src/9/gnot/devincon.c /n/bootesdump/1991/0906/sys/src/9/gnot/devincon.c
275,276d
## diffname gnot/devincon.c 1991/1122
## diff -e /n/bootesdump/1991/0906/sys/src/9/gnot/devincon.c /n/bootesdump/1991/1122/sys/src/9/gnot/devincon.c
691a
ip->in += BLEN(bp);
.
568a
ip->out += n;
.
559a
ip->wait = (n + ip->wait)>>1;
.
551c
start = NOW;
for(n = 0, end = start+1000; dev->status & TX_FULL; n++){
.
489c
ulong start, end;
.
396c
char b[256];
Incon *i;
if(c->qid.path == CHDIR)
return devdirread(c, buf, n, incondir, 1, streamgen);
else if(c->qid.path == Qstats){
i = &incon[c->dev];
sprint(b, "in: %d\nout: %d\noverflow: %d\ncrc: %d\nwait: %d\n", i->in,
i->out, i->overflow, i->crc, i->wait);
return stringread(buf, n, b, offset);
} else
return streamread(c, buf, n);
.
369c
if(c->qid.path == CHDIR || c->qid.path == Qstats){
.
363c
devstat(c, dp, incondir, 1, streamgen);
.
357c
return devwalk(c, name, incondir, 1, streamgen);
.
143a
Dirtab incondir[]={
"stats", {Qstats}, 0, 0444,
};
.
80a
ulong wait; /* wait time in milliseconds */
.
27c
Mfifo= 0xff, /* a mask, must be 2^n-1, must be > Nin */
Qstats= 1, /* qid of the statistics file */
.
## diffname gnot/devincon.c 1991/1209
## diff -e /n/bootesdump/1991/1122/sys/src/9/gnot/devincon.c /n/bootesdump/1991/1209/sys/src/9/gnot/devincon.c
831a
if(bp==0){
flushfifo(ip->dev);
return;
}
.
811a
if(bp==0){
flushfifo(ip->dev);
return;
}
.
## diffname gnot/devincon.c 1991/1219
## diff -e /n/bootesdump/1991/1209/sys/src/9/gnot/devincon.c /n/bootesdump/1991/1219/sys/src/9/gnot/devincon.c
458,465d
450a
wakeup(&ip->kr);
sleep(&ip->r, kNotliving, ip);
.
440a
* first wait for any old ones to die
.
439a
* for sleeping while kproc dies
*/
static int
kNotliving(void *arg)
{
Incon *ip;
ip = (Incon *)arg;
return ip->kstarted == 0;
}
/*
.
## diffname gnot/devincon.c 1992/0111
## diff -e /n/bootesdump/1991/1219/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0111/sys/src/9/gnot/devincon.c
6c
#include "../port/error.h"
.
## diffname gnot/devincon.c 1992/0321
## diff -e /n/bootesdump/1992/0111/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0321/sys/src/9/gnot/devincon.c
2c
#include "../port/lib.h"
.
## diffname gnot/devincon.c 1992/0611
## diff -e /n/bootesdump/1992/0321/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0611/sys/src/9/gnot/devincon.c
877a
void
.
## diffname gnot/devincon.c 1992/0623
## diff -e /n/bootesdump/1992/0611/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0623/sys/src/9/gnot/devincon.c
865c
if(bp->wptr != bp->rptr+3)
.
778c
bp->wptr = bp->rptr+3;
.
770,772c
bp->rptr[0] = ip->chan;
bp->rptr[1] = ip->chan>>8;
bp->rptr[2] = c;
.
545,549d
527a
if(BLEN(bp) < 3){
bp = pullup(bp, 3);
if(bp == 0){
print("inconoput pullup failed\n");
return;
}
}
.
412c
return readstr(offset, buf, n, b);
.
## diffname gnot/devincon.c 1992/0711
## diff -e /n/bootesdump/1992/0623/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0711/sys/src/9/gnot/devincon.c
885a
USED(ur);
.
672c
Block *bp;
.
431a
USED(c, dp);
.
425a
USED(c);
.
419a
USED(offset);
.
389a
USED(c, name, omode, perm);
.
312d
276d
## diffname gnot/devincon.c 1993/0501 # deleted
## diff -e /n/bootesdump/1992/0711/sys/src/9/gnot/devincon.c /n/fornaxdump/1993/0501/sys/src/brazil/gnot/devincon.c
1,925d
|