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