summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/Makefile.kernel8
-rw-r--r--linux-core/drmP.h14
-rw-r--r--linux-core/drm_bo.c109
-rw-r--r--linux-core/drm_bo_move.c6
-rw-r--r--linux-core/drm_bufs.c4
-rw-r--r--linux-core/drm_context.c43
-rw-r--r--linux-core/drm_drawable.c65
-rw-r--r--linux-core/drm_drv.c4
-rw-r--r--linux-core/drm_fence.c128
-rw-r--r--linux-core/drm_objects.h21
-rw-r--r--linux-core/drm_scatter.c49
-rw-r--r--linux-core/drm_stub.c26
-rw-r--r--linux-core/drm_sysfs.c31
-rw-r--r--linux-core/drm_vm.c3
l---------linux-core/nouveau_notifier.c1
l---------linux-core/nv04_fifo.c1
l---------linux-core/nv04_instmem.c1
l---------linux-core/nv10_fifo.c1
l---------linux-core/nv40_fifo.c1
l---------linux-core/nv50_fifo.c1
l---------linux-core/nv50_graph.c1
l---------linux-core/nv50_instmem.c1
l---------linux-core/nv50_mc.c1
23 files changed, 271 insertions, 249 deletions
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel
index d9865f5a..321eb807 100644
--- a/linux-core/Makefile.kernel
+++ b/linux-core/Makefile.kernel
@@ -21,12 +21,14 @@ i810-objs := i810_drv.o i810_dma.o
i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \
i915_buffer.o
nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
- nouveau_object.o nouveau_irq.o \
+ nouveau_object.o nouveau_irq.o nouveau_notifier.o \
nv04_timer.o \
- nv04_mc.o nv40_mc.o \
+ nv04_mc.o nv40_mc.o nv50_mc.o \
nv04_fb.o nv10_fb.o nv40_fb.o \
+ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \
- nv40_graph.o
+ nv40_graph.o nv50_graph.o \
+ nv04_instmem.o nv50_instmem.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
sis-objs := sis_drv.o sis_mm.o
ffb-objs := ffb_drv.o ffb_context.o
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index dd3a69df..2bbc6200 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -570,10 +570,6 @@ typedef struct drm_ctx_list {
drm_file_t *tag; /**< associated fd private data */
} drm_ctx_list_t;
-struct drm_ctx_sarea_list {
- drm_map_t *map;
-};
-
typedef struct drm_vbl_sig {
struct list_head head;
unsigned int sequence;
@@ -598,10 +594,6 @@ typedef struct ati_pcigart_info {
int table_size;
} drm_ati_pcigart_info;
-struct drm_drawable_list {
- drm_drawable_info_t info;
-};
-
#include "drm_objects.h"
/**
@@ -1056,6 +1048,9 @@ extern unsigned long drm_get_resource_start(drm_device_t *dev,
unsigned int resource);
extern unsigned long drm_get_resource_len(drm_device_t *dev,
unsigned int resource);
+extern drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
+ drm_local_map_t *map);
+
/* DMA support (drm_dma.h) */
extern int drm_dma_setup(drm_device_t * dev);
@@ -1137,8 +1132,9 @@ extern int drm_proc_cleanup(int minor,
/* Scatter Gather Support (drm_scatter.h) */
extern void drm_sg_cleanup(drm_sg_mem_t * entry);
-extern int drm_sg_alloc(struct inode *inode, struct file *filp,
+extern int drm_sg_alloc_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+extern int drm_sg_alloc(drm_device_t *dev, drm_scatter_gather_t * request);
extern int drm_sg_free(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index f1ca0b44..ab257825 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -269,31 +269,25 @@ static int drm_bo_handle_move_mem(drm_buffer_object_t * bo,
int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
int no_wait)
{
-
- drm_fence_object_t *fence = bo->fence;
int ret;
DRM_ASSERT_LOCKED(&bo->mutex);
- if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ if (bo->fence) {
+ if (drm_fence_object_signaled(bo->fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
if (no_wait) {
return -EBUSY;
}
ret =
- drm_fence_object_wait(dev, fence, lazy, ignore_signals,
+ drm_fence_object_wait(bo->fence, lazy, ignore_signals,
bo->fence_type);
if (ret)
return ret;
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
-
+ drm_fence_usage_deref_unlocked(&bo->fence);
}
return 0;
}
@@ -321,10 +315,8 @@ static int drm_bo_expire_fence(drm_buffer_object_t * bo, int allow_errors)
"Evicting buffer.\n");
}
}
- if (bo->fence) {
- drm_fence_usage_deref_unlocked(dev, bo->fence);
- bo->fence = NULL;
- }
+ if (bo->fence)
+ drm_fence_usage_deref_unlocked(&bo->fence);
}
return 0;
}
@@ -348,11 +340,9 @@ static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all)
DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
- if (bo->fence && drm_fence_object_signaled(dev, bo->fence,
- bo->fence_type, 0)) {
- drm_fence_usage_deref_unlocked(dev, bo->fence);
- bo->fence = NULL;
- }
+ if (bo->fence && drm_fence_object_signaled(bo->fence,
+ bo->fence_type, 0))
+ drm_fence_usage_deref_unlocked(&bo->fence);
if (bo->fence && remove_all)
(void)drm_bo_expire_fence(bo, 0);
@@ -383,7 +373,7 @@ static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all)
}
if (list_empty(&bo->ddestroy)) {
- drm_fence_object_flush(dev, bo->fence, bo->fence_type);
+ drm_fence_object_flush(bo->fence, bo->fence_type);
list_add_tail(&bo->ddestroy, &bm->ddestroy);
schedule_delayed_work(&bm->wq,
((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
@@ -503,12 +493,15 @@ static void drm_bo_delayed_workqueue(struct work_struct *work)
mutex_unlock(&dev->struct_mutex);
}
-void drm_bo_usage_deref_locked(drm_buffer_object_t * bo)
+void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo)
{
- DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
+ struct drm_buffer_object *tmp_bo = *bo;
+ bo = NULL;
- if (atomic_dec_and_test(&bo->usage)) {
- drm_bo_destroy_locked(bo);
+ DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex);
+
+ if (atomic_dec_and_test(&tmp_bo->usage)) {
+ drm_bo_destroy_locked(tmp_bo);
}
}
@@ -520,17 +513,19 @@ static void drm_bo_base_deref_locked(drm_file_t * priv, drm_user_object_t * uo)
DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
drm_bo_takedown_vm_locked(bo);
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
}
-static void drm_bo_usage_deref_unlocked(drm_buffer_object_t * bo)
+static void drm_bo_usage_deref_unlocked(drm_buffer_object_t ** bo)
{
- drm_device_t *dev = bo->dev;
+ struct drm_buffer_object *tmp_bo = *bo;
+ drm_device_t *dev = tmp_bo->dev;
- if (atomic_dec_and_test(&bo->usage)) {
+ *bo = NULL;
+ if (atomic_dec_and_test(&tmp_bo->usage)) {
mutex_lock(&dev->struct_mutex);
- if (atomic_read(&bo->usage) == 0)
- drm_bo_destroy_locked(bo);
+ if (atomic_read(&tmp_bo->usage) == 0)
+ drm_bo_destroy_locked(tmp_bo);
mutex_unlock(&dev->struct_mutex);
}
}
@@ -616,16 +611,15 @@ int drm_fence_buffer_objects(drm_file_t * priv,
if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) {
count++;
if (entry->fence)
- drm_fence_usage_deref_locked(dev, entry->fence);
- entry->fence = fence;
- atomic_inc(&fence->usage);
+ drm_fence_usage_deref_locked(&entry->fence);
+ entry->fence = drm_fence_reference_locked(fence);
DRM_FLAG_MASKED(entry->priv_flags, 0,
_DRM_BO_FLAG_UNFENCED);
DRM_WAKEUP(&entry->event_queue);
drm_bo_add_to_lru(entry);
}
mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_locked(entry);
+ drm_bo_usage_deref_locked(&entry);
l = f_list.next;
}
DRM_DEBUG("Fenced %d buffers\n", count);
@@ -742,7 +736,7 @@ static int drm_bo_mem_force_space(drm_device_t * dev,
ret = drm_bo_evict(entry, mem_type, no_wait);
mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_unlocked(entry);
+ drm_bo_usage_deref_unlocked(&entry);
if (ret)
return ret;
mutex_lock(&dev->struct_mutex);
@@ -962,10 +956,8 @@ static int drm_bo_quick_busy(drm_buffer_object_t * bo)
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
return 1;
@@ -984,16 +976,13 @@ static int drm_bo_busy(drm_buffer_object_t * bo)
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
if (fence) {
- drm_device_t *dev = bo->dev;
- if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
- drm_fence_object_flush(dev, fence, DRM_FENCE_TYPE_EXE);
- if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) {
- drm_fence_usage_deref_unlocked(dev, fence);
- bo->fence = NULL;
+ drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE);
+ if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+ drm_fence_usage_deref_unlocked(&bo->fence);
return 0;
}
return 1;
@@ -1190,7 +1179,7 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
drm_bo_fill_rep_arg(bo, rep);
out:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
@@ -1216,7 +1205,7 @@ static int drm_buffer_object_unmap(drm_file_t * priv, uint32_t handle)
}
drm_remove_ref_object(priv, ro);
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
out:
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -1512,7 +1501,7 @@ static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle,
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
@@ -1534,7 +1523,7 @@ static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle,
(void)drm_bo_busy(bo);
drm_bo_fill_rep_arg(bo, rep);
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return 0;
}
@@ -1566,7 +1555,7 @@ static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
out:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
@@ -1651,7 +1640,7 @@ int drm_buffer_object_create(drm_device_t *dev,
out_err:
mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(bo);
+ drm_bo_usage_deref_unlocked(&bo);
return ret;
}
@@ -1728,7 +1717,7 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
mask &
DRM_BO_FLAG_SHAREABLE);
if (rep.ret)
- drm_bo_usage_deref_unlocked(entry);
+ drm_bo_usage_deref_unlocked(&entry);
if (rep.ret)
break;
@@ -1957,7 +1946,7 @@ restart:
allow_errors);
mutex_lock(&dev->struct_mutex);
- drm_bo_usage_deref_locked(entry);
+ drm_bo_usage_deref_locked(&entry);
if (ret)
return ret;
@@ -1967,10 +1956,8 @@ restart:
do_restart = ((next->prev != list) && (next->prev != prev));
- if (nentry != NULL && do_restart) {
- drm_bo_usage_deref_locked(nentry);
- nentry = NULL;
- }
+ if (nentry != NULL && do_restart)
+ drm_bo_usage_deref_locked(&nentry);
if (do_restart)
goto restart;
@@ -2365,7 +2352,7 @@ static void drm_bo_takedown_vm_locked(drm_buffer_object_t * bo)
drm_ctl_free(map, sizeof(*map), DRM_MEM_BUFOBJ);
list->map = NULL;
list->user_token = 0ULL;
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked(&bo);
}
static int drm_bo_setup_vm_locked(drm_buffer_object_t * bo)
diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c
index 4f752065..8ef2a8ff 100644
--- a/linux-core/drm_bo_move.c
+++ b/linux-core/drm_bo_move.c
@@ -306,7 +306,7 @@ int drm_buffer_object_transfer(drm_buffer_object_t * bo,
INIT_LIST_HEAD(&fbo->p_mm_list);
#endif
- atomic_inc(&bo->fence->usage);
+ drm_fence_reference_unlocked(&fbo->fence, bo->fence);
fbo->pinned_node = NULL;
fbo->mem.mm_node->private = (void *)fbo;
atomic_set(&fbo->usage, 1);
@@ -339,7 +339,7 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo,
drm_buffer_object_t *old_obj;
if (bo->fence)
- drm_fence_usage_deref_unlocked(dev, bo->fence);
+ drm_fence_usage_deref_unlocked(&bo->fence);
ret = drm_fence_object_create(dev, fence_class, fence_type,
fence_flags | DRM_FENCE_FLAG_EMIT,
&bo->fence);
@@ -396,7 +396,7 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo,
DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
drm_bo_add_to_lru(old_obj);
- drm_bo_usage_deref_locked(old_obj);
+ drm_bo_usage_deref_locked(&old_obj);
mutex_unlock(&dev->struct_mutex);
}
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index a2c8a75e..2f3e4b2a 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -48,8 +48,7 @@ unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
}
EXPORT_SYMBOL(drm_get_resource_len);
-static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
- drm_local_map_t *map)
+drm_map_list_t *drm_find_matching_map(drm_device_t *dev, drm_local_map_t *map)
{
drm_map_list_t *entry;
list_for_each_entry(entry, &dev->maplist, head) {
@@ -62,6 +61,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
return NULL;
}
+EXPORT_SYMBOL(drm_find_matching_map);
static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
unsigned long user_token, int hashed_handle)
diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c
index 101a298c..195c7fb5 100644
--- a/linux-core/drm_context.c
+++ b/linux-core/drm_context.c
@@ -58,17 +58,9 @@
*/
void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
{
- struct drm_ctx_sarea_list *ctx;
-
mutex_lock(&dev->struct_mutex);
- ctx = idr_find(&dev->ctx_idr, ctx_handle);
- if (ctx) {
- idr_remove(&dev->ctx_idr, ctx_handle);
- drm_free(ctx, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
- } else
- DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle);
+ idr_remove(&dev->ctx_idr, ctx_handle);
mutex_unlock(&dev->struct_mutex);
- return;
}
/**
@@ -84,20 +76,15 @@ static int drm_ctxbitmap_next(drm_device_t * dev)
{
int new_id;
int ret;
- struct drm_ctx_sarea_list *new_ctx;
-
- new_ctx = drm_calloc(1, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
- if (!new_ctx)
- return -1;
again:
if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Out of memory expanding drawable idr\n");
- drm_free(new_ctx, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
return -ENOMEM;
}
mutex_lock(&dev->struct_mutex);
- ret = idr_get_new_above(&dev->ctx_idr, new_ctx, DRM_RESERVED_CONTEXTS, &new_id);
+ ret = idr_get_new_above(&dev->ctx_idr, NULL,
+ DRM_RESERVED_CONTEXTS, &new_id);
if (ret == -EAGAIN) {
mutex_unlock(&dev->struct_mutex);
goto again;
@@ -120,15 +107,6 @@ int drm_ctxbitmap_init(drm_device_t * dev)
return 0;
}
-
-
-static int drm_ctx_sarea_free(int id, void *p, void *data)
-{
- struct drm_ctx_sarea_list *ctx_entry = p;
- drm_free(ctx_entry, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST);
- return 0;
-}
-
/**
* Context bitmap cleanup.
*
@@ -140,7 +118,6 @@ static int drm_ctx_sarea_free(int id, void *p, void *data)
void drm_ctxbitmap_cleanup(drm_device_t * dev)
{
mutex_lock(&dev->struct_mutex);
- idr_for_each(&dev->ctx_idr, drm_ctx_sarea_free, NULL);
idr_remove_all(&dev->ctx_idr);
mutex_unlock(&dev->struct_mutex);
}
@@ -172,19 +149,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
drm_ctx_priv_map_t request;
drm_map_t *map;
drm_map_list_t *_entry;
- struct drm_ctx_sarea_list *ctx_sarea;
if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
mutex_lock(&dev->struct_mutex);
- ctx_sarea = idr_find(&dev->ctx_idr, request.ctx_id);
- if (!ctx_sarea) {
+ map = idr_find(&dev->ctx_idr, request.ctx_id);
+ if (!map) {
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
- map = ctx_sarea->map;
mutex_unlock(&dev->struct_mutex);
@@ -224,7 +199,6 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
drm_ctx_priv_map_t request;
drm_map_t *map = NULL;
drm_map_list_t *r_list = NULL;
- struct drm_ctx_sarea_list *ctx_sarea;
if (copy_from_user(&request,
(drm_ctx_priv_map_t __user *) arg, sizeof(request)))
@@ -245,14 +219,11 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
if (!map)
goto bad;
- mutex_lock(&dev->struct_mutex);
-
- ctx_sarea = idr_find(&dev->ctx_idr, request.ctx_id);
- if (!ctx_sarea)
+ if (IS_ERR(idr_replace(&dev->ctx_idr, map, request.ctx_id)))
goto bad;
- ctx_sarea->map = map;
mutex_unlock(&dev->struct_mutex);
+
return 0;
}
diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c
index eb44a189..7129980b 100644
--- a/linux-core/drm_drawable.c
+++ b/linux-core/drm_drawable.c
@@ -44,24 +44,18 @@ int drm_adddraw(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
unsigned long irqflags;
- struct drm_drawable_list *draw_info;
drm_draw_t draw;
int new_id = 0;
int ret;
- draw_info = drm_calloc(1, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
- if (!draw_info)
- return -ENOMEM;
-
again:
if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Out of memory expanding drawable idr\n");
- drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
return -ENOMEM;
}
spin_lock_irqsave(&dev->drw_lock, irqflags);
- ret = idr_get_new_above(&dev->drw_idr, draw_info, 1, &new_id);
+ ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id);
if (ret == -EAGAIN) {
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
goto again;
@@ -86,47 +80,46 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
DRM_DEVICE;
drm_draw_t draw;
unsigned long irqflags;
- struct drm_drawable_list *draw_info;
DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data,
sizeof(draw));
- draw_info = idr_find(&dev->drw_idr, draw.handle);
- if (!draw_info) {
- DRM_DEBUG("No such drawable %d\n", draw.handle);
- return -EINVAL;
- }
-
spin_lock_irqsave(&dev->drw_lock, irqflags);
+ drm_free(drm_get_drawable_info(dev, draw.handle),
+ sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
+
idr_remove(&dev->drw_idr, draw.handle);
- drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
DRM_DEBUG("%d\n", draw.handle);
return 0;
}
-int drm_update_drawable_info(DRM_IOCTL_ARGS) {
+int drm_update_drawable_info(DRM_IOCTL_ARGS)
+{
DRM_DEVICE;
drm_update_draw_t update;
unsigned long irqflags;
- drm_drawable_info_t *info;
drm_clip_rect_t *rects;
- struct drm_drawable_list *draw_info;
+ struct drm_drawable_info *info;
int err;
DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data,
sizeof(update));
- draw_info = idr_find(&dev->drw_idr, update.handle);
- if (!draw_info) {
- DRM_ERROR("No such drawable %d\n", update.handle);
- return DRM_ERR(EINVAL);
+ info = idr_find(&dev->drw_idr, update.handle);
+ if (!info) {
+ info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS);
+ if (!info)
+ return -ENOMEM;
+ if (IS_ERR(idr_replace(&dev->drw_idr, info, update.handle))) {
+ DRM_ERROR("No such drawable %d\n", update.handle);
+ drm_free(info, sizeof(*info), DRM_MEM_BUFS);
+ return -EINVAL;
+ }
}
- info = &draw_info->info;
-
switch (update.type) {
case DRM_DRAWABLE_CLIPRECTS:
if (update.num != info->num_rects) {
@@ -184,24 +177,22 @@ error:
/**
* Caller must hold the drawable spinlock!
*/
-drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) {
- struct drm_drawable_list *draw_info;
- draw_info = idr_find(&dev->drw_idr, id);
- if (!draw_info) {
- DRM_DEBUG("No such drawable %d\n", id);
- return NULL;
- }
-
- return &draw_info->info;
+drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id)
+{
+ return idr_find(&dev->drw_idr, id);
}
EXPORT_SYMBOL(drm_get_drawable_info);
static int drm_drawable_free(int idr, void *p, void *data)
{
- struct drm_drawable_list *drw_entry = p;
- drm_free(drw_entry->info.rects, drw_entry->info.num_rects *
- sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
- drm_free(drw_entry, sizeof(struct drm_drawable_list), DRM_MEM_BUFS);
+ struct drm_drawable_info *info = p;
+
+ if (info) {
+ drm_free(info->rects, info->num_rects *
+ sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
+ drm_free(info, sizeof(*info), DRM_MEM_BUFS);
+ }
+
return 0;
}
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index d5eb9713..0d446a12 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -113,7 +113,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+ [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
@@ -311,7 +311,7 @@ int drm_init(struct drm_driver *driver,
}
if (!drm_fb_loaded)
- pci_register_driver(&driver->pci_driver);
+ return pci_register_driver(&driver->pci_driver);
else {
for (i = 0; pciidlist[i].vendor != 0; i++) {
pid = &pciidlist[i];
diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c
index b5fc2235..5215feb6 100644
--- a/linux-core/drm_fence.c
+++ b/linux-core/drm_fence.c
@@ -124,56 +124,76 @@ static void drm_fence_unring(drm_device_t * dev, struct list_head *ring)
write_unlock_irqrestore(&fm->lock, flags);
}
-void drm_fence_usage_deref_locked(drm_device_t * dev,
- drm_fence_object_t * fence)
+void drm_fence_usage_deref_locked(drm_fence_object_t ** fence)
{
+ struct drm_fence_object *tmp_fence = *fence;
+ struct drm_device *dev = tmp_fence->dev;
drm_fence_manager_t *fm = &dev->fm;
DRM_ASSERT_LOCKED(&dev->struct_mutex);
-
- if (atomic_dec_and_test(&fence->usage)) {
- drm_fence_unring(dev, &fence->ring);
+ *fence = NULL;
+ if (atomic_dec_and_test(&tmp_fence->usage)) {
+ drm_fence_unring(dev, &tmp_fence->ring);
DRM_DEBUG("Destroyed a fence object 0x%08lx\n",
- fence->base.hash.key);
+ tmp_fence->base.hash.key);
atomic_dec(&fm->count);
- BUG_ON(!list_empty(&fence->base.list));
- drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE);
+ BUG_ON(!list_empty(&tmp_fence->base.list));
+ drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
}
}
-void drm_fence_usage_deref_unlocked(drm_device_t * dev,
- drm_fence_object_t * fence)
+void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence)
{
+ struct drm_fence_object *tmp_fence = *fence;
+ struct drm_device *dev = tmp_fence->dev;
drm_fence_manager_t *fm = &dev->fm;
- if (atomic_dec_and_test(&fence->usage)) {
+ *fence = NULL;
+ if (atomic_dec_and_test(&tmp_fence->usage)) {
mutex_lock(&dev->struct_mutex);
- if (atomic_read(&fence->usage) == 0) {
- drm_fence_unring(dev, &fence->ring);
+ if (atomic_read(&tmp_fence->usage) == 0) {
+ drm_fence_unring(dev, &tmp_fence->ring);
atomic_dec(&fm->count);
- BUG_ON(!list_empty(&fence->base.list));
- drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE);
+ BUG_ON(!list_empty(&tmp_fence->base.list));
+ drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
}
mutex_unlock(&dev->struct_mutex);
}
}
-static void drm_fence_object_destroy(drm_file_t * priv,
- drm_user_object_t * base)
+struct drm_fence_object
+*drm_fence_reference_locked(struct drm_fence_object *src)
+{
+ DRM_ASSERT_LOCKED(&src->dev->struct_mutex);
+
+ atomic_inc(&src->usage);
+ return src;
+}
+
+void drm_fence_reference_unlocked(struct drm_fence_object **dst,
+ struct drm_fence_object *src)
+{
+ mutex_lock(&src->dev->struct_mutex);
+ *dst = src;
+ atomic_inc(&src->usage);
+ mutex_unlock(&src->dev->struct_mutex);
+}
+
+
+static void drm_fence_object_destroy(drm_file_t *priv, drm_user_object_t * base)
{
- drm_device_t *dev = priv->head->dev;
drm_fence_object_t *fence =
drm_user_object_entry(base, drm_fence_object_t, base);
- drm_fence_usage_deref_locked(dev, fence);
+ drm_fence_usage_deref_locked(&fence);
}
-int drm_fence_object_signaled(drm_device_t * dev,
- drm_fence_object_t * fence,
- uint32_t mask, int poke_flush)
+int drm_fence_object_signaled(drm_fence_object_t * fence,
+ uint32_t mask, int poke_flush)
{
unsigned long flags;
int signaled;
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_driver_t *driver = dev->driver->fence_driver;
@@ -204,10 +224,10 @@ static void drm_fence_flush_exe(drm_fence_class_manager_t * fc,
}
}
-int drm_fence_object_flush(drm_device_t * dev,
- drm_fence_object_t * fence,
+int drm_fence_object_flush(drm_fence_object_t * fence,
uint32_t type)
{
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_class_manager_t *fc = &fm->class[fence->class];
drm_fence_driver_t *driver = dev->driver->fence_driver;
@@ -270,24 +290,23 @@ void drm_fence_flush_old(drm_device_t * dev, uint32_t class, uint32_t sequence)
mutex_unlock(&dev->struct_mutex);
return;
}
- fence = list_entry(fc->ring.next, drm_fence_object_t, ring);
- atomic_inc(&fence->usage);
+ fence = drm_fence_reference_locked(list_entry(fc->ring.next, drm_fence_object_t, ring));
mutex_unlock(&dev->struct_mutex);
diff = (old_sequence - fence->sequence) & driver->sequence_mask;
read_unlock_irqrestore(&fm->lock, flags);
if (diff < driver->wrap_diff) {
- drm_fence_object_flush(dev, fence, fence->type);
+ drm_fence_object_flush(fence, fence->type);
}
- drm_fence_usage_deref_unlocked(dev, fence);
+ drm_fence_usage_deref_unlocked(&fence);
}
EXPORT_SYMBOL(drm_fence_flush_old);
-static int drm_fence_lazy_wait(drm_device_t *dev,
- drm_fence_object_t *fence,
+static int drm_fence_lazy_wait(drm_fence_object_t *fence,
int ignore_signals,
uint32_t mask)
{
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_class_manager_t *fc = &fm->class[fence->class];
int signaled;
@@ -296,13 +315,13 @@ static int drm_fence_lazy_wait(drm_device_t *dev,
do {
DRM_WAIT_ON(ret, fc->fence_queue, 3 * DRM_HZ,
- (signaled = drm_fence_object_signaled(dev, fence, mask, 1)));
+ (signaled = drm_fence_object_signaled(fence, mask, 1)));
if (signaled)
return 0;
if (time_after_eq(jiffies, _end))
break;
} while (ret == -EINTR && ignore_signals);
- if (drm_fence_object_signaled(dev, fence, mask, 0))
+ if (drm_fence_object_signaled(fence, mask, 0))
return 0;
if (time_after_eq(jiffies, _end))
ret = -EBUSY;
@@ -317,10 +336,10 @@ static int drm_fence_lazy_wait(drm_device_t *dev,
return 0;
}
-int drm_fence_object_wait(drm_device_t * dev,
- drm_fence_object_t * fence,
+int drm_fence_object_wait(drm_fence_object_t * fence,
int lazy, int ignore_signals, uint32_t mask)
{
+ struct drm_device *dev = fence->dev;
drm_fence_driver_t *driver = dev->driver->fence_driver;
int ret = 0;
unsigned long _end;
@@ -332,16 +351,16 @@ int drm_fence_object_wait(drm_device_t * dev,
return -EINVAL;
}
- if (drm_fence_object_signaled(dev, fence, mask, 0))
+ if (drm_fence_object_signaled(fence, mask, 0))
return 0;
_end = jiffies + 3 * DRM_HZ;
- drm_fence_object_flush(dev, fence, mask);
+ drm_fence_object_flush(fence, mask);
if (lazy && driver->lazy_capable) {
- ret = drm_fence_lazy_wait(dev, fence, ignore_signals, mask);
+ ret = drm_fence_lazy_wait(fence, ignore_signals, mask);
if (ret)
return ret;
@@ -349,7 +368,7 @@ int drm_fence_object_wait(drm_device_t * dev,
if (driver->has_irq(dev, fence->class,
DRM_FENCE_TYPE_EXE)) {
- ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+ ret = drm_fence_lazy_wait(fence, ignore_signals,
DRM_FENCE_TYPE_EXE);
if (ret)
return ret;
@@ -357,13 +376,13 @@ int drm_fence_object_wait(drm_device_t * dev,
if (driver->has_irq(dev, fence->class,
mask & ~DRM_FENCE_TYPE_EXE)) {
- ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+ ret = drm_fence_lazy_wait(fence, ignore_signals,
mask);
if (ret)
return ret;
}
}
- if (drm_fence_object_signaled(dev, fence, mask, 0))
+ if (drm_fence_object_signaled(fence, mask, 0))
return 0;
/*
@@ -375,7 +394,7 @@ int drm_fence_object_wait(drm_device_t * dev,
#endif
do {
schedule();
- signaled = drm_fence_object_signaled(dev, fence, mask, 1);
+ signaled = drm_fence_object_signaled(fence, mask, 1);
} while (!signaled && !time_after_eq(jiffies, _end));
if (!signaled)
@@ -384,9 +403,10 @@ int drm_fence_object_wait(drm_device_t * dev,
return 0;
}
-int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
+int drm_fence_object_emit(drm_fence_object_t * fence,
uint32_t fence_flags, uint32_t class, uint32_t type)
{
+ struct drm_device *dev = fence->dev;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_driver_t *driver = dev->driver->fence_driver;
drm_fence_class_manager_t *fc = &fm->class[fence->class];
@@ -430,15 +450,22 @@ static int drm_fence_object_init(drm_device_t * dev, uint32_t class,
write_lock_irqsave(&fm->lock, flags);
INIT_LIST_HEAD(&fence->ring);
+
+ /*
+ * Avoid hitting BUG() for kernel-only fence objects.
+ */
+
+ INIT_LIST_HEAD(&fence->base.list);
fence->class = class;
fence->type = type;
fence->flush_mask = 0;
fence->submitted_flush = 0;
fence->signaled = 0;
fence->sequence = 0;
+ fence->dev = dev;
write_unlock_irqrestore(&fm->lock, flags);
if (fence_flags & DRM_FENCE_FLAG_EMIT) {
- ret = drm_fence_object_emit(dev, fence, fence_flags,
+ ret = drm_fence_object_emit(fence, fence_flags,
fence->class, type);
}
return ret;
@@ -476,7 +503,7 @@ int drm_fence_object_create(drm_device_t * dev, uint32_t class, uint32_t type,
return -ENOMEM;
ret = drm_fence_object_init(dev, class, type, flags, fence);
if (ret) {
- drm_fence_usage_deref_unlocked(dev, fence);
+ drm_fence_usage_deref_unlocked(&fence);
return ret;
}
*c_fence = fence;
@@ -533,8 +560,7 @@ drm_fence_object_t *drm_lookup_fence_object(drm_file_t * priv, uint32_t handle)
mutex_unlock(&dev->struct_mutex);
return NULL;
}
- fence = drm_user_object_entry(uo, drm_fence_object_t, base);
- atomic_inc(&fence->usage);
+ fence = drm_fence_reference_locked(drm_user_object_entry(uo, drm_fence_object_t, base));
mutex_unlock(&dev->struct_mutex);
return fence;
}
@@ -568,7 +594,7 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
arg.flags &
DRM_FENCE_FLAG_SHAREABLE);
if (ret) {
- drm_fence_usage_deref_unlocked(dev, fence);
+ drm_fence_usage_deref_unlocked(&fence);
return ret;
}
arg.handle = fence->base.hash.key;
@@ -603,14 +629,14 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
fence = drm_lookup_fence_object(priv, arg.handle);
if (!fence)
return -EINVAL;
- ret = drm_fence_object_flush(dev, fence, arg.type);
+ ret = drm_fence_object_flush(fence, arg.type);
break;
case drm_fence_wait:
fence = drm_lookup_fence_object(priv, arg.handle);
if (!fence)
return -EINVAL;
ret =
- drm_fence_object_wait(dev, fence,
+ drm_fence_object_wait(fence,
arg.flags & DRM_FENCE_FLAG_WAIT_LAZY,
0, arg.type);
break;
@@ -619,7 +645,7 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
fence = drm_lookup_fence_object(priv, arg.handle);
if (!fence)
return -EINVAL;
- ret = drm_fence_object_emit(dev, fence, arg.flags, arg.class,
+ ret = drm_fence_object_emit(fence, arg.flags, arg.class,
arg.type);
break;
case drm_fence_buffers:
@@ -647,7 +673,7 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS)
arg.type = fence->type;
arg.signaled = fence->signaled;
read_unlock_irqrestore(&fm->lock, flags);
- drm_fence_usage_deref_unlocked(dev, fence);
+ drm_fence_usage_deref_unlocked(&fence);
DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
return ret;
diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h
index 59c8902d..f82d6628 100644
--- a/linux-core/drm_objects.h
+++ b/linux-core/drm_objects.h
@@ -141,6 +141,7 @@ extern int drm_user_object_unref(drm_file_t * priv, uint32_t user_token,
typedef struct drm_fence_object {
drm_user_object_t base;
+ struct drm_device *dev;
atomic_t usage;
/*
@@ -196,17 +197,15 @@ extern void drm_fence_manager_init(struct drm_device *dev);
extern void drm_fence_manager_takedown(struct drm_device *dev);
extern void drm_fence_flush_old(struct drm_device *dev, uint32_t class,
uint32_t sequence);
-extern int drm_fence_object_flush(struct drm_device *dev,
- drm_fence_object_t * fence, uint32_t type);
-extern int drm_fence_object_signaled(struct drm_device *dev,
- drm_fence_object_t * fence,
+extern int drm_fence_object_flush(drm_fence_object_t * fence, uint32_t type);
+extern int drm_fence_object_signaled(drm_fence_object_t * fence,
uint32_t type, int flush);
-extern void drm_fence_usage_deref_locked(struct drm_device *dev,
- drm_fence_object_t * fence);
-extern void drm_fence_usage_deref_unlocked(struct drm_device *dev,
- drm_fence_object_t * fence);
-extern int drm_fence_object_wait(struct drm_device *dev,
- drm_fence_object_t * fence,
+extern void drm_fence_usage_deref_locked(drm_fence_object_t ** fence);
+extern void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence);
+extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src);
+extern void drm_fence_reference_unlocked(struct drm_fence_object **dst,
+ struct drm_fence_object *src);
+extern int drm_fence_object_wait(drm_fence_object_t * fence,
int lazy, int ignore_signals, uint32_t mask);
extern int drm_fence_object_create(struct drm_device *dev, uint32_t type,
uint32_t fence_flags, uint32_t class,
@@ -441,7 +440,7 @@ extern int drm_bo_pci_offset(struct drm_device *dev,
unsigned long *bus_size);
extern int drm_mem_reg_is_pci(struct drm_device *dev, drm_bo_mem_reg_t * mem);
-extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo);
+extern void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo);
extern int drm_fence_buffer_objects(drm_file_t * priv,
struct list_head *list,
uint32_t fence_flags,
diff --git a/linux-core/drm_scatter.c b/linux-core/drm_scatter.c
index e5c9f877..c0d6db24 100644
--- a/linux-core/drm_scatter.c
+++ b/linux-core/drm_scatter.c
@@ -55,6 +55,7 @@ void drm_sg_cleanup(drm_sg_mem_t * entry)
entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES);
drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
}
+EXPORT_SYMBOL(drm_sg_cleanup);
#ifdef _LP64
# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1)))
@@ -62,13 +63,8 @@ void drm_sg_cleanup(drm_sg_mem_t * entry)
# define ScatterHandle(x) (unsigned int)(x)
#endif
-int drm_sg_alloc(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_scatter_gather_t __user *argp = (void __user *)arg;
- drm_scatter_gather_t request;
drm_sg_mem_t *entry;
unsigned long pages, i, j;
@@ -80,17 +76,13 @@ int drm_sg_alloc(struct inode *inode, struct file *filp,
if (dev->sg)
return -EINVAL;
- if (copy_from_user(&request, argp, sizeof(request)))
- return -EFAULT;
-
entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS);
if (!entry)
return -ENOMEM;
memset(entry, 0, sizeof(*entry));
-
- pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
- DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages);
+ pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
+ DRM_DEBUG("sg size=%ld pages=%ld\n", request->size, pages);
entry->pages = pages;
entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist),
@@ -142,12 +134,7 @@ int drm_sg_alloc(struct inode *inode, struct file *filp,
SetPageReserved(entry->pagelist[j]);
}
- request.handle = entry->handle;
-
- if (copy_to_user(argp, &request, sizeof(request))) {
- drm_sg_cleanup(entry);
- return -EFAULT;
- }
+ request->handle = entry->handle;
dev->sg = entry;
@@ -196,6 +183,32 @@ int drm_sg_alloc(struct inode *inode, struct file *filp,
failed:
drm_sg_cleanup(entry);
return -ENOMEM;
+
+}
+EXPORT_SYMBOL(drm_sg_alloc);
+
+int drm_sg_alloc_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_scatter_gather_t __user *argp = (void __user *)arg;
+ drm_scatter_gather_t request;
+ int ret;
+
+ if (copy_from_user(&request, argp, sizeof(request)))
+ return -EFAULT;
+
+ ret = drm_sg_alloc(priv->head->dev, &request);
+ if ( ret ) return ret;
+
+ if (copy_to_user(argp, &request, sizeof(request))) {
+ drm_sg_cleanup(priv->head->dev->sg);
+ return -EFAULT;
+ }
+
+
+ return 0;
+
}
int drm_sg_free(struct inode *inode, struct file *filp,
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
index f57ed9cc..b96408ab 100644
--- a/linux-core/drm_stub.c
+++ b/linux-core/drm_stub.c
@@ -232,18 +232,22 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
if (!drm_fb_loaded) {
pci_set_drvdata(pdev, dev);
- pci_request_regions(pdev, driver->pci_driver.name);
+ ret = pci_request_regions(pdev, driver->pci_driver.name);
+ if (ret)
+ goto err_g1;
}
- pci_enable_device(pdev);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ goto err_g2;
pci_set_master(pdev);
if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
printk(KERN_ERR "DRM: fill_in_dev failed\n");
- goto err_g1;
+ goto err_g3;
}
if ((ret = drm_get_head(dev, &dev->primary)))
- goto err_g1;
+ goto err_g3;
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
@@ -251,12 +255,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
return 0;
-err_g1:
- if (!drm_fb_loaded) {
- pci_set_drvdata(pdev, NULL);
- pci_release_regions(pdev);
+ err_g3:
+ if (!drm_fb_loaded)
pci_disable_device(pdev);
- }
+ err_g2:
+ if (!drm_fb_loaded)
+ pci_release_regions(pdev);
+ err_g1:
+ if (!drm_fb_loaded)
+ pci_set_drvdata(pdev, NULL);
+
drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
printk(KERN_ERR "DRM: drm_get_dev failed.\n");
return ret;
diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c
index ace0778b..9b2f5dce 100644
--- a/linux-core/drm_sysfs.c
+++ b/linux-core/drm_sysfs.c
@@ -93,11 +93,15 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
retval = class_register(&cs->class);
if (retval)
goto error;
- class_create_file(&cs->class, &class_attr_version);
+ retval = class_create_file(&cs->class, &class_attr_version);
+ if (retval)
+ goto error_with_class;
return cs;
- error:
+ error_with_class:
+ class_unregister(&cs->class);
+ error:
kfree(cs);
return ERR_PTR(retval);
}
@@ -170,16 +174,31 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
if (retval)
goto error;
- class_device_create_file(&s_dev->class_dev, &cs->attr);
+ retval = class_device_create_file(&s_dev->class_dev, &cs->attr);
+ if (retval)
+ goto error_with_device;
+
class_set_devdata(&s_dev->class_dev, head);
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+ retval = class_device_create_file(&s_dev->class_dev,
+ &class_device_attrs[i]);
+ if (retval)
+ goto error_with_files;
+ }
return &s_dev->class_dev;
-error:
+ error_with_files:
+ while (i > 0)
+ class_device_remove_file(&s_dev->class_dev,
+ &class_device_attrs[--i]);
+ class_device_remove_file(&s_dev->class_dev, &cs->attr);
+ error_with_device:
+ class_device_unregister(&s_dev->class_dev);
+ error:
kfree(s_dev);
+
return ERR_PTR(retval);
}
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index f2c43508..72d63c10 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -840,7 +840,8 @@ static void drm_bo_vm_close(struct vm_area_struct *vma)
#ifdef DRM_ODD_MM_COMPAT
drm_bo_delete_vma(bo, vma);
#endif
- drm_bo_usage_deref_locked(bo);
+ drm_bo_usage_deref_locked((struct drm_buffer_object **)
+ &vma->vm_private_data);
mutex_unlock(&dev->struct_mutex);
}
return;
diff --git a/linux-core/nouveau_notifier.c b/linux-core/nouveau_notifier.c
new file mode 120000
index 00000000..285469c5
--- /dev/null
+++ b/linux-core/nouveau_notifier.c
@@ -0,0 +1 @@
+../shared-core/nouveau_notifier.c \ No newline at end of file
diff --git a/linux-core/nv04_fifo.c b/linux-core/nv04_fifo.c
new file mode 120000
index 00000000..d10beb19
--- /dev/null
+++ b/linux-core/nv04_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv04_fifo.c \ No newline at end of file
diff --git a/linux-core/nv04_instmem.c b/linux-core/nv04_instmem.c
new file mode 120000
index 00000000..e720fb5b
--- /dev/null
+++ b/linux-core/nv04_instmem.c
@@ -0,0 +1 @@
+../shared-core/nv04_instmem.c \ No newline at end of file
diff --git a/linux-core/nv10_fifo.c b/linux-core/nv10_fifo.c
new file mode 120000
index 00000000..8630ad04
--- /dev/null
+++ b/linux-core/nv10_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv10_fifo.c \ No newline at end of file
diff --git a/linux-core/nv40_fifo.c b/linux-core/nv40_fifo.c
new file mode 120000
index 00000000..cc71e7a4
--- /dev/null
+++ b/linux-core/nv40_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv40_fifo.c \ No newline at end of file
diff --git a/linux-core/nv50_fifo.c b/linux-core/nv50_fifo.c
new file mode 120000
index 00000000..4c9990a9
--- /dev/null
+++ b/linux-core/nv50_fifo.c
@@ -0,0 +1 @@
+../shared-core/nv50_fifo.c \ No newline at end of file
diff --git a/linux-core/nv50_graph.c b/linux-core/nv50_graph.c
new file mode 120000
index 00000000..03f69e68
--- /dev/null
+++ b/linux-core/nv50_graph.c
@@ -0,0 +1 @@
+../shared-core/nv50_graph.c \ No newline at end of file
diff --git a/linux-core/nv50_instmem.c b/linux-core/nv50_instmem.c
new file mode 120000
index 00000000..4e45344a
--- /dev/null
+++ b/linux-core/nv50_instmem.c
@@ -0,0 +1 @@
+../shared-core/nv50_instmem.c \ No newline at end of file
diff --git a/linux-core/nv50_mc.c b/linux-core/nv50_mc.c
new file mode 120000
index 00000000..f4bb369e
--- /dev/null
+++ b/linux-core/nv50_mc.c
@@ -0,0 +1 @@
+../shared-core/nv50_mc.c \ No newline at end of file