VirtualBox

source: vbox/trunk/src/VBox/Devices/USB/VUSBInternal.h

Last change on this file was 100517, checked in by vboxsync, 11 months ago

VUSB: Explicitly ignore any high bits of a USB address which is a 7-bit quantity (see bugref:10433).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.3 KB
RevLine 
[26970]1/* $Id: VUSBInternal.h 100517 2023-07-11 14:54:11Z vboxsync $ */
2/** @file
3 * Virtual USB - Internal header.
4 *
5 * This subsystem implements USB devices in a host controller independent
[93979]6 * way. All the host controller code has to do is use VUSBROOTHUB for its
[26970]7 * root hub implementation and any emulated USB device may be plugged into
8 * the virtual bus.
9 */
10
11/*
[98103]12 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[26970]13 *
[96407]14 * This file is part of VirtualBox base platform packages, as
15 * available from https://www.virtualbox.org.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation, in version 3 of the
20 * License.
21 *
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses>.
29 *
30 * SPDX-License-Identifier: GPL-3.0-only
[26970]31 */
32
[76565]33#ifndef VBOX_INCLUDED_SRC_USB_VUSBInternal_h
34#define VBOX_INCLUDED_SRC_USB_VUSBInternal_h
[76520]35#ifndef RT_WITHOUT_PRAGMA_ONCE
36# pragma once
37#endif
[26970]38
39#include <VBox/cdefs.h>
40#include <VBox/types.h>
41#include <VBox/vusb.h>
[35346]42#include <VBox/vmm/stam.h>
[59775]43#include <VBox/vmm/pdm.h>
44#include <VBox/vmm/vmapi.h>
[59718]45#include <VBox/vmm/pdmusb.h>
46#include <iprt/asm.h>
[31058]47#include <iprt/assert.h>
[52148]48#include <iprt/req.h>
[59775]49#include <iprt/asm.h>
[59722]50#include <iprt/list.h>
[26970]51
[53062]52#include "VUSBSniffer.h"
53
[26970]54RT_C_DECLS_BEGIN
55
56
[81369]57/** @defgroup grp_vusb_int VUSB Internals.
58 * @ingroup grp_vusb
59 * @internal
[26970]60 * @{
61 */
62
[81369]63/** @defgroup grp_vusb_int_dev Internal Device Operations, Structures and Constants.
64 * @{
65 */
66
[26970]67/** Pointer to a Virtual USB device (core). */
68typedef struct VUSBDEV *PVUSBDEV;
69/** Pointer to a VUSB root hub. */
70typedef struct VUSBROOTHUB *PVUSBROOTHUB;
71
72
73/** Number of the default control endpoint */
74#define VUSB_PIPE_DEFAULT 0
75
76/** @name Device addresses
77 * @{ */
78#define VUSB_DEFAULT_ADDRESS 0
79#define VUSB_INVALID_ADDRESS UINT8_C(0xff)
[100517]80#define VUSB_ADDRESS_MASK UINT8_C(0x7f)
[26970]81/** @} */
82
83/** @name Feature bits (1<<FEATURE for the u16Status bit)
84 * @{ */
85#define VUSB_DEV_SELF_POWERED 0
86#define VUSB_DEV_REMOTE_WAKEUP 1
87#define VUSB_EP_HALT 0
88/** @} */
89
90/** Maximum number of endpoint addresses */
91#define VUSB_PIPE_MAX 16
92
93/**
[59704]94 * The VUSB URB data.
95 */
96typedef struct VUSBURBVUSBINT
97{
[59737]98 /** Node for one of the lists the URB can be in. */
99 RTLISTNODE NdLst;
100 /** Pointer to the URB this structure is part of. */
101 PVUSBURB pUrb;
[59704]102 /** Pointer to the original for control messages. */
103 PVUSBURB pCtrlUrb;
104 /** Pointer to the VUSB device.
105 * This may be NULL if the destination address is invalid. */
106 PVUSBDEV pDev;
107 /** Specific to the pfnFree function. */
108 void *pvFreeCtx;
109 /**
110 * Callback which will free the URB once it's reaped and completed.
111 * @param pUrb The URB.
112 */
[85121]113 DECLCALLBACKMEMBER(void, pfnFree,(PVUSBURB pUrb));
[59704]114 /** Submit timestamp. (logging only) */
115 uint64_t u64SubmitTS;
116} VUSBURBVUSBINT;
117
118/**
[26970]119 * Control-pipe stages.
120 */
121typedef enum CTLSTAGE
122{
123 /** the control pipe is in the setup stage. */
124 CTLSTAGE_SETUP = 0,
125 /** the control pipe is in the data stage. */
126 CTLSTAGE_DATA,
127 /** the control pipe is in the status stage. */
128 CTLSTAGE_STATUS
129} CTLSTAGE;
130
131/**
132 * Extra data for a control pipe.
133 *
134 * This is state information needed for the special multi-stage
135 * transfers performed on this kind of pipes.
136 */
137typedef struct vusb_ctrl_extra
138{
139 /** Current pipe stage. */
140 CTLSTAGE enmStage;
141 /** Success indicator. */
142 bool fOk;
143 /** Set if the message URB has been submitted. */
144 bool fSubmitted;
145 /** Pointer to the SETUP.
146 * This is a pointer to Urb->abData[0]. */
147 PVUSBSETUP pMsg;
148 /** Current DATA pointer.
149 * This starts at pMsg + 1 and is incremented at we read/write data. */
150 uint8_t *pbCur;
151 /** The amount of data left to read on IN operations.
152 * On OUT operations this is not used. */
153 uint32_t cbLeft;
154 /** The amount of data we can house.
155 * This starts at the default 8KB, and this structure will be reallocated to
156 * accommodate any larger request (unlikely). */
157 uint32_t cbMax;
[84042]158 /** VUSB internal data for the extra URB. */
[84359]159 VUSBURBVUSBINT VUsbExtra;
[26970]160 /** The message URB. */
161 VUSBURB Urb;
162} VUSBCTRLEXTRA, *PVUSBCTRLEXTRA;
163
164void vusbMsgFreeExtraData(PVUSBCTRLEXTRA pExtra);
165void vusbMsgResetExtraData(PVUSBCTRLEXTRA pExtra);
166
167/**
168 * A VUSB pipe
169 */
170typedef struct vusb_pipe
171{
172 PCVUSBDESCENDPOINTEX in;
173 PCVUSBDESCENDPOINTEX out;
174 /** Pointer to the extra state data required to run a control pipe. */
175 PVUSBCTRLEXTRA pCtrl;
[52513]176 /** Critical section serializing access to the extra state data for a control pipe. */
177 RTCRITSECT CritSectCtrl;
[26970]178 /** Count of active async transfers. */
[49814]179 volatile uint32_t async;
[67590]180 /** Last scheduled frame - only valid for isochronous IN endpoints. */
181 uint32_t uLastFrameIn;
182 /** Last scheduled frame - only valid for isochronous OUT endpoints. */
183 uint32_t uLastFrameOut;
[26970]184} VUSBPIPE;
185/** Pointer to a VUSB pipe structure. */
186typedef VUSBPIPE *PVUSBPIPE;
187
188
189/**
190 * Interface state and possible settings.
191 */
192typedef struct vusb_interface_state
193{
194 /** Pointer to the interface descriptor of the currently selected (active)
195 * interface. */
196 PCVUSBDESCINTERFACEEX pCurIfDesc;
197 /** Pointer to the interface settings. */
198 PCVUSBINTERFACE pIf;
199} VUSBINTERFACESTATE;
200/** Pointer to interface state. */
201typedef VUSBINTERFACESTATE *PVUSBINTERFACESTATE;
202/** Pointer to const interface state. */
203typedef const VUSBINTERFACESTATE *PCVUSBINTERFACESTATE;
204
205
206/**
[59718]207 * VUSB URB pool.
208 */
209typedef struct VUSBURBPOOL
210{
211 /** Critical section protecting the pool. */
212 RTCRITSECT CritSectPool;
213 /** Chain of free URBs by type. (Singly linked) */
[59722]214 RTLISTANCHOR aLstFreeUrbs[VUSBXFERTYPE_ELEMENTS];
[59718]215 /** The number of URBs in the pool. */
[59722]216 volatile uint32_t cUrbsInPool;
[59718]217 /** Align the size to a 8 byte boundary. */
218 uint32_t Alignment0;
219} VUSBURBPOOL;
220/** Pointer to a VUSB URB pool. */
221typedef VUSBURBPOOL *PVUSBURBPOOL;
222
223AssertCompileSizeAlignment(VUSBURBPOOL, 8);
224
225/**
[26970]226 * A Virtual USB device (core).
227 *
228 * @implements VUSBIDEVICE
229 */
230typedef struct VUSBDEV
231{
232 /** The device interface exposed to the HCI. */
[93979]233 VUSBIDEVICE IDevice;
[26970]234 /** Pointer to the PDM USB device instance. */
[93979]235 PPDMUSBINS pUsbIns;
236 /** Pointer to the roothub this device is attached to. */
237 PVUSBROOTHUB pHub;
[52881]238 /** The device state. */
[93979]239 VUSBDEVICESTATE volatile enmState;
[62294]240 /** Reference counter to protect the device structure from going away. */
[93979]241 uint32_t volatile cRefs;
[26970]242
243 /** The device address. */
244 uint8_t u8Address;
245 /** The new device address. */
246 uint8_t u8NewAddress;
247 /** The port. */
248 int16_t i16Port;
249 /** Device status. (VUSB_DEV_SELF_POWERED or not.) */
250 uint16_t u16Status;
251
252 /** Pointer to the descriptor cache.
253 * (Provided by the device thru the pfnGetDescriptorCache method.) */
254 PCPDMUSBDESCCACHE pDescCache;
255 /** Current configuration. */
256 PCVUSBDESCCONFIGEX pCurCfgDesc;
257
258 /** Current interface state (including alternate interface setting) - maximum
259 * valid index is config->bNumInterfaces
260 */
261 PVUSBINTERFACESTATE paIfStates;
262
263 /** Pipe/direction -> endpoint descriptor mapping */
264 VUSBPIPE aPipes[VUSB_PIPE_MAX];
[52301]265 /** Critical section protecting the active URB list. */
266 RTCRITSECT CritSectAsyncUrbs;
267 /** List of active async URBs. */
[59737]268 RTLISTANCHOR LstAsyncUrbs;
[26970]269
270 /** Dumper state. */
271 union VUSBDEVURBDUMPERSTATE
272 {
273 /** The current scsi command. */
274 uint8_t u8ScsiCmd;
275 } Urb;
276
[37359]277 /** The reset timer handle. */
[87762]278 TMTIMERHANDLE hResetTimer;
[52269]279 /** Reset handler arguments. */
280 void *pvArgs;
[49814]281 /** URB submit and reap thread. */
282 RTTHREAD hUrbIoThread;
[52254]283 /** Request queue for executing tasks on the I/O thread which should be done
284 * synchronous and without any other thread accessing the USB device. */
285 RTREQQUEUE hReqQueueSync;
[53062]286 /** Sniffer instance for this device if configured. */
287 VUSBSNIFFER hSniffer;
[49814]288 /** Flag whether the URB I/O thread should terminate. */
289 bool volatile fTerminate;
290 /** Flag whether the I/O thread was woken up. */
291 bool volatile fWokenUp;
[49097]292#if HC_ARCH_BITS == 32
293 /** Align the size to a 8 byte boundary. */
[53211]294 bool afAlignment0[2];
[49097]295#endif
[59720]296 /** The pool of free URBs for faster allocation. */
297 VUSBURBPOOL UrbPool;
[26970]298} VUSBDEV;
[52304]299AssertCompileSizeAlignment(VUSBDEV, 8);
[26970]300
301
[53062]302int vusbDevInit(PVUSBDEV pDev, PPDMUSBINS pUsbIns, const char *pszCaptureFilename);
[26970]303void vusbDevDestroy(PVUSBDEV pDev);
304bool vusbDevDoSelectConfig(PVUSBDEV dev, PCVUSBDESCCONFIGEX pCfg);
305void vusbDevMapEndpoint(PVUSBDEV dev, PCVUSBDESCENDPOINTEX ep);
306int vusbDevDetach(PVUSBDEV pDev);
[93979]307int vusbDevAttach(PVUSBDEV pDev, PVUSBROOTHUB pHub);
[26970]308DECLINLINE(PVUSBROOTHUB) vusbDevGetRh(PVUSBDEV pDev);
309size_t vusbDevMaxInterfaces(PVUSBDEV dev);
310
311void vusbDevSetAddress(PVUSBDEV pDev, uint8_t u8Address);
312bool vusbDevStandardRequest(PVUSBDEV pDev, int EndPt, PVUSBSETUP pSetup, void *pvBuf, uint32_t *pcbBuf);
313
314
315/** @} */
316
317
[81369]318/** @defgroup grp_vusb_int_hub Internal Hub Operations, Structures and Constants.
[26970]319 * @{
320 */
321
322
323/** @} */
324
325
[81369]326/** @defgroup grp_vusb_int_roothub Internal Root Hub Operations, Structures and Constants.
[26970]327 * @{
328 */
329
330/**
331 * Per transfer type statistics.
332 */
333typedef struct VUSBROOTHUBTYPESTATS
334{
335 STAMCOUNTER StatUrbsSubmitted;
336 STAMCOUNTER StatUrbsFailed;
337 STAMCOUNTER StatUrbsCancelled;
338
339 STAMCOUNTER StatReqBytes;
340 STAMCOUNTER StatReqReadBytes;
341 STAMCOUNTER StatReqWriteBytes;
342
343 STAMCOUNTER StatActBytes;
344 STAMCOUNTER StatActReadBytes;
345 STAMCOUNTER StatActWriteBytes;
346} VUSBROOTHUBTYPESTATS, *PVUSBROOTHUBTYPESTATS;
347
348
349
[93914]350/** Pointer to a VUSBROOTHUBLOAD struct. */
351typedef struct VUSBROOTHUBLOAD *PVUSBROOTHUBLOAD;
352
[26970]353/**
354 * The instance data of a root hub driver.
355 *
356 * This extends the generic VUSB hub.
357 *
358 * @implements VUSBIROOTHUBCONNECTOR
359 */
360typedef struct VUSBROOTHUB
361{
362 /** Pointer to the driver instance. */
[93914]363 PPDMDRVINS pDrvIns;
[26970]364 /** Pointer to the root hub port interface we're attached to. */
[93914]365 PVUSBIROOTHUBPORT pIRhPort;
[26970]366 /** Connector interface exposed upwards. */
[93914]367 VUSBIROOTHUBCONNECTOR IRhConnector;
[26970]368
[93934]369 /** Critical section protecting the device arrays. */
[93914]370 RTCRITSECT CritSectDevices;
371 /** Array of pointers to USB devices indexed by the port the device is on. */
372 PVUSBDEV apDevByPort[VUSB_DEVICES_MAX];
[93939]373 /** Array of pointers to USB devices indexed by the address assigned. */
374 PVUSBDEV apDevByAddr[VUSB_DEVICES_MAX];
[93914]375 /** Structure after a saved state load to re-attach devices. */
376 PVUSBROOTHUBLOAD pLoad;
377
[93989]378 /** Roothub device state. */
379 VUSBDEVICESTATE enmState;
[93979]380 /** Number of ports this roothub offers. */
381 uint16_t cPorts;
382 /** Number of devices attached to this roothub currently. */
383 uint16_t cDevices;
384 /** Name of the roothub. Used for logging. */
385 char *pszName;
[93989]386 /** URB pool for URBs from the roothub. */
387 VUSBURBPOOL UrbPool;
[93979]388
[52307]389#if HC_ARCH_BITS == 32
[59875]390 uint32_t Alignment0;
[52307]391#endif
392
[26970]393 /** Availability Bitmap. */
[59875]394 VUSBPORTBITMAP Bitmap;
[26970]395
[53067]396 /** Sniffer instance for the root hub. */
[59875]397 VUSBSNIFFER hSniffer;
[26970]398 /** Version of the attached Host Controller. */
[59875]399 uint32_t fHcVersions;
[59700]400 /** Size of the HCI specific data for each URB. */
[59875]401 size_t cbHci;
[59700]402 /** Size of the HCI specific TD. */
[59875]403 size_t cbHciTd;
404
405 /** The periodic frame processing thread. */
406 R3PTRTYPE(PPDMTHREAD) hThreadPeriodFrame;
407 /** Event semaphore to interact with the periodic frame processing thread. */
408 R3PTRTYPE(RTSEMEVENTMULTI) hSemEventPeriodFrame;
409 /** Event semaphore to release the thread waiting for the periodic frame processing thread to stop. */
410 R3PTRTYPE(RTSEMEVENTMULTI) hSemEventPeriodFrameStopped;
411 /** Current default frame rate for periodic frame processing thread. */
412 volatile uint32_t uFrameRateDefault;
413 /** Current frame rate (can be lower than the default frame rate if there is no activity). */
414 uint32_t uFrameRate;
415 /** How long to wait until the next frame. */
416 uint64_t nsWait;
417 /** Timestamp when the last frame was processed. */
418 uint64_t tsFrameProcessed;
419 /** Number of USB work cycles with no transfers. */
420 uint32_t cIdleCycles;
421
422 /** Flag whether a frame is currently being processed. */
423 volatile bool fFrameProcessing;
424
425#if HC_ARCH_BITS == 32
426 uint32_t Alignment1;
427#endif
428
[59687]429#ifdef LOG_ENABLED
430 /** A serial number for URBs submitted on the roothub instance.
431 * Only logging builds. */
[59875]432 uint32_t iSerial;
[59687]433 /** Alignment */
[59875]434 uint32_t Alignment2;
[59687]435#endif
[26970]436#ifdef VBOX_WITH_STATISTICS
437 VUSBROOTHUBTYPESTATS Total;
438 VUSBROOTHUBTYPESTATS aTypes[VUSBXFERTYPE_MSG];
439 STAMCOUNTER StatIsocReqPkts;
440 STAMCOUNTER StatIsocReqReadPkts;
441 STAMCOUNTER StatIsocReqWritePkts;
442 STAMCOUNTER StatIsocActPkts;
443 STAMCOUNTER StatIsocActReadPkts;
444 STAMCOUNTER StatIsocActWritePkts;
445 struct
446 {
447 STAMCOUNTER Pkts;
448 STAMCOUNTER Ok;
449 STAMCOUNTER Ok0;
450 STAMCOUNTER DataUnderrun;
451 STAMCOUNTER DataUnderrun0;
452 STAMCOUNTER DataOverrun;
453 STAMCOUNTER NotAccessed;
454 STAMCOUNTER Misc;
455 STAMCOUNTER Bytes;
456 } aStatIsocDetails[8];
457
458 STAMPROFILE StatReapAsyncUrbs;
459 STAMPROFILE StatSubmitUrb;
[59875]460 STAMCOUNTER StatFramesProcessedClbk;
461 STAMCOUNTER StatFramesProcessedThread;
[26970]462#endif
463} VUSBROOTHUB;
[31058]464AssertCompileMemberAlignment(VUSBROOTHUB, IRhConnector, 8);
465AssertCompileMemberAlignment(VUSBROOTHUB, Bitmap, 8);
[52301]466AssertCompileMemberAlignment(VUSBROOTHUB, CritSectDevices, 8);
[31058]467#ifdef VBOX_WITH_STATISTICS
468AssertCompileMemberAlignment(VUSBROOTHUB, Total, 8);
469#endif
[26970]470
471/** Converts a pointer to VUSBROOTHUB::IRhConnector to a PVUSBROOTHUB. */
[73097]472#define VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface) (PVUSBROOTHUB)( (uintptr_t)(pInterface) - RT_UOFFSETOF(VUSBROOTHUB, IRhConnector) )
[26970]473
[32010]474/**
475 * URB cancellation modes
476 */
477typedef enum CANCELMODE
478{
479 /** complete the URB with an error (CRC). */
480 CANCELMODE_FAIL = 0,
481 /** do not change the URB contents. */
482 CANCELMODE_UNDO
483} CANCELMODE;
[26970]484
[81369]485/** @} */
[26970]486
487
488
[81369]489/** @defgroup grp_vusb_int_urb Internal URB Operations, Structures and Constants.
[26970]490 * @{ */
491int vusbUrbSubmit(PVUSBURB pUrb);
[59737]492void vusbUrbDoReapAsync(PRTLISTANCHOR pUrbLst, RTMSINTERVAL cMillies);
[49814]493void vusbUrbDoReapAsyncDev(PVUSBDEV pDev, RTMSINTERVAL cMillies);
[32010]494void vusbUrbCancel(PVUSBURB pUrb, CANCELMODE mode);
[52301]495void vusbUrbCancelAsync(PVUSBURB pUrb, CANCELMODE mode);
[26970]496void vusbUrbRipe(PVUSBURB pUrb);
[93993]497void vusbUrbCompletionRhEx(PVUSBROOTHUB pRh, PVUSBURB pUrb);
[49814]498int vusbUrbSubmitHardError(PVUSBURB pUrb);
[93993]499int vusbUrbErrorRhEx(PVUSBROOTHUB pRh, PVUSBURB pUrb);
[49814]500int vusbDevUrbIoThreadWakeup(PVUSBDEV pDev);
501int vusbDevUrbIoThreadCreate(PVUSBDEV pDev);
502int vusbDevUrbIoThreadDestroy(PVUSBDEV pDev);
[59775]503DECLHIDDEN(void) vusbDevCancelAllUrbs(PVUSBDEV pDev, bool fDetaching);
[52269]504DECLHIDDEN(int) vusbDevIoThreadExecV(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
505DECLHIDDEN(int) vusbDevIoThreadExec(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
[52254]506DECLHIDDEN(int) vusbDevIoThreadExecSync(PVUSBDEV pDev, PFNRT pfnFunction, unsigned cArgs, ...);
[53633]507DECLHIDDEN(int) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode);
[26970]508
[59875]509DECLHIDDEN(uint64_t) vusbRhR3ProcessFrame(PVUSBROOTHUB pThis, bool fCallback);
510
[26970]511int vusbUrbQueueAsyncRh(PVUSBURB pUrb);
512
[90049]513bool vusbDevIsDescriptorInCache(PVUSBDEV pDev, PCVUSBSETUP pSetup);
514
[59718]515/**
516 * Initializes the given URB pool.
517 *
518 * @returns VBox status code.
519 * @param pUrbPool The URB pool to initialize.
520 */
521DECLHIDDEN(int) vusbUrbPoolInit(PVUSBURBPOOL pUrbPool);
522
523/**
524 * Destroy a given URB pool freeing all ressources.
525 *
526 * @param pUrbPool The URB pool to destroy.
527 */
528DECLHIDDEN(void) vusbUrbPoolDestroy(PVUSBURBPOOL pUrbPool);
529
530/**
531 * Allocate a new URB from the given URB pool.
532 *
533 * @returns Pointer to the new URB or NULL if out of memory.
534 * @param pUrbPool The URB pool to allocate from.
535 * @param enmType Type of the URB.
536 * @param enmDir The direction of the URB.
537 * @param cbData The number of bytes to allocate for the data buffer.
538 * @param cbHci Size of the data private to the HCI for each URB when allocated.
539 * @param cbHciTd Size of one transfer descriptor.
540 * @param cTds Number of transfer descriptors.
541 */
542DECLHIDDEN(PVUSBURB) vusbUrbPoolAlloc(PVUSBURBPOOL pUrbPool, VUSBXFERTYPE enmType,
543 VUSBDIRECTION enmDir, size_t cbData,
544 size_t cbHci, size_t cbHciTd, unsigned cTds);
545
546/**
547 * Frees a given URB.
548 *
549 * @param pUrbPool The URB pool the URB was allocated from.
550 * @param pUrb The URB to free.
551 */
552DECLHIDDEN(void) vusbUrbPoolFree(PVUSBURBPOOL pUrbPool, PVUSBURB pUrb);
553
[59738]554#ifdef LOG_ENABLED
[99739]555
[59738]556/**
557 * Logs an URB in the debug log.
558 *
559 * @param pUrb The URB to log.
560 * @param pszMsg Additional message to log.
561 * @param fComplete Flag whther the URB is completing.
562 */
563DECLHIDDEN(void) vusbUrbTrace(PVUSBURB pUrb, const char *pszMsg, bool fComplete);
[59718]564
[59738]565/**
566 * Return the USB direction as a string from the given enum.
567 */
568DECLHIDDEN(const char *) vusbUrbDirName(VUSBDIRECTION enmDir);
569
570/**
571 * Return the URB type as string from the given enum.
572 */
573DECLHIDDEN(const char *) vusbUrbTypeName(VUSBXFERTYPE enmType);
574
575/**
576 * Return the URB status as string from the given enum.
577 */
578DECLHIDDEN(const char *) vusbUrbStatusName(VUSBSTATUS enmStatus);
579
[99739]580#endif /* LOG_ENABLED*/
581
[26970]582DECLINLINE(void) vusbUrbUnlink(PVUSBURB pUrb)
583{
[59704]584 PVUSBDEV pDev = pUrb->pVUsb->pDev;
[49814]585
[52301]586 RTCritSectEnter(&pDev->CritSectAsyncUrbs);
[59737]587 RTListNodeRemove(&pUrb->pVUsb->NdLst);
[52301]588 RTCritSectLeave(&pDev->CritSectAsyncUrbs);
[26970]589}
590
[93993]591
592DECLINLINE(int) vusbUrbErrorRh(PVUSBURB pUrb)
593{
594 PVUSBDEV pDev = pUrb->pVUsb->pDev;
595 PVUSBROOTHUB pRh = vusbDevGetRh(pDev);
596 AssertPtrReturn(pRh, VERR_VUSB_DEVICE_NOT_ATTACHED);
597
598 return vusbUrbErrorRhEx(pRh, pUrb);
599}
600
601
602DECLINLINE(void) vusbUrbCompletionRh(PVUSBURB pUrb)
603{
604 PVUSBROOTHUB pRh = vusbDevGetRh(pUrb->pVUsb->pDev);
605 AssertPtrReturnVoid(pRh);
606
607 vusbUrbCompletionRhEx(pRh, pUrb);
608}
609
610
[26970]611/** @def vusbUrbAssert
612 * Asserts that a URB is valid.
613 */
614#ifdef VBOX_STRICT
615# define vusbUrbAssert(pUrb) do { \
[90791]616 AssertPtr((pUrb)); \
[26970]617 AssertMsg((pUrb)->u32Magic == VUSBURB_MAGIC, ("%#x", (pUrb)->u32Magic)); \
618 AssertMsg((pUrb)->enmState > VUSBURBSTATE_INVALID && (pUrb)->enmState < VUSBURBSTATE_END, \
619 ("%d\n", (pUrb)->enmState)); \
620 } while (0)
621#else
622# define vusbUrbAssert(pUrb) do {} while (0)
623#endif
624
[52881]625/**
626 * @def VUSBDEV_ASSERT_VALID_STATE
627 * Asserts that the give device state is valid.
628 */
629#define VUSBDEV_ASSERT_VALID_STATE(enmState) \
630 AssertMsg((enmState) > VUSB_DEVICE_STATE_INVALID && (enmState) < VUSB_DEVICE_STATE_DESTROYED, ("enmState=%#x\n", enmState));
631
[52269]632/** Executes a function synchronously. */
633#define VUSB_DEV_IO_THREAD_EXEC_FLAGS_SYNC RT_BIT_32(0)
634
[26970]635/** @} */
636
637
638/**
639 * Gets the roothub of a device.
640 *
641 * @returns Pointer to the roothub instance the device is attached to.
642 * @returns NULL if not attached to any hub.
643 * @param pDev Pointer to the device in question.
644 */
645DECLINLINE(PVUSBROOTHUB) vusbDevGetRh(PVUSBDEV pDev)
646{
647 if (!pDev->pHub)
648 return NULL;
[93979]649 return pDev->pHub;
[26970]650}
651
652
[52881]653/**
654 * Returns the state of the USB device.
655 *
656 * @returns State of the USB device.
657 * @param pDev Pointer to the device.
658 */
659DECLINLINE(VUSBDEVICESTATE) vusbDevGetState(PVUSBDEV pDev)
660{
661 VUSBDEVICESTATE enmState = (VUSBDEVICESTATE)ASMAtomicReadU32((volatile uint32_t *)&pDev->enmState);
662 VUSBDEV_ASSERT_VALID_STATE(enmState);
663 return enmState;
664}
[26970]665
[52881]666
667/**
668 * Sets the given state for the USB device.
669 *
670 * @returns The old state of the device.
671 * @param pDev Pointer to the device.
672 * @param enmState The new state to set.
673 */
674DECLINLINE(VUSBDEVICESTATE) vusbDevSetState(PVUSBDEV pDev, VUSBDEVICESTATE enmState)
675{
676 VUSBDEV_ASSERT_VALID_STATE(enmState);
677 VUSBDEVICESTATE enmStateOld = (VUSBDEVICESTATE)ASMAtomicXchgU32((volatile uint32_t *)&pDev->enmState, enmState);
678 VUSBDEV_ASSERT_VALID_STATE(enmStateOld);
679 return enmStateOld;
680}
681
682
683/**
684 * Compare and exchange the states for the given USB device.
685 *
686 * @returns true if the state was changed.
687 * @returns false if the state wasn't changed.
688 * @param pDev Pointer to the device.
689 * @param enmStateNew The new state to set.
690 * @param enmStateOld The old state to compare with.
691 */
692DECLINLINE(bool) vusbDevSetStateCmp(PVUSBDEV pDev, VUSBDEVICESTATE enmStateNew, VUSBDEVICESTATE enmStateOld)
693{
694 VUSBDEV_ASSERT_VALID_STATE(enmStateNew);
695 VUSBDEV_ASSERT_VALID_STATE(enmStateOld);
696 return ASMAtomicCmpXchgU32((volatile uint32_t *)&pDev->enmState, enmStateNew, enmStateOld);
697}
698
[62294]699/**
700 * Retains the given VUSB device pointer.
701 *
702 * @returns New reference count.
703 * @param pThis The VUSB device pointer.
[93989]704 * @param pszWho Caller of the retaining.
[62294]705 */
[93989]706DECLINLINE(uint32_t) vusbDevRetain(PVUSBDEV pThis, const char *pszWho)
[62294]707{
708 AssertPtrReturn(pThis, UINT32_MAX);
709
710 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
[93989]711 LogFlowFunc(("pThis=%p{.cRefs=%u}[%s]\n", pThis, cRefs, pszWho)); RT_NOREF(pszWho);
[62294]712 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
713 return cRefs;
714}
715
716/**
717 * Releases the given VUSB device pointer.
718 *
719 * @returns New reference count.
720 * @retval 0 if no onw is holding a reference anymore causing the device to be destroyed.
[93989]721 * @param pThis The VUSB device pointer.
722 * @param pszWho Caller of the retaining.
[62294]723 */
[93989]724DECLINLINE(uint32_t) vusbDevRelease(PVUSBDEV pThis, const char *pszWho)
[62294]725{
726 AssertPtrReturn(pThis, UINT32_MAX);
727
728 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
[93989]729 LogFlowFunc(("pThis=%p{.cRefs=%u}[%s]\n", pThis, cRefs, pszWho)); RT_NOREF(pszWho);
[62294]730 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
731 if (cRefs == 0)
732 vusbDevDestroy(pThis);
733 return cRefs;
734}
735
[26970]736/** Strings for the CTLSTAGE enum values. */
737extern const char * const g_apszCtlStates[4];
738
[81369]739/** @} */
[26970]740RT_C_DECLS_END
[76565]741#endif /* !VBOX_INCLUDED_SRC_USB_VUSBInternal_h */
[26970]742
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use