1 | /* $Id: USBProxyDevice.h 106061 2024-09-16 14:03:52Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * USBPROXY - USB proxy header
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2006-2024 Oracle and/or its affiliates.
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox base platform packages, as
|
---|
10 | * available from https://www.virtualbox.org.
|
---|
11 | *
|
---|
12 | * This program is free software; you can redistribute it and/or
|
---|
13 | * modify it under the terms of the GNU General Public License
|
---|
14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
15 | * License.
|
---|
16 | *
|
---|
17 | * This program is distributed in the hope that it will be useful, but
|
---|
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
20 | * General Public License for more details.
|
---|
21 | *
|
---|
22 | * You should have received a copy of the GNU General Public License
|
---|
23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
24 | *
|
---|
25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
26 | */
|
---|
27 |
|
---|
28 | #ifndef VBOX_INCLUDED_SRC_USB_USBProxyDevice_h
|
---|
29 | #define VBOX_INCLUDED_SRC_USB_USBProxyDevice_h
|
---|
30 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
31 | # pragma once
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | #include <VBox/cdefs.h>
|
---|
35 | #include <VBox/vusb.h>
|
---|
36 |
|
---|
37 | RT_C_DECLS_BEGIN
|
---|
38 |
|
---|
39 |
|
---|
40 | /** Pointer to a USB proxy device. */
|
---|
41 | typedef struct USBPROXYDEV *PUSBPROXYDEV;
|
---|
42 |
|
---|
43 | /**
|
---|
44 | * USB Proxy Device Backend
|
---|
45 | */
|
---|
46 | typedef struct USBPROXYBACK
|
---|
47 | {
|
---|
48 | /** Name of the backend. */
|
---|
49 | const char *pszName;
|
---|
50 | /** Size of the backend specific data. */
|
---|
51 | size_t cbBackend;
|
---|
52 |
|
---|
53 | /**
|
---|
54 | * Opens the USB device specfied by pszAddress.
|
---|
55 | *
|
---|
56 | * This method will initialize backend private data. If the backend has
|
---|
57 | * already selected a configuration for the device, this must be indicated
|
---|
58 | * in USBPROXYDEV::iActiveCfg.
|
---|
59 | *
|
---|
60 | * @returns VBox status code.
|
---|
61 | * @param pProxyDev The USB Proxy Device instance.
|
---|
62 | * @param pszAddress Host specific USB device address.
|
---|
63 | */
|
---|
64 | DECLR3CALLBACKMEMBER(int, pfnOpen, (PUSBPROXYDEV pProxyDev, const char *pszAddress));
|
---|
65 |
|
---|
66 | /**
|
---|
67 | * Optional callback for initializing the device after the configuration
|
---|
68 | * has been established.
|
---|
69 | *
|
---|
70 | * @returns VBox status code.
|
---|
71 | * @param pProxyDev The USB Proxy Device instance.
|
---|
72 | */
|
---|
73 | DECLR3CALLBACKMEMBER(int, pfnInit, (PUSBPROXYDEV pProxyDev));
|
---|
74 |
|
---|
75 | /**
|
---|
76 | * Closes handle to the host USB device.
|
---|
77 | *
|
---|
78 | * @param pProxyDev The USB Proxy Device instance.
|
---|
79 | */
|
---|
80 | DECLR3CALLBACKMEMBER(void, pfnClose, (PUSBPROXYDEV pProxyDev));
|
---|
81 |
|
---|
82 | /**
|
---|
83 | * Reset a device.
|
---|
84 | *
|
---|
85 | * The backend must update iActualCfg and fIgnoreEqualSetConfig.
|
---|
86 | *
|
---|
87 | * @returns VBox status code.
|
---|
88 | * @param pProxyDev The USB Proxy Device instance.
|
---|
89 | * @param fResetOnLinux It's safe to do reset on linux, we can deal with devices
|
---|
90 | * being logically reconnected.
|
---|
91 | */
|
---|
92 | DECLR3CALLBACKMEMBER(int, pfnReset, (PUSBPROXYDEV pProxyDev, bool fResetOnLinux));
|
---|
93 |
|
---|
94 | /**
|
---|
95 | * Sets the given configuration of the device.
|
---|
96 | *
|
---|
97 | * @returns VBox status code.
|
---|
98 | * @param pProxyDev The USB Proxy Device instance.
|
---|
99 | * @param iCfg The configuration to set.
|
---|
100 | */
|
---|
101 | DECLR3CALLBACKMEMBER(int, pfnSetConfig, (PUSBPROXYDEV pProxyDev, int iCfg));
|
---|
102 |
|
---|
103 | /**
|
---|
104 | * Claim an interface for use by the prox device.
|
---|
105 | *
|
---|
106 | * @returns VBox status code.
|
---|
107 | * @param pProxyDev The USB Proxy Device instance.
|
---|
108 | * @param iIf Interface number to claim.
|
---|
109 | */
|
---|
110 | DECLR3CALLBACKMEMBER(int, pfnClaimInterface, (PUSBPROXYDEV pProxyDev, int iIf));
|
---|
111 |
|
---|
112 | /**
|
---|
113 | * Releases an interface which was claimed before.
|
---|
114 | *
|
---|
115 | * @returns VBox status code.
|
---|
116 | * @param pProxyDev The USB Proxy Device instance.
|
---|
117 | * @param iIf Interface number to release.
|
---|
118 | */
|
---|
119 | DECLR3CALLBACKMEMBER(int, pfnReleaseInterface, (PUSBPROXYDEV pProxyDev, int iIf));
|
---|
120 |
|
---|
121 | /**
|
---|
122 | * Sets the given alternate interface for the device.
|
---|
123 | *
|
---|
124 | * @returns VBox status code.
|
---|
125 | * @param pProxyDev The USB Proxy Device instance.
|
---|
126 | * @param iIf Interface to use.
|
---|
127 | * @param iSetting The alternate setting to use.
|
---|
128 | */
|
---|
129 | DECLR3CALLBACKMEMBER(int, pfnSetInterface, (PUSBPROXYDEV pProxyDev, int iIf, int iSetting));
|
---|
130 |
|
---|
131 | /**
|
---|
132 | * Clears the given halted endpoint.
|
---|
133 | *
|
---|
134 | * @returns VBox status code.
|
---|
135 | * @param pProxyDev The USB Proxy Device instance.
|
---|
136 | * @param iEp The endpoint to clear.
|
---|
137 | */
|
---|
138 | DECLR3CALLBACKMEMBER(int, pfnClearHaltedEndpoint, (PUSBPROXYDEV pDev, unsigned int iEp));
|
---|
139 |
|
---|
140 | /**
|
---|
141 | * Queue a new URB.
|
---|
142 | *
|
---|
143 | * @returns VBox status code.
|
---|
144 | * @param pProxyDev The USB Proxy Device instance.
|
---|
145 | * @param pUrb The URB to queue.
|
---|
146 | */
|
---|
147 | DECLR3CALLBACKMEMBER(int, pfnUrbQueue, (PUSBPROXYDEV pProxyDev, PVUSBURB pUrb));
|
---|
148 |
|
---|
149 | /**
|
---|
150 | * Cancel an in-flight URB.
|
---|
151 | *
|
---|
152 | * @returns VBox status code.
|
---|
153 | * @param pProxyDev The USB Proxy Device instance.
|
---|
154 | * @param pUrb The URB to cancel.
|
---|
155 | */
|
---|
156 | DECLR3CALLBACKMEMBER(int, pfnUrbCancel, (PUSBPROXYDEV pProxyDev, PVUSBURB pUrb));
|
---|
157 |
|
---|
158 | /**
|
---|
159 | * Reap URBs in-flight on a device.
|
---|
160 | *
|
---|
161 | * @returns Pointer to a completed URB.
|
---|
162 | * @returns NULL if no URB was completed.
|
---|
163 | * @param pProxyDev The USB Proxy Device instance.
|
---|
164 | * @param cMillies Number of milliseconds to wait. Use 0 to not
|
---|
165 | * wait at all.
|
---|
166 | */
|
---|
167 | DECLR3CALLBACKMEMBER(PVUSBURB, pfnUrbReap, (PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies));
|
---|
168 |
|
---|
169 | /**
|
---|
170 | * Kicks the thread waiting in pfnUrbReap to make it return.
|
---|
171 | *
|
---|
172 | * @returns VBox status code.
|
---|
173 | * @param pProxyDev The USB Proxy Device instance.
|
---|
174 | */
|
---|
175 | DECLR3CALLBACKMEMBER(int, pfnWakeup, (PUSBPROXYDEV pProxyDev));
|
---|
176 |
|
---|
177 | /** Dummy entry for making sure we've got all members initialized. */
|
---|
178 | uint32_t uDummy;
|
---|
179 | } USBPROXYBACK;
|
---|
180 | /** Pointer to a USB Proxy Device Backend. */
|
---|
181 | typedef USBPROXYBACK *PUSBPROXYBACK;
|
---|
182 | /** Pointer to a const USB Proxy Device Backend. */
|
---|
183 | typedef const USBPROXYBACK *PCUSBPROXYBACK;
|
---|
184 |
|
---|
185 | /** The Host backend. */
|
---|
186 | extern const USBPROXYBACK g_USBProxyDeviceHost;
|
---|
187 | /** The remote desktop backend. */
|
---|
188 | extern const USBPROXYBACK g_USBProxyDeviceVRDP;
|
---|
189 | /** The USB/IP backend. */
|
---|
190 | extern const USBPROXYBACK g_USBProxyDeviceUsbIp;
|
---|
191 |
|
---|
192 | #ifdef RDESKTOP
|
---|
193 | typedef struct VUSBDEV
|
---|
194 | {
|
---|
195 | char* pszName;
|
---|
196 | } VUSBDEV, *PVUSBDEV;
|
---|
197 | #endif
|
---|
198 |
|
---|
199 | /**
|
---|
200 | * USB Proxy device.
|
---|
201 | */
|
---|
202 | typedef struct USBPROXYDEV
|
---|
203 | {
|
---|
204 | /** The device descriptor. */
|
---|
205 | VUSBDESCDEVICE DevDesc;
|
---|
206 | /** The configuration descriptor array. */
|
---|
207 | PVUSBDESCCONFIGEX paCfgDescs;
|
---|
208 | #ifndef RDESKTOP
|
---|
209 | /** The descriptor cache.
|
---|
210 | * Contains &DevDesc and paConfigDescs. */
|
---|
211 | PDMUSBDESCCACHE DescCache;
|
---|
212 | /** Pointer to the PDM USB device instance. */
|
---|
213 | PPDMUSBINS pUsbIns;
|
---|
214 | #endif
|
---|
215 |
|
---|
216 | /** Pointer to the backend. */
|
---|
217 | PCUSBPROXYBACK pOps;
|
---|
218 | /** The currently active configuration.
|
---|
219 | * It's -1 if no configuration is active. This is set to -1 before open and reset,
|
---|
220 | * the backend will change it if open or reset implies SET_CONFIGURATION. */
|
---|
221 | int iActiveCfg;
|
---|
222 | /** Ignore one or two SET_CONFIGURATION operation.
|
---|
223 | * See usbProxyDevSetCfg for details. */
|
---|
224 | int cIgnoreSetConfigs;
|
---|
225 | /** Mask of the interfaces that the guest shall not see. */
|
---|
226 | uint32_t fMaskedIfs;
|
---|
227 | /** Whether we've opened the device or not.
|
---|
228 | * For dealing with failed construction (the destruct method is always called). */
|
---|
229 | bool fOpened;
|
---|
230 | /** Whether we've called pfnInit or not.
|
---|
231 | * For dealing with failed construction (the destruct method is always called). */
|
---|
232 | bool fInited;
|
---|
233 | /** Whether the device has been detached.
|
---|
234 | * This is hack for making PDMUSBREG::pfnUsbQueue return the right status code. */
|
---|
235 | bool fDetached;
|
---|
236 | /** Backend specific data, the size is stored in pOps::cbBackend. */
|
---|
237 | void *pvInstanceDataR3;
|
---|
238 |
|
---|
239 | #ifdef RDESKTOP
|
---|
240 | /** @name VRDP client (rdesktop) related members.
|
---|
241 | * @{ */
|
---|
242 | /** The vrdp device ID. */
|
---|
243 | uint32_t idVrdp;
|
---|
244 | /** The VUSB device structure - must be the first structure member. */
|
---|
245 | VUSBDEV Dev;
|
---|
246 | /** The next device in rdesktop-vrdp's linked list. */
|
---|
247 | PUSBPROXYDEV pNext;
|
---|
248 | /** The previous device in rdesktop-vrdp's linked list. */
|
---|
249 | PUSBPROXYDEV pPrev;
|
---|
250 | /** Linked list of in-flight URBs */
|
---|
251 | PVUSBURB pUrbs;
|
---|
252 | /** @} */
|
---|
253 | #endif
|
---|
254 | } USBPROXYDEV;
|
---|
255 |
|
---|
256 | /** @def USBPROXYDEV_2_DATA
|
---|
257 | * Converts a USB proxy Device, pointer to a pointer to the backend specific instance data.
|
---|
258 | */
|
---|
259 | #define USBPROXYDEV_2_DATA(a_pProxyDev, a_Type) ( (a_Type)(a_pProxyDev)->pvInstanceDataR3 )
|
---|
260 |
|
---|
261 |
|
---|
262 | DECLINLINE(const char *) usbProxyGetName(PUSBPROXYDEV pProxyDev)
|
---|
263 | {
|
---|
264 | #ifndef RDESKTOP
|
---|
265 | return pProxyDev->pUsbIns->pszName;
|
---|
266 | #else
|
---|
267 | return pProxyDev->Dev.pszName;
|
---|
268 | #endif
|
---|
269 | }
|
---|
270 |
|
---|
271 | #ifdef RDESKTOP
|
---|
272 | DECLINLINE(PUSBPROXYDEV) usbProxyFromVusbDev(PVUSBDEV pDev)
|
---|
273 | {
|
---|
274 | return RT_FROM_MEMBER(pDev, USBPROXYDEV, Dev);
|
---|
275 | }
|
---|
276 | #endif
|
---|
277 |
|
---|
278 | #ifdef RT_OS_LINUX
|
---|
279 | RTDECL(int) USBProxyDeviceLinuxGetFD(PUSBPROXYDEV pProxyDev);
|
---|
280 | #endif
|
---|
281 |
|
---|
282 | RT_C_DECLS_END
|
---|
283 |
|
---|
284 | #endif /* !VBOX_INCLUDED_SRC_USB_USBProxyDevice_h */
|
---|
285 |
|
---|