| plan 9 kernel history: overview | file list | diff list |
1991/0306/power/devhotrod.c (diff list | history)
| 1991/0304/sys/src/9/power/devhotrod.c:10,41 – 1991/0306/sys/src/9/power/devhotrod.c:10,37 (short | long | prev | next) | ||
| 1990/1013 | #include "io.h" | |
| 1991/0215 | #include "hrod.h" | |
| 1990/1013 | ||
| 1991/0306 | /* * If defined, causes memory test to be run at device open */ #ifdef ENABMEMTEST | |
| 1991/0303 | void mem(Hot*, ulong*, ulong); | |
| 1991/0306 | #endif | |
| 1991/0303 | /* * If set, causes data transfers to have checksums */ | |
| 1991/0304 |
| |
| 1991/0306 | #define ENABCKSUM 1 | |
| 1991/0303 | ||
| 1990/1013 | typedef struct Hotrod Hotrod; | |
| 1991/0209 |
| |
| 1990/1013 |
| |
| 1991/0306 | enum{ | |
| 1990/1013 | Vmevec= 0xd2, /* vme vector for interrupts */ Intlevel= 5, /* level to interrupt on */ | |
| 1991/0209 | Qdir= 0, /* Qid's */ Qhotrod= 1, | |
| 1991/0215 |
| |
| 1991/0209 | Nhotrod= 1, | |
| 1990/1013 | }; | |
| 1991/0209 |
| |
| 1990/1013 | ||
| 1991/0209 |
| |
| 1991/0212 | QLock buflock; | |
| 1991/0304/sys/src/9/power/devhotrod.c:42,52 – 1991/0306/sys/src/9/power/devhotrod.c:38,46 | ||
| 1991/0209 | Lock busy; | |
| 1991/0215 | Hot *addr; /* address of the device */ | |
| 1990/1106 | int vec; /* vme interrupt vector */ | |
| 1991/0209 |
| |
| 1991/0306 | ulong rq[NRQ]; /* read this queue to receive replies */ | |
| 1991/0209 | int ri; /* where to read next response */ | |
| 1990/1106 |
| |
| 1991/0220 | uchar buf[MAXFDATA+MAXMSG]; | |
| 1990/1013 | }; | |
| 1991/0304/sys/src/9/power/devhotrod.c:74,83 – 1991/0306/sys/src/9/power/devhotrod.c:68,77 | ||
| 1991/0304 | long l; | |
| 1991/0220 | /* print("hotsend send %d %d %lux %lux\n", h->wi, m->cmd, m, m->param[0]); /**/ | |
| 1991/0304 |
| |
| 1991/0306 | mp = (Hotmsg**)&h->addr->hostrq[h->wi]; | |
| 1991/0304 | *mp = (Hotmsg*)MP2VME(m); | |
| 1991/0209 | h->wi++; | |
| 1991/0306 | if(h->wi >= NRQ) | |
| 1991/0209 | h->wi = 0; | |
| 1991/0304 | l = 0; while(*mp){ | |
| 1991/0304/sys/src/9/power/devhotrod.c:103,109 – 1991/0306/sys/src/9/power/devhotrod.c:97,102 | ||
| 1991/0209 | /* * Write queue is at end of hotrod memory */ | |
| 1991/0215 |
| |
| 1991/0209 | hp->vec = Vmevec+i; setvmevec(hp->vec, hotrodintr); | |
| 1990/1013 | } | |
| 1991/0304/sys/src/9/power/devhotrod.c:181,188 – 1991/0306/sys/src/9/power/devhotrod.c:174,181 | ||
| 1991/0209 | /* * Clear communications region */ | |
| 1991/0306 | memset(hp->addr->hostrq, 0, NRQ*sizeof(ulong)); hp->addr->hostrp = 0; | |
| 1991/0209 | /* * Issue reset | |
| 1991/0304/sys/src/9/power/devhotrod.c:191,203 – 1991/0306/sys/src/9/power/devhotrod.c:184,196 | ||
| 1991/0209 | hp->ri = 0; | |
| 1991/0212 | mp = &u->khot; mp->cmd = RESET; | |
| 1991/0306 | mp->param[0] = MP2VME(hp->rq); mp->param[1] = NRQ; | |
| 1991/0209 | hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot); | |
| 1991/0215 | delay(100); | |
| 1991/0214 | print("reset\n"); | |
| 1991/0219 | ||
| 1991/0302 |
| |
| 1991/0306 | #ifdef ENABMEMTEST | |
| 1991/0219 | /* * Issue test */ | |
| 1991/0304/sys/src/9/power/devhotrod.c:253,258 – 1991/0306/sys/src/9/power/devhotrod.c:246,257 | ||
| 1991/0303 | return sum; } | |
| 1991/0306 | int hotmsgintr(Hotmsg *hm) { return hm->intr; } | |
| 1990/1013 | /* | |
| 1991/0212 | * Read and write use physical addresses if they can, which they usually can. * Most I/O is from devmnt, which has local buffers. Therefore just check | |
| 1991/0304/sys/src/9/power/devhotrod.c:264,270 – 1991/0306/sys/src/9/power/devhotrod.c:263,269 | ||
| 1990/1013 | { Hotrod *hp; | |
| 1991/0212 | Hotmsg *mp; | |
| 1991/0303 |
| |
| 1991/0306 | ulong l, m, isflush; | |
| 1990/1013 | hp = &hotrod[c->dev]; | |
| 1991/0212 | switch(c->qid.path){ | |
| 1991/0304/sys/src/9/power/devhotrod.c:277,283 – 1991/0306/sys/src/9/power/devhotrod.c:276,287 | ||
| 1991/0212 | /* * use supplied buffer, no need to lock for reply */ | |
| 1991/0306 | isflush = 0; mp = &((User*)(u->p->upage->pa|KZERO))->khot; if(mp->abort){ /* use reserved flush msg */ mp = &((User*)(u->p->upage->pa|KZERO))->fhot; isflush = 1; } | |
| 1991/0303 | mp->param[2] = 0; /* checksum */ mp->param[3] = 0; /* reply count */ | |
| 1991/0212 | qlock(hp); | |
| 1991/0304/sys/src/9/power/devhotrod.c:284,295 – 1991/0306/sys/src/9/power/devhotrod.c:288,310 | ||
| 1991/0212 | mp->cmd = READ; mp->param[0] = MP2VME(buf); mp->param[1] = n; | |
| 1991/0306 | mp->abort = isflush; mp->intr = 0; hotsend(hp, mp); | |
| 1991/0212 | qunlock(hp); | |
| 1991/0220 |
| |
| 1991/0212 |
| |
| 1991/0306 | if(isflush){ /* busy loop */ l = 100*1000*1000; do m = mp->param[3]; while(m==0 && --l>0); }else{ if(waserror()){ mp->abort = 1; nexterror(); } sleep(&mp->r, hotmsgintr, mp); | |
| 1991/0303 | m = mp->param[3]; | |
| 1991/0306 | } | |
| 1991/0303 | if(m==0 || m>n){ print("devhotrod: count %ld %ld\n", m, n); | |
| 1991/0215 | error(Egreg); | |
| 1991/0304/sys/src/9/power/devhotrod.c:299,309 – 1991/0306/sys/src/9/power/devhotrod.c:314,326 | ||
| 1991/0303 | hotsum(buf, n, 1), mp->param[2]); error(Eio); } | |
| 1991/0306 | if(!isflush) poperror(); | |
| 1991/0212 | }else{ /* | |
| 1991/0215 |
| |
| 1991/0306 | * use hotrod buffer. lock the buffer until the reply | |
| 1991/0212 | */ | |
| 1991/0306 | mp = &((User*)(u->p->upage->pa|KZERO))->uhot; | |
| 1991/0303 | mp->param[2] = 0; /* checksum */ mp->param[3] = 0; /* reply count */ | |
| 1991/0212 | qlock(&hp->buflock); | |
| 1991/0304/sys/src/9/power/devhotrod.c:311,317 – 1991/0306/sys/src/9/power/devhotrod.c:328,336 | ||
| 1991/0212 | mp->cmd = READ; mp->param[0] = MP2VME(hp->buf); mp->param[1] = n; | |
| 1991/0306 | mp->abort = 1; mp->intr = 0; hotsend(hp, mp); | |
| 1991/0212 | qunlock(hp); | |
| 1991/0215 | l = 100*1000*1000; | |
| 1991/0212 | do | |
| 1991/0304/sys/src/9/power/devhotrod.c:338,346 – 1991/0306/sys/src/9/power/devhotrod.c:357,362 | ||
| 1991/0212 | return 0; | |
| 1990/1013 | } | |
| 1991/0304/sys/src/9/power/devhotrod.c:356,376 – 1991/0306/sys/src/9/power/devhotrod.c:372,394 | ||
| 1991/0220 | } | |
| 1991/0212 | if((((ulong)buf)&(KSEGM|3)) == KSEG0){ /* | |
| 1991/0306 | * use supplied buffer, no need to lock for reply | |
| 1991/0212 | */ | |
| 1991/0306 | mp = &((User*)(u->p->upage->pa|KZERO))->khot; if(mp->abort) /* use reserved flush msg */ mp = &((User*)(u->p->upage->pa|KZERO))->fhot; | |
| 1991/0212 | qlock(hp); mp->cmd = WRITE; mp->param[0] = MP2VME(buf); mp->param[1] = n; | |
| 1991/0303 | mp->param[2] = hotsum(buf, n, ENABCKSUM); | |
| 1991/0212 |
| |
| 1991/0306 | hotsend(hp, mp); | |
| 1991/0212 | qunlock(hp); }else{ /* | |
| 1991/0304 |
| |
| 1991/0306 | * use hotrod buffer. lock the buffer until the reply | |
| 1991/0212 | */ | |
| 1991/0306 | mp = &((User*)(u->p->upage->pa|KZERO))->uhot; | |
| 1991/0212 | qlock(&hp->buflock); qlock(hp); memcpy(hp->buf, buf, n); | |
| 1991/0304/sys/src/9/power/devhotrod.c:378,384 – 1991/0306/sys/src/9/power/devhotrod.c:396,402 | ||
| 1991/0212 | mp->param[0] = MP2VME(hp->buf); mp->param[1] = n; | |
| 1991/0303 | mp->param[2] = hotsum((ulong*)hp->buf, n, ENABCKSUM); | |
| 1991/0212 |
| |
| 1991/0306 | hotsend(hp, mp); | |
| 1991/0212 | qunlock(hp); qunlock(&hp->buflock); } | |
| 1991/0304/sys/src/9/power/devhotrod.c:404,420 – 1991/0306/sys/src/9/power/devhotrod.c:422,448 | ||
| 1990/1106 | void | |
| 1990/1013 | hotrodintr(int vec) { | |
| 1991/0306 | Hotrod *h; Hotmsg *hm; | |
| 1990/1013 | ||
| 1991/0220 |
| |
| 1990/1013 |
| |
| 1991/0306 | h = &hotrod[vec - Vmevec]; if(h < hotrod || h > &hotrod[Nhotrod]){ | |
| 1990/1013 | print("bad hotrod vec\n"); return; } | |
| 1991/0219 |
| |
| 1991/0306 | h->addr->lcsr3 &= ~INT_VME; hm = (Hotmsg*)VME2MP(h->rq[h->ri]); h->rq[h->ri] = 0; h->ri++; if(h->ri >= NRQ) h->ri = 0; hm->intr = 1; if(hm->abort) return; wakeup(&hm->r); | |
| 1991/0303 | } | |
| 1991/0306 | #ifdef ENABMEMTEST | |
| 1991/0303 | void mem(Hot *hot, ulong *buf, ulong size) { | |
| 1991/0304/sys/src/9/power/devhotrod.c:504,506 – 1991/0306/sys/src/9/power/devhotrod.c:532,535 | ||
| 1991/0303 | } } | |
| 1990/1013 | } | |
| 1991/0306 | #endif | |