Annotation of researchv10no/sys/io/bitest.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.