VirtualBox

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

Last change on this file since 93979 was 93979, checked in by vboxsync, 3 years ago

Devices/USB: Get rid of the VUSBHUB structure which was mostly meaningless as roothubs were supported only since forever, bugref:10196

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