* instruction detected will be given a size of zero, which is a
  * signal to abort the rest of the buffer.
  */
-static int do_validate_cmd(int cmd)
+static int validate_cmd(int cmd)
 {
        switch (((cmd >> 29) & 0x7)) {
        case 0x0:
        return 0;
 }
 
-static int validate_cmd(int cmd)
-{
-       int ret = do_validate_cmd(cmd);
-
-/*     printk("validate_cmd( %x ): %d\n", cmd, ret); */
-
-       return ret;
-}
-
 static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       int i;
+       int i, ret;
 
        if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8)
                return -EINVAL;
 
-       BEGIN_LP_RING((dwords+1)&~1);
-
        for (i = 0; i < dwords;) {
-               int cmd, sz;
-
-               cmd = buffer[i];
-
-               if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
+               int sz = validate_cmd(buffer[i]);
+               if (sz == 0 || i + sz > dwords)
                        return -EINVAL;
-
-               OUT_RING(cmd);
-
-               while (++i, --sz) {
-                       OUT_RING(buffer[i]);
-               }
+               i += sz;
        }
 
+       ret = BEGIN_LP_RING((dwords+1)&~1);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < dwords; i++)
+               OUT_RING(buffer[i]);
        if (dwords & 1)
                OUT_RING(0);
 
              struct drm_clip_rect *boxes,
              int i, int DR1, int DR4)
 {
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_clip_rect box = boxes[i];
+       int ret;
 
        if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
                DRM_ERROR("Bad box %d,%d..%d,%d\n",
        }
 
        if (INTEL_INFO(dev)->gen >= 4) {
-               BEGIN_LP_RING(4);
+               ret = BEGIN_LP_RING(4);
+               if (ret)
+                       return ret;
+
                OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
                OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
                OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
                OUT_RING(DR4);
-               ADVANCE_LP_RING();
        } else {
-               BEGIN_LP_RING(6);
+               ret = BEGIN_LP_RING(6);
+               if (ret)
+                       return ret;
+
                OUT_RING(GFX_OP_DRAWRECT_INFO);
                OUT_RING(DR1);
                OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
                OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
                OUT_RING(DR4);
                OUT_RING(0);
-               ADVANCE_LP_RING();
        }
+       ADVANCE_LP_RING();
 
        return 0;
 }
        if (master_priv->sarea_priv)
                master_priv->sarea_priv->last_enqueue = dev_priv->counter;
 
-       BEGIN_LP_RING(4);
-       OUT_RING(MI_STORE_DWORD_INDEX);
-       OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-       OUT_RING(dev_priv->counter);
-       OUT_RING(0);
-       ADVANCE_LP_RING();
+       if (BEGIN_LP_RING(4) == 0) {
+               OUT_RING(MI_STORE_DWORD_INDEX);
+               OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               OUT_RING(dev_priv->counter);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       }
 }
 
 static int i915_dispatch_cmdbuffer(struct drm_device * dev,
                                     drm_i915_batchbuffer_t * batch,
                                     struct drm_clip_rect *cliprects)
 {
+       struct drm_i915_private *dev_priv = dev->dev_private;
        int nbox = batch->num_cliprects;
-       int i = 0, count;
+       int i, count, ret;
 
        if ((batch->start | batch->used) & 0x7) {
                DRM_ERROR("alignment");
        i915_kernel_lost_context(dev);
 
        count = nbox ? nbox : 1;
-
        for (i = 0; i < count; i++) {
                if (i < nbox) {
-                       int ret = i915_emit_box(dev, cliprects, i,
-                                               batch->DR1, batch->DR4);
+                       ret = i915_emit_box(dev, cliprects, i,
+                                           batch->DR1, batch->DR4);
                        if (ret)
                                return ret;
                }
 
                if (!IS_I830(dev) && !IS_845G(dev)) {
-                       BEGIN_LP_RING(2);
+                       ret = BEGIN_LP_RING(2);
+                       if (ret)
+                               return ret;
+
                        if (INTEL_INFO(dev)->gen >= 4) {
                                OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
                                OUT_RING(batch->start);
                                OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
                                OUT_RING(batch->start | MI_BATCH_NON_SECURE);
                        }
-                       ADVANCE_LP_RING();
                } else {
-                       BEGIN_LP_RING(4);
+                       ret = BEGIN_LP_RING(4);
+                       if (ret)
+                               return ret;
+
                        OUT_RING(MI_BATCH_BUFFER);
                        OUT_RING(batch->start | MI_BATCH_NON_SECURE);
                        OUT_RING(batch->start + batch->used - 4);
                        OUT_RING(0);
-                       ADVANCE_LP_RING();
                }
+               ADVANCE_LP_RING();
        }
 
 
        if (IS_G4X(dev) || IS_GEN5(dev)) {
-               BEGIN_LP_RING(2);
-               OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP);
-               OUT_RING(MI_NOOP);
-               ADVANCE_LP_RING();
+               if (BEGIN_LP_RING(2) == 0) {
+                       OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP);
+                       OUT_RING(MI_NOOP);
+                       ADVANCE_LP_RING();
+               }
        }
