Index: trunk/src/VBox/Additions/linux/drm/vbox_drv.h
===================================================================
--- trunk/src/VBox/Additions/linux/drm/vbox_drv.h	(revision 59640)
+++ trunk/src/VBox/Additions/linux/drm/vbox_drv.h	(revision 59697)
@@ -114,4 +114,5 @@
         struct ttm_bo_global_ref bo_global_ref;
         struct ttm_bo_device bdev;
+        bool mm_initialised;
     } ttm;
 
@@ -196,6 +197,8 @@
 #endif
 
-void vbox_enable_accel(struct vbox_private *vbox, unsigned crtc_id);
+void vbox_enable_accel(struct vbox_private *vbox);
+void vbox_disable_accel(struct vbox_private *vbox);
 void vbox_enable_caps(struct vbox_private *vbox);
+void vbox_disable_caps(struct vbox_private *vbox);
 
 void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb,
Index: trunk/src/VBox/Additions/linux/drm/vbox_fb.c
===================================================================
--- trunk/src/VBox/Additions/linux/drm/vbox_fb.c	(revision 59640)
+++ trunk/src/VBox/Additions/linux/drm/vbox_fb.c	(revision 59697)
@@ -82,5 +82,4 @@
     struct drm_device *dev;
     struct vbox_private *vbox;
-    unsigned i;
 
     LogFunc(("vboxvideo: %d\n", __LINE__));
@@ -88,7 +87,4 @@
     vbox = dev->dev_private;
     vbox_refresh_modes(dev);
-    for (i = 0; i < vbox->num_crtcs; ++i)
-        VBoxVBVADisable(&vbox->vbva_info[i], &vbox->submit_info, i);
-    VBoxHGSMISendCapsInfo(&vbox->submit_info, 0);
     return drm_fb_helper_set_par(info);
 }
@@ -448,4 +444,5 @@
 free:
     kfree(fbdev);
+    vbox->fbdev = NULL;
     LogFunc(("vboxvideo: %d, ret=%d\n", __LINE__, ret));
     return ret;
Index: trunk/src/VBox/Additions/linux/drm/vbox_main.c
===================================================================
--- trunk/src/VBox/Additions/linux/drm/vbox_main.c	(revision 59640)
+++ trunk/src/VBox/Additions/linux/drm/vbox_main.c	(revision 59697)
@@ -66,16 +66,28 @@
 }
 
