Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 43915
b: refs/heads/master
c: 541f29a
h: refs/heads/master
i:
  43913: 189a3e4
  43911: bc9e90b
v: v3
  • Loading branch information
=?utf-8?q?Michel_D=C3=A4nzer?= authored and airlied committed Dec 7, 2006
1 parent 9d28291 commit e665490
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a6b54f3f5050c0cbc0c35dd48064846c6302706b
refs/heads/master: 541f29aad766b6c7b911a7d900d952744369bf53
3 changes: 2 additions & 1 deletion trunk/drivers/char/drm/i915_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)

/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
Expand Down Expand Up @@ -248,7 +249,7 @@ typedef struct drm_i915_vblank_pipe {
*/
typedef struct drm_i915_vblank_swap {
drm_drawable_t drawable;
unsigned int pipe;
drm_vblank_seq_type_t seqtype;
unsigned int sequence;
} drm_i915_vblank_swap_t;

Expand Down
43 changes: 38 additions & 5 deletions trunk/drivers/char/drm/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_vblank_swap_t swap;
drm_i915_vbl_swap_t *vbl_swap;
unsigned int irqflags;
unsigned int pipe, seqtype, irqflags, curseq;
struct list_head *list;

if (!dev_priv) {
Expand All @@ -396,8 +396,23 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
DRM_COPY_FROM_USER_IOCTL(swap, (drm_i915_vblank_swap_t __user *) data,
sizeof(swap));

if (swap.pipe > 1 || !(dev_priv->vblank_pipe & (1 << swap.pipe))) {
DRM_ERROR("Invalid pipe %d\n", swap.pipe);
if (swap.seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
_DRM_VBLANK_SECONDARY)) {
DRM_ERROR("Invalid sequence type 0x%x\n", swap.seqtype);
return DRM_ERR(EINVAL);
}

pipe = (swap.seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;

seqtype = swap.seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);

if (seqtype == _DRM_VBLANK_RELATIVE && swap.sequence == 0) {
DRM_DEBUG("Not scheduling swap for current sequence\n");
return DRM_ERR(EINVAL);
}

if (!(dev_priv->vblank_pipe & (1 << pipe))) {
DRM_ERROR("Invalid pipe %d\n", pipe);
return DRM_ERR(EINVAL);
}

Expand All @@ -411,13 +426,28 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)

spin_unlock_irqrestore(&dev->drw_lock, irqflags);

curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);

spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);

switch (seqtype) {
case _DRM_VBLANK_RELATIVE:
swap.sequence += curseq;
break;
case _DRM_VBLANK_ABSOLUTE:
if ((curseq - swap.sequence) > (1<<23)) {
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
DRM_DEBUG("Missed target sequence\n");
return DRM_ERR(EINVAL);
}
break;
}

list_for_each(list, &dev_priv->vbl_swaps.head) {
vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);

if (vbl_swap->drw_id == swap.drawable &&
vbl_swap->pipe == swap.pipe &&
vbl_swap->pipe == pipe &&
vbl_swap->sequence == swap.sequence) {
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
DRM_DEBUG("Already scheduled\n");
Expand All @@ -437,7 +467,7 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)
DRM_DEBUG("\n");

vbl_swap->drw_id = swap.drawable;
vbl_swap->pipe = swap.pipe;
vbl_swap->pipe = pipe;
vbl_swap->sequence = swap.sequence;

spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
Expand All @@ -447,6 +477,9 @@ int i915_vblank_swap(DRM_IOCTL_ARGS)

spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);

DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_swap_t __user *) data, swap,
sizeof(swap));

return 0;
}

Expand Down

0 comments on commit e665490

Please sign in to comment.