home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / dev / grf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  16.9 KB  |  780 lines

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