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