[comp.windows.x] X Windows on Sun 386i bug

jne@goldhill.COM (09/06/89)

This bug has appeared on both the sun-386i and xpert mailing lists 
lately, so I'm posting to both.

In Sun 386i digest, vol. 1, issue 8, mike@bucasb.bu.edu writes:

> However, on the [Sun 386i] 150 the [X11.R3 server] code immediately exits
> because mmap fails yielding error BW2 mapping:  no such device or address.
> Sunview and screendump screenload which access directly or indirectly
> /dev/bwtwo0 both work fine on these machines.

I came across the same problem.  It seems that ddx/sun/sunBW2.c only
deals with the high resolution b&w monitor and the normal monitor, not
the "low resolution" monitor (1024x768).  I generalized/simplified the
code and made it deal with the low res. monitor.  I have commented out
the #def of FBSIZE_COMPUTE_ANSWER in my code, only because I needed a 
trusted version quickly and I didn't have the time or hardware to test
the computation (based on fbtype->fb_size) on all monitors.  You can
probably #def FBSIZE_COMPUTE_ANSWER and things will work.  Please let
me know if there's any problems with this.  

Jeff Eisen
Gold Hill Computers
617-621-3404
jne@goldhill.com

Here's the diff:

*** ddx/sun/sunBW2.c.orig	Sat May 21 14:49:33 1988
--- ddx/sun/sunBW2.c	Mon Jul 10 13:35:41 1989
***************
*** 61,75 ****
  
  extern caddr_t mmap();
  
! typedef struct bw2 {
!     u_char	image[BW2_FBSIZE];          /* Pixel buffer */
! } BW2, BW2Rec, *BW2Ptr;
  
! typedef struct bw2hr {
!     u_char	image[BW2_FBSIZE_HIRES];          /* Pixel buffer */
! } BW2HR, BW2HRRec, *BW2HRPtr;
  
  
  /*-
   *-----------------------------------------------------------------------
   * sunBW2SaveScreen --
--- 61,79 ----
  
  extern caddr_t mmap();
  
! /* This should be in <sundev/bw2reg.h> but isn't */
! #define BW2_FBSIZE_LORES (1024/8 * 768)
  
! /* compute or use magic numbers -- comment out to use magic numbers*/
! /* #define FBSIZE_COMPUTE_ANSWER */
  
+ /* The largest frame buffer possible */
+ #define MAX_BW2_FBSIZE (BW2_FBSIZE_HIRES)
  
+ typedef struct bw2 {
+   u_char	image[MAX_BW2_FBSIZE]; 		/* Pixel Buffer */
+ } BW2, BW2Rec, *BW2Ptr ;
+ 
  /*-
   *-----------------------------------------------------------------------
   * sunBW2SaveScreen --
***************
*** 236,242 ****
  
      if (!mfbScreenInit(index, pScreen,
  			   sunFbs[index].fb,
! 			   sunFbs[index].info.fb_width,
  			   sunFbs[index].info.fb_height, 90, 90))
  	return (FALSE);
  
--- 240,246 ----
  
      if (!mfbScreenInit(index, pScreen,
  			   sunFbs[index].fb,
! 		           sunFbs[index].info.fb_width,
  			   sunFbs[index].info.fb_height, 90, 90))
  	return (FALSE);
  
***************
*** 291,296 ****
--- 295,344 ----
  
  /*-
   *-----------------------------------------------------------------------
+  * sunBW2FBSize --
+  *	Determine the size of the frame buffer
+  *
+  * Results:
+  *	Returns the size of the frame buffer
+  *
+  * Side Effects:
+  *	None
+  *
+  *-----------------------------------------------------------------------
+  */
+ /*ARGSUSED*/
+ static int
+ sunBW2FBSize (pfbType)
+      struct fbtype *pfbType ;	/* the fbtype of the frame buffer */
+ {
+   int fb_width = pfbType->fb_width ;
+   int size ;
+   
+ #ifdef FBSIZE_COMPUTE_ANSWER
+     {
+       int fbsize = pfbType->fb_size ;
+       int pgsize = getpagesize() ;
+       /* round fbsize up to nearest pgsize */
+ 
+       size = ((fbsize + pgsize - 1) / pgsize) * pgsize ;
+     }
+ #else
+   if (fb_width > 1152) {			/* High resolution fb */
+     size = BW2_FBSIZE_HIRES ;
+   } else if (fb_width == 1152) {		/* Standard fb */
+     size = BW2_FBSIZE ;
+   } else {					/* Low resolution fb */
+     size = BW2_FBSIZE_LORES ;
+   }
+ #endif
+   if (size > MAX_BW2_FBSIZE) {
+     FatalError("Mapping BW2:  Frame buffer size %d larger than allowed maximum\n %d", size, MAX_BW2_FBSIZE) ;
+   }
+   return ((sizeof (u_char) * size)) ;
+ }
+ 
+ /*-
+  *-----------------------------------------------------------------------
   * sunBW2Probe --
   *	Attempt to find and initialize a bw2 framebuffer
   *
***************
*** 321,328 ****
  	int         fd;
  	struct fbtype fbType;
  	BW2Ptr      BW2fb = NULL;	/* Place to map the thing */
