VirtualBox

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

Last change on this file since 66348 was 66348, checked in by vboxsync, 8 years ago

Undo wrong commit.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.5 KB
Line 
1/* $Id: VUSBInternal.h 66348 2017-03-29 19:48:31Z 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-2016 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} VUSBPIPE;
161/** Pointer to a VUSB pipe structure. */
162typedef VUSBPIPE *PVUSBPIPE;
163
164
165/**
166 * Interface state and possible settings.
167 */
168typedef struct vusb_interface_state
169{
170 /** Pointer to the interface descriptor of the currently selected (active)
171 * interface. */
172 PCVUSBDESCINTERFACEEX pCurIfDesc;
173 /** Pointer to the interface settings. */
174 PCVUSBINTERFACE pIf;
175} VUSBINTERFACESTATE;
176/** Pointer to interface state. */
177typedef VUSBINTERFACESTATE *PVUSBINTERFACESTATE;
178/** Pointer to const interface state. */
179typedef const VUSBINTERFACESTATE *PCVUSBINTERFACESTATE;
180
181
182/**
183 * VUSB URB pool.
184 */
185typedef struct VUSBURBPOOL
186{
187 /** Critical section protecting the pool. */
188 RTCRITSECT CritSectPool;
189 /** Chain of free URBs by type. (Singly linked) */
190 RTLISTANCHOR aLstFreeUrbs[VUSBXFERTYPE_ELEMENTS];
191 /** The number of URBs in the pool. */
192 volatile uint32_t cUrbsInPool;
193 /** Align the size to a 8 byte boundary. */
194 uint32_t Alignment0;
195} VUSBURBPOOL;
196/** Pointer to a VUSB URB pool. */
197typedef VUSBURBPOOL *PVUSBURBPOOL;
198
199AssertCompileSizeAlignment(VUSBURBPOOL, 8);
200
201/**
202 * A Virtual USB device (core).
203 *
204 * @implements VUSBIDEVICE
205 */
206typedef struct VUSBDEV
207{
208 /** The device interface exposed to the HCI. */
209 VUSBIDEVICE IDevice;
210 /** Pointer to the PDM USB device instance. */
211 PPDMUSBINS pUsbIns;
212 /** Next device in the chain maintained by the roothub. */
213 PVUSBDEV pNext;
214 /** Pointer to the next device with the same address hash. */
215 PVUSBDEV pNextHash;
216 /** Pointer to the hub this device is attached to. */
217 PVUSBHUB pHub;
218 /** The device state. */
219 VUSBDEVICESTATE volatile enmState;
220 /** Reference counter to protect the device structure from going away. */
221 uint32_t volatile cRefs;
222
223 /** The device address. */
224 uint8_t u8Address;
225 /** The new device address. */
226 uint8_t u8NewAddress;
227 /** The port. */
228 int16_t i16Port;
229 /** Device status. (VUSB_DEV_SELF_POWERED or not.) */
230 uint16_t u16Status;
231
232 /** Pointer to the descriptor cache.
233 * (Provided by the device thru the pfnGetDescriptorCache method.) */
234 PCPDMUSBDESCCACHE pDescCache;
235 /** Current configuration. */
236 PCVUSBDESCCONFIGEX pCurCfgDesc;
237
238 /** Current interface state (including alternate interface setting) - maximum
239 * valid index is config->bNumInterfaces
240 */
241 PVUSBINTERFACESTATE paIfStates;
242
243 /** Pipe/direction -> endpoint descriptor mapping */
244 VUSBPIPE aPipes[VUSB_PIPE_MAX];
245 /** Critical section protecting the active URB list. */
246 RTCRITSECT CritSectAsyncUrbs;
247 /** List of active async URBs. */
248 RTLISTANCHOR LstAsyncUrbs;
249
250 /** Dumper state. */
251 union VUSBDEVURBDUMPERSTATE
252 {
253 /** The current scsi command. */
254 uint8_t u8ScsiCmd;
255 } Urb;
256
257 /** The reset timer handle. */
258 PTMTIMER pResetTimer;
259 /** Reset handler arguments. */
260 void *pvArgs;
261 /** URB submit and reap thread. */
262 RTTHREAD hUrbIoThread;
263 /** Request queue for executing tasks on the I/O thread which should be done
264 * synchronous and without any other thread accessing the USB device. */
265 RTREQQUEUE hReqQueueSync;
266 /** Sniffer instance for this device if configured. */
267 VUSBSNIFFER hSniffer;
268 /** Flag whether the URB I/O thread should terminate. */
269 bool volatile fTerminate;
270 /** Flag whether the I/O thread was woken up. */
271 bool volatile fWokenUp;
272#if HC_ARCH_BITS == 32
273 /** Align the size to a 8 byte boundary. */
274 bool afAlignment0[2];
275#endif
276 /** The pool of free URBs for faster allocation. */
277 VUSBURBPOOL UrbPool;
278} VUSBDEV;
279AssertCompileSizeAlignment(VUSBDEV, 8);
280
281
282int vusbDevInit(PVUSBDEV pDev, PPDMUSBINS pUsbIns, const char *pszCaptureFilename);
283void vusbDevDestroy(PVUSBDEV pDev);
284
285DECLINLINE(bool) vusbDevIsRh(PVUSBDEV pDev)
286{
287 return (pDev->pHub == (PVUSBHUB)pDev);
288}
289
290bool vusbDevDoSelectConfig(PVUSBDEV dev, PCVUSBDESCCONFIGEX pCfg);
291void vusbDevMapEndpoint(PVUSBDEV dev, PCVUSBDESCENDPOINTEX ep);
292int vusbDevDetach(PVUSBDEV pDev);
293DECLINLINE(PVUSBROOTHUB) vusbDevGetRh(PVUSBDEV pDev);
294size_t vusbDevMaxInterfaces(PVUSBDEV dev);
295
296void vusbDevSetAddress(PVUSBDEV pDev, uint8_t u8Address);
297bool vusbDevStandardRequest(PVUSBDEV pDev, int EndPt, PVUSBSETUP pSetup, void *pvBuf, uint32_t *pcbBuf);
298
299
300/** @} */
301
302
303/** @name Internal Hub Operations, Structures and Constants.
304 * @{
305 */
306
307
308/** Virtual method table for USB hub devices.
309 * Hub and roothub drivers need to implement these functions in addition to the
310 * vusb_dev_ops.
311 */
312typedef struct VUSBHUBOPS
313{
314 int (*pfnAttach)(PVUSBHUB pHub, PVUSBDEV pDev);
315 void (*pfnDetach)(PVUSBHUB pHub, PVUSBDEV pDev);
316} VUSBHUBOPS;
317/** Pointer to a const HUB method table. */
318typedef const VUSBHUBOPS *PCVUSBHUBOPS;
319
320/** A VUSB Hub Device - Hub and roothub drivers need to use this struct
321 * @todo eliminate this (PDM / roothubs only).
322 */
323typedef struct VUSBHUB
324{
325 VUSBDEV Dev;
326 PCVUSBHUBOPS pOps;
327 PVUSBROOTHUB pRootHub;
328 uint16_t cPorts;
329 uint16_t cDevices;
330 /** Name of the hub. Used for logging. */
331 char *pszName;
332} VUSBHUB;
333AssertCompileMemberAlignment(VUSBHUB, pOps, 8);
334AssertCompileSizeAlignment(VUSBHUB, 8);
335
336/** @} */
337
338
339/** @name Internal Root Hub Operations, Structures and Constants.
340 * @{
341 */
342
343/**
344 * Per transfer type statistics.
345 */
346typedef struct VUSBROOTHUBTYPESTATS
347{
348 STAMCOUNTER StatUrbsSubmitted;
349 STAMCOUNTER StatUrbsFailed;
350 STAMCOUNTER StatUrbsCancelled;
351
352 STAMCOUNTER StatReqBytes;
353 STAMCOUNTER StatReqReadBytes;
354 STAMCOUNTER StatReqWriteBytes;
355
356 STAMCOUNTER StatActBytes;
357 STAMCOUNTER StatActReadBytes;
358 STAMCOUNTER StatActWriteBytes;
359} VUSBROOTHUBTYPESTATS, *PVUSBROOTHUBTYPESTATS;
360
361
362
363/** The address hash table size. */
364#define VUSB_ADDR_HASHSZ 5
365
366/**
367 * The instance data of a root hub driver.
368 *
369 * This extends the generic VUSB hub.
370 *
371 * @implements VUSBIROOTHUBCONNECTOR
372 */
373typedef struct VUSBROOTHUB
374{
375 /** The HUB.
376 * @todo remove this? */
377 VUSBHUB Hub;
378 /** Address hash table. */
379 PVUSBDEV apAddrHash[VUSB_ADDR_HASHSZ];
380 /** The default address. */
381 PVUSBDEV pDefaultAddress;
382
383 /** Pointer to the driver instance. */
384 PPDMDRVINS pDrvIns;
385 /** Pointer to the root hub port interface we're attached to. */
386 PVUSBIROOTHUBPORT pIRhPort;
387 /** Connector interface exposed upwards. */
388 VUSBIROOTHUBCONNECTOR IRhConnector;
389
390 /** Critical section protecting the device list. */
391 RTCRITSECT CritSectDevices;
392 /** Chain of devices attached to this hub. */
393 PVUSBDEV pDevices;
394
395#if HC_ARCH_BITS == 32
396 uint32_t Alignment0;
397#endif
398
399 /** Availability Bitmap. */
400 VUSBPORTBITMAP Bitmap;
401
402 /** Sniffer instance for the root hub. */
403 VUSBSNIFFER hSniffer;
404 /** Version of the attached Host Controller. */
405 uint32_t fHcVersions;
406 /** Size of the HCI specific data for each URB. */
407 size_t cbHci;
408 /** Size of the HCI specific TD. */
409 size_t cbHciTd;
410
411 /** The periodic frame processing thread. */
412 R3PTRTYPE(PPDMTHREAD) hThreadPeriodFrame;
413 /** Event semaphore to interact with the periodic frame processing thread. */
414 R3PTRTYPE(RTSEMEVENTMULTI) hSemEventPeriodFrame;
415 /** Event semaphore to release the thread waiting for the periodic frame processing thread to stop. */
416 R3PTRTYPE(RTSEMEVENTMULTI) hSemEventPeriodFrameStopped;
417 /** Current default frame rate for periodic frame processing thread. */
418 volatile uint32_t uFrameRateDefault;
419 /** Current frame rate (can be lower than the default frame rate if there is no activity). */
420 uint32_t uFrameRate;
421 /** How long to wait until the next frame. */
422 uint64_t nsWait;
423 /** Timestamp when the last frame was processed. */
424 uint64_t tsFrameProcessed;
425 /** Number of USB work cycles with no transfers. */
426 uint32_t cIdleCycles;
427
428 /** Flag whether a frame is currently being processed. */
429 volatile bool fFrameProcessing;
430
431#if HC_ARCH_BITS == 32
432 uint32_t Alignment1;
433#endif
434
435#ifdef LOG_ENABLED
436 /** A serial number for URBs submitted on the roothub instance.
437 * Only logging builds. */
438 uint32_t iSerial;
439 /** Alignment */
440 uint32_t Alignment2;
441#endif
442#ifdef VBOX_WITH_STATISTICS
443 VUSBROOTHUBTYPESTATS Total;
444 VUSBROOTHUBTYPESTATS aTypes[VUSBXFERTYPE_MSG];
445 STAMCOUNTER StatIsocReqPkts;
446 STAMCOUNTER StatIsocReqReadPkts;
447 STAMCOUNTER StatIsocReqWritePkts;
448 STAMCOUNTER StatIsocActPkts;
449 STAMCOUNTER StatIsocActReadPkts;
450 STAMCOUNTER StatIsocActWritePkts;
451 struct
452 {
453 STAMCOUNTER Pkts;
454 STAMCOUNTER Ok;
455 STAMCOUNTER Ok0;
456 STAMCOUNTER DataUnderrun;
457 STAMCOUNTER DataUnderrun0;
458 STAMCOUNTER DataOverrun;
459 STAMCOUNTER NotAccessed;
460 STAMCOUNTER Misc;
461 STAMCOUNTER Bytes;
462 } aStatIsocDetails[8];
463
464 STAMPROFILE StatReapAsyncUrbs;
465 STAMPROFILE StatSubmitUrb;
466 STAMCOUNTER StatFramesProcessedClbk;
467 STAMCOUNTER StatFramesProcessedThread;
468#endif
469} VUSBROOTHUB;
470AssertCompileMemberAlignment(VUSBROOTHUB, IRhConnector, 8);
471AssertCompileMemberAlignment(VUSBROOTHUB, Bitmap, 8);
472AssertCompileMemberAlignment(VUSBROOTHUB, CritSectDevices, 8);
473#ifdef VBOX_WITH_STATISTICS
474AssertCompileMemberAlignment(VUSBROOTHUB, Total, 8);
475#endif
476
477/** Converts a pointer to VUSBROOTHUB::IRhConnector to a PVUSBROOTHUB. */
478#define VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface) (PVUSBROOTHUB)( (uintptr_t)(pInterface) - RT_OFFSETOF(VUSBROOTHUB, IRhConnector) )
479
480/**
481 * URB cancellation modes
482 */
483typedef enum CANCELMODE
484{
485 /** complete the URB with an error (CRC). */
486 CANCELMODE_FAIL = 0,
487 /** do not change the URB contents. */
488 CANCELMODE_UNDO
489} CANCELMODE;
490
491/* @} */
492
493
494
495/** @name Internal URB Operations, Structures and Constants.
496 * @{ */
497int vusbUrbSubmit(PVUSBURB pUrb);
498void vusbUrbDoReapAsync(PRTLISTANCHOR pUrbLst, RTMSINTERVAL cMillies);
499void vusbUrbDoReapAsyncDev(PVUSBDEV pDev, RTMSINTERVAL cMillies);
500void vusbUrbCancel(PVUSBURB pUrb, CANCELMODE mode);
501void vusbUrbCancelAsync(PVUSBURB pUrb, CANCELMODE mode);
502void vusbUrbRipe(PVUSBURB pUrb);
503void vusbUrbCompletionRh(PVUSBURB pUrb);
504int vusbUrbSubmitHardError(PVUSBURB pUrb);
505int vusbUrbErrorRh(PVUSBURB pUrb);
506int vusbDevUrbIoThreadWakeup(PVUSBDEV pDev);
507int vusbDevUrbIoThreadCreate(PVUSBDEV pDev);
508int vusbDevUrbIoThreadDestroy(PVUSBDEV pDev);
509DECLHIDDEN(void) vusbDevCancelAllUrbs(PVUSBDEV pDev, bool fDetaching);
510DECLHIDDEN(int) vusbDevIoThreadExecV(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
511DECLHIDDEN(int) vusbDevIoThreadExec(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
512DECLHIDDEN(int) vusbDevIoThreadExecSync(PVUSBDEV pDev, PFNRT pfnFunction, unsigned cArgs, ...);
513DECLHIDDEN(int) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode);
514
515DECLHIDDEN(uint64_t) vusbRhR3ProcessFrame(PVUSBROOTHUB pThis, bool fCallback);
516
517int vusbUrbQueueAsyncRh(PVUSBURB pUrb);
518
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 * @returns nothing.
531 * @param pUrbPool The URB pool to destroy.
532 */
533DECLHIDDEN(void) vusbUrbPoolDestroy(PVUSBURBPOOL pUrbPool);
534
535/**
536 * Allocate a new URB from the given URB pool.
537 *
538 * @returns Pointer to the new URB or NULL if out of memory.
539 * @param pUrbPool The URB pool to allocate from.
540 * @param enmType Type of the URB.
541 * @param enmDir The direction of the URB.
542 * @param cbData The number of bytes to allocate for the data buffer.
543 * @param cbHci Size of the data private to the HCI for each URB when allocated.
544 * @param cbHciTd Size of one transfer descriptor.
545 * @param cTds Number of transfer descriptors.
546 */
547DECLHIDDEN(PVUSBURB) vusbUrbPoolAlloc(PVUSBURBPOOL pUrbPool, VUSBXFERTYPE enmType,
548 VUSBDIRECTION enmDir, size_t cbData,
549 size_t cbHci, size_t cbHciTd, unsigned cTds);
550
551/**
552 * Frees a given URB.
553 *
554 * @returns nothing.
555 * @param pUrbPool The URB pool the URB was allocated from.
556 * @param pUrb The URB to free.
557 */
558DECLHIDDEN(void) vusbUrbPoolFree(PVUSBURBPOOL pUrbPool, PVUSBURB pUrb);
559
560#ifdef LOG_ENABLED
561/**
562 * Logs an URB in the debug log.
563 *
564 * @returns nothing.
565 * @param pUrb The URB to log.
566 * @param pszMsg Additional message to log.
567 * @param fComplete Flag whther the URB is completing.
568 */
569DECLHIDDEN(void) vusbUrbTrace(PVUSBURB pUrb, const char *pszMsg, bool fComplete);
570
571/**
572 * Return the USB direction as a string from the given enum.
573 */
574DECLHIDDEN(const char *) vusbUrbDirName(VUSBDIRECTION enmDir);
575
576/**
577 * Return the URB type as string from the given enum.
578 */
579DECLHIDDEN(const char *) vusbUrbTypeName(VUSBXFERTYPE enmType);
580
581/**
582 * Return the URB status as string from the given enum.
583 */
584DECLHIDDEN(const char *) vusbUrbStatusName(VUSBSTATUS enmStatus);
585#endif
586
587DECLINLINE(void) vusbUrbUnlink(PVUSBURB pUrb)
588{
589 PVUSBDEV pDev = pUrb->pVUsb->pDev;
590
591 RTCritSectEnter(&pDev->CritSectAsyncUrbs);
592 RTListNodeRemove(&pUrb->pVUsb->NdLst);
593 RTCritSectLeave(&pDev->CritSectAsyncUrbs);
594}
595
596/** @def vusbUrbAssert
597 * Asserts that a URB is valid.
598 */
599#ifdef VBOX_STRICT
600# define vusbUrbAssert(pUrb) do { \
601 AssertMsg(VALID_PTR((pUrb)), ("%p\n", (pUrb))); \
602 AssertMsg((pUrb)->u32Magic == VUSBURB_MAGIC, ("%#x", (pUrb)->u32Magic)); \
603 AssertMsg((pUrb)->enmState > VUSBURBSTATE_INVALID && (pUrb)->enmState < VUSBURBSTATE_END, \
604 ("%d\n", (pUrb)->enmState)); \
605 } while (0)
606#else
607# define vusbUrbAssert(pUrb) do {} while (0)
608#endif
609
610/**
611 * @def VUSBDEV_ASSERT_VALID_STATE
612 * Asserts that the give device state is valid.
613 */
614#define VUSBDEV_ASSERT_VALID_STATE(enmState) \
615 AssertMsg((enmState) > VUSB_DEVICE_STATE_INVALID && (enmState) < VUSB_DEVICE_STATE_DESTROYED, ("enmState=%#x\n", enmState));
616
617/** Executes a function synchronously. */
618#define VUSB_DEV_IO_THREAD_EXEC_FLAGS_SYNC RT_BIT_32(0)
619
620/** @} */
621
622
623
624
625/**
626 * Addresses are between 0 and 127 inclusive
627 */
628DECLINLINE(uint8_t) vusbHashAddress(uint8_t Address)
629{
630 uint8_t u8Hash = Address;
631 u8Hash ^= (Address >> 2);
632 u8Hash ^= (Address >> 3);
633 u8Hash %= VUSB_ADDR_HASHSZ;
634 return u8Hash;
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;
649 return pDev->pHub->pRootHub;
650}
651
652
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}
665
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
699/**
700 * Retains the given VUSB device pointer.
701 *
702 * @returns New reference count.
703 * @param pThis The VUSB device pointer.
704 */
705DECLINLINE(uint32_t) vusbDevRetain(PVUSBDEV pThis)
706{
707 AssertPtrReturn(pThis, UINT32_MAX);
708
709 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
710 AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
711 return cRefs;
712}
713
714/**
715 * Releases the given VUSB device pointer.
716 *
717 * @returns New reference count.
718 * @retval 0 if no onw is holding a reference anymore causing the device to be destroyed.
719 */
720DECLINLINE(uint32_t) vusbDevRelease(PVUSBDEV pThis)
721{
722 AssertPtrReturn(pThis, UINT32_MAX);
723
724 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
725 AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
726 if (cRefs == 0)
727 vusbDevDestroy(pThis);
728 return cRefs;
729}
730
731/** Strings for the CTLSTAGE enum values. */
732extern const char * const g_apszCtlStates[4];
733/** Default message pipe. */
734extern const VUSBDESCENDPOINTEX g_Endpoint0;
735/** Default configuration. */
736extern const VUSBDESCCONFIGEX g_Config0;
737
738RT_C_DECLS_END
739#endif
740
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