summaryrefslogtreecommitdiff
path: root/linux-core/drm_bo.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core/drm_bo.c')
-rw-r--r--linux-core/drm_bo.c71
1 files changed, 59 insertions, 12 deletions
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 95802fe2..c41f726c 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -574,7 +574,6 @@ void drm_putback_buffer_objects(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_putback_buffer_objects);
-
/*
* Note. The caller has to register (if applicable)
* and deregister fence object usage.
@@ -1758,7 +1757,7 @@ int drm_buffer_object_create(struct drm_device *dev,
size += buffer_start & ~PAGE_MASK;
num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
if (num_pages == 0) {
- DRM_ERROR("Illegal buffer object size.\n");
+ DRM_ERROR("Illegal buffer object size %ld.\n", size);
return -EINVAL;
}
@@ -2180,7 +2179,7 @@ restart:
return 0;
}
-int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type)
+int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean)
{
struct drm_buffer_manager *bm = &dev->bm;
struct drm_mem_type_manager *man = &bm->man[mem_type];
@@ -2196,6 +2195,13 @@ int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type)
"memory manager type %u\n", mem_type);
return ret;
}
+
+ if ((man->kern_init_type) && (kern_clean == 0)) {
+ DRM_ERROR("Trying to take down kernel initialized "
+ "memory manager type %u\n", mem_type);
+ return -EPERM;
+ }
+
man->use_type = 0;
man->has_type = 0;
@@ -2247,9 +2253,9 @@ static int drm_bo_lock_mm(struct drm_device *dev, unsigned mem_type)
return ret;
}
-int drm_bo_init_mm(struct drm_device *dev,
- unsigned type,
- unsigned long p_offset, unsigned long p_size)
+int drm_bo_init_mm(struct drm_device *dev, unsigned type,
+ unsigned long p_offset, unsigned long p_size,
+ int kern_init)
{
struct drm_buffer_manager *bm = &dev->bm;
int ret = -EINVAL;
@@ -2283,6 +2289,8 @@ int drm_bo_init_mm(struct drm_device *dev,
}
man->has_type = 1;
man->use_type = 1;
+ man->kern_init_type = kern_init;
+ man->size = p_size;
INIT_LIST_HEAD(&man->lru);
INIT_LIST_HEAD(&man->pinned);
@@ -2315,7 +2323,7 @@ int drm_bo_driver_finish(struct drm_device *dev)
man = &bm->man[i];
if (man->has_type) {
man->use_type = 0;
- if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i)) {
+ if ((i != DRM_BO_MEM_LOCAL) && drm_bo_clean_mm(dev, i, 1)) {
ret = -EBUSY;
DRM_ERROR("DRM memory manager type %d "
"is not clean.\n", i);
@@ -2351,6 +2359,7 @@ out:
mutex_unlock(&dev->struct_mutex);
return ret;
}
+EXPORT_SYMBOL(drm_bo_driver_finish);
/*
* This function is intended to be called on drm driver load.
@@ -2385,7 +2394,7 @@ int drm_bo_driver_init(struct drm_device *dev)
* Initialize the system memory buffer type.
* Other types need to be driver / IOCTL initialized.
*/
- ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0);
+ ret = drm_bo_init_mm(dev, DRM_BO_MEM_LOCAL, 0, 0, 1);
if (ret)
goto out_unlock;
@@ -2445,7 +2454,7 @@ int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_
goto out;
}
ret = drm_bo_init_mm(dev, arg->mem_type,
- arg->p_offset, arg->p_size);
+ arg->p_offset, arg->p_size, 0);
out:
mutex_unlock(&dev->struct_mutex);
@@ -2484,9 +2493,11 @@ int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *f
goto out;
}
ret = 0;
- if (drm_bo_clean_mm(dev, arg->mem_type)) {
- DRM_ERROR("Memory manager type %d not clean. "
- "Delaying takedown\n", arg->mem_type);
+ if ((ret = drm_bo_clean_mm(dev, arg->mem_type, 0))) {
+ if (ret == -EINVAL)
+ DRM_ERROR("Memory manager type %d not clean. "
+ "Delaying takedown\n", arg->mem_type);
+ ret = 0;
}
out:
mutex_unlock(&dev->struct_mutex);
@@ -2553,6 +2564,42 @@ int drm_mm_unlock_ioctl(struct drm_device *dev,
return 0;
}
+int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_mm_info_arg *arg = data;
+ struct drm_buffer_manager *bm = &dev->bm;
+ struct drm_bo_driver *driver = dev->driver->bo_driver;
+ struct drm_mem_type_manager *man;
+ int ret = 0;
+ int mem_type = arg->mem_type;
+
+ if (!driver) {
+ DRM_ERROR("Buffer objects are not supported by this driver\n");
+ return -EINVAL;
+ }
+
+ if (mem_type >= DRM_BO_MEM_TYPES) {
+ DRM_ERROR("Illegal memory type %d\n", arg->mem_type);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+ if (!bm->initialized) {
+ DRM_ERROR("DRM memory manager was not initialized\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+
+ man = &bm->man[arg->mem_type];
+
+ arg->p_size = man->size;
+
+out:
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
/*
* buffer object vm functions.
*/