1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)ik.c 7.7 (Berkeley) 12/16/90 7 */ 8 9 #include "ik.h" 10 #if NIK > 0 11 /* 12 * Ikonas Frame Buffer Interface -- Bill Reeves. 13 */ 14 #include "../include/pte.h" 15 16 #include "sys/param.h" 17 #include "sys/user.h" 18 #include "sys/buf.h" 19 #include "sys/systm.h" 20 #include "sys/map.h" 21 #include "sys/uio.h" 22 #include "sys/ioctl.h" 23 24 #include "ubareg.h" 25 #include "ubavar.h" 26 #include "ikreg.h" 27 28 #define IKBUSY 01 29 #define IKDMAPRI (PZERO-1) 30 #define IKWAITPRI (PZERO+1) 31 32 int ikprobe(), ikattach(), ikintr(); 33 struct uba_device *ikdinfo[NIK]; 34 u_short ikstd[] = { 0772460, 0000000, 0 }; 35 struct uba_driver ikdriver = 36 { ikprobe, 0, ikattach, 0, ikstd, "ik", ikdinfo, 0, 0 }; 37 38 struct ik_softc { 39 char ik_open; 40 short ik_uid; 41 short ik_state; 42 int ik_ubinfo; 43 int ik_count; 44 struct buf *ik_bp; 45 int ik_bufp; 46 int ik_icnt; 47 } ik_softc[NIK]; 48 49 int ikstrategy(); 50 u_int ikminphys(); 51 struct buf rikbuf[NIK]; 52 53 #define IKUNIT(dev) (minor(dev)) 54 55 ikprobe(reg) 56 caddr_t reg; 57 { 58 register int br, cvec; /* value-result */ 59 register struct ikdevice *ikaddr = (struct ikdevice *) reg; 60 61 #ifdef lint 62 br = 0; cvec = br; br = cvec; 63 ikintr(0); 64 #endif 65 ikaddr->ik_istat = 0; 66 ikaddr->ik_xaddr = 0; 67 ikaddr->ik_yaddr = 0; 68 ikaddr->ik_ustat = IK_IENABLE | IK_GO; 69 DELAY(10000); 70 ikaddr->ik_ustat = 0; 71 return (sizeof (struct ikdevice)); 72 } 73 74 /*ARGSUSED*/ 75 ikattach(ui) 76 struct uba_device *ui; 77 { 78 79 } 80 81 ikopen(dev) 82 dev_t dev; 83 { 84 register struct ik_softc *ikp; 85 register struct uba_device *ui; 86 87 if (IKUNIT(dev) >= NIK || (ikp = &ik_softc[minor(dev)])->ik_open || 88 (ui = ikdinfo[IKUNIT(dev)]) == 0 || ui->ui_alive == 0) 89 return (ENXIO); 90 ikp->ik_open = 1; 91 ikp->ik_icnt = 0; 92 ikp->ik_state = 0; 93 ikp->ik_uid = u.u_uid; 94 maptouser(ui->ui_addr); 95 return (0); 96 } 97 98 ikclose(dev) 99 dev_t dev; 100 { 101 102 ik_softc[minor(dev)].ik_open = 0; 103 ik_softc[minor(dev)].ik_state = 0; 104 unmaptouser(ikdinfo[IKUNIT(dev)]->ui_addr); 105 return (0); 106 } 107 108 ikread(dev, uio) 109 dev_t dev; 110 struct uio *uio; 111 { 112 register int unit = IKUNIT(dev); 113 114 if (unit >= NIK) 115 return (ENXIO); 116 return (physio(ikstrategy, &rikbuf[unit], dev, B_READ, ikminphys, uio)); 117 } 118 119 ikwrite(dev, uio) 120 dev_t dev; 121 struct uio *uio; 122 { 123 register int unit = IKUNIT(dev); 124 125 if (unit >= NIK) 126 return (ENXIO); 127 return (physio(ikstrategy, &rikbuf[unit], dev, B_WRITE, ikminphys, uio)); 128 } 129 130 u_int 131 ikminphys(bp) 132 register struct buf *bp; 133 { 134 135 if (bp->b_bcount > 65536) /* may be able to do twice as much */ 136 bp->b_bcount = 65536; 137 } 138 139 ikstrategy(bp) 140 register struct buf *bp; 141 { 142 register struct ik_softc *ikp = &ik_softc[IKUNIT(bp->b_dev)]; 143 register struct uba_device *ui; 144 145 if (IKUNIT(bp->b_dev) >= NIK || (ui = ikdinfo[IKUNIT(bp->b_dev)]) == 0 146 || ui->ui_alive == 0) 147 goto bad; 148 (void) spl5(); 149 while (ikp->ik_state & IKBUSY) 150 (void) tsleep((caddr_t)ikp, IKDMAPRI+1, devout, 0); 151 ikp->ik_state |= IKBUSY; 152 ikp->ik_bp = bp; 153 ikp->ik_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); 154 ikp->ik_bufp = UBAI_ADDR(ikp->ik_ubinfo); 155 ikp->ik_count = -(bp->b_bcount>>1); /* its a word count */ 156 ikstart(ui); 157 while (ikp->ik_state&IKBUSY) 158 (void) tsleep((caddr_t)ikp, IKDMAPRI, devout, 0); 159 ikp->ik_count = 0; 160 ikp->ik_bufp = 0; 161 (void) spl0(); 162 ubarelse(ui->ui_ubanum, &ikp->ik_ubinfo); 163 ikp->ik_bp = 0; 164 iodone(bp); 165 wakeup((caddr_t)ikp); 166 return; 167 bad: 168 bp->b_flags |= B_ERROR; 169 iodone(bp); 170 return; 171 } 172 173 ikstart(ui) 174 register struct uba_device *ui; 175 { 176 register int istat; 177 register struct ikdevice *ikaddr = (struct ikdevice *) ui->ui_addr; 178 register struct ik_softc *ikp = &ik_softc[IKUNIT(ui->ui_unit)]; 179 180 istat = ikaddr->ik_istat|DMAENABLE; 181 ikaddr->ik_istat = istat; 182 ikaddr->ik_wc = ikp->ik_count; 183 ikaddr->ik_ubaddr = ikp->ik_bufp; 184 ikaddr->ik_ustat = IK_GO|IK_IENABLE|((ikp->ik_bufp>>12)&060); 185 } 186 187 /*ARGSUSED*/ 188 ikioctl(dev, cmd, data, flag) 189 dev_t dev; 190 int cmd; 191 register caddr_t data; 192 int flag; 193 { 194 register struct uba_device *ui = ikdinfo[IKUNIT(dev)]; 195 register struct ik_softc *ikp; 196 int error = 0; 197 198 switch (cmd) { 199 200 case IKIOGETADDR: 201 *(caddr_t *)data = ui->ui_addr; 202 break; 203 204 case IKIOWAITINT: 205 ikp = &ik_softc[IKUNIT(dev)]; 206 ikp->ik_state |= IKBUSY; 207 while (ikp->ik_state&IKBUSY && error == 0) 208 error = tsleep((caddr_t)ikp, IKWAITPRI | PCATCH, 209 devwait, 0); 210 break; 211 212 default: 213 return (ENOTTY); 214 } 215 return (error); 216 } 217 218 /*ARGSUSED*/ 219 ikintr(dev) 220 dev_t dev; 221 { 222 register struct ikdevice *ikaddr = 223 (struct ikdevice *) ikdinfo[IKUNIT(dev)]->ui_addr; 224 register struct ik_softc *ikp = &ik_softc[IKUNIT(dev)]; 225 226 ikp->ik_icnt++; 227 if (ikp->ik_state&IKBUSY) { 228 ikaddr->ik_ustat = 0; 229 ikp->ik_state &= ~IKBUSY; 230 wakeup((caddr_t)ikp); 231 } 232 } 233 234 ikreset(uban) 235 int uban; 236 { 237 register int i; 238 register struct uba_device *ui; 239 register struct ik_softc *ikp = ik_softc; 240 241 for (i = 0; i < NIK; i++, ikp++) { 242 if ((ui = ikdinfo[i]) == 0 || ui->ui_alive == 0 || 243 ui->ui_ubanum != uban || ikp->ik_open == 0) 244 continue; 245 printf(" ik%d", i); 246 if ((ikp->ik_state&IKBUSY) == 0) 247 continue; 248 ikp->ik_ubinfo = 249 ubasetup(ui->ui_ubanum, ikp->ik_bp, UBA_NEEDBDP); 250 ikp->ik_count = -(ikp->ik_bp->b_bcount/2); 251 ikstart(ui); 252 } 253 } 254 #endif 255