VirtualBox

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

Last change on this file since 74901 was 73097, checked in by vboxsync, 6 years ago

*: Made RT_UOFFSETOF, RT_OFFSETOF, RT_UOFFSETOF_ADD and RT_OFFSETOF_ADD work like builtin_offsetof() and require compile time resolvable requests, adding RT_UOFFSETOF_DYN for the dynamic questions that can only be answered at runtime.

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