| plan 9 kernel history: overview | file list | diff list |
1998/0825/pc/devastar.c (diff list | history)
| 1994/1106/sys/src/9/pc/devastar.c:10,20 – 1994/1107/sys/src/9/pc/devastar.c:10,20 (short | long) | ||
|
Still writing driver.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1994/1106 | #include "../port/netif.h" /* | |
| 1994/1107 | * Stargate's Avanstar serial board. There are ISA, EISA, microchannel * versions. We only handle the ISA one. | |
| 1994/1106 | */ typedef struct Astar Astar; | |
| 1994/1107 | typedef struct Astarchan Astarchan; | |
| 1994/1106 | enum { | |
| 1994/1106/sys/src/9/pc/devastar.c:24,42 – 1994/1107/sys/src/9/pc/devastar.c:24,53 | ||
| 1994/1106 | ISAid1= 0x13, ISActl1= 1, /* board control */ ISAien= 1<<7, /* interrupt enable */ | |
| 1994/1107 | ISAirq= 7<<4, /* mask for irq code */ | |
| 1994/1106 | 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 */ | |
| 1994/1107 | 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 */ | |
| 1994/1106 | ISAstat1= 4, /* board status (1 bit per channel) */ ISAstat2= 5, /* board status (1 bit per channel) */ | |
| 1994/1107 | Maxcards= 3, | |
| 1994/1106 | }; | |
| 1994/1107 | /* 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, }; | |
| 1994/1106 | /* control program global control block */ typedef struct GCB GCB; struct GCB | |
| 1994/1106/sys/src/9/pc/devastar.c:59,64 – 1994/1107/sys/src/9/pc/devastar.c:70,107 | ||
| 1994/1106 | ushort cmdserv; /* channel command service request 'X' */ }; | |
| 1994/1107 | 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), }; | |
| 1994/1106 | /* control program channel control block */ typedef struct CCB CCB; struct CCB | |
| 1994/1106/sys/src/9/pc/devastar.c:65,76 – 1994/1107/sys/src/9/pc/devastar.c:108,119 | ||
| 1994/1106 | { ushort baud; /* baud rate */ ushort format; /* data format */ | |
| 1994/1107 | ushort proto; /* line protocol */ | |
| 1994/1106 | ushort insize; /* input buffer size */ ushort outsize; /* output buffer size */ ushort intrigger; /* input buffer trigger rate */ ushort outlow; /* output buffer low water mark */ | |
| 1994/1107 | char xon[2]; /* xon characters */ | |
| 1994/1106 | ushort inhigh; /* input buffer high water mark */ ushort inlow; /* input buffer low water mark */ ushort cmd; /* channel command */ | |
| 1994/1106/sys/src/9/pc/devastar.c:89,103 – 1994/1107/sys/src/9/pc/devastar.c:132,221 | ||
| 1994/1106 | ushort mstat; /* modem status */ ushort bstat; /* blocking status */ ushort rflag; /* character received flag */ | |
| 1994/1107 | char xoff[2]; /* xoff characters */ | |
| 1994/1106 | ushort status2; | |
| 1994/1107 | char strip[2]; /* strip/error characters */ | |
| 1994/1106 | }; | |
| 1994/1107 | 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 */ }; | |
| 1994/1106 | /* host per controller info */ struct Astar { | |
| 1994/1107 | ISAConf; int id; /* from plan9.ini */ int ramsize; /* 16k or 256k */ | |
| 1994/1106 | GCB *gbc; /* board comm area */ Astarchan *c; /* channels */ }; | |
| 1994/1106/sys/src/9/pc/devastar.c:107,114 – 1994/1107/sys/src/9/pc/devastar.c:225,234 | ||
| 1994/1106 | { QLock; | |
| 1994/1107 | CCB *ccb; /* control block */ | |
| 1994/1106 | /* buffers */ | |
| 1994/1107 | ||
| 1994/1106 | Queue *iq; Queue *oq; | |
| 1994/1106/sys/src/9/pc/devastar.c:123,145 – 1994/1107/sys/src/9/pc/devastar.c:243,286 | ||
| 1994/1106 | uchar *oe; }; | |
| 1994/1107 | Astar *a[Maxcard]; int astarsetup(Astar*); | |
| 1994/1106 | void | |
| 1994/1107 | astarreset(void) | |
| 1994/1106 | { int i; | |
| 1994/1107 | Astar *a; | |
| 1994/1106 | Dirtab *dp; for(i = 0; i < Maxcard; i++){ | |
| 1994/1107 | a = astar[i] = xalloc(sizeof(Astar)); if(isaconfig("serial", i, &a) == 0){ xfree(a); astar[i] = 0; | |
| 1994/1106 | break; } | |
| 1994/1107 | 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; } } | |
| 1994/1106 | ndir = 3*nuart; ns16552dir = xalloc(ndir * sizeof(Dirtab)); dp = ns16552dir; | |
| 1994/1106/sys/src/9/pc/devastar.c:158,161 – 1994/1107/sys/src/9/pc/devastar.c:299,360 | ||
| 1994/1106 | dp->perm = 0444; dp++; } | |
| 1994/1107 | } 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)); | |
| 1994/1106 | } | |
| 1994/1107/sys/src/9/pc/devastar.c:228,234 – 1994/1108/sys/src/9/pc/devastar.c:228,233 (short | long) | ||
|
Change default memory location.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1994/1107 | CCB *ccb; /* control block */ | |
| 1994/1106 | /* buffers */ | |
| 1994/1107 | ||
| 1994/1106 | Queue *iq; Queue *oq; | |
| 1994/1107/sys/src/9/pc/devastar.c:268,275 – 1994/1108/sys/src/9/pc/devastar.c:267,275 | ||
| 1994/1107 | a->ramsize = 256*1024; else continue; | |
| 1994/1108 | ||
| 1994/1107 | if(a->mem == 0) | |
| 1994/1108 | a->mem = 0xD4000; | |
| 1994/1107 | if(a->irq == 0) a->irq = 15; a->id = i; | |
| 1994/1108/sys/src/9/pc/devastar.c:225,230 – 1994/1109/sys/src/9/pc/devastar.c:225,231 (short | long) | ||
| 1994/1106 | { QLock; | |
| 1994/1109 | Astar *a; /* controller */ | |
| 1994/1107 | CCB *ccb; /* control block */ | |
| 1994/1106 | /* buffers */ | |
| 1994/1108/sys/src/9/pc/devastar.c:242,250 – 1994/1109/sys/src/9/pc/devastar.c:243,252 | ||
| 1994/1106 | uchar *oe; }; | |
| 1994/1107 |
| |
| 1994/1109 | Astar *astar[Maxcard]; int nastar; | |
| 1994/1107 |
| |
| 1994/1109 | static int astarsetup(Astar*); | |
| 1994/1107 | ||
| 1994/1106 | void | |
| 1994/1107 | astarreset(void) | |
| 1994/1108/sys/src/9/pc/devastar.c:254,263 – 1994/1109/sys/src/9/pc/devastar.c:256,265 | ||
| 1994/1106 | Dirtab *dp; for(i = 0; i < Maxcard; i++){ | |
| 1994/1107 |
| |
| 1994/1109 | a = astar[nastar] = xalloc(sizeof(Astar)); | |
| 1994/1107 | if(isaconfig("serial", i, &a) == 0){ xfree(a); | |
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1106 | break; } | |
| 1994/1108/sys/src/9/pc/devastar.c:276,284 – 1994/1109/sys/src/9/pc/devastar.c:278,287 | ||
| 1994/1107 | if(astarsetup(a) < 0){ xfree(a); | |
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1107 | continue; } | |
| 1994/1109 | nastar++; | |
| 1994/1107 | } | |
| 1994/1106 | ndir = 3*nuart; | |
| 1994/1108/sys/src/9/pc/devastar.c:306,316 – 1994/1109/sys/src/9/pc/devastar.c:309,319 | ||
| 1994/1107 | { } | |
| 1994/1109 | /* isa ports an ax00i can appear at */ int isaport[] = { 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 }; | |
| 1994/1107 |
| |
| 1994/1109 | static int astarprobe(int port) | |
| 1994/1107 | { uchar c, c1; | |
| 1994/1108/sys/src/9/pc/devastar.c:323,329 – 1994/1109/sys/src/9/pc/devastar.c:326,332 | ||
| 1994/1107 | || (c == ISAid1 && c1 == ISAid0)); } | |
| 1994/1109 | static int | |
| 1994/1107 | astarsetup(Astar *a) { int i, j, found; | |
| 1994/1108/sys/src/9/pc/devastar.c:333,339 – 1994/1109/sys/src/9/pc/devastar.c:336,342 | ||
| 1994/1107 | if(a->port == 0) for(i = 0; isaport[i]; i++){ a->port = isaport[i]; | |
| 1994/1109 | found = astarprobe(isaport[i]); | |
| 1994/1107 | if(found){ isaport[i] = -1; break; | |
| 1994/1108/sys/src/9/pc/devastar.c:357,360 – 1994/1109/sys/src/9/pc/devastar.c:360,365 | ||
| 1994/1107 | } c = inb(a->port + ISActl1) & ~ISAirq; outb(a->port + ISActl1, c | isairqcode(a->irq)); | |
| 1994/1109 | return 0; | |
| 1994/1106 | } | |
| 1994/1109/sys/src/9/pc/devastar.c:7,13 – 1994/1111/sys/src/9/pc/devastar.c:7,12 (short | long) | ||
| 1994/1106 | #include "../port/error.h" #include "devtab.h" | |
| 1994/1107 | * Stargate's Avanstar serial board. There are ISA, EISA, microchannel | |
| 1994/1109/sys/src/9/pc/devastar.c:215,223 – 1994/1111/sys/src/9/pc/devastar.c:214,223 | ||
| 1994/1106 | { | |
| 1994/1107 | ISAConf; int id; /* from plan9.ini */ | |
| 1994/1111 | int nchan; /* number of channels */ Astarchan *c; /* channels */ | |
| 1994/1107 | int ramsize; /* 16k or 256k */ | |
| 1994/1106 | GCB *gbc; /* board comm area */ | |
| 1994/1109/sys/src/9/pc/devastar.c:227,253 – 1994/1111/sys/src/9/pc/devastar.c:227,315 | ||
| 1994/1106 | ||
| 1994/1109 | Astar *a; /* controller */ | |
| 1994/1107 | CCB *ccb; /* control block */ | |
| 1994/1111 | int perm; | |
| 1994/1107 | ||
| 1994/1106 | /* buffers */ Queue *iq; Queue *oq; | |
| 1994/1109 | Astar *astar[Maxcard]; | |
| 1994/1111 | static int nastar; | |
| 1994/1107 | ||
| 1994/1111 | 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)) | |
| 1994/1109 | static int astarsetup(Astar*); | |
| 1994/1107 | ||
| 1994/1111 | 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; } | |
| 1994/1106 | void | |
| 1994/1107 | astarreset(void) | |
| 1994/1106 | { | |
| 1994/1109/sys/src/9/pc/devastar.c:283,314 – 1994/1111/sys/src/9/pc/devastar.c:345,352 | ||
| 1994/1107 | } | |
| 1994/1109 | nastar++; | |
| 1994/1107 | } | |
| 1994/1106 |
| |
| 1994/1107 | } | |
| 1994/1109 | /* isa ports an ax00i can appear at */ int isaport[] = { 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 }; | |
| 1994/1107 | ||
| 1994/1109/sys/src/9/pc/devastar.c:360,365 – 1994/1111/sys/src/9/pc/devastar.c:398,488 | ||
| 1994/1107 | } c = inb(a->port + ISActl1) & ~ISAirq; outb(a->port + ISActl1, c | isairqcode(a->irq)); | |
| 1994/1111 | 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); } | |
| 1994/1109 | return 0; | |
| 1994/1106 | } | |
| 1994/1111/sys/src/9/pc/devastar.c:35,41 – 1994/1112/sys/src/9/pc/devastar.c:35,44 (short | long) | ||
| 1994/1106 | ISAstat1= 4, /* board status (1 bit per channel) */ ISAstat2= 5, /* board status (1 bit per channel) */ | |
| 1994/1107 |
| |
| 1994/1112 | Maxcard= 8, Pramsize= 64*1024, /* size of program ram */ Footshift= 14, /* footprint of card mem in ISA space */ Footprint= 1<<Footshift, | |
| 1994/1106 | }; | |
| 1994/1107 | /* IRQ codes */ | |
| 1994/1111/sys/src/9/pc/devastar.c:191,197 – 1994/1112/sys/src/9/pc/devastar.c:194,200 | ||
| 1994/1107 | /* CCB.mctl fields */ Cdtrctl= 1<<0, Crtsctl= 1<<1, | |
| 1994/1112 | Cbreakctl= 1<<4, | |
| 1994/1107 | /* CCB.mstat fields */ | |
| 1994/1111/sys/src/9/pc/devastar.c:212,223 – 1994/1112/sys/src/9/pc/devastar.c:215,230 | ||
| 1994/1106 | /* host per controller info */ struct Astar { | |
| 1994/1112 | QLock; | |
| 1994/1107 | ISAConf; int id; /* from plan9.ini */ | |
| 1994/1111 | int nchan; /* number of channels */ | |
| 1994/1112 | Rendez r; | |
| 1994/1111 | Astarchan *c; /* channels */ | |
| 1994/1107 | int ramsize; /* 16k or 256k */ | |
| 1994/1106 | GCB *gbc; /* board comm area */ | |
| 1994/1112 | char *addr; /* memory area */ | |
| 1994/1106 | }; /* host per channel info */ | |
| 1994/1111/sys/src/9/pc/devastar.c:228,233 – 1994/1112/sys/src/9/pc/devastar.c:235,241 | ||
| 1994/1109 | Astar *a; /* controller */ | |
| 1994/1107 | CCB *ccb; /* control block */ | |
| 1994/1111 | int perm; | |
| 1994/1112 | int opens; | |
| 1994/1107 | ||
| 1994/1106 | /* buffers */ Queue *iq; | |
| 1994/1111/sys/src/9/pc/devastar.c:240,245 – 1994/1112/sys/src/9/pc/devastar.c:248,254 | ||
| 1994/1111 | enum { Qmem= 0, | |
| 1994/1112 | Qbctl, | |
| 1994/1111 | Qdata, Qctl, Qstat, | |
| 1994/1111/sys/src/9/pc/devastar.c:252,273 – 1994/1112/sys/src/9/pc/devastar.c:261,292 | ||
| 1994/1109 | static int astarsetup(Astar*); | |
| 1994/1107 | ||
| 1994/1111 | int | |
| 1994/1112 | astargen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db) | |
| 1994/1111 | { int dev, sofar, ch, t; | |
| 1994/1112 | extern ulong kerndate; | |
| 1994/1111 | USED(tab, ntab); sofar = 0; | |
| 1994/1112 | for(dev = 0; dev < nastar; dev++){ | |
| 1994/1111 | if(sofar == i){ | |
| 1994/1112 | sprint(db->name, "atar%dmem", astar[dev]->id); db->qid.path = QID(dev, 0, Qmem); | |
| 1994/1111 | db->mode = 0660; break; } | |
| 1994/1112 | sofar++; | |
| 1994/1111 |
| |
| 1994/1112 | 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){ | |
| 1994/1111 | i -= sofar; ch = i/3; t = i%3; | |
| 1994/1111/sys/src/9/pc/devastar.c:275,305 – 1994/1112/sys/src/9/pc/devastar.c:294,324 | ||
| 1994/1111 | case 0: sprint(db->name, "eia%d%2.2d", dev, ch); db->mode = astar[dev]->c[ch].perm; | |
| 1994/1112 | db->qid.path = QID(dev, 0, Qdata); | |
| 1994/1111 | break; case 1: sprint(db->name, "eia%d%2.2dctl", dev, ch); db->mode = astar[dev]->c[ch].perm; | |
| 1994/1112 | db->qid.path = QID(dev, 0, Qctl); | |
| 1994/1111 | break; case 2: sprint(db->name, "eia%d%2.2dstat", dev, ch); db->mode = 0444; | |
| 1994/1112 | db->qid.path = QID(dev, 0, Qstat); | |
| 1994/1111 | break; | |
| 1994/1112 | } | |
| 1994/1111 | break; } | |
| 1994/1112 | sofar += 3*astar[dev]->nchan; | |
| 1994/1111 | } | |
| 1994/1112 | if(dev == nastar) | |
| 1994/1111 | return -1; db->atime = seconds(); db->mtime = kerndate; db->hlength = 0; | |
| 1994/1112 | db->length = 0; /* update ???? */ | |
| 1994/1111 | memmove(db->uid, eve, NAMELEN); memmove(db->gid, eve, NAMELEN); db->type = devchar[c->type]; | |
| 1994/1111/sys/src/9/pc/devastar.c:315,325 – 1994/1112/sys/src/9/pc/devastar.c:334,343 | ||
| 1994/1106 | { int i; | |
| 1994/1107 | Astar *a; | |
| 1994/1106 |
| |
| 1994/1109 | a = astar[nastar] = xalloc(sizeof(Astar)); | |
| 1994/1107 |
| |
| 1994/1112 | if(isaconfig("serial", i, a) == 0){ | |
| 1994/1107 | xfree(a); | |
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1106 | break; | |
| 1994/1111/sys/src/9/pc/devastar.c:343,348 – 1994/1112/sys/src/9/pc/devastar.c:361,367 | ||
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1107 | continue; } | |
| 1994/1112 | print("serial%d avanstar addr %lux irq %d\n", i, a->addr, a->irq); | |
| 1994/1109 | nastar++; | |
| 1994/1107 | } } | |
| 1994/1111/sys/src/9/pc/devastar.c:361,373 – 1994/1112/sys/src/9/pc/devastar.c:380,392 | ||
| 1994/1107 | c = inb(port + ISAid); c1 = inb(port + ISAid); return (c == ISAid0 && c1 == ISAid1) | |
| 1994/1112 | || (c == ISAid1 && c1 == ISAid0); | |
| 1994/1107 | } | |
| 1994/1109 | static int | |
| 1994/1107 | astarsetup(Astar *a) { | |
| 1994/1112 | int i, found; | |
| 1994/1107 | /* see if the card exists */ found = 0; | |
| 1994/1111/sys/src/9/pc/devastar.c:381,387 – 1994/1112/sys/src/9/pc/devastar.c:400,406 | ||
| 1994/1107 | } } else | |
| 1994/1112 | found = astarprobe(a->port); | |
| 1994/1107 | if(!found){ print("avanstar %d not found\n", a->id); return -1; | |
| 1994/1111/sys/src/9/pc/devastar.c:389,403 – 1994/1112/sys/src/9/pc/devastar.c:408,421 | ||
| 1994/1107 | /* set memory address */ outb(a->port + ISAmaddr, (a->mem>>12) & 0xfc); | |
| 1994/1112 | a->gbc = (GCB*)(KZERO | a->mem); a->addr = (char*)(KZERO | a->mem); | |
| 1994/1107 | /* set interrupt level */ | |
| 1994/1112 | if(isairqcode[a->irq] == -1){ | |
| 1994/1107 | print("Avanstar %d bad irq %d\n", a->id, a->irq); return -1; } | |
| 1994/1111 | return 0; } | |
| 1994/1111/sys/src/9/pc/devastar.c:434,463 – 1994/1112/sys/src/9/pc/devastar.c:452,510 | ||
| 1994/1111 | Chan* astaropen(Chan *c, int omode) { | |
| 1994/1112 | Astar *a; | |
| 1994/1111 | c = devopen(c, omode, 0, 0, astargen); | |
| 1994/1112 | switch(TYPE(c->qid.path)){ case Qmem: case Qbctl: if(!iseve()) error(Eperm); break; } | |
| 1994/1111 | return c; } void | |
| 1994/1112 | 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; } | |
| 1994/1111 | } long astarread(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1112 | int i; | |
| 1994/1111 | Astar *a; | |
| 1994/1112 | char *to, *from, *e; char status[128]; | |
| 1994/1111 | if(c->qid.path & CHDIR) return devdirread(c, buf, n, 0, 0, astargen); | |
| 1994/1111/sys/src/9/pc/devastar.c:464,471 – 1994/1112/sys/src/9/pc/devastar.c:511,556 | ||
| 1994/1111 | switch(TYPE(c->qid.path)){ case Qmem: | |
| 1994/1112 | 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; | |
| 1994/1111 | } return 0; | |
| 1994/1111/sys/src/9/pc/devastar.c:474,480 – 1994/1112/sys/src/9/pc/devastar.c:559,568 | ||
| 1994/1111 | long astarwrite(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1112 | Astar *a; char *to, *from, *e; int i; char cmsg[32]; | |
| 1994/1111 | if(c->qid.path & CHDIR) error(Eperm); | |
| 1994/1111/sys/src/9/pc/devastar.c:481,488 – 1994/1112/sys/src/9/pc/devastar.c:569,666 | ||
| 1994/1111 | switch(TYPE(c->qid.path)){ case Qmem: | |
| 1994/1112 | 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; | |
| 1994/1111 | } | |
| 1994/1109 | return 0; | |
| 1994/1112 | } 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); | |
| 1994/1106 | } | |
| 1994/1112/sys/src/9/pc/devastar.c:11,17 – 1994/1113/sys/src/9/pc/devastar.c:11,30 (short | long) | ||
| 1994/1106 | /* | |
| 1994/1107 | * Stargate's Avanstar serial board. There are ISA, EISA, microchannel * versions. We only handle the ISA one. | |
| 1994/1113 | * * 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. | |
| 1994/1106 | */ | |
| 1994/1113 | #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 | |
| 1994/1106 | typedef struct Astar Astar; | |
| 1994/1107 | typedef struct Astarchan Astarchan; | |
| 1994/1106 | ||
| 1994/1112/sys/src/9/pc/devastar.c:37,46 – 1994/1113/sys/src/9/pc/devastar.c:50,62 | ||
| 1994/1107 | ||
| 1994/1112 | Maxcard= 8, Pramsize= 64*1024, /* size of program ram */ | |
| 1994/1113 | Pageshift= 14, /* footprint of card mem in ISA space */ Pagesize= 1<<Pageshift, Pagemask= Pagesize-1, | |
| 1994/1106 | }; | |
| 1994/1113 | #define APAGE(x) ((x)>>Pageshift) | |
| 1994/1107 | /* IRQ codes */ static int isairqcode[16] = { | |
| 1994/1112/sys/src/9/pc/devastar.c:60,68 – 1994/1113/sys/src/9/pc/devastar.c:76,84 | ||
| 1994/1106 | ushort avail; /* available buffer space */ ushort type; /* board type */ ushort cpvers; /* control program version */ | |
| 1994/1113 | ushort ccbn; /* control channel block count */ ushort ccboff; /* control channel block offset */ ushort ccbsz; /* control channel block size */ | |
| 1994/1106 | ushort cmd2; /* command word 2 */ ushort status2; /* status word 2 */ ushort errserv; /* comm error service request 'X' */ | |
| 1994/1112/sys/src/9/pc/devastar.c:146,155 – 1994/1113/sys/src/9/pc/devastar.c:162,168 | ||
| 1994/1107 | Cb115200= 0xff01, /* CCB.format fields */ | |
| 1994/1113 | Clenmask= 3<<0, /* data bits */ | |
| 1994/1107 | C1stop= 0<<2, /* stop bits */ C2stop= 1<<2, Cnopar= 0<<3, /* parity */ | |
| 1994/1112/sys/src/9/pc/devastar.c:157,162 – 1994/1113/sys/src/9/pc/devastar.c:170,176 | ||
| 1994/1107 | Cevenpar= 3<<3, Cmarkpar= 5<<3, Cspacepar= 7<<3, | |
| 1994/1113 | Cparmask= 7<<3, | |
| 1994/1107 | Cnormal= 0<<6, /* normal mode */ Cecho= 1<<6, /* echo mode */ Clloop= 2<<6, /* local loopback */ | |
| 1994/1112/sys/src/9/pc/devastar.c:220,230 – 1994/1113/sys/src/9/pc/devastar.c:234,248 | ||
| 1994/1107 | ISAConf; int id; /* from plan9.ini */ | |
| 1994/1111 | int nchan; /* number of channels */ | |
| 1994/1112 |
| |
| 1994/1111 | Astarchan *c; /* channels */ | |
| 1994/1107 | int ramsize; /* 16k or 256k */ | |
| 1994/1106 |
| |
| 1994/1112 |
| |
| 1994/1113 | 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 */ | |
| 1994/1106 | }; /* host per channel info */ | |
| 1994/1112/sys/src/9/pc/devastar.c:233,239 – 1994/1113/sys/src/9/pc/devastar.c:251,257 | ||
| 1994/1106 | QLock; | |
| 1994/1109 | Astar *a; /* controller */ | |
| 1994/1107 |
| |
| 1994/1113 | CCB *ccb; /* channel control block */ | |
| 1994/1111 | int perm; | |
| 1994/1112 | int opens; | |
| 1994/1107 | ||
| 1994/1112/sys/src/9/pc/devastar.c:240,245 – 1994/1113/sys/src/9/pc/devastar.c:258,264 | ||
| 1994/1106 | /* buffers */ Queue *iq; Queue *oq; | |
| 1994/1113 | Rendez r; | |
| 1994/1106 | }; | |
| 1994/1109 | Astar *astar[Maxcard]; | |
| 1994/1112/sys/src/9/pc/devastar.c:260,265 – 1994/1113/sys/src/9/pc/devastar.c:279,302 | ||
| 1994/1111 | ||
| 1994/1109 | static int astarsetup(Astar*); | |
| 1994/1107 | ||
| 1994/1113 | /* * 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 */ | |
| 1994/1111 | int | |
| 1994/1112 | astargen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db) | |
| 1994/1111 | { | |
| 1994/1112/sys/src/9/pc/devastar.c:355,360 – 1994/1113/sys/src/9/pc/devastar.c:392,398 | ||
| 1994/1107 | if(a->irq == 0) a->irq = 15; a->id = i; | |
| 1994/1113 | a->page = -1; | |
| 1994/1107 | if(astarsetup(a) < 0){ xfree(a); | |
| 1994/1112/sys/src/9/pc/devastar.c:377,384 – 1994/1113/sys/src/9/pc/devastar.c:415,422 | ||
| 1994/1107 | if(port < 0) return 0; | |
| 1994/1113 | c = inb(port+ISAid); c1 = inb(port+ISAid); | |
| 1994/1107 | return (c == ISAid0 && c1 == ISAid1) | |
| 1994/1112 | || (c == ISAid1 && c1 == ISAid0); | |
| 1994/1107 | } | |
| 1994/1112/sys/src/9/pc/devastar.c:407,413 – 1994/1113/sys/src/9/pc/devastar.c:445,451 | ||
| 1994/1107 | } /* set memory address */ | |
| 1994/1113 | outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc); | |
| 1994/1112 | a->gbc = (GCB*)(KZERO | a->mem); a->addr = (char*)(KZERO | a->mem); | |
| 1994/1107 | ||
| 1994/1112/sys/src/9/pc/devastar.c:479,496 – 1994/1113/sys/src/9/pc/devastar.c:517,534 | ||
| 1994/1112 | qlock(a); if(--a->opens == 0){ /* take board out of download mode and enable IRQ */ | |
| 1994/1113 | outb(a->port+ISActl1, ISAien|isairqcode[a->irq]); | |
| 1994/1112 | /* enable ISA access to first 16k */ | |
| 1994/1113 | outb(a->port+ISActl2, ISAmen|0); | |
| 1994/1112 | /* wait for program ready */ for(i = 0; i < 21; i++){ | |
| 1994/1113 | if(inb(a->port+ISActl1) & ISApr) | |
| 1994/1112 | break; tsleep(&r, return0, 0, 500); } | |
| 1994/1113 | if((inb(a->port+ISActl1) & ISApr) == 0) | |
| 1994/1112 | print("astar%d program not ready\n", a->id); } qunlock(a); | |
| 1994/1112/sys/src/9/pc/devastar.c:498,510 – 1994/1113/sys/src/9/pc/devastar.c:536,595 | ||
| 1994/1112 | } | |
| 1994/1111 | } | |
| 1994/1113 | 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); } | |
| 1994/1111 | long astarread(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1112 |
| |
| 1994/1111 |
| |
| 1994/1112 |
| |
| 1994/1111 | if(c->qid.path & CHDIR) return devdirread(c, buf, n, 0, 0, astargen); | |
| 1994/1112/sys/src/9/pc/devastar.c:511,644 – 1994/1113/sys/src/9/pc/devastar.c:596,897 | ||
| 1994/1111 | switch(TYPE(c->qid.path)){ case Qmem: | |
| 1994/1112 |
| |
| 1994/1113 | return memread(astar[BOARD(c->qid.path)], buf, n, offset); case Qbctl: return bctlread(astar[BOARD(c->qid.path)], buf, n, offset); } | |
| 1994/1112 |
| |
| 1994/1113 | return 0; } | |
| 1994/1112 |
| |
| 1994/1113 | 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); | |
| 1994/1112 | } | |
| 1994/1113 | } /* 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()){ | |
| 1994/1112 | qunlock(a); | |
| 1994/1113 | 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; | |
| 1994/1112 | break; | |
| 1994/1113 | case 'D': case 'd': | |
| 1994/1112 | break; | |
| 1994/1113 | 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; | |
| 1994/1111 | } | |
| 1994/1113 | ||
| 1994/1111 | long astarwrite(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1112 | Astar *a; | |
| 1994/1113 | Astarchan *ac; | |
| 1994/1112 | char cmsg[32]; | |
| 1994/1111 | if(c->qid.path & CHDIR) error(Eperm); | |
| 1994/1113 | a = astar[BOARD(c->qid.path)]; | |
| 1994/1111 | switch(TYPE(c->qid.path)){ case Qmem: | |
| 1994/1112 |
| |
| 1994/1113 | return memwrite(a, buf, n, offset); | |
| 1994/1112 | case Qbctl: if(n > sizeof cmsg) n = sizeof(cmsg) - 1; memmove(cmsg, buf, n); cmsg[n] = 0; | |
| 1994/1113 | 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); | |
| 1994/1111 | } | |
| 1994/1109 | return 0; | |
| 1994/1112/sys/src/9/pc/devastar.c:664,666 – 1994/1113/sys/src/9/pc/devastar.c:917,920 | ||
| 1994/1112 | USED(c, dp); error(Eperm); | |
| 1994/1106 | } | |
| 1994/1113 | ||
| 1994/1113/sys/src/9/pc/devastar.c:107,112 – 1994/1114/sys/src/9/pc/devastar.c:107,115 (short | long) | ||
| 1994/1107 | G100e= 0xA, Gx00i= 0xC, | |
| 1994/1114 | /* GCB.cmd2 bit */ Gintack= 0x1, | |
| 1994/1107 | /* GCB.status2 bits */ Ghas232= (1<<0), Ghas422= (1<<1), | |
| 1994/1113/sys/src/9/pc/devastar.c:229,254 – 1994/1114/sys/src/9/pc/devastar.c:232,259 | ||
| 1994/1106 | /* host per controller info */ struct Astar { | |
| 1994/1112 |
| |
| 1994/1114 | QLock; /* lock for rendez */ Rendez r; /* waiting for command completion */ | |
| 1994/1112 | ||
| 1994/1107 | ISAConf; | |
| 1994/1114 | Lock pagelock; /* lock for setting page */ int page; /* page currently mapped */ | |
| 1994/1107 | int id; /* from plan9.ini */ | |
| 1994/1111 | int nchan; /* number of channels */ Astarchan *c; /* channels */ | |
| 1994/1107 | int ramsize; /* 16k or 256k */ | |
| 1994/1113 | int memsize; /* size of memory currently mapped */ | |
| 1994/1106 | }; /* host per channel info */ struct Astarchan { | |
| 1994/1114 | QLock; /* lock for rendez */ Rendez r; /* waiting for command completion */ | |
| 1994/1106 | ||
| 1994/1109 | Astar *a; /* controller */ | |
| 1994/1113 | CCB *ccb; /* channel control block */ | |
| 1994/1113/sys/src/9/pc/devastar.c:255,264 – 1994/1114/sys/src/9/pc/devastar.c:260,267 | ||
| 1994/1111 | int perm; | |
| 1994/1112 | int opens; | |
| 1994/1107 | ||
| 1994/1106 |
| |
| 1994/1113 |
| |
| 1994/1106 | }; | |
| 1994/1109 | Astar *astar[Maxcard]; | |
| 1994/1113/sys/src/9/pc/devastar.c:277,288 – 1994/1114/sys/src/9/pc/devastar.c:280,295 | ||
| 1994/1111 | #define CHAN(x) ((((x)&~CHDIR)>>8)&0xff) #define QID(b,c,t) (((b)<<16)|((c)<<8)|(t)) | |
| 1994/1109 |
| |
| 1994/1114 | static int astarsetup(Astar*); static void astarintr(Ureg*, void*); static void astarkick(Astarchan*); static void enable(Astarchan*); static void disable(Astarchan*); | |
| 1994/1107 | ||
| 1994/1113 | /* * Only 16k maps into ISA space */ | |
| 1994/1114 | static void | |
| 1994/1113 | setpage(Astar *a, ulong offset) { int i; | |
| 1994/1113/sys/src/9/pc/devastar.c:401,406 – 1994/1114/sys/src/9/pc/devastar.c:408,415 | ||
| 1994/1107 | } | |
| 1994/1112 | print("serial%d avanstar addr %lux irq %d\n", i, a->addr, a->irq); | |
| 1994/1109 | nastar++; | |
| 1994/1114 | setvec(Int0vec + a->irq, astarintr, a); | |
| 1994/1107 | } } | |
| 1994/1113/sys/src/9/pc/devastar.c:500,505 – 1994/1114/sys/src/9/pc/devastar.c:509,526 | ||
| 1994/1112 | if(!iseve()) error(Eperm); break; | |
| 1994/1114 | case Qdata: case Qctl: qlock(ac); if(waserror()){ qunlock(a); nexterror(); } if(ac->opens++ == 0) enable(ac); qunlock(ac); poperror(); break; | |
| 1994/1112 | } | |
| 1994/1111 | return c; | |
| 1994/1113/sys/src/9/pc/devastar.c:513,546 – 1994/1114/sys/src/9/pc/devastar.c:534,564 | ||
| 1994/1112 | switch(TYPE(c->qid.path)){ case Qmem: | |
| 1994/1113 |
| |
| 1994/1112 |
| |
| 1994/1113 |
| |
| 1994/1112 |
| |
| 1994/1113 |
| |
| 1994/1112 |
| |
| 1994/1113 |
| |
| 1994/1112 |
| |
| 1994/1114 | break; case Qdata: case Qctl: qlock(ac); if(waserror()){ qunlock(a); nexterror(); | |
| 1994/1112 | } | |
| 1994/1114 | if(--ac->opens == 0) disable(ac); qunlock(ac); poperror(); | |
| 1994/1112 | break; } | |
| 1994/1111 | } | |
| 1994/1114 | /* * read ISA mapped memory */ | |
| 1994/1113 | static long memread(Astar *a, uchar *to, long n, ulong offset) { | |
| 1994/1114 | uchar *from, *e, *tp; | |
| 1994/1113 | int i, rem; | |
| 1994/1114 | uchar tmp[256]; | |
| 1994/1113 | if(offset+n > a->memsize){ if(offset >= a->memsize) | |
| 1994/1113/sys/src/9/pc/devastar.c:548,579 – 1994/1114/sys/src/9/pc/devastar.c:566,602 | ||
| 1994/1113 | n = a->memsize - offset; } | |
| 1994/1114 | from = a->addr + i; | |
| 1994/1113 | i = Pagesize - i; if(i > rem) i = rem; | |
| 1994/1114 | 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); | |
| 1994/1113 | for(e = from + i; from < e;) | |
| 1994/1114 | *tp++ = *from++; iunlock(&a->pagelock); memmove(to, tmp, i); to += i; | |
| 1994/1113 | } | |
| 1994/1114 | /* * read ISA status */ | |
| 1994/1113 | static long bctlread(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1113/sys/src/9/pc/devastar.c:604,614 – 1994/1114/sys/src/9/pc/devastar.c:627,641 | ||
| 1994/1113 | return 0; } | |
| 1994/1112 | ||
| 1994/1114 | /* * write ISA mapped memory */ | |
| 1994/1113 | static long memwrite(Astar *a, uchar *from, long n, ulong offset) { | |
| 1994/1114 | uchar *to, *e, *tp; | |
| 1994/1113 | int i, rem; | |
| 1994/1114 | uchar tmp[256]; | |
| 1994/1113 | if(offset+n > a->memsize){ if(offset >= a->memsize) | |
| 1994/1113/sys/src/9/pc/devastar.c:616,660 – 1994/1114/sys/src/9/pc/devastar.c:643,677 | ||
| 1994/1113 | n = a->memsize - offset; } | |
| 1994/1114 | to = a->addr + i; | |
| 1994/1113 | i = Pagesize - i; if(i > rem) i = rem; | |
| 1994/1114 | if(i > sizeof tmp) i = sizeof tmp; | |
| 1994/1113 |
| |
| 1994/1114 | /* * 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); | |
| 1994/1113 | for(e = from + i; from < e;) | |
| 1994/1114 | *to++ = *tp++; iunlock(&a->pagelock); from += i; | |
| 1994/1113 | } | |
| 1994/1113/sys/src/9/pc/devastar.c:663,668 – 1994/1114/sys/src/9/pc/devastar.c:680,686 | ||
| 1994/1113 | int n, i, sz; uchar *x; CCB *ccb; | |
| 1994/1114 | Astarchan *ac; | |
| 1994/1113 | if(a->running) error(Eio); | |
| 1994/1113/sys/src/9/pc/devastar.c:682,687 – 1994/1114/sys/src/9/pc/devastar.c:700,710 | ||
| 1994/1113 | error(Eio); } | |
| 1994/1114 | if(waserror()){ iunlock(&a->pagelock); poperror(); } ilock(&a->pagelock); | |
| 1994/1113 | setpage(a, 0); i = LEUS(a->gcb->type); switch(i){ | |
| 1994/1113/sys/src/9/pc/devastar.c:712,717 – 1994/1114/sys/src/9/pc/devastar.c:735,742 | ||
| 1994/1113 | error(Eio); | |
| 1994/1112 | } | |
| 1994/1113 | } | |
| 1994/1114 | iunlock(&a->pagelock); poperror(); | |
| 1994/1113 | /* setup the channels */ a->running = 1; | |
| 1994/1113/sys/src/9/pc/devastar.c:718,724 – 1994/1114/sys/src/9/pc/devastar.c:743,753 | ||
| 1994/1113 | a->nchan = i; a->c = xalloc(a->nchan * sizeof(Astarchan)); for(i = 0; i < a->nchan; i++){ | |
| 1994/1114 | 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); | |
| 1994/1113 | x += sz; } } | |
| 1994/1113/sys/src/9/pc/devastar.c:761,773 – 1994/1114/sys/src/9/pc/devastar.c:790,894 | ||
| 1994/1113 | } /* | |
| 1994/1114 | * 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); } /* | |
| 1994/1113 | * change channel parameters | |
| 1994/1114 | * (must be called with ac qlocked) | |
| 1994/1113 | */ | |
| 1994/1114 | static void | |
| 1994/1113 | astarctl(Astarchan *ac, char *cmd) { int i, n; int command; | |
| 1994/1114 | CCB *ccb; Astar *a; | |
| 1994/1113 | /* let output drain for a while */ for(i = 0; i < 16 && qlen(ac->oq); i++) | |
| 1994/1113/sys/src/9/pc/devastar.c:776,795 – 1994/1114/sys/src/9/pc/devastar.c:897,920 | ||
| 1994/1113 | if(strncmp(cmd, "break", 5) == 0) cmd = "k"; | |
| 1994/1114 | ccb = ac->ccb; | |
| 1994/1113 | command = 0; | |
| 1994/1114 | i = atoi(cmd+1); a = ac->a; ilock(&a->pagelock); setpage(a, 0); | |
| 1994/1113 | switch(*cmd){ case 'B': case 'b': | |
| 1994/1114 | switch(i){ | |
| 1994/1113 | case 76800: | |
| 1994/1114 | ccb->baud = LEUS(Cb76800); | |
| 1994/1113 | break; case 115200: | |
| 1994/1114 | ccb->baud = LEUS(Cb115200); | |
| 1994/1113 | break; default: | |
| 1994/1114 | ccb->baud = LEUS(n); | |
| 1994/1113 | break; } command = Cconfall; | |
| 1994/1113/sys/src/9/pc/devastar.c:796,801 – 1994/1114/sys/src/9/pc/devastar.c:921,932 | ||
| 1994/1112 | break; | |
| 1994/1113 | case 'D': case 'd': | |
| 1994/1114 | n = LEUS(ccb->mctl); if(i) n |= Cdtrctl; else n &= ~Cdtrctl; ccb->mctl = LEUS(n); | |
| 1994/1112 | break; | |
| 1994/1113 | case 'f': case 'F': | |
| 1994/1113/sys/src/9/pc/devastar.c:811,824 – 1994/1114/sys/src/9/pc/devastar.c:942,965 | ||
| 1994/1113 | n -= 5; if(n < 0 || n > 3) error(Ebadarg); | |
| 1994/1114 | n |= LEUS(ccb->format) & ~Clenmask; ccb->format = LEUS(n); | |
| 1994/1113 | command = Cconfall; break; case 'm': case 'M': | |
| 1994/1114 | /* 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; | |
| 1994/1113 | command = Cconfall; break; case 'n': | |
| 1994/1113/sys/src/9/pc/devastar.c:838,852 – 1994/1114/sys/src/9/pc/devastar.c:979,1011 | ||
| 1994/1113 | n = Cnopar; break; } | |
| 1994/1114 | n |= LEUS(ccb->format) & ~Cparmask; ccb->format = LEUS(n); | |
| 1994/1113 | command = Cconfall; break; case 'K': case 'k': | |
| 1994/1114 | 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); | |
| 1994/1113 | break; case 'R': case 'r': | |
| 1994/1114 | n = LEUS(ccb->mctl); if(i) n |= Crtsctl; else n &= ~Crtsctl; ccb->mctl = LEUS(n); | |
| 1994/1113 | break; case 'Q': case 'q': | |
| 1994/1113/sys/src/9/pc/devastar.c:855,868 – 1994/1114/sys/src/9/pc/devastar.c:1014,1034 | ||
| 1994/1113 | break; case 'X': case 'x': | |
| 1994/1114 | n = LEUS(ccb->proto); if(i) n |= Cobeyxon; else n &= ~Cobeyxon; ccb->proto = LEUS(n); | |
| 1994/1113 | command = Cconfall; break; | |
| 1994/1111 | } | |
| 1994/1114 | iunlock(&a->pagelock); if(command) chancmd(ac, command); | |
| 1994/1111 | } | |
| 1994/1113 | ||
| 1994/1111 | long astarwrite(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1113/sys/src/9/pc/devastar.c:887,897 – 1994/1114/sys/src/9/pc/devastar.c:1053,1072 | ||
| 1994/1113 | ac = a->c + CHAN(c->qid.path); return qwrite(ac->oq, buf, n); case Qctl: | |
| 1994/1114 | ac = a->c + CHAN(c->qid.path); | |
| 1994/1113 | if(n > sizeof cmsg) n = sizeof(cmsg) - 1; memmove(cmsg, buf, n); cmsg[n] = 0; | |
| 1994/1114 | if(waserror()){ qunlock(ac); nexterror(); } qlock(ac); astarctl(ac, msg); qunlock(ac); poperror(); | |
| 1994/1111 | } | |
| 1994/1109 | return 0; | |
| 1994/1113/sys/src/9/pc/devastar.c:918,920 – 1994/1114/sys/src/9/pc/devastar.c:1093,1166 | ||
| 1994/1112 | error(Eperm); | |
| 1994/1106 | } | |
| 1994/1113 | ||
| 1994/1114 | /* * 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); } | |
| 1994/1114/sys/src/9/pc/devastar.c:37,43 – 1994/1115/sys/src/9/pc/devastar.c:37,43 (short | long) | ||
| 1994/1106 | ISActl1= 1, /* board control */ ISAien= 1<<7, /* interrupt enable */ | |
| 1994/1107 | ISAirq= 7<<4, /* mask for irq code */ | |
| 1994/1106 |
| |
| 1994/1115 | ISAnotdl= 1<<1, /* download bit (0 == download) */ | |
| 1994/1106 | ISApr= 1<<0, /* program ready */ ISActl2= 2, /* board control */ ISA186ien= 1<<7, /* I186 irq enable bit state */ | |
| 1994/1114/sys/src/9/pc/devastar.c:213,219 – 1994/1115/sys/src/9/pc/devastar.c:213,218 | ||
| 1994/1107 | Crtsctl= 1<<1, | |
| 1994/1112 | Cbreakctl= 1<<4, | |
| 1994/1107 |
| |
| 1994/1114/sys/src/9/pc/devastar.c:243,249 – 1994/1115/sys/src/9/pc/devastar.c:242,248 | ||
| 1994/1111 | Astarchan *c; /* channels */ | |
| 1994/1107 | int ramsize; /* 16k or 256k */ | |
| 1994/1113 | int memsize; /* size of memory currently mapped */ | |
| 1994/1115 | GCB *gcb; /* global board comm area */ | |
| 1994/1113 | uchar *addr; /* base of memory area */ int running; | |
| 1994/1114/sys/src/9/pc/devastar.c:285,290 – 1994/1115/sys/src/9/pc/devastar.c:284,290 | ||
| 1994/1114 | static void astarkick(Astarchan*); static void enable(Astarchan*); static void disable(Astarchan*); | |
| 1994/1115 | static void astarctl(Astarchan*, char*); | |
| 1994/1107 | ||
| 1994/1113 | /* * Only 16k maps into ISA space | |
| 1994/1114/sys/src/9/pc/devastar.c:310,329 – 1994/1115/sys/src/9/pc/devastar.c:310,332 | ||
| 1994/1111 | int dev, sofar, ch, t; | |
| 1994/1112 | extern ulong kerndate; | |
| 1994/1111 | ||
| 1994/1115 | memset(db, 0, sizeof(Dir)); | |
| 1994/1111 | USED(tab, ntab); sofar = 0; | |
| 1994/1112 | for(dev = 0; dev < nastar; dev++){ | |
| 1994/1111 | if(sofar == i){ | |
| 1994/1112 |
| |
| 1994/1115 | sprint(db->name, "astar%dmem", astar[dev]->id); | |
| 1994/1112 | db->qid.path = QID(dev, 0, Qmem); | |
| 1994/1111 | db->mode = 0660; | |
| 1994/1115 | db->length = astar[dev]->memsize; | |
| 1994/1111 | break; } | |
| 1994/1112 | sofar++; | |
| 1994/1111 | ||
| 1994/1112 | if(sofar == i){ | |
| 1994/1115 | sprint(db->name, "astar%dctl", astar[dev]->id); | |
| 1994/1112 | db->qid.path = QID(dev, 0, Qbctl); db->mode = 0660; break; | |
| 1994/1114/sys/src/9/pc/devastar.c:338,354 – 1994/1115/sys/src/9/pc/devastar.c:341,357 | ||
| 1994/1111 | case 0: sprint(db->name, "eia%d%2.2d", dev, ch); db->mode = astar[dev]->c[ch].perm; | |
| 1994/1112 |
| |
| 1994/1115 | db->qid.path = QID(dev, ch, Qdata); | |
| 1994/1111 | break; case 1: sprint(db->name, "eia%d%2.2dctl", dev, ch); db->mode = astar[dev]->c[ch].perm; | |
| 1994/1112 |
| |
| 1994/1115 | db->qid.path = QID(dev, ch, Qctl); | |
| 1994/1111 | break; case 2: sprint(db->name, "eia%d%2.2dstat", dev, ch); db->mode = 0444; | |
| 1994/1112 |
| |
| 1994/1115 | db->qid.path = QID(dev, ch, Qstat); | |
| 1994/1111 | break; | |
| 1994/1112 | } | |
| 1994/1111 | break; | |
| 1994/1114/sys/src/9/pc/devastar.c:359,368 – 1994/1115/sys/src/9/pc/devastar.c:362,370 | ||
| 1994/1112 | if(dev == nastar) | |
| 1994/1111 | return -1; | |
| 1994/1115 | db->qid.vers = 0; | |
| 1994/1111 | db->atime = seconds(); db->mtime = kerndate; | |
| 1994/1112 |
| |
| 1994/1111 | memmove(db->uid, eve, NAMELEN); memmove(db->gid, eve, NAMELEN); db->type = devchar[c->type]; | |
| 1994/1114/sys/src/9/pc/devastar.c:376,382 – 1994/1115/sys/src/9/pc/devastar.c:378,384 | ||
| 1994/1106 | void | |
| 1994/1107 | astarreset(void) | |
| 1994/1106 | { | |
| 1994/1115 | int i, c; | |
| 1994/1107 | Astar *a; | |
| 1994/1106 | for(i = 0; i < Maxcard; i++){ | |
| 1994/1114/sys/src/9/pc/devastar.c:394,399 – 1994/1115/sys/src/9/pc/devastar.c:396,405 | ||
| 1994/1107 | else continue; | |
| 1994/1108 | ||
| 1994/1115 | c = inb(a->port+ISActl1); outb(a->port+ISActl1, c | ISAnotdl); a->memsize = a->ramsize; | |
| 1994/1107 | if(a->mem == 0) | |
| 1994/1108 | a->mem = 0xD4000; | |
| 1994/1107 | if(a->irq == 0) | |
| 1994/1114/sys/src/9/pc/devastar.c:406,412 – 1994/1115/sys/src/9/pc/devastar.c:412,419 | ||
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1107 | continue; } | |
| 1994/1112 |
| |
| 1994/1115 | print("serial%d avanstar port %d addr %lux irq %d\n", i, a->port, a->addr, a->irq); | |
| 1994/1109 | nastar++; | |
| 1994/1114 | setvec(Int0vec + a->irq, astarintr, a); | |
| 1994/1114/sys/src/9/pc/devastar.c:455,462 – 1994/1115/sys/src/9/pc/devastar.c:462,469 | ||
| 1994/1107 | /* set memory address */ | |
| 1994/1113 | outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc); | |
| 1994/1112 |
| |
| 1994/1115 | a->gcb = (GCB*)(KZERO | a->mem); a->addr = (uchar*)(KZERO | a->mem); | |
| 1994/1107 | /* set interrupt level */ | |
| 1994/1112 | if(isairqcode[a->irq] == -1){ | |
| 1994/1114/sys/src/9/pc/devastar.c:475,481 – 1994/1115/sys/src/9/pc/devastar.c:482,488 | ||
| 1994/1111 | Chan* astarattach(char *spec) { | |
| 1994/1115 | return devattach('G', spec); | |
| 1994/1111 | } Chan* | |
| 1994/1114/sys/src/9/pc/devastar.c:500,507 – 1994/1115/sys/src/9/pc/devastar.c:507,516 | ||
| 1994/1111 | astaropen(Chan *c, int omode) { | |
| 1994/1112 | Astar *a; | |
| 1994/1115 | Astarchan *ac; | |
| 1994/1111 | c = devopen(c, omode, 0, 0, astargen); | |
| 1994/1115 | a = astar[BOARD(c->qid.path)]; | |
| 1994/1111 | ||
| 1994/1112 | switch(TYPE(c->qid.path)){ case Qmem: | |
| 1994/1114/sys/src/9/pc/devastar.c:511,519 – 1994/1115/sys/src/9/pc/devastar.c:520,529 | ||
| 1994/1112 | break; | |
| 1994/1114 | case Qdata: case Qctl: | |
| 1994/1115 | ac = a->c + CHAN(c->qid.path); | |
| 1994/1114 | qlock(ac); if(waserror()){ | |
| 1994/1115 | qunlock(ac); | |
| 1994/1114 | nexterror(); } if(ac->opens++ == 0) | |
| 1994/1114/sys/src/9/pc/devastar.c:530,549 – 1994/1115/sys/src/9/pc/devastar.c:540,565 | ||
| 1994/1111 | astarclose(Chan *c) { | |
| 1994/1112 | Astar *a; | |
| 1994/1115 | Astarchan *ac; | |
| 1994/1112 | ||
| 1994/1115 | a = astar[BOARD(c->qid.path)]; | |
| 1994/1112 | switch(TYPE(c->qid.path)){ case Qmem: | |
| 1994/1114 | break; case Qdata: case Qctl: | |
| 1994/1115 | ac = a->c + CHAN(c->qid.path); | |
| 1994/1114 | qlock(ac); if(waserror()){ | |
| 1994/1115 | qunlock(ac); | |
| 1994/1114 | nexterror(); | |
| 1994/1112 | } | |
| 1994/1114 |
| |
| 1994/1115 | if(--ac->opens == 0){ | |
| 1994/1114 | disable(ac); | |
| 1994/1115 | qclose(ac->iq); qclose(ac->oq); } | |
| 1994/1114 | qunlock(ac); poperror(); | |
| 1994/1112 | break; | |
| 1994/1114/sys/src/9/pc/devastar.c:574,581 – 1994/1115/sys/src/9/pc/devastar.c:590,597 | ||
| 1994/1113 | i = Pagesize - i; if(i > rem) i = rem; | |
| 1994/1114 |
| |
| 1994/1115 | if(i > sizeof(tmp)) i = sizeof(tmp); | |
| 1994/1114 | /* * byte at a time so endian doesn't matter, | |
| 1994/1114/sys/src/9/pc/devastar.c:584,594 – 1994/1115/sys/src/9/pc/devastar.c:600,612 | ||
| 1994/1114 | tp = tmp; ilock(&a->pagelock); setpage(a, offset); | |
| 1994/1113 |
| |
| 1994/1115 | for(e = tp + i; tp < e;) | |
| 1994/1114 | *tp++ = *from++; iunlock(&a->pagelock); memmove(to, tmp, i); to += i; | |
| 1994/1115 | offset += i; | |
| 1994/1113 | } return n; | |
| 1994/1114/sys/src/9/pc/devastar.c:598,604 – 1994/1115/sys/src/9/pc/devastar.c:616,622 | ||
| 1994/1114 | * read ISA status */ | |
| 1994/1113 | static long | |
| 1994/1115 | bctlread(Astar *a, void *buf, long n, ulong offset) | |
| 1994/1113 | { char s[128]; | |
| 1994/1114/sys/src/9/pc/devastar.c:613,618 – 1994/1115/sys/src/9/pc/devastar.c:631,638 | ||
| 1994/1111 | long astarread(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1115 | Astar *a; Astarchan *ac; | |
| 1994/1111 | if(c->qid.path & CHDIR) return devdirread(c, buf, n, 0, 0, astargen); | |
| 1994/1114/sys/src/9/pc/devastar.c:622,627 – 1994/1115/sys/src/9/pc/devastar.c:642,651 | ||
| 1994/1113 | return memread(astar[BOARD(c->qid.path)], buf, n, offset); case Qbctl: return bctlread(astar[BOARD(c->qid.path)], buf, n, offset); | |
| 1994/1115 | case Qdata: a = astar[BOARD(c->qid.path)]; ac = a->c + CHAN(c->qid.path); return qread(ac->oq, buf, n); | |
| 1994/1113 | } | |
| 1994/1112 | ||
| 1994/1113 | return 0; | |
| 1994/1114/sys/src/9/pc/devastar.c:651,658 – 1994/1115/sys/src/9/pc/devastar.c:675,682 | ||
| 1994/1113 | i = Pagesize - i; if(i > rem) i = rem; | |
| 1994/1114 |
| |
| 1994/1115 | if(i > sizeof(tmp)) i = sizeof(tmp); | |
| 1994/1113 | ||
| 1994/1114 | /* * byte at a time so endian doesn't matter, | |
| 1994/1114/sys/src/9/pc/devastar.c:662,671 – 1994/1115/sys/src/9/pc/devastar.c:686,697 | ||
| 1994/1114 | tp = tmp; ilock(&a->pagelock); setpage(a, offset); | |
| 1994/1113 |
| |
| 1994/1115 | for(e = tp + i; tp < e;) | |
| 1994/1114 | *to++ = *tp++; iunlock(&a->pagelock); from += i; | |
| 1994/1115 | offset += i; | |
| 1994/1113 | } return n; | |
| 1994/1114/sys/src/9/pc/devastar.c:746,761 – 1994/1115/sys/src/9/pc/devastar.c:772,790 | ||
| 1994/1114 | ac = &a->c[i]; ac->a = a; ac->ccb = (CCB*)x; | |
| 1994/1115 | ac->perm = 0660; | |
| 1994/1114 | ac->iq = qopen(4*1024, 0, 0, 0); ac->oq = qopen(4*1024, 0, astarkick, ac); | |
| 1994/1113 | x += sz; } | |
| 1994/1115 | /* reenable interrupts */ a->gcb->cmd2 = LEUS(Gintack); | |
| 1994/1113 | } | |
| 1994/1115 | static void bctlwrite(Astar *a, char *cmsg) | |
| 1994/1113 | { | |
| 1994/1114/sys/src/9/pc/devastar.c:764,773 – 1994/1115/sys/src/9/pc/devastar.c:793,802 | ||
| 1994/1113 | } qlock(a); | |
| 1994/1115 | if(a->running) error(Eio); | |
| 1994/1113 | ||
| 1994/1115 | if(strncmp(cmsg, "download", 8) == 0){ | |
| 1994/1113 | /* put board in download mode */ c = inb(a->port+ISActl1); outb(a->port+ISActl1, c & ~ISAnotdl); | |
| 1994/1114/sys/src/9/pc/devastar.c:776,784 – 1994/1115/sys/src/9/pc/devastar.c:805,821 | ||
| 1994/1113 | /* enable ISA access to first 16k */ outb(a->port+ISActl2, ISAmen); | |
| 1994/1115 | } 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); | |
| 1994/1113 | } else if(strncmp(cmsg, "run", 3) == 0){ | |
| 1994/1115 | /* start up downloaded program */ | |
| 1994/1113 | startcp(a); } else | |
| 1994/1114/sys/src/9/pc/devastar.c:786,792 – 1994/1115/sys/src/9/pc/devastar.c:823,828 | ||
| 1994/1113 | qunlock(a); poperror(); | |
| 1994/1114/sys/src/9/pc/devastar.c:796,816 – 1994/1115/sys/src/9/pc/devastar.c:832,852 | ||
| 1994/1114 | static int chancmddone(void *arg) { | |
| 1994/1115 | Astarchan *ac = arg; | |
| 1994/1114 | int x; ilock(&ac->a->pagelock); setpage(ac->a, 0); | |
| 1994/1115 | x = ac->ccb->cmd; | |
| 1994/1114 | iunlock(&ac->a->pagelock); | |
| 1994/1115 | return !x; | |
| 1994/1114 | } static void chancmd(Astarchan *ac, int cmd) { | |
| 1994/1115 | int status; | |
| 1994/1114 | ccb = ac->ccb; | |
| 1994/1114/sys/src/9/pc/devastar.c:820,838 – 1994/1115/sys/src/9/pc/devastar.c:856,876 | ||
| 1994/1114 | iunlock(&ac->a->pagelock); /* wait outside of lock */ | |
| 1994/1115 | tsleep(&ac->r, chancmddone, ac, 1000); | |
| 1994/1114 | ilock(&ac->a->pagelock); setpage(ac->a, 0); | |
| 1994/1115 | status = ccb->status; cmd = ccb->cmd; iunlock(&ac->a->pagelock); if(cmd){ | |
| 1994/1114 | print("astar%d cmd didn't terminate\n", ac->a->id); error(Eio); } | |
| 1994/1115 | if(status){ print("astar%d cmd status %ux\n", ac->a->id, status); | |
| 1994/1114 | error(Eio); } | |
| 1994/1114/sys/src/9/pc/devastar.c:842,862 – 1994/1115/sys/src/9/pc/devastar.c:880,904 | ||
| 1994/1114 | static void enable(Astarchan *ac) { | |
| 1994/1115 | Astar *a = ac->a; int n; | |
| 1994/1114 | /* 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); | |
| 1994/1115 | ac->ccb->outlow = 64; | |
| 1994/1114 | iunlock(&a->pagelock); | |
| 1994/1115 | chancmd(ac, Cconfall); | |
| 1994/1114 |
| |
| 1994/1115 | chancmd(ac, Crcvena|Cxmtena|Cconfall); | |
| 1994/1114 | } /* | |
| 1994/1114/sys/src/9/pc/devastar.c:871,878 – 1994/1115/sys/src/9/pc/devastar.c:913,919 | ||
| 1994/1114 | ilock(&ac->a->pagelock); setpage(ac->a, 0); | |
| 1994/1115 | ac->ccb->intrigger = 0; | |
| 1994/1114 | iunlock(&ac->a->pagelock); chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall); | |
| 1994/1114/sys/src/9/pc/devastar.c:900,908 – 1994/1115/sys/src/9/pc/devastar.c:941,951 | ||
| 1994/1114 | ccb = ac->ccb; | |
| 1994/1113 | command = 0; | |
| 1994/1114 | i = atoi(cmd+1); | |
| 1994/1115 | ||
| 1994/1114 | a = ac->a; ilock(&a->pagelock); setpage(a, 0); | |
| 1994/1115 | ||
| 1994/1113 | switch(*cmd){ case 'B': case 'b': | |
| 1994/1114/sys/src/9/pc/devastar.c:914,920 – 1994/1115/sys/src/9/pc/devastar.c:957,963 | ||
| 1994/1114 | ccb->baud = LEUS(Cb115200); | |
| 1994/1113 | break; default: | |
| 1994/1114 |
| |
| 1994/1115 | ccb->baud = LEUS(i); | |
| 1994/1113 | break; } command = Cconfall; | |
| 1994/1114/sys/src/9/pc/devastar.c:939,945 – 1994/1115/sys/src/9/pc/devastar.c:982,988 | ||
| 1994/1113 | break; case 'L': case 'l': | |
| 1994/1115 | n = i - 5; | |
| 1994/1113 | if(n < 0 || n > 3) error(Ebadarg); | |
| 1994/1114 | n |= LEUS(ccb->format) & ~Clenmask; | |
| 1994/1114/sys/src/9/pc/devastar.c:958,970 – 1994/1115/sys/src/9/pc/devastar.c:1001,1012 | ||
| 1994/1114 | /* set fifo sizes */ ccb->intrigger = 8; | |
| 1994/1113 | command = Cconfall; break; case 'n': case 'N': | |
| 1994/1115 | qnoblock(ac->oq, i); | |
| 1994/1113 | break; case 'P': case 'p': | |
| 1994/1114/sys/src/9/pc/devastar.c:1009,1016 – 1994/1115/sys/src/9/pc/devastar.c:1051,1058 | ||
| 1994/1113 | break; case 'Q': case 'q': | |
| 1994/1115 | qsetlimit(ac->iq, i); qsetlimit(ac->oq, i); | |
| 1994/1113 | break; case 'X': case 'x': | |
| 1994/1114/sys/src/9/pc/devastar.c:1048,1054 – 1994/1115/sys/src/9/pc/devastar.c:1090,1097 | ||
| 1994/1112 | n = sizeof(cmsg) - 1; memmove(cmsg, buf, n); cmsg[n] = 0; | |
| 1994/1113 |
| |
| 1994/1115 | bctlwrite(a, cmsg); return n; | |
| 1994/1113 | case Qdata: ac = a->c + CHAN(c->qid.path); return qwrite(ac->oq, buf, n); | |
| 1994/1114/sys/src/9/pc/devastar.c:1064,1070 – 1994/1115/sys/src/9/pc/devastar.c:1107,1113 | ||
| 1994/1114 | nexterror(); } qlock(ac); | |
| 1994/1115 | astarctl(ac, cmsg); | |
| 1994/1114 | qunlock(ac); poperror(); | |
| 1994/1111 | } | |
| 1994/1114/sys/src/9/pc/devastar.c:1089,1096 – 1994/1115/sys/src/9/pc/devastar.c:1132,1151 | ||
| 1994/1112 | void astarwstat(Chan *c, char *dp) { | |
| 1994/1115 | 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; | |
| 1994/1106 | } | |
| 1994/1113 | ||
| 1994/1114 | /* | |
| 1994/1114/sys/src/9/pc/devastar.c:1100,1111 – 1994/1115/sys/src/9/pc/devastar.c:1155,1191 | ||
| 1994/1114 | astarkick1(Astarchan *ac) { Astar *a = ac->a; | |
| 1994/1115 | CCB *ccb = ac->ccb; uchar buf[256]; uchar *rp, *wp, *bp, *ep, *p, *e; | |
| 1994/1114 | int n; | |
| 1994/1115 | 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); | |
| 1994/1114 | for(;;){ | |
| 1994/1115 | 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; } | |
| 1994/1114 | setpage(a, 0); | |
| 1994/1115 | ccb->outwp = LEUS(wp - a->addr); | |
| 1994/1114 | } } static void | |
| 1994/1114/sys/src/9/pc/devastar.c:1112,1122 – 1994/1115/sys/src/9/pc/devastar.c:1192,1241 | ||
| 1994/1114 | astarkick(Astarchan *ac) { ilock(&ac->a->pagelock); | |
| 1994/1115 | astarkick1(ac); | |
| 1994/1114 | iunlock(&ac->a->pagelock); } /* | |
| 1994/1115 | * 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); } /* | |
| 1994/1114 | * handle an interrupt */ static void | |
| 1994/1114/sys/src/9/pc/devastar.c:1125,1131 – 1994/1115/sys/src/9/pc/devastar.c:1244,1249 | ||
| 1994/1114 | Astar *a = arg; Astarchan *ac; ulong vec, invec, outvec, errvec, mvec, cmdvec; | |
| 1994/1114/sys/src/9/pc/devastar.c:1137,1163 – 1994/1115/sys/src/9/pc/devastar.c:1255,1282 | ||
| 1994/1114 | errvec = LEUS(xchgw(&a->gcb->errserv, 0)); mvec = LEUS(xchgw(&a->gcb->modemserv, 0)); cmdvec = LEUS(xchgw(&a->gcb->cmdserv, 0)); | |
| 1994/1115 | USED(mvec); USED(cmdvec); USED(errvec); | |
| 1994/1114 | /* reenable interrupts */ | |
| 1994/1115 | a->gcb->cmd2 = LEUS(Gintack); | |
| 1994/1114 | /* service interrupts */ ac = a->c; | |
| 1994/1115 | for(vec = invec; vec; vec >>= 1){ if(vec&1) astarinput(ac); | |
| 1994/1114 | ac++; } ac = a->c; | |
| 1994/1115 | for(vec = outvec; vec; vec >>= 1){ | |
| 1994/1114 | if(vec&1) astarkick1(ac); | |
| 1994/1115 | for(vec = cmdvec; vec; vec >>= 1){ | |
| 1994/1114 | if(vec&1) wakeup(&ac->r); ac++; | |
| 1994/1115/sys/src/9/pc/devastar.c:57,62 – 1994/1116/sys/src/9/pc/devastar.c:57,65 (short | long) | ||
| 1994/1106 | ||
| 1994/1113 | #define APAGE(x) ((x)>>Pageshift) | |
| 1994/1116 | #define LOCKPAGE(a, o) if((a)->needpage){ilock(&(a)->pagelock);setpage(a, o);} #define UNLOCKPAGE(a) if((a)->needpage)iunlock(&(a)->pagelock) | |
| 1994/1107 | /* IRQ codes */ static int isairqcode[16] = { | |
| 1994/1115/sys/src/9/pc/devastar.c:242,251 – 1994/1116/sys/src/9/pc/devastar.c:245,254 | ||
| 1994/1111 | Astarchan *c; /* channels */ | |
| 1994/1107 | int ramsize; /* 16k or 256k */ | |
| 1994/1113 | int memsize; /* size of memory currently mapped */ | |
| 1994/1116 | int needpage; | |
| 1994/1115 | GCB *gcb; /* global board comm area */ | |
| 1994/1113 | uchar *addr; /* base of memory area */ int running; | |
| 1994/1106 | }; /* host per channel info */ | |
| 1994/1115/sys/src/9/pc/devastar.c:258,263 – 1994/1116/sys/src/9/pc/devastar.c:261,267 | ||
| 1994/1113 | CCB *ccb; /* channel control block */ | |
| 1994/1111 | int perm; | |
| 1994/1112 | int opens; | |
| 1994/1116 | int baud; | |
| 1994/1107 | ||
| 1994/1106 | Queue *iq; Queue *oq; | |
| 1994/1115/sys/src/9/pc/devastar.c:282,287 – 1994/1116/sys/src/9/pc/devastar.c:286,292 | ||
| 1994/1114 | static int astarsetup(Astar*); static void astarintr(Ureg*, void*); static void astarkick(Astarchan*); | |
| 1994/1116 | static void astarkickin(Astarchan*); | |
| 1994/1114 | static void enable(Astarchan*); static void disable(Astarchan*); | |
| 1994/1115 | static void astarctl(Astarchan*, char*); | |
| 1994/1115/sys/src/9/pc/devastar.c:526,533 – 1994/1116/sys/src/9/pc/devastar.c:531,541 | ||
| 1994/1115 | qunlock(ac); | |
| 1994/1114 | nexterror(); } | |
| 1994/1116 | if(ac->opens++ == 0){ | |
| 1994/1114 | enable(ac); | |
| 1994/1116 | qreopen(ac->iq); qreopen(ac->oq); } | |
| 1994/1114 | qunlock(ac); poperror(); break; | |
| 1994/1115/sys/src/9/pc/devastar.c:598,608 – 1994/1116/sys/src/9/pc/devastar.c:606,615 | ||
| 1994/1114 | * go via tmp to avoid pagefaults while ilock'd */ tp = tmp; | |
| 1994/1116 | LOCKPAGE(a, offset); | |
| 1994/1115 | for(e = tp + i; tp < e;) | |
| 1994/1114 | *tp++ = *from++; | |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | memmove(to, tmp, i); to += i; | |
| 1994/1115 | ||
| 1994/1115/sys/src/9/pc/devastar.c:645,651 – 1994/1116/sys/src/9/pc/devastar.c:652,658 | ||
| 1994/1115 | case Qdata: a = astar[BOARD(c->qid.path)]; ac = a->c + CHAN(c->qid.path); | |
| 1994/1116 | return qread(ac->iq, buf, n); | |
| 1994/1113 | } | |
| 1994/1112 | ||
| 1994/1113 | return 0; | |
| 1994/1115/sys/src/9/pc/devastar.c:684,694 – 1994/1116/sys/src/9/pc/devastar.c:691,700 | ||
| 1994/1114 | */ memmove(tmp, from, i); tp = tmp; | |
| 1994/1116 | LOCKPAGE(a, offset); | |
| 1994/1115 | for(e = tp + i; tp < e;) | |
| 1994/1114 | *to++ = *tp++; | |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | from += i; | |
| 1994/1115 | offset += i; | |
| 1994/1115/sys/src/9/pc/devastar.c:714,719 – 1994/1116/sys/src/9/pc/devastar.c:720,730 | ||
| 1994/1113 | /* take board out of download mode and enable IRQ */ outb(a->port+ISActl1, ISAien|isairqcode[a->irq]|ISAnotdl); a->memsize = a->ramsize; | |
| 1994/1116 | setpage(a, 0); if(a->memsize <= Pagesize) a->needpage = 0; else a->needpage = 1; | |
| 1994/1113 | /* wait for control program to signal life */ for(i = 0; i < 21; i++){ | |
| 1994/1115/sys/src/9/pc/devastar.c:727,737 – 1994/1116/sys/src/9/pc/devastar.c:738,747 | ||
| 1994/1113 | } | |
| 1994/1114 | if(waserror()){ | |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | poperror(); } | |
| 1994/1113 |
| |
| 1994/1116 | LOCKPAGE(a, 0); | |
| 1994/1113 | i = LEUS(a->gcb->type); switch(i){ default: | |
| 1994/1115/sys/src/9/pc/devastar.c:761,767 – 1994/1116/sys/src/9/pc/devastar.c:771,778 | ||
| 1994/1113 | error(Eio); | |
| 1994/1112 | } | |
| 1994/1113 | } | |
| 1994/1114 |
| |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | poperror(); | |
| 1994/1113 | /* setup the channels */ | |
| 1994/1115/sys/src/9/pc/devastar.c:773,785 – 1994/1116/sys/src/9/pc/devastar.c:784,798 | ||
| 1994/1114 | ac->a = a; ac->ccb = (CCB*)x; | |
| 1994/1115 | ac->perm = 0660; | |
| 1994/1114 |
| |
| 1994/1116 | ac->iq = qopen(4*1024, 0, astarkickin, ac); | |
| 1994/1114 | ac->oq = qopen(4*1024, 0, astarkick, ac); | |
| 1994/1113 | x += sz; } | |
| 1994/1115 |
| |
| 1994/1116 | /* enable control program interrupt generation */ LOCKPAGE(a, 0); | |
| 1994/1115 | a->gcb->cmd2 = LEUS(Gintack); | |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1113 | } | |
| 1994/1115 | static void | |
| 1994/1115/sys/src/9/pc/devastar.c:801,809 – 1994/1116/sys/src/9/pc/devastar.c:814,823 | ||
| 1994/1113 | c = inb(a->port+ISActl1); outb(a->port+ISActl1, c & ~ISAnotdl); a->memsize = Pramsize; | |
| 1994/1116 | a->needpage = 1; | |
| 1994/1113 | /* enable ISA access to first 16k */ | |
| 1994/1116 | setpage(a, 0); | |
| 1994/1113 | ||
| 1994/1115 | } else if(strncmp(cmsg, "sharedmem", 9) == 0){ /* map shared memory */ | |
| 1994/1115/sys/src/9/pc/devastar.c:835,844 – 1994/1116/sys/src/9/pc/devastar.c:849,857 | ||
| 1994/1115 | Astarchan *ac = arg; | |
| 1994/1114 | int x; | |
| 1994/1116 | LOCKPAGE(ac->a, 0); | |
| 1994/1115 | x = ac->ccb->cmd; | |
| 1994/1114 |
| |
| 1994/1116 | UNLOCKPAGE(ac->a); | |
| 1994/1114 | ||
| 1994/1115 | return !x; | |
| 1994/1114 | } | |
| 1994/1115/sys/src/9/pc/devastar.c:850,868 – 1994/1116/sys/src/9/pc/devastar.c:863,879 | ||
| 1994/1114 | ccb = ac->ccb; | |
| 1994/1116 | LOCKPAGE(ac->a, 0); | |
| 1994/1114 | ccb->cmd = cmd; | |
| 1994/1116 | UNLOCKPAGE(ac->a); | |
| 1994/1114 | /* wait outside of lock */ | |
| 1994/1115 | tsleep(&ac->r, chancmddone, ac, 1000); | |
| 1994/1114 |
| |
| 1994/1116 | LOCKPAGE(ac->a, 0); | |
| 1994/1115 | status = ccb->status; cmd = ccb->cmd; | |
| 1994/1116 | UNLOCKPAGE(ac->a); | |
| 1994/1115 | if(cmd){ | |
| 1994/1114 | print("astar%d cmd didn't terminate\n", ac->a->id); error(Eio); | |
| 1994/1115/sys/src/9/pc/devastar.c:884,895 – 1994/1116/sys/src/9/pc/devastar.c:895,905 | ||
| 1994/1115 | int n; | |
| 1994/1114 | /* make sure we control RTS, DTR and break */ | |
| 1994/1116 | LOCKPAGE(a, 0); | |
| 1994/1114 | n = LEUS(ac->ccb->proto) | Cmctl; ac->ccb->proto = LEUS(n); | |
| 1994/1115 | ac->ccb->outlow = 64; | |
| 1994/1114 |
| |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1115 | chancmd(ac, Cconfall); | |
| 1994/1114 | astarctl(ac, "b9600"); | |
| 1994/1115/sys/src/9/pc/devastar.c:911,921 – 1994/1116/sys/src/9/pc/devastar.c:921,926 | ||
| 1994/1114 | astarctl(ac, "d0"); astarctl(ac, "r0"); | |
| 1994/1115 |
| |
| 1994/1114 |
| |
| 1994/1115/sys/src/9/pc/devastar.c:943,954 – 1994/1116/sys/src/9/pc/devastar.c:948,959 | ||
| 1994/1114 | i = atoi(cmd+1); | |
| 1994/1115 | ||
| 1994/1114 | a = ac->a; | |
| 1994/1116 | LOCKPAGE(a, 0); | |
| 1994/1115 | ||
| 1994/1113 | switch(*cmd){ case 'B': case 'b': | |
| 1994/1116 | /* set baud rate (high rates are special - only 16 bits) */ | |
| 1994/1114 | switch(i){ | |
| 1994/1113 | case 76800: | |
| 1994/1114 | ccb->baud = LEUS(Cb76800); | |
| 1994/1115/sys/src/9/pc/devastar.c:960,965 – 1994/1116/sys/src/9/pc/devastar.c:965,979 | ||
| 1994/1115 | ccb->baud = LEUS(i); | |
| 1994/1113 | break; } | |
| 1994/1116 | 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); | |
| 1994/1113 | command = Cconfall; | |
| 1994/1112 | break; | |
| 1994/1113 | case 'D': | |
| 1994/1115/sys/src/9/pc/devastar.c:993,1007 – 1994/1116/sys/src/9/pc/devastar.c:1007,1021 | ||
| 1994/1113 | case 'M': | |
| 1994/1114 | /* turn on cts */ n = LEUS(ccb->proto); | |
| 1994/1116 | if(i){ n |= Cobeycts|Cgenrts; n &= ~Cmctl; } else { n &= ~(Cobeycts|Cgenrts); n |= Cmctl; } | |
| 1994/1114 | ccb->proto = LEUS(n); | |
| 1994/1113 | command = Cconfall; break; case 'n': | |
| 1994/1115/sys/src/9/pc/devastar.c:1031,1042 – 1994/1116/sys/src/9/pc/devastar.c:1045,1055 | ||
| 1994/1114 | i = 250; n = LEUS(ccb->mctl) | Cbreakctl; ccb->mctl = LEUS(n); | |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | tsleep(&ac->r, return0, 0, i); | |
| 1994/1116 | LOCKPAGE(a, 0); | |
| 1994/1114 | n &= ~Cbreakctl; ccb->mctl = LEUS(n); | |
| 1994/1113 | break; | |
| 1994/1115/sys/src/9/pc/devastar.c:1065,1071 – 1994/1116/sys/src/9/pc/devastar.c:1078,1084 | ||
| 1994/1113 | command = Cconfall; break; | |
| 1994/1111 | } | |
| 1994/1114 |
| |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | if(command) chancmd(ac, command); | |
| 1994/1115/sys/src/9/pc/devastar.c:1160,1166 – 1994/1116/sys/src/9/pc/devastar.c:1173,1180 | ||
| 1994/1115 | uchar *rp, *wp, *bp, *ep, *p, *e; | |
| 1994/1114 | int n; | |
| 1994/1115 |
| |
| 1994/1116 | if(a->needpage) setpage(a, 0); | |
| 1994/1115 | ep = a->addr; rp = ep + LEUS(ccb->outrp); wp = ep + LEUS(ccb->outwp); | |
| 1994/1115/sys/src/9/pc/devastar.c:1177,1183 – 1994/1116/sys/src/9/pc/devastar.c:1191,1198 | ||
| 1994/1115 | n = qconsume(ac->oq, buf, n); if(n <= 0) break; | |
| 1994/1116 | if(a->needpage) setpage(a, bp - a->addr); | |
| 1994/1115 | e = buf + n; for(p = buf; p < e;){ *wp++ = *p++; | |
| 1994/1115/sys/src/9/pc/devastar.c:1184,1190 – 1994/1116/sys/src/9/pc/devastar.c:1199,1206 | ||
| 1994/1115 | if(wp > ep) wp = bp; } | |
| 1994/1114 |
| |
| 1994/1116 | if(a->needpage) setpage(a, 0); | |
| 1994/1115 | ccb->outwp = LEUS(wp - a->addr); | |
| 1994/1114 | } } | |
| 1994/1115/sys/src/9/pc/devastar.c:1208,1214 – 1994/1116/sys/src/9/pc/devastar.c:1224,1231 | ||
| 1994/1115 | uchar *rp, *wp, *bp, *ep, *p, *e; int n; | |
| 1994/1116 | if(a->needpage) setpage(a, 0); | |
| 1994/1115 | ep = a->addr; rp = ep + LEUS(ccb->inrp); wp = ep + LEUS(ccb->inwp); | |
| 1994/1115/sys/src/9/pc/devastar.c:1222,1228 – 1994/1116/sys/src/9/pc/devastar.c:1239,1246 | ||
| 1994/1115 | n += ep - bp + 1; if(n > sizeof(buf)) n = sizeof(buf); | |
| 1994/1116 | if(a->needpage) setpage(a, bp - a->addr); | |
| 1994/1115 | e = buf + n; for(p = buf; p < e;){ *p++ = *rp++; | |
| 1994/1115/sys/src/9/pc/devastar.c:1229,1241 – 1994/1116/sys/src/9/pc/devastar.c:1247,1274 | ||
| 1994/1115 | if(rp > ep) rp = bp; } | |
| 1994/1116 | if(qroduce(ac->iq, buf, n) < 0) break; /* flow controlled */ if(a->needpage) setpage(a, 0); ccb->inrp = LEUS(rp - a->addr); | |
| 1994/1115 | } | |
| 1994/1116 | if(a->needpage) setpage(a, 0); | |
| 1994/1115 | } /* | |
| 1994/1116 | * get flow controlled input going again */ static void astarkick(Astarchan *ac) { ilock(&ac->a->pagelock); astarinput(ac); iunlock(&ac->a->pagelock); } /* | |
| 1994/1114 | * handle an interrupt */ static void | |
| 1994/1115/sys/src/9/pc/devastar.c:1247,1253 – 1994/1116/sys/src/9/pc/devastar.c:1280,1287 | ||
| 1994/1114 | USED(ur); lock(&a->pagelock); | |
| 1994/1116 | if(a->needpage) setpage(a, 0); | |
| 1994/1114 | /* get causes */ invec = LEUS(xchgw(&a->gcb->inserv, 0)); | |
| 1994/1116/sys/src/9/pc/devastar.c:344,360 – 1994/1117/sys/src/9/pc/devastar.c:344,360 (short | long) | ||
| 1994/1111 | t = i%3; switch(t){ case 0: | |
| 1994/1117 | sprint(db->name, "eia%d%2.2d", dev, ch+1); | |
| 1994/1111 | db->mode = astar[dev]->c[ch].perm; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qdata); | |
| 1994/1111 | break; case 1: | |
| 1994/1117 | sprint(db->name, "eia%d%2.2dctl", dev, ch+1); | |
| 1994/1111 | db->mode = astar[dev]->c[ch].perm; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qctl); | |
| 1994/1111 | break; case 2: | |
| 1994/1117 | sprint(db->name, "eia%d%2.2dstat", dev, ch+1); | |
| 1994/1111 | db->mode = 0444; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qstat); | |
| 1994/1111 | break; | |
| 1994/1116/sys/src/9/pc/devastar.c:918,926 – 1994/1117/sys/src/9/pc/devastar.c:918,932 | ||
| 1994/1114 | static void disable(Astarchan *ac) { | |
| 1994/1117 | int n; | |
| 1994/1114 | astarctl(ac, "d0"); astarctl(ac, "r0"); | |
| 1994/1117 | LOCKPAGE(ac->a, 0); n = LEUS(ac->ccb->proto) | Cmctl; ac->ccb->proto = LEUS(n); UNLOCKPAGE(ac->a); | |
| 1994/1114 | chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall); } | |
| 1994/1116/sys/src/9/pc/devastar.c:1165,1171 – 1994/1117/sys/src/9/pc/devastar.c:1171,1177 | ||
| 1994/1114 | * get output going */ static void | |
| 1994/1117 | astaroutput(Astarchan *ac) | |
| 1994/1114 | { Astar *a = ac->a; | |
| 1994/1115 | CCB *ccb = ac->ccb; | |
| 1994/1116/sys/src/9/pc/devastar.c:1208,1214 – 1994/1117/sys/src/9/pc/devastar.c:1214,1220 | ||
| 1994/1114 | astarkick(Astarchan *ac) { ilock(&ac->a->pagelock); | |
| 1994/1115 |
| |
| 1994/1117 | astaroutput(ac); | |
| 1994/1114 | iunlock(&ac->a->pagelock); } | |
| 1994/1116/sys/src/9/pc/devastar.c:1247,1253 – 1994/1117/sys/src/9/pc/devastar.c:1253,1259 | ||
| 1994/1115 | if(rp > ep) rp = bp; } | |
| 1994/1116 |
| |
| 1994/1117 | if(qproduce(ac->iq, buf, n) < 0) | |
| 1994/1116 | break; /* flow controlled */ if(a->needpage) setpage(a, 0); | |
| 1994/1116/sys/src/9/pc/devastar.c:1261,1267 – 1994/1117/sys/src/9/pc/devastar.c:1267,1273 | ||
| 1994/1116 | * get flow controlled input going again */ static void | |
| 1994/1117 | astarkickin(Astarchan *ac) | |
| 1994/1116 | { ilock(&ac->a->pagelock); astarinput(ac); | |
| 1994/1116/sys/src/9/pc/devastar.c:1306,1312 – 1994/1117/sys/src/9/pc/devastar.c:1312,1318 | ||
| 1994/1114 | ac = a->c; | |
| 1994/1115 | for(vec = outvec; vec; vec >>= 1){ | |
| 1994/1114 | if(vec&1) | |
| 1994/1117 | astaroutput(ac); | |
| 1994/1114 | ac++; } ac = a->c; | |
| 1994/1117/sys/src/9/pc/devastar.c:344,360 – 1994/1118/sys/src/9/pc/devastar.c:344,360 (short | long) | ||
| 1994/1111 | t = i%3; switch(t){ case 0: | |
| 1994/1117 |
| |
| 1994/1118 | sprint(db->name, "eia%d%2.2d", dev, ch); | |
| 1994/1111 | db->mode = astar[dev]->c[ch].perm; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qdata); | |
| 1994/1111 | break; case 1: | |
| 1994/1117 |
| |
| 1994/1118 | sprint(db->name, "eia%d%2.2dctl", dev, ch); | |
| 1994/1111 | db->mode = astar[dev]->c[ch].perm; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qctl); | |
| 1994/1111 | break; case 2: | |
| 1994/1117 |
| |
| 1994/1118 | sprint(db->name, "eia%d%2.2dstat", dev, ch); | |
| 1994/1111 | db->mode = 0444; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qstat); | |
| 1994/1111 | break; | |
| 1994/1117/sys/src/9/pc/devastar.c:391,397 – 1994/1118/sys/src/9/pc/devastar.c:391,397 | ||
| 1994/1112 | if(isaconfig("serial", i, a) == 0){ | |
| 1994/1107 | xfree(a); | |
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1106 |
| |
| 1994/1118 | continue; | |
| 1994/1106 | } | |
| 1994/1107 | if(strcmp(a->type, "a100i") == 0 || strcmp(a->type,"A100I") == 0) | |
| 1994/1117/sys/src/9/pc/devastar.c:398,416 – 1994/1118/sys/src/9/pc/devastar.c:398,414 | ||
| 1994/1107 | a->ramsize = 16*1024; else if(strcmp(a->type, "a200i") == 0 || strcmp(a->type,"A200I") == 0) a->ramsize = 256*1024; | |
| 1994/1118 | else { xfree(a); astar[nastar] = 0; | |
| 1994/1107 | continue; | |
| 1994/1118 | } | |
| 1994/1108 | ||
| 1994/1115 |
| |
| 1994/1107 | if(a->mem == 0) | |
| 1994/1108 | a->mem = 0xD4000; | |
| 1994/1107 | if(a->irq == 0) a->irq = 15; a->id = i; | |
| 1994/1113 |
| |
| 1994/1107 | if(astarsetup(a) < 0){ xfree(a); | |
| 1994/1117/sys/src/9/pc/devastar.c:421,427 – 1994/1118/sys/src/9/pc/devastar.c:419,431 | ||
| 1994/1115 | a->addr, a->irq); | |
| 1994/1109 | nastar++; | |
| 1994/1114 |
| |
| 1994/1118 | 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; | |
| 1994/1107 | } } | |
| 1994/1117/sys/src/9/pc/devastar.c:790,795 – 1994/1118/sys/src/9/pc/devastar.c:794,800 | ||
| 1994/1113 | } | |
| 1994/1115 | ||
| 1994/1116 | /* enable control program interrupt generation */ | |
| 1994/1118 | setvec(Int0vec + a->irq, astarintr, a); | |
| 1994/1116 | LOCKPAGE(a, 0); | |
| 1994/1115 | a->gcb->cmd2 = LEUS(Gintack); | |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1118/sys/src/9/pc/devastar.c:415,431 – 1994/1119/sys/src/9/pc/devastar.c:415,435 (short | long) | ||
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1107 | continue; } | |
| 1994/1115 |
| |
| 1994/1119 | print("serial%d avanstar port 0x%lux addr %lux irq %d\n", i, a->port, | |
| 1994/1115 | a->addr, a->irq); | |
| 1994/1109 | nastar++; | |
| 1994/1114 | ||
| 1994/1119 | /* disable ISA memory response */ c = inb(a->port+ISActl2); outb(a->port+ISActl2, c & ~ISAmen); /* download mode to turn off cpu */ | |
| 1994/1118 | c = inb(a->port+ISActl1); outb(a->port+ISActl1, c & ~ISAnotdl); a->memsize = Pramsize; | |
| 1994/1119 | setvec(Int0vec + a->irq, astarintr, a); | |
| 1994/1107 | } } | |
| 1994/1118/sys/src/9/pc/devastar.c:722,727 – 1994/1119/sys/src/9/pc/devastar.c:726,732 | ||
| 1994/1113 | error(Eio); /* take board out of download mode and enable IRQ */ | |
| 1994/1119 | print("out of download\n"); | |
| 1994/1113 | outb(a->port+ISActl1, ISAien|isairqcode[a->irq]|ISAnotdl); a->memsize = a->ramsize; | |
| 1994/1116 | setpage(a, 0); | |
| 1994/1118/sys/src/9/pc/devastar.c:731,736 – 1994/1119/sys/src/9/pc/devastar.c:736,742 | ||
| 1994/1116 | a->needpage = 1; | |
| 1994/1113 | /* wait for control program to signal life */ | |
| 1994/1119 | print("waiting for cp\n"); | |
| 1994/1113 | for(i = 0; i < 21; i++){ if(inb(a->port+ISActl1) & ISApr) break; | |
| 1994/1118/sys/src/9/pc/devastar.c:745,750 – 1994/1119/sys/src/9/pc/devastar.c:751,757 | ||
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | poperror(); } | |
| 1994/1119 | ||
| 1994/1116 | LOCKPAGE(a, 0); | |
| 1994/1113 | i = LEUS(a->gcb->type); switch(i){ | |
| 1994/1118/sys/src/9/pc/devastar.c:776,783 – 1994/1119/sys/src/9/pc/devastar.c:783,794 | ||
| 1994/1112 | } | |
| 1994/1113 | } | |
| 1994/1116 | ||
| 1994/1119 | /* enable control program interrupt generation */ a->gcb->cmd2 = LEUS(Gintack); | |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | poperror(); | |
| 1994/1119 | print("setting up channels\n"); | |
| 1994/1113 | /* setup the channels */ a->running = 1; | |
| 1994/1118/sys/src/9/pc/devastar.c:792,803 – 1994/1119/sys/src/9/pc/devastar.c:803,808 | ||
| 1994/1114 | ac->oq = qopen(4*1024, 0, astarkick, ac); | |
| 1994/1113 | x += sz; } | |
| 1994/1115 | ||
| 1994/1116 |
| |
| 1994/1118 |
| |
| 1994/1116 |
| |
| 1994/1115 |
| |
| 1994/1116 |
| |
| 1994/1113 | } | |
| 1994/1115 | static void | |
| 1994/1118/sys/src/9/pc/devastar.c:1293,1298 – 1994/1119/sys/src/9/pc/devastar.c:1298,1307 | ||
| 1994/1114 | lock(&a->pagelock); | |
| 1994/1116 | if(a->needpage) setpage(a, 0); | |
| 1994/1119 | if(a->running == 0){ print("astar interrupt but cp not running\n"); return; } | |
| 1994/1114 | /* get causes */ invec = LEUS(xchgw(&a->gcb->inserv, 0)); | |
| 1994/1119/sys/src/9/pc/devastar.c:43,49 – 1994/1120/sys/src/9/pc/devastar.c:43,49 (short | long) | ||
| 1994/1106 | ISA186ien= 1<<7, /* I186 irq enable bit state */ ISA186idata= 1<<6, /* I186 irq data bit state */ | |
| 1994/1107 | ISAmen= 1<<4, /* enable memory to respond to ISA cycles */ | |
| 1994/1120 | ISAmbank= 0xf<<0, /* shift for 4 bit memory bank */ | |
| 1994/1107 | ISAmaddr= 3, /* bits 14-19 of the boards mem address */ | |
| 1994/1106 | ISAstat1= 4, /* board status (1 bit per channel) */ ISAstat2= 5, /* board status (1 bit per channel) */ | |
| 1994/1119/sys/src/9/pc/devastar.c:297,308 – 1994/1120/sys/src/9/pc/devastar.c:297,310 | ||
| 1994/1114 | static void | |
| 1994/1113 | setpage(Astar *a, ulong offset) { | |
| 1994/1120 | int i, c; | |
| 1994/1113 | i = APAGE(offset); if(i == a->page) return; | |
| 1994/1120 | c = inb(a->port+ISActl2) & ~ISAmbank; outb(a->port+ISActl2, ISAmen|i|c); | |
| 1994/1113 | a->page = i; } | |
| 1994/1119/sys/src/9/pc/devastar.c:394,399 – 1994/1120/sys/src/9/pc/devastar.c:396,402 | ||
| 1994/1118 | continue; | |
| 1994/1106 | } | |
| 1994/1120 | /* check all possible names */ | |
| 1994/1107 | 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) | |
| 1994/1119/sys/src/9/pc/devastar.c:404,409 – 1994/1120/sys/src/9/pc/devastar.c:407,413 | ||
| 1994/1107 | continue; | |
| 1994/1118 | } | |
| 1994/1108 | ||
| 1994/1120 | /* defaults */ | |
| 1994/1107 | if(a->mem == 0) | |
| 1994/1108 | a->mem = 0xD4000; | |
| 1994/1107 | if(a->irq == 0) | |
| 1994/1119/sys/src/9/pc/devastar.c:415,435 – 1994/1120/sys/src/9/pc/devastar.c:419,427 | ||
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1107 | continue; } | |
| 1994/1119 |
| |
| 1994/1120 | print("serial%d avanstar port 0x%lux addr %lux irq %d\n", a->id, a->port, | |
| 1994/1115 | a->addr, a->irq); | |
| 1994/1109 | nastar++; | |
| 1994/1114 | ||
| 1994/1119 |
| |
| 1994/1118 |
| |
| 1994/1119 |
| |
| 1994/1107 | } } | |
| 1994/1119/sys/src/9/pc/devastar.c:453,459 – 1994/1120/sys/src/9/pc/devastar.c:445,451 | ||
| 1994/1109 | static int | |
| 1994/1107 | astarsetup(Astar *a) { | |
| 1994/1112 |
| |
| 1994/1120 | int i, c, found; | |
| 1994/1107 | /* see if the card exists */ found = 0; | |
| 1994/1119/sys/src/9/pc/devastar.c:473,489 – 1994/1120/sys/src/9/pc/devastar.c:465,494 | ||
| 1994/1107 | return -1; } | |
| 1994/1113 |
| |
| 1994/1115 |
| |
| 1994/1107 |
| |
| 1994/1120 | /* check interrupt level */ | |
| 1994/1112 | if(isairqcode[a->irq] == -1){ | |
| 1994/1107 | print("Avanstar %d bad irq %d\n", a->id, a->irq); return -1; } | |
| 1994/1111 | ||
| 1994/1120 | /* 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; | |
| 1994/1111 | return 0; } | |
| 1994/1119/sys/src/9/pc/devastar.c:717,723 – 1994/1120/sys/src/9/pc/devastar.c:722,728 | ||
| 1994/1113 | static void startcp(Astar *a) { | |
| 1994/1120 | int c, n, i, sz; | |
| 1994/1113 | uchar *x; CCB *ccb; | |
| 1994/1114 | Astarchan *ac; | |
| 1994/1119/sys/src/9/pc/devastar.c:727,735 – 1994/1120/sys/src/9/pc/devastar.c:732,740 | ||
| 1994/1113 | /* take board out of download mode and enable IRQ */ | |
| 1994/1119 | print("out of download\n"); | |
| 1994/1113 |
| |
| 1994/1120 | c = inb(a->port+ISActl1); outb(a->port+ISActl1, c|ISAien|ISAnotdl); | |
| 1994/1113 | a->memsize = a->ramsize; | |
| 1994/1116 |
| |
| 1994/1119/sys/src/9/pc/devastar.c:827,832 – 1994/1120/sys/src/9/pc/devastar.c:832,838 | ||
| 1994/1116 | a->needpage = 1; | |
| 1994/1113 | /* enable ISA access to first 16k */ | |
| 1994/1120 | a->page = -1; | |
| 1994/1116 | setpage(a, 0); | |
| 1994/1113 | ||
| 1994/1115 | } else if(strncmp(cmsg, "sharedmem", 9) == 0){ | |
| 1994/1119/sys/src/9/pc/devastar.c:836,842 – 1994/1120/sys/src/9/pc/devastar.c:842,849 | ||
| 1994/1115 | a->memsize = a->ramsize; /* enable ISA access to first 16k */ | |
| 1994/1120 | a->page = -1; setpage(a, 0); | |
| 1994/1115 | ||
| 1994/1113 | } else if(strncmp(cmsg, "run", 3) == 0){ | |
| 1994/1115 | /* start up downloaded program */ | |
| 1994/1120/sys/src/9/pc/devastar.c:43,49 – 1994/1121/sys/src/9/pc/devastar.c:43,49 (short | long) | ||
| 1994/1106 | ISA186ien= 1<<7, /* I186 irq enable bit state */ ISA186idata= 1<<6, /* I186 irq data bit state */ | |
| 1994/1107 | ISAmen= 1<<4, /* enable memory to respond to ISA cycles */ | |
| 1994/1120 |
| |
| 1994/1121 | ISAmbank= 0xf<<0, /* shift for 4 bit memory bank */ | |
| 1994/1107 | ISAmaddr= 3, /* bits 14-19 of the boards mem address */ | |
| 1994/1106 | ISAstat1= 4, /* board status (1 bit per channel) */ ISAstat2= 5, /* board status (1 bit per channel) */ | |
| 1994/1120/sys/src/9/pc/devastar.c:254,267 – 1994/1121/sys/src/9/pc/devastar.c:254,270 | ||
| 1994/1106 | /* host per channel info */ struct Astarchan { | |
| 1994/1114 |
| |
| 1994/1121 | QLock; /* lock for rendez */ Rendez r; /* waiting for command completion */ | |
| 1994/1106 | ||
| 1994/1109 |
| |
| 1994/1113 |
| |
| 1994/1121 | Astar *a; /* controller */ CCB *ccb; /* channel control block */ | |
| 1994/1111 | int perm; | |
| 1994/1112 | int opens; | |
| 1994/1116 |
| |
| 1994/1121 | int baud; /* baud rate */ int framing; /* framing errors */ int overrun; /* overruns */ int dtr; /* non-zero means dtr on */ | |
| 1994/1107 | ||
| 1994/1106 | Queue *iq; Queue *oq; | |
| 1994/1120/sys/src/9/pc/devastar.c:297,310 – 1994/1121/sys/src/9/pc/devastar.c:300,312 | ||
| 1994/1114 | static void | |
| 1994/1113 | setpage(Astar *a, ulong offset) { | |
| 1994/1120 |
| |
| 1994/1121 | int i; | |
| 1994/1113 | i = APAGE(offset); if(i == a->page) return; | |
| 1994/1120 |
| |
| 1994/1121 | outb(a->port+ISActl2, ISAmen|i); | |
| 1994/1113 | a->page = i; } | |
| 1994/1120/sys/src/9/pc/devastar.c:346,362 – 1994/1121/sys/src/9/pc/devastar.c:348,364 | ||
| 1994/1111 | t = i%3; switch(t){ case 0: | |
| 1994/1118 |
| |
| 1994/1121 | sprint(db->name, "eia%d%2.2d", astar[dev]->id, ch); | |
| 1994/1111 | db->mode = astar[dev]->c[ch].perm; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qdata); | |
| 1994/1111 | break; case 1: | |
| 1994/1118 |
| |
| 1994/1121 | sprint(db->name, "eia%d%2.2dctl", astar[dev]->id, ch); | |
| 1994/1111 | db->mode = astar[dev]->c[ch].perm; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qctl); | |
| 1994/1111 | break; case 2: | |
| 1994/1118 |
| |
| 1994/1121 | sprint(db->name, "eia%d%2.2dstat", astar[dev]->id, ch); | |
| 1994/1111 | db->mode = 0444; | |
| 1994/1115 | db->qid.path = QID(dev, ch, Qstat); | |
| 1994/1111 | break; | |
| 1994/1120/sys/src/9/pc/devastar.c:385,391 – 1994/1121/sys/src/9/pc/devastar.c:387,393 | ||
| 1994/1106 | void | |
| 1994/1107 | astarreset(void) | |
| 1994/1106 | { | |
| 1994/1115 |
| |
| 1994/1121 | int i; | |
| 1994/1107 | Astar *a; | |
| 1994/1106 | for(i = 0; i < Maxcard; i++){ | |
| 1994/1120/sys/src/9/pc/devastar.c:421,426 – 1994/1121/sys/src/9/pc/devastar.c:423,431 | ||
| 1994/1107 | } | |
| 1994/1120 | print("serial%d avanstar port 0x%lux addr %lux irq %d\n", a->id, a->port, | |
| 1994/1115 | a->addr, a->irq); | |
| 1994/1121 | 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)); | |
| 1994/1109 | nastar++; | |
| 1994/1107 | } } | |
| 1994/1120/sys/src/9/pc/devastar.c:445,451 – 1994/1121/sys/src/9/pc/devastar.c:450,456 | ||
| 1994/1109 | static int | |
| 1994/1107 | astarsetup(Astar *a) { | |
| 1994/1120 |
| |
| 1994/1121 | int i, found; | |
| 1994/1107 | /* see if the card exists */ found = 0; | |
| 1994/1120/sys/src/9/pc/devastar.c:476,494 – 1994/1121/sys/src/9/pc/devastar.c:481,494 | ||
| 1994/1120 | a->gcb = (GCB*)(KZERO | a->mem); a->addr = (uchar*)(KZERO | a->mem); | |
| 1994/1121 | outb(a->port+ISActl2, 0); | |
| 1994/1120 | a->memsize = 0; a->page = -1; | |
| 1994/1121 | /* reset processor */ outb(a->port+ISActl1, 0); | |
| 1994/1111 | return 0; } | |
| 1994/1120/sys/src/9/pc/devastar.c:648,653 – 1994/1121/sys/src/9/pc/devastar.c:648,682 | ||
| 1994/1113 | return readstr(offset, buf, n, s); } | |
| 1994/1121 | 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); } | |
| 1994/1111 | long astarread(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/1120/sys/src/9/pc/devastar.c:658,663 – 1994/1121/sys/src/9/pc/devastar.c:687,695 | ||
| 1994/1111 | return devdirread(c, buf, n, 0, 0, astargen); switch(TYPE(c->qid.path)){ | |
| 1994/1121 | case Qstat: a = astar[BOARD(c->qid.path)]; return statread(a->c + CHAN(c->qid.path), buf, n, offset); | |
| 1994/1111 | case Qmem: | |
| 1994/1113 | return memread(astar[BOARD(c->qid.path)], buf, n, offset); case Qbctl: | |
| 1994/1120/sys/src/9/pc/devastar.c:731,737 – 1994/1121/sys/src/9/pc/devastar.c:763,768 | ||
| 1994/1113 | error(Eio); /* take board out of download mode and enable IRQ */ | |
| 1994/1119 |
| |
| 1994/1120 | c = inb(a->port+ISActl1); outb(a->port+ISActl1, c|ISAien|ISAnotdl); | |
| 1994/1113 | a->memsize = a->ramsize; | |
| 1994/1120/sys/src/9/pc/devastar.c:739,747 – 1994/1121/sys/src/9/pc/devastar.c:770,779 | ||
| 1994/1116 | a->needpage = 0; else a->needpage = 1; | |
| 1994/1121 | a->page = -1; setpage(a, 0); | |
| 1994/1113 | /* wait for control program to signal life */ | |
| 1994/1119 |
| |
| 1994/1113 | for(i = 0; i < 21; i++){ if(inb(a->port+ISActl1) & ISApr) break; | |
| 1994/1120/sys/src/9/pc/devastar.c:788,804 – 1994/1121/sys/src/9/pc/devastar.c:820,832 | ||
| 1994/1112 | } | |
| 1994/1113 | } | |
| 1994/1116 | ||
| 1994/1119 |
| |
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1114 | poperror(); | |
| 1994/1119 |
| |
| 1994/1113 | /* setup the channels */ a->running = 1; a->nchan = i; | |
| 1994/1121 | a->c = smalloc(a->nchan * sizeof(Astarchan)); | |
| 1994/1113 | for(i = 0; i < a->nchan; i++){ | |
| 1994/1114 | ac = &a->c[i]; ac->a = a; | |
| 1994/1120/sys/src/9/pc/devastar.c:808,813 – 1994/1121/sys/src/9/pc/devastar.c:836,854 | ||
| 1994/1114 | ac->oq = qopen(4*1024, 0, astarkick, ac); | |
| 1994/1113 | x += sz; } | |
| 1994/1121 | /* 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); | |
| 1994/1113 | } | |
| 1994/1115 | static void | |
| 1994/1120/sys/src/9/pc/devastar.c:1006,1011 – 1994/1121/sys/src/9/pc/devastar.c:1047,1053 | ||
| 1994/1114 | n |= Cdtrctl; else n &= ~Cdtrctl; | |
| 1994/1121 | ac->dtr = n; | |
| 1994/1114 | ccb->mctl = LEUS(n); | |
| 1994/1112 | break; | |
| 1994/1113 | case 'f': | |
| 1994/1120/sys/src/9/pc/devastar.c:1300,1314 – 1994/1121/sys/src/9/pc/devastar.c:1342,1356 | ||
| 1994/1114 | Astar *a = arg; Astarchan *ac; ulong vec, invec, outvec, errvec, mvec, cmdvec; | |
| 1994/1121 | int c; | |
| 1994/1114 | USED(ur); | |
| 1994/1121 | if(a->running == 0) panic("astar interrupt but cp not running\n"); | |
| 1994/1114 | lock(&a->pagelock); | |
| 1994/1116 | if(a->needpage) setpage(a, 0); | |
| 1994/1119 |
| |
| 1994/1114 | /* get causes */ invec = LEUS(xchgw(&a->gcb->inserv, 0)); | |
| 1994/1120/sys/src/9/pc/devastar.c:1318,1324 – 1994/1121/sys/src/9/pc/devastar.c:1360,1365 | ||
| 1994/1114 | cmdvec = LEUS(xchgw(&a->gcb->cmdserv, 0)); | |
| 1994/1115 | USED(mvec); USED(cmdvec); | |
| 1994/1114 | /* reenable interrupts */ | |
| 1994/1115 | a->gcb->cmd2 = LEUS(Gintack); | |
| 1994/1120/sys/src/9/pc/devastar.c:1340,1345 – 1994/1121/sys/src/9/pc/devastar.c:1381,1395 | ||
| 1994/1115 | for(vec = cmdvec; vec; vec >>= 1){ | |
| 1994/1114 | if(vec&1) wakeup(&ac->r); | |
| 1994/1121 | 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++; | |
| 1994/1114 | ac++; } unlock(&a->pagelock); | |
| 1994/1121/sys/src/9/pc/devastar.c:265,270 – 1994/1122/sys/src/9/pc/devastar.c:265,271 (short | long) | ||
| 1994/1121 | int framing; /* framing errors */ int overrun; /* overruns */ int dtr; /* non-zero means dtr on */ | |
| 1994/1122 | int rts; /* non-zero means rts on */ | |
| 1994/1107 | ||
| 1994/1106 | Queue *iq; Queue *oq; | |
| 1994/1121/sys/src/9/pc/devastar.c:282,289 – 1994/1122/sys/src/9/pc/devastar.c:283,290 | ||
| 1994/1111 | Qstat, }; #define TYPE(x) ((x)&0xff) | |
| 1994/1122 | #define BOARD(x) (((x)>>16)&0xff) #define CHAN(x) (((x)>>8)&0xff) | |
| 1994/1111 | #define QID(b,c,t) (((b)<<16)|((c)<<8)|(t)) | |
| 1994/1114 | static int astarsetup(Astar*); | |
| 1994/1121/sys/src/9/pc/devastar.c:576,582 – 1994/1122/sys/src/9/pc/devastar.c:577,583 | ||
| 1994/1115 | qunlock(ac); | |
| 1994/1114 | nexterror(); | |
| 1994/1112 | } | |
| 1994/1115 |
| |
| 1994/1122 | if(--(ac->opens) == 0){ | |
| 1994/1114 | disable(ac); | |
| 1994/1115 | qclose(ac->iq); qclose(ac->oq); | |
| 1994/1121/sys/src/9/pc/devastar.c:660,666 – 1994/1122/sys/src/9/pc/devastar.c:661,668 | ||
| 1994/1121 | UNLOCKPAGE(ac->a); /* CCB.mstat fields */ | |
| 1994/1122 | sprint(s, "opens %d ferr %d oerr %d baud %d", ac->opens, ac->framing, ac->overrun, ac->baud); | |
| 1994/1121 | if(mstat & Cctsstat) strcat(s, " cts"); if(mstat & Cdsrstat) | |
| 1994/1121/sys/src/9/pc/devastar.c:669,678 – 1994/1122/sys/src/9/pc/devastar.c:671,681 | ||
| 1994/1121 | strcat(s, " ring"); if(mstat & Cdcdstat) strcat(s, " dcd"); | |
| 1994/1122 | if(ac->dtr) | |
| 1994/1121 | strcat(s, " dtr"); | |
| 1994/1122 | if(ac->rts && (bstat & Crbrts) == 0) | |
| 1994/1121 | strcat(s, " rts"); | |
| 1994/1122 | strcat(s, "\n"); | |
| 1994/1121 | return readstr(offset, buf, n, s); } | |
| 1994/1121/sys/src/9/pc/devastar.c:831,836 – 1994/1122/sys/src/9/pc/devastar.c:834,840 | ||
| 1994/1114 | ac = &a->c[i]; ac->a = a; ac->ccb = (CCB*)x; | |
| 1994/1122 | ac->baud = 9600; /* a100i default */ | |
| 1994/1115 | ac->perm = 0660; | |
| 1994/1116 | ac->iq = qopen(4*1024, 0, astarkickin, ac); | |
| 1994/1114 | ac->oq = qopen(4*1024, 0, astarkick, ac); | |
| 1994/1121/sys/src/9/pc/devastar.c:960,966 – 1994/1122/sys/src/9/pc/devastar.c:964,969 | ||
| 1994/1116 | UNLOCKPAGE(a); | |
| 1994/1115 | chancmd(ac, Cconfall); | |
| 1994/1114 |
| |
| 1994/1121/sys/src/9/pc/devastar.c:1047,1053 – 1994/1122/sys/src/9/pc/devastar.c:1050,1056 | ||
| 1994/1114 | n |= Cdtrctl; else n &= ~Cdtrctl; | |
| 1994/1121 |
| |
| 1994/1122 | ac->dtr = i; | |
| 1994/1114 | ccb->mctl = LEUS(n); | |
| 1994/1112 | break; | |
| 1994/1113 | case 'f': | |
| 1994/1121/sys/src/9/pc/devastar.c:1126,1131 – 1994/1122/sys/src/9/pc/devastar.c:1129,1135 | ||
| 1994/1114 | else n &= ~Crtsctl; ccb->mctl = LEUS(n); | |
| 1994/1122 | ac->rts = i; | |
| 1994/1113 | break; case 'Q': case 'q': | |
| 1994/1122/sys/src/9/pc/devastar.c:417,422 – 1994/1210/sys/src/9/pc/devastar.c:417,425 (short | long) | ||
| 1994/1107 | a->irq = 15; a->id = i; | |
| 1994/1210 | if(isaget(a->mem, Pagesize, 0) == 0) panic("astarreset: %lux", a->mem); | |
| 1994/1107 | if(astarsetup(a) < 0){ xfree(a); | |
| 1994/1109 | astar[nastar] = 0; | |
| 1994/1210/sys/src/9/pc/devastar.c:417,423 – 1994/1218/sys/src/9/pc/devastar.c:417,423 (short | long) | ||
| 1994/1107 | a->irq = 15; a->id = i; | |
| 1994/1210 |
| |
| 1994/1218 | if(getisa(a->mem, Pagesize, 0) == 0) | |
| 1994/1210 | panic("astarreset: %lux", a->mem); | |
| 1994/1107 | if(astarsetup(a) < 0){ | |
| 1994/1218/sys/src/9/pc/devastar.c:411,424 – 1995/0106/sys/src/9/pc/devastar.c:411,424 (short | long) | ||
| 1994/1118 | } | |
| 1994/1108 | ||
| 1994/1120 | /* defaults */ | |
| 1994/1107 |
| |
| 1994/1108 |
| |
| 1994/1107 | if(a->irq == 0) a->irq = 15; a->id = i; | |
| 1994/1218 |
| |
| 1995/0106 | a->mem = getisa(a->mem, Pagesize, Pagesize); if(a->mem == 0) | |
| 1994/1210 | panic("astarreset: %lux", a->mem); | |
| 1995/0106 | a->mem & ~KZERO; | |
| 1994/1210 | ||
| 1994/1107 | if(astarsetup(a) < 0){ xfree(a); | |
| 1995/0106/sys/src/9/pc/devastar.c:709,714 – 1995/0108/sys/src/9/pc/devastar.c:709,720 (short | long) | ||
| 1994/1113 | return 0; } | |
| 1994/1112 | ||
| 1995/0108 | Block* astarbread(Chan *c, long n, ulong offset) { return devbread(c, n, offset); } | |
| 1994/1114 | /* * write ISA mapped memory */ | |
| 1995/0106/sys/src/9/pc/devastar.c:1198,1203 – 1995/0108/sys/src/9/pc/devastar.c:1204,1215 | ||
| 1994/1111 | } | |
| 1994/1109 | return 0; | |
| 1995/0108 | } long astarbwrite(Chan *c, Block *bp, ulong offset) { return devbwrite(c, bp, offset); | |
| 1994/1112 | } void | |
| 1995/0108/sys/src/9/pc/devastar.c:418,424 – 1995/0115/sys/src/9/pc/devastar.c:418,424 (short | long) | ||
| 1995/0106 | a->mem = getisa(a->mem, Pagesize, Pagesize); if(a->mem == 0) | |
| 1994/1210 | panic("astarreset: %lux", a->mem); | |
| 1995/0106 |
| |
| 1995/0115 | a->mem &= ~KZERO; | |
| 1994/1210 | ||
| 1994/1107 | if(astarsetup(a) < 0){ xfree(a); | |
| 1995/0115/sys/src/9/pc/devastar.c:546,551 – 1995/0127/sys/src/9/pc/devastar.c:546,552 (short | long) | ||
| 1994/1114 | qlock(ac); if(waserror()){ | |
| 1994/1115 | qunlock(ac); | |
| 1995/0127 | ac->qopens--; | |
| 1994/1114 | nexterror(); } | |
| 1994/1116 | if(ac->opens++ == 0){ | |
| 1995/0127/sys/src/9/pc/devastar.c:546,552 – 1995/0207/sys/src/9/pc/devastar.c:546,552 (short | long) | ||
| 1994/1114 | qlock(ac); if(waserror()){ | |
| 1994/1115 | qunlock(ac); | |
| 1995/0127 |
| |
| 1995/0207 | ac->opens--; | |
| 1994/1114 | nexterror(); } | |
| 1994/1116 | if(ac->opens++ == 0){ | |
| 1995/0207/sys/src/9/pc/devastar.c:762,768 – 1995/0505/sys/src/9/pc/devastar.c:762,768 (short | long) | ||
| 1994/1113 | } /* | |
| 1995/0505 | * start control program | |
| 1994/1113 | */ static void startcp(Astar *a) | |
| 1995/0505/sys/src/9/pc/devastar.c:1214,1222 – 1995/0726/sys/src/9/pc/devastar.c:1214,1221 (short | long) | ||
| 1994/1112 | } void | |
| 1995/0726 | astarcreate(Chan*, char*, int, ulong) | |
| 1994/1112 | { | |
| 1995/0726/sys/src/9/pc/devastar.c:6,12 – 1996/0223/sys/src/9/pc/devastar.c:6,11 (short | long) | ||
| 1994/1106 | #include "io.h" #include "../port/error.h" | |
| 1994/1107 | * Stargate's Avanstar serial board. There are ISA, EISA, microchannel | |
| Too many diffs (26 > 25). Stopping. | ||