|
|
1.1 root 1: /*
2: * This software is provided solely for use with
3: * the National Instruments GPIB11-2.
4: *
5: * Copyright 1980, 1983 National Instruments
6: *
7: * Jeffrey Kodosky
8: * REV D: 10/30/83
9: * (4.1bsd mods)
10: */
11:
12: #include "ib.h"
13:
14: #include "../h/param.h"
15: #include "../h/systm.h"
16: #include "../h/dir.h"
17: #include "../h/callout.h"
18: #include "../h/user.h"
19: #include "../h/map.h"
20: #include "../h/pte.h"
21: #include "../h/buf.h"
22: #include "../h/conf.h"
23: #include "../h/reg.h"
24: #include "../h/ubareg.h"
25: #include "../h/ubavar.h"
26: #include <sys/ioctl.h>
27:
28:
29: #define TRI 0 /* 4 for Three-state highspeed timing; 0 for Normal timing */
30: #define EXT 1 /* 2 for Extended; 1 for Normal GPIB addressing */
31: #define MSA 0140 /* Msa&037 for Extended; 0140 for Normal GPIB addressing */
32: #define MA 025 /* GPIB address */
33: #define TRACE 0 /* Leave TRACE undefined to eliminate tracing code */
34: /*#define DEBUG 0 /* DEBUG may be defined (as anything) to include diagnostic xprintfs */
35: #define DONE 0x0080 /* this is what they wanted */
36:
37:
38: u_short ibaddrs[]= {
39: 0767710, 0 }; /* Unibus address of GPIB11-2 */
40:
41: #define SIGSRQ SIGINT
42:
43: static struct buf ibbuf;
44: static int ibmap, ibiomap;
45: static short iboddc, ibodda;
46:
47: #ifndef TRACE
48: #define T
49: #else
50: #define T tracer()
51: #endif
52:
53: #define xprintf
54:
55: #define IB ((struct ib *) ibdinfo->ui_addr)
56: #define in(a) IB->a
57: #define out(a,v) IB->a=(v)
58: #define Exclude sps=spl5()
59: #define Unexclude splx(sps)
60: #define Try(f) if((x=(f))<0) return x
61:
62:
63: #define INACTIVE 0 /* Software controller states */
64: #define IDLE 1
65: #define INCHARGE 2
66: #define STANDBY 3
67:
68: #define GO 1 /* Control/status register bits */
69: #define OUT 2
70: #define SEL 4
71: #define ECC 010
72: #define XBA 060
73: #define IE 0100
74: #define LMR 0200
75: #define CIC 0400
76: #define ATN 01000
77: #define EOI 02000
78: #define OCSW 02000
79: #define TCS 04000
80: #define DAV 04000
81: #define SRQ_IE 010000
82: #define SRQ 010000
83: #define INT 020000
84: #define DMA_ENAB 020000
85: #define NEX 040000
86: #define REN 040000
87: #define IFC 0100000
88:
89: #define DIR 0 /* Internal register addresses */
90: #define DOR 0
91: #define ISR1 1
92: #define IMR1 1
93: #define ISR2 2
94: #define IMR2 2
95: #define SPS 3
96: #define SPM 3
97: #define ADS 4
98: #define ADM 4
99: #define CPT 5
100: #define AUX 5
101: #define AD0 6
102: #define ADR 6
103: #define AD1 7
104: #define EOS 7
105:
106: #define ERR_IE 4 /* Internal register bits */
107: #define END_IE 020
108: #define CPT_IE 0200
109: #define DMAI_ENAB 020
110: #define DMAO_ENAB 040
111: #define SRQS 0100
112: #define RSV 0100
113: #define TA 2
114: #define LA 4
115: #define LON 0100
116: #define TON 0200
117: #define DL 040
118: #define DT 0100
119: #define ARS 0200
120:
121: #define _CLKR 040 /* Hidden register addresses & offsets */
122: #define _PPR 0140
123: #define _AUXA 0200
124: #define _AUXB 0240
125: #define CLKR 0
126: #define PPR 1
127: #define AUXA 2
128: #define AUXB 3
129:
130: #define U 020 /* Hidden register bits */
131: #define BIN 020
132: #define S 010
133: #define REOS 4
134: #define HLDE 2
135: #define HLDA 1
136: #define CPT_ENAB 1
137: #define PACS 1 /* Software status bits */
138: #define MON 2
139:
140: #define IST 011 /* Special interface functions */
141: #define NIST 1
142: #define VSC 017
143: #define NVSC 7
144: #define SEOI 6
145: #define FH 3
146: #define IR 2
147: #define PON 0
148:
149: #define OK 1 /* Error codes */
150: #define ENONE -1 /* No command byte available (READCOMMAND) */
151: #define ECACFLT -2 /* ATN not unasserted after IFC sent (bus problem) */
152: #define ENOTCAC -3 /* Not Active Controller for operation requiring CAC (software problem) */
153: #define ENOTSAC -4 /* Not System Controller for operation requiring SAC (software problem) */
154: #define EIFCLR -5 /* IFC caused operation to abort (bus problem) */
155: #define ETIMO -6 /* Operation did not complete within allotted time (bus problem) */
156: #define ENOFUN -7 /* Non-existent function code (software problem) */
157: #define ETCTIMO -8 /* Take control not completed within allotted time (bus problem) */
158: #define ENOIBDEV -9 /* No Listeners addressed or no devices connected (bus problem) */
159: #define EIDMACNT -10 /* Internal DMA completed without bcr going to 0 (hardware problem) */
160: #define ENOPP -11 /* PP operation attempted on three-state GPIB (software problem) */
161: #define EITIMO -12 /* Internal DMA did not complete within allotted time (hardware problem) */
162: #define EINEXM -13 /* Internal DMA aborted due to non-existent memory (software/hardware problem) */
163: #define ENEXMEM -14 /* GPIB DMA aborted due to non-existent memory (software/hardware problem) */
164: #define ECNTRS -15 /* Bar and bcr are inconsistent following GPIB DMA (hardware problem) */
165:
166: #define RQC_STB (RSV | 1) /* Service request status bytes */
167: #define RQT_STB (RSV | 2)
168: #define RQL_STB (RSV | 4)
169:
170: #define RQC 1 /* Asynchronous op codes */
171: #define CAC 2
172: #define TAC 3
173: #define LAC 4
174: #define CWT 5
175: #define WSRQ 6
176:
177: #define TCT 011 /* GPIB multiline messages */
178: #define PPC 5
179: #define PPU 025
180: #define SCG 0140
181:
182: #define IN 0
183: #define ITIMO 25 /* Internal loopcount timeout */
184: #define GTIMO 10 /* Default GPIB timeout in seconds */
185: #define TCTIMO 100
186: #define MONHWAT 32
187:
188: #define RD (DMA_ENAB|TCS|IN|GO)
189: #define WT (DMA_ENAB|TCS|OUT|GO)
190: #define RDIR (DMA_ENAB|IN|SEL|GO)
191: #define WTIR (DMA_ENAB|OUT|SEL|GO)
192:
193:
194: int ibprobe(), ibattach();
195: struct uba_device *ibdinfo;
196: struct uba_driver ibdriver =
197: {
198: ibprobe, 0, ibattach, 0, ibaddrs, "ib", &ibdinfo, 0, 0, 0
199: };
200:
201: struct ib {
202: short unsigned bcr, bar, csr, ccf; /* Unibus device registers */
203: char internal[8]; /* Internal registers */
204: char hidden[4]; /* Hidden registers */
205: char cstate, istr, op;
206: int ans;
207: int timo; /* Watchdog timer */
208: struct proc *owner; /* GPIB owning process */
209: short unsigned rdbcr, rdbar, rdcsr;
210: char rdinternal[8];
211: int arg[3];
212: #ifdef TRACE
213: #define TRSZ 32
214: int trin;
215: int trbuf[TRSZ];
216: #endif
217: } ib;
218:
219: static int status(), spbyte();
220: static int command(), transfer(), clear(), remote(), local(), ppoll();
221: static int passctrl(), setstat(), monitor(), readcmd(), setparam(), testsrq();
222:
223: int (*ibfn[])() =
224: {
225: command, transfer, clear, remote, local, ppoll,
226: passctrl, setstat, monitor, readcmd, setparam, testsrq,
227: status, spbyte
228: };
229:
230: #define NFNS ((sizeof ibfn)/(sizeof ibfn[0]))
231:
232:
233: ibprobe(ibp)
234: struct ib *ibp;
235: {
236: register int br, cvec;
237:
238: ibp->csr= LMR;
239: ibp->bcr= -1;
240: ibp->bar= 0;
241: ibp->csr= DMA_ENAB|SEL|OUT|IE|GO;
242: DELAY(10000);
243: ibp->csr= LMR;
244: return 1;
245: }
246:
247: ibattach(ui)
248: struct uba_device *ui;
249: {
250: }
251:
252: ibopen(dev,rw)
253: {
254: register int sps, x;
255:
256: Exclude;
257: xprintf("open (%o)\n",ibopen);
258: if(ib.owner || ibdinfo==0 || ibdinfo->ui_alive==0)
259: u.u_error= ENXIO;
260: else {
261: T;
262: ibmap= uballoc(ibdinfo->ui_ubanum, &ib, sizeof ib, 0);
263: xprintf("\tibmap= %o\n", ibmap);
264: if((ib.ans=init())<0){
265: x= ubarelse(ibdinfo->ui_ubanum, &ibmap);
266: xprintf("\tubarelse= %d\n",x);
267: u.u_error= EIO;
268: }
269: else ib.owner= u.u_procp;
270: }
271: Unexclude;
272: }
273:
274: ibclose(dev)
275: {
276: register int sps, x;
277:
278: Exclude;
279: xprintf("close (%o)\n",ibclose);
280: T;
281: x= ubarelse(ibdinfo->ui_ubanum, &ibmap);
282: xprintf("\tubarelse= %d\n",x);
283: ib.cstate= INACTIVE;
284: ib.csr= 0;
285: out(csr,LMR);
286: ib.owner= 0;
287: Unexclude;
288: }
289:
290: ibioctl(dev,cmd,addr)
291: caddr_t addr;
292: {
293: register int sps, x;
294:
295: Exclude;
296: xprintf("ioctl (%o)\n",ibioctl);
297: switch(cmd){
298: case TIOCGETP:
299: T;
300: ib.arg[0]= ib.ans;
301: ib.arg[1]= in(csr);
302: ib.arg[2]= in(bcr);
303: xprintf("\tgtty: %o %o %o\n",ib.arg[0],ib.arg[1],ib.arg[2]);
304: if(copyout(ib.arg,addr,sizeof ib.arg)) u.u_error= EFAULT;
305: break;
306: case TIOCSETP:
307: T;
308: if(copyin(addr,ib.arg,sizeof ib.arg)){
309: u.u_error= EFAULT;
310: break;
311: }
312: xprintf("\tstty: %o %o %o\n",ib.arg[0],ib.arg[1],ib.arg[2]);
313: if((x=ib.arg[0])<0 || x>=NFNS){
314: ib.ans= ENOFUN;
315: u.u_error= EIO;
316: }
317: else if((ib.ans= (*ibfn[x])())<0) u.u_error= EIO;
318: break;
319: default:
320: u.u_error= ENOTTY;
321: break;
322: }
323: Unexclude;
324: }
325:
326: static
327: command()
328: {
329: T;
330: ib.op= CWT;
331: return OK;
332: }
333:
334: static
335: transfer()
336: {
337: T;
338: return gts(EXT);
339: }
340:
341: static
342: clear()
343: {
344: register int x;
345:
346: T;
347: Try(unhold());
348: out(csr, ib.csr | IFC);
349: wait100us();
350: if(in(csr)&ATN) return ECACFLT;
351: ib.cstate= INCHARGE;
352: out(csr, (ib.csr |= ATN | SRQ_IE | CIC));
353: T;
354: return lun(TON);
355: }
356:
357: static
358: remote()
359: {
360: T;
361: out(csr, (ib.csr |= REN));
362: return OK;
363: }
364:
365: static
366: local()
367: {
368: T;
369: out(csr, (ib.csr &= ~REN));
370: return OK;
371: }
372:
373: static
374: ppoll()
375: {
376: register int x;
377:
378: T;
379: Try(tcs());
380: Try(lun(LON));
381: T;
382: out(csr, (ib.csr |= EOI));
383: Try(xfer(RDIR, &ib.rdinternal[CPT], 1, CPT));
384: out(csr, (ib.csr &= ~EOI));
385: return (ib.rdinternal[CPT]&0377|0400);
386: }
387:
388: static
389: passctrl()
390: {
391: T;
392: return ENOIBDEV;
393: }
394:
395: static
396: setstat()
397: {
398: T;
399: return OK;
400: }
401:
402: static
403: monitor()
404: {
405: T;
406: return OK;
407: }
408:
409: static
410: readcmd()
411: {
412: T;
413: return ENONE;
414: }
415:
416: static
417: setparam()
418: {
419: T;
420: ib.timo= ib.arg[1];
421: ib.internal[0]= ib.arg[2];
422: ib.internal[EOS]= ib.arg[2]>>8;
423: return OK;
424: }
425:
426: static
427: testsrq()
428: {
429: int ibtimer();
430:
431: T;
432: if(in(csr)&SRQ) return OK;
433: if(ib.csr&CIC) out(csr, (ib.csr |= SRQ_IE));
434: if(ib.arg[1]){
435: ib.op= WSRQ;
436: if(ib.timo)
437: timeout(ibtimer,0,ib.timo*hz);
438: sleep(&ibbuf,10);
439: return ib.ans;
440: }
441: return ENONE;
442: }
443:
444: static
445: status()
446: {
447: register char *c;
448: register int ct;
449:
450: T;
451: c= (caddr_t)&ib;
452: u.u_base= (caddr_t)ib.arg[1];
453: if((u.u_count=ib.arg[2]) > sizeof ib)
454: u.u_count= sizeof ib;
455: ct= u.u_count;
456: while(passc(*c++)>=0) ;
457: return ct;
458: }
459:
460: static
461: spbyte()
462: {
463: register int x;
464:
465: T;
466: return OK;
467: }
468:
469: static
470: init()
471: {
472: register char *cp;
473: register int x;
474:
475: out(csr, LMR);
476: ib.csr= 0;
477: cp= &ib.hidden[0];
478: *cp++= _CLKR | 6;
479: *cp++= _PPR | U;
480: *cp++= _AUXA;
481: *cp++= _AUXB | TRI | CPT_ENAB;
482:
483: cp= &ib.internal[0];
484: *cp++= 0;
485: *cp++= CPT_IE | ERR_IE;
486: *cp++= 0;
487: *cp++= 0;
488: *cp++= EXT;
489: *cp++= ib.hidden[CLKR];
490: *cp++= ARS | MSA;
491: *cp++= 0;
492:
493: ib.istr= 0;
494: ib.op= 0;
495: ib.ans= 0;
496: ib.timo= GTIMO;
497: #ifdef TRACE
498: ib.trin= 0;
499: #endif
500: Try(irload());
501: T;
502: ib.cstate= IDLE;
503: out(csr, ib.csr= IE);
504: return 0;
505: }
506:
507: static
508: ibstop()
509: {
510: register int x;
511:
512: T;
513: out(csr, (ib.csr &= ~(DMA_ENAB|GO)));
514: ib.op= 0;
515: ibdone(&ibbuf);
516: return ETIMO;
517: }
518:
519: static
520: irload()
521: {
522: register int x;
523:
524: Try(xfer(WTIR,&ib.internal[ISR1],7,ISR1));
525: ib.internal[AUX]= ib.hidden[AUXA];
526: ib.internal[ADR]= MA;
527: Try(xfer(WTIR,&ib.internal[AUX],2,AUX));
528: Try(xfer(WTIR,&ib.hidden[AUXB],1,AUX));
529: x= ib.internal[ADM];
530: ib.internal[ADM]= 0;
531: return lun(x);
532: }
533:
534: static
535: lun(newadm)
536: char newadm;
537: { /* Note: rsv is cleared and not restored*/
538: register int x;
539:
540: if(ib.internal[ADM]==newadm) return OK;
541: ib.internal[ADM]= newadm;
542: ib.internal[AUX]= PON;
543: Try(xfer(WTIR,&ib.internal[ADM],2,ADM));
544: Try(xfer(WTIR,&ib.hidden[PPR],1,AUX));
545: return (ib.istr&S)? ldaux(IST): OK;
546: }
547:
548: ibwrite(dev)
549: {
550: register int sps;
551: int ibstrategy();
552:
553: Exclude;
554: T;
555: if((ib.ans=wsetup())>=0)
556: physio(ibstrategy, &ibbuf, dev, B_WRITE, minphys);
557: ib.op= 0;
558: if(ib.ans<0) u.u_error= EIO;
559: Unexclude;
560: }
561:
562: static
563: wsetup()
564: {
565: register x;
566:
567: ib.ccf= 0;
568: ib.csr &= ~ECC;
569: if(ib.op==CWT)
570: if((x=tcs())<0){
571: T;
572: return x;
573: }
574: else {
575: T;
576: Try(lun(TON));
577: ib.op= CAC;
578: }
579: else {
580: T;
581: if((x=gts(TON))<0){
582: T;
583: return x;
584: }
585: if(ib.internal[0]&2){
586: ib.ccf= SEOI;
587: ib.csr |= ECC;
588: }
589: ib.op= TAC;
590: }
591: ibodda= (int)u.u_base&1;
592: u.u_base -= ibodda;
593: iboddc= ((ibodda + u.u_count + 1)&~1) - u.u_count;
594: u.u_count += iboddc;
595: return OK;
596: }
597:
598: ibread(dev)
599: {
600: register int sps;
601: int ibstrategy();
602:
603: Exclude;
604: T;
605: if((ib.ans=rsetup())>=0)
606: physio(ibstrategy, &ibbuf, dev, B_READ, minphys);
607: ib.op= 0;
608: if(ib.ans<0) u.u_error= EIO;
609: Unexclude;
610: }
611:
612: static
613: rsetup()
614: {
615: register int x;
616:
617: ib.ccf= 0;
618: ib.csr &= ~ECC;
619: if((x=gts(LON))<0){
620: T;
621: return x;
622: }
623: ib.hidden[AUXA] |= (ib.internal[0]&(2<<4)? REOS:0) | (ib.internal[0]&(1<<4)? BIN:0);
624: if(ib.internal[0]&(4<<4)) ib.internal[IMR1] &= ~END_IE;
625: else {
626: T;
627: ib.internal[IMR1] |= END_IE;
628: if(ib.cstate==STANDBY) ib.hidden[AUXA] |= HLDE;
629: }
630: ib.internal[AUX]= ib.hidden[AUXA];
631: Try(xfer(WTIR, &ib.internal[IMR1], 7, IMR1));
632: if(ib.cstate==STANDBY){
633: T;
634: ib.ccf= ib.hidden[AUXA]= ib.hidden[AUXA]&~HLDE|HLDA;
635: ib.csr |= ECC;
636: }
637: ib.op= LAC;
638: ibodda= (int)u.u_base&1;
639: u.u_base -= ibodda;
640: iboddc= ((ibodda + u.u_count + 1)&~1) - u.u_count;
641: u.u_count += iboddc;
642: return OK;
643: }
644:
645: ibstrategy(bp)
646: register struct buf *bp;
647: {
648: register int x, rw;
649:
650: T;
651: ibiomap= ubasetup(ibdinfo->ui_ubanum, bp, 0);
652: xprintf("ibstrategy (%o): ibiomap= %o\n", ibstrategy, ibiomap);
653: rw= bp->b_flags&B_READ? RD:(ib.op==RQC? OUT:WT);
654: if((x=xfer(rw, ibiomap+ibodda, bp->b_bcount-iboddc, 0))<0){
655: T;
656: ib.ans= x;
657: ibdone(bp);
658: }
659: }
660:
661: static
662: ibdone(bp)
663: register struct buf *bp;
664: {
665: register int x;
666:
667: T;
668: iodone(bp);
669: x= ubarelse(ibdinfo->ui_ubanum, &ibiomap);
670: xprintf("ibdone (%o): ubarelse= %d\n",ibdone,x);
671: }
672:
673:
674: static
675: gts(newadm)
676: char newadm;
677: {
678: register int x;
679:
680: T;
681: Try(unhold());
682: if(ib.cstate==STANDBY)
683: return (ib.internal[ADM]==newadm)? OK : ENOIBDEV;
684: T;
685: if(ib.cstate==IDLE) return ENOTCAC;
686: Try(lun(newadm));
687: out(csr, (ib.csr &= ~ATN));
688: ib.cstate= STANDBY;
689: return OK;
690: }
691:
692: static
693: tcs()
694: {
695: if(ib.cstate==INCHARGE) return OK;
696: T;
697: if(ib.cstate==IDLE) return ENOTCAC;
698: out(csr, (ib.csr |= ATN));
699: ib.cstate= INCHARGE;
700: return unhold();
701: }
702:
703: static
704: unhold()
705: {
706: register int x;
707:
708: if(ib.hidden[AUXA]&(HLDE|HLDA)){
709: T;
710: ib.hidden[AUXA]= _AUXA;
711: Try(ldaux(FH));
712: return xfer(WTIR, &ib.hidden[AUXA], 1, AUX);
713: }
714: return OK;
715: }
716:
717: xfer(rw,bp,n,fr)
718: { /* fr is internal reg addr */
719: register int i, x;
720: int ibtimer();
721:
722: if(n<=0) return OK;
723: if(rw&SEL){
724: T;
725: out(bcr, (-n<<8) | fr & 7);
726: bp += ibmap - (int)&ib;
727: out(bar, bp);
728: out(csr, ib.csr & (REN|SRQ_IE|EOI|ATN|CIC) | (bp>>12) & XBA | rw);
729: for(i=ITIMO; !((x=in(csr))&DONE); )
730: if(--i<=0) return EITIMO;
731: if(x&NEX) return EINEXM;
732: if(in(bcr)&0177400) return EIDMACNT;
733: out(csr, ib.csr & (REN|SRQ_IE|ATN|CIC|IE));
734: return n;
735: }
736: ib.internal[IMR2]= rw&OUT? DMAO_ENAB:DMAI_ENAB;
737: Try(xfer(WTIR,&ib.internal[IMR2],1,IMR2));
738: T;
739: out(bcr, ib.bcr= -n);
740: out(bar, ib.bar= bp);
741: out(ccf, ib.ccf);
742: out(csr, (ib.csr= ib.csr & (REN|SRQ_IE|TCS|ATN|CIC|ECC) | (bp>>12) & XBA | IE | rw));
743: ib.ans= 0;
744: if(ib.timo) timeout(ibtimer,0,ib.timo*hz);
745: return OK;
746: }
747:
748: static
749: ldaux(a)
750: {
751: ib.internal[AUX]= a;
752: return xfer(WTIR, &ib.internal[AUX], 1, AUX);
753: }
754:
755: ibtimer(id)
756: {
757: int sps;
758:
759: Exclude;
760: printf("timer (%o)\n",ibtimer);
761: T;
762: ib.ans= ibstop();
763: Unexclude;
764: }
765:
766: ibintr()
767: {
768: register int x, i;
769: register short unsigned y;
770:
771: xprintf("intr (%o)",ibintr);
772: ib.rdcsr= in(csr);
773: ib.rdbcr= in(bcr);
774: ib.rdbar= in(bar);
775: xprintf("\trdbcr,rdbar,rdcsr= %o %o %o\n",ib.rdbcr,ib.rdbar,ib.rdcsr);
776: T;
777: if((ib.rdcsr&SRQ) && (ib.csr&SRQ_IE)){
778: xprintf("srq intr\n");
779: T;
780: out(csr, (ib.csr &= ~SRQ_IE) & ~GO);
781: if(ib.op==WSRQ){
782: ib.op= 0;
783: ib.ans= OK;
784: untimeout(ibtimer,0);
785: wakeup(&ibbuf);
786: }
787: else if(ib.owner) psignal(ib.owner,SIGSRQ);
788: }
789: if(ib.rdcsr&INT){
790: T;
791: xprintf("int intr");
792: out(csr, ib.csr & ~(DMA_ENAB|GO));
793: ib.rdcsr= in(csr);
794: ib.rdbcr= in(bcr);
795: ib.rdbar= in(bar);
796: xprintf("\trdbcr,rdbar,rdcsr,oldbcr= %o %o %o %o\n",ib.rdbcr,ib.rdbar,ib.rdcsr,x);
797: if((x=xfer(RDIR, &ib.rdinternal[ISR1], 5, ISR1))<0) goto quit;
798: if(ib.rdinternal[ISR1]&ERR_IE) ib.ans= ENOIBDEV;
799: if(ib.internal[IMR1]&END_IE){
800: T;
801: ib.internal[IMR1] &= ~END_IE;
802: if((x=xfer(WTIR,&ib.internal[IMR1],1,IMR1))<0) goto quit;
803: }
804: }
805: if((ib.rdcsr&DONE) && (ib.csr&GO)){
806: T;
807: ib.csr &= ~GO;
808: if(ib.timo) untimeout(ibtimer,0);
809: if(ib.rdcsr&NEX) ib.ans= ENEXMEM;
810: x = y = ib.rdbcr - ib.bcr;
811: if((ib.rdbar - ib.bar) != y){
812: x= ECNTRS;
813: printf("\trdbcr,rdbar,rdcsr= %o %o %o\n",ib.rdbcr,ib.rdbar,ib.rdcsr);
814: printf("\tbcr,bar,csr= %o %o %o\n",ib.bcr,ib.bar,ib.csr);
815: }
816: ibbuf.b_resid= -ib.rdbcr;
817: if(ib.ans==0)
818: quit:
819: ib.ans= x;
820: ib.op= 0;
821: T;
822: ibdone(&ibbuf);
823: }
824: }
825:
826: static
827: wait100us()
828: {
829: register int i;
830:
831: for(i=100; i-->0; ) ;
832: }
833:
834: #ifdef TRACE
835: tracer(a)
836: {
837: register int s, *p;
838:
839: s= spl7();
840: p= &a;
841: p--;
842: xprintf("\tT %o\n", *p);
843: ib.trbuf[ib.trin++]= *p; /* save caller pc */
844: if(ib.trin>=TRSZ) ib.trin= 0;
845: splx(s);
846: }
847: #endif
848:
849: untimeout(fn,arg)
850: register int (*fn)();
851: caddr_t arg;
852: {
853: register struct callout *p, *q;
854: int s;
855:
856: s= spl7();
857: for(p= &calltodo; q=p->c_next; p=q)
858: if(q->c_func==fn && q->c_arg==arg){
859: p->c_next= q->c_next;
860: q->c_next= callfree;
861: callfree= q;
862: if(p=p->c_next)
863: p->c_time += q->c_time;
864: break;
865: }
866: splx(s);
867: }
868:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.