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.3 (Berkeley) 04/25/89 7 */ 8 9 #include "ik.h" 10 #if NIK > 0 11 /* 12 * Ikonas Frame Buffer Interface -- Bill Reeves. 13 */ 14 #include "machine/pte.h" 15 16 #include "param.h" 17 #include "dir.h" 18 #include "user.h" 19 #include "buf.h" 20 #include "systm.h" 21 #include "map.h" 22 #include "uio.h" 23 #include "ioctl.h" 24 25 #include "ubareg.h" 26 #include "ubavar.h" 27 #include "ikreg.h" 28 29 #define IKBUSY 01 30 #define IKDMAPRI (PZERO-1) 31 #define IKWAITPRI (PZERO+1) 32 33 int ikprobe(), ikattach(), ikintr(); 34 struct uba_device *ikdinfo[NIK]; 35 u_short ikstd[] = { 0772460, 0000000, 0 }; 36 struct uba_driver ikdriver = 37 { ikprobe, 0, ikattach, 0, ikstd, "ik", ikdinfo, 0, 0 }; 38 39 struct ik_softc { 40 char ik_open; 41 short ik_uid; 42 short ik_state; 43 int ik_ubinfo; 44 int ik_count; 45 struct buf *ik_bp; 46 int ik_bufp; 47 int ik_icnt; 48 } ik_softc[NIK]; 49 50 int ikstrategy(); 51 u_int ikminphys(); 52 struct buf rikbuf[NIK]; 53 54 #define IKUNIT(dev) (minor(dev)) 55 56 ikprobe(reg) 57 caddr_t reg; 58 { 59 register int br, cvec; /* value-result */ 60 register struct ikdevice *ikaddr = (struct ikdevice *) reg; 61 62 #ifdef lint 63 br = 0; cvec = br; br = cvec; 64 ikintr(0); 65 #endif 66 ikaddr->ik_istat = 0; 67 ikaddr->ik_xaddr = 0; 68 ikaddr->ik_yaddr = 0; 69 ikaddr->ik_ustat = IK_IENABLE | IK_GO; 70 DELAY(10000); 71 ikaddr->ik_ustat = 0; 72 return (sizeof (struct ikdevice)); 73 } 74 75 /*ARGSUSED*/ 76 ikattach(ui) 77 struct uba_device *ui; 78 { 79 80 } 81 82 ikopen(dev) 83 dev_t dev; 84 { 85 register struct ik_softc *ikp; 86 register struct uba_device *ui; 87 88 if (IKUNIT(dev) >= NIK || (ikp = &ik_softc[minor(dev)])->ik_open || 89 (ui = ikdinfo[IKUNIT(dev)]) == 0 || ui->ui_alive == 0) 90 return (ENXIO); 91 ikp->ik_open = 1; 92 ikp->ik_icnt = 0; 93 ikp->ik_state = 0; 94 ikp->ik_uid = u.u_uid; 95 maptouser(ui->ui_addr); 96 return (0); 97 } 98 99 ikclose(dev) 100 dev_t dev; 101 { 102 103 ik_softc[minor(dev)].ik_open = 0; 104 ik_softc[minor(dev)].ik_state = 0; 105 unmaptouser(ikdinfo[IKUNIT(dev)]->ui_addr); 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 sleep((caddr_t)ikp, IKDMAPRI+1); 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 sleep((caddr_t)ikp, IKDMAPRI); 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 197 switch (cmd) { 198 199 case IKIOGETADDR: 200 *(caddr_t *)data = ui->ui_addr; 201 break; 202 203 case IKIOWAITINT: 204 ikp = &ik_softc[IKUNIT(dev)]; 205 ikp->ik_state |= IKBUSY; 206 while (ikp->ik_state&IKBUSY) 207 sleep((caddr_t)ikp, IKWAITPRI); 208 break; 209 210 default: 211 return (ENOTTY); 212 } 213 return (0); 214 } 215 216 /*ARGSUSED*/ 217 ikintr(dev) 218 dev_t dev; 219 { 220 register struct ikdevice *ikaddr = 221 (struct ikdevice *) ikdinfo[IKUNIT(dev)]->ui_addr; 222 register struct ik_softc *ikp = &ik_softc[IKUNIT(dev)]; 223 224 ikp->ik_icnt++; 225 if (ikp->ik_state&IKBUSY) { 226 ikaddr->ik_ustat = 0; 227 ikp->ik_state &= ~IKBUSY; 228 wakeup((caddr_t)ikp); 229 } 230 } 231 232 ikreset(uban) 233 int uban; 234 { 235 register int i; 236 register struct uba_device *ui; 237 register struct ik_softc *ikp = ik_softc; 238 239 for (i = 0; i < NIK; i++, ikp++) { 240 if ((ui = ikdinfo[i]) == 0 || ui->ui_alive == 0 || 241 ui->ui_ubanum != uban || ikp->ik_open == 0) 242 continue; 243 printf(" ik%d", i); 244 if ((ikp->ik_state&IKBUSY) == 0) 245 continue; 246 ikp->ik_ubinfo = 247 ubasetup(ui->ui_ubanum, ikp->ik_bp, UBA_NEEDBDP); 248 ikp->ik_count = -(ikp->ik_bp->b_bcount/2); 249 ikstart(ui); 250 } 251 } 252 #endif 253