-       i915_emit_breadcrumb(dev);
 
+       i915_emit_breadcrumb(dev);
        return 0;
 }
 
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv =
                dev->primary->master->driver_priv;
+       int ret;
 
        if (!master_priv->sarea_priv)
                return -EINVAL;
 
        i915_kernel_lost_context(dev);
 
-       BEGIN_LP_RING(2);
+       ret = BEGIN_LP_RING(10);
+       if (ret)
+               return ret;
+
        OUT_RING(MI_FLUSH | MI_READ_FLUSH);
        OUT_RING(0);
-       ADVANCE_LP_RING();
 
-       BEGIN_LP_RING(6);
        OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
        OUT_RING(0);
        if (dev_priv->current_page == 0) {
                dev_priv->current_page = 0;
        }
        OUT_RING(0);
-       ADVANCE_LP_RING();
 
-       BEGIN_LP_RING(2);
        OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
        OUT_RING(0);
+
        ADVANCE_LP_RING();
 
        master_priv->sarea_priv->last_enqueue = dev_priv->counter++;
 
-       BEGIN_LP_RING(4);
-       OUT_RING(MI_STORE_DWORD_INDEX);
-       OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-       OUT_RING(dev_priv->counter);
-       OUT_RING(0);
-       ADVANCE_LP_RING();
+       if (BEGIN_LP_RING(4) == 0) {
+               OUT_RING(MI_STORE_DWORD_INDEX);
+               OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               OUT_RING(dev_priv->counter);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       }
 
        master_priv->sarea_priv->pf_current_page = dev_priv->current_page;
        return 0;
 
 #if WATCH_EXEC
                DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
 #endif
