diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2010-07-12 16:37:03 +0300 |
---|---|---|
committer | Yonit Halperin <yhalperi@redhat.com> | 2010-07-14 08:33:25 +0300 |
commit | 3f1b5fffa0474e1c31950bfd5dbbed02c78dc380 (patch) | |
tree | c3d09166e541692ae5e80bbaac32bd6560b0f1c7 | |
parent | f55b4857ed8a828f75c2034e6d1bbec60d56abc1 (diff) |
Fix corrupted ram data (e.g., release_ring), and unsynchronized worker, after driver is disabled and re-enabled.
On logoff, in Win7 guest, and on switch user and login into a Winxp guest, the driver is disabled and re-enabled (while the miniport in not reset).
However, before the fix, all the draw objects, e.g., surfaces, were still alive in the worker and the release ring still contained objects, while all the driver's data was initialized. This caused blue screens, and panics in the worker.
-rw-r--r-- | display/driver.c | 1 | ||||
-rw-r--r-- | display/qxldd.h | 1 | ||||
-rw-r--r-- | display/res.c | 21 | ||||
-rw-r--r-- | display/res.h | 2 |
4 files changed, 25 insertions, 0 deletions
diff --git a/display/driver.c b/display/driver.c index 7dce00e..4eaedc4 100644 --- a/display/driver.c +++ b/display/driver.c @@ -256,6 +256,7 @@ BOOL DrvEnableDriver(ULONG engine_version, ULONG enable_data_size, PDRVENABLEDAT VOID DrvDisableDriver(VOID) { DEBUG_PRINT((NULL, 1, "%s\n", __FUNCTION__)); + ResetAllDevices(); ResDestroyGlobals(); CleanGlobalRes(); } diff --git a/display/qxldd.h b/display/qxldd.h index ffa8b8c..b90aaad 100644 --- a/display/qxldd.h +++ b/display/qxldd.h @@ -168,6 +168,7 @@ typedef struct DevRes { UINT8 *surfaces_used; + HANDLE driver; #ifdef DBG int num_free_pages; int num_outputs; diff --git a/display/res.c b/display/res.c index c769aeb..a8357f7 100644 --- a/display/res.c +++ b/display/res.c @@ -28,6 +28,8 @@ #include "surface.h" #include "dd.h" #include "rop.h" +#include "devioctl.h" +#include "ntddvdeo.h" #if (WINVER < 0x0501) #define WAIT_FOR_EVENT(pdev, event, timeout) (pdev)->WaitForEvent(event, timeout) @@ -397,6 +399,8 @@ static void InitRes(PDev *pdev) RtlZeroMemory(pdev->Res.palette_cache, sizeof(pdev->Res.palette_cache)); RingInit(&pdev->Res.dynamic->palette_lru); pdev->Res.num_palettes = 0; + + pdev->Res.driver = pdev->driver; ONDBG(pdev->Res.num_outputs = 0); ONDBG(pdev->Res.num_path_pages = 0); @@ -3156,5 +3160,22 @@ void CheckAndSetSSE2() } } +void ResetAllDevices() +{ + UINT32 i; + EngAcquireSemaphore(res_sem); + for (i = 0; i < num_global_res; i++) { + if (global_res[i].driver) { + DWORD length; + if (EngDeviceIoControl(global_res[i].driver, IOCTL_VIDEO_RESET_DEVICE, + NULL, 0, NULL, 0, &length)) { + DEBUG_PRINT((NULL, 0, "%s: reset to device failed 0x%lx\n", + __FUNCTION__, global_res[i].driver)); + + } + } + } + EngReleaseSemaphore(res_sem); +} diff --git a/display/res.h b/display/res.h index 3bfb0c7..7a10035 100644 --- a/display/res.h +++ b/display/res.h @@ -63,4 +63,6 @@ void ResDestroy(PDev *pdev); void ResInitGlobals(); void ResDestroyGlobals(); void CheckAndSetSSE2(); +void ResetAllDevices(); + #endif |