|
|
1.1 ! root 1: #include "cv.h" ! 2: #if NCV > 0 ! 3: /* ! 4: * Raster Technologies Color Video Interface -- Rob Pike ! 5: * Model One 20 with Option Card, on DR-11/W ! 6: */ ! 7: ! 8: #include "../h/param.h" ! 9: #include "../h/dir.h" ! 10: #include "../h/user.h" ! 11: #include "../h/buf.h" ! 12: #include "../h/systm.h" ! 13: #include "../h/pte.h" ! 14: #include "../h/map.h" ! 15: #include "../h/ioctl.h" ! 16: #include "../h/ubareg.h" ! 17: #include "../h/ubavar.h" ! 18: ! 19: struct cvdevice { ! 20: short wcr; /* Unibus word count reg */ ! 21: u_short bar; /* Unibus address register */ ! 22: u_short csr; /* Unibus status/command reg */ ! 23: u_short idr; /* Input Data Register */ ! 24: }; ! 25: #define eir csr /* Error and Information Register */ ! 26: #define odr idr /* Output Data Register */ ! 27: ! 28: /* ! 29: * Unibus status/command register bits ! 30: */ ! 31: ! 32: #define GO 0000001 ! 33: #define IENABLE 0000100 ! 34: #define READY 0000200 ! 35: #define MAINT 0010000 ! 36: #define ERROR 0100000 ! 37: ! 38: /* ! 39: * Function codes ! 40: */ ! 41: #define WR_IMAGE (1<<1) ! 42: #define WR_CMD (4<<1) ! 43: #define WR_RLE (5<<1) ! 44: #define RD_CMD (7<<1) ! 45: #define RD_IMAGE (3<<1) ! 46: #define FUNCMASK (7<<1) ! 47: #define TOGGLE (8<<1) /* toggle between X and WR_CMD, WR_CMD first */ ! 48: ! 49: /* ! 50: * IOCTL ! 51: */ ! 52: #define CVSETDMA (('c'<<8)|1) ! 53: ! 54: #define BUSY 01 ! 55: #define DMAPRI (PZERO-1) ! 56: #define WAITPRI (PZERO+1) ! 57: ! 58: int cvprobe(), cvattach(), cvintr(); ! 59: struct uba_device *cvdinfo[NCV]; ! 60: u_short cvstd[] = { 0772410, 0000000, 0 }; ! 61: struct uba_driver cvdriver = { ! 62: cvprobe, 0, cvattach, 0, cvstd, "cv", cvdinfo, 0, 0 ! 63: }; ! 64: ! 65: struct cvsoftc { ! 66: char open; ! 67: short uid; ! 68: short state; ! 69: int ubinfo; ! 70: int count; ! 71: struct buf *bp; ! 72: int bufp; ! 73: int icnt; ! 74: short dmamode; ! 75: short func; ! 76: } cvsoftc[NCV]; ! 77: ! 78: int cvstrategy(); ! 79: u_int cvminphys(); ! 80: struct buf rcvbuf[NCV]; ! 81: ! 82: #define UNIT(dev) (minor(dev)) ! 83: ! 84: cvprobe(reg) ! 85: caddr_t reg; ! 86: { ! 87: register int br, cvec; /* value-result */ ! 88: register struct cvdevice *cvaddr = (struct cvdevice *) reg; ! 89: ! 90: #ifdef lint ! 91: br = 0; cvec = br; br = cvec; ! 92: cvintr(0); ! 93: #endif ! 94: cvaddr->csr = IENABLE; ! 95: cvaddr->odr = 0x0707; /* clear screen, force interrupt */ ! 96: DELAY(10000); ! 97: cvaddr->csr = 0; ! 98: /* KLUDGE */ ! 99: br=0x15; ! 100: cvec=0124; ! 101: return (sizeof (struct cvdevice)); ! 102: } ! 103: ! 104: /*ARGSUSED*/ ! 105: cvattach(ui) ! 106: struct uba_device *ui; ! 107: { ! 108: ! 109: } ! 110: ! 111: cvopen(dev) ! 112: dev_t dev; ! 113: { ! 114: register struct cvsoftc *cvp; ! 115: register struct uba_device *ui; ! 116: ! 117: if (UNIT(dev) >= NCV || (cvp = &cvsoftc[minor(dev)])->open || ! 118: (ui = cvdinfo[UNIT(dev)]) == 0 || ui->ui_alive == 0) ! 119: u.u_error = EBUSY; ! 120: else { ! 121: cvp->open = 1; ! 122: cvp->icnt = 0; ! 123: cvp->state = 0; ! 124: cvp->uid = u.u_uid; ! 125: cvp->dmamode = -1; ! 126: } ! 127: } ! 128: ! 129: cvclose(dev) ! 130: dev_t dev; ! 131: { ! 132: ! 133: cvsoftc[minor(dev)].open = 0; ! 134: cvsoftc[minor(dev)].state = 0; ! 135: } ! 136: ! 137: cvread(dev, uio) ! 138: dev_t dev; ! 139: struct uio *uio; ! 140: { ! 141: register int unit = UNIT(dev); ! 142: ! 143: if (unit >= NCV) ! 144: return (ENXIO); ! 145: return (physio(cvstrategy, &rcvbuf[unit], dev, B_READ, cvminphys, uio)); ! 146: } ! 147: ! 148: cvwrite(dev, uio) ! 149: dev_t dev; ! 150: struct uio *uio; ! 151: { ! 152: register int unit = UNIT(dev); ! 153: ! 154: if (unit >= NCV) ! 155: return (ENXIO); ! 156: return (physio(cvstrategy, &rcvbuf[unit], dev, B_WRITE, cvminphys, uio)); ! 157: } ! 158: ! 159: u_int ! 160: cvminphys(bp) ! 161: register struct buf *bp; ! 162: { ! 163: ! 164: if (bp->b_bcount > 65536) /* may be able to do twice as much */ ! 165: bp->b_bcount = 65536; ! 166: } ! 167: ! 168: cvstrategy(bp) ! 169: register struct buf *bp; ! 170: { ! 171: register struct cvsoftc *cvp = &cvsoftc[UNIT(bp->b_dev)]; ! 172: register struct uba_device *ui; ! 173: ! 174: if (UNIT(bp->b_dev) >= NCV || (ui = cvdinfo[UNIT(bp->b_dev)]) == 0 ! 175: || ui->ui_alive == 0) ! 176: goto bad; ! 177: (void) spl5(); ! 178: while (cvp->state & BUSY) ! 179: sleep((caddr_t)cvp, DMAPRI+1); ! 180: cvp->state |= BUSY; ! 181: cvp->bp = bp; ! 182: if(bp->b_bcount<=0 || (bp->b_bcount&1) || ! 183: ((int)bp->b_un.b_addr&1) || cvp->dmamode<0){ ! 184: u.u_error = EINVAL; ! 185: goto bad; ! 186: } ! 187: cvp->ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); ! 188: cvp->bufp = cvp->ubinfo & 0x3ffff; ! 189: cvp->count = -(bp->b_bcount>>1); /* it's a word count */ ! 190: cvstart(ui); ! 191: if(tsleep((caddr_t)cvp, DMAPRI+1, 15) != TS_OK){ ! 192: register struct cvdevice *cvaddr = (struct cvdevice *) ui->ui_addr; ! 193: bp->b_flags |= B_ERROR; ! 194: /* stop the dma */ ! 195: cvslam(cvaddr); ! 196: cvaddr->wcr=0xFFFF; /* gently; -1 first... */ ! 197: cvaddr->wcr=0x0000; /* then zero */ ! 198: /* reset device */ ! 199: cvslam(cvaddr); ! 200: /* fake an interrupt to clear software status */ ! 201: cvintr(UNIT(bp->b_dev)); ! 202: } ! 203: cvp->count = 0; ! 204: cvp->bufp = 0; ! 205: (void) spl0(); ! 206: ubarelse(ui->ui_ubanum, &cvp->ubinfo); ! 207: cvp->bp = 0; ! 208: iodone(bp); ! 209: wakeup((caddr_t)cvp); ! 210: return; ! 211: bad: ! 212: cvp->state &= ~BUSY; ! 213: bp->b_flags |= B_ERROR; ! 214: iodone(bp); ! 215: return; ! 216: } ! 217: ! 218: cvslam(cvaddr) ! 219: register struct cvdevice *cvaddr; ! 220: { ! 221: register i; ! 222: cvaddr->csr=MAINT; ! 223: for(i=0; i<10; i++) ! 224: ; ! 225: cvaddr->csr=0; ! 226: for(i=0; i<10; i++) ! 227: ; ! 228: } ! 229: cvstart(ui) ! 230: register struct uba_device *ui; ! 231: { ! 232: register int csr; ! 233: register struct cvdevice *cvaddr = (struct cvdevice *) ui->ui_addr; ! 234: register struct cvsoftc *cvp = &cvsoftc[UNIT(ui->ui_unit)]; ! 235: ! 236: if((cvp->dmamode&TOGGLE) && cvp->func!=WR_CMD) ! 237: cvp->func = WR_CMD; ! 238: else ! 239: cvp->func = cvp->dmamode&~TOGGLE; ! 240: csr = IENABLE|((cvp->bufp>>12)&060) | cvp->func; ! 241: cvaddr->wcr = cvp->count; ! 242: cvaddr->bar = cvp->bufp; ! 243: cvaddr->csr = csr; /* No GO bit; let function codes settle */ ! 244: cvaddr->csr = csr|GO; ! 245: } ! 246: ! 247: /*ARGSUSED*/ ! 248: cvioctl(dev, cmd, data) ! 249: dev_t dev; ! 250: int cmd; ! 251: register caddr_t data; ! 252: { ! 253: register struct uba_device *ui = cvdinfo[UNIT(dev)]; ! 254: register struct cvsoftc *cvp = &cvsoftc[UNIT(dev)]; ! 255: int fmt; ! 256: ! 257: switch (cmd) { ! 258: case CVSETDMA: /* set DMA mode */ ! 259: if (copyin(data, (caddr_t)&fmt, sizeof(fmt))) { ! 260: u.u_error = EFAULT; ! 261: goto out; ! 262: } ! 263: switch (fmt&~TOGGLE) { ! 264: case WR_IMAGE: ! 265: case WR_CMD: ! 266: case WR_RLE: ! 267: case RD_CMD: ! 268: case RD_IMAGE: ! 269: cvp->dmamode = cvp->func = fmt; ! 270: cvp->func &= ~TOGGLE; ! 271: break; ! 272: default: ! 273: u.u_error = EINVAL; ! 274: } ! 275: goto out; ! 276: ! 277: default: ! 278: return (ENOTTY); ! 279: } ! 280: out: ! 281: return u.u_error; ! 282: } ! 283: ! 284: /*ARGSUSED*/ ! 285: cvintr(dev) ! 286: dev_t dev; ! 287: { ! 288: register struct cvdevice *cvaddr = ! 289: (struct cvdevice *) cvdinfo[UNIT(dev)]->ui_addr; ! 290: register struct cvsoftc *cvp = &cvsoftc[UNIT(dev)]; ! 291: register csr; ! 292: ! 293: cvp->icnt++; ! 294: if (cvp->state&BUSY) { ! 295: csr = cvaddr->csr; ! 296: if(csr & ERROR){ ! 297: cvaddr->eir |= ERROR; ! 298: printf("cv: CSR %x EIR %x\n", csr, cvaddr->eir); ! 299: } ! 300: cvaddr->csr = csr&~FUNCMASK; ! 301: cvp->state &= ~BUSY; ! 302: wakeup((caddr_t)cvp); ! 303: } ! 304: } ! 305: ! 306: cvreset(uban) ! 307: int uban; ! 308: { ! 309: register int i; ! 310: register struct uba_device *ui; ! 311: register struct cvsoftc *cvp = cvsoftc; ! 312: #ifdef untried ! 313: for (i = 0; i < NCV; i++, cvp++) { ! 314: if ((ui = cvdinfo[i]) == 0 || ui->ui_alive == 0 || ! 315: ui->ui_ubanum != uban || cvp->open == 0) ! 316: continue; ! 317: printf(" cv%d", i); ! 318: if ((cvp->state&CVBUSY) == 0) ! 319: continue; ! 320: cvp->ubinfo = ! 321: ubasetup(ui->ui_ubanum, cvp->bp, UBA_NEEDBDP); ! 322: cvp->count = -(cvp->bp->b_bcount/2); ! 323: cvstart(ui); ! 324: } ! 325: #endif ! 326: } ! 327: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.