|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 University of Utah. ! 3: * Copyright (c) 1990 The Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * This code is derived from software contributed to Berkeley by ! 7: * the Systems Programming Group of the University of Utah Computer ! 8: * Science Department. ! 9: * ! 10: * Redistribution and use in source and binary forms, with or without ! 11: * modification, are permitted provided that the following conditions ! 12: * are met: ! 13: * 1. Redistributions of source code must retain the above copyright ! 14: * notice, this list of conditions and the following disclaimer. ! 15: * 2. Redistributions in binary form must reproduce the above copyright ! 16: * notice, this list of conditions and the following disclaimer in the ! 17: * documentation and/or other materials provided with the distribution. ! 18: * 3. All advertising materials mentioning features or use of this software ! 19: * must display the following acknowledgement: ! 20: * This product includes software developed by the University of ! 21: * California, Berkeley and its contributors. ! 22: * 4. Neither the name of the University nor the names of its contributors ! 23: * may be used to endorse or promote products derived from this software ! 24: * without specific prior written permission. ! 25: * ! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 36: * SUCH DAMAGE. ! 37: * ! 38: * from: Utah $Hdr: grf.c 1.31 91/01/21$ ! 39: * ! 40: * @(#)grf.c 7.8 (Berkeley) 5/7/91 ! 41: */ ! 42: ! 43: /* ! 44: * Graphics display driver for the HP300. ! 45: * This is the hardware-independent portion of the driver. ! 46: * Hardware access is through the grfdev routines below. ! 47: */ ! 48: ! 49: #include "grf.h" ! 50: #if NGRF > 0 ! 51: ! 52: #include "param.h" ! 53: #include "proc.h" ! 54: #include "ioctl.h" ! 55: #include "file.h" ! 56: #include "malloc.h" ! 57: ! 58: #include "device.h" ! 59: #include "grfioctl.h" ! 60: #include "grfvar.h" ! 61: ! 62: #include "machine/cpu.h" ! 63: ! 64: #ifdef HPUXCOMPAT ! 65: #include "../hpux/hpux.h" ! 66: #endif ! 67: ! 68: #include "vm/vm.h" ! 69: #include "vm/vm_kern.h" ! 70: #include "vm/vm_page.h" ! 71: #include "vm/vm_pager.h" ! 72: ! 73: #include "specdev.h" ! 74: #include "vnode.h" ! 75: #include "mman.h" ! 76: ! 77: #include "ite.h" ! 78: #if NITE == 0 ! 79: #define iteon(u,f) ! 80: #define iteoff(u,f) ! 81: #endif ! 82: ! 83: int grfprobe(); ! 84: int tc_init(), tc_mode(); ! 85: int gb_init(), gb_mode(); ! 86: int rb_init(), rb_mode(); ! 87: int dv_init(), dv_mode(); ! 88: ! 89: struct grfdev grfdev[] = { ! 90: GID_TOPCAT, GRFBOBCAT, tc_init, tc_mode, ! 91: "topcat", ! 92: GID_GATORBOX, GRFGATOR, gb_init, gb_mode, ! 93: "gatorbox", ! 94: GID_RENAISSANCE,GRFRBOX, rb_init, rb_mode, ! 95: "renaissance", ! 96: GID_LRCATSEYE, GRFCATSEYE, tc_init, tc_mode, ! 97: "lo-res catseye", ! 98: GID_HRCCATSEYE, GRFCATSEYE, tc_init, tc_mode, ! 99: "hi-res catseye", ! 100: GID_HRMCATSEYE, GRFCATSEYE, tc_init, tc_mode, ! 101: "hi-res catseye", ! 102: GID_DAVINCI, GRFDAVINCI, dv_init, dv_mode, ! 103: "davinci", ! 104: }; ! 105: int ngrfdev = sizeof(grfdev) / sizeof(grfdev[0]); ! 106: ! 107: struct driver grfdriver = { grfprobe, "grf" }; ! 108: struct grf_softc grf_softc[NGRF]; ! 109: ! 110: #ifdef DEBUG ! 111: int grfdebug = 0; ! 112: #define GDB_DEVNO 0x01 ! 113: #define GDB_MMAP 0x02 ! 114: #define GDB_IOMAP 0x04 ! 115: #define GDB_LOCK 0x08 ! 116: #endif ! 117: ! 118: /* ! 119: * XXX: called from ite console init routine. ! 120: * Does just what configure will do later but without printing anything. ! 121: */ ! 122: grfconfig() ! 123: { ! 124: register caddr_t addr; ! 125: register struct hp_hw *hw; ! 126: register struct hp_device *hd, *nhd; ! 127: ! 128: for (hw = sc_table; hw->hw_type; hw++) { ! 129: if (!HW_ISDEV(hw, D_BITMAP)) ! 130: continue; ! 131: /* ! 132: * Found one, now match up with a logical unit number ! 133: */ ! 134: nhd = NULL; ! 135: addr = hw->hw_kva; ! 136: for (hd = hp_dinit; hd->hp_driver; hd++) { ! 137: if (hd->hp_driver != &grfdriver || hd->hp_alive) ! 138: continue; ! 139: /* ! 140: * Wildcarded. If first, remember as possible match. ! 141: */ ! 142: if (hd->hp_addr == NULL) { ! 143: if (nhd == NULL) ! 144: nhd = hd; ! 145: continue; ! 146: } ! 147: /* ! 148: * Not wildcarded. ! 149: * If exact match done searching, else keep looking. ! 150: */ ! 151: if (sctova(hd->hp_addr) == addr) { ! 152: nhd = hd; ! 153: break; ! 154: } ! 155: } ! 156: /* ! 157: * Found a match, initialize ! 158: */ ! 159: if (nhd && grfinit(addr, nhd->hp_unit)) ! 160: nhd->hp_addr = addr; ! 161: } ! 162: } ! 163: ! 164: /* ! 165: * Normal init routine called by configure() code ! 166: */ ! 167: grfprobe(hd) ! 168: struct hp_device *hd; ! 169: { ! 170: struct grf_softc *gp = &grf_softc[hd->hp_unit]; ! 171: ! 172: if ((gp->g_flags & GF_ALIVE) == 0 && ! 173: !grfinit(hd->hp_addr, hd->hp_unit)) ! 174: return(0); ! 175: printf("grf%d: %d x %d ", hd->hp_unit, ! 176: gp->g_display.gd_dwidth, gp->g_display.gd_dheight); ! 177: if (gp->g_display.gd_colors == 2) ! 178: printf("monochrome"); ! 179: else ! 180: printf("%d color", gp->g_display.gd_colors); ! 181: printf(" %s display\n", grfdev[gp->g_type].gd_desc); ! 182: return(1); ! 183: } ! 184: ! 185: grfinit(addr, unit) ! 186: caddr_t addr; ! 187: { ! 188: struct grf_softc *gp = &grf_softc[unit]; ! 189: struct grfreg *gr; ! 190: register struct grfdev *gd; ! 191: ! 192: gr = (struct grfreg *) addr; ! 193: if (gr->gr_id != GRFHWID) ! 194: return(0); ! 195: for (gd = grfdev; gd < &grfdev[ngrfdev]; gd++) ! 196: if (gd->gd_hardid == gr->gr_id2) ! 197: break; ! 198: if (gd < &grfdev[ngrfdev] && (*gd->gd_init)(gp, addr)) { ! 199: gp->g_display.gd_id = gd->gd_softid; ! 200: gp->g_type = gd - grfdev; ! 201: gp->g_flags = GF_ALIVE; ! 202: return(1); ! 203: } ! 204: return(0); ! 205: } ! 206: ! 207: /*ARGSUSED*/ ! 208: grfopen(dev, flags) ! 209: dev_t dev; ! 210: { ! 211: int unit = GRFUNIT(dev); ! 212: register struct grf_softc *gp = &grf_softc[unit]; ! 213: int error = 0; ! 214: ! 215: if (unit >= NGRF || (gp->g_flags & GF_ALIVE) == 0) ! 216: return(ENXIO); ! 217: if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE)) ! 218: return(EBUSY); ! 219: #ifdef HPUXCOMPAT ! 220: /* ! 221: * XXX: cannot handle both HPUX and BSD processes at the same time ! 222: */ ! 223: if (curproc->p_flag & SHPUX) ! 224: if (gp->g_flags & GF_BSDOPEN) ! 225: return(EBUSY); ! 226: else ! 227: gp->g_flags |= GF_HPUXOPEN; ! 228: else ! 229: if (gp->g_flags & GF_HPUXOPEN) ! 230: return(EBUSY); ! 231: else ! 232: gp->g_flags |= GF_BSDOPEN; ! 233: #endif ! 234: /* ! 235: * First open. ! 236: * XXX: always put in graphics mode. ! 237: */ ! 238: error = 0; ! 239: if ((gp->g_flags & GF_OPEN) == 0) { ! 240: gp->g_flags |= GF_OPEN; ! 241: error = grfon(dev); ! 242: } ! 243: return(error); ! 244: } ! 245: ! 246: /*ARGSUSED*/ ! 247: grfclose(dev, flags) ! 248: dev_t dev; ! 249: { ! 250: register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 251: ! 252: (void) grfoff(dev); ! 253: (void) grfunlock(gp); ! 254: gp->g_flags &= GF_ALIVE; ! 255: return(0); ! 256: } ! 257: ! 258: /*ARGSUSED*/ ! 259: grfioctl(dev, cmd, data, flag, p) ! 260: dev_t dev; ! 261: caddr_t data; ! 262: struct proc *p; ! 263: { ! 264: register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 265: int error; ! 266: ! 267: #ifdef HPUXCOMPAT ! 268: if (p->p_flag & SHPUX) ! 269: return(hpuxgrfioctl(dev, cmd, data, flag, p)); ! 270: #endif ! 271: error = 0; ! 272: switch (cmd) { ! 273: ! 274: /* XXX: compatibility hack */ ! 275: case OGRFIOCGINFO: ! 276: bcopy((caddr_t)&gp->g_display, data, sizeof(struct ogrfinfo)); ! 277: break; ! 278: ! 279: case GRFIOCGINFO: ! 280: bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)); ! 281: break; ! 282: ! 283: case GRFIOCON: ! 284: error = grfon(dev); ! 285: break; ! 286: ! 287: case GRFIOCOFF: ! 288: error = grfoff(dev); ! 289: break; ! 290: ! 291: case GRFIOCMAP: ! 292: error = grfmmap(dev, (caddr_t *)data, p); ! 293: break; ! 294: ! 295: case GRFIOCUNMAP: ! 296: error = grfunmmap(dev, *(caddr_t *)data, p); ! 297: break; ! 298: ! 299: default: ! 300: error = EINVAL; ! 301: break; ! 302: ! 303: } ! 304: return(error); ! 305: } ! 306: ! 307: /*ARGSUSED*/ ! 308: grfselect(dev, rw) ! 309: dev_t dev; ! 310: { ! 311: if (rw == FREAD) ! 312: return(0); ! 313: return(1); ! 314: } ! 315: ! 316: grflock(gp, block) ! 317: register struct grf_softc *gp; ! 318: int block; ! 319: { ! 320: struct proc *p = curproc; /* XXX */ ! 321: int error; ! 322: extern char devioc[]; ! 323: ! 324: #ifdef DEBUG ! 325: if (grfdebug & GDB_LOCK) ! 326: printf("grflock(%d): dev %x flags %x lockpid %x\n", ! 327: p->p_pid, gp-grf_softc, gp->g_flags, ! 328: gp->g_lockp ? gp->g_lockp->p_pid : -1); ! 329: #endif ! 330: #ifdef HPUXCOMPAT ! 331: if (gp->g_pid) { ! 332: #ifdef DEBUG ! 333: if (grfdebug & GDB_LOCK) ! 334: printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", ! 335: gp->g_lock->gl_lockslot, gp->g_lockpslot, ! 336: gp->g_lock->gl_locks[gp->g_lockpslot]); ! 337: #endif ! 338: gp->g_lock->gl_lockslot = 0; ! 339: if (gp->g_lock->gl_locks[gp->g_lockpslot] == 0) { ! 340: gp->g_lockp = NULL; ! 341: gp->g_lockpslot = 0; ! 342: } ! 343: } ! 344: #endif ! 345: if (gp->g_lockp) { ! 346: if (gp->g_lockp == p) ! 347: return(EBUSY); ! 348: if (!block) ! 349: return(EAGAIN); ! 350: do { ! 351: gp->g_flags |= GF_WANTED; ! 352: if (error = tsleep((caddr_t)&gp->g_flags, ! 353: (PZERO+1) | PCATCH, devioc, 0)) ! 354: return (error); ! 355: } while (gp->g_lockp); ! 356: } ! 357: gp->g_lockp = p; ! 358: #ifdef HPUXCOMPAT ! 359: if (gp->g_pid) { ! 360: int slot = grffindpid(gp); ! 361: #ifdef DEBUG ! 362: if (grfdebug & GDB_LOCK) ! 363: printf(" slot %d\n", slot); ! 364: #endif ! 365: gp->g_lockpslot = gp->g_lock->gl_lockslot = slot; ! 366: gp->g_lock->gl_locks[slot] = 1; ! 367: } ! 368: #endif ! 369: return(0); ! 370: } ! 371: ! 372: grfunlock(gp) ! 373: register struct grf_softc *gp; ! 374: { ! 375: #ifdef DEBUG ! 376: if (grfdebug & GDB_LOCK) ! 377: printf("grfunlock(%d): dev %x flags %x lockpid %d\n", ! 378: curproc->p_pid, gp-grf_softc, gp->g_flags, ! 379: gp->g_lockp ? gp->g_lockp->p_pid : -1); ! 380: #endif ! 381: if (gp->g_lockp != curproc) ! 382: return(EBUSY); ! 383: #ifdef HPUXCOMPAT ! 384: if (gp->g_pid) { ! 385: #ifdef DEBUG ! 386: if (grfdebug & GDB_LOCK) ! 387: printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", ! 388: gp->g_lock->gl_lockslot, gp->g_lockpslot, ! 389: gp->g_lock->gl_locks[gp->g_lockpslot]); ! 390: #endif ! 391: gp->g_lock->gl_locks[gp->g_lockpslot] = 0; ! 392: gp->g_lockpslot = gp->g_lock->gl_lockslot = 0; ! 393: } ! 394: #endif ! 395: if (gp->g_flags & GF_WANTED) { ! 396: wakeup((caddr_t)&gp->g_flags); ! 397: gp->g_flags &= ~GF_WANTED; ! 398: } ! 399: gp->g_lockp = NULL; ! 400: return(0); ! 401: } ! 402: ! 403: /*ARGSUSED*/ ! 404: grfmap(dev, off, prot) ! 405: dev_t dev; ! 406: { ! 407: return(grfaddr(&grf_softc[GRFUNIT(dev)], off)); ! 408: } ! 409: ! 410: #ifdef HPUXCOMPAT ! 411: ! 412: /*ARGSUSED*/ ! 413: hpuxgrfioctl(dev, cmd, data, flag, p) ! 414: dev_t dev; ! 415: caddr_t data; ! 416: struct proc *p; ! 417: { ! 418: register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 419: int error; ! 420: ! 421: error = 0; ! 422: switch (cmd) { ! 423: ! 424: case GCID: ! 425: *(int *)data = gp->g_display.gd_id; ! 426: break; ! 427: ! 428: case GCON: ! 429: error = grfon(dev); ! 430: break; ! 431: ! 432: case GCOFF: ! 433: error = grfoff(dev); ! 434: break; ! 435: ! 436: case GCLOCK: ! 437: error = grflock(gp, 1); ! 438: break; ! 439: ! 440: case GCUNLOCK: ! 441: error = grfunlock(gp); ! 442: break; ! 443: ! 444: case GCAON: ! 445: case GCAOFF: ! 446: break; ! 447: ! 448: /* GCSTATIC is implied by our implementation */ ! 449: case GCSTATIC_CMAP: ! 450: case GCVARIABLE_CMAP: ! 451: break; ! 452: ! 453: /* map in control regs and frame buffer */ ! 454: case GCMAP: ! 455: error = grfmmap(dev, (caddr_t *)data, p); ! 456: break; ! 457: ! 458: case GCUNMAP: ! 459: error = grfunmmap(dev, *(caddr_t *)data, p); ! 460: /* XXX: HP-UX uses GCUNMAP to get rid of GCSLOT memory */ ! 461: if (error) ! 462: error = grflckunmmap(dev, *(caddr_t *)data); ! 463: break; ! 464: ! 465: case GCSLOT: ! 466: { ! 467: struct grf_slot *sp = (struct grf_slot *)data; ! 468: ! 469: sp->slot = grffindpid(gp); ! 470: if (sp->slot) { ! 471: error = grflckmmap(dev, (caddr_t *)&sp->addr); ! 472: if (error && gp->g_pid) { ! 473: free((caddr_t)gp->g_pid, M_DEVBUF); ! 474: gp->g_pid = NULL; ! 475: } ! 476: } else ! 477: error = EINVAL; /* XXX */ ! 478: break; ! 479: } ! 480: ! 481: /* ! 482: * XXX: only used right now to map in rbox control registers ! 483: * Will be replaced in the future with a real IOMAP interface. ! 484: */ ! 485: case IOMAPMAP: ! 486: error = iommap(dev, (caddr_t *)data); ! 487: #if 0 ! 488: /* ! 489: * It may not be worth kludging this (using p_devtmp) to ! 490: * make this work. It was an undocumented side-effect ! 491: * in HP-UX that the mapped address was the return value ! 492: * of the ioctl. The only thing I remember that counted ! 493: * on this behavior was the rbox X10 server. ! 494: */ ! 495: if (!error) ! 496: u.u_r.r_val1 = *(int *)data; /* XXX: this sux */ ! 497: #endif ! 498: break; ! 499: ! 500: case IOMAPUNMAP: ! 501: error = iounmmap(dev, *(caddr_t *)data); ! 502: break; ! 503: ! 504: default: ! 505: error = EINVAL; ! 506: break; ! 507: } ! 508: return(error); ! 509: } ! 510: ! 511: #endif ! 512: ! 513: grfon(dev) ! 514: dev_t dev; ! 515: { ! 516: int unit = GRFUNIT(dev); ! 517: struct grf_softc *gp = &grf_softc[unit]; ! 518: ! 519: /* ! 520: * XXX: iteoff call relies on devices being in same order ! 521: * as ITEs and the fact that iteoff only uses the minor part ! 522: * of the dev arg. ! 523: */ ! 524: iteoff(unit, 3); ! 525: return((*grfdev[gp->g_type].gd_mode) ! 526: (gp, (dev&GRFOVDEV) ? GM_GRFOVON : GM_GRFON)); ! 527: } ! 528: ! 529: grfoff(dev) ! 530: dev_t dev; ! 531: { ! 532: int unit = GRFUNIT(dev); ! 533: struct grf_softc *gp = &grf_softc[unit]; ! 534: int error; ! 535: ! 536: (void) grfunmmap(dev, (caddr_t)0, curproc); ! 537: error = (*grfdev[gp->g_type].gd_mode) ! 538: (gp, (dev&GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF); ! 539: /* XXX: see comment for iteoff above */ ! 540: iteon(unit, 2); ! 541: return(error); ! 542: } ! 543: ! 544: grfaddr(gp, off) ! 545: struct grf_softc *gp; ! 546: register int off; ! 547: { ! 548: register struct grfinfo *gi = &gp->g_display; ! 549: ! 550: /* control registers */ ! 551: if (off >= 0 && off < gi->gd_regsize) ! 552: return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); ! 553: ! 554: /* frame buffer */ ! 555: if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { ! 556: off -= gi->gd_regsize; ! 557: return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); ! 558: } ! 559: /* bogus */ ! 560: return(-1); ! 561: } ! 562: ! 563: #ifdef HPUXCOMPAT ! 564: /* ! 565: * Convert a BSD style minor devno to HPUX style. ! 566: * We cannot just create HPUX style nodes as they require 24 bits ! 567: * of minor device number and we only have 8. ! 568: * XXX: This may give the wrong result for remote stats of other ! 569: * machines where device 10 exists. ! 570: */ ! 571: grfdevno(dev) ! 572: dev_t dev; ! 573: { ! 574: int unit = GRFUNIT(dev); ! 575: struct grf_softc *gp = &grf_softc[unit]; ! 576: int newdev, sc; ! 577: ! 578: if (unit >= NGRF || (gp->g_flags&GF_ALIVE) == 0) ! 579: return(bsdtohpuxdev(dev)); ! 580: /* magic major number */ ! 581: newdev = 12 << 24; ! 582: /* now construct minor number */ ! 583: if (gp->g_display.gd_regaddr != (caddr_t)GRFIADDR) { ! 584: sc = patosc(gp->g_display.gd_regaddr); ! 585: newdev |= (sc << 16) | 0x200; ! 586: } ! 587: if (dev & GRFIMDEV) ! 588: newdev |= 0x02; ! 589: else if (dev & GRFOVDEV) ! 590: newdev |= 0x01; ! 591: #ifdef DEBUG ! 592: if (grfdebug & GDB_DEVNO) ! 593: printf("grfdevno: dev %x newdev %x\n", dev, newdev); ! 594: #endif ! 595: return(newdev); ! 596: } ! 597: #endif ! 598: ! 599: grfmmap(dev, addrp, p) ! 600: dev_t dev; ! 601: caddr_t *addrp; ! 602: struct proc *p; ! 603: { ! 604: struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 605: int len, error; ! 606: struct vnode vn; ! 607: struct specinfo si; ! 608: int flags; ! 609: ! 610: #ifdef DEBUG ! 611: if (grfdebug & GDB_MMAP) ! 612: printf("grfmmap(%d): addr %x\n", p->p_pid, *addrp); ! 613: #endif ! 614: len = gp->g_display.gd_regsize + gp->g_display.gd_fbsize; ! 615: flags = MAP_FILE|MAP_SHARED; ! 616: if (*addrp) ! 617: flags |= MAP_FIXED; ! 618: else ! 619: *addrp = (caddr_t)0x1000000; /* XXX */ ! 620: vn.v_type = VCHR; /* XXX */ ! 621: vn.v_specinfo = &si; /* XXX */ ! 622: vn.v_rdev = dev; /* XXX */ ! 623: error = vm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *)addrp, ! 624: (vm_size_t)len, VM_PROT_ALL, flags, (caddr_t)&vn, 0); ! 625: return(error); ! 626: } ! 627: ! 628: grfunmmap(dev, addr, p) ! 629: dev_t dev; ! 630: caddr_t addr; ! 631: struct proc *p; ! 632: { ! 633: struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 634: vm_size_t size; ! 635: int rv; ! 636: ! 637: #ifdef DEBUG ! 638: if (grfdebug & GDB_MMAP) ! 639: printf("grfunmmap(%d): dev %x addr %x\n", p->p_pid, dev, addr); ! 640: #endif ! 641: if (addr == 0) ! 642: return(EINVAL); /* XXX: how do we deal with this? */ ! 643: size = round_page(gp->g_display.gd_regsize + gp->g_display.gd_fbsize); ! 644: rv = vm_deallocate(p->p_vmspace->vm_map, (vm_offset_t)addr, size); ! 645: return(rv == KERN_SUCCESS ? 0 : EINVAL); ! 646: } ! 647: ! 648: #ifdef HPUXCOMPAT ! 649: iommap(dev, addrp) ! 650: dev_t dev; ! 651: caddr_t *addrp; ! 652: { ! 653: struct proc *p = curproc; /* XXX */ ! 654: struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 655: ! 656: #ifdef DEBUG ! 657: if (grfdebug & (GDB_MMAP|GDB_IOMAP)) ! 658: printf("iommap(%d): addr %x\n", p->p_pid, *addrp); ! 659: #endif ! 660: return(EINVAL); ! 661: } ! 662: ! 663: iounmmap(dev, addr) ! 664: dev_t dev; ! 665: caddr_t addr; ! 666: { ! 667: int unit = minor(dev); ! 668: ! 669: #ifdef DEBUG ! 670: if (grfdebug & (GDB_MMAP|GDB_IOMAP)) ! 671: printf("iounmmap(%d): id %d addr %x\n", ! 672: curproc->p_pid, unit, addr); ! 673: #endif ! 674: return(0); ! 675: } ! 676: ! 677: /* ! 678: * Processes involved in framebuffer mapping via GCSLOT are recorded in ! 679: * an array of pids. The first element is used to record the last slot used ! 680: * (for faster lookups). The remaining elements record up to GRFMAXLCK-1 ! 681: * process ids. Returns a slot number between 1 and GRFMAXLCK or 0 if no ! 682: * slot is available. ! 683: */ ! 684: grffindpid(gp) ! 685: struct grf_softc *gp; ! 686: { ! 687: register short pid, *sp; ! 688: register int i, limit; ! 689: int ni; ! 690: ! 691: if (gp->g_pid == NULL) { ! 692: gp->g_pid = (short *) ! 693: malloc(GRFMAXLCK * sizeof(short), M_DEVBUF, M_WAITOK); ! 694: bzero((caddr_t)gp->g_pid, GRFMAXLCK * sizeof(short)); ! 695: } ! 696: pid = curproc->p_pid; ! 697: ni = limit = gp->g_pid[0]; ! 698: for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { ! 699: if (*sp == pid) ! 700: goto done; ! 701: if (*sp == 0) ! 702: ni = i; ! 703: } ! 704: i = ni; ! 705: if (i < limit) { ! 706: gp->g_pid[i] = pid; ! 707: goto done; ! 708: } ! 709: if (++i == GRFMAXLCK) ! 710: return(0); ! 711: gp->g_pid[0] = i; ! 712: gp->g_pid[i] = pid; ! 713: done: ! 714: #ifdef DEBUG ! 715: if (grfdebug & GDB_LOCK) ! 716: printf("grffindpid(%d): slot %d of %d\n", ! 717: pid, i, gp->g_pid[0]); ! 718: #endif ! 719: return(i); ! 720: } ! 721: ! 722: grfrmpid(gp) ! 723: struct grf_softc *gp; ! 724: { ! 725: register short pid, *sp; ! 726: register int limit, i; ! 727: int mi; ! 728: ! 729: if (gp->g_pid == NULL || (limit = gp->g_pid[0]) == 0) ! 730: return; ! 731: pid = curproc->p_pid; ! 732: limit = gp->g_pid[0]; ! 733: mi = 0; ! 734: for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { ! 735: if (*sp == pid) ! 736: *sp = 0; ! 737: else if (*sp) ! 738: mi = i; ! 739: } ! 740: i = mi; ! 741: if (i < limit) ! 742: gp->g_pid[0] = i; ! 743: #ifdef DEBUG ! 744: if (grfdebug & GDB_LOCK) ! 745: printf("grfrmpid(%d): slot %d of %d\n", ! 746: pid, sp-gp->g_pid, gp->g_pid[0]); ! 747: #endif ! 748: } ! 749: ! 750: grflckmmap(dev, addrp) ! 751: dev_t dev; ! 752: caddr_t *addrp; ! 753: { ! 754: #ifdef DEBUG ! 755: struct proc *p = curproc; /* XXX */ ! 756: ! 757: if (grfdebug & (GDB_MMAP|GDB_LOCK)) ! 758: printf("grflckmmap(%d): addr %x\n", ! 759: p->p_pid, *addrp); ! 760: #endif ! 761: return(EINVAL); ! 762: } ! 763: ! 764: grflckunmmap(dev, addr) ! 765: dev_t dev; ! 766: caddr_t addr; ! 767: { ! 768: #ifdef DEBUG ! 769: int unit = minor(dev); ! 770: ! 771: if (grfdebug & (GDB_MMAP|GDB_LOCK)) ! 772: printf("grflckunmmap(%d): id %d addr %x\n", ! 773: curproc->p_pid, unit, addr); ! 774: #endif ! 775: return(EINVAL); ! 776: } ! 777: #endif /* HPUXCOMPAT */ ! 778: ! 779: #endif /* NGRF > 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.