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.3 (Berkeley) 06/20/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 struct proc *p = u.u_procp; /* XXX */ 299 int error; 300 extern char devioc[]; 301 302 #ifdef DEBUG 303 if (grfdebug & GDB_LOCK) 304 printf("grflock(%d): dev %x flags %x lockpid %x\n", 305 p->p_pid, gp-grf_softc, gp->g_flags, 306 gp->g_lockp ? gp->g_lockp->p_pid : -1); 307 #endif 308 #ifdef HPUXCOMPAT 309 if (gp->g_pid) { 310 #ifdef DEBUG 311 if (grfdebug & GDB_LOCK) 312 printf(" lock[0] %d lockslot %d lock[lockslot] %d\n", 313 gp->g_locks[0], gp->g_lockpslot, 314 gp->g_locks[gp->g_lockpslot]); 315 #endif 316 gp->g_locks[0] = 0; 317 if (gp->g_locks[gp->g_lockpslot] == 0) { 318 gp->g_lockp = NULL; 319 gp->g_lockpslot = 0; 320 } 321 } 322 #endif 323 if (gp->g_lockp) { 324 if (gp->g_lockp == p) 325 return(EBUSY); 326 if (!block) 327 return(EAGAIN); 328 do { 329 gp->g_flags |= GF_WANTED; 330 sleep((caddr_t)&gp->g_flags, PZERO+1); 331 332 if (error = tsleep((caddr_t)&gp->g_flags, 333 (PZERO+1) | PCATCH, devioc, 0)) 334 return (error); 335 336 } while (gp->g_lockp); 337 } 338 gp->g_lockp = p; 339 #ifdef HPUXCOMPAT 340 if (gp->g_pid) { 341 int slot = grffindpid(gp); 342 #ifdef DEBUG 343 if (grfdebug & GDB_LOCK) 344 printf(" slot %d\n", slot); 345 #endif 346 gp->g_lockpslot = gp->g_locks[0] = slot; 347 gp->g_locks[slot] = 1; 348 } 349 #endif 350 return(0); 351 } 352 353 grfunlock(gp) 354 register struct grf_softc *gp; 355 { 356 #ifdef DEBUG 357 if (grfdebug & GDB_LOCK) 358 printf("grfunlock(%d): dev %x flags %x lockpid %d\n", 359 u.u_procp->p_pid, gp-grf_softc, gp->g_flags, 360 gp->g_lockp ? gp->g_lockp->p_pid : -1); 361 #endif 362 if (gp->g_lockp != u.u_procp) 363 return(EBUSY); 364 #ifdef HPUXCOMPAT 365 if (gp->g_pid) { 366 #ifdef DEBUG 367 if (grfdebug & GDB_LOCK) 368 printf(" lock[0] %d lockslot %d lock[lockslot] %d\n", 369 gp->g_locks[0], gp->g_lockpslot, 370 gp->g_locks[gp->g_lockpslot]); 371 #endif 372 gp->g_locks[gp->g_lockpslot] = gp->g_locks[0] = 0; 373 gp->g_lockpslot = 0; 374 } 375 #endif 376 if (gp->g_flags & GF_WANTED) { 377 wakeup((caddr_t)&gp->g_flags); 378 gp->g_flags &= ~GF_WANTED; 379 } 380 gp->g_lockp = NULL; 381 return(0); 382 } 383 384 /*ARGSUSED*/ 385 grfmap(dev, off, prot) 386 dev_t dev; 387 { 388 return(grfaddr(&grf_softc[GRFUNIT(dev)], off)); 389 } 390 391 #ifdef HPUXCOMPAT 392 393 /*ARGSUSED*/ 394 hpuxgrfioctl(dev, cmd, data, flag) 395 dev_t dev; 396 caddr_t data; 397 { 398 register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 399 int error; 400 401 error = 0; 402 switch (cmd) { 403 404 case GCID: 405 *(int *)data = gp->g_display.gd_id; 406 break; 407 408 case GCON: 409 error = grfon(dev); 410 break; 411 412 case GCOFF: 413 error = grfoff(dev); 414 break; 415 416 case GCLOCK: 417 error = grflock(gp, 1); 418 break; 419 420 case GCUNLOCK: 421 error = grfunlock(gp); 422 break; 423 424 case GCAON: 425 case GCAOFF: 426 break; 427 428 /* GCSTATIC is implied by our implementation */ 429 case GCSTATIC_CMAP: 430 case GCVARIABLE_CMAP: 431 break; 432 433 #ifdef MAPMEM 434 /* map in control regs and frame buffer */ 435 case GCMAP: 436 error = grfmmap(dev, (caddr_t *)data); 437 break; 438 439 case GCUNMAP: 440 error = grfunmmap(dev, *(caddr_t *)data); 441 /* XXX: HP-UX uses GCUNMAP to get rid of GCSLOT memory */ 442 if (error) 443 error = grflckunmmap(dev, *(caddr_t *)data); 444 break; 445 446 case GCSLOT: 447 { 448 struct grf_slot *sp = (struct grf_slot *)data; 449 450 sp->slot = grffindpid(gp); 451 if (sp->slot) 452 error = grflckmmap(dev, (caddr_t *)&sp->addr); 453 else 454 error = EINVAL; /* XXX */ 455 break; 456 } 457 458 /* 459 * XXX: only used right now to map in rbox control registers 460 * Will be replaced in the future with a real IOMAP interface. 461 */ 462 case IOMAPMAP: 463 error = iommap(dev, (caddr_t *)data); 464 if (!error) 465 u.u_r.r_val1 = *(int *)data; /* XXX: this sux */ 466 break; 467 468 case IOMAPUNMAP: 469 error = iounmmap(dev, *(caddr_t *)data); 470 break; 471 #endif 472 473 default: 474 error = EINVAL; 475 break; 476 } 477 return(error); 478 } 479 480 #endif 481 482 grfon(dev) 483 dev_t dev; 484 { 485 int unit = GRFUNIT(dev); 486 struct grf_softc *gp = &grf_softc[unit]; 487 488 /* 489 * XXX: iteoff call relies on devices being in same order 490 * as ITEs and the fact that iteoff only uses the minor part 491 * of the dev arg. 492 */ 493 iteoff(unit, 3); 494 return((*grfdev[gp->g_type].gd_mode) 495 (gp, (dev&GRFOVDEV) ? GM_GRFOVON : GM_GRFON)); 496 } 497 498 grfoff(dev) 499 dev_t dev; 500 { 501 int unit = GRFUNIT(dev); 502 struct grf_softc *gp = &grf_softc[unit]; 503 int error; 504 505 #ifdef MAPMEM 506 (void) grfunmmap(dev, (caddr_t)0); 507 #endif 508 error = (*grfdev[gp->g_type].gd_mode) 509 (gp, (dev&GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF); 510 /* XXX: see comment for iteoff above */ 511 iteon(unit, 2); 512 return(error); 513 } 514 515 grfaddr(gp, off) 516 struct grf_softc *gp; 517 register int off; 518 { 519 #ifdef MAPMEM 520 register struct grfinfo *gi = &gp->g_display; 521 522 /* control registers */ 523 if (off >= 0 && off < gi->gd_regsize) 524 return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); 525 526 /* frame buffer */ 527 if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { 528 off -= gi->gd_regsize; 529 return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); 530 } 531 #endif 532 /* bogus */ 533 return(-1); 534 } 535 536 #ifdef HPUXCOMPAT 537 /* 538 * Convert a BSD style minor devno to HPUX style. 539 * We cannot just create HPUX style nodes as they require 24 bits 540 * of minor device number and we only have 8. 541 * XXX: This may give the wrong result for remote stats of other 542 * machines where device 10 exists. 543 */ 544 grfdevno(dev) 545 dev_t dev; 546 { 547 int unit = GRFUNIT(dev); 548 struct grf_softc *gp = &grf_softc[unit]; 549 int newdev; 550 551 if (unit >= NGRF || (gp->g_flags&GF_ALIVE) == 0) 552 return(bsdtohpuxdev(dev)); 553 /* magic major number */ 554 newdev = 12 << 24; 555 /* now construct minor number */ 556 #if defined(HP360) || defined(HP370) 557 if (gp->g_display.gd_regaddr == (caddr_t)DIOIIBASE) 558 newdev |= 0x840200; 559 else 560 #endif 561 if (gp->g_display.gd_regaddr != (caddr_t)GRFIADDR) 562 newdev |= ((u_int)gp->g_display.gd_regaddr-EXTIOBASE) | 0x200; 563 if (dev & GRFIMDEV) 564 newdev |= 0x02; 565 else if (dev & GRFOVDEV) 566 newdev |= 0x01; 567 #ifdef DEBUG 568 if (grfdebug & GDB_DEVNO) 569 printf("grfdevno: dev %x newdev %x\n", dev, newdev); 570 #endif 571 return(newdev); 572 } 573 #endif 574 575 #ifdef MAPMEM 576 grfmapin(mp, off) 577 struct mapmem *mp; 578 { 579 return(grfaddr(&grf_softc[GRFUNIT(mp->mm_id)], off)); 580 } 581 582 grfmmap(dev, addrp) 583 dev_t dev; 584 caddr_t *addrp; 585 { 586 struct proc *p = u.u_procp; /* XXX */ 587 struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 588 struct mapmem *mp; 589 int len, grfmapin(); 590 591 #ifdef DEBUG 592 if (grfdebug & GDB_MMAP) 593 printf("grfmmap(%d): addr %x\n", p->p_pid, *addrp); 594 #endif 595 len = gp->g_display.gd_regsize + gp->g_display.gd_fbsize; 596 if (u.u_error = mmalloc(p, minor(dev), addrp, len, MM_RW|MM_CI|MM_NOCORE, &grfops, &mp)) 597 return(u.u_error); 598 if (!mmmapin(p, mp, grfmapin)) { 599 mmfree(p, mp); 600 return(u.u_error); 601 } 602 return(0); 603 } 604 605 grfunmmap(dev, addr) 606 dev_t dev; 607 caddr_t addr; 608 { 609 register struct mapmem *mp, **mpp; 610 int found, unit = minor(dev); 611 612 #ifdef DEBUG 613 if (grfdebug & GDB_MMAP) 614 printf("grfunmmap(%d): id %d addr %x\n", 615 u.u_procp->p_pid, unit, addr); 616 #endif 617 found = 0; 618 mpp = &u.u_mmap; 619 for (mp = *mpp; mp; mp = *mpp) { 620 if (mp->mm_ops != &grfops || mp->mm_id != unit) { 621 mpp = &mp->mm_next; 622 continue; 623 } 624 if (addr && 625 (addr < mp->mm_uva || addr >= mp->mm_uva+mp->mm_size)) { 626 mpp = &mp->mm_next; 627 continue; 628 } 629 grfexit(mp); 630 found++; 631 } 632 return(found ? 0 : EINVAL); 633 } 634 635 grfexit(mp) 636 struct mapmem *mp; 637 { 638 struct proc *p = u.u_procp; /* XXX */ 639 struct grf_softc *gp = &grf_softc[GRFUNIT(mp->mm_id)]; 640 641 #ifdef DEBUG 642 if (grfdebug & GDB_MMAP) 643 printf("grfexit(%d): id %d %x@%x\n", 644 p->p_pid, mp->mm_id, mp->mm_size, mp->mm_uva); 645 #endif 646 (void) grfunlock(gp); 647 #ifdef HPUXCOMPAT 648 grfrmpid(gp); 649 #endif 650 mmmapout(p, mp); 651 mmfree(p, mp); 652 } 653 654 #ifdef HPUXCOMPAT 655 iommap(dev, addrp) 656 dev_t dev; 657 caddr_t *addrp; 658 { 659 struct proc *p = u.u_procp; /* XXX */ 660 struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 661 struct mapmem *mp; 662 int len, grfmapin(); 663 664 #ifdef DEBUG 665 if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 666 printf("iommap(%d): addr %x\n", p->p_pid, *addrp); 667 #endif 668 len = gp->g_display.gd_regsize; 669 if (u.u_error = mmalloc(p, minor(dev), addrp, len, MM_RW|MM_CI|MM_NOCORE, &grfiomops, &mp)) 670 return(u.u_error); 671 if (!mmmapin(p, mp, grfmapin)) { 672 mmfree(p, mp); 673 return(u.u_error); 674 } 675 return(0); 676 } 677 678 iounmmap(dev, addr) 679 dev_t dev; 680 caddr_t addr; 681 { 682 struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 683 register struct mapmem *mp, **mpp; 684 int found, len, unit = minor(dev); 685 686 #ifdef DEBUG 687 if (grfdebug & (GDB_MMAP|GDB_IOMAP)) 688 printf("iounmmap(%d): id %d addr %x\n", 689 u.u_procp->p_pid, unit, addr); 690 #endif 691 found = 0; 692 len = gp->g_display.gd_regsize; 693 mpp = &u.u_mmap; 694 for (mp = *mpp; mp; mp = *mpp) { 695 if (mp->mm_ops != &grfiomops || mp->mm_id != unit) { 696 mpp = &mp->mm_next; 697 continue; 698 } 699 if (addr && 700 (addr < mp->mm_uva || addr >= mp->mm_uva+mp->mm_size || 701 len != mp->mm_size)) { 702 mpp = &mp->mm_next; 703 continue; 704 } 705 grfexit(mp); 706 found++; 707 } 708 return(found ? 0 : EINVAL); 709 } 710 711 /* 712 * Processes involved in framebuffer mapping via GCSLOT are recorded in 713 * an array of pids. The first element is used to record the last slot used 714 * (for faster lookups). The remaining elements record up to GRFMAXLCK-1 715 * process ids. Returns a slot number between 1 and GRFMAXLCK or 0 if no 716 * slot is available. 717 */ 718 grffindpid(gp) 719 struct grf_softc *gp; 720 { 721 register short pid, *sp; 722 register int i, limit; 723 int ni; 724 725 if (gp->g_pid == NULL) { 726 gp->g_pid = (short *) 727 malloc(GRFMAXLCK * sizeof(short), M_DEVBUF, M_WAITOK); 728 bzero((caddr_t)gp->g_pid, GRFMAXLCK * sizeof(short)); 729 } 730 pid = u.u_procp->p_pid; 731 ni = limit = gp->g_pid[0]; 732 for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 733 if (*sp == pid) 734 goto done; 735 if (*sp == 0) 736 ni = i; 737 } 738 i = ni; 739 if (i < limit) { 740 gp->g_pid[i] = pid; 741 goto done; 742 } 743 if (++i == GRFMAXLCK) 744 return(0); 745 gp->g_pid[0] = i; 746 gp->g_pid[i] = pid; 747 done: 748 #ifdef DEBUG 749 if (grfdebug & GDB_LOCK) 750 printf("grffindpid(%d): slot %d of %d\n", 751 pid, i, gp->g_pid[0]); 752 #endif 753 return(i); 754 } 755 756 grfrmpid(gp) 757 struct grf_softc *gp; 758 { 759 register short pid, *sp; 760 register int limit, i; 761 int mi; 762 763 if (gp->g_pid == NULL || (limit = gp->g_pid[0]) == 0) 764 return; 765 pid = u.u_procp->p_pid; 766 limit = gp->g_pid[0]; 767 mi = 0; 768 for (i = 1, sp = &gp->g_pid[1]; i <= limit; i++, sp++) { 769 if (*sp == pid) 770 *sp = 0; 771 else if (*sp) 772 mi = i; 773 } 774 i = mi; 775 if (i < limit) 776 gp->g_pid[0] = i; 777 #ifdef DEBUG 778 if (grfdebug & GDB_LOCK) 779 printf("grfrmpid(%d): slot %d of %d\n", 780 pid, sp-gp->g_pid, gp->g_pid[0]); 781 #endif 782 } 783 784 /*ARGSUSED*/ 785 grflckmapin(mp, off) 786 struct mapmem *mp; 787 { 788 u_int pa = kvtop((u_int)grf_softc[GRFUNIT(mp->mm_id)].g_locks); 789 790 #ifdef DEBUG 791 if (grfdebug & GDB_LOCK) 792 printf("grflckmapin(%d): va %x pa %x\n", u.u_procp->p_pid, 793 grf_softc[GRFUNIT(mp->mm_id)].g_locks, pa); 794 #endif 795 return(pa >> PGSHIFT); 796 } 797 798 grflckmmap(dev, addrp) 799 dev_t dev; 800 caddr_t *addrp; 801 { 802 struct proc *p = u.u_procp; /* XXX */ 803 struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; 804 struct mapmem *mp; 805 int grflckmapin(); 806 807 #ifdef DEBUG 808 if (grfdebug & (GDB_MMAP|GDB_LOCK)) 809 printf("grflckmmap(%d): addr %x\n", 810 p->p_pid, *addrp); 811 #endif 812 if (gp->g_locks == NULL) { 813 gp->g_locks = (u_char *) cialloc(NBPG); 814 if (gp->g_locks == NULL) 815 return(ENOMEM); 816 } 817 if (u.u_error = mmalloc(p, minor(dev), addrp, NBPG, MM_RW|MM_CI, &grflckops, &mp)) 818 return(u.u_error); 819 if (!mmmapin(p, mp, grflckmapin)) { 820 mmfree(p, mp); 821 return(u.u_error); 822 } 823 return(0); 824 } 825 826 grflckunmmap(dev, addr) 827 dev_t dev; 828 caddr_t addr; 829 { 830 register struct mapmem *mp; 831 int unit = minor(dev); 832 833 #ifdef DEBUG 834 if (grfdebug & (GDB_MMAP|GDB_LOCK)) 835 printf("grflckunmmap(%d): id %d addr %x\n", 836 u.u_procp->p_pid, unit, addr); 837 #endif 838 for (mp = u.u_mmap; mp; mp = mp->mm_next) 839 if (mp->mm_ops == &grflckops && mp->mm_id == unit && 840 mp->mm_uva == addr) { 841 grfexit(mp); 842 return(0); 843 } 844 return(EINVAL); 845 } 846 #endif /* HPUXCOMPAT */ 847 #endif /* MAPMEM */ 848 #endif /* NGRF > 0 */ 849