|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.