## 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<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<>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