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 * 1264473Shibler * from: Utah $Hdr: grf.c 1.36 93/08/13$ 1341480Smckusick * 14*65698Shibler * @(#)grf.c 8.4 (Berkeley) 01/12/94 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; 7065642Sbostic int flags; 7141480Smckusick { 7241480Smckusick int unit = GRFUNIT(dev); 7341480Smckusick register struct grf_softc *gp = &grf_softc[unit]; 7441480Smckusick int error = 0; 7541480Smckusick 7641480Smckusick if (unit >= NGRF || (gp->g_flags & GF_ALIVE) == 0) 7741480Smckusick return(ENXIO); 7841480Smckusick if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE)) 7941480Smckusick return(EBUSY); 8041480Smckusick #ifdef HPUXCOMPAT 8141480Smckusick /* 8241480Smckusick * XXX: cannot handle both HPUX and BSD processes at the same time 8341480Smckusick */ 8457309Shibler if (curproc->p_md.md_flags & MDP_HPUX) 8541480Smckusick if (gp->g_flags & GF_BSDOPEN) 8641480Smckusick return(EBUSY); 8741480Smckusick else 8841480Smckusick gp->g_flags |= GF_HPUXOPEN; 8941480Smckusick else 9041480Smckusick if (gp->g_flags & GF_HPUXOPEN) 9141480Smckusick return(EBUSY); 9241480Smckusick else 9341480Smckusick gp->g_flags |= GF_BSDOPEN; 9441480Smckusick #endif 9541480Smckusick /* 9641480Smckusick * First open. 9741480Smckusick * XXX: always put in graphics mode. 9841480Smckusick */ 9941480Smckusick error = 0; 10041480Smckusick if ((gp->g_flags & GF_OPEN) == 0) { 10141480Smckusick gp->g_flags |= GF_OPEN; 10241480Smckusick error = grfon(dev); 10341480Smckusick } 10441480Smckusick return(error); 10541480Smckusick } 10641480Smckusick 10741480Smckusick /*ARGSUSED*/ 10841480Smckusick grfclose(dev, flags) 10941480Smckusick dev_t dev; 11065642Sbostic int flags; 11141480Smckusick { 11241480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 11341480Smckusick 11441480Smckusick (void) grfoff(dev); 11564473Shibler #ifdef HPUXCOMPAT 11641480Smckusick (void) grfunlock(gp); 11764473Shibler #endif 11841480Smckusick gp->g_flags &= GF_ALIVE; 11941480Smckusick return(0); 12041480Smckusick } 12141480Smckusick 12241480Smckusick /*ARGSUSED*/ 12349132Skarels grfioctl(dev, cmd, data, flag, p) 12441480Smckusick dev_t dev; 12565642Sbostic int cmd, flag; 12641480Smckusick caddr_t data; 12749132Skarels struct proc *p; 12841480Smckusick { 12941480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 13041480Smckusick int error; 13141480Smckusick 13241480Smckusick #ifdef HPUXCOMPAT 13357309Shibler if (p->p_md.md_flags & MDP_HPUX) 13449132Skarels return(hpuxgrfioctl(dev, cmd, data, flag, p)); 13541480Smckusick #endif 13641480Smckusick error = 0; 13741480Smckusick switch (cmd) { 13841480Smckusick 13941480Smckusick case GRFIOCGINFO: 14041480Smckusick bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)); 14141480Smckusick break; 14241480Smckusick 14341480Smckusick case GRFIOCON: 14441480Smckusick error = grfon(dev); 14541480Smckusick break; 14641480Smckusick 14741480Smckusick case GRFIOCOFF: 14841480Smckusick error = grfoff(dev); 14941480Smckusick break; 15041480Smckusick 15141480Smckusick case GRFIOCMAP: 15249132Skarels error = grfmmap(dev, (caddr_t *)data, p); 15341480Smckusick break; 15441480Smckusick 15541480Smckusick case GRFIOCUNMAP: 15649132Skarels error = grfunmmap(dev, *(caddr_t *)data, p); 15741480Smckusick break; 15841480Smckusick 15941480Smckusick default: 16041480Smckusick error = EINVAL; 16141480Smckusick break; 16241480Smckusick 16341480Smckusick } 16441480Smckusick return(error); 16541480Smckusick } 16641480Smckusick 16741480Smckusick /*ARGSUSED*/ 16841480Smckusick grfselect(dev, rw) 16941480Smckusick dev_t dev; 17065642Sbostic int rw; 17141480Smckusick { 17241480Smckusick if (rw == FREAD) 17341480Smckusick return(0); 17441480Smckusick return(1); 17541480Smckusick } 17641480Smckusick 17764473Shibler /*ARGSUSED*/ 17864473Shibler grfmap(dev, off, prot) 17964473Shibler dev_t dev; 18065642Sbostic int off, prot; 18141480Smckusick { 18264473Shibler return(grfaddr(&grf_softc[GRFUNIT(dev)], off)); 18341480Smckusick } 18441480Smckusick 18564473Shibler grfon(dev) 18664473Shibler dev_t dev; 18741480Smckusick { 18864473Shibler int unit = GRFUNIT(dev); 18964473Shibler struct grf_softc *gp = &grf_softc[unit]; 19064473Shibler 19164473Shibler /* 19264473Shibler * XXX: iteoff call relies on devices being in same order 19364473Shibler * as ITEs and the fact that iteoff only uses the minor part 19464473Shibler * of the dev arg. 19564473Shibler */ 19664473Shibler iteoff(unit, 3); 19764473Shibler return((*gp->g_sw->gd_mode)(gp, 19864473Shibler (dev&GRFOVDEV) ? GM_GRFOVON : GM_GRFON, 19964473Shibler (caddr_t)0)); 20041480Smckusick } 20141480Smckusick 20264473Shibler grfoff(dev) 20341480Smckusick dev_t dev; 20441480Smckusick { 20564473Shibler int unit = GRFUNIT(dev); 20664473Shibler struct grf_softc *gp = &grf_softc[unit]; 20764473Shibler int error; 20864473Shibler 20964473Shibler (void) grfunmmap(dev, (caddr_t)0, curproc); 21064473Shibler error = (*gp->g_sw->gd_mode)(gp, 21164473Shibler (dev&GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF, 21264473Shibler (caddr_t)0); 21364473Shibler /* XXX: see comment for iteoff above */ 21464473Shibler iteon(unit, 2); 21564473Shibler return(error); 21641480Smckusick } 21741480Smckusick 21864473Shibler grfaddr(gp, off) 21964473Shibler struct grf_softc *gp; 22064473Shibler register int off; 22164473Shibler { 22264473Shibler register struct grfinfo *gi = &gp->g_display; 22364473Shibler 22464473Shibler /* control registers */ 22564473Shibler if (off >= 0 && off < gi->gd_regsize) 22664473Shibler return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); 22764473Shibler 22864473Shibler /* frame buffer */ 22964473Shibler if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { 23064473Shibler off -= gi->gd_regsize; 23164473Shibler return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); 23264473Shibler } 23364473Shibler /* bogus */ 23464473Shibler return(-1); 23564473Shibler } 23664473Shibler 23764473Shibler /* 23864473Shibler * HP-UX compatibility routines 23964473Shibler */ 24041480Smckusick #ifdef HPUXCOMPAT 24141480Smckusick 24241480Smckusick /*ARGSUSED*/ 24349132Skarels hpuxgrfioctl(dev, cmd, data, flag, p) 24441480Smckusick dev_t dev; 24565642Sbostic int cmd, flag; 24641480Smckusick caddr_t data; 24749132Skarels struct proc *p; 24841480Smckusick { 24941480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 25041480Smckusick int error; 25141480Smckusick 25241480Smckusick error = 0; 25341480Smckusick switch (cmd) { 25441480Smckusick 25541480Smckusick case GCID: 25641480Smckusick *(int *)data = gp->g_display.gd_id; 25741480Smckusick break; 25841480Smckusick 25941480Smckusick case GCON: 26041480Smckusick error = grfon(dev); 26141480Smckusick break; 26241480Smckusick 26341480Smckusick case GCOFF: 26441480Smckusick error = grfoff(dev); 26541480Smckusick break; 26641480Smckusick 26741480Smckusick case GCLOCK: 26841480Smckusick error = grflock(gp, 1); 26941480Smckusick break; 27041480Smckusick 27141480Smckusick case GCUNLOCK: 27241480Smckusick error = grfunlock(gp); 27341480Smckusick break; 27441480Smckusick 27541480Smckusick case GCAON: 27641480Smckusick case GCAOFF: 27741480Smckusick break; 27841480Smckusick 27941480Smckusick /* GCSTATIC is implied by our implementation */ 28041480Smckusick case GCSTATIC_CMAP: 28141480Smckusick case GCVARIABLE_CMAP: 28241480Smckusick break; 28341480Smckusick 28441480Smckusick /* map in control regs and frame buffer */ 28541480Smckusick case GCMAP: 28649132Skarels error = grfmmap(dev, (caddr_t *)data, p); 28741480Smckusick break; 28841480Smckusick 28941480Smckusick case GCUNMAP: 29049132Skarels error = grfunmmap(dev, *(caddr_t *)data, p); 29141480Smckusick /* XXX: HP-UX uses GCUNMAP to get rid of GCSLOT memory */ 29241480Smckusick if (error) 29341480Smckusick error = grflckunmmap(dev, *(caddr_t *)data); 29441480Smckusick break; 29541480Smckusick 29641480Smckusick case GCSLOT: 29741480Smckusick { 29841480Smckusick struct grf_slot *sp = (struct grf_slot *)data; 29941480Smckusick 30041480Smckusick sp->slot = grffindpid(gp); 30145750Smckusick if (sp->slot) { 30241480Smckusick error = grflckmmap(dev, (caddr_t *)&sp->addr); 30345750Smckusick if (error && gp->g_pid) { 30445750Smckusick free((caddr_t)gp->g_pid, M_DEVBUF); 30545750Smckusick gp->g_pid = NULL; 30645750Smckusick } 30745750Smckusick } else 30841480Smckusick error = EINVAL; /* XXX */ 30941480Smckusick break; 31041480Smckusick } 31141480Smckusick 31264473Shibler case GCDESCRIBE: 31364473Shibler error = (*gp->g_sw->gd_mode)(gp, GM_DESCRIBE, data); 31464473Shibler break; 31564473Shibler 31641480Smckusick /* 31741480Smckusick * XXX: only used right now to map in rbox control registers 31841480Smckusick * Will be replaced in the future with a real IOMAP interface. 31941480Smckusick */ 32041480Smckusick case IOMAPMAP: 32141480Smckusick error = iommap(dev, (caddr_t *)data); 32243410Shibler #if 0 32343410Shibler /* 32443410Shibler * It may not be worth kludging this (using p_devtmp) to 32543410Shibler * make this work. It was an undocumented side-effect 32643410Shibler * in HP-UX that the mapped address was the return value 32743410Shibler * of the ioctl. The only thing I remember that counted 32843410Shibler * on this behavior was the rbox X10 server. 32943410Shibler */ 33041480Smckusick if (!error) 33141480Smckusick u.u_r.r_val1 = *(int *)data; /* XXX: this sux */ 33243410Shibler #endif 33341480Smckusick break; 33441480Smckusick 33541480Smckusick case IOMAPUNMAP: 33641480Smckusick error = iounmmap(dev, *(caddr_t *)data); 33741480Smckusick break; 33841480Smckusick 33941480Smckusick default: 34041480Smckusick error = EINVAL; 34141480Smckusick break; 34241480Smckusick } 34341480Smckusick return(error); 34441480Smckusick } 34541480Smckusick 34664473Shibler grflock(gp, block) 34764473Shibler register struct grf_softc *gp; 34864473Shibler int block; 34941480Smckusick { 35064473Shibler struct proc *p = curproc; /* XXX */ 35164473Shibler int error; 35264473Shibler extern char devioc[]; 35341480Smckusick 35464473Shibler #ifdef DEBUG 35564473Shibler if (grfdebug & GDB_LOCK) 35664473Shibler printf("grflock(%d): dev %x flags %x lockpid %x\n", 35764473Shibler p->p_pid, gp-grf_softc, gp->g_flags, 35864473Shibler gp->g_lockp ? gp->g_lockp->p_pid : -1); 35964473Shibler #endif 36064473Shibler if (gp->g_pid) { 36164473Shibler #ifdef DEBUG 36264473Shibler if (grfdebug & GDB_LOCK) 36364473Shibler printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", 36464473Shibler gp->g_lock->gl_lockslot, gp->g_lockpslot, 36564473Shibler gp->g_lock->gl_locks[gp->g_lockpslot]); 36664473Shibler #endif 36764473Shibler gp->g_lock->gl_lockslot = 0; 36864473Shibler if (gp->g_lock->gl_locks[gp->g_lockpslot] == 0) { 36964473Shibler gp->g_lockp = NULL; 37064473Shibler gp->g_lockpslot = 0; 37164473Shibler } 37264473Shibler } 37364473Shibler if (gp->g_lockp) { 37464473Shibler if (gp->g_lockp == p) 37564473Shibler return(EBUSY); 37664473Shibler if (!block) 37764473Shibler return(OEAGAIN); 37864473Shibler do { 37964473Shibler gp->g_flags |= GF_WANTED; 38064473Shibler if (error = tsleep((caddr_t)&gp->g_flags, 38164473Shibler (PZERO+1) | PCATCH, devioc, 0)) 38264473Shibler return (error); 38364473Shibler } while (gp->g_lockp); 38464473Shibler } 38564473Shibler gp->g_lockp = p; 38664473Shibler if (gp->g_pid) { 38764473Shibler int slot = grffindpid(gp); 38841480Smckusick 38964473Shibler #ifdef DEBUG 39064473Shibler if (grfdebug & GDB_LOCK) 39164473Shibler printf(" slot %d\n", slot); 39264473Shibler #endif 39364473Shibler gp->g_lockpslot = gp->g_lock->gl_lockslot = slot; 39464473Shibler gp->g_lock->gl_locks[slot] = 1; 39564473Shibler } 39664473Shibler return(0); 39741480Smckusick } 39841480Smckusick 39964473Shibler grfunlock(gp) 40064473Shibler register struct grf_softc *gp; 40141480Smckusick { 40264473Shibler #ifdef DEBUG 40364473Shibler if (grfdebug & GDB_LOCK) 40464473Shibler printf("grfunlock(%d): dev %x flags %x lockpid %d\n", 40564473Shibler curproc->p_pid, gp-grf_softc, gp->g_flags, 40664473Shibler gp->g_lockp ? gp->g_lockp->p_pid : -1); 40764473Shibler #endif 40864473Shibler if (gp->g_lockp != curproc) 40964473Shibler return(EBUSY); 41064473Shibler if (gp->g_pid) { 41164473Shibler #ifdef DEBUG 41264473Shibler if (grfdebug & GDB_LOCK) 41364473Shibler printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", 41464473Shibler gp->g_lock->gl_lockslot, gp->g_lockpslot, 41564473Shibler gp->g_lock->gl_locks[gp->g_lockpslot]); 41664473Shibler #endif 41764473Shibler gp->g_lock->gl_locks[gp->g_lockpslot] = 0; 41864473Shibler gp->g_lockpslot = gp->g_lock->gl_lockslot = 0; 41941480Smckusick } 42064473Shibler if (gp->g_flags & GF_WANTED) { 42164473Shibler wakeup((caddr_t)&gp->g_flags); 42264473Shibler gp->g_flags &= ~GF_WANTED; 42364473Shibler } 42464473Shibler gp->g_lockp = NULL; 42564473Shibler return(0); 42641480Smckusick } 42741480Smckusick 42841480Smckusick /* 42941480Smckusick * Convert a BSD style minor devno to HPUX style. 43041480Smckusick * We cannot just create HPUX style nodes as they require 24 bits 43141480Smckusick * of minor device number and we only have 8. 43241480Smckusick * XXX: This may give the wrong result for remote stats of other 43341480Smckusick * machines where device 10 exists. 43441480Smckusick */ 43541480Smckusick grfdevno(dev) 43641480Smckusick dev_t dev; 43741480Smckusick { 43841480Smckusick int unit = GRFUNIT(dev); 43941480Smckusick struct grf_softc *gp = &grf_softc[unit]; 44053923Shibler int newdev; 44141480Smckusick 44241480Smckusick if (unit >= NGRF || (gp->g_flags&GF_ALIVE) == 0) 44341480Smckusick return(bsdtohpuxdev(dev)); 44441480Smckusick /* magic major number */ 44541480Smckusick newdev = 12 << 24; 44641480Smckusick /* now construct minor number */ 44749306Shibler if (gp->g_display.gd_regaddr != (caddr_t)GRFIADDR) { 44853923Shibler int sc = patosc(gp->g_display.gd_regaddr); 44949306Shibler newdev |= (sc << 16) | 0x200; 45049306Shibler } 45141480Smckusick if (dev & GRFIMDEV) 45241480Smckusick newdev |= 0x02; 45341480Smckusick else if (dev & GRFOVDEV) 45441480Smckusick newdev |= 0x01; 45541480Smckusick #ifdef DEBUG 45641480Smckusick if (grfdebug & GDB_DEVNO) 45741480Smckusick printf("grfdevno: dev %x newdev %x\n", dev, newdev); 45841480Smckusick #endif 45941480Smckusick return(newdev); 46041480Smckusick } 46141480Smckusick 46264473Shibler #endif /* HPUXCOMPAT */ 46364473Shibler 46449132Skarels grfmmap(dev, addrp, p) 46541480Smckusick dev_t dev; 46641480Smckusick caddr_t *addrp; 46749132Skarels struct proc *p; 46841480Smckusick { 46941480Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 47045750Smckusick int len, error; 47145750Smckusick struct vnode vn; 47245750Smckusick struct specinfo si; 47345750Smckusick int flags; 47441480Smckusick 47541480Smckusick #ifdef DEBUG 47641480Smckusick if (grfdebug & GDB_MMAP) 47743316Smckusick printf("grfmmap(%d): addr %x\n", p->p_pid, *addrp); 47841480Smckusick #endif 47941480Smckusick len = gp->g_display.gd_regsize + gp->g_display.gd_fbsize; 48054298Smckusick flags = MAP_SHARED; 48145750Smckusick if (*addrp) 48245750Smckusick flags |= MAP_FIXED; 48345750Smckusick else 48445750Smckusick *addrp = (caddr_t)0x1000000; /* XXX */ 48545750Smckusick vn.v_type = VCHR; /* XXX */ 48645750Smckusick vn.v_specinfo = &si; /* XXX */ 48745750Smckusick vn.v_rdev = dev; /* XXX */ 48849132Skarels error = vm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *)addrp, 48958591Shibler (vm_size_t)len, VM_PROT_ALL, VM_PROT_ALL, 49058591Shibler flags, (caddr_t)&vn, 0); 49164473Shibler if (error == 0) 49264473Shibler (void) (*gp->g_sw->gd_mode)(gp, GM_MAP, *addrp); 49343410Shibler return(error); 49441480Smckusick } 49541480Smckusick 49649132Skarels grfunmmap(dev, addr, p) 49741480Smckusick dev_t dev; 49841480Smckusick caddr_t addr; 49949132Skarels struct proc *p; 50041480Smckusick { 50145750Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 50245750Smckusick vm_size_t size; 50345750Smckusick int rv; 50441480Smckusick 50541480Smckusick #ifdef DEBUG 50641480Smckusick if (grfdebug & GDB_MMAP) 50745750Smckusick printf("grfunmmap(%d): dev %x addr %x\n", p->p_pid, dev, addr); 50841480Smckusick #endif 50945750Smckusick if (addr == 0) 51045750Smckusick return(EINVAL); /* XXX: how do we deal with this? */ 51164473Shibler (void) (*gp->g_sw->gd_mode)(gp, GM_UNMAP, 0); 51245750Smckusick size = round_page(gp->g_display.gd_regsize + gp->g_display.gd_fbsize); 51353316Smckusick rv = vm_deallocate(&p->p_vmspace->vm_map, (vm_offset_t)addr, size); 51445750Smckusick return(rv == KERN_SUCCESS ? 0 : EINVAL); 51541480Smckusick } 51641480Smckusick 51741480Smckusick #ifdef HPUXCOMPAT 51841480Smckusick iommap(dev, addrp) 51941480Smckusick dev_t dev; 52041480Smckusick caddr_t *addrp; 52141480Smckusick { 52241480Smckusick 52341480Smckusick #ifdef DEBUG 52441480Smckusick if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 525*65698Shibler printf("iommap(%d): addr %x\n", curproc->p_pid, *addrp); 52641480Smckusick #endif 52745750Smckusick return(EINVAL); 52841480Smckusick } 52941480Smckusick 53041480Smckusick iounmmap(dev, addr) 53141480Smckusick dev_t dev; 53241480Smckusick caddr_t addr; 53341480Smckusick { 53445750Smckusick int unit = minor(dev); 53541480Smckusick 53641480Smckusick #ifdef DEBUG 53741480Smckusick if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 53841480Smckusick printf("iounmmap(%d): id %d addr %x\n", 53949132Skarels curproc->p_pid, unit, addr); 54041480Smckusick #endif 54145750Smckusick return(0); 54241480Smckusick } 54341480Smckusick 54441480Smckusick /* 54541480Smckusick * Processes involved in framebuffer mapping via GCSLOT are recorded in 54641480Smckusick * an array of pids. The first element is used to record the last slot used 54741480Smckusick * (for faster lookups). The remaining elements record up to GRFMAXLCK-1 54841480Smckusick * process ids. Returns a slot number between 1 and GRFMAXLCK or 0 if no 54941480Smckusick * slot is available. 55041480Smckusick */ 55141480Smckusick grffindpid(gp) 55241480Smckusick struct grf_softc *gp; 55341480Smckusick { 55441480Smckusick register short pid, *sp; 55541480Smckusick register int i, limit; 55641480Smckusick int ni; 55741480Smckusick 55841480Smckusick if (gp->g_pid == NULL) { 55941480Smckusick gp->g_pid = (short *) 56041480Smckusick malloc(GRFMAXLCK * sizeof(short), M_DEVBUF, M_WAITOK); 56141480Smckusick bzero((caddr_t)gp->g_pid, GRFMAXLCK * sizeof(short)); 56241480Smckusick } 56349132Skarels pid = curproc->p_pid; 56441480Smckusick ni = limit = gp->g_pid[0]; 56541480Smckusick for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 56641480Smckusick if (*sp == pid) 56741480Smckusick goto done; 56841480Smckusick if (*sp == 0) 56941480Smckusick ni = i; 57041480Smckusick } 57141480Smckusick i = ni; 57241480Smckusick if (i < limit) { 57341480Smckusick gp->g_pid[i] = pid; 57441480Smckusick goto done; 57541480Smckusick } 57641480Smckusick if (++i == GRFMAXLCK) 57741480Smckusick return(0); 57841480Smckusick gp->g_pid[0] = i; 57941480Smckusick gp->g_pid[i] = pid; 58041480Smckusick done: 58141480Smckusick #ifdef DEBUG 58241480Smckusick if (grfdebug & GDB_LOCK) 58341480Smckusick printf("grffindpid(%d): slot %d of %d\n", 58441480Smckusick pid, i, gp->g_pid[0]); 58541480Smckusick #endif 58641480Smckusick return(i); 58741480Smckusick } 58841480Smckusick 58941480Smckusick grfrmpid(gp) 59041480Smckusick struct grf_softc *gp; 59141480Smckusick { 59241480Smckusick register short pid, *sp; 59341480Smckusick register int limit, i; 59441480Smckusick int mi; 59541480Smckusick 59641480Smckusick if (gp->g_pid == NULL || (limit = gp->g_pid[0]) == 0) 59741480Smckusick return; 59849132Skarels pid = curproc->p_pid; 59941480Smckusick limit = gp->g_pid[0]; 60041480Smckusick mi = 0; 60141480Smckusick for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 60241480Smckusick if (*sp == pid) 60341480Smckusick *sp = 0; 60441480Smckusick else if (*sp) 60541480Smckusick mi = i; 60641480Smckusick } 60741480Smckusick i = mi; 60841480Smckusick if (i < limit) 60941480Smckusick gp->g_pid[0] = i; 61041480Smckusick #ifdef DEBUG 61141480Smckusick if (grfdebug & GDB_LOCK) 61241480Smckusick printf("grfrmpid(%d): slot %d of %d\n", 61341480Smckusick pid, sp-gp->g_pid, gp->g_pid[0]); 61441480Smckusick #endif 61541480Smckusick } 61641480Smckusick 61741480Smckusick grflckmmap(dev, addrp) 61841480Smckusick dev_t dev; 61941480Smckusick caddr_t *addrp; 62041480Smckusick { 62149132Skarels #ifdef DEBUG 62249132Skarels struct proc *p = curproc; /* XXX */ 62341480Smckusick 62441480Smckusick if (grfdebug & (GDB_MMAP|GDB_LOCK)) 62541480Smckusick printf("grflckmmap(%d): addr %x\n", 62643316Smckusick p->p_pid, *addrp); 62741480Smckusick #endif 62845750Smckusick return(EINVAL); 62941480Smckusick } 63041480Smckusick 63141480Smckusick grflckunmmap(dev, addr) 63241480Smckusick dev_t dev; 63341480Smckusick caddr_t addr; 63441480Smckusick { 63549132Skarels #ifdef DEBUG 63641480Smckusick int unit = minor(dev); 63741480Smckusick 63841480Smckusick if (grfdebug & (GDB_MMAP|GDB_LOCK)) 63941480Smckusick printf("grflckunmmap(%d): id %d addr %x\n", 64049132Skarels curproc->p_pid, unit, addr); 64141480Smckusick #endif 64241480Smckusick return(EINVAL); 64341480Smckusick } 64441480Smckusick #endif /* HPUXCOMPAT */ 64545750Smckusick 64641480Smckusick #endif /* NGRF > 0 */ 647