-               intel_ring_begin(ring, 2);
-               intel_ring_emit(ring, cmd);
-               intel_ring_emit(ring, MI_NOOP);
-               intel_ring_advance(ring);
+               if (intel_ring_begin(ring, 2) == 0) {
+                       intel_ring_emit(ring, cmd);
+                       intel_ring_emit(ring, MI_NOOP);
+                       intel_ring_advance(ring);
+               }
        }
 }
 
        seqno = i915_gem_get_seqno(dev);
 
        if (IS_GEN6(dev)) {
-               intel_ring_begin(ring, 6);
-               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3);
-               intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE |
-                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
-                        PIPE_CONTROL_NOTIFY);
-               intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-               intel_ring_emit(ring, seqno);
-               intel_ring_emit(ring, 0);
-               intel_ring_emit(ring, 0);
-               intel_ring_advance(ring);
+               if (intel_ring_begin(ring, 6) == 0) {
+                       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3);
+                       intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE |
+                                       PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
+                                       PIPE_CONTROL_NOTIFY);
+                       intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+                       intel_ring_emit(ring, seqno);
+                       intel_ring_emit(ring, 0);
+                       intel_ring_emit(ring, 0);
+                       intel_ring_advance(ring);
+               }
        } else if (HAS_PIPE_CONTROL(dev)) {
                u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
 
                 * PIPE_NOTIFY buffers out to memory before requesting
                 * an interrupt.
                 */
-               intel_ring_begin(ring, 32);
-               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
-               intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-               intel_ring_emit(ring, seqno);
-               intel_ring_emit(ring, 0);
-               PIPE_CONTROL_FLUSH(ring, scratch_addr);
-               scratch_addr += 128; /* write to separate cachelines */
-               PIPE_CONTROL_FLUSH(ring, scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(ring, scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(ring, scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(ring, scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(ring, scratch_addr);
-               intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
-                        PIPE_CONTROL_NOTIFY);
-               intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-               intel_ring_emit(ring, seqno);
-               intel_ring_emit(ring, 0);
-               intel_ring_advance(ring);
+               if (intel_ring_begin(ring, 32) == 0) {
+                       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                                       PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
+                       intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+                       intel_ring_emit(ring, seqno);
+                       intel_ring_emit(ring, 0);
+                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
+                       scratch_addr += 128; /* write to separate cachelines */
+                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(ring, scratch_addr);
+                       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                                       PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+                                       PIPE_CONTROL_NOTIFY);
+                       intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+                       intel_ring_emit(ring, seqno);
+                       intel_ring_emit(ring, 0);
+                       intel_ring_advance(ring);
+               }
        } else {
-               intel_ring_begin(ring, 4);
-               intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
-               intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-               intel_ring_emit(ring, seqno);
+               if (intel_ring_begin(ring, 4) == 0) {
+                       intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
+                       intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+                       intel_ring_emit(ring, seqno);
 
-               intel_ring_emit(ring, MI_USER_INTERRUPT);
-               intel_ring_advance(ring);
+                       intel_ring_emit(ring, MI_USER_INTERRUPT);
+                       intel_ring_advance(ring);
+               }
        }
        return seqno;
 }
               u32     invalidate_domains,
               u32     flush_domains)
 {
-       intel_ring_begin(ring, 2);
-       intel_ring_emit(ring, MI_FLUSH);
-       intel_ring_emit(ring, MI_NOOP);
-       intel_ring_advance(ring);
+       if (intel_ring_begin(ring, 2) == 0) {
+               intel_ring_emit(ring, MI_FLUSH);
+               intel_ring_emit(ring, MI_NOOP);
+               intel_ring_advance(ring);
+       }
 }
 
 static u32
 
        seqno = i915_gem_get_seqno(ring->dev);
 
