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