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.
*/