aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
author=?utf-8?q?Michel_D=C3=A4nzer?= <michel@tungstengraphics.com>2006-10-24 10:08:23 -0400
committerairlied <airlied@linux.ie>2006-12-06 23:53:30 -0500
commit5b51694aff705c465ef5941a99073036f3e444d9 (patch)
tree8e5e6b97696da7c23de2e9f9df0ffbc1660d9f49 /drivers/char
parent541f29aad766b6c7b911a7d900d952744369bf53 (diff)
drm: Make handling of dev_priv->vblank_pipe more robust.
Initialize it to default value if it hasn't been set by the X server yet. In i915_vblank_pipe_set(), only update dev_priv->vblank_pipe and call i915_enable_interrupt() if the argument passed from userspace is valid to avoid corrupting dev_priv->vblank_pipe on invalid arguments. Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/drm/i915_irq.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index d56455666312..e9e46c41bf36 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -304,7 +304,7 @@ int i915_irq_wait(DRM_IOCTL_ARGS)
304 return i915_wait_irq(dev, irqwait.irq_seq); 304 return i915_wait_irq(dev, irqwait.irq_seq);
305} 305}
306 306
307static int i915_enable_interrupt (drm_device_t *dev) 307static void i915_enable_interrupt (drm_device_t *dev)
308{ 308{
309 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 309 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
310 u16 flag; 310 u16 flag;
@@ -314,13 +314,8 @@ static int i915_enable_interrupt (drm_device_t *dev)
314 flag |= VSYNC_PIPEA_FLAG; 314 flag |= VSYNC_PIPEA_FLAG;
315 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) 315 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
316 flag |= VSYNC_PIPEB_FLAG; 316 flag |= VSYNC_PIPEB_FLAG;
317 if (dev_priv->vblank_pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) { 317
318 DRM_ERROR("%s called with invalid pipe 0x%x\n",
319 __FUNCTION__, dev_priv->vblank_pipe);
320 return DRM_ERR(EINVAL);
321 }
322 I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); 318 I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
323 return 0;
324} 319}
325 320
326/* Set the vblank monitor pipe 321/* Set the vblank monitor pipe
@@ -339,8 +334,17 @@ int i915_vblank_pipe_set(DRM_IOCTL_ARGS)
339 DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data, 334 DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data,
340 sizeof(pipe)); 335 sizeof(pipe));
341 336
337 if (pipe.pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
338 DRM_ERROR("%s called with invalid pipe 0x%x\n",
339 __FUNCTION__, pipe.pipe);
340 return DRM_ERR(EINVAL);
341 }
342
342 dev_priv->vblank_pipe = pipe.pipe; 343 dev_priv->vblank_pipe = pipe.pipe;
343 return i915_enable_interrupt (dev); 344
345 i915_enable_interrupt (dev);
346
347 return 0;
344} 348}
345 349
346int i915_vblank_pipe_get(DRM_IOCTL_ARGS) 350int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
@@ -502,6 +506,8 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
502 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); 506 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
503 dev_priv->swaps_pending = 0; 507 dev_priv->swaps_pending = 0;
504 508
509 if (!dev_priv->vblank_pipe)
510 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
505 i915_enable_interrupt(dev); 511 i915_enable_interrupt(dev);
506 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); 512 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
507} 513}