VirtualBox

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

Last change on this file was 105377, checked in by vboxsync, 2 months ago

iprt/cdefs.h,*: s/RT_IPRT_CALL_ATTR/RT_IPRT_CALLREQ_ATTR/g bugref:10725

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.5 KB
RevLine 
[26970]1/* $Id: VUSBInternal.h 105377 2024-07-17 14:06:05Z 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;
[104804]424 /** Flag whether we are in the middle of saving the VM state. */
425 volatile bool fSavingState;
[59875]426
427#if HC_ARCH_BITS == 32
428 uint32_t Alignment1;
429#endif
430
[59687]431#ifdef LOG_ENABLED
432 /** A serial number for URBs submitted on the roothub instance.
433 * Only logging builds. */
[59875]434 uint32_t iSerial;
[59687]435 /** Alignment */
[59875]436 uint32_t Alignment2;
[59687]437#endif
[26970]438#ifdef VBOX_WITH_STATISTICS
439 VUSBROOTHUBTYPESTATS Total;
440 VUSBROOTHUBTYPESTATS aTypes[VUSBXFERTYPE_MSG];
441 STAMCOUNTER StatIsocReqPkts;
442 STAMCOUNTER StatIsocReqReadPkts;
443 STAMCOUNTER StatIsocReqWritePkts;
444 STAMCOUNTER StatIsocActPkts;
445 STAMCOUNTER StatIsocActReadPkts;
446 STAMCOUNTER StatIsocActWritePkts;
447 struct
448 {
449 STAMCOUNTER Pkts;
450 STAMCOUNTER Ok;
451 STAMCOUNTER Ok0;
452 STAMCOUNTER DataUnderrun;
453 STAMCOUNTER DataUnderrun0;
454 STAMCOUNTER DataOverrun;
455 STAMCOUNTER NotAccessed;
456 STAMCOUNTER Misc;
457 STAMCOUNTER Bytes;
458 } aStatIsocDetails[8];
459
460 STAMPROFILE StatReapAsyncUrbs;
461 STAMPROFILE StatSubmitUrb;
[59875]462 STAMCOUNTER StatFramesProcessedClbk;
463 STAMCOUNTER StatFramesProcessedThread;
[26970]464#endif
465} VUSBROOTHUB;
[31058]466AssertCompileMemberAlignment(VUSBROOTHUB, IRhConnector, 8);
467AssertCompileMemberAlignment(VUSBROOTHUB, Bitmap, 8);
[52301]468AssertCompileMemberAlignment(VUSBROOTHUB, CritSectDevices, 8);
[31058]469#ifdef VBOX_WITH_STATISTICS
470AssertCompileMemberAlignment(VUSBROOTHUB, Total, 8);
471#endif
[26970]472
473/** Converts a pointer to VUSBROOTHUB::IRhConnector to a PVUSBROOTHUB. */
[73097]474#define VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface) (PVUSBROOTHUB)( (uintptr_t)(pInterface) - RT_UOFFSETOF(VUSBROOTHUB, IRhConnector) )
[26970]475
[32010]476/**
477 * URB cancellation modes
478 */
479typedef enum CANCELMODE
480{
481 /** complete the URB with an error (CRC). */
482 CANCELMODE_FAIL = 0,
483 /** do not change the URB contents. */
484 CANCELMODE_UNDO
485} CANCELMODE;
[26970]486
[81369]487/** @} */
[26970]488
489
490
[81369]491/** @defgroup grp_vusb_int_urb Internal URB Operations, Structures and Constants.
[26970]492 * @{ */
493int vusbUrbSubmit(PVUSBURB pUrb);
[59737]494void vusbUrbDoReapAsync(PRTLISTANCHOR pUrbLst, RTMSINTERVAL cMillies);
[49814]495void vusbUrbDoReapAsyncDev(PVUSBDEV pDev, RTMSINTERVAL cMillies);
[32010]496void vusbUrbCancel(PVUSBURB pUrb, CANCELMODE mode);
[52301]497void vusbUrbCancelAsync(PVUSBURB pUrb, CANCELMODE mode);
[26970]498void vusbUrbRipe(PVUSBURB pUrb);
[93993]499void vusbUrbCompletionRhEx(PVUSBROOTHUB pRh, PVUSBURB pUrb);
[49814]500int vusbUrbSubmitHardError(PVUSBURB pUrb);
[93993]501int vusbUrbErrorRhEx(PVUSBROOTHUB pRh, PVUSBURB pUrb);
[49814]502int vusbDevUrbIoThreadWakeup(PVUSBDEV pDev);
503int vusbDevUrbIoThreadCreate(PVUSBDEV pDev);
504int vusbDevUrbIoThreadDestroy(PVUSBDEV pDev);
[59775]505DECLHIDDEN(void) vusbDevCancelAllUrbs(PVUSBDEV pDev, bool fDetaching);
[105353]506DECLHIDDEN(int) vusbDevIoThreadExecV(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction,
[105377]507 unsigned cArgs, va_list Args) RT_IPRT_CALLREQ_ATTR(3, 4, 0);
[105353]508DECLHIDDEN(int) vusbDevIoThreadExec(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction,
[105377]509 unsigned cArgs, ...) RT_IPRT_CALLREQ_ATTR(3, 4, 5);
510DECLHIDDEN(int) vusbDevIoThreadExecSync(PVUSBDEV pDev, PFNRT pfnFunction, unsigned cArgs, ...) RT_IPRT_CALLREQ_ATTR(2, 3, 4);
[53633]511DECLHIDDEN(int) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode);
[26970]512
[59875]513DECLHIDDEN(uint64_t) vusbRhR3ProcessFrame(PVUSBROOTHUB pThis, bool fCallback);
514
[26970]515int vusbUrbQueueAsyncRh(PVUSBURB pUrb);
516
[90049]517bool vusbDevIsDescriptorInCache(PVUSBDEV pDev, PCVUSBSETUP pSetup);
518
[59718]519/**
520 * Initializes the given URB pool.
521 *
522 * @returns VBox status code.
523 * @param pUrbPool The URB pool to initialize.
524 */
525DECLHIDDEN(int) vusbUrbPoolInit(PVUSBURBPOOL pUrbPool);
526
527/**
528 * Destroy a given URB pool freeing all ressources.
529 *
530 * @param pUrbPool The URB pool to destroy.
531 */
532DECLHIDDEN(void) vusbUrbPoolDestroy(PVUSBURBPOOL pUrbPool);
533
534/**
535 * Allocate a new URB from the given URB pool.
536 *
537 * @returns Pointer to the new URB or NULL if out of memory.
538 * @param pUrbPool The URB pool to allocate from.
539 * @param enmType Type of the URB.
540 * @param enmDir The direction of the URB.
541 * @param cbData The number of bytes to allocate for the data buffer.
542 * @param cbHci Size of the data private to the HCI for each URB when allocated.
543 * @param cbHciTd Size of one transfer descriptor.
544 * @param cTds Number of transfer descriptors.
545 */
546DECLHIDDEN(PVUSBURB) vusbUrbPoolAlloc(PVUSBURBPOOL pUrbPool, VUSBXFERTYPE enmType,
547 VUSBDIRECTION enmDir, size_t cbData,
548 size_t cbHci, size_t cbHciTd, unsigned cTds);
549
550/**
551 * Frees a given URB.
552 *
553 * @param pUrbPool The URB pool the URB was allocated from.
554 * @param pUrb The URB to free.
555 */
556DECLHIDDEN(void) vusbUrbPoolFree(PVUSBURBPOOL pUrbPool, PVUSBURB pUrb);
557
[59738]558#ifdef LOG_ENABLED
[99739]559
[59738]560/**
561 * Logs an URB in the debug log.
562 *
563 * @param pUrb The URB to log.
564 * @param pszMsg Additional message to log.
565 * @param fComplete Flag whther the URB is completing.
566 */
567DECLHIDDEN(void) vusbUrbTrace(PVUSBURB pUrb, const char *pszMsg, bool fComplete);
[59718]568
[59738]569/**
570 * Return the USB direction as a string from the given enum.
571 */
572DECLHIDDEN(const char *) vusbUrbDirName(VUSBDIRECTION enmDir);
573
574/**
575 * Return the URB type as string from the given enum.
576 */
577DECLHIDDEN(const char *) vusbUrbTypeName(VUSBXFERTYPE enmType);
578
579/**
580 * Return the URB status as string from the given enum.
581 */
582DECLHIDDEN(const char *) vusbUrbStatusName(VUSBSTATUS enmStatus);
583
[99739]584#endif /* LOG_ENABLED*/
585
[26970]586DECLINLINE(void) vusbUrbUnlink(PVUSBURB pUrb)
587{
[59704]588 PVUSBDEV pDev = pUrb->pVUsb->pDev;
[49814]589
[52301]590 RTCritSectEnter(&pDev->CritSectAsyncUrbs);
[59737]591 RTListNodeRemove(&pUrb->pVUsb->NdLst);
[52301]592 RTCritSectLeave(&pDev->CritSectAsyncUrbs);
[26970]593}
594
[93993]595
596DECLINLINE(int) vusbUrbErrorRh(PVUSBURB pUrb)
597{
598 PVUSBDEV pDev = pUrb->pVUsb->pDev;
599 PVUSBROOTHUB pRh = vusbDevGetRh(pDev);
600 AssertPtrReturn(pRh, VERR_VUSB_DEVICE_NOT_ATTACHED);
601
602 return vusbUrbErrorRhEx(pRh, pUrb);
603}
604
605
606DECLINLINE(void) vusbUrbCompletionRh(PVUSBURB pUrb)
607{
608 PVUSBROOTHUB pRh = vusbDevGetRh(pUrb->pVUsb->pDev);
609 AssertPtrReturnVoid(pRh);
610
611 vusbUrbCompletionRhEx(pRh, pUrb);
612}
613
614
[26970]615/** @def vusbUrbAssert
616 * Asserts that a URB is valid.
617 */
618#ifdef VBOX_STRICT
619# define vusbUrbAssert(pUrb) do { \
[90791]620 AssertPtr((pUrb)); \
[26970]621 AssertMsg((pUrb)->u32Magic == VUSBURB_MAGIC, ("%#x", (pUrb)->u32Magic)); \
622 AssertMsg((pUrb)->enmState > VUSBURBSTATE_INVALID && (pUrb)->enmState < VUSBURBSTATE_END, \
623 ("%d\n", (pUrb)->enmState)); \
624 } while (0)
625#else
626# define vusbUrbAssert(pUrb) do {} while (0)
627#endif
628
[52881]629/**
630 * @def VUSBDEV_ASSERT_VALID_STATE
631 * Asserts that the give device state is valid.
632 */
633#define VUSBDEV_ASSERT_VALID_STATE(enmState) \
634 AssertMsg((enmState) > VUSB_DEVICE_STATE_INVALID && (enmState) < VUSB_DEVICE_STATE_DESTROYED, ("enmState=%#x\n", enmState));
635
[52269]636/** Executes a function synchronously. */
637#define VUSB_DEV_IO_THREAD_EXEC_FLAGS_SYNC RT_BIT_32(0)
638
[26970]639/** @} */
640
641
642/**
643 * Gets the roothub of a device.
644 *
645 * @returns Pointer to the roothub instance the device is attached to.
646 * @returns NULL if not attached to any hub.
647 * @param pDev Pointer to the device in question.
648 */
649DECLINLINE(PVUSBROOTHUB) vusbDevGetRh(PVUSBDEV pDev)
650{
651 if (!pDev->pHub)
652 return NULL;
[93979]653 return pDev->pHub;
[26970]654}
655
656
[52881]657/**
658 * Returns the state of the USB device.
659 *
660 * @returns State of the USB device.
661 * @param pDev Pointer to the device.
662 */
663DECLINLINE(VUSBDEVICESTATE) vusbDevGetState(PVUSBDEV pDev)
664{
665 VUSBDEVICESTATE enmState = (VUSBDEVICESTATE)ASMAtomicReadU32((volatile uint32_t *)&pDev->enmState);
666 VUSBDEV_ASSERT_VALID_STATE(enmState);
667 return enmState;
668}
[26970]669
[52881]670
671/**
672 * Sets the given state for the USB device.
673 *
674 * @returns The old state of the device.
675 * @param pDev Pointer to the device.
676 * @param enmState The new state to set.
677 */
678DECLINLINE(VUSBDEVICESTATE) vusbDevSetState(PVUSBDEV pDev, VUSBDEVICESTATE enmState)
679{
680 VUSBDEV_ASSERT_VALID_STATE(enmState);
681 VUSBDEVICESTATE enmStateOld = (VUSBDEVICESTATE)ASMAtomicXchgU32((volatile uint32_t *)&pDev->enmState, enmState);
682 VUSBDEV_ASSERT_VALID_STATE(enmStateOld);
683 return enmStateOld;
684}
685
686
687/**
688 * Compare and exchange the states for the given USB device.
689 *
690 * @returns true if the state was changed.
691 * @returns false if the state wasn't changed.
692 * @param pDev Pointer to the device.
693 * @param enmStateNew The new state to set.
694 * @param enmStateOld The old state to compare with.
695 */
696DECLINLINE(bool) vusbDevSetStateCmp(PVUSBDEV pDev, VUSBDEVICESTATE enmStateNew, VUSBDEVICESTATE enmStateOld)
697{
698 VUSBDEV_ASSERT_VALID_STATE(enmStateNew);
699 VUSBDEV_ASSERT_VALID_STATE(enmStateOld);
700 return ASMAtomicCmpXchgU32((volatile uint32_t *)&pDev->enmState, enmStateNew, enmStateOld);
701}
702
[62294]703/**
704 * Retains the given VUSB device pointer.
705 *
706 * @returns New reference count.
707 * @param pThis The VUSB device pointer.
[93989]708 * @param pszWho Caller of the retaining.
[62294]709 */
[93989]710DECLINLINE(uint32_t) vusbDevRetain(PVUSBDEV pThis, const char *pszWho)
[62294]711{
712 AssertPtrReturn(pThis, UINT32_MAX);
713
714 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
[93989]715 LogFlowFunc(("pThis=%p{.cRefs=%u}[%s]\n", pThis, cRefs, pszWho)); RT_NOREF(pszWho);
[62294]716 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
717 return cRefs;
718}
719
720/**
721 * Releases the given VUSB device pointer.
722 *
723 * @returns New reference count.
724 * @retval 0 if no onw is holding a reference anymore causing the device to be destroyed.
[93989]725 * @param pThis The VUSB device pointer.
726 * @param pszWho Caller of the retaining.
[62294]727 */
[93989]728DECLINLINE(uint32_t) vusbDevRelease(PVUSBDEV pThis, const char *pszWho)
[62294]729{
730 AssertPtrReturn(pThis, UINT32_MAX);
731
732 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
[93989]733 LogFlowFunc(("pThis=%p{.cRefs=%u}[%s]\n", pThis, cRefs, pszWho)); RT_NOREF(pszWho);
[62294]734 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
735 if (cRefs == 0)
736 vusbDevDestroy(pThis);
737 return cRefs;
738}
739
[26970]740/** Strings for the CTLSTAGE enum values. */
741extern const char * const g_apszCtlStates[4];
742
[81369]743/** @} */
[26970]744RT_C_DECLS_END
[76565]745#endif /* !VBOX_INCLUDED_SRC_USB_VUSBInternal_h */
[26970]746
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