Home | History | Annotate | Download | only in Xxf86dga
      1 /* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.19 2001/08/18 02:41:30 dawes Exp $ */
      2 /*
      3 
      4 Copyright (c) 1995  Jon Tombs
      5 Copyright (c) 1995,1996  The XFree86 Project, Inc
      6 
      7 */
      8 
      9 /* THIS IS NOT AN X CONSORTIUM STANDARD */
     10 
     11 #ifdef __EMX__ /* needed here to override certain constants in X headers */
     12 #define INCL_DOS
     13 #define INCL_DOSIOCTL
     14 #include <os2.h>
     15 #endif
     16 
     17 #if defined(linux)
     18 #define HAS_MMAP_ANON
     19 #include <sys/types.h>
     20 #include <sys/mman.h>
     21 /*#include <asm/page.h>*/   /* PAGE_SIZE */
     22 #define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
     23 #define HAS_GETPAGESIZE
     24 #endif /* linux */
     25 
     26 #if defined(CSRG_BASED)
     27 #define HAS_MMAP_ANON
     28 #define HAS_GETPAGESIZE
     29 #include <sys/types.h>
     30 #include <sys/mman.h>
     31 #endif /* CSRG_BASED */
     32 
     33 #if defined(DGUX)
     34 #define HAS_GETPAGESIZE
     35 #define MMAP_DEV_ZERO
     36 #include <sys/types.h>
     37 #include <sys/mman.h>
     38 #include <unistd.h>
     39 #endif /* DGUX */
     40 
     41 #if defined(SVR4) && !defined(DGUX)
     42 #define MMAP_DEV_ZERO
     43 #include <sys/types.h>
     44 #include <sys/mman.h>
     45 #include <unistd.h>
     46 #endif /* SVR4 && !DGUX */
     47 
     48 #if defined(sun) && !defined(SVR4) /* SunOS */
     49 #define MMAP_DEV_ZERO   /* doesn't SunOS have MAP_ANON ?? */
     50 #define HAS_GETPAGESIZE
     51 #include <sys/types.h>
     52 #include <sys/mman.h>
     53 #endif /* sun && !SVR4 */
     54 
     55 #ifdef XNO_SYSCONF
     56 #undef _SC_PAGESIZE
     57 #endif
     58 
     59 #define NEED_EVENTS
     60 #define NEED_REPLIES
     61 
     62 /* Apparently some X11 systems can't include this multiple times... */
     63 #ifndef SDL_INCLUDED_XLIBINT_H
     64 #define SDL_INCLUDED_XLIBINT_H 1
     65 #include <X11/Xlibint.h>
     66 #endif
     67 
     68 #include "../extensions/xf86dga.h"
     69 #include "../extensions/xf86dgastr.h"
     70 #include "../extensions/Xext.h"
     71 #include "../extensions/extutil.h"
     72 
     73 extern XExtDisplayInfo* SDL_NAME(xdga_find_display)(Display*);
     74 extern char *SDL_NAME(xdga_extension_name);
     75 
     76 #define XF86DGACheckExtension(dpy,i,val) \
     77   XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
     78 
     79 /*****************************************************************************
     80  *                                                                           *
     81  *		    public XFree86-DGA Extension routines                    *
     82  *                                                                           *
     83  *****************************************************************************/
     84 
     85 Bool SDL_NAME(XF86DGAQueryExtension) (
     86     Display *dpy,
     87     int *event_basep,
     88     int *error_basep
     89 ){
     90     return SDL_NAME(XDGAQueryExtension)(dpy, event_basep, error_basep);
     91 }
     92 
     93 Bool SDL_NAME(XF86DGAQueryVersion)(
     94     Display* dpy,
     95     int* majorVersion,
     96     int* minorVersion
     97 ){
     98     return SDL_NAME(XDGAQueryVersion)(dpy, majorVersion, minorVersion);
     99 }
    100 
    101 Bool SDL_NAME(XF86DGAGetVideoLL)(
    102     Display* dpy,
    103     int screen,
    104     int *offset,
    105     int *width,
    106     int *bank_size,
    107     int *ram_size
    108 ){
    109     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    110     xXF86DGAGetVideoLLReply rep;
    111     xXF86DGAGetVideoLLReq *req;
    112 
    113     XF86DGACheckExtension (dpy, info, False);
    114 
    115     LockDisplay(dpy);
    116     GetReq(XF86DGAGetVideoLL, req);
    117     req->reqType = info->codes->major_opcode;
    118     req->dgaReqType = X_XF86DGAGetVideoLL;
    119     req->screen = screen;
    120     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    121 	UnlockDisplay(dpy);
    122 	SyncHandle();
    123 	return False;
    124     }
    125 
    126     *offset = /*(char *)*/rep.offset;
    127     *width = rep.width;
    128     *bank_size = rep.bank_size;
    129     *ram_size = rep.ram_size;
    130 
    131     UnlockDisplay(dpy);
    132     SyncHandle();
    133     return True;
    134 }
    135 
    136 
    137 Bool SDL_NAME(XF86DGADirectVideoLL)(
    138     Display* dpy,
    139     int screen,
    140     int enable
    141 ){
    142     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    143     xXF86DGADirectVideoReq *req;
    144 
    145     XF86DGACheckExtension (dpy, info, False);
    146 
    147     LockDisplay(dpy);
    148     GetReq(XF86DGADirectVideo, req);
    149     req->reqType = info->codes->major_opcode;
    150     req->dgaReqType = X_XF86DGADirectVideo;
    151     req->screen = screen;
    152     req->enable = enable;
    153     UnlockDisplay(dpy);
    154     SyncHandle();
    155     XSync(dpy,False);
    156     return True;
    157 }
    158 
    159 Bool SDL_NAME(XF86DGAGetViewPortSize)(
    160     Display* dpy,
    161     int screen,
    162     int *width,
    163     int *height
    164 ){
    165     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    166     xXF86DGAGetViewPortSizeReply rep;
    167     xXF86DGAGetViewPortSizeReq *req;
    168 
    169     XF86DGACheckExtension (dpy, info, False);
    170 
    171     LockDisplay(dpy);
    172     GetReq(XF86DGAGetViewPortSize, req);
    173     req->reqType = info->codes->major_opcode;
    174     req->dgaReqType = X_XF86DGAGetViewPortSize;
    175     req->screen = screen;
    176     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    177 	UnlockDisplay(dpy);
    178 	SyncHandle();
    179 	return False;
    180     }
    181 
    182     *width = rep.width;
    183     *height = rep.height;
    184 
    185     UnlockDisplay(dpy);
    186     SyncHandle();
    187     return True;
    188 }
    189 
    190 
    191 Bool SDL_NAME(XF86DGASetViewPort)(
    192     Display* dpy,
    193     int screen,
    194     int x,
    195     int y
    196 ){
    197     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    198     xXF86DGASetViewPortReq *req;
    199 
    200     XF86DGACheckExtension (dpy, info, False);
    201 
    202     LockDisplay(dpy);
    203     GetReq(XF86DGASetViewPort, req);
    204     req->reqType = info->codes->major_opcode;
    205     req->dgaReqType = X_XF86DGASetViewPort;
    206     req->screen = screen;
    207     req->x = x;
    208     req->y = y;
    209     UnlockDisplay(dpy);
    210     SyncHandle();
    211     XSync(dpy,False);
    212     return True;
    213 }
    214 
    215 
    216 Bool SDL_NAME(XF86DGAGetVidPage)(
    217     Display* dpy,
    218     int screen,
    219     int *vpage
    220 ){
    221     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    222     xXF86DGAGetVidPageReply rep;
    223     xXF86DGAGetVidPageReq *req;
    224 
    225     XF86DGACheckExtension (dpy, info, False);
    226 
    227     LockDisplay(dpy);
    228     GetReq(XF86DGAGetVidPage, req);
    229     req->reqType = info->codes->major_opcode;
    230     req->dgaReqType = X_XF86DGAGetVidPage;
    231     req->screen = screen;
    232     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    233 	UnlockDisplay(dpy);
    234 	SyncHandle();
    235 	return False;
    236     }
    237 
    238     *vpage = rep.vpage;
    239     UnlockDisplay(dpy);
    240     SyncHandle();
    241     return True;
    242 }
    243 
    244 
    245 Bool SDL_NAME(XF86DGASetVidPage)(
    246     Display* dpy,
    247     int screen,
    248     int vpage
    249 ){
    250     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    251     xXF86DGASetVidPageReq *req;
    252 
    253     XF86DGACheckExtension (dpy, info, False);
    254 
    255     LockDisplay(dpy);
    256     GetReq(XF86DGASetVidPage, req);
    257     req->reqType = info->codes->major_opcode;
    258     req->dgaReqType = X_XF86DGASetVidPage;
    259     req->screen = screen;
    260     req->vpage = vpage;
    261     UnlockDisplay(dpy);
    262     SyncHandle();
    263     XSync(dpy,False);
    264     return True;
    265 }
    266 
    267 Bool SDL_NAME(XF86DGAInstallColormap)(
    268     Display* dpy,
    269     int screen,
    270     Colormap cmap
    271 ){
    272     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    273     xXF86DGAInstallColormapReq *req;
    274 
    275     XF86DGACheckExtension (dpy, info, False);
    276 
    277     LockDisplay(dpy);
    278     GetReq(XF86DGAInstallColormap, req);
    279     req->reqType = info->codes->major_opcode;
    280     req->dgaReqType = X_XF86DGAInstallColormap;
    281     req->screen = screen;
    282     req->id = cmap;
    283     UnlockDisplay(dpy);
    284     SyncHandle();
    285     XSync(dpy,False);
    286     return True;
    287 }
    288 
    289 Bool SDL_NAME(XF86DGAQueryDirectVideo)(
    290     Display *dpy,
    291     int screen,
    292     int *flags
    293 ){
    294     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    295     xXF86DGAQueryDirectVideoReply rep;
    296     xXF86DGAQueryDirectVideoReq *req;
    297 
    298     XF86DGACheckExtension (dpy, info, False);
    299 
    300     LockDisplay(dpy);
    301     GetReq(XF86DGAQueryDirectVideo, req);
    302     req->reqType = info->codes->major_opcode;
    303     req->dgaReqType = X_XF86DGAQueryDirectVideo;
    304     req->screen = screen;
    305     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    306 	UnlockDisplay(dpy);
    307 	SyncHandle();
    308 	return False;
    309     }
    310     *flags = rep.flags;
    311     UnlockDisplay(dpy);
    312     SyncHandle();
    313     return True;
    314 }
    315 
    316 Bool SDL_NAME(XF86DGAViewPortChanged)(
    317     Display *dpy,
    318     int screen,
    319     int n
    320 ){
    321     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    322     xXF86DGAViewPortChangedReply rep;
    323     xXF86DGAViewPortChangedReq *req;
    324 
    325     XF86DGACheckExtension (dpy, info, False);
    326 
    327     LockDisplay(dpy);
    328     GetReq(XF86DGAViewPortChanged, req);
    329     req->reqType = info->codes->major_opcode;
    330     req->dgaReqType = X_XF86DGAViewPortChanged;
    331     req->screen = screen;
    332     req->n = n;
    333     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    334 	UnlockDisplay(dpy);
    335 	SyncHandle();
    336 	return False;
    337     }
    338     UnlockDisplay(dpy);
    339     SyncHandle();
    340     return rep.result;
    341 }
    342 
    343 
    344 
    345 /* Helper functions */
    346 
    347 #include <X11/Xmd.h>
    348 #include "../extensions/xf86dga.h"
    349 #include <stdlib.h>
    350 #include <stdio.h>
    351 #include <fcntl.h>
    352 #if defined(ISC)
    353 # define HAS_SVR3_MMAP
    354 # include <sys/types.h>
    355 # include <errno.h>
    356 
    357 # include <sys/at_ansi.h>
    358 # include <sys/kd.h>
    359 
    360 # include <sys/sysmacros.h>
    361 # include <sys/immu.h>
    362 # include <sys/region.h>
    363 
    364 # include <sys/mmap.h>
    365 #else
    366 # if !defined(Lynx)
    367 #  if !defined(__EMX__)
    368 #   include <sys/mman.h>
    369 #  endif
    370 # else
    371 #  include <sys/types.h>
    372 #  include <errno.h>
    373 #  include <smem.h>
    374 # endif
    375 #endif
    376 #include <sys/wait.h>
    377 #include <signal.h>
    378 #include <unistd.h>
    379 
    380 #if defined(SVR4) && !defined(sun) && !defined(SCO325)
    381 #define DEV_MEM "/dev/pmem"
    382 #elif defined(SVR4) && defined(sun)
    383 #define DEV_MEM "/dev/xsvc"
    384 #else
    385 #define DEV_MEM "/dev/mem"
    386 #endif
    387 
    388 typedef struct {
    389     unsigned long physaddr;	/* actual requested physical address */
    390     unsigned long size;		/* actual requested map size */
    391     unsigned long delta;	/* delta to account for page alignment */
    392     void *	  vaddr;	/* mapped address, without the delta */
    393     int		  refcount;	/* reference count */
    394 } MapRec, *MapPtr;
    395 
    396 typedef struct {
    397     Display *	display;
    398     int		screen;
    399     MapPtr	map;
    400 } ScrRec, *ScrPtr;
    401 
    402 static int mapFd = -1;
    403 static int numMaps = 0;
    404 static int numScrs = 0;
    405 static MapPtr *mapList = NULL;
    406 static ScrPtr *scrList = NULL;
    407 
    408 static MapPtr
    409 AddMap(void)
    410 {
    411     MapPtr *old;
    412 
    413     old = mapList;
    414     mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1));
    415     if (!mapList) {
    416 	mapList = old;
    417 	return NULL;
    418     }
    419     mapList[numMaps] = malloc(sizeof(MapRec));
    420     if (!mapList[numMaps])
    421 	return NULL;
    422     return mapList[numMaps++];
    423 }
    424 
    425 static ScrPtr
    426 AddScr(void)
    427 {
    428     ScrPtr *old;
    429 
    430     old = scrList;
    431     scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1));
    432     if (!scrList) {
    433 	scrList = old;
    434 	return NULL;
    435     }
    436     scrList[numScrs] = malloc(sizeof(ScrRec));
    437     if (!scrList[numScrs])
    438 	return NULL;
    439     return scrList[numScrs++];
    440 }
    441 
    442 static MapPtr
    443 FindMap(unsigned long address, unsigned long size)
    444 {
    445     int i;
    446 
    447     for (i = 0; i < numMaps; i++) {
    448 	if (mapList[i]->physaddr == address &&
    449 	    mapList[i]->size == size)
    450 	    return mapList[i];
    451     }
    452     return NULL;
    453 }
    454 
    455 static ScrPtr
    456 FindScr(Display *display, int screen)
    457 {
    458     int i;
    459 
    460     for (i = 0; i < numScrs; i++) {
    461 	if (scrList[i]->display == display &&
    462 	    scrList[i]->screen == screen)
    463 	    return scrList[i];
    464     }
    465     return NULL;
    466 }
    467 
    468 static void *
    469 MapPhysAddress(unsigned long address, unsigned long size)
    470 {
    471     unsigned long offset, delta;
    472     int pagesize = -1;
    473     void *vaddr;
    474     MapPtr mp;
    475 #if defined(ISC) && defined(HAS_SVR3_MMAP)
    476     struct kd_memloc mloc;
    477 #elif defined(__EMX__)
    478     APIRET rc;
    479     ULONG action;
    480     HFILE hfd;
    481 #endif
    482 
    483     if ((mp = FindMap(address, size))) {
    484 	mp->refcount++;
    485 	return (void *)((unsigned long)mp->vaddr + mp->delta);
    486     }
    487 
    488 #if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE)
    489     pagesize = sysconf(_SC_PAGESIZE);
    490 #endif
    491 #ifdef _SC_PAGE_SIZE
    492     if (pagesize == -1)
    493 	pagesize = sysconf(_SC_PAGE_SIZE);
    494 #endif
    495 #ifdef HAS_GETPAGESIZE
    496     if (pagesize == -1)
    497 	pagesize = getpagesize();
    498 #endif
    499 #ifdef PAGE_SIZE
    500     if (pagesize == -1)
    501 	pagesize = PAGE_SIZE;
    502 #endif
    503     if (pagesize == -1)
    504 	pagesize = 4096;
    505 
    506    delta = address % pagesize;
    507    offset = address - delta;
    508 
    509 #if defined(ISC) && defined(HAS_SVR3_MMAP)
    510     if (mapFd < 0) {
    511 	if ((mapFd = open("/dev/mmap", O_RDWR)) < 0)
    512 	    return NULL;
    513     }
    514     mloc.vaddr = (char *)0;
    515     mloc.physaddr = (char *)offset;
    516     mloc.length = size + delta;
    517     mloc.ioflg=1;
    518 
    519     if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1)
    520 	return NULL;
    521 #elif defined (__EMX__)
    522     /*
    523      * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
    524      * Consecutive calling of this routine will make PMAP$ driver run out
    525      * of memory handles. Some umap/close mechanism should be provided
    526      */
    527 
    528     rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
    529 		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
    530     if (rc != 0)
    531 	return NULL;
    532     {
    533 	struct map_ioctl {
    534 		union {
    535 			ULONG phys;
    536 			void* user;
    537 		} a;
    538 		ULONG size;
    539 	} pmap,dmap;
    540 	ULONG plen,dlen;
    541 #define XFREE86_PMAP	0x76
    542 #define PMAP_MAP	0x44
    543 
    544 	pmap.a.phys = offset;
    545 	pmap.size = size + delta;
    546 	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
    547 			 (PULONG)&pmap, sizeof(pmap), &plen,
    548 			 (PULONG)&dmap, sizeof(dmap), &dlen);
    549 	if (rc == 0) {
    550 		vaddr = dmap.a.user;
    551 	}
    552    }
    553    if (rc != 0)
    554 	return NULL;
    555 #elif defined (Lynx)
    556     vaddr = (void *)smem_create("XF86DGA", (char *)offset,
    557 				size + delta, SM_READ|SM_WRITE);
    558 #else
    559 #ifndef MAP_FILE
    560 #define MAP_FILE 0
    561 #endif
    562     if (mapFd < 0) {
    563 	if ((mapFd = open(DEV_MEM, O_RDWR)) < 0)
    564 	    return NULL;
    565     }
    566     vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE,
    567                         MAP_FILE | MAP_SHARED, mapFd, (off_t)offset);
    568     if (vaddr == (void *)-1)
    569 	return NULL;
    570 #endif
    571 
    572     if (!vaddr) {
    573 	if (!(mp = AddMap()))
    574 	    return NULL;
    575 	mp->physaddr = address;
    576 	mp->size = size;
    577 	mp->delta = delta;
    578 	mp->vaddr = vaddr;
    579 	mp->refcount = 1;
    580     }
    581     return (void *)((unsigned long)vaddr + delta);
    582 }
    583 
    584 /*
    585  * Still need to find a clean way of detecting the death of a DGA app
    586  * and returning things to normal - Jon
    587  * This is here to help debugging without rebooting... Also C-A-BS
    588  * should restore text mode.
    589  */
    590 
    591 int
    592 SDL_NAME(XF86DGAForkApp)(int screen)
    593 {
    594     pid_t pid;
    595     int status;
    596     int i;
    597 
    598      /* fork the app, parent hangs around to clean up */
    599     if ((pid = fork()) > 0) {
    600 	ScrPtr sp;
    601 
    602 	waitpid(pid, &status, 0);
    603 	for (i = 0; i < numScrs; i++) {
    604 	    sp = scrList[i];
    605 	    SDL_NAME(XF86DGADirectVideoLL)(sp->display, sp->screen, 0);
    606 	    XSync(sp->display, False);
    607 	}
    608     if (WIFEXITED(status))
    609 	    exit(0);
    610 	else
    611 	    exit(-1);
    612     }
    613     return pid;
    614 }
    615 
    616 
    617 Bool
    618 SDL_NAME(XF86DGADirectVideo)(
    619     Display *dis,
    620     int screen,
    621     int enable
    622 ){
    623     ScrPtr sp;
    624     MapPtr mp = NULL;
    625 
    626     if ((sp = FindScr(dis, screen)))
    627 	mp = sp->map;
    628 
    629     if (enable & XF86DGADirectGraphics) {
    630 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
    631 	&& !defined(__EMX__)
    632 	if (mp && mp->vaddr)
    633 	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE);
    634 #endif
    635     } else {
    636 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
    637 	&& !defined(__EMX__)
    638 	if (mp && mp->vaddr)
    639 	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ);
    640 #elif defined(Lynx)
    641 	/* XXX this doesn't allow enable after disable */
    642 	smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH);
    643 	smem_remove("XF86DGA");
    644 #endif
    645     }
    646 
    647     SDL_NAME(XF86DGADirectVideoLL)(dis, screen, enable);
    648     return 1;
    649 }
    650 
    651 
    652 static void
    653 XF86cleanup(int sig)
    654 {
    655     ScrPtr sp;
    656     int i;
    657     static char beenhere = 0;
    658 
    659     if (beenhere)
    660 	    exit(3);
    661     beenhere = 1;
    662 
    663     for (i = 0; i < numScrs; i++) {
    664 	sp = scrList[i];
    665 	SDL_NAME(XF86DGADirectVideo)(sp->display, sp->screen, 0);
    666 	XSync(sp->display, False);
    667     }
    668     exit(3);
    669 }
    670 
    671 Bool
    672 SDL_NAME(XF86DGAGetVideo)(
    673     Display *dis,
    674     int screen,
    675     char **addr,
    676     int *width,
    677     int *bank,
    678     int *ram
    679 ){
    680     /*unsigned long*/ int offset;
    681     static int beenHere = 0;
    682     ScrPtr sp;
    683     MapPtr mp;
    684 
    685     if (!(sp = FindScr(dis, screen))) {
    686 	if (!(sp = AddScr())) {
    687 	    fprintf(stderr, "XF86DGAGetVideo: malloc failure\n");
    688 	    exit(-2);
    689 	}
    690 	sp->display = dis;
    691 	sp->screen = screen;
    692 	sp->map = NULL;
    693     }
    694 
    695     SDL_NAME(XF86DGAGetVideoLL)(dis, screen , &offset, width, bank, ram);
    696 
    697     *addr = MapPhysAddress(offset, *bank);
    698     if (*addr == NULL) {
    699 	fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n",
    700 		strerror(errno));
    701 	exit(-2);
    702     }
    703 
    704     if ((mp = FindMap(offset, *bank)))
    705 	sp->map = mp;
    706 
    707     if (!beenHere) {
    708 	beenHere = 1;
    709 	atexit((void(*)(void))XF86cleanup);
    710 	/* one shot XF86cleanup attempts */
    711 	signal(SIGSEGV, XF86cleanup);
    712 #ifdef SIGBUS
    713 	signal(SIGBUS, XF86cleanup);
    714 #endif
    715 	signal(SIGHUP, XF86cleanup);
    716 	signal(SIGFPE, XF86cleanup);
    717     }
    718 
    719     return 1;
    720 }
    721 
    722