| plan 9 kernel history: overview | file list | diff list |
1994/1112/pc/devastar.c (diff list | history)
| 1994/1111/sys/src/9/pc/devastar.c:35,41 – 1994/1112/sys/src/9/pc/devastar.c:35,44 (short | long | prev | next) | ||
| 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 | } | |