|
|
1.1 ! root 1: /* dr.c 4.10 82/05/18 */ ! 2: ! 3: #include "ekx.h" ! 4: #if NEKX > 0 ! 5: /* ! 6: * UNIBUS DR11-B driver for various graphical systems,. ! 7: * TS ! 8: */ ! 9: ! 10: #include "../h/param.h" ! 11: #include "../h/systm.h" ! 12: #include "../h/cpu.h" ! 13: #include "../h/nexus.h" ! 14: #include "../h/dk.h" ! 15: #include "../h/buf.h" ! 16: #include "../h/conf.h" ! 17: #include "../h/dir.h" ! 18: #include "../h/user.h" ! 19: #include "../h/map.h" ! 20: #include "../h/pte.h" ! 21: #include "../h/mtpr.h" ! 22: #include "../h/vm.h" ! 23: #include "../h/ubavar.h" ! 24: #include "../h/ubareg.h" ! 25: #include "../h/cmap.h" ! 26: ! 27: #include "../h/ekcmd.h" ! 28: ! 29: struct ekdevice{ ! 30: u_short ekgc; ! 31: u_short ekdc; ! 32: u_short ekgs; ! 33: u_short ekds; ! 34: short ekwc; ! 35: u_short ekba; ! 36: u_short ekcs; ! 37: u_short ekdata; ! 38: }; ! 39: struct ekctl { ! 40: u_short mode; ! 41: u_short dma_device; ! 42: u_short device; ! 43: u_short state; ! 44: } ek[NEKX]; ! 45: #define EK_GO 01 ! 46: #define EK_FCTN 016 ! 47: #define EK_12BIT 0 ! 48: #define EK_12BITST 04 ! 49: #define EK_8BIT 02 ! 50: #define EK_8BITST 06 ! 51: #define EK_DARK 0 ! 52: #define EK_GAIN 02 ! 53: #define EK_HTST 010 ! 54: #define EK_GTST 012 ! 55: #define EK_X1617 060 ! 56: #define EK_IE 0100 ! 57: #define EK_READY 0200 ! 58: #define EK_DIR 0400 ! 59: #define EK_ODEV 01000 ! 60: #define EK_OVER 02000 ! 61: #define EK_ATTN 020000 ! 62: #define EK_NEX 040000 ! 63: #define EK_ERROR 0100000 ! 64: ! 65: int ekxprobe(),ekxattach(),ekxdgo(),ekxintr(); ! 66: int ekstrategy(),ekstart(); ! 67: struct uba_ctlr *ekxminfo[NEKX]; ! 68: struct uba_device *ekxdinfo[NEKX]; ! 69: struct uba_ctlr ekctlr[NEKX]; /* ekxminfo points to this */ ! 70: u_short ekxstd[] = { 0163700, 0}; ! 71: struct uba_driver ekxdriver = ! 72: { ekxprobe,0,ekxattach,ekxdgo,ekxstd,"ekx",ekxdinfo,"ekx",ekxminfo }; ! 73: ! 74: #define ui_open ui_type ! 75: struct buf ekbuf[NEKX]; ! 76: struct buf ekutab[NEKX]; ! 77: int ct1, ct2, ct3, ct4, ct5, ct6, ct7, ct8, ct9, ct10, ct11; ! 78: short sekgs, sekds, sekcs; ! 79: unsigned short sekwc; ! 80: ! 81: /*ARGSUSED*/ ! 82: ekxprobe(reg) ! 83: caddr_t reg; ! 84: { ! 85: register int br,cvec; ! 86: ! 87: #ifdef LINT ! 88: br = 0; cvec = br; br = cvec; ! 89: #endif ! 90: ! 91: /* There seems to be no way to make this vile animal ! 92: interrupt, so we cheat... */ ! 93: ! 94: br = 0x15; ! 95: cvec = 0270; ! 96: } ! 97: ! 98: ekxattach(ui) ! 99: register struct uba_device *ui; ! 100: { ! 101: register struct uba_ctlr *um; ! 102: register int unit; ! 103: ! 104: unit = ui->ui_unit; ! 105: ! 106: um = &ekctlr[unit]; ! 107: ekxminfo[unit] = um; ! 108: ui->ui_ctlr = unit; ! 109: ui->ui_mi = um; ! 110: um->um_driver = ui->ui_driver; ! 111: um->um_ctlr = unit; ! 112: um->um_ubanum = ui->ui_ubanum; ! 113: um->um_alive = 1; ! 114: um->um_intr = ui->ui_intr; ! 115: um->um_addr = ui->ui_addr; ! 116: um->um_hd = ui->ui_hd; ! 117: } ! 118: ! 119: ekxopen(dev) ! 120: dev_t dev; ! 121: { ! 122: register int unit; ! 123: ! 124: ct1 = ct2 = ct3 = ct4 = ct5 = 0; ! 125: ct6 = ct7 = ct8 = ct9 = 0; ! 126: ct10 = ct11 = 0; ! 127: unit = minor(dev); ! 128: if((unit >= NEKX) || (ekxdinfo[unit]->ui_open)) { ! 129: u.u_error = ENXIO; ! 130: return; ! 131: } ! 132: ekxdinfo[unit]->ui_open++; ! 133: } ! 134: ! 135: ekxclose(dev) ! 136: dev_t dev; ! 137: { ! 138: register int unit; ! 139: ! 140: ekxdinfo[minor(dev)]->ui_open = 0; ! 141: } ! 142: ! 143: ekxread(dev) ! 144: dev_t dev; ! 145: { ! 146: register int unit = minor(dev); ! 147: ! 148: ct1++; ! 149: physio(ekstrategy,&ekbuf[unit],dev,B_READ,minphys); ! 150: ct2++; ! 151: } ! 152: ! 153: ekxwrite(dev) ! 154: dev_t dev; ! 155: { ! 156: register int unit = minor(dev); ! 157: ! 158: physio(ekstrategy,&ekbuf[unit],dev,B_WRITE,minphys); ! 159: } ! 160: ! 161: /* ! 162: * Due to the fact the ekstrategy routine is called only by ekxread ! 163: * and ekxwrite via physio, there will only be one transaction in each ! 164: * DR11-B's queue at any time. Therefore, one can just tack the given ! 165: * buffer header pointer on at the end of the queue, and call ekstart. ! 166: */ ! 167: ekstrategy(bp) ! 168: register struct buf *bp; ! 169: { ! 170: register struct uba_device *ui; ! 171: register struct uba_ctlr *um; ! 172: register struct buf *dp; ! 173: register int s; ! 174: struct ekdevice *draddr; ! 175: dev_t unit; ! 176: ! 177: ct3++; ! 178: unit = minor(bp->b_dev); /* chose a DR11-B */ ! 179: ui = ekxdinfo[unit]; ! 180: um = ui->ui_mi; /* get ctlr ptr */ ! 181: dp = &ekutab[unit]; ! 182: s = spl5(); ! 183: dp->b_actf = bp; ! 184: dp->b_actl = bp; ! 185: bp->av_forw = NULL; ! 186: um->um_tab.b_actf = dp; ! 187: um->um_tab.b_actl = dp; ! 188: ! 189: ekstart(um); ! 190: splx(s); ! 191: switch(tsleep((caddr_t)bp, PRIBIO+1, 20)) { ! 192: case TS_OK: ! 193: break; ! 194: case TS_SIG: /* not supposed to happen*/ ! 195: case TS_TIME: ! 196: draddr = (struct ekdevice *)um->um_addr; ! 197: sekgs = draddr->ekgs; ! 198: sekds = draddr->ekds; ! 199: sekwc = draddr->ekwc; ! 200: sekcs = draddr->ekcs; ! 201: printf("gs %o ds %o wc %o cs %o\n",sekgs, sekds, sekwc, sekcs); ! 202: printf("ct1 %o ct2 %o ct3 %o ct4 %o ct5 %o ct6 %o\n",ct1,ct2,ct3,ct4,ct5,ct6); ! 203: printf("ct7 %o ct8 %o ct9 %o ct10 %o ct11 %o\n",ct7,ct8,ct9,ct10,ct11); ! 204: bp->b_flags |= B_DONE | B_ERROR; ! 205: s = spl6(); ! 206: ekxintr(unit); ! 207: splx(s); ! 208: } ! 209: } ! 210: ! 211: ekstart(um) ! 212: register struct uba_ctlr *um; ! 213: { ! 214: register struct buf *bp,*dp; ! 215: register struct ekdevice *draddr; ! 216: register struct ekctl *ekp; ! 217: int cmd; ! 218: ! 219: dp = um->um_tab.b_actf; ! 220: bp = dp->b_actf; ! 221: ekp = &ek[minor(bp->b_dev)]; ! 222: ! 223: um->um_tab.b_active++; ! 224: draddr = (struct ekdevice *)um->um_addr; ! 225: draddr->ekwc = -bp->b_bcount / sizeof (short); ! 226: if(bp->b_flags & B_READ) ! 227: cmd = EK_IE|EK_DIR|ekp->mode; ! 228: else ! 229: cmd = EK_IE|ekp->dma_device; ! 230: um->um_cmd = cmd|EK_GO; ! 231: ct4++; ! 232: draddr->ekcs = cmd; ! 233: ct5++; ! 234: DELAY(10); ! 235: if( ubago(ekxdinfo[minor(bp->b_dev)])== 0) ! 236: printf("ubago returned 0\n"); ! 237: } ! 238: ! 239: ekxioctl(dev, cmd, arg) ! 240: dev_t dev; ! 241: int cmd; ! 242: register caddr_t arg; ! 243: { ! 244: register struct ekctl *ekp = &ek[minor(dev)]; ! 245: register struct uba_device *ui = ekxdinfo[minor(dev)]; ! 246: register struct ekdevice *draddr = (struct ekdevice *)ui->ui_addr; ! 247: u_short realcmd; ! 248: ! 249: if( (cmd != EKGS) && (cmd != EKDMA)){ ! 250: if(copyin(arg, (caddr_t)&realcmd, sizeof(realcmd))){ ! 251: u.u_error = EFAULT; ! 252: return; ! 253: } ! 254: } ! 255: switch(cmd){ ! 256: case EKGC: ! 257: draddr->ekgc = realcmd; ! 258: return; ! 259: case EKDC: ! 260: draddr->ekdc = realcmd; ! 261: return; ! 262: case EKGS: ! 263: realcmd = draddr->ekgs; ! 264: break; ! 265: case EKDS: ! 266: draddr->ekdc = EKDC_READ|realcmd; ! 267: realcmd = draddr->ekds; ! 268: break; ! 269: case EKMOD: ! 270: ek->mode = realcmd & EK_FCTN; ! 271: return; ! 272: case EKDEV: ! 273: ek->dma_device = realcmd & EK_FCTN; ! 274: return; ! 275: default: ! 276: u.u_error = ENXIO; ! 277: return; ! 278: } ! 279: if(copyout((caddr_t)&realcmd, arg, sizeof(realcmd))) ! 280: u.u_error = EFAULT; ! 281: } ! 282: ekreset() {} ! 283: ekxdgo(um) ! 284: struct uba_ctlr *um; ! 285: { ! 286: register struct ekdevice *draddr = (struct ekdevice *)um->um_addr; ! 287: ! 288: ct6++; ! 289: draddr->ekba = um->um_ubinfo; ! 290: draddr->ekcs = um->um_cmd|((um->um_ubinfo>>12)&EK_X1617); ! 291: ct7++; ! 292: } ! 293: ekxintr(dr11) ! 294: register dr11; ! 295: { ! 296: register struct buf *bp,*dp; ! 297: register struct ekdevice *draddr; ! 298: register struct uba_ctlr *um; ! 299: register int stat; ! 300: ! 301: ct8++; ! 302: um = ekxminfo[dr11]; ! 303: ! 304: if(um->um_tab.b_active == 0) ! 305: return; ! 306: ! 307: if(ekxdinfo[dr11]->ui_open == 0) ! 308: return; ! 309: dp = um->um_tab.b_actf; ! 310: bp = dp->b_actf; ! 311: draddr = (struct ekdevice *)um->um_addr; ! 312: stat = draddr->ekcs; ! 313: ! 314: if(stat & EK_ODEV){ ! 315: ct11++; ! 316: } ! 317: ! 318: /*should check stat&EK_OVER for retry*/ ! 319: if((stat&EK_ERROR) && draddr->ekwc && (draddr->ekba == 0)) { ! 320: draddr->ekcs = um->um_cmd|(((um->um_ubinfo>>12)+1)&EK_X1617); ! 321: ct10++; ! 322: } ! 323: ! 324: um->um_tab.b_active = 0; ! 325: um->um_tab.b_errcnt = 0; ! 326: um->um_tab.b_actf = dp->b_forw; ! 327: dp->b_errcnt = 0; ! 328: dp->b_active = 0; ! 329: bp->b_resid = (-draddr->ekwc * sizeof(short)); ! 330: ubadone(um); ! 331: iodone(bp); ! 332: ct9++; ! 333: } ! 334: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.