13e12c5d1SDavid du Colombier #include "all.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier #define DEBUG 0
43e12c5d1SDavid du Colombier
53e12c5d1SDavid du Colombier long niob;
63e12c5d1SDavid du Colombier long nhiob;
73e12c5d1SDavid du Colombier Hiob *hiob;
83e12c5d1SDavid du Colombier
93e12c5d1SDavid du Colombier Iobuf*
getbuf(Device dev,long addr,int flag)103e12c5d1SDavid du Colombier getbuf(Device dev, long addr, int flag)
113e12c5d1SDavid du Colombier {
123e12c5d1SDavid du Colombier Iobuf *p, *s;
133e12c5d1SDavid du Colombier Hiob *hp;
143e12c5d1SDavid du Colombier long h;
153e12c5d1SDavid du Colombier
163e12c5d1SDavid du Colombier if(DEBUG)
173e12c5d1SDavid du Colombier print("getbuf %D(%ld) f=%x\n", dev, addr, flag);
183e12c5d1SDavid du Colombier h = addr +
193e12c5d1SDavid du Colombier dev.type*1009L +
203e12c5d1SDavid du Colombier dev.ctrl*10007L +
213e12c5d1SDavid du Colombier dev.unit*100003L +
223e12c5d1SDavid du Colombier dev.part*1000003L;
233e12c5d1SDavid du Colombier if(h < 0)
243e12c5d1SDavid du Colombier h = ~h;
253e12c5d1SDavid du Colombier h %= nhiob;
263e12c5d1SDavid du Colombier hp = &hiob[h];
273e12c5d1SDavid du Colombier
283e12c5d1SDavid du Colombier loop:
293e12c5d1SDavid du Colombier lock(hp);
303e12c5d1SDavid du Colombier
313e12c5d1SDavid du Colombier /*
323e12c5d1SDavid du Colombier * look for it in the active list
333e12c5d1SDavid du Colombier */
343e12c5d1SDavid du Colombier s = hp->link;
353e12c5d1SDavid du Colombier for(p=s;;) {
363e12c5d1SDavid du Colombier if(p->addr == addr && !devcmp(p->dev, dev)) {
373e12c5d1SDavid du Colombier if(p != s) {
383e12c5d1SDavid du Colombier p->back->fore = p->fore;
393e12c5d1SDavid du Colombier p->fore->back = p->back;
403e12c5d1SDavid du Colombier p->fore = s;
413e12c5d1SDavid du Colombier p->back = s->back;
423e12c5d1SDavid du Colombier s->back = p;
433e12c5d1SDavid du Colombier p->back->fore = p;
443e12c5d1SDavid du Colombier hp->link = p;
453e12c5d1SDavid du Colombier }
463e12c5d1SDavid du Colombier unlock(hp);
473e12c5d1SDavid du Colombier qlock(p);
483e12c5d1SDavid du Colombier if(p->addr != addr || devcmp(p->dev, dev)) {
493e12c5d1SDavid du Colombier qunlock(p);
503e12c5d1SDavid du Colombier goto loop;
513e12c5d1SDavid du Colombier }
523e12c5d1SDavid du Colombier p->flags |= flag;
533e12c5d1SDavid du Colombier cons.bhit.count++;
543e12c5d1SDavid du Colombier p->iobuf = p->xiobuf;
553e12c5d1SDavid du Colombier return p;
563e12c5d1SDavid du Colombier }
573e12c5d1SDavid du Colombier p = p->fore;
583e12c5d1SDavid du Colombier if(p == s)
593e12c5d1SDavid du Colombier break;
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier if(flag & Bprobe) {
623e12c5d1SDavid du Colombier unlock(hp);
633e12c5d1SDavid du Colombier return 0;
643e12c5d1SDavid du Colombier }
653e12c5d1SDavid du Colombier
663e12c5d1SDavid du Colombier /*
673e12c5d1SDavid du Colombier * not found
683e12c5d1SDavid du Colombier * take oldest unlocked entry in this queue
693e12c5d1SDavid du Colombier */
703e12c5d1SDavid du Colombier xloop:
713e12c5d1SDavid du Colombier p = s->back;
723e12c5d1SDavid du Colombier if(!canqlock(p)) {
733e12c5d1SDavid du Colombier if(p == hp->link) {
743e12c5d1SDavid du Colombier unlock(hp);
753e12c5d1SDavid du Colombier print("iobuf all locked\n");
763e12c5d1SDavid du Colombier goto loop;
773e12c5d1SDavid du Colombier }
783e12c5d1SDavid du Colombier s = p;
793e12c5d1SDavid du Colombier goto xloop;
803e12c5d1SDavid du Colombier }
813e12c5d1SDavid du Colombier /*
823e12c5d1SDavid du Colombier * its dangerous to flush the pseudo
833e12c5d1SDavid du Colombier * devices since they recursively call
843e12c5d1SDavid du Colombier * getbuf/putbuf. deadlock!
853e12c5d1SDavid du Colombier */
863e12c5d1SDavid du Colombier if(p->flags & Bres) {
873e12c5d1SDavid du Colombier qunlock(p);
883e12c5d1SDavid du Colombier if(p == hp->link) {
893e12c5d1SDavid du Colombier unlock(hp);
903e12c5d1SDavid du Colombier print("iobuf all resed\n");
913e12c5d1SDavid du Colombier goto loop;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier s = p;
943e12c5d1SDavid du Colombier goto xloop;
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier if(p->flags & Bmod) {
973e12c5d1SDavid du Colombier unlock(hp);
983e12c5d1SDavid du Colombier if(!devwrite(p->dev, p->addr, p->xiobuf))
993e12c5d1SDavid du Colombier p->flags &= ~(Bimm|Bmod);
1003e12c5d1SDavid du Colombier qunlock(p);
1013e12c5d1SDavid du Colombier goto loop;
1023e12c5d1SDavid du Colombier }
1033e12c5d1SDavid du Colombier hp->link = p;
1043e12c5d1SDavid du Colombier p->addr = addr;
1053e12c5d1SDavid du Colombier p->dev = dev;
1063e12c5d1SDavid du Colombier p->flags = flag;
1073e12c5d1SDavid du Colombier unlock(hp);
1083e12c5d1SDavid du Colombier p->iobuf = p->xiobuf;
1093e12c5d1SDavid du Colombier if(flag & Bread) {
1103e12c5d1SDavid du Colombier if(devread(p->dev, p->addr, p->iobuf)) {
1113e12c5d1SDavid du Colombier p->flags = 0;
1123e12c5d1SDavid du Colombier p->dev = devnone;
1133e12c5d1SDavid du Colombier p->addr = -1;
1143e12c5d1SDavid du Colombier p->iobuf = (char*)-1;
1153e12c5d1SDavid du Colombier qunlock(p);
1163e12c5d1SDavid du Colombier return 0;
1173e12c5d1SDavid du Colombier }
1183e12c5d1SDavid du Colombier cons.bread.count++;
1193e12c5d1SDavid du Colombier return p;
1203e12c5d1SDavid du Colombier }
1213e12c5d1SDavid du Colombier cons.binit.count++;
1223e12c5d1SDavid du Colombier return p;
1233e12c5d1SDavid du Colombier }
1243e12c5d1SDavid du Colombier
1253e12c5d1SDavid du Colombier /*
1263e12c5d1SDavid du Colombier * syncblock tries to put out a block per hashline
1273e12c5d1SDavid du Colombier * returns 0 all done,
1283e12c5d1SDavid du Colombier * returns 1 if it missed something
1293e12c5d1SDavid du Colombier */
1303e12c5d1SDavid du Colombier int
syncblock(void)1313e12c5d1SDavid du Colombier syncblock(void)
1323e12c5d1SDavid du Colombier {
1333e12c5d1SDavid du Colombier Iobuf *p, *s, *q;
1343e12c5d1SDavid du Colombier Hiob *hp;
1353e12c5d1SDavid du Colombier long h;
1363e12c5d1SDavid du Colombier int flag;
1373e12c5d1SDavid du Colombier
1383e12c5d1SDavid du Colombier flag = 0;
1393e12c5d1SDavid du Colombier for(h=0; h<nhiob; h++) {
1403e12c5d1SDavid du Colombier q = 0;
1413e12c5d1SDavid du Colombier hp = &hiob[h];
1423e12c5d1SDavid du Colombier lock(hp);
1433e12c5d1SDavid du Colombier s = hp->link;
1443e12c5d1SDavid du Colombier for(p=s;;) {
1453e12c5d1SDavid du Colombier if(p->flags & Bmod) {
1463e12c5d1SDavid du Colombier if(q)
1473e12c5d1SDavid du Colombier flag = 1; /* more than 1 mod/line */
1483e12c5d1SDavid du Colombier q = p;
1493e12c5d1SDavid du Colombier }
1503e12c5d1SDavid du Colombier p = p->fore;
1513e12c5d1SDavid du Colombier if(p == s)
1523e12c5d1SDavid du Colombier break;
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier unlock(hp);
1553e12c5d1SDavid du Colombier if(q) {
1563e12c5d1SDavid du Colombier if(!canqlock(q)) {
1573e12c5d1SDavid du Colombier flag = 1; /* missed -- was locked */
1583e12c5d1SDavid du Colombier continue;
1593e12c5d1SDavid du Colombier }
1603e12c5d1SDavid du Colombier if(!(q->flags & Bmod)) {
1613e12c5d1SDavid du Colombier qunlock(q);
1623e12c5d1SDavid du Colombier continue;
1633e12c5d1SDavid du Colombier }
1643e12c5d1SDavid du Colombier if(!devwrite(q->dev, q->addr, q->xiobuf))
1653e12c5d1SDavid du Colombier q->flags &= ~(Bmod|Bimm);
1663e12c5d1SDavid du Colombier qunlock(q);
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier return flag;
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier
1723e12c5d1SDavid du Colombier void
sync(char * reason)1733e12c5d1SDavid du Colombier sync(char *reason)
1743e12c5d1SDavid du Colombier {
1753e12c5d1SDavid du Colombier long i;
1763e12c5d1SDavid du Colombier
1773e12c5d1SDavid du Colombier print("sync: %s\n", reason);
1783e12c5d1SDavid du Colombier for(i=10*nhiob; i>0; i--)
1793e12c5d1SDavid du Colombier if(!syncblock())
1803e12c5d1SDavid du Colombier return;
1813e12c5d1SDavid du Colombier print("sync shorted\n");
1823e12c5d1SDavid du Colombier }
1833e12c5d1SDavid du Colombier
1843e12c5d1SDavid du Colombier void
putbuf(Iobuf * p)1853e12c5d1SDavid du Colombier putbuf(Iobuf *p)
1863e12c5d1SDavid du Colombier {
1873e12c5d1SDavid du Colombier if(canqlock(p))
1883e12c5d1SDavid du Colombier print("buffer not locked %D(%ld)\n", p->dev, p->addr);
1893e12c5d1SDavid du Colombier if(p->flags & Bimm) {
1903e12c5d1SDavid du Colombier if(!(p->flags & Bmod))
1913e12c5d1SDavid du Colombier print("imm and no mod %D(%ld)\n", p->dev, p->addr);
1923e12c5d1SDavid du Colombier if(!devwrite(p->dev, p->addr, p->iobuf))
1933e12c5d1SDavid du Colombier p->flags &= ~(Bmod|Bimm);
1943e12c5d1SDavid du Colombier }
1953e12c5d1SDavid du Colombier p->iobuf = (char*)-1;
1963e12c5d1SDavid du Colombier qunlock(p);
1973e12c5d1SDavid du Colombier }
1983e12c5d1SDavid du Colombier
1993e12c5d1SDavid du Colombier int
checktag(Iobuf * p,int tag,long qpath)2003e12c5d1SDavid du Colombier checktag(Iobuf *p, int tag, long qpath)
2013e12c5d1SDavid du Colombier {
2023e12c5d1SDavid du Colombier Tag *t;
2033e12c5d1SDavid du Colombier
2043e12c5d1SDavid du Colombier t = (Tag*)(p->iobuf+BUFSIZE);
2053e12c5d1SDavid du Colombier if(t->tag != tag) {
2063e12c5d1SDavid du Colombier if(1 || CHAT(0))
207*9a747e4fSDavid du Colombier print(" tag = %G; expected %G; addr = %lud\n",
208*9a747e4fSDavid du Colombier t->tag, tag, p->addr);
2093e12c5d1SDavid du Colombier return 2;
2103e12c5d1SDavid du Colombier }
2113e12c5d1SDavid du Colombier if(qpath != QPNONE) {
2123e12c5d1SDavid du Colombier qpath &= ~QPDIR;
2133e12c5d1SDavid du Colombier if(qpath != t->path) {
2143e12c5d1SDavid du Colombier if(qpath == (t->path&~QPDIR)) /* old bug */
2153e12c5d1SDavid du Colombier return 0;
2163e12c5d1SDavid du Colombier if(1 || CHAT(0))
2173e12c5d1SDavid du Colombier print(" tag/path = %lux; expected %G/%lux\n",
2183e12c5d1SDavid du Colombier t->path, tag, qpath);
2193e12c5d1SDavid du Colombier return 1;
2203e12c5d1SDavid du Colombier }
2213e12c5d1SDavid du Colombier }
2223e12c5d1SDavid du Colombier return 0;
2233e12c5d1SDavid du Colombier }
2243e12c5d1SDavid du Colombier
2253e12c5d1SDavid du Colombier void
settag(Iobuf * p,int tag,long qpath)2263e12c5d1SDavid du Colombier settag(Iobuf *p, int tag, long qpath)
2273e12c5d1SDavid du Colombier {
2283e12c5d1SDavid du Colombier Tag *t;
2293e12c5d1SDavid du Colombier
2303e12c5d1SDavid du Colombier t = (Tag*)(p->iobuf+BUFSIZE);
2313e12c5d1SDavid du Colombier t->tag = tag;
2323e12c5d1SDavid du Colombier if(qpath != QPNONE)
2333e12c5d1SDavid du Colombier t->path = qpath & ~QPDIR;
2343e12c5d1SDavid du Colombier p->flags |= Bmod;
2353e12c5d1SDavid du Colombier }
236