diff options
author | =?utf-8?q?Michel_D=C3=A4nzer?= <michel@tungstengraphics.com> | 2006-10-24 10:08:23 -0400 |
---|---|---|
committer | airlied <airlied@linux.ie> | 2006-12-06 23:53:30 -0500 |
commit | 5b51694aff705c465ef5941a99073036f3e444d9 (patch) | |
tree | 8e5e6b97696da7c23de2e9f9df0ffbc1660d9f49 /drivers/char/drm/i915_irq.c | |
parent | 541f29aad766b6c7b911a7d900d952744369bf53 (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/drm/i915_irq.c')
-rw-r--r-- | drivers/char/drm/i915_irq.c | 22 |
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 | ||
307 | static int i915_enable_interrupt (drm_device_t *dev) | 307 | static 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 | ||
346 | int i915_vblank_pipe_get(DRM_IOCTL_ARGS) | 350 | int 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 | } |