-void vbox_enable_accel(struct vbox_private *vbox, unsigned crtc_id)
-{
-    struct VBVABUFFER *vbva = vbox->vbva_info[crtc_id].pVBVA;
-
-    if (vbva == NULL) {
-        LogFunc(("vboxvideo: enabling VBVA.\n"));
-        vbva = (struct VBVABUFFER *) (  ((uint8_t *)vbox->vram)
-                                       + vbox->vram_size
-                                       + crtc_id * VBVA_MIN_BUFFER_SIZE);
-        if (!VBoxVBVAEnable(&vbox->vbva_info[crtc_id], &vbox->submit_info, vbva, crtc_id))
-            AssertReleaseMsgFailed(("VBoxVBVAEnable failed - heap allocation error, very old host or driver error.\n"));
-    }
+void vbox_enable_accel(struct vbox_private *vbox)
+{
+    unsigned i;
+    struct VBVABUFFER *vbva;
+
+    AssertLogRelReturnVoid(vbox->vbva_info != NULL);
+    for (i = 0; i < vbox->num_crtcs; ++i) {
+        if (vbox->vbva_info[i].pVBVA == NULL) {
+            LogFunc(("vboxvideo: enabling VBVA.\n"));
+            vbva = (struct VBVABUFFER *) (  ((uint8_t *)vbox->vram)
+                                           + vbox->vram_size
+                                           + i * VBVA_MIN_BUFFER_SIZE);
+            if (!VBoxVBVAEnable(&vbox->vbva_info[i], &vbox->submit_info, vbva, i))
+                AssertReleaseMsgFailed(("VBoxVBVAEnable failed - heap allocation error, very old host or driver error.\n"));
+        }
+    }
+}
+
+void vbox_disable_accel(struct vbox_private *vbox)
+{
+    unsigned i;
+
+    for (i = 0; i < vbox->num_crtcs; ++i)
+        VBoxVBVADisable(&vbox->vbva_info[i], &vbox->submit_info, i);
 }
 
@@ -83,4 +95,9 @@
 {
     VBoxHGSMISendCapsInfo(&vbox->submit_info, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION | VBVACAPS_IRQ);
+}
+
+void vbox_disable_caps(struct vbox_private *vbox)
+{
+    VBoxHGSMISendCapsInfo(&vbox->submit_info, 0);
 }
 
@@ -99,11 +116,5 @@
     LogFunc(("vboxvideo: %d: fb=%p, num_rects=%u, vbox=%p\n", __LINE__, fb,
              num_rects, vbox));
-    if (vbox->vbva_info[0].pVBVA == NULL) {
-        for (i = 0; i < vbox->num_crtcs; ++i)
-            vbox_enable_accel(vbox, i);
-        /* Assume that if the user knows to send dirty rectangle information
-         * they can also handle hot-plug events. */
-        vbox_enable_caps(vbox);
-    }
+    vbox_enable_accel(vbox);
     spin_lock_irqsave(&vbox->dev_lock, flags);
     for (i = 0; i < num_rects; ++i)
@@ -214,10 +225,7 @@
 static void vbox_accel_fini(struct vbox_private *vbox)
 {
-    unsigned i;
-
     if (vbox->vbva_info)
     {
-        for (i = 0; i < vbox->num_crtcs; ++i)
-            VBoxVBVADisable(&vbox->vbva_info[i], &vbox->submit_info, i);
+        vbox_disable_accel(vbox);
         kfree(vbox->vbva_info);
         vbox->vbva_info = NULL;
@@ -293,4 +301,7 @@
     void *guest_heap;
 
+    vbox->full_vram_size = VBoxVideoGetVRAMSize();
+    vbox->any_pitch = VBoxVideoAnyWidthAllowed();
+    DRM_INFO("VRAM %08x\n", vbox->full_vram_size);
     VBoxHGSMIGetBaseMappingInfo(vbox->full_vram_size, &base_offset, NULL,
                                 &guest_heap_offset, &guest_heap_size, &host_flags_offset);
@@ -314,4 +325,11 @@
 }
 
+static void vbox_hw_fini(struct vbox_private *vbox)
+{
+    vbox_accel_fini(vbox);
+    if (vbox->last_mode_hints)
+        kfree(vbox->last_mode_hints);
+    vbox->last_mode_hints = NULL;
+}
 
 int vbox_driver_load(struct drm_device *dev, unsigned long flags)
@@ -337,7 +355,4 @@
         goto out_free;
     }
-    vbox->full_vram_size = VBoxVideoGetVRAMSize();
-    vbox->any_pitch = VBoxVideoAnyWidthAllowed();
-    DRM_INFO("VRAM %08x\n", vbox->full_vram_size);
 
     ret = vbox_hw_init(vbox);
@@ -373,27 +388,26 @@
     return 0;
 out_free:
+    vbox_driver_unload(dev);
+    LogFunc(("vboxvideo: %d: ret=%d\n", __LINE__, ret));
+    return ret;
+}
+
+int vbox_driver_unload(struct drm_device *dev)
+{
+    struct vbox_private *vbox = dev->dev_private;
+
+    LogFunc(("vboxvideo: %d\n", __LINE__));
+    vbox_fbdev_fini(dev);
     vbox_irq_fini(vbox);
+    vbox_mode_fini(dev);
+    if (dev->mode_config.funcs)
+        drm_mode_config_cleanup(dev);
+
+    vbox_hw_fini(vbox);
+    vbox_mm_fini(vbox);
     if (vbox->vram)
         pci_iounmap(dev->pdev, vbox->vram);
     kfree(vbox);
     dev->dev_private = NULL;
-    LogFunc(("vboxvideo: %d: ret=%d\n", __LINE__, ret));
-    return ret;
-}
-
-int vbox_driver_unload(struct drm_device *dev)
-{
-    struct vbox_private *vbox = dev->dev_private;
-
-    LogFunc(("vboxvideo: %d\n", __LINE__));
-    vbox_fbdev_fini(dev);
-    vbox_irq_fini(vbox);
-    vbox_mode_fini(dev);
-    drm_mode_config_cleanup(dev);
-
-    vbox_accel_fini(vbox);
-    vbox_mm_fini(vbox);
-    pci_iounmap(dev->pdev, vbox->vram);
-    kfree(vbox);
     LogFunc(("vboxvideo: %d\n", __LINE__));
     return 0;
Index: trunk/src/VBox/Additions/linux/drm/vbox_mode.c
===================================================================
--- trunk/src/VBox/Additions/linux/drm/vbox_mode.c	(revision 59640)
+++ trunk/src/VBox/Additions/linux/drm/vbox_mode.c	(revision 59697)
@@ -218,10 +218,10 @@
         if (ret)
             DRM_ERROR("failed to kmap fbcon\n");
+        vbox_disable_accel(vbox);
+        vbox_disable_caps(vbox);
     }
     else {
-        unsigned i;
-
-        for (i = 0; i < vbox->num_crtcs; ++i)
-            vbox_enable_accel(vbox, i);
+        vbox_enable_accel(vbox);
+        vbox_enable_caps(vbox);
     }
     vbox_bo_unreserve(bo);
Index: trunk/src/VBox/Additions/linux/drm/vbox_ttm.c
===================================================================
--- trunk/src/VBox/Additions/linux/drm/vbox_ttm.c	(revision 59640)
+++ trunk/src/VBox/Additions/linux/drm/vbox_ttm.c	(revision 59697)
@@ -316,4 +316,5 @@
 #endif
 
+    vbox->ttm.mm_initialised = true;
     return 0;
 }
@@ -324,4 +325,6 @@
     struct drm_device *dev = vbox->dev;
 #endif
+    if (!vbox->ttm.mm_initialised)
+        return;
     ttm_bo_device_release(&vbox->ttm.bdev);
 
