/* $Id$ */
/** @file
* USBPROXY - USB proxy header
*/
/*
* Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef ___USBProxyDevice_h
#define ___USBProxyDevice_h
#include <VBox/cdefs.h>
#include <VBox/vusb.h>
RT_C_DECLS_BEGIN
/** Pointer to a USB proxy device. */
typedef struct USBPROXYDEV *PUSBPROXYDEV;
/**
* USB Proxy Device Backend
*/
typedef struct USBPROXYBACK
{
/** Name of the backend. */
const char *pszName;
/** Size of the backend specific data. */
size_t cbBackend;
/**
* Opens the USB device specfied by pszAddress.
*
* This method will initialize backend private data. If the backend has
* already selected a configuration for the device, this must be indicated
* in USBPROXYDEV::iActiveCfg.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param pszAddress Host specific USB device address.
* @param pvBackend Pointer to backend specific data.
*/
DECLR3CALLBACKMEMBER(int, pfnOpen, (PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend));
/**
* Optional callback for initializing the device after the configuration
* has been established.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
*/
DECLR3CALLBACKMEMBER(int, pfnInit, (PUSBPROXYDEV pProxyDev));
/**
* Closes handle to the host USB device.
*
* @param pProxyDev The USB Proxy Device instance.
*/
DECLR3CALLBACKMEMBER(void, pfnClose, (PUSBPROXYDEV pProxyDev));
/**
* Reset a device.
*
* The backend must update iActualCfg and fIgnoreEqualSetConfig.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param fResetOnLinux It's safe to do reset on linux, we can deal with devices
* being logically reconnected.
*/
DECLR3CALLBACKMEMBER(int, pfnReset, (PUSBPROXYDEV pProxyDev, bool fResetOnLinux));
/**
* Sets the given configuration of the device.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param iCfg The configuration to set.
*/
DECLR3CALLBACKMEMBER(int, pfnSetConfig, (PUSBPROXYDEV pProxyDev, int iCfg));
/**
* Claim an interface for use by the prox device.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param iIf Interface number to claim.
*/
DECLR3CALLBACKMEMBER(int, pfnClaimInterface, (PUSBPROXYDEV pProxyDev, int iIf));
/**
* Releases an interface which was claimed before.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param iIf Interface number to release.
*/
DECLR3CALLBACKMEMBER(int, pfnReleaseInterface, (PUSBPROXYDEV pProxyDev, int iIf));
/**
* Sets the given alternate interface for the device.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param iIf Interface to use.
* @param iSetting The alternate setting to use.
*/
DECLR3CALLBACKMEMBER(int, pfnSetInterface, (PUSBPROXYDEV pProxyDev, int iIf, int iSetting));
/**
* Clears the given halted endpoint.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param iEp The endpoint to clear.
*/
DECLR3CALLBACKMEMBER(int, pfnClearHaltedEndpoint, (PUSBPROXYDEV pDev, unsigned int iEp));
/**
* Queue a new URB.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param pUrb The URB to queue.
*/
DECLR3CALLBACKMEMBER(int, pfnUrbQueue, (PUSBPROXYDEV pProxyDev, PVUSBURB pUrb));
/**
* Cancel an in-flight URB.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
* @param pUrb The URB to cancel.
*/
DECLR3CALLBACKMEMBER(int, pfnUrbCancel, (PUSBPROXYDEV pProxyDev, PVUSBURB pUrb));
/**
* Reap URBs in-flight on a device.
*
* @returns Pointer to a completed URB.
* @returns NULL if no URB was completed.
* @param pProxyDev The USB Proxy Device instance.
* @param cMillies Number of milliseconds to wait. Use 0 to not
* wait at all.
*/
DECLR3CALLBACKMEMBER(PVUSBURB, pfnUrbReap, (PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies));
/**
* Kicks the thread waiting in pfnUrbReap to make it return.
*
* @returns VBox status code.
* @param pProxyDev The USB Proxy Device instance.
*/
DECLR3CALLBACKMEMBER(int, pfnWakeup, (PUSBPROXYDEV pProxyDev));
/** Dummy entry for making sure we've got all members initialized. */
uint32_t uDummy;
} USBPROXYBACK;
/** Pointer to a USB Proxy Device Backend. */
typedef USBPROXYBACK *PUSBPROXYBACK;
/** Pointer to a const USB Proxy Device Backend. */
typedef const USBPROXYBACK *PCUSBPROXYBACK;
/** The Host backend. */
extern const USBPROXYBACK g_USBProxyDeviceHost;
/** The remote desktop backend. */
extern const USBPROXYBACK g_USBProxyDeviceVRDP;
#ifdef RDESKTOP
typedef struct VUSBDEV
{
char* pszName;
} VUSBDEV, *PVUSBDEV;
#endif
/**
* USB Proxy device.
*/
typedef struct USBPROXYDEV
{
#ifdef RDESKTOP
/** The VUSB device structure - must be the first structure member. */
VUSBDEV Dev;
/** The next device in rdesktop-vrdp's linked list */
PUSBPROXYDEV pNext;
/** The previous device in rdesktop-vrdp's linked list */
PUSBPROXYDEV pPrev;
/** The vrdp device ID */
uint32_t devid;
/** Linked list of in-flight URBs */
PVUSBURB pUrbs;
#endif
/** The device descriptor. */
VUSBDESCDEVICE DevDesc;
/** The configuration descriptor array. */
PVUSBDESCCONFIGEX paCfgDescs;
#ifndef RDESKTOP
/** The descriptor cache.
* Contains &DevDesc and paConfigDescs. */
PDMUSBDESCCACHE DescCache;
/** Pointer to the PDM USB device instance. */
PPDMUSBINS pUsbIns;
#endif
/** Pointer to the backend. */
PCUSBPROXYBACK pOps;
/** The currently active configuration.
* It's -1 if no configuration is active. This is set to -1 before open and reset,
* the backend will change it if open or reset implies SET_CONFIGURATION. */
int iActiveCfg;
/** Ignore one or two SET_CONFIGURATION operation.
* See usbProxyDevSetCfg for details. */
int cIgnoreSetConfigs;
/** Mask of the interfaces that the guest shall doesn't see.
* This is experimental!
*/
uint32_t fMaskedIfs;
/** Whether we've opened the device or not.
* For dealing with failed construction (the destruct method is always called). */
bool fOpened;
/** Whether we've called pfnInit or not.
* For dealing with failed construction (the destruct method is always called). */
bool fInited;
/** Whether the device has been detached.
* This is hack for making PDMUSBREG::pfnUsbQueue return the right status code. */
bool fDetached;
/** Backend specific data, the size is stored in pOps::cbBackend. */
void *pvInstanceDataR3;
} USBPROXYDEV;
/** @def USBPROXYDEV_2_DATA
* Converts a USB proxy Device, pointer to a pointer to the backend specific instance data.
*/
#define USBPROXYDEV_2_DATA(a_pProxyDev, a_Type) ( (a_Type)(a_pProxyDev)->pvInstanceDataR3 )
static inline char *usbProxyGetName(PUSBPROXYDEV pProxyDev)
{
#ifndef RDESKTOP
return pProxyDev->pUsbIns->pszName;
#else
return pProxyDev->Dev.pszName;
#endif
}
#ifdef RDESKTOP
static inline PUSBPROXYDEV usbProxyFromVusbDev(PVUSBDEV pDev)
{
return (PUSBPROXYDEV)pDev;
}
#endif
#ifdef RT_OS_LINUX
RTDECL(int) USBProxyDeviceLinuxGetFD(PUSBPROXYDEV pProxyDev);
#endif
RT_C_DECLS_END
#endif