drm: add _DRM_CONSISTENT map type
authorDave Airlie <airlied@starflyer.(none)>
Sun, 10 Jul 2005 04:34:13 +0000 (14:34 +1000)
committerDave Airlie <airlied@linux.ie>
Sun, 10 Jul 2005 04:34:13 +0000 (14:34 +1000)
Added a new DRM map type _DRM_CONSISTENT for consistent PCI memory. It
uses drm_pci_alloc/free for allocating/freeing the memory.

From: Felix Kuhling <fxkuehl@gmx.de>
Signed-off-by: David Airlie <airlied@linux.ie>
drivers/char/drm/drm.h
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_drv.c
drivers/char/drm/drm_proc.c
drivers/char/drm/drm_vm.c

index e8371dd87fbca0867953f1e53c07b5ec8b5a19d5..50c4d981c4978d37091b51f76da486946d036c8c 100644 (file)
@@ -209,7 +209,8 @@ typedef enum drm_map_type {
        _DRM_REGISTERS      = 1,  /**< no caching, no core dump */
        _DRM_SHM            = 2,  /**< shared, cached */
        _DRM_AGP            = 3,  /**< AGP/GART */
-       _DRM_SCATTER_GATHER = 4   /**< Scatter/gather memory for PCI DMA */
+       _DRM_SCATTER_GATHER = 4,  /**< Scatter/gather memory for PCI DMA */
+       _DRM_CONSISTENT     = 5,  /**< Consistent memory for PCI DMA */
 } drm_map_type_t;
 
 
index 4c6191d231b8e06e20d876af0287d03df9335153..89f301ffd97e01706508308b684db09a62cc90c4 100644 (file)
@@ -180,7 +180,22 @@ int drm_addmap( struct inode *inode, struct file *filp,
                }
                map->offset += dev->sg->handle;
                break;
-
+       case _DRM_CONSISTENT: 
+       {
+               /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
+                * As we're limit the address to 2^32-1 (or lses),
+                * casting it down to 32 bits is no problem, but we
+                * need to point to a 64bit variable first. */
+               dma_addr_t bus_addr;
+               map->handle = drm_pci_alloc(dev, map->size, map->size,
+                                           0xffffffffUL, &bus_addr);
+               map->offset = (unsigned long)bus_addr;
+               if (!map->handle) {
+                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+                       return -ENOMEM;
+               }
+               break;
+       }
        default:
                drm_free( map, sizeof(*map), DRM_MEM_MAPS );
                return -EINVAL;
@@ -291,6 +306,9 @@ int drm_rmmap(struct inode *inode, struct file *filp,
                case _DRM_AGP:
                case _DRM_SCATTER_GATHER:
                        break;
+               case _DRM_CONSISTENT:
+                       drm_pci_free(dev, map->size, map->handle, map->offset);
+                       break;
                }
                drm_free(map, sizeof(*map), DRM_MEM_MAPS);
        }
index 3333c250c4d9995848053d4f8a3ecf1286b1ed6b..f4046c8c70b53d8ba62929eb4fed20ecd2278949 100644 (file)
@@ -228,6 +228,10 @@ int drm_takedown( drm_device_t *dev )
                                                dev->sg = NULL;
                                        }
                                        break;
+                               case _DRM_CONSISTENT:
+                                       drm_pci_free(dev, map->size,
+                                                    map->handle, map->offset);
+                                       break;
                                }
                                drm_free(map, sizeof(*map), DRM_MEM_MAPS);
                        }
index 4774087d2e9e82c64d0d05511d02743d9371375f..f4154cc71abbe63a70b64619eaf4197c7544caea 100644 (file)
@@ -210,8 +210,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
 
                                /* Hardcoded from _DRM_FRAME_BUFFER,
                                    _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
-                                   _DRM_SCATTER_GATHER. */
-       const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
+                                   _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
+       const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
        const char   *type;
        int          i;
 
@@ -229,9 +229,12 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
        if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
                r_list = list_entry(list, drm_map_list_t, head);
                map = r_list->map;
-               if(!map) continue;
-               if (map->type < 0 || map->type > 4) type = "??";
-               else                                type = types[map->type];
+               if(!map)
+                       continue;
+               if (map->type < 0 || map->type > 5)
+                       type = "??";
+               else    
+                       type = types[map->type];
                DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
                               i,
                               map->offset,
index 621220f3f37207492ed8bfccdcef7d5e94cc0fda..644ec9dadc0549ffbbd7df7a33f57eca78c135cd 100644 (file)
@@ -228,6 +228,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
                        case _DRM_AGP:
                        case _DRM_SCATTER_GATHER:
                                break;
+                       case _DRM_CONSISTENT:
+                               drm_pci_free(dev, map->size, map->handle,
+                                            map->offset);
+                               break;
                        }
                        drm_free(map, sizeof(*map), DRM_MEM_MAPS);
                }
@@ -645,6 +649,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
                vma->vm_ops = &drm_vm_ops;
                break;
        case _DRM_SHM:
+       case _DRM_CONSISTENT:
+               /* Consistent memory is really like shared memory. It's only
+                * allocate in a different way */
                vma->vm_ops = &drm_vm_shm_ops;
                vma->vm_private_data = (void *)map;
                                /* Don't let this area swap.  Change when