! 	BW2HRPtr    BW2HRfb = NULL;	/* Place to map the thing */
! 	int         isHiRes = 0;
  
  	if ((fd = sunOpenFrameBuffer(FBTYPE_SUN2BW, &fbType, index, fbNum,
  				     argc, argv)) < 0) {
--- 369,375 ----
  	int         fd;
  	struct fbtype fbType;
  	BW2Ptr      BW2fb = NULL;	/* Place to map the thing */
! 	int         fbsize = 0 ;
  
  	if ((fd = sunOpenFrameBuffer(FBTYPE_SUN2BW, &fbType, index, fbNum,
  				     argc, argv)) < 0) {
***************
*** 330,376 ****
  	    return FALSE;
  	}
  
! 	isHiRes = (fbType.fb_width > 1152);
  #ifdef	_MAP_NEW
! 	if (isHiRes) {
! 	    BW2HRfb = (BW2HRPtr) mmap((caddr_t) 0, sizeof(BW2HRRec),
! 			   PROT_READ | PROT_WRITE,
! 			   MAP_SHARED | _MAP_NEW,
! 			   fd, (off_t) 0);
! 	    if ((int)BW2HRfb == -1) {
! 		Error("mapping BW2 (hires)");
! 		sunFbData[fbNum].probeStatus = probedAndFailed;
! 		(void) close(fd);
! 		return FALSE;
! 	    }
  	}
- 	else {
- 	    BW2fb = (BW2Ptr) mmap((caddr_t) 0, sizeof(BW2Rec),
- 			 PROT_READ | PROT_WRITE,
- 			 MAP_SHARED | _MAP_NEW,
- 			 fd, (off_t) 0);
- 	    if ((int)BW2fb == -1) {
- 		Error("mapping BW2");
- 		sunFbData[fbNum].probeStatus = probedAndFailed;
- 		(void) close(fd);
- 		return FALSE;
- 	    }
- 	}
  #else
! 	if (isHiRes) {
! 	    BW2HRfb = (BW2HRPtr) valloc(sizeof(BW2HRRec));
! 	}
! 	else {
! 	    BW2fb = (BW2Ptr) valloc(sizeof(BW2Rec));
! 	}
! 	if ((BW2fb == (BW2Ptr) NULL) && (BW2HRfb == (BW2HRPtr) NULL)) {
  	    ErrorF("Could not allocate room for frame buffer.\n");
  	    sunFbData[fbNum].probeStatus = probedAndFailed;
  	    (void) close(fd);
  	    return FALSE;
  	}
! 	if (mmap((isHiRes ? (pointer) BW2HRfb : (pointer) BW2fb),
! 		 (isHiRes ? sizeof(BW2HRRec) : sizeof(BW2Rec)),
  		 PROT_READ | PROT_WRITE, MAP_SHARED,
  		 fd, (off_t) 0) < 0) {
  	    ErrorF("Mapping bw2");
--- 377,404 ----
  	    return FALSE;
  	}
  
! 	fbsize = sunBW2FBSize (&fbType) ;
! 
  #ifdef	_MAP_NEW
! 	BW2fb = (BW2Ptr) mmap((caddr_t) 0, fbsize,
! 			      PROT_READ | PROT_WRITE,
! 			      MAP_SHARED | _MAP_NEW,
! 			      fd, (off_t) 0);
! 	if ((int)BW2fb == -1) {
! 	  Error("mapping BW2");
! 	  sunFbData[fbNum].probeStatus = probedAndFailed;
! 	  (void) close(fd);
! 	  return FALSE;
  	}
  #else
! 	BW2fb = (BW2Ptr) valloc(fbsize) ;
! 	if (BW2fb == (BW2Ptr) NULL) {
  	    ErrorF("Could not allocate room for frame buffer.\n");
  	    sunFbData[fbNum].probeStatus = probedAndFailed;
  	    (void) close(fd);
  	    return FALSE;
  	}
! 	if (mmap((pointer) BW2fb, fbsize,
  		 PROT_READ | PROT_WRITE, MAP_SHARED,
  		 fd, (off_t) 0) < 0) {
  	    ErrorF("Mapping bw2");
***************
*** 388,394 ****
  	if ((sunFbData[fbNum].pr = pr_open(sunFbData[fbNum].devName)) == 0) {
  	    ErrorF("Opening bw2 pixrect");
  	    sunFbData[fbNum].probeStatus = probedAndFailed;
! 	    /* do we need to free BW2fb or BW2HRfb? */
  	    (void) close(fd);
  	    return FALSE;
  	}
--- 416,422 ----
  	if ((sunFbData[fbNum].pr = pr_open(sunFbData[fbNum].devName)) == 0) {
  	    ErrorF("Opening bw2 pixrect");
  	    sunFbData[fbNum].probeStatus = probedAndFailed;
! 	    /* do we need to free BW2fb? */
  	    (void) close(fd);
  	    return FALSE;
  	}
***************
*** 397,409 ****
  			   fbType.fb_width, fbType.fb_height, 1)) == 0) {
  	    ErrorF("Opening bw2 scratch pixrect");
  	    sunFbData[fbNum].probeStatus = probedAndFailed;
! 	    /* do we need to free BW2fb or BW2HRfb? */
  	    pr_destroy(sunFbData[fbNum].pr);
  	    (void) close(fd);
  	    return FALSE;
  	}
  #endif ZOIDS
! 	sunFbs[index].fb = (isHiRes ? (pointer) BW2HRfb : (pointer) BW2fb);
  	sunFbs[index].fd = fd;
  	sunFbs[index].info = fbType;
          sunFbs[index].EnterLeave = NoopDDA;
--- 425,437 ----
  			   fbType.fb_width, fbType.fb_height, 1)) == 0) {
  	    ErrorF("Opening bw2 scratch pixrect");
  	    sunFbData[fbNum].probeStatus = probedAndFailed;
! 	    /* do we need to free BW2fb? */
  	    pr_destroy(sunFbData[fbNum].pr);
  	    (void) close(fd);
  	    return FALSE;
  	}
  #endif ZOIDS
! 	sunFbs[index].fb = (pointer) BW2fb ;
  	sunFbs[index].fd = fd;
  	sunFbs[index].info = fbType;
          sunFbs[index].EnterLeave = NoopDDA;