Here's a new version that should be compatible with all of the cases:
1) multiple maps
2) old X doing AddMap
3) fixed X doing GetMap - X needs to switch to this after all the
drivers get fixed
4) drivers that have implemented permanent maps
4) drivers that have not implemented permanent maps

I have a fix for my editor now that strips trailing blanks so I'm
generating a few extra diffs but this will get rid of the trailing
blanks in CVS after a few check ins.

The reason for this change is to prevent X from moving the address of
the framebuffer in PCI space. That is an illegal thing for X to do on
Linux without also making the appropriate kernel calls. After all of
the DRM drivers implement permanent mapping, X will get an error if it
tried to move the framebuffer address.
===== linux/drm_bufs.h 1.8 vs edited =====
--- 1.8/linux/drm_bufs.h	Sun Sep  5 21:22:06 2004
+++ edited/linux/drm_bufs.h	Tue Sep  7 11:31:45 2004
@@ -1,7 +1,7 @@
 /**
- * \file drm_bufs.h 
+ * \file drm_bufs.h
  * Generic buffer template
- * 
+ *
  * \author Rickard E. (Rik) Faith <[EMAIL PROTECTED]>
  * \author Gareth Hughes <[EMAIL PROTECTED]>
  */
@@ -39,7 +39,7 @@
 /**
  * Compute size order.  Returns the exponent of the smaller power of two which
  * is greater or equal to given number.
- * 
+ *
  * \param size size.
  * \return order.
  *
@@ -59,6 +59,7 @@
 	return order;
 }
 
+static int permanent_maps = 0;
  /**
  * Adjusts the memory offset to its absolute value according to the mapping
  * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
@@ -80,7 +81,7 @@
 	if ( !(list = DRM(alloc)( sizeof(*list), DRM_MEM_MAPS )))
 		return -ENOMEM;
 	memset(list, 0, sizeof(*list));
-		
+
 	if ( !(map = DRM(alloc)( sizeof(*map), DRM_MEM_MAPS ))) {
 		DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
 		return -ENOMEM;
@@ -98,7 +99,7 @@
 
 	DRM_DEBUG( "initmap offset = 0x%08lx, size = 0x%08lx, type = %d\n",
 		   map->offset, map->size, map->type );
-        
+
 #ifdef __alpha__
 	map->offset += dev->hose->mem_space->start;
 #endif
@@ -116,7 +117,8 @@
 	down(&dev->struct_sem);
 	list_add(&list->head, &dev->maplist->head);
 	up(&dev->struct_sem);
-	
+
+	permanent_maps = 1;
 	DRM_DEBUG("finished\n");
 
 	return 0;
@@ -175,19 +177,24 @@
 	switch ( map->type ) {
 	case _DRM_REGISTERS:
 	case _DRM_FRAME_BUFFER: {
-		/* after all the drivers switch to permanent mapping this should just return an error */
         	struct list_head *_list;
 
-		/* if map already exists, return the existing one instead of creating a new one */
-		list_for_each( _list, &dev->maplist->head ) {
-			drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head );
-			if ( _entry->map && _entry->map->type == map->type ) {
-				DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-				map = _entry->map;
-				DRM_DEBUG( "Found existing: offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-					map->offset, map->size, map->type );
-				goto found_it;
+		/* If permanent maps are implemented, maps must match */
+		if (permanent_maps) {
+			list_for_each( _list, &dev->maplist->head ) {
+				drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head );
+				if ( _entry->map && _entry->map->type == map->type &&
+						_entry->map->offset == map->offset &&
+						_entry->map->size == map->size ) {
+					DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
+					map = _entry->map;
+					DRM_DEBUG( "Found existing: offset = 0x%08lx, size = 0x%08lx, type = %d\n",
+						map->offset, map->size, map->type );
+					goto found_it;
+				}
 			}
+			/* addmap didn't match an existing permanent maps, that's an error */
+			return -EINVAL;
 		}
 #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
 		if ( map->offset + map->size < map->offset ||
@@ -309,7 +316,7 @@
 			   sizeof(request))) {
 		return -EFAULT;
 	}
-	
+
 	down(&dev->struct_sem);
 	list = &dev->maplist->head;
 	list_for_each(list, &dev->maplist->head) {
@@ -328,7 +335,7 @@
 		return -EINVAL;
 	}
 	map = r_list->map;
-	
+
 	/* Register and framebuffer maps are permanent */
 	if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
 		up(&dev->struct_sem);
@@ -412,7 +419,7 @@
  * \param cmd command.
  * \param arg pointer to a drm_buf_desc_t request.
  * \return zero on success or a negative number on failure.
- * 
+ *
  * After some sanity checks creates a drm_buf structure for each buffer and
  * reallocates the buffer list of the same size order to accommodate the new
  * buffers.
@@ -837,7 +844,7 @@
 	drm_buf_t **temp_buflist;
 
 	if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL;
-	
+
 	if ( !dma ) return -EINVAL;
 
 	if ( copy_from_user( &request, argp, sizeof(request) ) )
@@ -1000,7 +1007,7 @@
 	drm_buf_desc_t request;
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->dev;
-	
+
 	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
 		return -EINVAL;
 
@@ -1160,14 +1167,14 @@
 }
 
 /**
- * Unreserve the buffers in list, previously reserved using drmDMA. 
+ * Unreserve the buffers in list, previously reserved using drmDMA.
  *
  * \param inode device inode.
  * \param filp file pointer.
  * \param cmd command.
  * \param arg pointer to a drm_buf_free structure.
  * \return zero on success or a negative number on failure.
- * 
+ *
  * Calls free_buffer() for each used buffer.
  * This function is primarily used for debugging.
  */

Reply via email to