|
|
1.1 ! root 1: #include "sys/param.h" ! 2: #include "sys/biaddr.h" ! 3: #include "sys/conf.h" ! 4: #include "sys/user.h" ! 5: #include "sys/buf.h" ! 6: #include "sys/pte.h" ! 7: ! 8: extern caddr_t bitest[]; ! 9: extern struct biaddr bitstaddr[]; ! 10: extern int bitstcnt; ! 11: ! 12: static bitstopen(); ! 13: static bitstread(), bitstwrite(); ! 14: struct cdevsw bitstcdev = cdinit(bitstopen, nulldev, bitstread, bitstwrite, nodev); ! 15: ! 16: char biscratch[4096]; ! 17: ! 18: /* ! 19: * BVP data structures ! 20: */ ! 21: ! 22: typedef struct quadque { ! 23: struct quadque *head, *tail; ! 24: } quadque; ! 25: ! 26: struct pqb { ! 27: quadque p_cmdq[4]; /* command queues */ ! 28: quadque p_rspq; /* response queue */ ! 29: short p_vector; /* interrupt vector, BR */ ! 30: short p_nodmsk; /* interrupt node mask */ ! 31: long p_nfreeq; /* number of free queues */ ! 32: struct fqb *p_fqb; /* fqp virtual address */ ! 33: char pp_junk0[156]; ! 34: long p_bvplvl; /* BVP protocol version */ ! 35: struct pqb *p_pqb; /* pqb virtual self-pointer */ ! 36: struct bdt *p_bdt; /* bdt virtual address */ ! 37: long p_bdtlen; /* and size */ ! 38: struct pte *p_spt; /* system page table phys addr */ ! 39: long p_sptlen; /* and size */ ! 40: struct pte *p_gpt; /* global page pable phys addr */ ! 41: long p_gptlen; /* and size */ ! 42: long p_funcmask; /* ?? */ ! 43: char pp_junk1[24]; ! 44: /* stuff filled in by port after init */ ! 45: short p_maxdg; /* max datagram size */ ! 46: short p_maxmsg; /* max message size */ ! 47: long p_ucodetype; ! 48: long p_ucodevers; ! 49: long p_hwtype; ! 50: long p_vers[3]; ! 51: char p_qelogo[216]; /* `queue entry logout area' */ ! 52: }; ! 53: ! 54: /* ! 55: * free queue block ! 56: */ ! 57: struct fqb { ! 58: long f_size; /* max size of things in this queue */ ! 59: long f_junk; /* reserved, apparently */ ! 60: quadque f_q; /* the free queue itself */ ! 61: }; ! 62: ! 63: #define NFREEQ 1 ! 64: ! 65: /* ! 66: * buffer descriptor ! 67: */ ! 68: struct bdt { ! 69: short b_flags; ! 70: short b_key; ! 71: long b_len; /* length of buffer */ ! 72: struct pte *b_pte; /* relevant page table */ ! 73: long b_sw; /* reserved for software */ ! 74: }; ! 75: ! 76: #define NBDT 1 ! 77: ! 78: /* ! 79: * bundle of data for one port ! 80: * the pqb must be page-aligned; ! 81: * stick this in a buffer, ! 82: * which means it must all fit in one ! 83: */ ! 84: struct bvpdata { ! 85: struct pqb p; ! 86: struct fqb f[NFREEQ]; ! 87: struct bdt b[NBDT]; ! 88: }; ! 89: ! 90: /* ! 91: * port registers ! 92: */ ! 93: struct regs { ! 94: long ctrl; ! 95: long stat; ! 96: long err; ! 97: long data; ! 98: }; ! 99: ! 100: /* ! 101: * control bits ! 102: */ ! 103: #define PCOWN 0x80 /* port own -- here is a command */ ! 104: #define PCINIT 1 ! 105: #define PCENAB 2 ! 106: #define PCCMDQ 6 /* command queue not empty */ ! 107: #define PCFREQ 7 /* free queue not empty */ ! 108: ! 109: /* ! 110: * status bits ! 111: */ ! 112: #define PSOWN 0x80000000 /* port own -- status valid */ ! 113: #define PSSTD 0x20000000 /* self test done */ ! 114: #define PSACC 0x10000000 /* adapter can communicate */ ! 115: #define PSSTAT 0x70000 /* port state: */ ! 116: #define SUNDEF 0x10000 /* undefined */ ! 117: #define SINIT 0x20000 /* initialized */ ! 118: #define SENAB 0x40000 /* enabled */ ! 119: #define PSERR 0x40 /* error summary */ ! 120: ! 121: /* ! 122: * to a header later ! 123: */ ! 124: struct bvp { ! 125: struct bvpdata *d; ! 126: struct regs *r; ! 127: struct buf *dbuf; ! 128: }; ! 129: ! 130: char *bitsnd, *bitrcv; /* places to put packets */ ! 131: ! 132: struct bvp bvp; ! 133: ! 134: static ! 135: bitstopen(dev, flag) ! 136: int dev, flag; ! 137: { ! 138: ! 139: if (minor(dev)) { ! 140: u.u_error = ENXIO; ! 141: return; ! 142: } ! 143: if (bitest[0] == 0) { /* wrong */ ! 144: if ((bitest[0] = biaddr(&bitstaddr[0])) == 0 ! 145: || badaddr(bitest[0], sizeof(long))) { ! 146: printf("bitest absent\n"); ! 147: u.u_error = ENXIO; ! 148: return; ! 149: } ! 150: bvp.r = (struct regs *)(bitest[0] + 0x204); /* cheat */ ! 151: bitsnd = biscratch+7; ! 152: bitrcv = bitsnd + 2048; ! 153: bitsnd -= (long)bitsnd & 07; /* quad align */ ! 154: bitrcv -= (long)bitrcv & 07; ! 155: } ! 156: if (bvpinit(&bvp) == 0) { ! 157: u.u_error = ENXIO; ! 158: return; ! 159: } ! 160: } ! 161: ! 162: /* ! 163: * read routine: ! 164: * nab a packet ! 165: */ ! 166: static ! 167: bitstread(dev) ! 168: { ! 169: register struct bvpdata *b; ! 170: ! 171: b = bvp.d; ! 172: b->f[0].f_size = 2048; ! 173: if (insqti(bitrcv, &b->p.p_fqb[0].f_q)) ! 174: bvpcomm(bvp.r, PCOWN|PCFREQ); ! 175: /* let someone else wait for now */ ! 176: } ! 177: ! 178: /* ! 179: * write routine: ! 180: * send a packet ! 181: */ ! 182: static ! 183: bitstwrite(dev) ! 184: { ! 185: register struct bvpdata *b; ! 186: ! 187: b = bvp.d; ! 188: if (insqti(bitsnd, &b->p.p_cmdq[0])) ! 189: bvpcomm(bvp.r, PCOWN|PCCMDQ); ! 190: } ! 191: ! 192: bvpinit(bv) ! 193: register struct bvp *bv; ! 194: { ! 195: register struct bvpdata *b; ! 196: register struct regs *r; ! 197: ! 198: if (bv->dbuf == NULL) { ! 199: bv->dbuf = geteblk(); ! 200: if (bv->dbuf->b_bcount < sizeof(struct bvpdata)) { ! 201: printf("bcount too small\n"); ! 202: brelse(bv->dbuf); ! 203: return (0); ! 204: } ! 205: clrbuf(bv->dbuf); ! 206: bv->d = (struct bvpdata *)bv->dbuf->b_un.b_addr; ! 207: } ! 208: r = bv->r; ! 209: if ((r->stat & PSSTAT) == SUNDEF) { ! 210: bvpdatinit(bv->d); ! 211: bvpcomm(r, physadr(&bv->d->p)|PCOWN|PCINIT); ! 212: bvpstat(r); ! 213: } ! 214: if ((r->stat & PSSTAT) == SINIT) { ! 215: bvpcomm(r, PCOWN|PCENAB); ! 216: bvpstat(r); ! 217: } ! 218: if ((r->stat & PSSTAT) != SENAB) { ! 219: printf("ps %x pe %x pd %x\n", r->stat, r->err, r->data); ! 220: return (0); ! 221: } ! 222: return (1); ! 223: } ! 224: ! 225: bvpdatinit(b) ! 226: register struct bvpdata *b; ! 227: { ! 228: /* ! 229: * just enough to make hardware happy ! 230: */ ! 231: b->p.p_nfreeq = NFREEQ; ! 232: b->p.p_fqb = b->f; ! 233: b->p.p_bvplvl = 1; ! 234: b->p.p_pqb = &b->p; ! 235: b->p.p_bdt = b->b; ! 236: b->p.p_bdtlen = NBDT; ! 237: b->p.p_spt = (struct pte *)physadr(Sysmap); ! 238: b->p.p_sptlen = 0x100000; /* huge */ ! 239: b->p.p_gpt = b->p.p_spt; ! 240: b->p.p_gptlen = b->p.p_sptlen; ! 241: } ! 242: ! 243: /* ! 244: * send a port command ! 245: * need a timeout ! 246: */ ! 247: bvpcomm(r, c) ! 248: register struct regs *r; ! 249: long c; ! 250: { ! 251: while (r->ctrl & PCOWN) ! 252: ; ! 253: r->stat &=~ PSOWN; ! 254: r->ctrl = c; ! 255: } ! 256: ! 257: /* ! 258: * wait for status in init ! 259: * needs timeout ! 260: */ ! 261: ! 262: long ! 263: bvpstat(r) ! 264: register struct regs *r; ! 265: { ! 266: while ((r->stat & PSOWN) == 0) ! 267: ; ! 268: return (r->stat); ! 269: } ! 270: ! 271: /* ! 272: * VAX queue primitives ! 273: */ ! 274: ! 275: /* ! 276: * make an empty queue ! 277: */ ! 278: initvq(q) ! 279: register quadque *q; ! 280: { ! 281: q->head = q->tail = 0; ! 282: } ! 283: ! 284: /* ! 285: * remove entry from head; ! 286: * return entry, or 0 if none ! 287: */ ! 288: caddr_t ! 289: remqhi(q) ! 290: quadque *q; ! 291: { ! 292: asm("clrl r0"); ! 293: asm("0: remqhi *4(ap),r0"); ! 294: asm("bcs 0b"); /* couldn't interlock; try again */ ! 295: } ! 296: ! 297: /* ! 298: * insert entry to tail ! 299: * return 1 if this was the first entry ! 300: */ ! 301: insqti(e, q) ! 302: caddr_t e; ! 303: quadque *q; ! 304: { ! 305: asm("clrl r0"); ! 306: asm("0: insqti *4(ap),*8(ap)"); ! 307: asm("bcs 0b"); ! 308: asm("bneq 1f"); ! 309: asm("incl r0"); ! 310: asm("1:"); ! 311: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.