|
|
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.