141480Smckusick /* 241480Smckusick * Copyright (c) 1988 University of Utah. 341480Smckusick * Copyright (c) 1990 The Regents of the University of California. 441480Smckusick * 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 * 1253923Shibler * from: Utah $Hdr: grf.c 1.32 92/01/21$ 1341480Smckusick * 14*54298Smckusick * @(#)grf.c 7.12 (Berkeley) 06/23/92 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 2341480Smckusick #include "grf.h" 2441480Smckusick #if NGRF > 0 2541480Smckusick 2649132Skarels #include "param.h" 2749132Skarels #include "proc.h" 2849132Skarels #include "ioctl.h" 2949132Skarels #include "file.h" 3049132Skarels #include "malloc.h" 3141480Smckusick 3241480Smckusick #include "grfioctl.h" 3341480Smckusick #include "grfvar.h" 3453923Shibler #include "grfreg.h" 3541480Smckusick 3649132Skarels #include "machine/cpu.h" 3741480Smckusick 3841480Smckusick #ifdef HPUXCOMPAT 3941480Smckusick #include "../hpux/hpux.h" 4041480Smckusick #endif 4141480Smckusick 4249132Skarels #include "vm/vm.h" 4345788Sbostic #include "vm/vm_kern.h" 4445788Sbostic #include "vm/vm_page.h" 4545788Sbostic #include "vm/vm_pager.h" 4645750Smckusick 4753504Sheideman #include "vnode.h" 4849132Skarels #include "specdev.h" 4949132Skarels #include "mman.h" 5049132Skarels 5141480Smckusick #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 */ 8349132Skarels if (curproc->p_flag & SHPUX) 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); 11341480Smckusick (void) grfunlock(gp); 11441480Smckusick gp->g_flags &= GF_ALIVE; 11541480Smckusick return(0); 11641480Smckusick } 11741480Smckusick 11841480Smckusick /*ARGSUSED*/ 11949132Skarels grfioctl(dev, cmd, data, flag, p) 12041480Smckusick dev_t dev; 12141480Smckusick caddr_t data; 12249132Skarels struct proc *p; 12341480Smckusick { 12441480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 12541480Smckusick int error; 12641480Smckusick 12741480Smckusick #ifdef HPUXCOMPAT 12849132Skarels if (p->p_flag & SHPUX) 12949132Skarels return(hpuxgrfioctl(dev, cmd, data, flag, p)); 13041480Smckusick #endif 13141480Smckusick error = 0; 13241480Smckusick switch (cmd) { 13341480Smckusick 13441480Smckusick case GRFIOCGINFO: 13541480Smckusick bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)); 13641480Smckusick break; 13741480Smckusick 13841480Smckusick case GRFIOCON: 13941480Smckusick error = grfon(dev); 14041480Smckusick break; 14141480Smckusick 14241480Smckusick case GRFIOCOFF: 14341480Smckusick error = grfoff(dev); 14441480Smckusick break; 14541480Smckusick 14641480Smckusick case GRFIOCMAP: 14749132Skarels error = grfmmap(dev, (caddr_t *)data, p); 14841480Smckusick break; 14941480Smckusick 15041480Smckusick case GRFIOCUNMAP: 15149132Skarels error = grfunmmap(dev, *(caddr_t *)data, p); 15241480Smckusick break; 15341480Smckusick 15441480Smckusick default: 15541480Smckusick error = EINVAL; 15641480Smckusick break; 15741480Smckusick 15841480Smckusick } 15941480Smckusick return(error); 16041480Smckusick } 16141480Smckusick 16241480Smckusick /*ARGSUSED*/ 16341480Smckusick grfselect(dev, rw) 16441480Smckusick dev_t dev; 16541480Smckusick { 16641480Smckusick if (rw == FREAD) 16741480Smckusick return(0); 16841480Smckusick return(1); 16941480Smckusick } 17041480Smckusick 17141480Smckusick grflock(gp, block) 17241480Smckusick register struct grf_softc *gp; 17341480Smckusick int block; 17441480Smckusick { 17549132Skarels struct proc *p = curproc; /* XXX */ 17642358Smckusick int error; 17742358Smckusick extern char devioc[]; 17842358Smckusick 17941480Smckusick #ifdef DEBUG 18041480Smckusick if (grfdebug & GDB_LOCK) 18141480Smckusick printf("grflock(%d): dev %x flags %x lockpid %x\n", 18243316Smckusick p->p_pid, gp-grf_softc, gp->g_flags, 18341480Smckusick gp->g_lockp ? gp->g_lockp->p_pid : -1); 18441480Smckusick #endif 18541480Smckusick #ifdef HPUXCOMPAT 18641480Smckusick if (gp->g_pid) { 18741480Smckusick #ifdef DEBUG 18841480Smckusick if (grfdebug & GDB_LOCK) 18949306Shibler printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", 19049306Shibler gp->g_lock->gl_lockslot, gp->g_lockpslot, 19149306Shibler gp->g_lock->gl_locks[gp->g_lockpslot]); 19241480Smckusick #endif 19349306Shibler gp->g_lock->gl_lockslot = 0; 19449306Shibler if (gp->g_lock->gl_locks[gp->g_lockpslot] == 0) { 19541480Smckusick gp->g_lockp = NULL; 19641480Smckusick gp->g_lockpslot = 0; 19741480Smckusick } 19841480Smckusick } 19941480Smckusick #endif 20041480Smckusick if (gp->g_lockp) { 20143316Smckusick if (gp->g_lockp == p) 20241480Smckusick return(EBUSY); 20341480Smckusick if (!block) 20441480Smckusick return(EAGAIN); 20541480Smckusick do { 20641480Smckusick gp->g_flags |= GF_WANTED; 20742358Smckusick if (error = tsleep((caddr_t)&gp->g_flags, 20842358Smckusick (PZERO+1) | PCATCH, devioc, 0)) 20942358Smckusick return (error); 21041480Smckusick } while (gp->g_lockp); 21141480Smckusick } 21243316Smckusick gp->g_lockp = p; 21341480Smckusick #ifdef HPUXCOMPAT 21441480Smckusick if (gp->g_pid) { 21541480Smckusick int slot = grffindpid(gp); 21641480Smckusick #ifdef DEBUG 21741480Smckusick if (grfdebug & GDB_LOCK) 21841480Smckusick printf(" slot %d\n", slot); 21941480Smckusick #endif 22049306Shibler gp->g_lockpslot = gp->g_lock->gl_lockslot = slot; 22149306Shibler gp->g_lock->gl_locks[slot] = 1; 22241480Smckusick } 22341480Smckusick #endif 22441480Smckusick return(0); 22541480Smckusick } 22641480Smckusick 22741480Smckusick grfunlock(gp) 22841480Smckusick register struct grf_softc *gp; 22941480Smckusick { 23041480Smckusick #ifdef DEBUG 23141480Smckusick if (grfdebug & GDB_LOCK) 23241480Smckusick printf("grfunlock(%d): dev %x flags %x lockpid %d\n", 23349132Skarels curproc->p_pid, gp-grf_softc, gp->g_flags, 23441480Smckusick gp->g_lockp ? gp->g_lockp->p_pid : -1); 23541480Smckusick #endif 23649132Skarels if (gp->g_lockp != curproc) 23741480Smckusick return(EBUSY); 23841480Smckusick #ifdef HPUXCOMPAT 23941480Smckusick if (gp->g_pid) { 24041480Smckusick #ifdef DEBUG 24141480Smckusick if (grfdebug & GDB_LOCK) 24249306Shibler printf(" lockpslot %d lockslot %d lock[lockslot] %d\n", 24349306Shibler gp->g_lock->gl_lockslot, gp->g_lockpslot, 24449306Shibler gp->g_lock->gl_locks[gp->g_lockpslot]); 24541480Smckusick #endif 24649306Shibler gp->g_lock->gl_locks[gp->g_lockpslot] = 0; 24749306Shibler gp->g_lockpslot = gp->g_lock->gl_lockslot = 0; 24841480Smckusick } 24941480Smckusick #endif 25041480Smckusick if (gp->g_flags & GF_WANTED) { 25141480Smckusick wakeup((caddr_t)&gp->g_flags); 25241480Smckusick gp->g_flags &= ~GF_WANTED; 25341480Smckusick } 25441480Smckusick gp->g_lockp = NULL; 25541480Smckusick return(0); 25641480Smckusick } 25741480Smckusick 25841480Smckusick /*ARGSUSED*/ 25941480Smckusick grfmap(dev, off, prot) 26041480Smckusick dev_t dev; 26141480Smckusick { 26241480Smckusick return(grfaddr(&grf_softc[GRFUNIT(dev)], off)); 26341480Smckusick } 26441480Smckusick 26541480Smckusick #ifdef HPUXCOMPAT 26641480Smckusick 26741480Smckusick /*ARGSUSED*/ 26849132Skarels hpuxgrfioctl(dev, cmd, data, flag, p) 26941480Smckusick dev_t dev; 27041480Smckusick caddr_t data; 27149132Skarels struct proc *p; 27241480Smckusick { 27341480Smckusick register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 27441480Smckusick int error; 27541480Smckusick 27641480Smckusick error = 0; 27741480Smckusick switch (cmd) { 27841480Smckusick 27941480Smckusick case GCID: 28041480Smckusick *(int *)data = gp->g_display.gd_id; 28141480Smckusick break; 28241480Smckusick 28341480Smckusick case GCON: 28441480Smckusick error = grfon(dev); 28541480Smckusick break; 28641480Smckusick 28741480Smckusick case GCOFF: 28841480Smckusick error = grfoff(dev); 28941480Smckusick break; 29041480Smckusick 29141480Smckusick case GCLOCK: 29241480Smckusick error = grflock(gp, 1); 29341480Smckusick break; 29441480Smckusick 29541480Smckusick case GCUNLOCK: 29641480Smckusick error = grfunlock(gp); 29741480Smckusick break; 29841480Smckusick 29941480Smckusick case GCAON: 30041480Smckusick case GCAOFF: 30141480Smckusick break; 30241480Smckusick 30341480Smckusick /* GCSTATIC is implied by our implementation */ 30441480Smckusick case GCSTATIC_CMAP: 30541480Smckusick case GCVARIABLE_CMAP: 30641480Smckusick break; 30741480Smckusick 30841480Smckusick /* map in control regs and frame buffer */ 30941480Smckusick case GCMAP: 31049132Skarels error = grfmmap(dev, (caddr_t *)data, p); 31141480Smckusick break; 31241480Smckusick 31341480Smckusick case GCUNMAP: 31449132Skarels error = grfunmmap(dev, *(caddr_t *)data, p); 31541480Smckusick /* XXX: HP-UX uses GCUNMAP to get rid of GCSLOT memory */ 31641480Smckusick if (error) 31741480Smckusick error = grflckunmmap(dev, *(caddr_t *)data); 31841480Smckusick break; 31941480Smckusick 32041480Smckusick case GCSLOT: 32141480Smckusick { 32241480Smckusick struct grf_slot *sp = (struct grf_slot *)data; 32341480Smckusick 32441480Smckusick sp->slot = grffindpid(gp); 32545750Smckusick if (sp->slot) { 32641480Smckusick error = grflckmmap(dev, (caddr_t *)&sp->addr); 32745750Smckusick if (error && gp->g_pid) { 32845750Smckusick free((caddr_t)gp->g_pid, M_DEVBUF); 32945750Smckusick gp->g_pid = NULL; 33045750Smckusick } 33145750Smckusick } else 33241480Smckusick error = EINVAL; /* XXX */ 33341480Smckusick break; 33441480Smckusick } 33541480Smckusick 33641480Smckusick /* 33741480Smckusick * XXX: only used right now to map in rbox control registers 33841480Smckusick * Will be replaced in the future with a real IOMAP interface. 33941480Smckusick */ 34041480Smckusick case IOMAPMAP: 34141480Smckusick error = iommap(dev, (caddr_t *)data); 34243410Shibler #if 0 34343410Shibler /* 34443410Shibler * It may not be worth kludging this (using p_devtmp) to 34543410Shibler * make this work. It was an undocumented side-effect 34643410Shibler * in HP-UX that the mapped address was the return value 34743410Shibler * of the ioctl. The only thing I remember that counted 34843410Shibler * on this behavior was the rbox X10 server. 34943410Shibler */ 35041480Smckusick if (!error) 35141480Smckusick u.u_r.r_val1 = *(int *)data; /* XXX: this sux */ 35243410Shibler #endif 35341480Smckusick break; 35441480Smckusick 35541480Smckusick case IOMAPUNMAP: 35641480Smckusick error = iounmmap(dev, *(caddr_t *)data); 35741480Smckusick break; 35841480Smckusick 35941480Smckusick default: 36041480Smckusick error = EINVAL; 36141480Smckusick break; 36241480Smckusick } 36341480Smckusick return(error); 36441480Smckusick } 36541480Smckusick 36641480Smckusick #endif 36741480Smckusick 36841480Smckusick grfon(dev) 36941480Smckusick dev_t dev; 37041480Smckusick { 37141480Smckusick int unit = GRFUNIT(dev); 37241480Smckusick struct grf_softc *gp = &grf_softc[unit]; 37341480Smckusick 37441480Smckusick /* 37541480Smckusick * XXX: iteoff call relies on devices being in same order 37641480Smckusick * as ITEs and the fact that iteoff only uses the minor part 37741480Smckusick * of the dev arg. 37841480Smckusick */ 37941480Smckusick iteoff(unit, 3); 38053923Shibler return((*gp->g_sw->gd_mode)(gp, 38153923Shibler (dev&GRFOVDEV) ? GM_GRFOVON : GM_GRFON, 38253923Shibler (caddr_t)0)); 38341480Smckusick } 38441480Smckusick 38541480Smckusick grfoff(dev) 38641480Smckusick dev_t dev; 38741480Smckusick { 38841480Smckusick int unit = GRFUNIT(dev); 38941480Smckusick struct grf_softc *gp = &grf_softc[unit]; 39041480Smckusick int error; 39141480Smckusick 39249132Skarels (void) grfunmmap(dev, (caddr_t)0, curproc); 39353923Shibler error = (*gp->g_sw->gd_mode)(gp, 39453923Shibler (dev&GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF, 39553923Shibler (caddr_t)0); 39641480Smckusick /* XXX: see comment for iteoff above */ 39741480Smckusick iteon(unit, 2); 39841480Smckusick return(error); 39941480Smckusick } 40041480Smckusick 40141480Smckusick grfaddr(gp, off) 40241480Smckusick struct grf_softc *gp; 40341480Smckusick register int off; 40441480Smckusick { 40541480Smckusick register struct grfinfo *gi = &gp->g_display; 40641480Smckusick 40741480Smckusick /* control registers */ 40841480Smckusick if (off >= 0 && off < gi->gd_regsize) 40941480Smckusick return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); 41041480Smckusick 41141480Smckusick /* frame buffer */ 41241480Smckusick if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { 41341480Smckusick off -= gi->gd_regsize; 41441480Smckusick return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); 41541480Smckusick } 41641480Smckusick /* bogus */ 41741480Smckusick return(-1); 41841480Smckusick } 41941480Smckusick 42041480Smckusick #ifdef HPUXCOMPAT 42141480Smckusick /* 42241480Smckusick * Convert a BSD style minor devno to HPUX style. 42341480Smckusick * We cannot just create HPUX style nodes as they require 24 bits 42441480Smckusick * of minor device number and we only have 8. 42541480Smckusick * XXX: This may give the wrong result for remote stats of other 42641480Smckusick * machines where device 10 exists. 42741480Smckusick */ 42841480Smckusick grfdevno(dev) 42941480Smckusick dev_t dev; 43041480Smckusick { 43141480Smckusick int unit = GRFUNIT(dev); 43241480Smckusick struct grf_softc *gp = &grf_softc[unit]; 43353923Shibler int newdev; 43441480Smckusick 43541480Smckusick if (unit >= NGRF || (gp->g_flags&GF_ALIVE) == 0) 43641480Smckusick return(bsdtohpuxdev(dev)); 43741480Smckusick /* magic major number */ 43841480Smckusick newdev = 12 << 24; 43941480Smckusick /* now construct minor number */ 44049306Shibler if (gp->g_display.gd_regaddr != (caddr_t)GRFIADDR) { 44153923Shibler int sc = patosc(gp->g_display.gd_regaddr); 44249306Shibler newdev |= (sc << 16) | 0x200; 44349306Shibler } 44441480Smckusick if (dev & GRFIMDEV) 44541480Smckusick newdev |= 0x02; 44641480Smckusick else if (dev & GRFOVDEV) 44741480Smckusick newdev |= 0x01; 44841480Smckusick #ifdef DEBUG 44941480Smckusick if (grfdebug & GDB_DEVNO) 45041480Smckusick printf("grfdevno: dev %x newdev %x\n", dev, newdev); 45141480Smckusick #endif 45241480Smckusick return(newdev); 45341480Smckusick } 45441480Smckusick #endif 45541480Smckusick 45649132Skarels grfmmap(dev, addrp, p) 45741480Smckusick dev_t dev; 45841480Smckusick caddr_t *addrp; 45949132Skarels struct proc *p; 46041480Smckusick { 46141480Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 46245750Smckusick int len, error; 46345750Smckusick struct vnode vn; 46445750Smckusick struct specinfo si; 46545750Smckusick int flags; 46641480Smckusick 46741480Smckusick #ifdef DEBUG 46841480Smckusick if (grfdebug & GDB_MMAP) 46943316Smckusick printf("grfmmap(%d): addr %x\n", p->p_pid, *addrp); 47041480Smckusick #endif 47141480Smckusick len = gp->g_display.gd_regsize + gp->g_display.gd_fbsize; 472*54298Smckusick flags = MAP_SHARED; 47345750Smckusick if (*addrp) 47445750Smckusick flags |= MAP_FIXED; 47545750Smckusick else 47645750Smckusick *addrp = (caddr_t)0x1000000; /* XXX */ 47745750Smckusick vn.v_type = VCHR; /* XXX */ 47845750Smckusick vn.v_specinfo = &si; /* XXX */ 47945750Smckusick vn.v_rdev = dev; /* XXX */ 48049132Skarels error = vm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *)addrp, 48145750Smckusick (vm_size_t)len, VM_PROT_ALL, flags, (caddr_t)&vn, 0); 48243410Shibler return(error); 48341480Smckusick } 48441480Smckusick 48549132Skarels grfunmmap(dev, addr, p) 48641480Smckusick dev_t dev; 48741480Smckusick caddr_t addr; 48849132Skarels struct proc *p; 48941480Smckusick { 49045750Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 49145750Smckusick vm_size_t size; 49245750Smckusick int rv; 49341480Smckusick 49441480Smckusick #ifdef DEBUG 49541480Smckusick if (grfdebug & GDB_MMAP) 49645750Smckusick printf("grfunmmap(%d): dev %x addr %x\n", p->p_pid, dev, addr); 49741480Smckusick #endif 49845750Smckusick if (addr == 0) 49945750Smckusick return(EINVAL); /* XXX: how do we deal with this? */ 50045750Smckusick size = round_page(gp->g_display.gd_regsize + gp->g_display.gd_fbsize); 50153316Smckusick rv = vm_deallocate(&p->p_vmspace->vm_map, (vm_offset_t)addr, size); 50245750Smckusick return(rv == KERN_SUCCESS ? 0 : EINVAL); 50341480Smckusick } 50441480Smckusick 50541480Smckusick #ifdef HPUXCOMPAT 50641480Smckusick iommap(dev, addrp) 50741480Smckusick dev_t dev; 50841480Smckusick caddr_t *addrp; 50941480Smckusick { 51049132Skarels struct proc *p = curproc; /* XXX */ 51141480Smckusick struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 51241480Smckusick 51341480Smckusick #ifdef DEBUG 51441480Smckusick if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 51543316Smckusick printf("iommap(%d): addr %x\n", p->p_pid, *addrp); 51641480Smckusick #endif 51745750Smckusick return(EINVAL); 51841480Smckusick } 51941480Smckusick 52041480Smckusick iounmmap(dev, addr) 52141480Smckusick dev_t dev; 52241480Smckusick caddr_t addr; 52341480Smckusick { 52445750Smckusick int unit = minor(dev); 52541480Smckusick 52641480Smckusick #ifdef DEBUG 52741480Smckusick if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 52841480Smckusick printf("iounmmap(%d): id %d addr %x\n", 52949132Skarels curproc->p_pid, unit, addr); 53041480Smckusick #endif 53145750Smckusick return(0); 53241480Smckusick } 53341480Smckusick 53441480Smckusick /* 53541480Smckusick * Processes involved in framebuffer mapping via GCSLOT are recorded in 53641480Smckusick * an array of pids. The first element is used to record the last slot used 53741480Smckusick * (for faster lookups). The remaining elements record up to GRFMAXLCK-1 53841480Smckusick * process ids. Returns a slot number between 1 and GRFMAXLCK or 0 if no 53941480Smckusick * slot is available. 54041480Smckusick */ 54141480Smckusick grffindpid(gp) 54241480Smckusick struct grf_softc *gp; 54341480Smckusick { 54441480Smckusick register short pid, *sp; 54541480Smckusick register int i, limit; 54641480Smckusick int ni; 54741480Smckusick 54841480Smckusick if (gp->g_pid == NULL) { 54941480Smckusick gp->g_pid = (short *) 55041480Smckusick malloc(GRFMAXLCK * sizeof(short), M_DEVBUF, M_WAITOK); 55141480Smckusick bzero((caddr_t)gp->g_pid, GRFMAXLCK * sizeof(short)); 55241480Smckusick } 55349132Skarels pid = curproc->p_pid; 55441480Smckusick ni = limit = gp->g_pid[0]; 55541480Smckusick for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 55641480Smckusick if (*sp == pid) 55741480Smckusick goto done; 55841480Smckusick if (*sp == 0) 55941480Smckusick ni = i; 56041480Smckusick } 56141480Smckusick i = ni; 56241480Smckusick if (i < limit) { 56341480Smckusick gp->g_pid[i] = pid; 56441480Smckusick goto done; 56541480Smckusick } 56641480Smckusick if (++i == GRFMAXLCK) 56741480Smckusick return(0); 56841480Smckusick gp->g_pid[0] = i; 56941480Smckusick gp->g_pid[i] = pid; 57041480Smckusick done: 57141480Smckusick #ifdef DEBUG 57241480Smckusick if (grfdebug & GDB_LOCK) 57341480Smckusick printf("grffindpid(%d): slot %d of %d\n", 57441480Smckusick pid, i, gp->g_pid[0]); 57541480Smckusick #endif 57641480Smckusick return(i); 57741480Smckusick } 57841480Smckusick 57941480Smckusick grfrmpid(gp) 58041480Smckusick struct grf_softc *gp; 58141480Smckusick { 58241480Smckusick register short pid, *sp; 58341480Smckusick register int limit, i; 58441480Smckusick int mi; 58541480Smckusick 58641480Smckusick if (gp->g_pid == NULL || (limit = gp->g_pid[0]) == 0) 58741480Smckusick return; 58849132Skarels pid = curproc->p_pid; 58941480Smckusick limit = gp->g_pid[0]; 59041480Smckusick mi = 0; 59141480Smckusick for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 59241480Smckusick if (*sp == pid) 59341480Smckusick *sp = 0; 59441480Smckusick else if (*sp) 59541480Smckusick mi = i; 59641480Smckusick } 59741480Smckusick i = mi; 59841480Smckusick if (i < limit) 59941480Smckusick gp->g_pid[0] = i; 60041480Smckusick #ifdef DEBUG 60141480Smckusick if (grfdebug & GDB_LOCK) 60241480Smckusick printf("grfrmpid(%d): slot %d of %d\n", 60341480Smckusick pid, sp-gp->g_pid, gp->g_pid[0]); 60441480Smckusick #endif 60541480Smckusick } 60641480Smckusick 60741480Smckusick grflckmmap(dev, addrp) 60841480Smckusick dev_t dev; 60941480Smckusick caddr_t *addrp; 61041480Smckusick { 61149132Skarels #ifdef DEBUG 61249132Skarels struct proc *p = curproc; /* XXX */ 61341480Smckusick 61441480Smckusick if (grfdebug & (GDB_MMAP|GDB_LOCK)) 61541480Smckusick printf("grflckmmap(%d): addr %x\n", 61643316Smckusick p->p_pid, *addrp); 61741480Smckusick #endif 61845750Smckusick return(EINVAL); 61941480Smckusick } 62041480Smckusick 62141480Smckusick grflckunmmap(dev, addr) 62241480Smckusick dev_t dev; 62341480Smckusick caddr_t addr; 62441480Smckusick { 62549132Skarels #ifdef DEBUG 62641480Smckusick int unit = minor(dev); 62741480Smckusick 62841480Smckusick if (grfdebug & (GDB_MMAP|GDB_LOCK)) 62941480Smckusick printf("grflckunmmap(%d): id %d addr %x\n", 63049132Skarels curproc->p_pid, unit, addr); 63141480Smckusick #endif 63241480Smckusick return(EINVAL); 63341480Smckusick } 63441480Smckusick #endif /* HPUXCOMPAT */ 63545750Smckusick 63641480Smckusick #endif /* NGRF > 0 */ 637