-       intel_ring_begin(ring, 4);
-       intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
-       intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-       intel_ring_emit(ring, seqno);
-       intel_ring_emit(ring, MI_USER_INTERRUPT);
-       intel_ring_advance(ring);
+       if (intel_ring_begin(ring, 4) == 0) {
+               intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
+               intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               intel_ring_emit(ring, seqno);
+               intel_ring_emit(ring, MI_USER_INTERRUPT);
+               intel_ring_advance(ring);
+       }
 
        DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
 
                         uint64_t exec_offset)
 {
        uint32_t exec_start;
+       int ret;
 
        exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
 
-       intel_ring_begin(ring, 2);
+       ret = intel_ring_begin(ring, 2);
+       if (ret)
+               return ret;
+
        intel_ring_emit(ring,
                        MI_BATCH_BUFFER_START |
                        (2 << 6) |
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        int nbox = exec->num_cliprects;
-       int i = 0, count;
        uint32_t exec_start, exec_len;
+       int i, count, ret;
 
        exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
        exec_len = (uint32_t) exec->batch_len;
        trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1);
 
        count = nbox ? nbox : 1;
-
        for (i = 0; i < count; i++) {
                if (i < nbox) {
-                       int ret = i915_emit_box(dev, cliprects, i,
-                                               exec->DR1, exec->DR4);
+                       ret = i915_emit_box(dev, cliprects, i,
+                                           exec->DR1, exec->DR4);
                        if (ret)
                                return ret;
                }
 
                if (IS_I830(dev) || IS_845G(dev)) {
-                       intel_ring_begin(ring, 4);
+                       ret = intel_ring_begin(ring, 4);
+                       if (ret)
+                               return ret;
+
                        intel_ring_emit(ring, MI_BATCH_BUFFER);
                        intel_ring_emit(ring, exec_start | MI_BATCH_NON_SECURE);
                        intel_ring_emit(ring, exec_start + exec_len - 4);
                        intel_ring_emit(ring, 0);
                } else {
-                       intel_ring_begin(ring, 2);
+                       ret = intel_ring_begin(ring, 2);
+                       if (ret)
+                               return ret;
+
                        if (INTEL_INFO(dev)->gen >= 4) {
                                intel_ring_emit(ring,
                                                MI_BATCH_BUFFER_START | (2 << 6)
        }
 
        if (IS_G4X(dev) || IS_GEN5(dev)) {
-               intel_ring_begin(ring, 2);
-               intel_ring_emit(ring, MI_FLUSH |
-                               MI_NO_WRITE_FLUSH |
-                               MI_INVALIDATE_ISP );
-               intel_ring_emit(ring, MI_NOOP);
-               intel_ring_advance(ring);
+               if (intel_ring_begin(ring, 2) == 0) {
+                       intel_ring_emit(ring, MI_FLUSH |
+                                       MI_NO_WRITE_FLUSH |
+                                       MI_INVALIDATE_ISP );
+                       intel_ring_emit(ring, MI_NOOP);
+                       intel_ring_advance(ring);
+               }
        }
        /* XXX breadcrumb */
 
        return -EBUSY;
 }
 
-void intel_ring_begin(struct intel_ring_buffer *ring,
-                     int num_dwords)
+int intel_ring_begin(struct intel_ring_buffer *ring,
+                    int num_dwords)
 {
        int n = 4*num_dwords;
+       int ret;
 
-       if (unlikely(ring->tail + n > ring->size))
-               intel_wrap_ring_buffer(ring);
+       if (unlikely(ring->tail + n > ring->size)) {
+               ret = intel_wrap_ring_buffer(ring);
+               if (unlikely(ret))
+                       return ret;
+       }
 
-       if (unlikely(ring->space < n))
-               intel_wait_ring_buffer(ring, n);
+       if (unlikely(ring->space < n)) {
+               ret = intel_wait_ring_buffer(ring, n);
+               if (unlikely(ret))
+                       return ret;
+       }
 
        ring->space -= n;
+       return 0;
 }
 
 void intel_ring_advance(struct intel_ring_buffer *ring)
                            u32 invalidate_domains,
                            u32 flush_domains)
 {
-       intel_ring_begin(ring, 4);
-       intel_ring_emit(ring, MI_FLUSH_DW);
-       intel_ring_emit(ring, 0);
-       intel_ring_emit(ring, 0);
-       intel_ring_emit(ring, 0);
-       intel_ring_advance(ring);
+       if (intel_ring_begin(ring, 4) == 0) {
+               intel_ring_emit(ring, MI_FLUSH_DW);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_emit(ring, 0);
+               intel_ring_advance(ring);
+       }
 }
 
 static int
                              uint64_t exec_offset)
 {
        uint32_t exec_start;
+       int ret;
 
        exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
 
-       intel_ring_begin(ring, 2);
+       ret = intel_ring_begin(ring, 2);
+       if (ret)
+              return ret;
+
        intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965);
        /* bit0-7 is the length on GEN6+ */
        intel_ring_emit(ring, exec_start);