VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.h@ 53403

Last change on this file since 53403 was 49137, checked in by vboxsync, 11 years ago

HostDrivers: Minor nit. Coding style.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: VBoxUsbDev.h 49137 2013-10-16 12:28:02Z vboxsync $ */
2/** @file
3 * VBoxUsbDev.h - USB device.
4 */
5/*
6 * Copyright (C) 2011-2012 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16#ifndef ___VBoxUsbDev_h___
17#define ___VBoxUsbDev_h___
18#include "VBoxUsbCmn.h"
19#include <iprt/assert.h>
20
21typedef struct VBOXUSB_GLOBALS
22{
23 PDRIVER_OBJECT pDrvObj;
24 UNICODE_STRING RegPath;
25 VBOXUSBRT_IDC RtIdc;
26} VBOXUSB_GLOBALS, *PVBOXUSB_GLOBALS;
27
28extern VBOXUSB_GLOBALS g_VBoxUsbGlobals;
29
30/* pnp state decls */
31typedef enum
32{
33 ENMVBOXUSB_PNPSTATE_UNKNOWN = 0,
34 ENMVBOXUSB_PNPSTATE_START_PENDING,
35 ENMVBOXUSB_PNPSTATE_STARTED,
36 ENMVBOXUSB_PNPSTATE_STOP_PENDING,
37 ENMVBOXUSB_PNPSTATE_STOPPED,
38 ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED,
39 ENMVBOXUSB_PNPSTATE_REMOVE_PENDING,
40 ENMVBOXUSB_PNPSTATE_REMOVED,
41 ENMVBOXUSB_PNPSTATE_FORSEDWORD = 0x8fffffff
42} ENMVBOXUSB_PNPSTATE;
43AssertCompile(sizeof (ENMVBOXUSB_PNPSTATE) == sizeof (uint32_t));
44
45#ifdef DEBUG
46DECLHIDDEN(VOID) vboxUsbPnPStateGbgChange(ENMVBOXUSB_PNPSTATE enmOld, ENMVBOXUSB_PNPSTATE enmNew);
47# define VBOXUSB_PNP_GBG_STATE_CHANGE(_old, _new) vboxUsbPnPStateGbgChange((_old), (_new))
48#else
49# define VBOXUSB_PNP_GBG_STATE_CHANGE(_old, _new) do { } while (0)
50#endif
51
52
53typedef struct VBOXUSB_PNPSTATE
54{
55 /* Current state */
56 volatile ENMVBOXUSB_PNPSTATE Curr;
57 /* Previous state, used to restore state info on cancell stop device */
58 ENMVBOXUSB_PNPSTATE Prev;
59} VBOXUSB_PNPSTATE, *PVBOXUSB_PNPSTATE;
60
61typedef struct VBOXUSBDEV_DDISTATE
62{
63 /* Lock */
64 KSPIN_LOCK Lock;
65 VBOXDRVTOOL_REF Ref;
66 VBOXUSB_PNPSTATE PnPState;
67 VBOXUSB_PWRSTATE PwrState;
68 /* current dev caps */
69 DEVICE_CAPABILITIES DevCaps;
70} VBOXUSBDEV_DDISTATE, *PVBOXUSBDEV_DDISTATE;
71
72typedef struct VBOXUSBDEV_EXT
73{
74 PDEVICE_OBJECT pFDO;
75 PDEVICE_OBJECT pPDO;
76 PDEVICE_OBJECT pLowerDO;
77
78 VBOXUSBDEV_DDISTATE DdiState;
79
80 uint32_t cHandles;
81
82 VBOXUSB_RT Rt;
83
84} VBOXUSBDEV_EXT, *PVBOXUSBDEV_EXT;
85
86/* pnp state api */
87static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbPnPStateGet(PVBOXUSBDEV_EXT pDevExt)
88{
89 return (ENMVBOXUSB_PNPSTATE)ASMAtomicUoReadU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr);
90}
91
92static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbPnPStateSet(PVBOXUSBDEV_EXT pDevExt, ENMVBOXUSB_PNPSTATE enmState)
93{
94 KIRQL Irql;
95 ENMVBOXUSB_PNPSTATE enmOldState;
96 KeAcquireSpinLock(&pDevExt->DdiState.Lock, &Irql);
97 pDevExt->DdiState.PnPState.Prev = (ENMVBOXUSB_PNPSTATE)ASMAtomicUoReadU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr);
98 ASMAtomicWriteU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr, (uint32_t)enmState);
99 pDevExt->DdiState.PnPState.Curr = enmState;
100 enmOldState = pDevExt->DdiState.PnPState.Prev;
101 KeReleaseSpinLock(&pDevExt->DdiState.Lock, Irql);
102 VBOXUSB_PNP_GBG_STATE_CHANGE(enmOldState, enmState);
103 return enmState;
104}
105
106static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbPnPStateRestore(PVBOXUSBDEV_EXT pDevExt)
107{
108 ENMVBOXUSB_PNPSTATE enmNewState, enmOldState;
109 KIRQL Irql;
110 KeAcquireSpinLock(&pDevExt->DdiState.Lock, &Irql);
111 enmOldState = pDevExt->DdiState.PnPState.Curr;
112 enmNewState = pDevExt->DdiState.PnPState.Prev;
113 ASMAtomicWriteU32((volatile uint32_t*)&pDevExt->DdiState.PnPState.Curr, (uint32_t)pDevExt->DdiState.PnPState.Prev);
114 KeReleaseSpinLock(&pDevExt->DdiState.Lock, Irql);
115 VBOXUSB_PNP_GBG_STATE_CHANGE(enmOldState, enmNewState);
116 Assert(enmNewState == ENMVBOXUSB_PNPSTATE_STARTED);
117 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING
118 || enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING);
119 return enmNewState;
120}
121
122static DECLINLINE(VOID) vboxUsbPnPStateInit(PVBOXUSBDEV_EXT pDevExt)
123{
124 pDevExt->DdiState.PnPState.Curr = pDevExt->DdiState.PnPState.Prev = ENMVBOXUSB_PNPSTATE_START_PENDING;
125}
126
127static DECLINLINE(VOID) vboxUsbDdiStateInit(PVBOXUSBDEV_EXT pDevExt)
128{
129 KeInitializeSpinLock(&pDevExt->DdiState.Lock);
130 VBoxDrvToolRefInit(&pDevExt->DdiState.Ref);
131 vboxUsbPwrStateInit(pDevExt);
132 vboxUsbPnPStateInit(pDevExt);
133}
134
135static DECLINLINE(bool) vboxUsbDdiStateRetainIfStarted(PVBOXUSBDEV_EXT pDevExt)
136{
137 KIRQL oldIrql;
138 bool bRetained = true;
139 KeAcquireSpinLock(&pDevExt->DdiState.Lock, &oldIrql);
140 if (vboxUsbPnPStateGet(pDevExt) == ENMVBOXUSB_PNPSTATE_STARTED)
141 {
142 VBoxDrvToolRefRetain(&pDevExt->DdiState.Ref);
143 }
144 else
145 {
146 bRetained = false;
147 }
148 KeReleaseSpinLock(&pDevExt->DdiState.Lock, oldIrql);
149 return bRetained;
150}
151
152/* if device is removed - does nothing and returns zero,
153 * otherwise increments a ref counter and returns the current pnp state
154 * NOTE: never returns ENMVBOXUSB_PNPSTATE_REMOVED
155 * */
156static DECLINLINE(ENMVBOXUSB_PNPSTATE) vboxUsbDdiStateRetainIfNotRemoved(PVBOXUSBDEV_EXT pDevExt)
157{
158 KIRQL oldIrql;
159 ENMVBOXUSB_PNPSTATE enmState;
160 KeAcquireSpinLock(&pDevExt->DdiState.Lock, &oldIrql);
161 enmState = vboxUsbPnPStateGet(pDevExt);
162 if (enmState != ENMVBOXUSB_PNPSTATE_REMOVED)
163 {
164 VBoxDrvToolRefRetain(&pDevExt->DdiState.Ref);
165 }
166 KeReleaseSpinLock(&pDevExt->DdiState.Lock, oldIrql);
167 return enmState != ENMVBOXUSB_PNPSTATE_REMOVED ? enmState : (ENMVBOXUSB_PNPSTATE)0;
168}
169
170static DECLINLINE(uint32_t) vboxUsbDdiStateRetain(PVBOXUSBDEV_EXT pDevExt)
171{
172 return VBoxDrvToolRefRetain(&pDevExt->DdiState.Ref);
173}
174
175static DECLINLINE(uint32_t) vboxUsbDdiStateRelease(PVBOXUSBDEV_EXT pDevExt)
176{
177 return VBoxDrvToolRefRelease(&pDevExt->DdiState.Ref);
178}
179
180static DECLINLINE(VOID) vboxUsbDdiStateReleaseAndWaitCompleted(PVBOXUSBDEV_EXT pDevExt)
181{
182 VBoxDrvToolRefRelease(&pDevExt->DdiState.Ref);
183 VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 1);
184}
185
186static DECLINLINE(VOID) vboxUsbDdiStateReleaseAndWaitRemoved(PVBOXUSBDEV_EXT pDevExt)
187{
188 VBoxDrvToolRefRelease(&pDevExt->DdiState.Ref);
189 VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 0);
190}
191
192static DECLHIDDEN(VOID) vboxUsbDdiStateWaitOtherCompleted(PVBOXUSBDEV_EXT pDevExt)
193{
194 /* Earlier we assumed that 1 request will be pending while we service
195 Device Power IRP which was leading to host hang when USB is connected
196 to VM.
197 With debugging found that at the point when host goes to sleep
198 state and USB is connected to VM, two Power IRP requests are pending :
199 One for SYSTEM and other for DEVICE.
200 */
201 VBoxDrvToolRefWaitEqual(&pDevExt->DdiState.Ref, 3);
202}
203
204#endif /* #ifndef ___VBoxUsbDev_h___ */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette