USBProxyDevice-solaris.cpp revision 9de2fa82343af2df7df171b18afbe32b6f37ed84
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/* $Id$ */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** @file
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * USB device proxy - the Solaris backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Copyright (C) 2008 Oracle Corporation
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Oracle Corporation confidential
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * All rights reserved
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Header Files *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define LOG_GROUP LOG_GROUP_DRV_USBPROXY
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <limits.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <stdio.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <signal.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <errno.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <sys/usb/usba.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <sys/usb/clients/ugen/usb_ugen.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <sys/asynch.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <VBox/log.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <VBox/err.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <VBox/pdm.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/assert.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/mem.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/string.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/critsect.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/time.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <iprt/file.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include "../USBProxyDevice.h"
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#include <VBox/usblib.h>
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/* WORK-IN-PROGRESS */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Defined Constants And Macros *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** Log Prefix. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBR3PROXY "USBProxyDev"
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** Maximum endpoints supported. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBSOL_MAXENDPOINTS 32
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** Maximum interfaces supported. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBSOL_MAXINTERFACES 256
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** EndPoint address mask (bEndPointAddress) */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBSOL_EPADDR_NUM_MASK 0x0F
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBSOL_EPADDR_DIR_MASK 0x80
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBSOL_EPADDR_IN 0x80
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBSOL_EPADDR_OUT 0x00
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define USBSOL_CTRLREQ_SIZE 0x08
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** This really needs to be defined in vusb.h! */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#ifndef VUSB_DIR_TO_DEV
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync# define VUSB_DIR_TO_DEV 0x00
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** Ugen isoc support toggle, disable this for S10. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync//#define VBOX_WITH_SOLARIS_USB_ISOC
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** -XXX- Remove this hackery eventually */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#if 0
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#ifdef DEBUG_ramshankar
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync# undef LogFlow
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync# define LogFlow LogRel
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync# undef Log
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync# define Log LogRel
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Structures and Typedefs *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsynctypedef struct USBPROXYURBSOL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Asynchronous URB status.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsynctypedef struct URBSTATUSSOL
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The result of the transfer. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync aio_result_t Result;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The URB associated with this transfer. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync USBPROXYURBSOL *pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync} URBSTATUSSOL, *PURBSTATUSSOL;
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 VUSB URB (set to NULL if canceled). */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PVUSBURB pVUsbUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The millisecond timestamp when this URB was submitted. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync uint64_t u64SubmitTS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the Solaris device. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync struct USBPROXYDEVSOL *pDevSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Status of this URB. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync URBSTATUSSOL Status;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#ifdef VBOX_WITH_SOLARIS_USB_ISOC
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Isoc. OUT buffer. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync caddr_t pIsocBufOut;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Size of the isoc. OUT buffer */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbIsocBufOut;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Isoc. IN buffer. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync caddr_t pIsocBufIn;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Size of the isoc. IN buffer. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbIsocBufIn;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the next solaris URB. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync struct USBPROXYURBSOL *pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the previous solaris URB. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync 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 dev tree (driver bound). */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char *pszDevPath;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Path of the USB device in the devices tree (persistent). */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char *pszDevicePath;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Status endpoint. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTFILE StatFile;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the proxy device instance. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEV pProxyDev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Array of all endpoints. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTFILE aEpFile[USBSOL_MAXENDPOINTS];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Array of all status endpoints.*/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTFILE aEpStatFile[USBSOL_MAXENDPOINTS];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Critical section protecting the two lists. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCRITSECT CritSect;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The list of free solaris URBs. Singly linked. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync 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. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pInFlightHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The list of landed solaris URBs. Doubly linked.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Only the split head will appear in this list. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pTaxingHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The tail of the landed solaris URBs. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pTaxingTail;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync} USBPROXYDEVSOL, *PUSBPROXYDEVSOL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Internal Functions *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisAsyncNotify(bool fActive);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSendReq(RTFILE File, RTFILE StatFile, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, int *pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSendReqAsync(RTFILE File, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, PURBSTATUSSOL pUrbStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisCtrlReq(RTFILE File, RTFILE StatFile, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, int *pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisCtrlReqAsync(RTFILE File, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, PURBSTATUSSOL pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisIO(RTFILE File, RTFILE StatFile, caddr_t pData, size_t cbData, int fOpenMode, int *pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisIOAsync(RTFILE File, caddr_t pData, size_t cbData, int fOpenMode, PURBSTATUSSOL pUrbStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisInitAllPipes(PUSBPROXYDEVSOL pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisOpenDevPipes(PUSBPROXYDEVSOL pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisCloseDevPipes(PUSBPROXYDEVSOL pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisCloseEndPoints(PUSBPROXYDEVSOL pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisCloseDevice(PUSBPROXYDEVSOL pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisGetStatus(RTFILE StatFile, int *pStatus, bool fDevStat);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisGetActiveCfg(PUSBPROXYDEVSOL pDevSol, int *pConfigValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisConfigIndex(PUSBPROXYDEVSOL pDevSol, uint8_t bCfgValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSeizeAllInterfaces(PUSBPROXYDEVSOL pDevSol, uint8_t bCfgValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic VUSBXFERTYPE usbProxySolarisXferType(uint8_t bmAttribute);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic uint32_t usbProxySolarisOpenMode(uint8_t bmEndPointAddress, VUSBXFERTYPE XferType);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisOpenEndPoint(PUSBPROXYDEVSOL pDevSol, int EndPoint, VUSBXFERTYPE XferType);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisOpenNode(PUSBPROXYDEVSOL pDevSol, uint8_t bCfgValue, int iInterface, int iAlternate, int EndPoint,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync VUSBXFERTYPE XferType);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisAsyncComplete(int Sig);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Toggle asynchronous notification signals for asynchronous USB IO.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param fNotify Whether notification is active.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisAsyncNotify(bool fNotify)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (fNotify)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync sigset(SIGIO, usbProxySolarisAsyncComplete);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync sigrelse(SIGIO);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Translate the USB ugen status code to a VUSB status.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VUSB URB status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param irc ugen status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic VUSBSTATUS vusbProxySolarisStatusToVUsbStatus(int irc)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":vusbProxySolarisStatusToVUsbStatus irc=%d\n", irc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync switch (irc)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_NOERROR: return VUSBSTATUS_OK;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_CRC: return VUSBSTATUS_CRC;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_STALL: return VUSBSTATUS_STALL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DEV_NOT_RESP: return VUSBSTATUS_DNR;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DATA_OVERRUN: return VUSBSTATUS_DATA_OVERRUN;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DATA_UNDERRUN: return VUSBSTATUS_DATA_UNDERRUN;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_TIMEOUT: return VUSBSTATUS_DNR;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_NOT_ACCESSED: return VUSBSTATUS_NOT_ACCESSED;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_BITSTUFFING:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_DATA_TOGGLE_MM:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_PID_CHECKFAILURE:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_UNEXP_PID:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_BUFFER_OVERRUN:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_BUFFER_UNDERRUN:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_UNSPECIFIED_ERR:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_NO_BANDWIDTH:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_HW_ERR:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_SUSPENDED:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_DISCONNECTED:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_INTR_BUF_FULL:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_INVALID_REQ:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_INTERRUPTED:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_NO_RESOURCES:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //case USB_LC_STAT_INTR_POLLING_FAILED:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync default:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":vusbProxySolarisStatusToVUsbStatus irc=%#x!!\n", irc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VUSBSTATUS_STALL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Setup a USB request packet.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisSetupReq(PVUSBSETUP pSetupData, uint8_t bmRequestType, uint8_t bRequest,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync uint16_t wValue, uint16_t wIndex, uint16_t wLength)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertCompile(sizeof(VUSBSETUP) == USBSOL_CTRLREQ_SIZE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisSetupReq pSetupData=%p bmRequestType=%#x bRequest=%#x wValue=%#x wIndex=%#x wLength=%#x\n",
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pSetupData, bmRequestType, bRequest, wValue, wIndex, wLength));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pSetupData->bmRequestType = bmRequestType;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pSetupData->bRequest = bRequest;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle endianess here. Currently no swapping is needed. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pSetupData->wValue = wValue;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pSetupData->wIndex = wIndex;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pSetupData->wLength = wLength;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Helper for sending messages through an endpoint, Synchronous version.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Note: pData is assumed to be (pReq + 1) i.e. following the request! Caller's responsibility.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns Number of bytes transferred.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pStatus Where to store the VUSB status (Optional).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSendReq(RTFILE File, RTFILE StatFile, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, int *pStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle read request */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pReq->bmRequestType & VUSB_DIR_TO_HOST)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisIO(File, StatFile, (caddr_t)pReq, sizeof(VUSBSETUP), RTFILE_O_WRITE, pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle write request */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisIO(File, StatFile, (caddr_t)pReq, sizeof(VUSBSETUP) + cbData, RTFILE_O_WRITE, pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Helper for sending messages through an endpoint, Asynchronous version.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Note: pData is assumed to (pReq + 1) i.e. following the request! Caller's responsibility.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pUrbStatus Where to store the status.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSendReqAsync(RTFILE File, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, PURBSTATUSSOL pUrbStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle read request */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pReq->bmRequestType & VUSB_DIR_TO_HOST)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisIOAsync(File, (caddr_t)pReq, sizeof(VUSBSETUP), RTFILE_O_WRITE, pUrbStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle write request */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisIOAsync(File, (caddr_t)pReq, sizeof(VUSBSETUP) + cbData, RTFILE_O_WRITE, pUrbStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Helper for sending control messages, Synchronous version.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns Number of bytes transferred or -1 for errors.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pStatus Where to store the VUSB status (Optional).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisCtrlReq(RTFILE File, RTFILE StatFile, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, int *pStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int cbIO = usbProxySolarisSendReq(File, StatFile, pReq, pData, cbData, pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (cbIO < USBSOL_CTRLREQ_SIZE)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return cbIO;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle read requests, synchronous. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync cbIO -= USBSOL_CTRLREQ_SIZE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( (pReq->bmRequestType & VUSB_DIR_TO_HOST)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync && cbData > 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync cbIO = usbProxySolarisIO(File, StatFile, pData, cbData, RTFILE_O_READ, pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return cbIO;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Helper for sending control messages, Asynchronous version.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pStatus Where to store the VUSB status (Optional).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisCtrlReqAsync(RTFILE File, PVUSBSETUP pReq, caddr_t pData, uint16_t cbData, PURBSTATUSSOL pStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int cbIO = usbProxySolarisSendReq(File, NIL_RTFILE, pReq, pData, cbData, NULL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (cbIO < USBSOL_CTRLREQ_SIZE)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_BUFFER_OVERFLOW;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle read requests, asynchronous. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( (pReq->bmRequestType & VUSB_DIR_TO_HOST)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync && cbData > 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = usbProxySolarisIOAsync(File, pData, cbData, RTFILE_O_READ, pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#ifdef VBOX_WITH_SOLARIS_USB_ISOC
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Helper for sending isochronous requests, Asynchronous version.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pStatus Where to store the VUSB status (Optional).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisIsocReqAsync(RTFILE File, PUSBPROXYURBSOL pUrbSol, PURBSTATUSSOL pStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PVUSBURB pUrb = pUrbSol->pVUsbUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrb->enmDir == VUSBDIRECTION_OUT)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisIOAsync(File, pUrbSol->pIsocBufOut, pUrbSol->cbIsocBufOut, RTFILE_O_WRITE, pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Handle read request, write request info synchronous, read asynchronous */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int cbIO = usbProxySolarisIO(File, NIL_RTFILE, pUrbSol->pIsocBufOut, pUrbSol->cbIsocBufOut, RTFILE_O_WRITE, NULL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Free OUT buffer for the read request. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pUrbSol->pIsocBufOut);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pIsocBufOut = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->cbIsocBufOut = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (cbIO < 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_GENERAL_FAILURE; /* @todo find proper error code here */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisIOAsync(File, pUrbSol->pIsocBufIn, pUrbSol->cbIsocBufIn, RTFILE_O_READ, pStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif /* VBOX_WITH_SOLARIS_USB_ISOC */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Basic USB IO function for transferring data to/from endpoint nodes, Synchronous version.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns Number of bytes transferred or -1 on errors.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param File The endpoint node
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param StatFile The associated status endpoint node (Optional, can be NIL_RTFILE).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pData Pre-allocated buffer to read/write into.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param cbData Number of bytes to transfer (should be size of buffer).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param fOpenMode Open mode for the endpoint determining a Read/Write operation.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pError Where to store VUSB result of operation (Optional, can be NULL).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisIO(RTFILE File, RTFILE StatFile, caddr_t pData, size_t cbData, int fOpenMode, int *pStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(cbData > 0, VERR_IO_BAD_LENGTH);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbIO;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (fOpenMode == RTFILE_O_READ)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTFileRead(File, pData, cbData, &cbIO);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTFileWrite(File, pData, cbData, &cbIO);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( pStatus
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync && StatFile != NIL_RTFILE)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int Status;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisGetStatus(StatFile, &Status, false);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *pStatus = vusbProxySolarisStatusToVUsbStatus(Status);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return cbIO;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Basic USB IO function for transferring data to/from endpoint nodes, Asynchronous version.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param File The endpoint node
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pData Pre-allocated buffer to read/write into.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param cbData Number of bytes to transfer (should be size of buffer).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param fMode RT IO mode for the endpoint (RTFILE_O_READ/RTFILE_O_WRITE).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pUrbStatus Where to store the result (allocated by caller).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisIOAsync(RTFILE File, caddr_t pData, size_t cbData, int fMode, PURBSTATUSSOL pUrbStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(cbData > 0, VERR_IO_BAD_LENGTH);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Turn on asynchronous notifications. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisAsyncNotify(true);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (fMode == RTFILE_O_READ)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = aioread((int)File, pData, cbData, 0, SEEK_CUR, (aio_result_t *)pUrbStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = aiowrite((int)File, pData, cbData, 0, SEEK_CUR, (aio_result_t *)pUrbStatus);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (!rc)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return RTErrConvertFromErrno(rc);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Initializes all pipes (including the default pipe) to their default state.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisInitAllPipes(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (int i = 0; i < USBSOL_MAXENDPOINTS; i++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->aEpFile[i] = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->aEpStatFile[i] = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Opens the default device pipe and it's corresponding status node.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Also opens the device status node in non-blocking mode.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisOpenDevPipes(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisOpenDevPipes pDevSol=%p\n", pDevSol));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pDevSol->pszDevPath, VERR_INVALID_NAME);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char achBuf[PATH_MAX];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrPrintf(achBuf, sizeof(achBuf), "%s/devstat", pDevSol->pszDevPath);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open status endpoint as read-only.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = RTFileOpen(&pDevSol->StatFile, achBuf, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_NON_BLOCK);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":failed to open status end-point. achBuf=%s rc=%Rrc\n", achBuf, rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open default control endpoint as read-write.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrPrintf(achBuf, sizeof(achBuf), "%s/cntrl0", pDevSol->pszDevPath);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTFileOpen(&pDevSol->aEpFile[0], achBuf, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":failed to open control end-point achBuf=%s. rc=%Rrc\n", achBuf, rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open default control status endpoint as read-only.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrPrintf(achBuf, sizeof(achBuf), "%s/cntrl0stat", pDevSol->pszDevPath);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTFileOpen(&pDevSol->aEpStatFile[0], achBuf, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":failed to open control status end-point achBuf=%s. rc=%Rrc\n", achBuf, rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Closes the default pipe, status node and device status node.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisCloseDevPipes(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisCloseDevPipes pDevSol=%p\n", pDevSol));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#define CLOSEFILE_AND_RESET(servicefile) \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync do { \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (servicefile != NIL_RTFILE) \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync { \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTFileClose(servicefile); \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertRC(rc); \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync servicefile = NIL_RTFILE; \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync } \
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync } while(0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync CLOSEFILE_AND_RESET(pDevSol->StatFile);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync CLOSEFILE_AND_RESET(pDevSol->aEpFile[0]);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync CLOSEFILE_AND_RESET(pDevSol->aEpStatFile[0]);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Close all endpoints and reset endpoint descriptor arrays.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisCloseEndPoints(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Close endpoint and endpoint status descriptors. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (int i = 1; i < USBSOL_MAXENDPOINTS; i++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pDevSol->aEpFile[i] != NIL_RTFILE)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTFileClose(pDevSol->aEpFile[i]);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->aEpFile[i] = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pDevSol->aEpStatFile[i] != NIL_RTFILE)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTFileClose(pDevSol->aEpStatFile[i]);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->aEpStatFile[i] = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Helper/Wrapper for closing all the device nodes and control pipes.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisCloseDevice(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisCloseEndPoints(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisCloseDevPipes(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Get status information from a status node.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param StatFile The opened status node,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pStatus Where to store the status (optional).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param fDevStat Whether the passed StatFile is the device status node.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisGetStatus(RTFILE StatFile, int *pStatus, bool fDevStat)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisGetStatus pStatus=%p fDevStat=%d\n", pStatus, fDevStat));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int Status;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbRead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = RTFileRead(StatFile, &Status, sizeof(Status), &cbRead);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (cbRead != sizeof(Status))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = VERR_DEV_IO_ERROR;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY "usbProxySolarisGetStatus: failed to read. rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Ugen supplied error codes.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (!fDevStat)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync switch (Status)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_NOERROR: Log((USBR3PROXY ":usbProxySolarisGetStatus: No Error\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_CRC: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: CRC Timeout Detected\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_BITSTUFFING: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Bit Stuffing Violation\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DATA_TOGGLE_MM: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Data Toggle Mismatch\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_STALL: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: End Point Stalled\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DEV_NOT_RESP: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Device Not Responding\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_PID_CHECKFAILURE: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: PID Check Failure\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_UNEXP_PID: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Unexpected PID\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DATA_OVERRUN: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Data Exceeded Size\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DATA_UNDERRUN: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Less Data Received\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_BUFFER_OVERRUN: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Buffer Size Exceeded\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_BUFFER_UNDERRUN: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Buffer Underrun\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_TIMEOUT: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Command has timed out\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_NOT_ACCESSED: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Not Accessed by Hardware\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_UNSPECIFIED_ERR: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Unspecified Error\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_NO_BANDWIDTH: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: No Bandwidth\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_HW_ERR: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Host Controller Hardware Error\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_SUSPENDED: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Device Suspended\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_DISCONNECTED: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Device Disconnected\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_INTR_BUF_FULL: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Interrupt Buffer full\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_INVALID_REQ: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Request Invalid\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_INTERRUPTED: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Request Interrupted\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_NO_RESOURCES: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: No Resources Available for Request\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_LC_STAT_INTR_POLLING_FAILED: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Failed to Restart Poll")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync default: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Error Not Determined %d\n", Status)); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync switch (Status)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_DEV_STAT_ONLINE: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Device Online\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_DEV_STAT_DISCONNECTED: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Device Disconnected\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_DEV_STAT_RESUMED: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Device Resumed\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case USB_DEV_STAT_UNAVAILABLE: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Device Status Unavailable\n")); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync default: LogRel((USBR3PROXY ":usbProxySolarisGetStatus: Unknown error %d!\n", Status)); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pStatus)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *pStatus = Status;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Get currently active configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB Device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pConfigValue Where to store the configuration value.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisGetActiveCfg(PUSBPROXYDEVSOL pDevSol, int *pConfigValue)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisGetActiveCfg pDevSol=%p pConfigValue=%p\n", pDevSol, pConfigValue));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pConfigValue, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* USB 2.0(Sec. 9.4.2): bRequest=GET_CONFIGURATION(0x08) wValue=0 wIndex=0 wLength=1 */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync VUSBSETUP SetupData;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisSetupReq(&SetupData, VUSB_DIR_TO_HOST, VUSB_REQ_GET_CONFIGURATION, 0, 0, 1);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int iConfig = -1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = RTFileWrite(pDevSol->aEpFile[0], &SetupData, sizeof(SetupData), NULL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbRead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTFileRead(pDevSol->aEpFile[0], &iConfig, sizeof(iConfig), &cbRead);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( cbRead == sizeof(iConfig)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync && RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisGetActiveCfg success. cfg=%d\n", iConfig));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *pConfigValue = iConfig;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = VERR_DEV_IO_ERROR;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisGetActiveCfg failed to read configuration. cbRead=%d rc=%Rrc iConfig=%d\n", cbRead, rc, iConfig));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisGetActiveCfg failed to write configuration request!\n"));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Finds the interface and alternate setting for a given Endpoint address.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param EndPoint The endpoint address as seen in the descriptor.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param piInterface Where to store the interface number.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param piAlternate Where to store the alternate number.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisGetInterfaceForEndpoint(PUSBPROXYDEVSOL pDevSol, int EndPoint, int *piInterface, int *piAlternate)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisGetInterfaceForEndpoint pDevSol=%p Endpoint=%#x\n", pDevSol, EndPoint));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Find the interface for this endpoint. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEV pProxyDev = pDevSol->pProxyDev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCPDMUSBDESCCACHE pDescCache = &pProxyDev->DescCache;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pDescCache, VERR_INVALID_HANDLE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Find the configuration index for this configuration value. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int iCfg = usbProxySolarisConfigIndex(pDevSol, pProxyDev->iActiveCfg >= 1 ? pProxyDev->iActiveCfg : 1);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (iCfg < 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisGetInterfaceForEndpoint failed to obtain configuration index\n"));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_GENERAL_FAILURE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCCONFIGEX pCfg = &pProxyDev->paCfgDescs[iCfg];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pCfg, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Loop through all interfaces for this configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (int i = 0; i < pCfg->Core.bNumInterfaces; i++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBINTERFACE pInterface = &pCfg->paIfs[i];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pInterface, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Loop through all alternate settings of this interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (uint32_t k = 0; k < pInterface->cSettings; k++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCINTERFACEEX pInterfaceEx = &pInterface->setting[k];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pInterfaceEx, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Loop through all the endpoints of this interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (unsigned j = 0; j < pInterfaceEx->Core.bNumEndpoints; j++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCENDPOINTEX pEndPoint = &pInterfaceEx->paEndpoints[j];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pEndPoint, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pEndPoint->Core.bEndpointAddress == EndPoint)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (piInterface)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *piInterface = pInterfaceEx->Core.bInterfaceNumber;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (piAlternate)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *piAlternate = pInterfaceEx->Core.bAlternateSetting;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisGetInterfaceForEndpoint failed for EndPt=%#x\n", EndPoint));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_GENERAL_FAILURE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Finds configuration index for the configuration value.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns Index of configuration with value 'bCfgValue' or -1 if not found.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisConfigIndex(PUSBPROXYDEVSOL pDevSol, uint8_t bCfgValue)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisConfigIndex pDevSol=%p bCfgValue=%d\n", bCfgValue));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Find the configuration index corresponding to this configuration value. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEV pProxyDev = pDevSol->pProxyDev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCPDMUSBDESCCACHE pDescCache = &pProxyDev->DescCache;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pDescCache, VERR_INVALID_HANDLE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int cCfg = pDescCache->pDevice->bNumConfigurations;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (int i = 0; i < cCfg; i++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCCONFIGEX pCfg = &pProxyDev->paCfgDescs[i];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pCfg, -1);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pCfg->Core.bConfigurationValue == bCfgValue)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisConfigIndex found bCfgValue=%d at index %d\n", bCfgValue, i));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return i;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisConfigIndex bCfgValue=%d not found!\n", bCfgValue));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return -1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Claims all interfaces for a given configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param bCfgValue The configuration value.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSeizeAllInterfaces(PUSBPROXYDEVSOL pDevSol, uint8_t bCfgValue)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisSeizeAllInterfaces pDevSol=%p bCfgValue=%d\n", pDevSol, bCfgValue));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pDevSol, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * ugen doesn't have a seize all interface scheme, but we can just open all the end-points of the interface
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * in exclusive mode to have a similar effect. This should mostly be called from Init.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCPDMUSBDESCCACHE pDescCache = &pDevSol->pProxyDev->DescCache;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pDescCache, VERR_INVALID_HANDLE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = VERR_GENERAL_FAILURE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int cCfg = pDescCache->pDevice->bNumConfigurations;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Find the configuration index for this configuration value. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int iCfg = usbProxySolarisConfigIndex(pDevSol, bCfgValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (iCfg < 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisSeizeAllInterfaces failed to find configuration index for configuration value %d\n", bCfgValue));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_GENERAL_FAILURE; /* @todo find a better code? */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (iCfg < cCfg)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCCONFIGEX pCfg = &pDevSol->pProxyDev->paCfgDescs[iCfg];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Loop through all interfaces for this configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (int iInterface = 0; iInterface < pCfg->Core.bNumInterfaces; iInterface++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBINTERFACE pInterface = &pCfg->paIfs[iInterface];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pInterface, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Loop through all alternate settings of this interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (uint32_t k = 0; k < pInterface->num_settings; k++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCINTERFACEEX pInterfaceEx = &pInterface->setting[k];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pInterfaceEx, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int iAlternate = pInterfaceEx->Core.bAlternateSetting;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Loop through all endpoints for this interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (unsigned j = 0; j < pInterfaceEx->Core.bNumEndpoints; j++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCENDPOINTEX pEndPoint = &pInterfaceEx->paEndpoints[j];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pEndPoint, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = usbProxySolarisOpenNode(pDevSol,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync bCfgValue, /* Configuration value */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync iInterface, /* Interface number */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync iAlternate, /* Alternate setting */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pEndPoint->Core.bEndpointAddress, /* Endpoint Address */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisXferType(pEndPoint->Core.bmAttributes)); /* Xfer Type */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisSeizeAllInterfaces failed to open Cfg%d If%d Alt%d Ep%d(Addr %#x)\n", bCfgValue,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync iInterface, iAlternate, k, pEndPoint->Core.bEndpointAddress));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisSeizeAllInterfaces failed! iCfg %d > cCfg %d\n", iCfg, cCfg));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisSeizeAllInterfaces returned %d\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Determine the XferType from the endpoint attribute.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns XferType for the given endpoint 'bmAttribute'
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic VUSBXFERTYPE usbProxySolarisXferType(uint8_t bmAttribute)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisXferType bmAttribute=%#x\n", bmAttribute));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * USB 2.0(Sec. 9.6.6): bmAttribute transfer type.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return (VUSBXFERTYPE)(bmAttribute & 0x03);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Determines the ugen node's open mode based on the XferType and direction.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns The file open mode, or UINT32_MAX upon errors.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param bmEndpointAddress Address of endpoint as seen in the descriptor.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param XferType The VUSB XferType.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncDECLINLINE(uint32_t) usbProxySolarisOpenMode(uint8_t bmEndpointAddress, VUSBXFERTYPE XferType)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisOpenMode bmEndpointAddress=%#x XferType=%d\n", bmEndpointAddress, XferType));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync uint32_t fMode = RTFILE_O_OPEN | RTFILE_O_DENY_NONE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int fIn = bmEndpointAddress & USBSOL_EPADDR_IN;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync switch (XferType)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_INTR: fMode |= (fIn ? RTFILE_O_READ : RTFILE_O_WRITE | RTFILE_O_NON_BLOCK); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_BULK: fMode |= (fIn ? RTFILE_O_READ : RTFILE_O_WRITE); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_ISOC: fMode |= RTFILE_O_READWRITE | RTFILE_O_NON_BLOCK; break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_CTRL: fMode |= RTFILE_O_READWRITE; break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_MSG : fMode |= RTFILE_O_READWRITE | RTFILE_O_NON_BLOCK; break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_INVALID: fMode = UINT32_MAX; LogRel((USBR3PROXY ":invalid XferType %d\n", XferType)); break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return fMode;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open and endpoint given the XferType and optional OpenMode.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param EndPoint The endpoint address as in the descriptor.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param XferType Endpoint xfer type.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisOpenEndPoint(PUSBPROXYDEVSOL pDevSol, int EndPoint, VUSBXFERTYPE XferType)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisOpenEndPoint pDevSol=%p EndPoint=%#x XferType=%d\n", EndPoint, XferType));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Endpoint zero (the default control pipe) would already be open. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (EndPoint == 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEV pProxyDev = pDevSol->pProxyDev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* @todo Fix This! I'm not yet sure what's the right thing to do here regarding configuration... */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Get current configuration index. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int bCfgValue = pProxyDev->iActiveCfg;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (bCfgValue == -1)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* @todo Fix or remove this. GET_CONFIGURATION requests don't work... */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = usbProxySolarisGetActiveCfg(pDevSol, &bCfgValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync bCfgValue = 1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Get interface for endpoint. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int iInterface;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int iAlternate;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = usbProxySolarisGetInterfaceForEndpoint(pDevSol, EndPoint, &iInterface, &iAlternate);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisOpenNode(pDevSol, bCfgValue, iInterface, iAlternate, EndPoint, XferType);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisOpenEndPoint usbProxySolarisGetInterfaceForEndpoint failed. rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_GENERAL_FAILURE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open an endpoint node and stores it among the list of open endpoints.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param bCfgValue The configuration value.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param iInterface The interface number.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param iAlternate The alternate setting.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param EndPoint The endpoint address as stored in the descriptor.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param XferType Endpoint xfer type.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param fOpenMode Open mode for the endpoint (< 0 auto-detects mode based on xfer type and direction).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisOpenNode(PUSBPROXYDEVSOL pDevSol, uint8_t bCfgValue, int iInterface, int iAlternate, int EndPoint,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync VUSBXFERTYPE XferType)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisOpenNode pDevSol=%p bCfgValue=%d iInterface=%d iAlternate=%d EndPoint=%#x XferType=%d\n",
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol, bCfgValue, iInterface, iAlternate, EndPoint, XferType));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int EndPtIndex = (EndPoint & USBSOL_EPADDR_NUM_MASK) + ((EndPoint & USBSOL_EPADDR_DIR_MASK) ? USBSOL_MAXENDPOINTS / 2 : 0);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (EndPtIndex < 0 || EndPtIndex > USBSOL_MAXENDPOINTS - 1)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_INVALID_HANDLE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Check if already open; ep0 should already be open as well. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( EndPtIndex == 0
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync || pDevSol->aEpFile[EndPtIndex] != NIL_RTFILE)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Construct the node name and open the endpoint.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char szEndPoint[PATH_MAX + 1];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char szConfig[12];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char szAlternate[12];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync memset(szConfig, 0, sizeof(szConfig));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync memset(szAlternate, 0, sizeof(szAlternate));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int iCfg = usbProxySolarisConfigIndex(pDevSol, bCfgValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (iCfg > 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrPrintf(szConfig, sizeof(szConfig), "cfg%d", bCfgValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (iAlternate > 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrPrintf(szAlternate, sizeof(szAlternate), ".%d", iAlternate);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrPrintf(szEndPoint, sizeof(szEndPoint), "%s/%sif%d%s%s%d", pDevSol->pszDevPath, szConfig, iInterface,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync szAlternate, (EndPoint & USBSOL_EPADDR_DIR_MASK) ? "in" : "out", (EndPoint & USBSOL_EPADDR_NUM_MASK));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Ugen requires Interrupt IN endpoints to be polled before opening.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char szEndPointStat[PATH_MAX + 1];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrPrintf(szEndPointStat, sizeof(szEndPointStat), "%sstat", szEndPoint);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open the endpoint status node.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( XferType == VUSBXFERTYPE_INTR
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync && (EndPoint & USBSOL_EPADDR_IN))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = RTFileOpen(&pDevSol->aEpStatFile[EndPtIndex], szEndPointStat, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisOpenNode failed to poll Intr IN endpoint stat %s\n", szEndPointStat));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->aEpStatFile[EndPtIndex] = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Unbuffered Interrupt IN transfers requires us to open the status endpoint and transfer
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * USB_EP_INTR_ONE_XFER once. This will put it in unbuffered transfer mode until it's closed.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char cMsg = USB_EP_INTR_ONE_XFER;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTFileWrite(pDevSol->aEpStatFile[EndPtIndex], &cMsg, sizeof(cMsg), NULL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisOpenNode failed to poll Intr IN endpoint %s\n", szEndPointStat));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTFileClose(pDevSol->aEpStatFile[EndPtIndex]);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->aEpStatFile[EndPtIndex] = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = RTFileOpen(&pDevSol->aEpStatFile[EndPtIndex], szEndPointStat, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisOpenNode failed to open endpoint stat %s in read only.\n", szEndPointStat));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync uint32_t fOpenMode = usbProxySolarisOpenMode(EndPoint, XferType);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (fOpenMode == UINT32_MAX)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisOpenNode invalid file mode for XferType %d\n", XferType));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_INVALID_FMODE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open the Endpoint.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = RTFileOpen(&pDevSol->aEpFile[EndPtIndex], szEndPoint, fOpenMode);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_FAILURE(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisOpenNode failed to open endpoint %s in mode %d\n", szEndPoint, fOpenMode));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTFileClose(pDevSol->aEpStatFile[EndPtIndex]);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->aEpStatFile[EndPtIndex] = NIL_RTFILE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log((USBR3PROXY ":usbProxySolarisOpenNode Success! szEndPoint=%s Endpoint=%#x EndPtIndex=%#x\n", szEndPoint, EndPoint, EndPtIndex));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Completion callback worker.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pTimeout Pointer to a timeval struct specifying the timeout.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisUrbComplete(struct timeval *pTimeout)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Deque the completed URB.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync aio_result_t *pResult = aiowait(pTimeout);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (!pResult) /* Timeout */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log(("usbProxySolarisUrbComplete: timed out\n"));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else if ((intptr_t)pResult == -1) /* aiowait returns -1 instead of a pointer for errors. crap. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (errno == EINVAL)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log(("usbProxySolarisUrbComplete: No pending requests.\n"));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log(("usbProxySolarisUrbComplete: aiowait failed errno=%d\n", errno));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Update the URB status.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PURBSTATUSSOL pStatus = (PURBSTATUSSOL)pResult;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = pStatus->pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = pUrbSol->pDevSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PVUSBURB pUrb = pUrbSol->pVUsbUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#ifdef VBOX_WITH_SOLARIS_USB_ISOC
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrb->enmType == VUSBXFERTYPE_ISOC)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrb->enmDir == VUSBDIRECTION_IN)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync void *pvPayload = pUrbSol->pIsocBufIn + pUrb->cIsocPkts * sizeof(ugen_isoc_pkt_descr_t);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync memcpy(pUrb->abData, pvPayload, pUrb->cbData);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pUrbSol->pIsocBufIn);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pIsocBufIn = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->cbIsocBufIn = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pUrbSol->pIsocBufOut);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pIsocBufOut = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->cbIsocBufOut = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif /* !VBOX_WITH_SOLARIS_USB_ISOC */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->cbData = pResult->aio_return;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->enmStatus = pResult->aio_errno ? VUSBSTATUS_STALL : VUSBSTATUS_OK; /* @todo find a better way */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrb->enmType == VUSBXFERTYPE_MSG)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->cbData += sizeof(VUSBSETUP);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Remove from the active list.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrbSol->pNext)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pNext->pPrev = pUrbSol->pPrev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrbSol->pPrev)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pPrev->pNext = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Assert(pDevSol->pInFlightHead == pUrbSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pInFlightHead = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Link it into the taxing list.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pNext = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pPrev = pDevSol->pTaxingTail;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pDevSol->pTaxingTail)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pTaxingTail->pNext = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pTaxingHead = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pTaxingTail = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectLeave(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log(("%s: usbProxySolarisUrbComplete: cb=%d EndPt=%#x enmStatus=%s\n",
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->pszDesc, pUrb->cbData, pUrb->EndPt, pUrb->enmStatus == VUSBSTATUS_OK ? "VUSBSTATUS_OK" : "NotSuccessful"));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Completion callback for asynchronous URBs.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisAsyncComplete(int Sig)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisAsyncComplete Sig=%s %d\n", Sig == SIGIO ? "SIGIO" : "Irrelevant Sig", Sig));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (Sig == SIGIO)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisUrbComplete(NULL);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Opens the USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pProxyDev The device instance.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pszAddress The path to the device in the dev and devices tree,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The format of this string is "/dev/path|/devices/path".
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pvBackend Backend specific pointer, unused for the solaris backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisOpen pProxyDev=%p pszAddress=%s pvBackend=%p\n", pProxyDev, pszAddress, pvBackend));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Initialize our USB R3 lib.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = USBLibInit();
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Allocate and initialize the solaris backend data.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)RTMemAllocZ(sizeof(*pDevSol));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Parse out 2 paths (dev and devices tree).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char szDevBuf[PATH_MAX];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync char szDevicesBuf[PATH_MAX];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int cFields = sscanf(pszAddress, "%[^'|']|%s", szDevBuf, szDevicesBuf);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (cFields == 2)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync szDevBuf[strlen(szDevBuf)] = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync szDevicesBuf[strlen(szDevicesBuf)] = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrAPrintf(&pDevSol->pszDevPath, "%s", szDevBuf);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrAPrintf(&pDevSol->pszDevicePath, "%s", szDevicesBuf);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = RTCritSectInit(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->Backend.pv = pDevSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Initialize all pipes.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisInitAllPipes(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open the default control and control status endpoint.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = usbProxySolarisOpenDevPipes(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @todo Fix this: Try to get the active configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //int iActiveCfg = -1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //rc = usbProxySolarisGetActiveCfg(pDevSol, &iActiveCfg);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync //pProxyDev->iActiveCfg = usbProxySolarisConfigIndex(pDevSol, iActiveCfg) > 0 ? iActiveCfg : -1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->iActiveCfg = -1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->cIgnoreSetConfigs = 1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisGetActiveCfg failed! rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pProxyDev = pProxyDev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisDevPipes failed. rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisCloseDevPipes(pDevSol); /* Close here to handle partial open failures. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectDelete(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":RTCritSectInit failed. rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrFree(pDevSol->pszDevPath);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrFree(pDevSol->pszDevicePath);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = VERR_GENERAL_FAILURE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":Failed to parse address of USB device pszAddress=%s\n", pszAddress));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync rc = VERR_NO_MEMORY;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":USBLibInit failed. rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync USBLibTerm();
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->Backend.pv = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Post-open initialization of the USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pProxyDev The device instance.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisInit(PUSBPROXYDEV pProxyDev)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisInit: pProxyDev=%p\n", pProxyDev));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pDevSol, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Use the first configuration as the active configure. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PCVUSBDESCCONFIGEX pCfg = &pProxyDev->paCfgDescs[0];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pCfg)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Now seize all the interfaces. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return usbProxySolarisSeizeAllInterfaces(pDevSol, pCfg->Core.bConfigurationValue);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisInit invalid device descriptors.\n"));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_INVALID_HANDLE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Close the USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pProxyDev The device instance.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisClose(PUSBPROXYDEV pProxyDev)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisClose: pProxyDev=%p\n", pProxyDev));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Close the device. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisCloseDevice(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Reset the device without reattaching a new driver. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync USBLibResetDevice(pDevSol->pszDevicePath, false);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Now we can close it and free all the resources.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectDelete(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync while ((pUrbSol = pDevSol->pInFlightHead) != NULL)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pInFlightHead = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pUrbSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync while ((pUrbSol = pDevSol->pFreeHead) != NULL)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pFreeHead = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pUrbSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisAsyncNotify(false);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrFree(pDevSol->pszDevPath);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pszDevPath = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTStrFree(pDevSol->pszDevicePath);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pszDevicePath = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->Backend.pv = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync USBLibTerm();
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Reset the device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pProxyDev The device to reset.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisReset(PUSBPROXYDEV pProxyDev, bool fResetOnSolaris)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisReset pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Close all endpoints and endpoint status nodes. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisCloseEndPoints(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Stop notifications */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisAsyncNotify(false);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Specific device resets are implicitly handled by ugen upon closing/reopening the device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Root hub resets that affects all devices are executed.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (fResetOnSolaris)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /* Reset the device without reattaching a new driver */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = USBLibResetDevice(pDevSol->pszDevicePath, false);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->cIgnoreSetConfigs = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->iActiveCfg = -1;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel(("usbProxySolarisReset: failed! rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return rc;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Set the active configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The caller makes sure that it's not called first time after open or reset
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * with the active interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns success indicator.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pProxyDev The device instance data.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param iCfg The configuration value to set.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSetConfig(PUSBPROXYDEV pProxyDev, int iCfg)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisSetConfig: pProxyDev=%p iCfg=%d\n", pProxyDev, iCfg));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Solaris ugen ignores any SET_CONFIGURATION requests. It does an implicitly config change while
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * opening the appropriate nodes of the configuration. So what we need to do is make sure all the
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * nodes of previous configuration is closed before re-opening/claiming the new configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pProxyDev->iActiveCfg == iCfg)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisCloseEndPoints(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = usbProxySolarisSeizeAllInterfaces(pDevSol, (uint8_t)iCfg);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (iCfg > 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pProxyDev->iActiveCfg = iCfg;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisSetConfig invalid iCfg %d\n", iCfg));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisSetConfig failed to seize all interfaces for iCfg %d\n", iCfg));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return false;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Claims an interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * This is a stub on Solaris since we release/claim all interfaces at
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * open/reset/setconfig time.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns success indicator (always true).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisClaimInterface(PUSBPROXYDEV pProxyDev, int iIf)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Releases an interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * This is a stub on Solaris since we release/claim all interfaces at
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * open/reset/setconfig time.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns success indicator.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisReleaseInterface(PUSBPROXYDEV pProxyDev, int iIf)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Specify an alternate setting for the specified interface of the current configuration.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns success indicator.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisSetInterface(PUSBPROXYDEV pProxyDev, int iIf, int iAlt)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * We already open all alternate settings for all interfaces. Don't think we need to do
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * anything special here. As talking with the specified alternate setting would already be
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * possible as it's already open.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Clears the halted endpoint 'EndPt'.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic bool usbProxySolarisClearHaltedEp(PUSBPROXYDEV pProxyDev, unsigned int EndPt)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisClearHaltedEp pProxyDev=%p EndPt=%u", pProxyDev, EndPt));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Clearing the zero control pipe doesn't make sense and isn't
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * supported by the USBA. Just ignore it.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (EndPt == 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int Status;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync VUSBSETUP Req;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisSetupReq(&Req, VUSB_DIR_TO_DEV | VUSB_TO_ENDPOINT, VUSB_REQ_CLEAR_FEATURE, 0, EndPt, 0);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisCtrlReq(pDevSol->aEpFile[0], pDevSol->aEpStatFile[0], &Req, NULL, 0, &Status);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (Status == VUSBSTATUS_OK)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisClearHaltedEp failed! EndPt=%u\n", EndPt));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return false;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Allocates a Solaris URB request structure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns Pointer to an active URB request.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns NULL on failure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic PUSBPROXYURBSOL usbProxySolarisUrbAlloc(PUSBPROXYDEVSOL pDevSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Try remove a Solaris URB from the free list, if none there allocate a new one.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol = pDevSol->pFreeHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pFreeHead = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectLeave(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol = (PUSBPROXYURBSOL)RTMemAllocZ(sizeof(*pUrbSol));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (!pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->Status.pUrbSol = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pVUsbUrb = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pDevSol = pDevSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Link it into the active list
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pPrev = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pNext = pDevSol->pInFlightHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrbSol->pNext)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pNext->pPrev = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pInFlightHead = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectLeave(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#ifdef VBOX_WITH_SOLARIS_USB_ISOC
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Allocates an isochronous buffer.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pUrbSol Pointer to the solaris URB associated with the transfer.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisUrbAllocIsocBuf(PUSBPROXYURBSOL pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertReturn(pUrbSol, VERR_INVALID_POINTER);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisUrbAllocIsocBuf pUrbSol=%p\n", pUrbSol));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PVUSBURB pUrb = pUrbSol->pVUsbUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync bool fOut = (pUrb->enmDir == VUSBDIRECTION_OUT);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync uint32_t cIsocPkts = pUrb->cIsocPkts;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbIsocPkt = pUrb->aIsocPkts[0].cb; /* I hope this is okay. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbBufOut = sizeof(int) + sizeof(ugen_isoc_pkt_descr_t) * cIsocPkts;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync size_t cbBufIn = cbBufOut - sizeof(int);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync cbBufOut += cbIsocPkt * cIsocPkts;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync caddr_t pBuf = (caddr_t)RTMemAlloc(fOut ? cbBufOut : cbBufIn);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pBuf)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync ugen_isoc_req_head_t *pIsocReq = (ugen_isoc_req_head_t *)pBuf;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync ugen_isoc_pkt_descr_t *pIsocPkt = (ugen_isoc_pkt_descr_t *)pIsocReq->req_isoc_pkt_descrs;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pIsocReq->req_isoc_pkts_count = cIsocPkts;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync for (ushort_t i = 0; i < cIsocPkts; i++)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pIsocPkt[i].dsc_isoc_pkt_len = pUrb->aIsocPkts[i].cb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pIsocPkt[i].dsc_isoc_pkt_actual_len = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pIsocPkt[i].dsc_isoc_pkt_status = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Copy the isoc. Out buffers.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (fOut)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync caddr_t pPayload = pBuf + sizeof(int) + sizeof(*pIsocPkt) * cIsocPkts;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync memcpy(pPayload, pUrb->abData, pUrb->cbData);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Associate the buffer with the solaris URB to free it later as
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * we perform async. transfers.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pIsocBufOut = pBuf;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->cbIsocBufOut = cbBufOut;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (fOut)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pIsocBufIn = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->cbIsocBufIn = 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Allocate space for read buffer. While perform isoc. IN request we will make
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * use of both the pvIsocIn and pvIsocOut buffers (see usbProxySolarisIsocReqAsync).
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync caddr_t pBufIn = (caddr_t)RTMemAlloc(cbBufIn);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pBufIn)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pIsocBufIn = pBufIn;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->cbIsocBufIn = cbBufIn;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTMemFree(pUrbSol->pIsocBufOut);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_NO_MEMORY;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisUrbAllocIsocBuf success! cbBufIn=%ld cbBufOut=%ld\n", cbBufIn, cbBufOut));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VINF_SUCCESS;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_NO_MEMORY;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Frees a Solaris URB request structure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pDevSol The Solaris USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @param pUrbSol The Solaris URB to free.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisUrbFree(PUSBPROXYDEVSOL pDevSol, PUSBPROXYURBSOL pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectEnter(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Remove from the active or taxing list.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrbSol->pNext)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pNext->pPrev = pUrbSol->pPrev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else if (pDevSol->pTaxingTail == pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pTaxingTail = pUrbSol->pPrev;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrbSol->pPrev)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pPrev->pNext = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else if (pDevSol->pTaxingHead == pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pTaxingHead = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else if (pDevSol->pInFlightHead == pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pInFlightHead = pUrbSol->pNext;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertFailed();
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Link it into the free list.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pPrev = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pNext = pDevSol->pFreeHead;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pDevSol->pFreeHead = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pVUsbUrb = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pDevSol = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync RTCritSectLeave(&pDevSol->CritSect);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @copydoc USBPROXYBACK::pfnUrbQueue
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic int usbProxySolarisUrbQueue(PVUSBURB pUrb)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEV pProxyDev = PDMINS_2_DATA(pUrb->pUsbIns, PUSBPROXYDEV);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisUrbQueue pUrb=%p pProxyDev=%p pDevSol=%p EndPt=%#x cbData=%d\n", pUrb, pProxyDev, pDevSol,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->EndPt, pUrb->cbData));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Allocate a solaris urb.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = usbProxySolarisUrbAlloc(pDevSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (!pUrbSol)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return false;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->u64SubmitTS = RTTimeMilliTS();
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pVUsbUrb = pUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrbSol->pDevSol = pDevSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PVUSBSETUP pSetup = (PVUSBSETUP)&pUrb->abData[0];
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync uint8_t EndPt = pUrb->EndPt;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (pUrb->EndPt)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync EndPt = pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? 0x80 : 0);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int EndPtIndex = (EndPt & USBSOL_EPADDR_NUM_MASK) + ((EndPt & USBSOL_EPADDR_DIR_MASK) ? USBSOL_MAXENDPOINTS / 2 : 0);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (EndPtIndex < 0 || EndPtIndex > USBSOL_MAXENDPOINTS - 1)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":usbProxySolarisUrbQueue invalid endpoint address=%#x!\n", pUrb->EndPt));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return VERR_INVALID_HANDLE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log((USBR3PROXY ":usbProxySolarisUrbQueue EndPoint=%#x EndPtIndex=%d XferType=%d Direction=%s\n", pUrb->EndPt, EndPtIndex, pUrb->enmType,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->enmDir == VUSBDIRECTION_IN ? "read" : "write"));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Open the endpoint.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int irc = VERR_GENERAL_FAILURE;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = usbProxySolarisOpenEndPoint(pDevSol, EndPt, pUrb->enmType);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(rc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Perform the transfer.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync switch (pUrb->enmType)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_MSG:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertMsgBreak(pUrb->cbData >= sizeof(VUSBSETUP), ("cbData=%d\n", pUrb->cbData));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (EndPtIndex == 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync irc = usbProxySolarisCtrlReqAsync(pDevSol->aEpFile[EndPtIndex], pSetup, (caddr_t)(pSetup + 1), pSetup->wLength,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync &pUrbSol->Status);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync else
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync irc = usbProxySolarisSendReqAsync(pDevSol->aEpFile[EndPtIndex], pSetup, (caddr_t)(pSetup + 1), pSetup->wLength,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync &pUrbSol->Status);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_INTR:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_BULK:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertMsgBreak(pUrb->enmDir == VUSBDIRECTION_IN || pUrb->enmDir == VUSBDIRECTION_OUT, ("invalid enmDir=%d\n", pUrb->enmDir));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync irc = usbProxySolarisIOAsync(pDevSol->aEpFile[EndPtIndex], (caddr_t)(pUrb->abData), pUrb->cbData,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->enmDir == VUSBDIRECTION_IN ? RTFILE_O_READ : RTFILE_O_WRITE, &pUrbSol->Status);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log((USBR3PROXY ":usbProxySolarisUrbQueue enmType=%d\n", pUrb->enmType));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#ifdef VBOX_WITH_SOLARIS_USB_ISOC
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync case VUSBXFERTYPE_ISOC:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Allocate the isoc buffer and submit the request.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync irc = usbProxySolarisUrbAllocIsocBuf(pUrbSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (RT_SUCCESS(irc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync irc = usbProxySolarisIsocReqAsync(pDevSol->aEpFile[EndPtIndex], pUrbSol, &pUrbSol->Status);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync#endif
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync default:
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync AssertMsgFailed(("%s: enmType=%#x\n", pUrb->pszDesc, pUrb->enmType));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync break;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( RT_SUCCESS(rc)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync && RT_SUCCESS(irc))
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":successfully queued USB %p Endpoint=%d EndPtIndex=%d enmType=%d cbData=%d\n", pUrb, pUrb->EndPt, EndPtIndex,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->enmType, pUrb->cbData));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pUrb->Dev.pvPrivate = pUrbSol;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return true;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbFree(pDevSol, pUrbSol);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogRel((USBR3PROXY ":failed to transfer URB %p Endpoint=%d enmType=%d cbData=%d\n", pUrb, pUrb->EndPt, pUrb->enmType, pUrb->cbData));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return false;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Cancels the URB.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The URB requires reaping, so we don't change its state.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic void usbProxySolarisUrbCancel(PVUSBURB pUrb)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = (PUSBPROXYURBSOL)pUrb->Dev.pvPrivate;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisUrbCancel pUrb=%p pUrbSol=%p pDevSol=%p", pUrb, pUrbSol, pUrbSol->pDevSol));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync int rc = aiocancel(&pUrbSol->Status.Result);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log((USBR3PROXY ":usbProxySolarisUrbCancel aiocancel returned to %d.\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync NOREF(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 */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncstatic PVUSBURB usbProxySolarisUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync LogFlow((USBR3PROXY ":usbProxySolarisUrbReap pProxyDev=%p cMillies=%u\n", pProxyDev, cMillies));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Deque URBs inflight or those landed.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if ( pDevSol->pInFlightHead
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync || pDevSol->pTaxingHead)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync struct timeval *pTimeout = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync if (cMillies > 0)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync {
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync struct timeval Timeout;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Timeout.tv_sec = cMillies >= 1000 ? cMillies / 1000L : 0;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Timeout.tv_usec = cMillies >= 1000 ? cMillies % 1000L : cMillies;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync pTimeout = &Timeout;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbComplete(pTimeout);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync }
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /*
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Any URBs pending delivery?
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PVUSBURB pUrb = NULL;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync while ( pDevSol->pTaxingHead
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync && !pUrb)
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 if (pUrb)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync Log(("%s: usbProxySolarisUrbReap: pProxyDev=%s returns %p enmStatus=%d\n", pUrb->pszDesc, pProxyDev->pUsbIns->pszName, pUrb, pUrb->enmStatus));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync return pUrb;
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync}
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/**
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The Solaris USB Proxy Backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsyncextern const USBPROXYBACK g_USBProxyDeviceHost =
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync{
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync "host",
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisOpen,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisInit,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisClose,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisReset,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisSetConfig,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisClaimInterface,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisReleaseInterface,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisSetInterface,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisClearHaltedEp,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbQueue,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbCancel,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync usbProxySolarisUrbReap,
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync NULL
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync};
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync