141480Smckusick /* 241480Smckusick * Copyright (c) 1988 University of Utah. 363146Sbostic * Copyright (c) 1990, 1993 463146Sbostic * The Regents of the University of California. All rights reserved. 541480Smckusick * 641480Smckusick * This code is derived from software contributed to Berkeley by 741480Smckusick * the Systems Programming Group of the University of Utah Computer 841480Smckusick * Science Department. 941480Smckusick * 1041480Smckusick * %sccs.include.redist.c% 1141480Smckusick * 12*64473Shibler * from: Utah $Hdr: grf.c 1.36 93/08/13$ 1341480Smckusick * 14*64473Shibler * @(#)grf.c 8.2 (Berkeley) 09/09/93 1541480Smckusick */ 1641480Smckusick 1741480Smckusick /* 1853923Shibler * Graphics display driver for HP 300/400/700/800 machines. 1941480Smckusick * This is the hardware-independent portion of the driver. 2053923Shibler * Hardware access is through the machine dependent grf switch routines. 2141480Smckusick */ 2241480Smckusick 2356504Sbostic #include "grf.h" 2441480Smckusick #if NGRF > 0 2541480Smckusick 2655049Smckusick #include <sys/param.h> 2755049Smckusick #include <sys/proc.h> 2855049Smckusick #include <sys/ioctl.h> 2955049Smckusick #include <sys/file.h> 3055049Smckusick #include <sys/malloc.h> 3155049Smckusick #include <sys/vnode.h> 3255049Smckusick #include <sys/mman.h> 3341480Smckusick 3455049Smckusick #include <hp/dev/grfioctl.h> 3555049Smckusick #include <hp/dev/grfvar.h> 3655049Smckusick #include <hp/dev/grfreg.h> 3741480Smckusick 3855049Smckusick #include <machine/cpu.h> 3941480Smckusick 4041480Smckusick #ifdef HPUXCOMPAT 4155049Smckusick #include <hp/hpux/hpux.h> 4241480Smckusick #endif 4341480Smckusick 4455049Smckusick #include <vm/vm.h> 4555049Smckusick #include <vm/vm_kern.h> 4655049Smckusick #include <vm/vm_page.h> 4755049Smckusick #include <vm/vm_pager.h> 4845750Smckusick 4955049Smckusick #include <miscfs/specfs/specdev.h> 5049132Skarels 5155049Smckusick #include <ite.h> 5241480Smckusick #if NITE == 0 5341480Smckusick #define iteon(u,f) 5441480Smckusick #define iteoff(u,f) 5541480Smckusick #endif 5641480Smckusick 5741480Smckusick struct grf_softc grf_softc[NGRF]; 5841480Smckusick 5941480Smckusick #ifdef DEBUG 6041480Smckusick int grfdebug = 0; 6141480Smckusick #define GDB_DEVNO 0x01 6241480Smckusick #define GDB_MMAP 0x02 6341480Smckusick #define GDB_IOMAP 0x04 6441480Smckusick #define GDB_LOCK 0x08 6541480Smckusick #endif 6641480Smckusick 6741480Smckusick /*ARGSUSED*/ 6841480Smckusick grfopen(dev, flags) 6941480Smckusick dev_t dev; 7041480Smckusick { 7141480Smckusick int unit = GRFUNIT(dev); 7241480Smckusick register struct grf_softc *gp = &grf_softc[unit]; 7341480Smckusick int error = 0; 7441480Smckusick 7541480Smckusick if (unit >= NGRF || (gp->g_flags & GF_ALIVE) == 0) 7641480Smckusick return(ENXIO); 7741480Smckusick if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE)) 7841480Smckusick return(EBUSY); 7941480Smckusick #ifdef HPUXCOMPAT 8041480Smckusick /* 8141480Smckusick * XXX: cannot handle both HPUX and BSD processes at the same time 8241480Smckusick */ 8357309Shibler if (curproc->p_md.md_flags & MDP_HPUX) 8441480Smckusick if (gp->g_flags & GF_BSDOPEN) 8541480Smckusick return(EBUSY); 8641480Smckusick else 8741480Smckusick gp->g_flags |= GF_HPUXOPEN; 8841480Smckusick else 8941480Smckusick if (gp->g_flags & GF_HPUXOPEN) 9041480Smckusick return(EBUSY); 9141480Smckusick else 9241480Smckusick gp->g_flags |= GF_BSDOPEN; 9341480Smckusick #endif 9441480Smckusick /* 9541480Smckusick * First open. 9641480Smckusick * XXX: always put in graphics mode. 9741480Smckusick */ 9841480Smckusick error = 0; 9941480Smckusick if ((gp->g_flags & GF_OPEN) == 0) { 10041480Smckusick gp->g_flags |= GF_OPEN; 10141480Smckusick error = grfon(dev); 10241480Smckusick } 10341480Smckusick return(error); 10441480Smckusick } 10541480Smckusick 10641480Smckusick /*ARGSUSED*/ 10741480Smckusick grfclose(dev, flags) 10841480Smckusick dev_t dev; 10941480Smckusick { 11041480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 11141480Smckusick 11241480Smckusick (void) grfoff(dev); 113*64473Shibler #ifdef HPUXCOMPAT 11441480Smckusick (void) grfunlock(gp); 115*64473Shibler #endif 11641480Smckusick gp->g_flags &= GF_ALIVE; 11741480Smckusick return(0); 11841480Smckusick } 11941480Smckusick 12041480Smckusick /*ARGSUSED*/ 12149132Skarels grfioctl(dev, cmd, data, flag, p) 12241480Smckusick dev_t dev; 12341480Smckusick caddr_t data; 12449132Skarels struct proc *p; 12541480Smckusick { 12641480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 12741480Smckusick int error; 12841480Smckusick 12941480Smckusick #ifdef HPUXCOMPAT 13057309Shibler if (p->p_md.md_flags & MDP_HPUX) 13149132Skarels return(hpuxgrfioctl(dev, cmd, data, flag, p)); 13241480Smckusick #endif 13341480Smckusick error = 0; 13441480Smckusick switch (cmd) { 13541480Smckusick 13641480Smckusick case GRFIOCGINFO: 13741480Smckusick bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)); 13841480Smckusick break; 13941480Smckusick 14041480Smckusick case GRFIOCON: 14141480Smckusick error = grfon(dev); 14241480Smckusick break; 14341480Smckusick 14441480Smckusick case GRFIOCOFF: 14541480Smckusick error = grfoff(dev); 14641480Smckusick break; 14741480Smckusick 14841480Smckusick case GRFIOCMAP: 14949132Skarels error = grfmmap(dev, (caddr_t *)data, p); 15041480Smckusick break; 15141480Smckusick 15241480Smckusick case GRFIOCUNMAP: 15349132Skarels error = grfunmmap(dev, *(caddr_t *)data, p); 15441480Smckusick break; 15541480Smckusick 15641480Smckusick default: 15741480Smckusick error = EINVAL; 15841480Smckusick break; 15941480Smckusick 16041480Smckusick } 16141480Smckusick return(error); 16241480Smckusick } 16341480Smckusick 16441480Smckusick /*ARGSUSED*/ 16541480Smckusick grfselect(dev, rw) 16641480Smckusick dev_t dev; 16741480Smckusick { 16841480Smckusick if (rw == FREAD) 16941480Smckusick return(0); 17041480Smckusick return(1); 17141480Smckusick } 17241480Smckusick 173*64473Shibler /*ARGSUSED*/ 174*64473Shibler grfmap(dev, off, prot) 175*64473Shibler dev_t dev; 17641480Smckusick { 177*64473Shibler return(grfaddr(&grf_softc[GRFUNIT(dev)], off)); 17841480Smckusick } 17941480Smckusick 180*64473Shibler grfon(dev) 181*64473Shibler dev_t dev; 18241480Smckusick { 183*64473Shibler int unit = GRFUNIT(dev); 184*64473Shibler struct grf_softc *gp = &grf_softc[unit]; 185*64473Shibler 186*64473Shibler /* 187*64473Shibler * XXX: iteoff call relies on devices being in same order 188*64473Shibler * as ITEs and the fact that iteoff only uses the minor part 189*64473Shibler * of the dev arg. 190*64473Shibler */ 191*64473Shibler iteoff(unit, 3); 192*64473Shibler return((*gp->g_sw->gd_mode)(gp, 193*64473Shibler (dev&GRFOVDEV) ? GM_GRFOVON : GM_GRFON, 194*64473Shibler (caddr_t)0)); 19541480Smckusick } 19641480Smckusick 197*64473Shibler grfoff(dev) 19841480Smckusick dev_t dev; 19941480Smckusick { 200*64473Shibler int unit = GRFUNIT(dev); 201*64473Shibler struct grf_softc *gp = &grf_softc[unit]; 202*64473Shibler int error; 203*64473Shibler 204*64473Shibler (void) grfunmmap(dev, (caddr_t)0, curproc); 205*64473Shibler error = (*gp->g_sw->gd_mode)(gp, 206*64473Shibler (dev&GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF, 207*64473Shibler (caddr_t)0); 208*64473Shibler /* XXX: see comment for iteoff above */ 209*64473Shibler iteon(unit, 2); 210*64473Shibler return(error); 21141480Smckusick } 21241480Smckusick 213*64473Shibler grfaddr(gp, off) 214*64473Shibler struct grf_softc *gp; 215*64473Shibler register int off; 216*64473Shibler { 217*64473Shibler register struct grfinfo *gi = &gp->g_display; 218*64473Shibler 219*64473Shibler /* control registers */ 220*64473Shibler if (off >= 0 && off < gi->gd_regsize) 221*64473Shibler return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); 222*64473Shibler 223*64473Shibler /* frame buffer */ 224*64473Shibler if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { 225*64473Shibler off -= gi->gd_regsize; 226*64473Shibler return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); 227*64473Shibler } 228*64473Shibler /* bogus */ 229*64473Shibler return(-1); 230*64473Shibler } 231*64473Shibler 232*64473Shibler /* 233*64473Shibler * HP-UX compatibility routines 234*64473Shibler */ 23541480Smckusick #ifdef HPUXCOMPAT 23641480Smckusick 23741480Smckusick /*ARGSUSED*/ 23849132Skarels hpuxgrfioctl(dev, cmd, data, flag, p) 23941480Smckusick dev_t dev; 24041480Smckusick caddr_t data; 24149132Skarels struct proc *p; 24241480Smckusick { 24341480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 24441480Smckusick int error; 24541480Smckusick 24641480Smckusick error = 0; 24741480Smckusick switch (cmd) { 24841480Smckusick 24941480Smckusick case GCID: 25041480Smckusick *(int *)data = gp->g_display.gd_id; 25141480Smckusick break; 25241480Smckusick 25341480Smckusick case GCON: 25441480Smckusick error = grfon(dev); 25541480Smckusick break; 25641480Smckusick 25741480Smckusick case GCOFF: 25841480Smckusick error = grfoff(dev); 25941480Smckusick break; 26041480Smckusick 26141480Smckusick case GCLOCK: 26241480Smckusick error = grflock(gp, 1); 26341480Smckusick break; 26441480Smckusick 26541480Smckusick case GCUNLOCK: 26641480Smckusick error = grfunlock(gp); 26741480Smckusick break; 26841480Smckusick 26941480Smckusick case GCAON: 27041480Smckusick case GCAOFF: 27141480Smckusick break; 27241480Smckusick 27341480Smckusick /* GCSTATIC is implied by our implementation */ 27441480Smckusick case GCSTATIC_CMAP: 27541480Smckusick case GCVARIABLE_CMAP: 27641480Smckusick break; 27741480Smckusick 27841480Smckusick /* map in control regs and frame buffer */ 27941480Smckusick case GCMAP: 28049132Skarels error = grfmmap(dev, (caddr_t *)data, p); 28141480Smckusick break; 28241480Smckusick 28341480Smckusick case GCUNMAP: 28449132Skarels error = grfunmmap(dev, *(caddr_t *)data, p); 28541480Smckusick /* XXX: HP-UX uses GCUNMAP to get rid of GCSLOT memory */ 28641480Smckusick if (error) 28741480Smckusick error = grflckunmmap(dev, *(caddr_t *)data); 28841480Smckusick break; 28941480Smckusick 29041480Smckusick case GCSLOT: 29141480Smckusick { 29241480Smckusick struct grf_slot *sp = (struct grf_slot *)data; 29341480Smckusick 29441480Smckusick sp->slot = grffindpid(gp); 29545750Smckusick if (sp->slot) { 29641480Smckusick error = grflckmmap(dev, (caddr_t *)&sp->addr); 29745750Smckusick if (error && gp->g_pid) { 29845750Smckusick free((caddr_t)gp->g_pid, M_DEVBUF); 29945750Smckusick gp->g_pid = NULL; 30045750Smckusick } 30145750Smckusick } else 30241480Smckusick error = EINVAL; /* XXX */ 30341480Smckusick break; 30441480Smckusick } 30541480Smckusick 306*64473Shibler case GCDESCRIBE: 307*64473Shibler error = (*gp->g_sw->gd_mode)(gp, GM_DESCRIBE, data); 308*64473Shibler break; 309*64473Shibler 31041480Smckusick /* 31141480Smckusick * XXX: only used right now to map in rbox control registers 31241480Smckusick * Will be replaced in the future with a real IOMAP interface. 31341480Smckusick */ 31441480Smckusick case IOMAPMAP: 31541480Smckusick error = iommap(dev, (caddr_t *)data); 31643410Shibler #if 0 31743410Shibler /* 31843410Shibler * It may not be worth kludging this (using p_devtmp) to 31943410Shibler * make this work. It was an undocumented side-effect 32043410Shibler * in HP-UX that the mapped address was the return value 32143410Shibler * of the ioctl. The only thing I remember that counted 32243410Shibler * on this behavior was the rbox X10 server. 32343410Shibler */ 32441480Smckusick if (!error) 32541480Smckusick u.u_r.r_val1 = *(int *)data; /* XXX: this sux */ 32643410Shibler #endif 32741480Smckusick break; 32841480Smckusick 32941480Smckusick case IOMAPUNMAP: 33041480Smckusick error = iounmmap(dev, *(caddr_t *)data); 33141480Smckusick break; 33241480Smckusick 33341480Smckusick default: 33441480Smckusick error = EINVAL; 33541480Smckusick break; 33641480Smckusick } 33741480Smckusick return(error); 33841480Smckusick } 33941480Smckusick 340*64473Shibler grflock(gp, block) 341*64473Shibler register struct grf_softc *gp; 342*64473Shibler int block; 34341480Smckusick { 344*64473Shibler struct proc *p = curproc; /* XXX */ 345*64473Shibler int error; 346*64473Shibler extern char devioc[]; 34741480Smckusick 348*64473Shibler #ifdef DEBUG 349*64473Shibler if (grfdebug & GDB_LOCK) 350*64473Shibler printf("grflock(%d): dev %x flags %x lockpid %x\n", 351*64473Shibler p->p_pid, gp-grf_softc, gp->g_flags, 352*64473Shibler gp->g_lockp ? gp->g_lockp->p_pid : -1); 353*64473Shibler #endif 354*64473Shibler if (gp->g_pid) { 355*64473Shibler #ifdef DEBUG 356*64473Shibler if (grfdebug & GDB_LOCK) 357*64473Shibler printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", 358*64473Shibler gp->g_lock->gl_lockslot, gp->g_lockpslot, 359*64473Shibler gp->g_lock->gl_locks[gp->g_lockpslot]); 360*64473Shibler #endif 361*64473Shibler gp->g_lock->gl_lockslot = 0; 362*64473Shibler if (gp->g_lock->gl_locks[gp->g_lockpslot] == 0) { 363*64473Shibler gp->g_lockp = NULL; 364*64473Shibler gp->g_lockpslot = 0; 365*64473Shibler } 366*64473Shibler } 367*64473Shibler if (gp->g_lockp) { 368*64473Shibler if (gp->g_lockp == p) 369*64473Shibler return(EBUSY); 370*64473Shibler if (!block) 371*64473Shibler return(OEAGAIN); 372*64473Shibler do { 373*64473Shibler gp->g_flags |= GF_WANTED; 374*64473Shibler if (error = tsleep((caddr_t)&gp->g_flags, 375*64473Shibler (PZERO+1) | PCATCH, devioc, 0)) 376*64473Shibler return (error); 377*64473Shibler } while (gp->g_lockp); 378*64473Shibler } 379*64473Shibler gp->g_lockp = p; 380*64473Shibler if (gp->g_pid) { 381*64473Shibler int slot = grffindpid(gp); 38241480Smckusick 383*64473Shibler #ifdef DEBUG 384*64473Shibler if (grfdebug & GDB_LOCK) 385*64473Shibler printf(" slot %d\n", slot); 386*64473Shibler #endif 387*64473Shibler gp->g_lockpslot = gp->g_lock->gl_lockslot = slot; 388*64473Shibler gp->g_lock->gl_locks[slot] = 1; 389*64473Shibler } 390*64473Shibler return(0); 39141480Smckusick } 39241480Smckusick 393*64473Shibler grfunlock(gp) 394*64473Shibler register struct grf_softc *gp; 39541480Smckusick { 396*64473Shibler #ifdef DEBUG 397*64473Shibler if (grfdebug & GDB_LOCK) 398*64473Shibler printf("grfunlock(%d): dev %x flags %x lockpid %d\n", 399*64473Shibler curproc->p_pid, gp-grf_softc, gp->g_flags, 400*64473Shibler gp->g_lockp ? gp->g_lockp->p_pid : -1); 401*64473Shibler #endif 402*64473Shibler if (gp->g_lockp != curproc) 403*64473Shibler return(EBUSY); 404*64473Shibler if (gp->g_pid) { 405*64473Shibler #ifdef DEBUG 406*64473Shibler if (grfdebug & GDB_LOCK) 407*64473Shibler printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", 408*64473Shibler gp->g_lock->gl_lockslot, gp->g_lockpslot, 409*64473Shibler gp->g_lock->gl_locks[gp->g_lockpslot]); 410*64473Shibler #endif 411*64473Shibler gp->g_lock->gl_locks[gp->g_lockpslot] = 0; 412*64473Shibler gp->g_lockpslot = gp->g_lock->gl_lockslot = 0; 41341480Smckusick } 414*64473Shibler if (gp->g_flags & GF_WANTED) { 415*64473Shibler wakeup((caddr_t)&gp->g_flags); 416*64473Shibler gp->g_flags &= ~GF_WANTED; 417*64473Shibler } 418*64473Shibler gp->g_lockp = NULL; 419*64473Shibler return(0); 42041480Smckusick } 42141480Smckusick 42241480Smckusick /* 42341480Smckusick * Convert a BSD style minor devno to HPUX style. 42441480Smckusick * We cannot just create HPUX style nodes as they require 24 bits 42541480Smckusick * of minor device number and we only have 8. 42641480Smckusick * XXX: This may give the wrong result for remote stats of other 42741480Smckusick * machines where device 10 exists. 42841480Smckusick */ 42941480Smckusick grfdevno(dev) 43041480Smckusick dev_t dev; 43141480Smckusick { 43241480Smckusick int unit = GRFUNIT(dev); 43341480Smckusick struct grf_softc *gp = &grf_softc[unit]; 43453923Shibler int newdev; 43541480Smckusick 43641480Smckusick if (unit >= NGRF || (gp->g_flags&GF_ALIVE) == 0) 43741480Smckusick return(bsdtohpuxdev(dev)); 43841480Smckusick /* magic major number */ 43941480Smckusick newdev = 12 << 24; 44041480Smckusick /* now construct minor number */ 44149306Shibler if (gp->g_display.gd_regaddr != (caddr_t)GRFIADDR) { 44253923Shibler int sc = patosc(gp->g_display.gd_regaddr); 44349306Shibler newdev |= (sc << 16) | 0x200; 44449306Shibler } 44541480Smckusick if (dev & GRFIMDEV) 44641480Smckusick newdev |= 0x02; 44741480Smckusick else if (dev & GRFOVDEV) 44841480Smckusick newdev |= 0x01; 44941480Smckusick #ifdef DEBUG 45041480Smckusick if (grfdebug & GDB_DEVNO) 45141480Smckusick printf("grfdevno: dev %x newdev %x\n", dev, newdev); 45241480Smckusick #endif 45341480Smckusick return(newdev); 45441480Smckusick } 45541480Smckusick 456*64473Shibler #endif /* HPUXCOMPAT */ 457*64473Shibler 45849132Skarels grfmmap(dev, addrp, p) 45941480Smckusick dev_t dev; 46041480Smckusick caddr_t *addrp; 46149132Skarels struct proc *p; 46241480Smckusick { 46341480Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 46445750Smckusick int len, error; 46545750Smckusick struct vnode vn; 46645750Smckusick struct specinfo si; 46745750Smckusick int flags; 46841480Smckusick 46941480Smckusick #ifdef DEBUG 47041480Smckusick if (grfdebug & GDB_MMAP) 47143316Smckusick printf("grfmmap(%d): addr %x\n", p->p_pid, *addrp); 47241480Smckusick #endif 47341480Smckusick len = gp->g_display.gd_regsize + gp->g_display.gd_fbsize; 47454298Smckusick flags = MAP_SHARED; 47545750Smckusick if (*addrp) 47645750Smckusick flags |= MAP_FIXED; 47745750Smckusick else 47845750Smckusick *addrp = (caddr_t)0x1000000; /* XXX */ 47945750Smckusick vn.v_type = VCHR; /* XXX */ 48045750Smckusick vn.v_specinfo = &si; /* XXX */ 48145750Smckusick vn.v_rdev = dev; /* XXX */ 48249132Skarels error = vm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *)addrp, 48358591Shibler (vm_size_t)len, VM_PROT_ALL, VM_PROT_ALL, 48458591Shibler flags, (caddr_t)&vn, 0); 485*64473Shibler if (error == 0) 486*64473Shibler (void) (*gp->g_sw->gd_mode)(gp, GM_MAP, *addrp); 48743410Shibler return(error); 48841480Smckusick } 48941480Smckusick 49049132Skarels grfunmmap(dev, addr, p) 49141480Smckusick dev_t dev; 49241480Smckusick caddr_t addr; 49349132Skarels struct proc *p; 49441480Smckusick { 49545750Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 49645750Smckusick vm_size_t size; 49745750Smckusick int rv; 49841480Smckusick 49941480Smckusick #ifdef DEBUG 50041480Smckusick if (grfdebug & GDB_MMAP) 50145750Smckusick printf("grfunmmap(%d): dev %x addr %x\n", p->p_pid, dev, addr); 50241480Smckusick #endif 50345750Smckusick if (addr == 0) 50445750Smckusick return(EINVAL); /* XXX: how do we deal with this? */ 505*64473Shibler (void) (*gp->g_sw->gd_mode)(gp, GM_UNMAP, 0); 50645750Smckusick size = round_page(gp->g_display.gd_regsize + gp->g_display.gd_fbsize); 50753316Smckusick rv = vm_deallocate(&p->p_vmspace->vm_map, (vm_offset_t)addr, size); 50845750Smckusick return(rv == KERN_SUCCESS ? 0 : EINVAL); 50941480Smckusick } 51041480Smckusick 51141480Smckusick #ifdef HPUXCOMPAT 51241480Smckusick iommap(dev, addrp) 51341480Smckusick dev_t dev; 51441480Smckusick caddr_t *addrp; 51541480Smckusick { 51649132Skarels struct proc *p = curproc; /* XXX */ 51741480Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 51841480Smckusick 51941480Smckusick #ifdef DEBUG 52041480Smckusick if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 52143316Smckusick printf("iommap(%d): addr %x\n", p->p_pid, *addrp); 52241480Smckusick #endif 52345750Smckusick return(EINVAL); 52441480Smckusick } 52541480Smckusick 52641480Smckusick iounmmap(dev, addr) 52741480Smckusick dev_t dev; 52841480Smckusick caddr_t addr; 52941480Smckusick { 53045750Smckusick int unit = minor(dev); 53141480Smckusick 53241480Smckusick #ifdef DEBUG 53341480Smckusick if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 53441480Smckusick printf("iounmmap(%d): id %d addr %x\n", 53549132Skarels curproc->p_pid, unit, addr); 53641480Smckusick #endif 53745750Smckusick return(0); 53841480Smckusick } 53941480Smckusick 54041480Smckusick /* 54141480Smckusick * Processes involved in framebuffer mapping via GCSLOT are recorded in 54241480Smckusick * an array of pids. The first element is used to record the last slot used 54341480Smckusick * (for faster lookups). The remaining elements record up to GRFMAXLCK-1 54441480Smckusick * process ids. Returns a slot number between 1 and GRFMAXLCK or 0 if no 54541480Smckusick * slot is available. 54641480Smckusick */ 54741480Smckusick grffindpid(gp) 54841480Smckusick struct grf_softc *gp; 54941480Smckusick { 55041480Smckusick register short pid, *sp; 55141480Smckusick register int i, limit; 55241480Smckusick int ni; 55341480Smckusick 55441480Smckusick if (gp->g_pid == NULL) { 55541480Smckusick gp->g_pid = (short *) 55641480Smckusick malloc(GRFMAXLCK * sizeof(short), M_DEVBUF, M_WAITOK); 55741480Smckusick bzero((caddr_t)gp->g_pid, GRFMAXLCK * sizeof(short)); 55841480Smckusick } 55949132Skarels pid = curproc->p_pid; 56041480Smckusick ni = limit = gp->g_pid[0]; 56141480Smckusick for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 56241480Smckusick if (*sp == pid) 56341480Smckusick goto done; 56441480Smckusick if (*sp == 0) 56541480Smckusick ni = i; 56641480Smckusick } 56741480Smckusick i = ni; 56841480Smckusick if (i < limit) { 56941480Smckusick gp->g_pid[i] = pid; 57041480Smckusick goto done; 57141480Smckusick } 57241480Smckusick if (++i == GRFMAXLCK) 57341480Smckusick return(0); 57441480Smckusick gp->g_pid[0] = i; 57541480Smckusick gp->g_pid[i] = pid; 57641480Smckusick done: 57741480Smckusick #ifdef DEBUG 57841480Smckusick if (grfdebug & GDB_LOCK) 57941480Smckusick printf("grffindpid(%d): slot %d of %d\n", 58041480Smckusick pid, i, gp->g_pid[0]); 58141480Smckusick #endif 58241480Smckusick return(i); 58341480Smckusick } 58441480Smckusick 58541480Smckusick grfrmpid(gp) 58641480Smckusick struct grf_softc *gp; 58741480Smckusick { 58841480Smckusick register short pid, *sp; 58941480Smckusick register int limit, i; 59041480Smckusick int mi; 59141480Smckusick 59241480Smckusick if (gp->g_pid == NULL || (limit = gp->g_pid[0]) == 0) 59341480Smckusick return; 59449132Skarels pid = curproc->p_pid; 59541480Smckusick limit = gp->g_pid[0]; 59641480Smckusick mi = 0; 59741480Smckusick for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 59841480Smckusick if (*sp == pid) 59941480Smckusick *sp = 0; 60041480Smckusick else if (*sp) 60141480Smckusick mi = i; 60241480Smckusick } 60341480Smckusick i = mi; 60441480Smckusick if (i < limit) 60541480Smckusick gp->g_pid[0] = i; 60641480Smckusick #ifdef DEBUG 60741480Smckusick if (grfdebug & GDB_LOCK) 60841480Smckusick printf("grfrmpid(%d): slot %d of %d\n", 60941480Smckusick pid, sp-gp->g_pid, gp->g_pid[0]); 61041480Smckusick #endif 61141480Smckusick } 61241480Smckusick 61341480Smckusick grflckmmap(dev, addrp) 61441480Smckusick dev_t dev; 61541480Smckusick caddr_t *addrp; 61641480Smckusick { 61749132Skarels #ifdef DEBUG 61849132Skarels struct proc *p = curproc; /* XXX */ 61941480Smckusick 62041480Smckusick if (grfdebug & (GDB_MMAP|GDB_LOCK)) 62141480Smckusick printf("grflckmmap(%d): addr %x\n", 62243316Smckusick p->p_pid, *addrp); 62341480Smckusick #endif 62445750Smckusick return(EINVAL); 62541480Smckusick } 62641480Smckusick 62741480Smckusick grflckunmmap(dev, addr) 62841480Smckusick dev_t dev; 62941480Smckusick caddr_t addr; 63041480Smckusick { 63149132Skarels #ifdef DEBUG 63241480Smckusick int unit = minor(dev); 63341480Smckusick 63441480Smckusick if (grfdebug & (GDB_MMAP|GDB_LOCK)) 63541480Smckusick printf("grflckunmmap(%d): id %d addr %x\n", 63649132Skarels curproc->p_pid, unit, addr); 63741480Smckusick #endif 63841480Smckusick return(EINVAL); 63941480Smckusick } 64041480Smckusick #endif /* HPUXCOMPAT */ 64145750Smckusick 64241480Smckusick #endif /* NGRF > 0 */ 643