9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/* $Id$ */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** @file
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * USB device proxy - the Solaris backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Copyright (C) 2009-2014 Oracle Corporation
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * available from http://www.virtualbox.org. This file is free software;
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * General Public License (GPL) as published by the Free Software
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Header Files *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define LOG_GROUP LOG_GROUP_DRV_USBPROXY
87902654924b5893d165c3f31f1d8a50f87205b4vboxsync#ifdef DEBUG_ramshankar
87902654924b5893d165c3f31f1d8a50f87205b4vboxsync# define LOG_INSTANCE RTLogRelDefaultInstance()
87902654924b5893d165c3f31f1d8a50f87205b4vboxsync#endif
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync#include <sys/poll.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <errno.h>
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync#include <strings.h>
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync#include <limits.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <VBox/log.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <VBox/err.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/pdm.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/string.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/critsect.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/time.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/file.h>
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync#include <iprt/mem.h>
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync#include <iprt/pipe.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include "../USBProxyDevice.h"
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <VBox/usblib.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Defined Constants And Macros *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** Log Prefix. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync#define USBPROXY "USBProxy"
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Structures and Typedefs *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Wrapper around the solaris urb request structure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * This is required to track in-flight and landed URBs.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsynctypedef struct USBPROXYURBSOL
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the Solaris device. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync struct USBPROXYDEVSOL *pDevSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /** Pointer to the VUSB URB (set to NULL if canceled). */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PVUSBURB pVUsbUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the next solaris URB. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync struct USBPROXYURBSOL *pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the previous solaris URB. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync struct USBPROXYURBSOL *pPrev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync} USBPROXYURBSOL, *PUSBPROXYURBSOL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Data for the solaris usb proxy backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsynctypedef struct USBPROXYDEVSOL
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Path of the USB device in the devices tree (persistent). */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync char *pszDevicePath;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /** The connection to the client driver. */
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync RTFILE hFile;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the proxy device instance. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYDEV pProxyDev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Critical section protecting the two lists. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCRITSECT CritSect;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The list of free solaris URBs. Singly linked. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pFreeHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The list of active solaris URBs. Doubly linked.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * We must maintain this so we can properly reap URBs of a detached device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Only the split head will appear in this list. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pInFlightHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The list of landed solaris URBs. Doubly linked.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Only the split head will appear in this list. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pTaxingHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The tail of the landed solaris URBs. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pTaxingTail;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /** Pipe handle for waking up - writing end. */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync RTPIPE hPipeWakeupW;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /** Pipe handle for waking up - reading end. */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync RTPIPE hPipeWakeupR;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync} USBPROXYDEVSOL, *PUSBPROXYDEVSOL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
07a38a36071e285664891c195d2c44003dc19b1avboxsyncstatic PVUSBURB usbProxySolarisUrbComplete(PUSBPROXYDEVSOL pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Allocates a Solaris URB request structure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns Pointer to an active URB request.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns NULL on failure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic PUSBPROXYURBSOL usbProxySolarisUrbAlloc(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pUrbSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Try remove a Solaris URB from the free list, if none there allocate a new one.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol = pDevSol->pFreeHead;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrbSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pFreeHead = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectLeave(&pDevSol->CritSect);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol = (PUSBPROXYURBSOL)RTMemAlloc(sizeof(*pUrbSol));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (!pUrbSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pVUsbUrb = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pDevSol = pDevSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Link it into the active list
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pPrev = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pNext = pDevSol->pInFlightHead;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrbSol->pNext)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pNext->pPrev = pUrbSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pInFlightHead = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectLeave(&pDevSol->CritSect);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Frees a Solaris URB request structure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris USB device.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pUrbSol The Solaris URB to free.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic void usbProxySolarisUrbFree(PUSBPROXYDEVSOL pDevSol, PUSBPROXYURBSOL pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Remove from the active or taxing list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrbSol->pNext)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pNext->pPrev = pUrbSol->pPrev;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else if (pDevSol->pTaxingTail == pUrbSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pTaxingTail = pUrbSol->pPrev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrbSol->pPrev)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pPrev->pNext = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else if (pDevSol->pTaxingHead == pUrbSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pTaxingHead = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else if (pDevSol->pInFlightHead == pUrbSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pInFlightHead = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync AssertFailed();
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Link it into the free list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pPrev = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pNext = pDevSol->pFreeHead;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pFreeHead = pUrbSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pVUsbUrb = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pDevSol = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectLeave(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync/*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Close the connection to the USB client driver.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * This is required because our userland enumeration relies on drivers/device trees
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * to recognize active devices, and hence if this device is unplugged we should no
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * longer keep the client driver loaded.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic void usbProxySolarisCloseFile(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync RTFileClose(pDevSol->hFile);
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync pDevSol->hFile = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * The client driver IOCtl Wrapper function.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris device instance.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param Function The Function.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pvData Opaque pointer to the data.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param cbData Size of the data pointed to by pvData.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic int usbProxySolarisIOCtl(PUSBPROXYDEVSOL pDevSol, unsigned Function, void *pvData, size_t cbData)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync if (RT_UNLIKELY(pDevSol->hFile == NIL_RTFILE))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisIOCtl connection to driver gone!\n"));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return VERR_VUSB_DEVICE_NOT_ATTACHED;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ Req;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync Req.u32Magic = VBOXUSB_MAGIC;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync Req.rc = -1;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync Req.cbData = cbData;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync Req.pvDataR3 = pvData;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int Ret = -1;
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync int rc = RTFileIoCtl(pDevSol->hFile, Function, &Req, sizeof(Req), &Ret);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_FAILURE(Req.rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (Req.rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pProxyDev->fDetached = true;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync usbProxySolarisCloseFile(pDevSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Command %#x failed, USB Device '%s' disconnected!\n", Function, pDevSol->pProxyDev->pUsbIns->pszName));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Command %#x failed. Req.rc=%Rrc\n", Function, Req.rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return Req.rc;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Function %#x failed. rc=%Rrc\n", Function, rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Get the active configuration from the device. The first time this is called
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * our client driver would returned the cached configuration since the device is first plugged in.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Subsequent get configuration requests are passed on to the device.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris device instance.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic inline int usbProxySolarisGetActiveConfig(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_GET_CONFIG GetConfigReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync bzero(&GetConfigReq, sizeof(GetConfigReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_CONFIG, &GetConfigReq, sizeof(GetConfigReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pProxyDev->iActiveCfg = GetConfigReq.bConfigValue;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pProxyDev->cIgnoreSetConfigs = 0;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Failed to get configuration. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pProxyDev->iActiveCfg = -1;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pProxyDev->cIgnoreSetConfigs = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Opens the USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device instance.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pszAddress The unique device identifier.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * The format of this string is "VendorId:ProducIt:Release:StaticPath".
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pvBackend Backend specific pointer, unused for the solaris backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisOpen pProxyDev=%p pszAddress=%s pvBackend=%p\n", pProxyDev, pszAddress, pvBackend));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Initialize our USB R3 lib.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = USBLibInit();
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Allocate and initialize the solaris backend data.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync AssertCompile(PATH_MAX >= MAXPATHLEN);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync char szDeviceIdent[PATH_MAX+48];
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = RTStrPrintf(szDeviceIdent, sizeof(szDeviceIdent), "%s", pszAddress);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = RTCritSectInit(&pDevSol->CritSect);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /*
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Create wakeup pipe.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = RTPipeCreate(&pDevSol->hPipeWakeupR, &pDevSol->hPipeWakeupW, 0);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync int Instance;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync char *pszDevicePath = NULL;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = USBLibGetClientInfo(szDeviceIdent, &pszDevicePath, &Instance);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync pDevSol->pszDevicePath = pszDevicePath;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /*
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Open the client driver.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync RTFILE hFile;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = RTFileOpen(&hFile, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync pDevSol->hFile = hFile;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync pDevSol->pProxyDev = pProxyDev;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Verify client driver version.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync VBOXUSBREQ_GET_VERSION GetVersionReq;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync bzero(&GetVersionReq, sizeof(GetVersionReq));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_VERSION, &GetVersionReq, sizeof(GetVersionReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync if ( GetVersionReq.u32Major == VBOXUSB_VERSION_MAJOR
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync && GetVersionReq.u32Minor >= VBOXUSB_VERSION_MINOR)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /*
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Try & get the current cached config from Solaris.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync usbProxySolarisGetActiveConfig(pDevSol);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync return VINF_SUCCESS;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":version mismatch! driver v%d.%d expecting ~v%d.%d\n", GetVersionReq.u32Major,
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync GetVersionReq.u32Minor, VBOXUSB_VERSION_MAJOR, VBOXUSB_VERSION_MINOR));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = VERR_VERSION_MISMATCH;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":failed to query driver version. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync RTFileClose(pDevSol->hFile);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync pDevSol->hFile = NIL_RTFILE;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync pDevSol->pProxyDev = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":failed to open device. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync RTStrFree(pDevSol->pszDevicePath);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync pDevSol->pszDevicePath = NULL;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync }
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync else
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync {
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":failed to get client info. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync if (rc == VERR_NOT_FOUND)
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = VERR_OPEN_FAILED;
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync }
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync RTPipeClose(pDevSol->hPipeWakeupR);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync RTPipeClose(pDevSol->hPipeWakeupW);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync RTCritSectDelete(&pDevSol->CritSect);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":RTCritSectInit failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":RTStrAPrintf failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":USBLibInit failed. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync USBLibTerm();
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Close the USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device instance.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(void) usbProxySolarisClose(PUSBPROXYDEV pProxyDev)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisClose: pProxyDev=%p\n", pProxyDev));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Close the device (do not re-enumerate). */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_CLOSE_DEVICE CloseReq;
7e5ac7913370b687d1b62e233ce54247d9db0f4fvboxsync CloseReq.ResetLevel = VBOXUSB_RESET_LEVEL_CLOSE;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLOSE_DEVICE, &CloseReq, sizeof(CloseReq));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pProxyDev->fDetached = true;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync usbProxySolarisCloseFile(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Now we can close it and free all the resources.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectDelete(&pDevSol->CritSect);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pUrbSol = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync while ((pUrbSol = pDevSol->pInFlightHead) != NULL)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pInFlightHead = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTMemFree(pUrbSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync while ((pUrbSol = pDevSol->pFreeHead) != NULL)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pFreeHead = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTMemFree(pUrbSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
fdd4de0a765fab2da4919899d85d8aae4084afafvboxsync RTPipeClose(pDevSol->hPipeWakeupR);
fdd4de0a765fab2da4919899d85d8aae4084afafvboxsync RTPipeClose(pDevSol->hPipeWakeupW);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTStrFree(pDevSol->pszDevicePath);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pszDevicePath = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync USBLibTerm();
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Reset the device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device to reset.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param fRootHubReset Is this a root hub reset or device specific reset request.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisReset(PUSBPROXYDEV pProxyDev, bool fRootHubReset)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisReset pProxyDev=%s fRootHubReset=%d\n", pProxyDev->pUsbIns->pszName, fRootHubReset));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /** Pass all resets to the device. The Trekstor USB (1.1) stick requires this to work. */
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Soft reset the device. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_CLOSE_DEVICE CloseReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync CloseReq.ResetLevel = VBOXUSB_RESET_LEVEL_SOFT;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLOSE_DEVICE, &CloseReq, sizeof(CloseReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Get the active config. Solaris USBA sets a default config. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync usbProxySolarisGetActiveConfig(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else if (rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisReset failed. rc=%d\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Set the active configuration.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * The caller makes sure that it's not called first time after open or reset
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * with the active interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device instance data.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param iCfg The configuration value to set.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisSetConfig(PUSBPROXYDEV pProxyDev, int iCfg)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisSetConfig: pProxyDev=%p iCfg=%#x\n", pProxyDev, iCfg));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync AssertPtrReturn(pDevSol, VERR_INVALID_POINTER);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_SET_CONFIG SetConfigReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync SetConfigReq.bConfigValue = iCfg;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_SET_CONFIG, &SetConfigReq, sizeof(SetConfigReq));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync if ( RT_FAILURE(rc)
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync && rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisSetConfig failed to switch configuration. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Claims an interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * This is a stub on Solaris since we release/claim all interfaces at
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * as and when required with endpoint opens.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator (always true).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisClaimInterface(PUSBPROXYDEV pProxyDev, int iIf)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Releases an interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * This is a stub on Solaris since we release/claim all interfaces at
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * as and when required with endpoint opens.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisReleaseInterface(PUSBPROXYDEV pProxyDev, int iIf)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Specify an alternate setting for the specified interface of the current configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisSetInterface(PUSBPROXYDEV pProxyDev, int iIf, int iAlt)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisSetInterface: pProxyDev=%p iIf=%d iAlt=%d\n", pProxyDev, iIf, iAlt));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync AssertPtrReturn(pDevSol, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_SET_INTERFACE SetInterfaceReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync SetInterfaceReq.bInterface = iIf;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync SetInterfaceReq.bAlternate = iAlt;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_SET_INTERFACE, &SetInterfaceReq, sizeof(SetInterfaceReq));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync if ( RT_FAILURE(rc)
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync && rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisSetInterface failed to set interface. rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Clears the halted endpoint 'EndPt'.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsyncstatic DECLCALLBACK(int) usbProxySolarisClearHaltedEp(PUSBPROXYDEV pProxyDev, unsigned int EndPt)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisClearHaltedEp pProxyDev=%p EndPt=%#x\n", pProxyDev, EndPt));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync AssertPtrReturn(pDevSol, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_CLEAR_EP ClearEpReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync ClearEpReq.bEndpoint = EndPt;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLEAR_EP, &ClearEpReq, sizeof(ClearEpReq));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync if ( RT_FAILURE(rc)
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync && rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisClearHaltedEp failed! rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @copydoc USBPROXYBACK::pfnUrbQueue
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
938ff344730f28b89abcc18ee7b629cdae335d33vboxsyncstatic DECLCALLBACK(int) usbProxySolarisUrbQueue(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ": usbProxySolarisUrbQueue: pProxyDev=%s pUrb=%p EndPt=%#x enmDir=%d cbData=%d pvData=%p\n",
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pProxyDev->pUsbIns->pszName, pUrb, pUrb->EndPt, pUrb->enmDir, pUrb->cbData, pUrb->abData));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = usbProxySolarisUrbAlloc(pDevSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_UNLIKELY(!pUrbSol))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisUrbQueue: Failed to allocate URB.\n"));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return VERR_NO_MEMORY;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pVUsbUrb = pUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pDevSol = pDevSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync uint8_t EndPt = pUrb->EndPt;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (EndPt)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync EndPt |= pUrb->enmDir == VUSBDIRECTION_IN ? VUSB_DIR_TO_HOST : VUSB_DIR_TO_DEVICE;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_URB UrbReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.pvUrbR3 = pUrbSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.bEndpoint = EndPt;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.enmType = pUrb->enmType;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.enmDir = pUrb->enmDir;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.enmStatus = pUrb->enmStatus;
a93df3b074afab82b9f5fa0d5dde963d22857521vboxsync UrbReq.fShortOk = !pUrb->fShortNotOk;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.cbData = pUrb->cbData;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.pvData = pUrb->abData;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrb->enmType == VUSBXFERTYPE_ISOC)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.cIsocPkts = pUrb->cIsocPkts;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync for (unsigned i = 0; i < pUrb->cIsocPkts; i++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.aIsocPkts[i].cbPkt = pUrb->aIsocPkts[i].cb;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.aIsocPkts[i].cbActPkt = 0;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.aIsocPkts[i].enmStatus = VUSBSTATUS_INVALID;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_SEND_URB, &UrbReq, sizeof(UrbReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrb->enmType == VUSBXFERTYPE_ISOC)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisUrbQueue success cbData=%d.\n", pUrb->cbData));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->Dev.pvPrivate = pUrbSol;
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisUrbQueue Failed!! pProxyDev=%s pUrb=%p EndPt=%#x bEndpoint=%#x enmType=%d enmDir=%d cbData=%u rc=%Rrc\n",
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pProxyDev->pUsbIns->pszName, pUrb, pUrb->EndPt, UrbReq.bEndpoint, pUrb->enmType, pUrb->enmDir, pUrb->cbData, rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Cancels a URB.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The URB requires reaping, so we don't change its state.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @remark There isn't any way to cancel a specific asynchronous request
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * on Solaris. So we just abort pending URBs on the pipe.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsyncstatic DECLCALLBACK(int) usbProxySolarisUrbCancel(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = (PUSBPROXYURBSOL)pUrb->Dev.pvPrivate;
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
5db4d87e2154413787b7c6628cfd2b296c584c78vboxsync AssertPtrReturn(pDevSol, VERR_INVALID_POINTER);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisUrbCancel pUrb=%p pUrbSol=%p pDevSol=%p\n", pUrb, pUrbSol, pUrbSol->pDevSol));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Aborting the control pipe isn't supported, pretend success. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (!pUrb->EndPt)
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return VINF_SUCCESS;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_ABORT_PIPE AbortPipeReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync AbortPipeReq.bEndpoint = pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? VUSB_DIR_TO_HOST : VUSB_DIR_TO_DEVICE);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_ABORT_PIPE, &AbortPipeReq, sizeof(AbortPipeReq));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync if ( RT_FAILURE(rc)
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync && rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync LogRel((USBPROXY ":usbProxySolarisUrbCancel failed to abort pipe. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync LogFlow((USBPROXY ":usbProxySolarisUrbCancel: rc=%Rrc.\n", rc));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Reap URBs in-flight on a device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns Pointer to a completed URB.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns NULL if no URB was completed.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pProxyDev The device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param cMillies Number of milliseconds to wait. Use 0 to not wait at all.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(PVUSBURB) usbProxySolarisUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync //LogFlowFunc((USBPROXY ":usbProxySolarisUrbReap pProxyDev=%p cMillies=%u\n", pProxyDev, cMillies));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Don't block if nothing is in the air.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (!pDevSol->pInFlightHead)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Deque URBs inflight or those landed.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (cMillies > 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync for (;;)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync int cMilliesWait = cMillies == RT_INDEFINITE_WAIT ? -1 : cMillies;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync struct pollfd pfd[2];
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync pfd[0].fd = RTFileToNative(pDevSol->hFile);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync pfd[0].events = POLLIN;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync pfd[0].revents = 0;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
fdd4de0a765fab2da4919899d85d8aae4084afafvboxsync pfd[1].fd = RTPipeToNative(pDevSol->hPipeWakeupR);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync pfd[1].events = POLLIN;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync pfd[1].revents = 0;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
fdd4de0a765fab2da4919899d85d8aae4084afafvboxsync int rc = poll(&pfd[0], 2, cMilliesWait);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (rc > 0)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync if (pfd[0].revents & POLLHUP)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Reaping failed, USB Device '%s' disconnected!\n", pDevSol->pProxyDev->pUsbIns->pszName));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pProxyDev->fDetached = true;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync usbProxySolarisCloseFile(pDevSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync if (pfd[1].revents & POLLIN)
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync {
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync /* Got woken up, drain pipe. */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync uint8_t bRead;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync size_t cbIgnored = 0;
fdd4de0a765fab2da4919899d85d8aae4084afafvboxsync RTPipeRead(pDevSol->hPipeWakeupR, &bRead, 1, &cbIgnored);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync /*
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync * It is possible that we got woken up and have an URB pending
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync * for completion. Do it on the way out. Otherwise return
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync * immediately to the caller.
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync */
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync if (!(pfd[0].revents & POLLIN))
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync return NULL;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync }
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync break;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (rc == 0)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync //LogFlow((USBPROXY ":usbProxySolarisUrbReap: Timed out\n"));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else if (rc != EAGAIN)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisUrbReap Poll rc=%d errno=%d\n", rc, errno));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync usbProxySolarisUrbComplete(pDevSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Any URBs pending delivery?
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PVUSBURB pUrb = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync while (pDevSol->pTaxingHead)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = pDevSol->pTaxingHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb = pUrbSol->pVUsbUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrb)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->Dev.pvPrivate = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbFree(pDevSol, pUrbSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectLeave(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return pUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync/**
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Reads a completed/error'd URB from the client driver (no waiting).
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync *
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris device instance.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic PVUSBURB usbProxySolarisUrbComplete(PUSBPROXYDEVSOL pDevSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync{
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisUrbComplete pDevSol=%p\n", pDevSol));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync VBOXUSBREQ_URB UrbReq;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync bzero(&UrbReq, sizeof(UrbReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_REAP_URB, &UrbReq, sizeof(UrbReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_SUCCESS(rc))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (UrbReq.pvUrbR3)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pUrbSol = (PUSBPROXYURBSOL)UrbReq.pvUrbR3;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PVUSBURB pUrb = pUrbSol->pVUsbUrb;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (RT_LIKELY(pUrb))
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync Assert(pUrb->u32Magic == VUSBURB_MAGIC);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Update the URB.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if ( pUrb->enmType == VUSBXFERTYPE_ISOC
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync && pUrb->enmDir == VUSBDIRECTION_IN)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync size_t cbData = 0;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync for (unsigned i = 0; i < UrbReq.cIsocPkts; i++)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->aIsocPkts[i].cb = UrbReq.aIsocPkts[i].cbActPkt;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync cbData += UrbReq.aIsocPkts[i].cbActPkt;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->aIsocPkts[i].enmStatus = UrbReq.aIsocPkts[i].enmStatus;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisUrbComplete ISOC cbData=%d cbActPktSum=%d\n", pUrb->cbData, cbData));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->cbData = cbData;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->enmStatus = UrbReq.enmStatus;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->cbData = UrbReq.cbData;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->enmStatus = UrbReq.enmStatus;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectEnter(&pDevSol->CritSect);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Remove from the active list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrbSol->pNext)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pNext->pPrev = pUrbSol->pPrev;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pUrbSol->pPrev)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pPrev->pNext = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync Assert(pDevSol->pInFlightHead == pUrbSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pInFlightHead = pUrbSol->pNext;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /*
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Link it into the taxing list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pNext = NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol->pPrev = pDevSol->pTaxingTail;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (pDevSol->pTaxingTail)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pTaxingTail->pNext = pUrbSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pTaxingHead = pUrbSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pTaxingTail = pUrbSol;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync RTCritSectLeave(&pDevSol->CritSect);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY "usbProxySolarisUrbComplete: cb=%d EndPt=%#x enmDir=%d enmStatus=%s (%d) \n",
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->cbData, pUrb->EndPt, pUrb->enmDir, pUrb->enmStatus == VUSBSTATUS_OK ? "OK" : "** Failed **", pUrb->enmStatus));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync// if (pUrb->cbData < 2049)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync// LogFlow((USBPROXY "%.*Rhxd\n", pUrb->cbData, pUrb->abData));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return pUrb;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync else
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync {
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync if (rc != VERR_VUSB_DEVICE_NOT_ATTACHED)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Reaping URB failed. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync }
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync return NULL;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync}
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncstatic DECLCALLBACK(int) usbProxySolarisWakeup(PUSBPROXYDEV pProxyDev)
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync{
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync size_t cbIgnored;
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync LogFlowFunc(("pProxyDev=%p\n", pProxyDev));
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync return RTPipeWrite(pDevSol->hPipeWakeupW, "", 1, &cbIgnored);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync}
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The Solaris USB Proxy Backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncextern const USBPROXYBACK g_USBProxyDeviceHost =
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /* pszName */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync "host",
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /* cbBackend */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync sizeof(USBPROXYDEVSOL),
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisOpen,
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync NULL,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisClose,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisReset,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisSetConfig,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisClaimInterface,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisReleaseInterface,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisSetInterface,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisClearHaltedEp,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbQueue,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbCancel,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbReap,
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync usbProxySolarisWakeup,
7e5ac7913370b687d1b62e233ce54247d9db0f4fvboxsync 0
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync};
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync