cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/* $Id$ */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @file
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Virtual USB - Internal header.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * This subsystem implements USB devices in a host controller independent
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * way. All the host controller code has to do is use VUSBHUB for its
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * root hub implementation and any emulated USB device may be plugged into
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * the virtual bus.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2011 Oracle Corporation
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * available from http://www.virtualbox.org. This file is free software;
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * General Public License (GPL) as published by the Free Software
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#ifndef ___VUSBInternal_h
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define ___VUSBInternal_h
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#include <VBox/cdefs.h>
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#include <VBox/types.h>
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#include <VBox/vusb.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/stam.h>
ee271ac5f5a0f262528a59171392bffd9108509bvboxsync#include <iprt/assert.h>
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync#include <iprt/queueatomic.h>
b79e974bbebf5c83f3277b8f3a54ad98f2496caavboxsync#include <iprt/req.h>
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
dcc837f3a6f10996beb8aa7965f67f7f6c273fb4vboxsync#include "VUSBSniffer.h"
dcc837f3a6f10996beb8aa7965f67f7f6c273fb4vboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncRT_C_DECLS_BEGIN
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @name Internal Device Operations, Structures and Constants.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to a Virtual USB device (core). */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBDEV *PVUSBDEV;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to a VUSB hub device. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBHUB *PVUSBHUB;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to a VUSB root hub. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBROOTHUB *PVUSBROOTHUB;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Number of the default control endpoint */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_PIPE_DEFAULT 0
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @name Device addresses
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @{ */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_DEFAULT_ADDRESS 0
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_INVALID_ADDRESS UINT8_C(0xff)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @} */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @name Feature bits (1<<FEATURE for the u16Status bit)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @{ */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_DEV_SELF_POWERED 0
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_DEV_REMOTE_WAKEUP 1
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_EP_HALT 0
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @} */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Maximum number of endpoint addresses */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_PIPE_MAX 16
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Control-pipe stages.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef enum CTLSTAGE
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** the control pipe is in the setup stage. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync CTLSTAGE_SETUP = 0,
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** the control pipe is in the data stage. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync CTLSTAGE_DATA,
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** the control pipe is in the status stage. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync CTLSTAGE_STATUS
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} CTLSTAGE;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Extra data for a control pipe.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * This is state information needed for the special multi-stage
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * transfers performed on this kind of pipes.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct vusb_ctrl_extra
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Current pipe stage. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync CTLSTAGE enmStage;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Success indicator. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync bool fOk;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Set if the message URB has been submitted. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync bool fSubmitted;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the SETUP.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * This is a pointer to Urb->abData[0]. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBSETUP pMsg;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Current DATA pointer.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * This starts at pMsg + 1 and is incremented at we read/write data. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint8_t *pbCur;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The amount of data left to read on IN operations.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * On OUT operations this is not used. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint32_t cbLeft;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The amount of data we can house.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * This starts at the default 8KB, and this structure will be reallocated to
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * accommodate any larger request (unlikely). */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint32_t cbMax;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The message URB. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBURB Urb;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBCTRLEXTRA, *PVUSBCTRLEXTRA;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbMsgFreeExtraData(PVUSBCTRLEXTRA pExtra);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbMsgResetExtraData(PVUSBCTRLEXTRA pExtra);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
ff1ea1a768f003a41f4b02f742060708e633819avboxsync/** Opaque VUSB read ahead buffer management handle. */
ff1ea1a768f003a41f4b02f742060708e633819avboxsynctypedef struct VUSBREADAHEADINT *VUSBREADAHEAD;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * A VUSB pipe
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct vusb_pipe
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PCVUSBDESCENDPOINTEX in;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PCVUSBDESCENDPOINTEX out;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the extra state data required to run a control pipe. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBCTRLEXTRA pCtrl;
49e18d6e5fc87bd475db9dcacbfee7c98e2d1b30vboxsync /** Critical section serializing access to the extra state data for a control pipe. */
49e18d6e5fc87bd475db9dcacbfee7c98e2d1b30vboxsync RTCRITSECT CritSectCtrl;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Count of active async transfers. */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync volatile uint32_t async;
ff1ea1a768f003a41f4b02f742060708e633819avboxsync /** Read ahead handle. */
ff1ea1a768f003a41f4b02f742060708e633819avboxsync VUSBREADAHEAD hReadAhead;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBPIPE;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to a VUSB pipe structure. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef VUSBPIPE *PVUSBPIPE;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Interface state and possible settings.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct vusb_interface_state
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the interface descriptor of the currently selected (active)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * interface. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PCVUSBDESCINTERFACEEX pCurIfDesc;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the interface settings. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PCVUSBINTERFACE pIf;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBINTERFACESTATE;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to interface state. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef VUSBINTERFACESTATE *PVUSBINTERFACESTATE;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to const interface state. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef const VUSBINTERFACESTATE *PCVUSBINTERFACESTATE;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * A Virtual USB device (core).
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @implements VUSBIDEVICE
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBDEV
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The device interface exposed to the HCI. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBIDEVICE IDevice;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the PDM USB device instance. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PPDMUSBINS pUsbIns;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Next device in the chain maintained by the roothub. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBDEV pNext;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the next device with the same address hash. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBDEV pNextHash;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the hub this device is attached to. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBHUB pHub;
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync /** The device state. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBDEVICESTATE volatile enmState;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The device address. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint8_t u8Address;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The new device address. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint8_t u8NewAddress;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The port. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync int16_t i16Port;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Device status. (VUSB_DEV_SELF_POWERED or not.) */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint16_t u16Status;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the descriptor cache.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * (Provided by the device thru the pfnGetDescriptorCache method.) */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PCPDMUSBDESCCACHE pDescCache;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Current configuration. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PCVUSBDESCCONFIGEX pCurCfgDesc;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Current interface state (including alternate interface setting) - maximum
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * valid index is config->bNumInterfaces
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBINTERFACESTATE paIfStates;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pipe/direction -> endpoint descriptor mapping */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBPIPE aPipes[VUSB_PIPE_MAX];
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync /** Critical section protecting the active URB list. */
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync RTCRITSECT CritSectAsyncUrbs;
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync /** List of active async URBs. */
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync PVUSBURB pAsyncUrbHead;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Dumper state. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync union VUSBDEVURBDUMPERSTATE
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync {
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The current scsi command. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint8_t u8ScsiCmd;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync } Urb;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
a3cc5474f3cdd349476201c13a2a1c60484ffbb2vboxsync /** The reset timer handle. */
a3cc5474f3cdd349476201c13a2a1c60484ffbb2vboxsync PTMTIMER pResetTimer;
c4bcf8396f4cc15b50a94fde59325a01ec80be34vboxsync /** Reset handler arguments. */
c4bcf8396f4cc15b50a94fde59325a01ec80be34vboxsync void *pvArgs;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync /** URB submit and reap thread. */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync RTTHREAD hUrbIoThread;
ff1ea1a768f003a41f4b02f742060708e633819avboxsync /** Request queue for executing tasks on the I/O thread which should be done
ff1ea1a768f003a41f4b02f742060708e633819avboxsync * synchronous and without any other thread accessing the USB device. */
ff1ea1a768f003a41f4b02f742060708e633819avboxsync RTREQQUEUE hReqQueueSync;
dcc837f3a6f10996beb8aa7965f67f7f6c273fb4vboxsync /** Sniffer instance for this device if configured. */
dcc837f3a6f10996beb8aa7965f67f7f6c273fb4vboxsync VUSBSNIFFER hSniffer;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync /** Flag whether the URB I/O thread should terminate. */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync bool volatile fTerminate;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync /** Flag whether the I/O thread was woken up. */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync bool volatile fWokenUp;
bf7f0c7283957d64d924ab166eda258706eb7531vboxsync#if HC_ARCH_BITS == 32
bf7f0c7283957d64d924ab166eda258706eb7531vboxsync /** Align the size to a 8 byte boundary. */
f3582d40554353e5b71af41d7c734748f92c1180vboxsync bool afAlignment0[2];
bf7f0c7283957d64d924ab166eda258706eb7531vboxsync#endif
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBDEV;
1b419671a64ecb9cba31cf9350b4028de0a5db1cvboxsyncAssertCompileSizeAlignment(VUSBDEV, 8);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to the virtual method table for a kind of USB devices. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct vusb_dev_ops *PVUSBDEVOPS;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to the const virtual method table for a kind of USB devices. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef const struct vusb_dev_ops *PCVUSBDEVOPS;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Virtual method table for USB devices - these are the functions you need to
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * implement when writing a new device (or hub)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Note that when creating your structure, you are required to zero the
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * vusb_dev fields (ie. use calloc).
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct vusb_dev_ops
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /* mandatory */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync const char *name;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBDEVOPS;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
dcc837f3a6f10996beb8aa7965f67f7f6c273fb4vboxsyncint vusbDevInit(PVUSBDEV pDev, PPDMUSBINS pUsbIns, const char *pszCaptureFilename);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncint vusbDevCreateOld(const char *pszDeviceName, void *pvDriverInit, PCRTUUID pUuid, PVUSBDEV *ppDev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbDevDestroy(PVUSBDEV pDev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncDECLINLINE(bool) vusbDevIsRh(PVUSBDEV pDev)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync return (pDev->pHub == (PVUSBHUB)pDev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync}
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncbool vusbDevDoSelectConfig(PVUSBDEV dev, PCVUSBDESCCONFIGEX pCfg);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbDevMapEndpoint(PVUSBDEV dev, PCVUSBDESCENDPOINTEX ep);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncint vusbDevDetach(PVUSBDEV pDev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncDECLINLINE(PVUSBROOTHUB) vusbDevGetRh(PVUSBDEV pDev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncsize_t vusbDevMaxInterfaces(PVUSBDEV dev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbDevSetAddress(PVUSBDEV pDev, uint8_t u8Address);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncbool vusbDevStandardRequest(PVUSBDEV pDev, int EndPt, PVUSBSETUP pSetup, void *pvBuf, uint32_t *pcbBuf);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @} */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @name Internal Hub Operations, Structures and Constants.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Virtual method table for USB hub devices.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Hub and roothub drivers need to implement these functions in addition to the
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * vusb_dev_ops.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBHUBOPS
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync int (*pfnAttach)(PVUSBHUB pHub, PVUSBDEV pDev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync void (*pfnDetach)(PVUSBHUB pHub, PVUSBDEV pDev);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBHUBOPS;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Pointer to a const HUB method table. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef const VUSBHUBOPS *PCVUSBHUBOPS;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** A VUSB Hub Device - Hub and roothub drivers need to use this struct
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @todo eliminate this (PDM / roothubs only).
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBHUB
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBDEV Dev;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PCVUSBHUBOPS pOps;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBROOTHUB pRootHub;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint16_t cPorts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint16_t cDevices;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Name of the hub. Used for logging. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync char *pszName;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBHUB;
bf7f0c7283957d64d924ab166eda258706eb7531vboxsyncAssertCompileMemberAlignment(VUSBHUB, pOps, 8);
1b419671a64ecb9cba31cf9350b4028de0a5db1cvboxsyncAssertCompileSizeAlignment(VUSBHUB, 8);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @} */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @name Internal Root Hub Operations, Structures and Constants.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Per transfer type statistics.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBROOTHUBTYPESTATS
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatUrbsSubmitted;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatUrbsFailed;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatUrbsCancelled;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatReqBytes;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatReqReadBytes;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatReqWriteBytes;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatActBytes;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatActReadBytes;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatActWriteBytes;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBROOTHUBTYPESTATS, *PVUSBROOTHUBTYPESTATS;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** The address hash table size. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSB_ADDR_HASHSZ 5
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * The instance data of a root hub driver.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * This extends the generic VUSB hub.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @implements VUSBIROOTHUBCONNECTOR
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsynctypedef struct VUSBROOTHUB
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The HUB.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @todo remove this? */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBHUB Hub;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Address hash table. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBDEV apAddrHash[VUSB_ADDR_HASHSZ];
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The default address. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBDEV pDefaultAddress;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the driver instance. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PPDMDRVINS pDrvIns;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Pointer to the root hub port interface we're attached to. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBIROOTHUBPORT pIRhPort;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Connector interface exposed upwards. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBIROOTHUBCONNECTOR IRhConnector;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
15d01c99464d6518f5cf6e7993e1357308fa12aevboxsync#if HC_ARCH_BITS == 32
15d01c99464d6518f5cf6e7993e1357308fa12aevboxsync uint32_t Alignment0;
15d01c99464d6518f5cf6e7993e1357308fa12aevboxsync#endif
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync /** Critical section protecting the device list. */
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync RTCRITSECT CritSectDevices;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Chain of devices attached to this hub. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBDEV pDevices;
1343c0dc573781e1f309076f3d9819915bff1705vboxsync
1343c0dc573781e1f309076f3d9819915bff1705vboxsync#if HC_ARCH_BITS == 32
1343c0dc573781e1f309076f3d9819915bff1705vboxsync uint32_t Alignment1;
1343c0dc573781e1f309076f3d9819915bff1705vboxsync#endif
1343c0dc573781e1f309076f3d9819915bff1705vboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Availability Bitmap. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBPORTBITMAP Bitmap;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Critical section protecting the free list. */
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync RTCRITSECT CritSectFreeUrbs;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Chain of free URBs. (Singly linked) */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync PVUSBURB pFreeUrbs;
a68ecdc0c30415782314028469b6a97fbd51a975vboxsync /** Sniffer instance for the root hub. */
a68ecdc0c30415782314028469b6a97fbd51a975vboxsync VUSBSNIFFER hSniffer;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** The number of URBs in the pool. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint32_t cUrbsInPool;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync /** Version of the attached Host Controller. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint32_t fHcVersions;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#ifdef VBOX_WITH_STATISTICS
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBROOTHUBTYPESTATS Total;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync VUSBROOTHUBTYPESTATS aTypes[VUSBXFERTYPE_MSG];
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatIsocReqPkts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatIsocReqReadPkts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatIsocReqWritePkts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatIsocActPkts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatIsocActReadPkts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER StatIsocActWritePkts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync struct
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync {
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER Pkts;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER Ok;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER Ok0;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER DataUnderrun;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER DataUnderrun0;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER DataOverrun;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER NotAccessed;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER Misc;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMCOUNTER Bytes;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync } aStatIsocDetails[8];
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMPROFILE StatReapAsyncUrbs;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync STAMPROFILE StatSubmitUrb;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#endif
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync} VUSBROOTHUB;
ee271ac5f5a0f262528a59171392bffd9108509bvboxsyncAssertCompileMemberAlignment(VUSBROOTHUB, IRhConnector, 8);
ee271ac5f5a0f262528a59171392bffd9108509bvboxsyncAssertCompileMemberAlignment(VUSBROOTHUB, Bitmap, 8);
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsyncAssertCompileMemberAlignment(VUSBROOTHUB, CritSectDevices, 8);
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsyncAssertCompileMemberAlignment(VUSBROOTHUB, CritSectFreeUrbs, 8);
ee271ac5f5a0f262528a59171392bffd9108509bvboxsync#ifdef VBOX_WITH_STATISTICS
ee271ac5f5a0f262528a59171392bffd9108509bvboxsyncAssertCompileMemberAlignment(VUSBROOTHUB, Total, 8);
ee271ac5f5a0f262528a59171392bffd9108509bvboxsync#endif
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Converts a pointer to VUSBROOTHUB::IRhConnector to a PVUSBROOTHUB. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#define VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface) (PVUSBROOTHUB)( (uintptr_t)(pInterface) - RT_OFFSETOF(VUSBROOTHUB, IRhConnector) )
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
abe2f4a16e43726264648542b029e782337fbc9cvboxsync/**
abe2f4a16e43726264648542b029e782337fbc9cvboxsync * URB cancellation modes
abe2f4a16e43726264648542b029e782337fbc9cvboxsync */
abe2f4a16e43726264648542b029e782337fbc9cvboxsynctypedef enum CANCELMODE
abe2f4a16e43726264648542b029e782337fbc9cvboxsync{
abe2f4a16e43726264648542b029e782337fbc9cvboxsync /** complete the URB with an error (CRC). */
abe2f4a16e43726264648542b029e782337fbc9cvboxsync CANCELMODE_FAIL = 0,
abe2f4a16e43726264648542b029e782337fbc9cvboxsync /** do not change the URB contents. */
abe2f4a16e43726264648542b029e782337fbc9cvboxsync CANCELMODE_UNDO
abe2f4a16e43726264648542b029e782337fbc9cvboxsync} CANCELMODE;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/* @} */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @name Internal URB Operations, Structures and Constants.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @{ */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncint vusbUrbSubmit(PVUSBURB pUrb);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbUrbTrace(PVUSBURB pUrb, const char *pszMsg, bool fComplete);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbUrbDoReapAsync(PVUSBURB pHead, RTMSINTERVAL cMillies);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncvoid vusbUrbDoReapAsyncDev(PVUSBDEV pDev, RTMSINTERVAL cMillies);
abe2f4a16e43726264648542b029e782337fbc9cvboxsyncvoid vusbUrbCancel(PVUSBURB pUrb, CANCELMODE mode);
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsyncvoid vusbUrbCancelAsync(PVUSBURB pUrb, CANCELMODE mode);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbUrbRipe(PVUSBURB pUrb);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbUrbCompletionRh(PVUSBURB pUrb);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncint vusbUrbSubmitHardError(PVUSBURB pUrb);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncint vusbUrbErrorRh(PVUSBURB pUrb);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncint vusbDevUrbIoThreadWakeup(PVUSBDEV pDev);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncint vusbDevUrbIoThreadCreate(PVUSBDEV pDev);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncint vusbDevUrbIoThreadDestroy(PVUSBDEV pDev);
c4bcf8396f4cc15b50a94fde59325a01ec80be34vboxsyncDECLHIDDEN(int) vusbDevIoThreadExecV(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
c4bcf8396f4cc15b50a94fde59325a01ec80be34vboxsyncDECLHIDDEN(int) vusbDevIoThreadExec(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
ff1ea1a768f003a41f4b02f742060708e633819avboxsyncDECLHIDDEN(int) vusbDevIoThreadExecSync(PVUSBDEV pDev, PFNRT pfnFunction, unsigned cArgs, ...);
899acd106e06a30ecb233d09c74f9aa71867627fvboxsyncDECLHIDDEN(int) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncvoid vusbUrbCompletionReadAhead(PVUSBURB pUrb);
ff1ea1a768f003a41f4b02f742060708e633819avboxsyncVUSBREADAHEAD vusbReadAheadStart(PVUSBDEV pDev, PVUSBPIPE pPipe);
ff1ea1a768f003a41f4b02f742060708e633819avboxsyncvoid vusbReadAheadStop(VUSBREADAHEAD hReadAhead);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncint vusbUrbQueueAsyncRh(PVUSBURB pUrb);
ff1ea1a768f003a41f4b02f742060708e633819avboxsyncint vusbUrbSubmitBufferedRead(PVUSBURB pUrb, VUSBREADAHEAD hReadAhead);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncPVUSBURB vusbRhNewUrb(PVUSBROOTHUB pRh, uint8_t DstAddress, uint32_t cbData, uint32_t cTds);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncDECLINLINE(void) vusbUrbUnlink(PVUSBURB pUrb)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync PVUSBDEV pDev = pUrb->VUsb.pDev;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync RTCritSectEnter(&pDev->CritSectAsyncUrbs);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *pUrb->VUsb.ppPrev = pUrb->VUsb.pNext;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync if (pUrb->VUsb.pNext)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync pUrb->VUsb.pNext->VUsb.ppPrev = pUrb->VUsb.ppPrev;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync pUrb->VUsb.pNext = NULL;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync pUrb->VUsb.ppPrev = NULL;
ebe394fa0ecbdea5feff1a5edfc2e17a2ccfbd25vboxsync RTCritSectLeave(&pDev->CritSectAsyncUrbs);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync}
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @def vusbUrbAssert
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Asserts that a URB is valid.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#ifdef VBOX_STRICT
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync# define vusbUrbAssert(pUrb) do { \
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync AssertMsg(VALID_PTR((pUrb)), ("%p\n", (pUrb))); \
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync AssertMsg((pUrb)->u32Magic == VUSBURB_MAGIC, ("%#x", (pUrb)->u32Magic)); \
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync AssertMsg((pUrb)->enmState > VUSBURBSTATE_INVALID && (pUrb)->enmState < VUSBURBSTATE_END, \
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync ("%d\n", (pUrb)->enmState)); \
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync } while (0)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#else
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync# define vusbUrbAssert(pUrb) do {} while (0)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#endif
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync/**
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @def VUSBDEV_ASSERT_VALID_STATE
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * Asserts that the give device state is valid.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync */
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync#define VUSBDEV_ASSERT_VALID_STATE(enmState) \
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync AssertMsg((enmState) > VUSB_DEVICE_STATE_INVALID && (enmState) < VUSB_DEVICE_STATE_DESTROYED, ("enmState=%#x\n", enmState));
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync
c4bcf8396f4cc15b50a94fde59325a01ec80be34vboxsync/** Executes a function synchronously. */
c4bcf8396f4cc15b50a94fde59325a01ec80be34vboxsync#define VUSB_DEV_IO_THREAD_EXEC_FLAGS_SYNC RT_BIT_32(0)
c4bcf8396f4cc15b50a94fde59325a01ec80be34vboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** @} */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Addresses are between 0 and 127 inclusive
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncDECLINLINE(uint8_t) vusbHashAddress(uint8_t Address)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync uint8_t u8Hash = Address;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync u8Hash ^= (Address >> 2);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync u8Hash ^= (Address >> 3);
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync u8Hash %= VUSB_ADDR_HASHSZ;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync return u8Hash;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync}
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/**
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * Gets the roothub of a device.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync *
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @returns Pointer to the roothub instance the device is attached to.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @returns NULL if not attached to any hub.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync * @param pDev Pointer to the device in question.
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncDECLINLINE(PVUSBROOTHUB) vusbDevGetRh(PVUSBDEV pDev)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync{
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync if (!pDev->pHub)
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync return NULL;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync return pDev->pHub->pRootHub;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync}
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync/**
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * Returns the state of the USB device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync *
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @returns State of the USB device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @param pDev Pointer to the device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync */
baa2caaaee73e61f053304c6203335f4efe0c422vboxsyncDECLINLINE(VUSBDEVICESTATE) vusbDevGetState(PVUSBDEV pDev)
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync{
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync VUSBDEVICESTATE enmState = (VUSBDEVICESTATE)ASMAtomicReadU32((volatile uint32_t *)&pDev->enmState);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync VUSBDEV_ASSERT_VALID_STATE(enmState);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync return enmState;
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync}
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync/**
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * Sets the given state for the USB device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync *
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @returns The old state of the device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @param pDev Pointer to the device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @param enmState The new state to set.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync */
baa2caaaee73e61f053304c6203335f4efe0c422vboxsyncDECLINLINE(VUSBDEVICESTATE) vusbDevSetState(PVUSBDEV pDev, VUSBDEVICESTATE enmState)
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync{
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync VUSBDEV_ASSERT_VALID_STATE(enmState);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync VUSBDEVICESTATE enmStateOld = (VUSBDEVICESTATE)ASMAtomicXchgU32((volatile uint32_t *)&pDev->enmState, enmState);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync VUSBDEV_ASSERT_VALID_STATE(enmStateOld);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync return enmStateOld;
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync}
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync/**
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * Compare and exchange the states for the given USB device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync *
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @returns true if the state was changed.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @returns false if the state wasn't changed.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @param pDev Pointer to the device.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @param enmStateNew The new state to set.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync * @param enmStateOld The old state to compare with.
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync */
baa2caaaee73e61f053304c6203335f4efe0c422vboxsyncDECLINLINE(bool) vusbDevSetStateCmp(PVUSBDEV pDev, VUSBDEVICESTATE enmStateNew, VUSBDEVICESTATE enmStateOld)
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync{
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync VUSBDEV_ASSERT_VALID_STATE(enmStateNew);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync VUSBDEV_ASSERT_VALID_STATE(enmStateOld);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync return ASMAtomicCmpXchgU32((volatile uint32_t *)&pDev->enmState, enmStateNew, enmStateOld);
baa2caaaee73e61f053304c6203335f4efe0c422vboxsync}
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Strings for the CTLSTAGE enum values. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncextern const char * const g_apszCtlStates[4];
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Default message pipe. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncextern const VUSBDESCENDPOINTEX g_Endpoint0;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync/** Default configuration. */
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncextern const VUSBDESCCONFIGEX g_Config0;
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsyncRT_C_DECLS_END
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync#endif
cb4a18edeb5422163b264fe5a66276769cfe864dvboxsync