Annotation of 43BSDReno/sys/hpdev/grf.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.