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