## diffname pc/devastar.c 1994/1106
## diff -e /dev/null /n/fornaxdump/1994/1106/sys/src/brazil/pc/devastar.c
0a
#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++;
}
}
.
## diffname pc/devastar.c 1994/1107
## diff -e /n/fornaxdump/1994/1106/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1107/sys/src/brazil/pc/devastar.c
160a
}
void
astarinit(void)
{
}
int isaport[] =
{ 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 };
int
isax00i(int port)
{
uchar c, c1;
if(port < 0)
return 0;
c = inb(port + ISAid);
c1 = inb(port + ISAid);
return (c == ISAid0 && c1 == ISAid1)
|| (c == ISAid1 && c1 == ISAid0));
}
int
astarsetup(Astar *a)
{
int i, j, found;
/* see if the card exists */
found = 0;
if(a->port == 0)
for(i = 0; isaport[i]; i++){
a->port = isaport[i];
found = isax00i(isaport[i]);
if(found){
isaport[i] = -1;
break;
}
}
else
found = isax00i(a->port);
if(!found){
print("avanstar %d not found\n", a->id);
return -1;
}
/* set memory address */
outb(a->port + ISAmaddr, (a->mem>>12) & 0xfc);
a->gcb = KZERO | a->mem;
/* set interrupt level */
if(isairqcode(a->irq) == -1){
print("Avanstar %d bad irq %d\n", a->id, a->irq);
return -1;
}
c = inb(a->port + ISActl1) & ~ISAirq;
outb(a->port + ISActl1, c | isairqcode(a->irq));
.
142a
if(strcmp(a->type, "a100i") == 0 || strcmp(a->type,"A100I") == 0)
a->ramsize = 16*1024;
else if(strcmp(a->type, "a200i") == 0 || strcmp(a->type,"A200I") == 0)
a->ramsize = 256*1024;
else
continue;
if(a->mem == 0)
a->mem = 0xD0000;
if(a->irq == 0)
a->irq = 15;
a->id = i;
if(astarsetup(a) < 0){
xfree(a);
astar[i] = 0;
continue;
}
}
.
137,139c
a = astar[i] = xalloc(sizeof(Astar));
if(isaconfig("serial", i, &a) == 0){
xfree(a);
astar[i] = 0;
.
133a
Astar *a;
.
131c
astarreset(void)
.
126,129c
Astar *a[Maxcard];
int astarsetup(Astar*);
.
111c
.
109a
CCB *ccb; /* control block */
.
100c
ISAConf;
int id; /* from plan9.ini */
int ramsize; /* 16k or 256k */
.
96a
enum
{
/* special baud rate codes for CCB.baud */
Cb76800= 0xff00,
Cb115200= 0xff01,
/* CCB.format fields */
C5bit= 0<<0, /* data bits */
C6bit= 0<<1,
C7bit= 0<<2,
C8bit= 0<<3,
C1stop= 0<<2, /* stop bits */
C2stop= 1<<2,
Cnopar= 0<<3, /* parity */
Coddpar= 1<<3,
Cevenpar= 3<<3,
Cmarkpar= 5<<3,
Cspacepar= 7<<3,
Cnormal= 0<<6, /* normal mode */
Cecho= 1<<6, /* echo mode */
Clloop= 2<<6, /* local loopback */
Crloop= 3<<6, /* remote loopback */
/* CCB.proto fields */
Cobeyxon= 1<<0, /* obey received xoff/xon controls */
Canyxon= 1<<1, /* any rcvd character restarts xmit */
Cgenxon= 1<<2, /* generate xoff/xon controls */
Cobeycts= 1<<3, /* obey hardware flow ctl */
Cgendtr= 1<<4, /* dtr off when uart rcvr full */
C½duplex= 1<<5, /* rts off while xmitting */
Cgenrts= 1<<6, /* generate hardware flow ctl */
Cmctl= 1<<7, /* direct modem control via CCB.mctl */
Cstrip= 1<<12, /* to strip out characters */
Ceia422= 1<<13, /* to select eia 422 lines */
/* CCB.cmd fields */
Cconfall= 1<<0, /* configure channel and UART */
Cconfchan= 1<<1, /* configure just channel */
Cflushin= 1<<2, /* flush input buffer */
Cflushout= 1<<3, /* flush output buffer */
Crcvena= 1<<4, /* enable receiver */
Crcvdis= 1<<5, /* disable receiver */
Cxmtena= 1<<6, /* enable transmitter */
Cxmtdis= 1<<7, /* disable transmitter */
Cmreset= 1<<9, /* reset modem */
/* CCB.errstat fields */
Coverrun= 1<<0,
Cparity= 1<<1,
Cframing= 1<<2,
Cbreak= 1<<3,
/* CCB.mctl fields */
Cdtrctl= 1<<0,
Crtsctl= 1<<1,
Cbreakctl= 1<<4
/* CCB.mstat fields */
Cctsstat= 1<<0,
Cdsrstat= 1<<1,
Cristat= 1<<2,
Cdcdstat= 1<<3,
/* CCB.bstat fields */
Cbrcvoff= 1<<0,
Cbxmtoff= 1<<1,
Clbxoff= 1<<2, /* transmitter blocked by XOFF */
Clbcts= 1<<3, /* transmitter blocked by CTS */
Crbxoff= 1<<4, /* remote blocked by xoff */
Crbrts= 1<<4, /* remote blocked by rts */
};
.
94c
char strip[2]; /* strip/error characters */
.
92c
char xoff[2]; /* xoff characters */
.
73c
char xon[2]; /* xon characters */
.
68c
ushort proto; /* line protocol */
.
61a
enum
{
/* GCB.cmd commands/codes */
Greadycmd= 0,
Gdiagcmd= 1,
Gresetcmd= 2,
/* GCB.status values */
Gready= 0,
Gstopped= 1,
Gramerr= 2,
Gbadcmd= 3,
Gbusy= 4,
/* GCB.type values */
Gx00m= 0x6,
G100e= 0xA,
Gx00i= 0xC,
/* GCB.status2 bits */
Ghas232= (1<<0),
Ghas422= (1<<1),
Ghasmodems= (1<<2),
Ghasrj11s= (1<<7),
Ghasring= (1<<8),
Ghasdcd= (1<<9),
Ghasdtr= (1<<10),
Ghasdsr= (1<<11),
Ghascts= (1<<12),
Ghasrts= (1<<13),
};
.
39a
/* IRQ codes */
static int isairqcode[16] =
{
-1, -1, -1, 0<<4,
1<<4, 2<<4, -1, -1,
-1, 3<<4, 4<<4, 5<<4,
6<<4, -1, -1, 7<<4,
};
.
37a
Maxcards= 3,
.
33,35c
ISAmen= 1<<4, /* enable memory to respond to ISA cycles */
ISAmbank= 0, /* shift for 4 bit memory bank */
ISAmaddr= 3, /* bits 14-19 of the boards mem address */
.
27c
ISAirq= 7<<4, /* mask for irq code */
.
17c
typedef struct Astarchan Astarchan;
.
13,14c
* Stargate's Avanstar serial board. There are ISA, EISA, microchannel
* versions. We only handle the ISA one.
.
## diffname pc/devastar.c 1994/1108
## diff -e /n/fornaxdump/1994/1107/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1108/sys/src/brazil/pc/devastar.c
272c
a->mem = 0xD4000;
.
270a
.
231d
## diffname pc/devastar.c 1994/1109
## diff -e /n/fornaxdump/1994/1108/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1109/sys/src/brazil/pc/devastar.c
359a
return 0;
.
336c
found = astarprobe(isaport[i]);
.
326c
static int
.
312,313c
static int
astarprobe(int port)
.
309,310c
/* isa ports an ax00i can appear at */
int isaport[] = { 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 };
.
281a
nastar++;
.
279c
astar[nastar] = 0;
.
260c
astar[nastar] = 0;
.
257c
a = astar[nastar] = xalloc(sizeof(Astar));
.
247c
static int astarsetup(Astar*);
.
245c
Astar *astar[Maxcard];
int nastar;
.
227a
Astar *a; /* controller */
.
## diffname pc/devastar.c 1994/1111
## diff -e /n/fornaxdump/1994/1109/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1111/sys/src/brazil/pc/devastar.c
362a
return 0;
}
void
astarinit(void)
{
}
Chan*
astarattach(char *spec)
{
return devattach('g', spec);
}
Chan*
astarclone(Chan *c, Chan *nc)
{
return devclone(c, nc);
}
int
astarwalk(Chan *c, char *name)
{
return devwalk(c, name, 0, 0, astargen);
}
void
astarstat(Chan *c, char *dp)
{
devstat(c, dp, 0, 0, astargen);
}
Chan*
astaropen(Chan *c, int omode)
{
Uart *p;
c = devopen(c, omode, 0, 0, astargen);
return c;
}
void
astarcreate(Chan *c, char *name, int omode, ulong perm)
{
USED(c, name, omode, perm);
error(Eperm);
}
void
astarclose(Chan *c)
{
USED(c);
}
long
astarread(Chan *c, void *buf, long n, ulong offset)
{
Astar *a;
if(c->qid.path & CHDIR)
return devdirread(c, buf, n, 0, 0, astargen);
switch(TYPE(c->qid.path)){
case Qmem:
a = astar[
return qread(p->iq, buf, n);
}
return 0;
}
long
astarwrite(Chan *c, void *buf, long n, ulong offset)
{
Uart *p;
if(c->qid.path & CHDIR)
error(Eperm);
switch(TYPE(c->qid.path)){
case Qmem:
return qread(p->iq, buf, n);
}
.
307,311d
286,304d
250a
int
devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db)
{
int dev, sofar, ch, t;
USED(tab, ntab);
sofar = 0;
for(dev = 0; dev < nstar; dev++){
if(sofar == i){
sprint(db->name, "atar%dmem", astar[dev].id);
db->qid = QID(dev, 0, Qmem);
db->mode = 0660;
break;
}
if(i < sofar + 3*astar[dev].nchan){
i -= sofar;
ch = i/3;
t = i%3;
switch(t){
case 0:
sprint(db->name, "eia%d%2.2d", dev, ch);
db->mode = astar[dev]->c[ch].perm;
db->qid = QID(dev, 0, Qdata);
break;
case 1:
sprint(db->name, "eia%d%2.2dctl", dev, ch);
db->mode = astar[dev]->c[ch].perm;
db->qid = QID(dev, 0, Qctl);
break;
case 2:
sprint(db->name, "eia%d%2.2dstat", dev, ch);
db->mode = 0444;
db->qid = QID(dev, 0, Qstat);
break;
break;
}
sofar += 1 + 3*astar[dev].nchan;
}
if(j == nstar)
return -1;
db->atime = seconds();
db->mtime = kerndate;
db->hlength = 0;
db->length = length;
memmove(db->uid, eve, NAMELEN);
memmove(db->gid, eve, NAMELEN);
db->type = devchar[c->type];
db->dev = c->dev;
if(c->flag&CMSG)
db->mode |= CHMOUNT;
return 1;
}
.
248a
enum
{
Qmem= 0,
Qdata,
Qctl,
Qstat,
};
#define TYPE(x) ((x)&0xff)
#define BOARD(x) ((((x)&~CHDIR)>>16)&0xff)
#define CHAN(x) ((((x)&~CHDIR)>>8)&0xff)
#define QID(b,c,t) (((b)<<16)|((c)<<8)|(t))
.
247c
static int nastar;
.
234,243d
229a
int perm;
.
220d
217a
int nchan; /* number of channels */
Astarchan *c; /* channels */
.
10d
## diffname pc/devastar.c 1994/1112
## diff -e /n/fornaxdump/1994/1111/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1112/sys/src/brazil/pc/devastar.c
487a
}
void
astarcreate(Chan *c, char *name, int omode, ulong perm)
{
USED(c, name, omode, perm);
error(Eperm);
}
void
astarremove(Chan *c)
{
USED(c);
error(Eperm);
}
void
astarwstat(Chan *c, char *dp)
{
USED(c, dp);
error(Eperm);
.
484c
a = astar[BOARD(c->qid.path)];
if(offset+n > Pramsize){
if(offset >= Pramsize)
return 0;
n = Pramsize - offset;
}
if(waserror()){
qunlock(a);
nexterror();
}
qlock(a);
to = buf;
while(n > 0){
/* map in right piece of memory */
outb(a->port + ISActl2, ISAmen|(offset>>Footshift));
i = offset%Footprint;
from = a->addr + i;
i = Footprint - i;
if(i > n)
i = n;
/* byte at a time so endian doesn't matter */
for(e = from + i; from < e;)
*to++ = *from++;
n -= i;
}
qunlock(a);
poperror();
break;
case Qbctl:
if(n > sizeof cmsg)
n = sizeof(cmsg) - 1;
memmove(cmsg, buf, n);
cmsg[n] = 0;
if(waserror()){
qunlock(a);
nexterror();
}
qlock(a);
if(strncmp(cmsg, "download", 8) == 0){
/* put board in download mode */
outb(a->port + ISActl1, ISAdl);
/* enable ISA access to first 16k */
outb(a->port + ISActl2, ISAmen);
} else if(strncmp(cmsg, "run", 3) == 0){
/* take board out of download mode and enable IRQ */
outb(a->port + ISActl1, ISAien|isairqcode[a->irq]);
/* enable ISA access to first 16k */
outb(a->port + ISActl2, ISAmen);
/* wait for control program to signal life */
for(i = 0; i < 21; i++){
if(inb(a->port + ISActl1) & ISApr)
break;
tsleep(&a->r, return0, 0, 500);
}
if((inb(a->port + ISActl1) & ISApr) == 0)
print("astar%d program not ready\n", a->id);
} else
error(Ebadarg);
qunlock(a);
poperror();
break;
.
477c
Astar *a;
char *to, *from, *e;
int i;
char cmsg[32];
.
467,468c
a = astar[BOARD(c->qid.path)];
if(offset+n > Pramsize){
if(offset >= Pramsize)
return 0;
n = Pramsize - offset;
}
if(waserror()){
qunlock(a);
nexterror();
}
qlock(a);
from = buf;
while(n > 0){
/* map in right piece of memory */
outb(a->port + ISActl2, ISAmen|(offset>>Footshift));
i = offset%Footprint;
to = a->addr + i;
i = Footprint - i;
if(i > n)
i = n;
/* byte at a time so endian doesn't matter */
for(e = from + i; from < e;)
*to++ = *from++;
n -= i;
}
qunlock(a);
poperror();
break;
case Qbctl:
a = astar[BOARD(c->qid.path)];
sprint(status, "id %2.2ux%2.2ux ctl1 %2.2ux ctl2 %2.2ux maddr %2.2ux stat %2.2ux%2.2ux",
inb(a->port+ISAid), inb(a->port+ISAid),
inb(a->port+ISActl1), inb(a->port+ISActl2),
inb(a->port+ISAmaddr),
inb(a->port+ISAstat2), inb(a->port+ISAstat1));
n = readstr(offset, buf, n, status);
break;
.
460a
char *to, *from, *e;
char status[128];
.
459a
int i;
.
454c
Astar *a;
int i;
switch(TYPE(c->qid.path)){
case Qmem:
a = astar[BOARD(c->qid.path)];
qlock(a);
if(--a->opens == 0){
/* take board out of download mode and enable IRQ */
outb(a->port + ISActl1, ISAien|isairqcode[a->irq]);
/* enable ISA access to first 16k */
outb(a->port + ISActl2, ISAmen|0);
/* wait for program ready */
for(i = 0; i < 21; i++){
if(inb(a->port + ISActl1) & ISApr)
break;
tsleep(&r, return0, 0, 500);
}
if((inb(a->port + ISActl1) & ISApr) == 0)
print("astar%d program not ready\n", a->id);
}
qunlock(a);
break;
}
.
445,451d
440a
switch(TYPE(c->qid.path)){
case Qmem:
case Qbctl:
if(!iseve())
error(Eperm);
break;
}
.
437c
Astar *a;
.
399,400d
395c
if(isairqcode[a->irq] == -1){
.
392c
a->gbc = (GCB*)(KZERO | a->mem);
a->addr = (char*)(KZERO | a->mem);
.
384c
found = astarprobe(a->port);
.
370c
int i, found;
.
364c
|| (c == ISAid1 && c1 == ISAid0);
.
345a
print("serial%d avanstar addr %lux irq %d\n", i, a->addr, a->irq);
.
322c
if(isaconfig("serial", i, a) == 0){
.
318d
302c
db->length = 0; /* update ???? */
.
296c
if(dev == nastar)
.
292,293c
sofar += 3*astar[dev]->nchan;
.
289a
}
.
288c
db->qid.path = QID(dev, 0, Qstat);
.
283c
db->qid.path = QID(dev, 0, Qctl);
.
278c
db->qid.path = QID(dev, 0, Qdata);
.
270c
if(sofar == i){
sprint(db->name, "atar%dctl", astar[dev]->id);
db->qid.path = QID(dev, 0, Qbctl);
db->mode = 0660;
break;
}
sofar++;
if(i - sofar < 3*astar[dev]->nchan){
.
268a
sofar++;
.
264,265c
sprint(db->name, "atar%dmem", astar[dev]->id);
db->qid.path = QID(dev, 0, Qmem);
.
262c
for(dev = 0; dev < nastar; dev++){
.
257a
extern ulong kerndate;
.
255c
astargen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db)
.
242a
Qbctl,
.
230a
int opens;
.
220a
char *addr; /* memory area */
.
217a
Rendez r;
.
214a
QLock;
.
194c
Cbreakctl= 1<<4,
.
38c
Maxcard= 8,
Pramsize= 64*1024, /* size of program ram */
Footshift= 14, /* footprint of card mem in ISA space */
Footprint= 1<<Footshift,
.
## diffname pc/devastar.c 1994/1113
## diff -e /n/fornaxdump/1994/1112/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1113/sys/src/brazil/pc/devastar.c
666a
.
608,641c
return bctlwrite(a, cmsg);
case Qdata:
ac = a->c + CHAN(c->qid.path);
return qwrite(ac->oq, buf, n);
case Qctl:
if(n > sizeof cmsg)
n = sizeof(cmsg) - 1;
memmove(cmsg, buf, n);
cmsg[n] = 0;
return astarctl(a, msg);
.
572,602c
return memwrite(a, buf, n, offset);
.
569a
a = astar[BOARD(c->qid.path)];
.
563,564c
Astarchan *ac;
.
558a
.
555,556d
553a
case 'f':
case 'F':
qflush(ac->oq);
break;
case 'H':
case 'h':
qhangup(ac->iq);
qhangup(ac->oq);
break;
case 'L':
case 'l':
n -= 5;
if(n < 0 || n > 3)
error(Ebadarg);
n |= LEUS(ac->ccb->format) & ~Clenmask;
ac->ccb->format = LEUS(n);
command = Cconfall;
break;
case 'm':
case 'M':
n = LEUS(ac->ccb->format) | Cobeycts;
ac->ccb->proto = LEUS(n);
command = Cconfall;
break;
case 'n':
case 'N':
qnoblock(p->oq, n);
break;
case 'P':
case 'p':
switch(*(cmd+1)){
case 'e':
n = Cevenpar;
break;
case 'o':
n = Coddpar;
break;
default:
n = Cnopar;
break;
}
n |= LEUS(ac->ccb->format) & ~Cparmask;
ac->ccb->format = LEUS(n);
command = Cconfall;
break;
case 'K':
case 'k':
break;
case 'R':
case 'r':
break;
case 'Q':
case 'q':
qsetlimit(ac->iq, n);
qsetlimit(ac->oq, n);
break;
case 'X':
case 'x':
n = LEUS(ac->ccb->format) | Cobeyxon;
ac->ccb->proto = LEUS(n);
command = Cconfall;
break;
.
545,552c
case 'D':
case 'd':
.
543c
nexterror();
}
qlock(a);
if(strncmp(cmsg, "download", 8) == 0){
if(a->running)
error(Eio);
/* put board in download mode */
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c & ~ISAnotdl);
a->memsize = Pramsize;
/* enable ISA access to first 16k */
outb(a->port+ISActl2, ISAmen);
} else if(strncmp(cmsg, "run", 3) == 0){
if(a->running)
error(Eio);
startcp(a);
} else
error(Ebadarg);
qunlock(a);
poperror();
return n;
}
/*
* change channel parameters
*/
void
astarctl(Astarchan *ac, char *cmd)
{
int i, n;
int command;
/* let output drain for a while */
for(i = 0; i < 16 && qlen(ac->oq); i++)
tsleep(&ac->r, qlen, ac->oq, 125);
if(strncmp(cmd, "break", 5) == 0)
cmd = "k";
command = 0;
n = atoi(cmd+1);
switch(*cmd){
case 'B':
case 'b':
switch(n){
case 76800:
ac->ccb->baud = LEUS(Cb76800);
break;
case 115200:
ac->ccb->baud = LEUS(Cb115200);
break;
default:
ac->ccb->baud = LEUS(n);
break;
}
command = Cconfall;
.
541a
}
/* setup the channels */
a->running = 1;
a->nchan = i;
a->c = xalloc(a->nchan * sizeof(Astarchan));
for(i = 0; i < a->nchan; i++){
chansetup(a, &a->c[i], (CCB*)x);
x += sz;
}
}
static long
bctlwrite(Astar *a, char *msg)
{
int i;
uchar c;
if(waserror()){
.
540c
static long
memwrite(Astar *a, uchar *from, long n, ulong offset)
{
uchar *to, *e;
int i, rem;
if(offset+n > a->memsize){
if(offset >= a->memsize)
return 0;
n = a->memsize - offset;
}
if(waserror()){
qunlock(a);
nexterror();
}
qlock(a);
for(rem = n; rem > 0; rem -= i){
/* map in right piece of memory */
setpage(a, offset);
i = offset&Pagemask;
from = a->addr + i;
i = Pagesize - i;
if(i > rem)
i = rem;
/* byte at a time so endian doesn't matter */
for(e = from + i; from < e;)
*to++ = *from++;
}
qunlock(a);
poperror();
return n;
}
/*
* setup a channel
*/
static void
chansetup(Astar *a, Astarchan *ac, void *ccb)
{
ac->a = a;
ac->ccb = ccb;
ac->iq = qopen(4*1024, 0, 0, 0);
ac->oq = qopen(4*1024, 0, astarkick, p);
}
/*
* start control progarm
*/
static void
startcp(Astar *a)
{
int n, i, sz;
uchar *x;
CCB *ccb;
if(a->running)
error(Eio);
/* take board out of download mode and enable IRQ */
outb(a->port+ISActl1, ISAien|isairqcode[a->irq]|ISAnotdl);
a->memsize = a->ramsize;
/* wait for control program to signal life */
for(i = 0; i < 21; i++){
if(inb(a->port+ISActl1) & ISApr)
break;
tsleep(&a->r, return0, 0, 500);
}
if((inb(a->port+ISActl1) & ISApr) == 0){
print("astar%d program not ready\n", a->id);
error(Eio);
}
setpage(a, 0);
i = LEUS(a->gcb->type);
switch(i){
default:
print("astar%d wrong board type %ux\n", a->id, i);
error(Eio);
case 0xc:
break;
}
/* check assumptions */
n = LEUS(a->gcb->ccbn);
if(n != 8 && n != 16){
print("astar%d had %d channels?\n", a->id, i);
error(Eio);
}
x = a->addr + LEUS(a->gcb->ccboff);
sz = LEUS(a->gcb->ccbsz);
if(x+n*sz > a->addr+Pagesize){
print("astar%d ccb's not in 1st page\n", a->id);
error(Eio);
}
for(i = 0; i < n; i++){
ccb = (CCB*)(x + i*sz);
if(APAGE(LEUS(ccb->inbase)) != APAGE(LEUS(ccb->inlim)) ||
APAGE(LEUS(ccb->outbase)) != APAGE(LEUS(ccb->outlim))){
print("astar%d chan buffer spans pages\n", a->id);
error(Eio);
.
521,538c
return 0;
}
.
514,519c
return memread(astar[BOARD(c->qid.path)], buf, n, offset);
case Qbctl:
return bctlread(astar[BOARD(c->qid.path)], buf, n, offset);
}
.
504,507d
500a
static long
memread(Astar *a, uchar *to, long n, ulong offset)
{
uchar *from, *e;
int i, rem;
if(offset+n > a->memsize){
if(offset >= a->memsize)
return 0;
n = a->memsize - offset;
}
if(waserror()){
qunlock(a);
nexterror();
}
qlock(a);
for(rem = n; rem > 0; rem -= i){
/* map in right piece of memory */
setpage(a, offset);
i = offset&Pagemask;
to = a->addr + i;
i = Pagesize - i;
if(i > rem)
i = rem;
/* byte at a time so endian doesn't matter */
for(e = from + i; from < e;)
*to++ = *from++;
}
qunlock(a);
poperror();
return n;
}
static long
bctlread(Chan *c, void *buf, long n, ulong offset)
{
char s[128];
sprint(s, "id %4.4ux ctl1 %2.2ux ctl2 %2.2ux maddr %2.2ux stat %4.4ux",
(inb(a->port+ISAid)<<8)|inb(a->port+ISAid),
inb(a->port+ISActl1), inb(a->port+ISActl2),
inb(a->port+ISAmaddr),
(inb(a->port+ISAstat2)<<8)|inb(a->port+ISAstat1));
return readstr(offset, buf, n, s);
}
.
493c
if((inb(a->port+ISActl1) & ISApr) == 0)
.
489c
if(inb(a->port+ISActl1) & ISApr)
.
485c
outb(a->port+ISActl2, ISAmen|0);
.
482c
outb(a->port+ISActl1, ISAien|isairqcode[a->irq]);
.
410c
outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc);
.
380,381c
c = inb(port+ISAid);
c1 = inb(port+ISAid);
.
357a
a->page = -1;
.
262a
/*
* Only 16k maps into ISA space
*/
void
setpage(Astar *a, ulong offset)
{
int i;
i = APAGE(offset);
if(i == a->page)
return;
outb(a->port+ISActl2, ISAmen|i);
a->page = i;
}
/*
* generate the astar directory entries
*/
.
242a
Rendez r;
.
236c
CCB *ccb; /* channel control block */
.
226,227c
int memsize; /* size of memory currently mapped */
int page; /* page currently mapped */
GCB *gbc; /* global board comm area */
uchar *addr; /* base of memory area */
int running;
Rendez r; /* when waiting for board */
.
223d
159a
Cparmask= 7<<3,
.
149,152c
Clenmask= 3<<0, /* data bits */
.
63,65c
ushort ccbn; /* control channel block count */
ushort ccboff; /* control channel block offset */
ushort ccbsz; /* control channel block size */
.
43a
#define APAGE(x) ((x)>>Pageshift)
.
40,41c
Pageshift= 14, /* footprint of card mem in ISA space */
Pagesize= 1<<Pageshift,
Pagemask= Pagesize-1,
.
14a
#define LENDIAN 1
/* unsigned short little endian representation */
#ifdef LENDIAN
#define LEUS(x) (x)
#else
#define LEUS(x) ( (((x)<<8)&0xff00) | (((x)>>8)&0xff) )
#endif LENDIAN
.
13a
*
* At the expense of performance, I've tried to be careful about
* endian-ness to make this convertable to other ISA bus machines.
* However, xchngus() is in assembler and will have to be translated.
.
## diffname pc/devastar.c 1994/1114
## diff -e /n/fornaxdump/1994/1113/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1114/sys/src/brazil/pc/devastar.c
920a
/*
* get output going
*/
static void
astarkick1(Astarchan *ac)
{
Astar *a = ac->a;
CCB *ccb = a->ccb;
uchar tmp[256];
int n;
for(;;){
setpage(a, 0);
}
}
static void
astarkick(Astarchan *ac)
{
ilock(&ac->a->pagelock);
astarkick(ac);
iunlock(&ac->a->pagelock);
}
/*
* handle an interrupt
*/
static void
astarintr(Ureg *ur, void *arg)
{
Astar *a = arg;
Astarchan *ac;
ulong vec, invec, outvec, errvec, mvec, cmdvec;
int i;
USED(ur);
lock(&a->pagelock);
setpage(a, 0);
/* get causes */
invec = LEUS(xchgw(&a->gcb->inserv, 0));
outvec = LEUS(xchgw(&a->gcb->outserv, 0));
errvec = LEUS(xchgw(&a->gcb->errserv, 0));
mvec = LEUS(xchgw(&a->gcb->modemserv, 0));
cmdvec = LEUS(xchgw(&a->gcb->cmdserv, 0));
/* reenable interrupts */
a->cmd2 = LEUS(Gintack);
/* service interrupts */
ac = a->c;
for(vec = LEUS(xchgw(&a->gcb->inserv, 0)); vec; vec >>= 1){
if(vec&1){
}
setpage(a, 0);
ac++;
}
ac = a->c;
for(vec = LEUS(xchgw(&a->gcb->outserv, 0)); vec; vec >>= 1){
if(vec&1)
astarkick1(ac);
setpage(a, 0);
ac++;
}
ac = a->c;
for(vec = LEUS(xchgw(&a->gcb->cmdserv, 0)); vec; vec >>= 1){
if(vec&1)
wakeup(&ac->r);
ac++;
}
unlock(&a->pagelock);
}
.
894c
if(waserror()){
qunlock(ac);
nexterror();
}
qlock(ac);
astarctl(ac, msg);
qunlock(ac);
poperror();
.
889a
ac = a->c + CHAN(c->qid.path);
.
865d
862a
iunlock(&a->pagelock);
if(command)
chancmd(ac, command);
.
858,859c
n = LEUS(ccb->proto);
if(i)
n |= Cobeyxon;
else
n &= ~Cobeyxon;
ccb->proto = LEUS(n);
.
849a
n = LEUS(ccb->mctl);
if(i)
n |= Crtsctl;
else
n &= ~Crtsctl;
ccb->mctl = LEUS(n);
.
846a
if(i <= 0)
i = 250;
n = LEUS(ccb->mctl) | Cbreakctl;
ccb->mctl = LEUS(n);
iunlock(&a->pagelock);
tsleep(&ac->r, return0, 0, i);
ilock(&a->pagelock);
setpage(a, 0);
n &= ~Cbreakctl;
ccb->mctl = LEUS(n);
.
841,842c
n |= LEUS(ccb->format) & ~Cparmask;
ccb->format = LEUS(n);
.
820,821c
/* turn on cts */
n = LEUS(ccb->proto);
if(i)
n |= Cobeycts;
else
n &= ~Cobeycts;
ccb->proto = LEUS(n);
/* set fifo sizes */
ccb->intrigger = 8;
ccb->outlow = 32;
.
814,815c
n |= LEUS(ccb->format) & ~Clenmask;
ccb->format = LEUS(n);
.
798a
n = LEUS(ccb->mctl);
if(i)
n |= Cdtrctl;
else
n &= ~Cdtrctl;
ccb->mctl = LEUS(n);
.
792c
ccb->baud = LEUS(n);
.
789c
ccb->baud = LEUS(Cb115200);
.
786c
ccb->baud = LEUS(Cb76800);
.
784c
switch(i){
.
780c
i = atoi(cmd+1);
a = ac->a;
ilock(&a->pagelock);
setpage(a, 0);
.
778a
ccb = ac->ccb;
.
770a
CCB *ccb;
Astar *a;
.
766c
static void
.
764a
* (must be called with ac qlocked)
.
763a
* Send a command to a channel
* (must be called with ac qlocked)
*/
static int
chancmddone(void *arg)
{
CCB *ccb = arg;
int x;
ilock(&ac->a->pagelock);
setpage(ac->a, 0);
x = ccb->cmd;
iunlock(&ac->a->pagelock);
return x;
}
static void
chancmd(Astarchan *ac, int cmd)
{
int i;
CCB *ccb;
ccb = ac->ccb;
ilock(&ac->a->pagelock);
setpage(ac->a, 0);
ccb->cmd = cmd;
iunlock(&ac->a->pagelock);
/* wait outside of lock */
tsleep(&ac->r, chancmddone, ccb, 1000);
ilock(&ac->a->pagelock);
setpage(ac->a, 0);
if(ccb->cmd){
print("astar%d cmd didn't terminate\n", ac->a->id);
error(Eio);
}
if(ccb->status){
print("astar%d cmd status %ux\n", ac->a->id, ccb->status);
error(Eio);
}
iunlock(&ac->a->pagelock);
}
/*
* enable a channel for IO, set standard params.
* (must be called with ac qlocked)
*/
static void
enable(Astarchan *ac)
{
Astar qÍ*a = ac->a;
/* make sure we control RTS, DTR and break */
ilock(&a->pagelock);
setpage(a, 0);
n = LEUS(ac->ccb->proto) | Cmctl;
ac->ccb->proto = LEUS(n);
iunlock(&a->pagelock);
chancmd(ac, Crcvena|Cxmtena|Cflushin|Cflushout|Confall);
astarctl(ac, "b9600");
astarctl(ac, "l8");
astarctl(ac, "p0");
astarctl(ac, "d1");
astarctl(ac, "r1");
}
/*
* disable a channel for IO
* (must be called with ac qlocked)
*/
static void
disable(Astarchan *ac)
{
astarctl(ac, "d0");
astarctl(ac, "r0");
ilock(&ac->a->pagelock);
setpage(ac->a, 0);
ccb->intrigger = 8;
ccb->outlow = 32;
iunlock(&ac->a->pagelock);
chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall);
}
/*
.
721c
ac = &a->c[i];
ac->a = a;
ac->ccb = (CCB*)x;
ac->iq = qopen(4*1024, 0, 0, 0);
ac->oq = qopen(4*1024, 0, astarkick, ac);
.
714a
iunlock(&a->pagelock);
poperror();
.
684a
if(waserror()){
iunlock(&a->pagelock);
poperror();
}
ilock(&a->pagelock);
.
665a
Astarchan *ac;
.
646,657d
640,641d
637c
*to++ = *tp++;
iunlock(&a->pagelock);
from += i;
.
635c
/*
* byte at a time so endian doesn't matter,
* go via tmp to avoid pagefaults while ilock'd
*/
memmove(tmp, from, i);
tp = tmp;
ilock(&a->pagelock);
setpage(a, offset);
.
633a
if(i > sizeof tmp)
i = sizeof tmp;
.
630c
to = a->addr + i;
.
628d
619,624d
611a
uchar tmp[256];
.
610c
uchar *to, *e, *tp;
.
606a
/*
* write ISA mapped memory
*/
.
576a
/*
* read ISA status
*/
.
572,573d
569c
*tp++ = *from++;
iunlock(&a->pagelock);
memmove(to, tmp, i);
to += i;
.
566,567c
if(i > sizeof tmp)
i = sizeof tmp;
/*
* byte at a time so endian doesn't matter,
* go via tmp to avoid pagefaults while ilock'd
*/
tp = tmp;
ilock(&a->pagelock);
setpage(a, offset);
.
562c
from = a->addr + i;
.
560d
551,556d
543a
uchar tmp[256];
.
542c
uchar *from, *e, *tp;
.
538a
/*
* read ISA mapped memory
*/
.
534c
if(--ac->opens == 0)
disable(ac);
qunlock(ac);
poperror();
.
516,532c
break;
case Qdata:
case Qctl:
qlock(ac);
if(waserror()){
qunlock(a);
nexterror();
.
502a
case Qdata:
case Qctl:
qlock(ac);
if(waserror()){
qunlock(a);
nexterror();
}
if(ac->opens++ == 0)
enable(ac);
qunlock(ac);
poperror();
break;
.
403a
setvec(Int0vec + a->irq, astarintr, a);
.
285c
static void
.
280c
static int astarsetup(Astar*);
static void astarintr(Ureg*, void*);
static void astarkick(Astarchan*);
static void enable(Astarchan*);
static void disable(Astarchan*);
.
261d
258d
251c
QLock; /* lock for rendez */
Rendez r; /* waiting for command completion */
.
245d
240d
234a
Lock pagelock; /* lock for setting page */
int page; /* page currently mapped */
.
232c
QLock; /* lock for rendez */
Rendez r; /* waiting for command completion */
.
109a
/* GCB.cmd2 bit */
Gintack= 0x1,
.
## diffname pc/devastar.c 1994/1115
## diff -e /n/fornaxdump/1994/1114/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1115/sys/src/brazil/pc/devastar.c
1160c
for(vec = cmdvec; vec; vec >>= 1){
.
1156d
1153c
for(vec = outvec; vec; vec >>= 1){
.
1146,1149c
for(vec = invec; vec; vec >>= 1){
if(vec&1)
astarinput(ac);
.
1142c
a->gcb->cmd2 = LEUS(Gintack);
.
1139a
USED(mvec);
USED(cmdvec);
USED(errvec);
.
1128d
1119a
* process input
*/
static void
astarinput(Astarchan *ac)
{
Astar *a = ac->a;
CCB *ccb = ac->ccb;
uchar buf[256];
uchar *rp, *wp, *bp, *ep, *p, *e;
int n;
setpage(a, 0);
ep = a->addr;
rp = ep + LEUS(ccb->inrp);
wp = ep + LEUS(ccb->inwp);
bp = ep + LEUS(ccb->inbase);
ep = ep + LEUS(ccb->inlim);
for(;;){
n = wp - rp;
if(n == 0)
break;
if(n < 0)
n += ep - bp + 1;
if(n > sizeof(buf))
n = sizeof(buf);
setpage(a, bp - a->addr);
e = buf + n;
for(p = buf; p < e;){
*p++ = *rp++;
if(rp > ep)
rp = bp;
}
qproduce(ac->iq, buf, n);
}
setpage(a, 0);
ccb->inrp = LEUS(rp - a->addr);
}
/*
.
1115c
astarkick1(ac);
.
1108a
ccb->outwp = LEUS(wp - a->addr);
.
1107a
n = rp - wp - 1;
if(n < 0)
n += ep - bp + 1;
if(n == 0)
break;
if(n > sizeof(buf))
n = sizeof(buf);
n = qconsume(ac->oq, buf, n);
if(n <= 0)
break;
setpage(a, bp - a->addr);
e = buf + n;
for(p = buf; p < e;){
*wp++ = *p++;
if(wp > ep)
wp = bp;
}
.
1106a
setpage(a, 0);
ep = a->addr;
rp = ep + LEUS(ccb->outrp);
wp = ep + LEUS(ccb->outwp);
bp = ep + LEUS(ccb->outbase);
ep = ep + LEUS(ccb->outlim);
.
1103,1104c
CCB *ccb = ac->ccb;
uchar buf[256];
uchar *rp, *wp, *bp, *ep, *p, *e;
.
1092,1093c
Dir d;
Astarchan *ac;
if(!iseve())
error(Eperm);
if(CHDIR & c->qid.path)
error(Eperm);
if(TYPE(c->qid.path) != Qdata && TYPE(c->qid.path) != Qctl)
error(Eperm);
ac = astar[BOARD(c->qid.path)]->c + CHAN(c->qid.path);
convM2D(dp, &d);
d.mode &= 0666;
ac->perm = d.mode;
.
1067c
astarctl(ac, cmsg);
.
1051c
bctlwrite(a, cmsg);
return n;
.
1012,1013c
qsetlimit(ac->iq, i);
qsetlimit(ac->oq, i);
.
967c
qnoblock(ac->oq, i);
.
961d
942c
n = i - 5;
.
917c
ccb->baud = LEUS(i);
.
905a
.
902a
.
874,875c
ac->ccb->intrigger = 0;
.
859a
chancmd(ac, Crcvena|Cxmtena|Cconfall);
.
853,854d
851a
chancmd(ac, Cconfall);
.
850a
ac->ccb->outlow = 64;
.
845c
Astar *a = ac->a;
int n;
.
835d
831,832c
if(status){
print("astar%d cmd status %ux\n", ac->a->id, status);
.
827c
status = ccb->status;
cmd = ccb->cmd;
iunlock(&ac->a->pagelock);
if(cmd){
.
823c
tsleep(&ac->r, chancmddone, ac, 1000);
.
813a
int status;
.
812d
807c
return !x;
.
804c
x = ac->ccb->cmd;
.
799c
Astarchan *ac = arg;
.
789d
780,781c
/* start up downloaded program */
.
778a
} else if(strncmp(cmsg, "sharedmem", 9) == 0){
/* map shared memory */
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c | ISAnotdl);
a->memsize = a->ramsize;
/* enable ISA access to first 16k */
outb(a->port+ISActl2, ISAmen);
.
770a
if(strncmp(cmsg, "download", 8) == 0){
.
767,769c
if(a->running)
error(Eio);
.
758d
755,756c
static void
bctlwrite(Astar *a, char *cmsg)
.
752a
/* reenable interrupts */
a->gcb->cmd2 = LEUS(Gintack);
.
748a
ac->perm = 0660;
.
668a
offset += i;
.
665c
for(e = tp + i; tp < e;)
.
654,655c
if(i > sizeof(tmp))
i = sizeof(tmp);
.
624a
case Qdata:
a = astar[BOARD(c->qid.path)];
ac = a->c + CHAN(c->qid.path);
return qread(ac->oq, buf, n);
.
615a
Astar *a;
Astarchan *ac;
.
601c
bctlread(Astar *a, void *buf, long n, ulong offset)
.
591a
offset += i;
.
587c
for(e = tp + i; tp < e;)
.
577,578c
if(i > sizeof(tmp))
i = sizeof(tmp);
.
546a
qclose(ac->iq);
qclose(ac->oq);
}
.
545c
if(--ac->opens == 0){
.
542c
qunlock(ac);
.
539a
ac = a->c + CHAN(c->qid.path);
.
534a
a = astar[BOARD(c->qid.path)];
.
533c
Astarchan *ac;
.
516c
qunlock(ac);
.
513a
ac = a->c + CHAN(c->qid.path);
.
504a
a = astar[BOARD(c->qid.path)];
.
502a
Astarchan *ac;
.
478c
return devattach('G', spec);
.
458,459c
a->gcb = (GCB*)(KZERO | a->mem);
a->addr = (uchar*)(KZERO | a->mem);
.
409c
print("serial%d avanstar port %d addr %lux irq %d\n", i, a->port,
a->addr, a->irq);
.
396a
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c | ISAnotdl);
a->memsize = a->ramsize;
.
379c
int i, c;
.
364,365d
361a
db->qid.vers = 0;
.
351c
db->qid.path = QID(dev, ch, Qstat);
.
346c
db->qid.path = QID(dev, ch, Qctl);
.
341c
db->qid.path = QID(dev, ch, Qdata);
.
326c
sprint(db->name, "astar%dctl", astar[dev]->id);
.
320a
db->length = astar[dev]->memsize;
.
318c
sprint(db->name, "astar%dmem", astar[dev]->id);
.
312a
memset(db, 0, sizeof(Dir));
.
287a
static void astarctl(Astarchan*, char*);
.
246c
GCB *gcb; /* global board comm area */
.
216d
40c
ISAnotdl= 1<<1, /* download bit (0 == download) */
.
## diffname pc/devastar.c 1994/1116
## diff -e /n/fornaxdump/1994/1115/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1116/sys/src/brazil/pc/devastar.c
1250c
if(a->needpage)
setpage(a, 0);
.
1238a
* get flow controlled input going again
*/
static void
astarkick(Astarchan *ac)
{
ilock(&ac->a->pagelock);
astarinput(ac);
iunlock(&ac->a->pagelock);
}
/*
.
1234,1235c
if(a->needpage)
setpage(a, 0);
.
1232c
if(qroduce(ac->iq, buf, n) < 0)
break; /* flow controlled */
if(a->needpage)
setpage(a, 0);
ccb->inrp = LEUS(rp - a->addr);
.
1225c
if(a->needpage)
setpage(a, bp - a->addr);
.
1211c
if(a->needpage)
setpage(a, 0);
.
1187c
if(a->needpage)
setpage(a, 0);
.
1180c
if(a->needpage)
setpage(a, bp - a->addr);
.
1163c
if(a->needpage)
setpage(a, 0);
.
1068c
UNLOCKPAGE(a);
.
1038,1039c
LOCKPAGE(a, 0);
.
1034c
UNLOCKPAGE(a);
.
1002,1004d
996,999c
if(i){
n |= Cobeycts|Cgenrts;
n &= ~Cmctl;
} else {
n &= ~(Cobeycts|Cgenrts);
n |= Cmctl;
}
.
962a
ac->baud = i;
/* set trigger level to about 50 per second */
n = i/500;
i = (LEUS(ccb->inlim) - LEUS(ccb->inbase))/2;
if(n > i)
n = i;
ccb->intrigger = LEUS(n);
.
951a
/* set baud rate (high rates are special - only 16 bits) */
.
946,947c
LOCKPAGE(a, 0);
.
914,918d
892c
UNLOCKPAGE(a);
.
887,888c
LOCKPAGE(a, 0);
.
865c
UNLOCKPAGE(ac->a);
.
861,862c
LOCKPAGE(ac->a, 0);
.
856c
UNLOCKPAGE(ac->a);
.
853,854c
LOCKPAGE(ac->a, 0);
.
841c
UNLOCKPAGE(ac->a);
.
838,839c
LOCKPAGE(ac->a, 0);
.
806c
setpage(a, 0);
.
803a
a->needpage = 1;
.
782a
UNLOCKPAGE(a);
.
781c
/* enable control program interrupt generation */
LOCKPAGE(a, 0);
.
776c
ac->iq = qopen(4*1024, 0, astarkickin, ac);
.
764c
UNLOCKPAGE(a);
.
733,734c
LOCKPAGE(a, 0);
.
730c
UNLOCKPAGE(a);
.
716a
setpage(a, 0);
if(a->memsize <= Pagesize)
a->needpage = 0;
else
a->needpage = 1;
.
691c
UNLOCKPAGE(a);
.
687,688c
LOCKPAGE(a, offset);
.
648c
return qread(ac->iq, buf, n);
.
605c
UNLOCKPAGE(a);
.
601,602c
LOCKPAGE(a, offset);
.
530a
qreopen(ac->iq);
qreopen(ac->oq);
}
.
529c
if(ac->opens++ == 0){
.
284a
static void astarkickin(Astarchan*);
.
260a
int baud;
.
248d
244a
int needpage;
.
59a
#define LOCKPAGE(a, o) if((a)->needpage){ilock(&(a)->pagelock);setpage(a, o);}
#define UNLOCKPAGE(a) if((a)->needpage)iunlock(&(a)->pagelock)
.
## diffname pc/devastar.c 1994/1117
## diff -e /n/fornaxdump/1994/1116/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1117/sys/src/brazil/pc/devastar.c
1309c
astaroutput(ac);
.
1264c
astarkickin(Astarchan *ac)
.
1250c
if(qproduce(ac->iq, buf, n) < 0)
.
1211c
astaroutput(ac);
.
1168c
astaroutput(Astarchan *ac)
.
923a
LOCKPAGE(ac->a, 0);
n = LEUS(ac->ccb->proto) | Cmctl;
ac->ccb->proto = LEUS(n);
UNLOCKPAGE(ac->a);
.
920a
int n;
.
357c
sprint(db->name, "eia%d%2.2dstat", dev, ch+1);
.
352c
sprint(db->name, "eia%d%2.2dctl", dev, ch+1);
.
347c
sprint(db->name, "eia%d%2.2d", dev, ch+1);
.
## diffname pc/devastar.c 1994/1118
## diff -e /n/fornaxdump/1994/1117/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1118/sys/src/brazil/pc/devastar.c
792a
setvec(Int0vec + a->irq, astarintr, a);
.
424c
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c & ~ISAnotdl);
a->memsize = Pramsize;
c = inb(a->port+ISActl2);
outb(a->port+ISActl2, c & ~ISAmen);
a->page = -1;
.
413d
404,407d
402a
}
.
401c
else {
xfree(a);
astar[nastar] = 0;
.
394c
continue;
.
357c
sprint(db->name, "eia%d%2.2dstat", dev, ch);
.
352c
sprint(db->name, "eia%d%2.2dctl", dev, ch);
.
347c
sprint(db->name, "eia%d%2.2d", dev, ch);
.
## diffname pc/devastar.c 1994/1119
## diff -e /n/fornaxdump/1994/1118/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1119/sys/src/brazil/pc/devastar.c
1295a
if(a->running == 0){
print("astar interrupt but cp not running\n");
return;
}
.
795,800d
780a
print("setting up channels\n");
.
778a
/* enable control program interrupt generation */
a->gcb->cmd2 = LEUS(Gintack);
.
747a
.
733a
print("waiting for cp\n");
.
724a
print("out of download\n");
.
428a
setvec(Int0vec + a->irq, astarintr, a);
.
425,427d
421a
/* disable ISA memory response */
c = inb(a->port+ISActl2);
outb(a->port+ISActl2, c & ~ISAmen);
/* download mode to turn off cpu */
.
418c
print("serial%d avanstar port 0x%lux addr %lux irq %d\n", i, a->port,
.
## diffname pc/devastar.c 1994/1120
## diff -e /n/fornaxdump/1994/1119/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1120/sys/src/brazil/pc/devastar.c
839c
a->page = -1;
setpage(a, 0);
.
829a
a->page = -1;
.
732d
730c
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c|ISAien|ISAnotdl);
.
720c
int c, n, i, sz;
.
486a
/* set ISA memory address */
outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc);
a->gcb = (GCB*)(KZERO | a->mem);
a->addr = (uchar*)(KZERO | a->mem);
/* set up interrupt level, reset processor, leave interrupts off */
c = inb(a->port+ISActl1);
c &= ~(ISAnotdl|ISAien|ISAirq);
c |= isairqcode[a->irq];
outb(a->port+ISActl1, c);
setvec(Int0vec + a->irq, astarintr, a);
/* disable ISA memory response */
c = inb(a->port+ISActl2);
outb(a->port+ISActl2, c & ~ISAmen);
a->memsize = 0;
a->page = -1;
.
476,481c
/* check interrupt level */
.
456c
int i, c, found;
.
421,432d
418c
print("serial%d avanstar port 0x%lux addr %lux irq %d\n", a->id, a->port,
.
406a
/* defaults */
.
396a
/* check all possible names */
.
305c
c = inb(a->port+ISActl2) & ~ISAmbank;
outb(a->port+ISActl2, ISAmen|i|c);
.
300c
int i, c;
.
46c
ISAmbank= 0xf<<0, /* shift for 4 bit memory bank */
.
## diffname pc/devastar.c 1994/1121
## diff -e /n/fornaxdump/1994/1120/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1121/sys/src/brazil/pc/devastar.c
1342a
ac++;
}
ac = a->c;
for(vec = errvec; vec; vec >>= 1){
c = LEUS(ac->ccb->errstat);
if(c & Cframing)
ac->framing++;
if(c & Coverrun)
ac->overrun++;
.
1321d
1308,1311d
1304a
if(a->running == 0)
panic("astar interrupt but cp not running\n");
.
1302a
int c;
.
1008a
ac->dtr = n;
.
810a
/* set up interrupt level, enable interrupts */
c = inb(a->port+ISActl1);
c &= ~ISAirq;
c |= ISAien|isairqcode[a->irq];
outb(a->port+ISActl1, c);
setvec(Int0vec + a->irq, astarintr, a);
/* enable control program interrupt generation */
LOCKPAGE(a, 0);
a->gcb->cmd2 = LEUS(Gintack);
UNLOCKPAGE(a);
.
801c
a->c = smalloc(a->nchan * sizeof(Astarchan));
.
796d
791,793d
744d
741a
a->page = -1;
setpage(a, 0);
.
734d
660a
case Qstat:
a = astar[BOARD(c->qid.path)];
return statread(a->c + CHAN(c->qid.path), buf, n, offset);
.
650a
static long
statread(Astarchan *ac, void *buf, long n, ulong offset)
{
char s[128];
int mstat, bstat;
LOCKPAGE(ac->a, 0);
mstat = LEUS(ac->ccb->mstat);
bstat = LEUS(ac->ccb->bstat);
UNLOCKPAGE(ac->a);
/* CCB.mstat fields */
sprint(s, "ferr %d oerr %d baud %d", 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->opens)
strcat(s, " dtr");
if((bstat & Crbrts) == 0)
strcat(s, " rts");
return readstr(offset, buf, n, s);
}
.
491a
/* reset processor */
outb(a->port+ISActl1, 0);
.
487,488c
outb(a->port+ISActl2, 0);
.
479,485d
448c
int i, found;
.
423a
print("\tctl1 %ux ctl2 %ux maddr %ux stat1 %ux stat2 %ux\n", inb(a->port+ISActl1),
inb(a->port+ISActl2), inb(a->port+ISAmaddr), inb(a->port+ISAstat1),
inb(a->port+ISAstat2));
.
388c
int i;
.
359c
sprint(db->name, "eia%d%2.2dstat", astar[dev]->id, ch);
.
354c
sprint(db->name, "eia%d%2.2dctl", astar[dev]->id, ch);
.
349c
sprint(db->name, "eia%d%2.2d", astar[dev]->id, ch);
.
306,307c
outb(a->port+ISActl2, ISAmen|i);
.
300c
int i;
.
264c
int baud; /* baud rate */
int framing; /* framing errors */
int overrun; /* overruns */
int dtr; /* non-zero means dtr on */
.
260,261c
Astar *a; /* controller */
CCB *ccb; /* channel control block */
.
257,258c
QLock; /* lock for rendez */
Rendez r; /* waiting for command completion */
.
46c
ISAmbank= 0xf<<0, /* shift for 4 bit memory bank */
.
## diffname pc/devastar.c 1994/1122
## diff -e /n/fornaxdump/1994/1121/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1122/sys/src/brazil/pc/devastar.c
1128a
ac->rts = i;
.
1050c
ac->dtr = i;
.
963d
833a
ac->baud = 9600; /* a100i default */
.
675a
strcat(s, "\n");
.
674c
if(ac->rts && (bstat & Crbrts) == 0)
.
672c
if(ac->dtr)
.
663c
sprint(s, "opens %d ferr %d oerr %d baud %d", ac->opens, ac->framing,
ac->overrun, ac->baud);
.
579c
if(--(ac->opens) == 0){
.
285,286c
#define BOARD(x) (((x)>>16)&0xff)
#define CHAN(x) (((x)>>8)&0xff)
.
267a
int rts; /* non-zero means rts on */
.
## diffname pc/devastar.c 1994/1210
## diff -e /n/fornaxdump/1994/1122/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1210/sys/src/brazil/pc/devastar.c
419a
if(isaget(a->mem, Pagesize, 0) == 0)
panic("astarreset: %lux", a->mem);
.
## diffname pc/devastar.c 1994/1218
## diff -e /n/fornaxdump/1994/1210/sys/src/brazil/pc/devastar.c /n/fornaxdump/1994/1218/sys/src/brazil/pc/devastar.c
420c
if(getisa(a->mem, Pagesize, 0) == 0)
.
## diffname pc/devastar.c 1995/0106
## diff -e /n/fornaxdump/1994/1218/sys/src/brazil/pc/devastar.c /n/fornaxdump/1995/0106/sys/src/brazil/pc/devastar.c
421a
a->mem & ~KZERO;
.
420c
a->mem = getisa(a->mem, Pagesize, Pagesize);
if(a->mem == 0)
.
414,415d
## diffname pc/devastar.c 1995/0108
## diff -e /n/fornaxdump/1995/0106/sys/src/brazil/pc/devastar.c /n/fornaxdump/1995/0108/sys/src/brazil/pc/devastar.c
1200a
}
long
astarbwrite(Chan *c, Block *bp, ulong offset)
{
return devbwrite(c, bp, offset);
.
711a
Block*
astarbread(Chan *c, long n, ulong offset)
{
return devbread(c, n, offset);
}
.
## diffname pc/devastar.c 1995/0115
## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/pc/devastar.c /n/fornaxdump/1995/0115/sys/src/brazil/pc/devastar.c
421c
a->mem &= ~KZERO;
.
## diffname pc/devastar.c 1995/0127
## diff -e /n/fornaxdump/1995/0115/sys/src/brazil/pc/devastar.c /n/fornaxdump/1995/0127/sys/src/brazil/pc/devastar.c
548a
ac->qopens--;
.
## diffname pc/devastar.c 1995/0207
## diff -e /n/fornaxdump/1995/0127/sys/src/brazil/pc/devastar.c /n/fornaxdump/1995/0207/sys/src/brazil/pc/devastar.c
549c
ac->opens--;
.
## diffname pc/devastar.c 1995/0505
## diff -e /n/fornaxdump/1995/0207/sys/src/brazil/pc/devastar.c /n/fornaxdump/1995/0505/sys/src/brazil/pc/devastar.c
765c
* start control program
.
## diffname pc/devastar.c 1995/0726
## diff -e /n/fornaxdump/1995/0505/sys/src/brazil/pc/devastar.c /n/fornaxdump/1995/0726/sys/src/brazil/pc/devastar.c
1219d
1217c
astarcreate(Chan*, char*, int, ulong)
.
## diffname pc/devastar.c 1996/0223
## diff -e /n/fornaxdump/1995/0726/sys/src/brazil/pc/devastar.c /n/fornaxdump/1996/0223/sys/src/brazil/pc/devastar.c
9d
## diffname pc/devastar.c 1996/0807
## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/pc/devastar.c /n/fornaxdump/1996/0807/sys/src/brazil/pc/devastar.c
450c
|| (c == ISAid1 && c1 == ISAid0)
|| (c == ISAid0x && c1 == ISAid1x)
|| (c == ISAid1x && c1 == ISAid0x);
.
35a
ISAid0x= 0x69,
ISAid1x= 0x96,
.
## diffname pc/devastar.c 1996/0808
## diff -e /n/fornaxdump/1996/0807/sys/src/brazil/pc/devastar.c /n/fornaxdump/1996/0808/sys/src/brazil/pc/devastar.c
887,894c
downloadmode(a);
.
767a
* put board into download mode
*/
static void
downloadmode(Astar *a)
{
int c, i;
/* put board in download mode */
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c & ~ISAnotdl);
a->memsize = Pramsize;
a->needpage = 1;
/* give it up to 5 seconds to reset */
for(i = 0; i < 21; i++){
if(!(inb(a->port+ISActl1) & ISAnotdl))
break;
tsleep(&a->r, return0, 0, 500);
}
if(inb(a->port+ISActl1) & ISAnotdl){
print("astar%d did not reset\n", a->id);
error(Eio);
}
/* enable ISA access to first 16k */
a->page = -1;
setpage(a, 0);
}
/*
.
## diffname pc/devastar.c 1997/0327
## diff -e /n/fornaxdump/1996/0808/sys/src/brazil/pc/devastar.c /n/emeliedump/1997/0327/sys/src/brazil/pc/devastar.c
1316a
.
1273a
Dev astardevtab = {
astarreset,
devinit,
astarattach,
devclone,
astarwalk,
astarstat,
astaropen,
devcreate,
astarclose,
astarread,
devbread,
astarwrite,
devbwrite,
devremove,
astarwstat,
};
.
1236,1255c
static void
.
1192c
static long
.
1098,1099c
qhangup(ac->iq, nil);
qhangup(ac->oq, nil);
.
893c
intrenable(VectorPIC + a->irq, astarintr, a, BUSUNKNOWN);
.
716,721d
690c
static long
.
568c
static void
.
531c
static Chan*
.
525c
static void
.
513,519c
static int
.
502,507c
static Chan*
.
439c
static int isaport[] = { 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 };
.
419c
a->mem = umbmalloc(a->mem, Pagesize, Pagesize);
.
389c
static void
.
318c
static int
.
## diffname pc/devastar.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/devastar.c /n/emeliedump/1997/0408/sys/src/brazil/pc/devastar.c
1238a
'G',
"astar",
.
381c
db->type = devtab[c->type]->dc;
.
## diffname pc/devastar.c 1997/0710
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/pc/devastar.c /n/emeliedump/1997/0710/sys/src/brazil/pc/devastar.c
566,567d
562a
if((c->flag & COPEN) == 0)
return;
.
280c
Qmem= 1,
.
## diffname pc/devastar.c 1997/0917
## diff -e /n/emeliedump/1997/0710/sys/src/brazil/pc/devastar.c /n/emeliedump/1997/0917/sys/src/brazil/pc/devastar.c
1394d
1387a
globvec = LEUS(xchgw(&a->gcb->serv, 0));
USED(globvec);
.
1376c
ulong globvec, vec, invec, outvec, errvec, mvec, cmdvec;
.
406c
else if(strcmp(a->type, "a200i") == 0 ||
strcmp(a->type,"A200I") == 0 ||
strcmp(a->type, "a16i") == 0)
.
## diffname pc/devastar.c 1997/0919
## diff -e /n/emeliedump/1997/0917/sys/src/brazil/pc/devastar.c /n/emeliedump/1997/0919/sys/src/brazil/pc/devastar.c
1349,1350c
if(ac->opens == 0 || qproduce(ac->iq, buf, n) < 0)
break; /* flow controlled or not open */
.
## diffname pc/devastar.c 1998/0109
## diff -e /n/emeliedump/1997/0919/sys/src/brazil/pc/devastar.c /n/emeliedump/1998/0109/sys/src/brazil/pc/devastar.c
1399a
if(a->pci){
/*
* Only the PCI doorbell interrupt is expected.
*/
status = inl(a->port+PCIstatus);
if((status & 0x0810E000) != 0x00002000)
print("#G%d: unexpected interrupt %uX\n", a->id, status);
if(status & 0x00002000)
outl(a->port+PCIdoorbell1, 1);
}
.
1383c
panic("#G%d: interrupt but cp not running\n", a->id);
.
1380a
.
1379c
int c, status;
.
1191c
if(a->pci)
return pcimemwrite(a, buf, n, offset);
return isamemwrite(a, buf, n, offset);
.
966c
print("#G%d: cmd status %ux\n", ac->a->id, status);
.
962c
print("#G%d: cmd didn't terminate\n", ac->a->id);
.
918a
} else if(strncmp(cmsg, "test", 4) == 0){
uchar *p;
#ifdef notdef
p = a->addr;
a->page = -1;
setpage(a, 16*1024);
*p = 'X';
p = a->addr;
print("page0: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
setpage(a, 2*16*1024);
print("page1: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
p = a->addr;
*p = 'Y';
p = a->addr;
print("page1: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
setpage(a, 16*1024);
p = a->addr;
print("page0: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
#else
p = a->addr;
*p = 'A';
print(" 0K: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
p = a->addr+(16*1024);
*p = 'B';
print("16K: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
p = a->addr;
print(" 0K: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
*p = 'C';
print(" 0K: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
p = a->addr+(64*1024);
*p = 'D';
print("64K: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
p = a->addr;
print(" 0K: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
p = a->addr+(16*1024);
print("16K: %8.8uX %2.2uX\n", inl(a->port+PCIremap), *p);
#endif /* notdef */
.
905,914d
890,891d
879,880d
874,877c
if(a->pci){
/*
* Which bits in the interrupt control register should be set?
*/
outl(a->port+PCIcontrol, 0x00031F00);
intrenable(VectorPIC + a->irq, astarintr, a, a->pci->tbdf);
}
else{
c = inb(a->port+ISActl1);
c &= ~ISAirq;
c |= ISAien|isairqcode[a->irq];
outb(a->port+ISActl1, c);
intrenable(VectorPIC + a->irq, astarintr, a, BUSUNKNOWN);
}
.
850c
print("#G%d: chan buffer spans pages\n", a->id);
.
843c
print("#G%d: ccb's not in 1st page\n", a->id);
.
837c
print("#G%d: has %d channels?\n", a->id, i);
.
830c
case 0x0C:
case 0x12: /* AvanstarXp */
.
828c
print("#G%d: wrong board type %uX\n", a->id, i);
.
814,817d
805,812d
803c
else{
a->page = -1;
setpage(a, 0);
.
801c
if(a->pci || a->memsize <= Pagesize)
.
798,799c
if(a->pci){
outl(a->port+PCImailbox, 1);
/* wait for control program to signal life */
delay(100);
for(i = 0; i < 10; i++){
if(inl(a->port+PCImailbox) & 0x80000000)
break;
tsleep(&a->r, return0, 0, 100);
}
if(!(inl(a->port+PCImailbox) & 0x80000000)){
print("#G%d: program not ready\n", a->id);
//error(Eio);
}
a->addr = (uchar*)(a->mem+0x10000);
}
else{
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c|ISAien|ISAnotdl);
/* wait for control program to signal life */
for(i = 0; i < 21; i++){
if(inb(a->port+ISActl1) & ISApr)
break;
tsleep(&a->r, return0, 0, 500);
}
if((inb(a->port+ISActl1) & ISApr) == 0){
print("#G%d: program not ready\n", a->id);
error(Eio);
}
}
.
778,780c
/* give it up to 5 seconds to reset */
for(i = 0; i < 21; i++){
if(!(inb(a->port+ISActl1) & ISAnotdl))
break;
tsleep(&a->r, return0, 0, 500);
}
if(inb(a->port+ISActl1) & ISAnotdl){
print("#G%d: did not reset\n", a->id);
error(Eio);
}
/* enable ISA access to first 16k */
a->page = -1;
setpage(a, 0);
}
.
773,776c
else{
a->memsize = Pramsize;
a->needpage = 1;
c = inb(a->port+ISActl1);
outb(a->port+ISActl1, c & ~ISAnotdl);
.
762,771c
if(a->pci){
/*
* Don't let the download write over the
* i960 data structures.
*/
a->memsize = 0xD000;
a->addr = (uchar*)a->mem;
.
712c
isamemwrite(Astar *a, uchar *from, long n, ulong offset)
.
708a
* write PCI mapped memory
*/
static long
pcimemwrite(Astar *a, uchar *from, long n, ulong offset)
{
uchar *to;
int rem;
ulong limit;
/*
* Disallow writes above 0xD000 where the i960
* data structures live if writing in the lower bank.
*/
if(a->addr == (uchar*)a->mem)
limit = 0xD000;
else
limit = a->memsize;
if(offset+n > limit){
if(offset >= limit)
return 0;
n = limit - offset;
}
to = a->addr+offset;
for(rem = n; rem > 0; rem--)
*to++ = *from++;
return n;
}
/*
.
696c
a = astar[BOARD(c->qid.path)];
if(a->pci)
return pcimemread(a, buf, n, offset);
return isamemread(a, buf, n, offset);
.
643,647c
if(a->pci)
sprint(s, "range %uX remap %uX region %uX mailbox %uX doorbell0 %uX doorbell1 %uX control %uX command %uX",
inl(a->port+PCIrange),
inl(a->port+PCIremap),
inl(a->port+PCIregion),
inl(a->port+PCImailbox),
inl(a->port+PCIdoorbell0),
inl(a->port+PCIdoorbell1),
inl(a->port+PCIcontrol),
inl(a->port+PCIcommand));
else
sprint(s, "id %4.4ux ctl1 %2.2ux ctl2 %2.2ux maddr %2.2ux stat %4.4ux",
(inb(a->port+ISAid)<<8)|inb(a->port+ISAid),
inb(a->port+ISActl1), inb(a->port+ISActl2),
inb(a->port+ISAmaddr),
(inb(a->port+ISAstat2)<<8)|inb(a->port+ISAstat1));
.
594c
isamemread(Astar *a, uchar *to, long n, ulong offset)
.
590a
* read PCI mapped memory
*/
static long
pcimemread(Astar *a, uchar *to, long n, ulong offset)
{
uchar *from;
int rem;
if(offset+n > a->memsize){
if(offset >= a->memsize)
return 0;
n = a->memsize - offset;
}
from = a->addr+offset;
for(rem = n; rem > 0; rem--)
*to++ = *from++;
return n;
}
/*
.
490,491c
a->gcb = KADDR(a->mem);
a->addr = KADDR(a->mem);
.
484c
print("#G%d: bad irq %d\n", a->id, a->irq);
.
478c
print("#G%d: not found\n", a->id);
.
431,435c
else{
/* defaults */
if(a->irq == 0)
a->irq = 15;
a->mem = umbmalloc(a->mem, Pagesize, Pagesize);
if(a->mem == 0)
panic("astarreset: %lux", a->mem);
a->mem = PADDR(a->mem);
if(astarsetup(a) < 0){
xfree(a);
astar[nastar] = 0;
continue;
}
print("\tctl1 %ux ctl2 %ux maddr %ux stat1 %ux stat2 %ux\n",
inb(a->port+ISActl1), inb(a->port+ISActl2), inb(a->port+ISAmaddr),
inb(a->port+ISAstat1), inb(a->port+ISAstat2));
}
print("#G%d: %s port 0x%luX addr 0x%luX irq %d\n",
a->id, a->type, a->port, a->addr, a->irq);
.
426,429c
/*
* So the memory can be read before any other
* initialisation takes place.
*/
a->memsize = a->ramsize;
.
421,424c
/*
* Toggle the software reset and wait for
* the adapter local init status to indicate done.
*/
outl(a->port+PCIremap, 0xA0000001);
x = inl(a->port+PCIcommand);
outl(a->port+PCIcommand, 0x40000000|x);
microdelay(1);
outl(a->port+PCIcommand, x);
delay(100);
for(x = 0; x < 10000; x++){
if(inl(a->port+PCIcommand) & 0x80000000)
break;
}
if(!(inl(a->port+PCIcommand) & 0x80000000))
print("#G: didn't reset\n", a->id);
.
419a
if(a->pci){
a->irq = p->intl;
a->port = p->mem[1].bar & ~0x03;
a->mem = upamalloc(p->mem[2].bar & ~0x0F, p->mem[2].size, 0);
a->addr = (uchar*)a->mem;
a->gcb = (GCB*)(a->mem+0x10000);
.
416,418d
410c
else if(cistrcmp(a->type, "AvanstarXp") == 0){
if(p = pcimatch(p, 0x114F, 0x6001)){
a->pci = p;
/*
* It's really 128KB, but split into
* two 64KB chunks.
*/
a->ramsize = 64*1024;
}
}
if(a->ramsize == 0){
.
406,408c
else if(cistrcmp(a->type, "a200i") == 0 ||
cistrcmp(a->type,"A200I") == 0 ||
cistrcmp(a->type, "a16i") == 0)
.
404c
if(cistrcmp(a->type, "a100i") == 0 || cistrcmp(a->type,"A100I") == 0)
.
402a
a->ramsize = 0;
.
394a
p = nil;
.
393a
Pcidev *p;
.
392c
int i, x;
.
306a
if(a->pci){
print("#G%d: setpage caller pc %uX\n", a->id, getcallerpc(a));
return;
}
.
249a
int pagebase; /* pci */
.
241a
Pcidev* pci;
.
56a
PCIrange= 0x00,
PCIremap= 0x04,
PCIregion= 0x18,
PCImailbox= 0x40,
PCIdoorbell0= 0x60,
PCIdoorbell1= 0x64,
PCIcontrol= 0x68, /* write */
PCIstatus= 0x68, /* read */
PCIcommand= 0x6C,
Maxcard= 8,
Pramsize= 64*1024, /* size of program ram */
.
52,53d
16c
* However, xchgw() is in assembler and will have to be translated.
.
## diffname pc/devastar.c 1998/0319
## diff -e /n/emeliedump/1998/0109/sys/src/brazil/pc/devastar.c /n/emeliedump/1998/0319/sys/src/brazil/pc/devastar.c
1389a
ulong offset = off;
.
1385c
astarwrite(Chan *c, void *buf, long n, vlong off)
.
785a
ulong offset = off;
.
782c
astarread(Chan *c, void *buf, long n, vlong off)
.
352c
db->length1 = astar[dev]->memsize; /* BOTCH */
db->length2 = astar[dev]->memsize; /* BOTCH */
.
344d
337c
astargen(Chan *c, Dirtab *, int , int i, Dir *db)
.
## diffname pc/devastar.c 1998/0414
## diff -e /n/emeliedump/1998/0319/sys/src/brazil/pc/devastar.c /n/emeliedump/1998/0414/sys/src/brazil/pc/devastar.c
571a
ulong ctlrno;
char *p;
ctlrno = 0;
if(spec && *spec){
ctlrno = strtoul(spec, &p, 0);
if((ctlrno == 0 && p == spec) || *p || (ctlrno >= Maxcard))
error(Ebadarg);
}
if(astar[ctlrno] == nil)
error(Enodev);
.
351,352c
db->length = astar[dev]->memsize;
.
## diffname pc/devastar.c 1998/0813
## diff -e /n/emeliedump/1998/0414/sys/src/brazil/pc/devastar.c /n/emeliedump/1998/0813/sys/src/brazil/pc/devastar.c
470c
print("#G%d: didn't reset\n", a->id);
.
## diffname pc/devastar.c 1998/0825
## diff -e /n/emeliedump/1998/0813/sys/src/brazil/pc/devastar.c /n/emeliedump/1998/0825/sys/src/brazil/pc/devastar.c
1134c
print("16K: %8.8luX %2.2uX\n", inl(a->port+PCIremap), *p);
.
1131c
print(" 0K: %8.8luX %2.2uX\n", inl(a->port+PCIremap), *p);
.
1128c
print("64K: %8.8luX %2.2uX\n", inl(a->port+PCIremap), *p);
.
1124c
print(" 0K: %8.8luX %2.2uX\n", inl(a->port+PCIremap), *p);
.
1121c
print(" 0K: %8.8luX %2.2uX\n", inl(a->port+PCIremap), *p);
.
1118c
print("16K: %8.8luX %2.2uX\n", inl(a->port+PCIremap), *p);
.
1114c
print(" 0K: %8.8luX %2.2uX\n", inl(a->port+PCIremap), *p);
.
742c
sprint(s, "range %luX remap %luX region %luX mailbox %luX doorbell0 %luX doorbell1 %luX control %luX command %luX",
.
548c
print("#G%d: bad irq %lud\n", a->id, a->irq);
.
498c
print("#G%d: %s port 0x%luX addr 0x%luX irq %lud\n",
.
321c
print("#G%d: setpage caller pc %luX\n", a->id, getcallerpc(a));
.
## diffname pc/devastar.c 1998/0910
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/pc/devastar.c /n/emeliedump/1998/0910/sys/src/brazil/pc/devastar.c
1063c
intrenable(a->irq, astarintr, a, BUSUNKNOWN);
.
1056c
intrenable(a->irq, astarintr, a, a->pci->tbdf);
.
## diffname pc/devastar.c 1998/0926
## diff -e /n/emeliedump/1998/0910/sys/src/brazil/pc/devastar.c /n/emeliedump/1998/0926/sys/src/brazil/pc/devastar.c
1092,1136d
## diffname pc/devastar.c 1999/0315
## diff -e /n/emeliedump/1998/0926/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/0315/sys/src/brazil/pc/devastar.c
1605a
ac++;
}
ac = a->c;
for(vec = mvec; vec; vec >>= 1){
if(vec&1)
astarmodemchange(ac);
.
1574d
1545a
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;
}
.
1186a
ac->dsr = ac->dcd = 0;
.
788a
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" : ""
);
.
772,787c
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",
.
769a
fstat = LEUS(ac->ccb->format);
.
764,765c
char s[256];
int mstat, bstat, fstat;
.
282a
int dsr; /* non-zero means dsr on */
int dcd; /* non-zero means dcd on */
.
280a
int hup_dsr; /* hangup when dsr goes away */
int hup_dcd; /* hangup when dcd goes away */
.
## diffname pc/devastar.c 1999/0501
## diff -e /n/emeliedump/1999/0315/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/0501/sys/src/brazil/pc/devastar.c
325c
print("#G%d: setpage caller pc %luX\n", a->id, getcallerpc(&a));
.
## diffname pc/devastar.c 1999/0629
## diff -e /n/emeliedump/1999/0501/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/0629/sys/src/brazil/pc/devastar.c
1551a
Astarchan *ac;
ac = v;
.
1550c
astarkickin(void *v)
.
1495a
Astarchan *ac;
ac = v;
.
1494c
astarkick(void *v)
.
1214c
tsleep(&ac->r, (int (*)(void*))qlen, ac->oq, 125);
.
310,311c
static void astarkick(void*);
static void astarkickin(void*);
.
## diffname pc/devastar.c 1999/0714
## diff -e /n/emeliedump/1999/0629/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/0714/sys/src/brazil/pc/devastar.c
552a
iofree(a->port);
.
546a
iofree(a->port);
.
544a
}
.
543c
else {
sprint(name, "astar%d", a->id);
if(ioalloc(a->port, 6, 0, name) < 0){
print("#G%d: port 0x%lux in use\n", a->id, a->port);
return -1;
}
.
536a
sprint(name, "astar%d", a->id);
if(ioalloc(a->port, 6, 0, name) < 0)
continue;
.
530a
char name[8];
.
458a
sprint(name, "astar%d", i);
if(ioalloc(a->port, p->mem[2].size, 0, name) < 0){
print("#G%d: port 0x%lux in use", a->id, a->port);
xfree(a);
astar[nastar] = 0;
continue;
}
.
415a
char name[8];
.
## diffname pc/devastar.c 1999/0721
## diff -e /n/emeliedump/1999/0714/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/0721/sys/src/brazil/pc/devastar.c
461,462c
if(ioalloc(a->port, p->mem[1].size, 0, name) < 0){
print("#G%d: port 0x%lux in use\n", a->id, a->port);
.
## diffname pc/devastar.c 1999/0801
## diff -e /n/emeliedump/1999/0721/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/0801/sys/src/brazil/pc/devastar.c
376a
db->length = qlen(astar[dev]->c[ch].iq);
.
## diffname pc/devastar.c 1999/0819
## diff -e /n/emeliedump/1999/0801/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/0819/sys/src/brazil/pc/devastar.c
1095c
intrenable(a->irq, astarintr, a, BUSUNKNOWN, name);
.
1088c
intrenable(a->irq, astarintr, a, a->pci->tbdf, name);
.
1081a
snprint(name, sizeof name, "astar%d", a->id);
.
979a
char name[10];
.
## diffname pc/devastar.c 1999/1230
## diff -e /n/emeliedump/1999/0819/sys/src/brazil/pc/devastar.c /n/emeliedump/1999/1230/sys/src/9/pc/devastar.c
349a
if(i == DEVDOTDOT){
devdir(c, (Qid){CHDIR, 0}, "#G", 0, eve, 0555, db);
return 1;
}
.
## diffname pc/devastar.c 2000/0606
## diff -e /n/emeliedump/1999/1230/sys/src/9/pc/devastar.c /n/emeliedump/2000/0606/sys/src/9/pc/devastar.c
435c
if(cistrcmp(a->type, "a100i") == 0)
.
## diffname pc/devastar.c 2001/0503
## diff -e /n/emeliedump/2000/0606/sys/src/9/pc/devastar.c /n/emeliedump/2001/0503/sys/src/9/pc/devastar.c
692d
682,685d
## diffname pc/devastar.c 2001/0527
## diff -e /n/emeliedump/2001/0503/sys/src/9/pc/devastar.c /n/emeliedump/2001/0527/sys/src/9/pc/devastar.c
687a
poperror();
.
681a
if(waserror()){
qunlock(ac);
nexterror();
}
.
## diffname pc/devastar.c 2001/1106 # deleted
## diff -e /n/emeliedump/2001/0527/sys/src/9/pc/devastar.c /n/emeliedump/2001/1106/sys/src/9/pc/devastar.c
1,1687d
|