drm/vmwgfx: Allow userspace to change default layout. Bump minor.
[safe/jmp/linux-2.6] / drivers / gpu / drm / vmwgfx / vmwgfx_kms.c
index 648ba04..f1d6261 100644 (file)
@@ -938,3 +938,48 @@ int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
 
        return 0;
 }
+
+int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv)
+{
+       struct vmw_private *dev_priv = vmw_priv(dev);
+       struct drm_vmw_update_layout_arg *arg =
+               (struct drm_vmw_update_layout_arg *)data;
+       struct vmw_master *vmaster = vmw_master(file_priv->master);
+       void __user *user_rects;
+       struct drm_vmw_rect *rects;
+       unsigned rects_size;
+       int ret;
+
+       ret = ttm_read_lock(&vmaster->lock, true);
+       if (unlikely(ret != 0))
+               return ret;
+
+       if (!arg->num_outputs) {
+               struct drm_vmw_rect def_rect = {0, 0, 800, 600};
+               vmw_kms_ldu_update_layout(dev_priv, 1, &def_rect);
+               goto out_unlock;
+       }
+
+       rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
+       rects = kzalloc(rects_size, GFP_KERNEL);
+       if (unlikely(!rects)) {
+               ret = -ENOMEM;
+               goto out_unlock;
+       }
+
+       user_rects = (void __user *)(unsigned long)arg->rects;
+       ret = copy_from_user(rects, user_rects, rects_size);
+       if (unlikely(ret != 0)) {
+               DRM_ERROR("Failed to get rects.\n");
+               goto out_free;
+       }
+
+       vmw_kms_ldu_update_layout(dev_priv, arg->num_outputs, rects);
+
+out_free:
+       kfree(rects);
+out_unlock:
+       ttm_read_unlock(&vmaster->lock);
+       return ret;
+}