diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-10-27 07:45:26 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-10-27 18:26:34 -0400 |
commit | e1f99ce6cac3b6a95551642be5ddb5d9c46bea76 (patch) | |
tree | fb5152a582fc5b6c190287d9c90d57ca415d6f9d /drivers/gpu/drm/i915/intel_overlay.c | |
parent | 78501eac34f372bfbeb4e1d9de688c13efa916f6 (diff) |
drm/i915: Propagate errors from writing to ringbuffer
Preparing the ringbuffer for adding new commands can fail (a timeout
whilst waiting for the GPU to catch up and free some space). So check
for any potential error before overwriting HEAD with new commands, and
propagate that error back to the user where possible.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_overlay.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index afb96d25219a..78fa6a249964 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -289,6 +289,7 @@ i830_deactivate_pipe_a(struct drm_device *dev) | |||
289 | static int intel_overlay_on(struct intel_overlay *overlay) | 289 | static int intel_overlay_on(struct intel_overlay *overlay) |
290 | { | 290 | { |
291 | struct drm_device *dev = overlay->dev; | 291 | struct drm_device *dev = overlay->dev; |
292 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
292 | struct drm_i915_gem_request *request; | 293 | struct drm_i915_gem_request *request; |
293 | int pipe_a_quirk = 0; | 294 | int pipe_a_quirk = 0; |
294 | int ret; | 295 | int ret; |
@@ -308,7 +309,12 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
308 | goto out; | 309 | goto out; |
309 | } | 310 | } |
310 | 311 | ||
311 | BEGIN_LP_RING(4); | 312 | ret = BEGIN_LP_RING(4); |
313 | if (ret) { | ||
314 | kfree(request); | ||
315 | goto out; | ||
316 | } | ||
317 | |||
312 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); | 318 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); |
313 | OUT_RING(overlay->flip_addr | OFC_UPDATE); | 319 | OUT_RING(overlay->flip_addr | OFC_UPDATE); |
314 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 320 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
@@ -332,6 +338,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
332 | struct drm_i915_gem_request *request; | 338 | struct drm_i915_gem_request *request; |
333 | u32 flip_addr = overlay->flip_addr; | 339 | u32 flip_addr = overlay->flip_addr; |
334 | u32 tmp; | 340 | u32 tmp; |
341 | int ret; | ||
335 | 342 | ||
336 | BUG_ON(!overlay->active); | 343 | BUG_ON(!overlay->active); |
337 | 344 | ||
@@ -347,7 +354,11 @@ static int intel_overlay_continue(struct intel_overlay *overlay, | |||
347 | if (tmp & (1 << 17)) | 354 | if (tmp & (1 << 17)) |
348 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); | 355 | DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); |
349 | 356 | ||
350 | BEGIN_LP_RING(2); | 357 | ret = BEGIN_LP_RING(2); |
358 | if (ret) { | ||
359 | kfree(request); | ||
360 | return ret; | ||
361 | } | ||
351 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 362 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
352 | OUT_RING(flip_addr); | 363 | OUT_RING(flip_addr); |
353 | ADVANCE_LP_RING(); | 364 | ADVANCE_LP_RING(); |
@@ -389,8 +400,10 @@ static int intel_overlay_off(struct intel_overlay *overlay, | |||
389 | bool interruptible) | 400 | bool interruptible) |
390 | { | 401 | { |
391 | struct drm_device *dev = overlay->dev; | 402 | struct drm_device *dev = overlay->dev; |
403 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
392 | u32 flip_addr = overlay->flip_addr; | 404 | u32 flip_addr = overlay->flip_addr; |
393 | struct drm_i915_gem_request *request; | 405 | struct drm_i915_gem_request *request; |
406 | int ret; | ||
394 | 407 | ||
395 | BUG_ON(!overlay->active); | 408 | BUG_ON(!overlay->active); |
396 | 409 | ||
@@ -404,7 +417,11 @@ static int intel_overlay_off(struct intel_overlay *overlay, | |||
404 | * of the hw. Do it in both cases */ | 417 | * of the hw. Do it in both cases */ |
405 | flip_addr |= OFC_UPDATE; | 418 | flip_addr |= OFC_UPDATE; |
406 | 419 | ||
407 | BEGIN_LP_RING(6); | 420 | ret = BEGIN_LP_RING(6); |
421 | if (ret) { | ||
422 | kfree(request); | ||
423 | return ret; | ||
424 | } | ||
408 | /* wait for overlay to go idle */ | 425 | /* wait for overlay to go idle */ |
409 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 426 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
410 | OUT_RING(flip_addr); | 427 | OUT_RING(flip_addr); |
@@ -467,7 +484,12 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) | |||
467 | if (request == NULL) | 484 | if (request == NULL) |
468 | return -ENOMEM; | 485 | return -ENOMEM; |
469 | 486 | ||
470 | BEGIN_LP_RING(2); | 487 | ret = BEGIN_LP_RING(2); |
488 | if (ret) { | ||
489 | kfree(request); | ||
490 | return ret; | ||
491 | } | ||
492 | |||
471 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 493 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
472 | OUT_RING(MI_NOOP); | 494 | OUT_RING(MI_NOOP); |
473 | ADVANCE_LP_RING(); | 495 | ADVANCE_LP_RING(); |