USBProxyDevice-usbip.cpp revision dc90b2bed0e77e6ff8b99ddd7abc218ec274cb59
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * USB device proxy - USB/IP backend.
772269936494ffaddd0750ba9e28e805ba81398cvboxsync * Copyright (C) 2014 Oracle Corporation
78f327ee942771169c65c91baf789fd10e72b01avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
78f327ee942771169c65c91baf789fd10e72b01avboxsync * available from http://www.virtualbox.org. This file is free software;
78f327ee942771169c65c91baf789fd10e72b01avboxsync * you can redistribute it and/or modify it under the terms of the GNU
78f327ee942771169c65c91baf789fd10e72b01avboxsync * General Public License (GPL) as published by the Free Software
78f327ee942771169c65c91baf789fd10e72b01avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
78f327ee942771169c65c91baf789fd10e72b01avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
78f327ee942771169c65c91baf789fd10e72b01avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/*******************************************************************************
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync* Header Files *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync*******************************************************************************/
e24bfeec424d0e6481eccbe85ffde550384b6364vboxsync/*******************************************************************************
e24bfeec424d0e6481eccbe85ffde550384b6364vboxsync* Constants And Macros, Structures and Typedefs *
e24bfeec424d0e6481eccbe85ffde550384b6364vboxsync*******************************************************************************/
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** The USB version number used for the protocol. */
dcd01485c22687cd874d69a566131b4a6a82e54bvboxsync/** Request indicator in the command code. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Command/Reply code for OP_REQ/RET_DEVLIST. */
7c7005551979d5c932efd88089122124a9de6751vboxsync/** Command/Reply code for OP_REQ/REP_IMPORT. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** USB submit command identifier. */
7c7005551979d5c932efd88089122124a9de6751vboxsync/** USB submit status identifier. */
7c7005551979d5c932efd88089122124a9de6751vboxsync/** URB unlink (cancel) command identifier. */
7c7005551979d5c932efd88089122124a9de6751vboxsync/** URB unlink (cancel) reply identifier. */
7c7005551979d5c932efd88089122124a9de6751vboxsync/** Short read is not okay for the specified URB. */
7c7005551979d5c932efd88089122124a9de6751vboxsync/** Queue the isochronous URB as soon as possible. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Don't use DMA mappings for this URB. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#define USBIP_XFER_FLAGS_NO_TRANSFER_DMA_MAP RT_BIT_32(2)
1f2b5fc378de7ce78fee422ffb66635630f23016vboxsync/** Explain - only applies to UHCI. */
1f2b5fc378de7ce78fee422ffb66635630f23016vboxsync/** URB direction - input. */
1f2b5fc378de7ce78fee422ffb66635630f23016vboxsync/** URB direction - output. */
1f2b5fc378de7ce78fee422ffb66635630f23016vboxsync * Exported device entry in the OP_RET_DEVLIST reply.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Path of the device, zero terminated string. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Bus ID of the exported device, zero terminated string. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Bus number. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Device number. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Speed indicator of the device. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Vendor ID of the device. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Product ID of the device. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Device release number. */
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync /** Device class. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Device Subclass. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Device protocol. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Current configuration value of the device. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Number of interfaces for the device. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pointer to a exported device entry. */
7c7005551979d5c932efd88089122124a9de6751vboxsync * Interface descriptor entry for an exported device.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Intefrace class. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Interface sub class. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Interface protocol identifier. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Padding byte for alignment. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pointer to an interface descriptor entry. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsynctypedef UsbIpDeviceInterface *PUsbIpDeviceInterface;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * USB/IP Import request.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Protocol version number. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Command code. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Status field, unused. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Bus Id of the device as zero terminated string. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pointer to a import request. */
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync * USB/IP Import reply.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * This is only the header, for successful
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * imports the device details are sent to as
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * defined in UsbIpExportedDevice.
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Protocol version number. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Command code. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Status field, unused. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pointer to a import reply. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Command/Reply header common to the submit and unlink commands
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Sequence number to identify the URB. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Device id. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Direction of the endpoint (host->device, device->host). */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Endpoint number. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pointer to a request/reply header. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * USB/IP Submit request.
7c7005551979d5c932efd88089122124a9de6751vboxsync /** The request header. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Transfer flags for the URB. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Transfer buffer length. */
2868a4e01e366cc5b7228503675dbbf3ecdeba2cvboxsync /** Frame to transmit an ISO frame. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Number of isochronous packets. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Maximum time for the request on the server side host controller. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Setup data for a control URB. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pointer to a submit request. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * USB/IP Submit reply.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** The reply header. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Status code. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Actual length of the reply buffer. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** The actual selected frame for a isochronous transmit. */
ff8c2dd777cdea509c35fae4acbfcf61e9c7a3c4vboxsync /** Number of isochronous packets. */
ff8c2dd777cdea509c35fae4acbfcf61e9c7a3c4vboxsync /** Number of failed isochronous packets. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Setup data for a control URB. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pointer to a submit reply. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Unlink URB request.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** The request header. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** The sequence number to unlink. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync/** Pointer to a URB unlink request. */
3c3d0383bb6ce1db26a5d4ca83da998bbac6eeb5vboxsync * Unlink URB reply.
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** The reply header. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Status of the request. */
ebc7c1b822f7cde4e2ed4c54da127eb7a3a28e7dvboxsync/** Pointer to a URB unlink request. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync * USB/IP backend specific data for one URB.
26809165876a75147696a496b69185a6aecbb8b0vboxsync * Required for tracking in flight and landed URBs.
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** List node for the in flight or landed URB list. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Sequence number the assigned URB is identified by. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Pointer to the VUSB URB. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync/** Pointer to a USB/IP URB. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Backend data for the USB/IP USB Proxy device backend.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** IPRT socket handle. */
32c2812cebede5503d639923fb8b4340cf514e4evboxsync /** Pollset with the wakeup pipe and socket. */
32c2812cebede5503d639923fb8b4340cf514e4evboxsync /** Pipe endpoint - read (in the pollset). */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Pipe endpoint - write. */
7c7005551979d5c932efd88089122124a9de6751vboxsync /** Flag whether the reaper thread was woken up. */
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync volatile bool fWokenUp;
a6fc0ecba4e98bb619fc1d42bcdb4c37353ebf8evboxsync /** Flag whether the reaper thread is waiting in the select call. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync volatile bool fWaiting;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Next sequence number to use for identifying submitted URBs. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** Fast mutex protecting the lists below against concurrent access. */
7c7005551979d5c932efd88089122124a9de6751vboxsync /** List of in flight URBs. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** List of landed URBs. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** Port of the USB/IP host to connect to. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** USB/IP host address. */
d97357e2036109245c83ba553d0290212e28ea40vboxsync /** USB Bus ID of the device to capture. */
7c7005551979d5c932efd88089122124a9de6751vboxsync /** The device ID to use to identify the device. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pollset id of the socket. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Pollset id of the pipe. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Converts a request/reply header from network to host endianness.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns nothing.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pHdr The header to convert.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncDECLINLINE(void) usbProxyUsbIpReqRetHdrN2H(PUsbIpReqRetHdr pHdr)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pHdr->u32Direction = RT_H2N_U32(pHdr->u32Direction);
80a573ec1c224241824d55a4c1bdb1294618aa96vboxsync * Converts a request/reply header from host to network endianness.
541ba632c438350cc8044d7ce2c8623dca446546vboxsync * @returns nothing.
80a573ec1c224241824d55a4c1bdb1294618aa96vboxsync * @param pHdr The header to convert.
d97357e2036109245c83ba553d0290212e28ea40vboxsyncDECLINLINE(void) usbProxyUsbIpReqRetHdrH2N(PUsbIpReqRetHdr pHdr)
d97357e2036109245c83ba553d0290212e28ea40vboxsync pHdr->u32Direction = RT_N2H_U32(pHdr->u32Direction);
d97357e2036109245c83ba553d0290212e28ea40vboxsync * Converts a submit request from host to network endianness.
d97357e2036109245c83ba553d0290212e28ea40vboxsync * @returns nothing.
d97357e2036109245c83ba553d0290212e28ea40vboxsync * @param pReqSubmit The submit request to convert.
d97357e2036109245c83ba553d0290212e28ea40vboxsyncDECLINLINE(void) usbProxyUsbIpReqSubmitH2N(PUsbIpReqSubmit pReqSubmit)
d97357e2036109245c83ba553d0290212e28ea40vboxsync pReqSubmit->u32XferFlags = RT_H2N_U32(pReqSubmit->u32XferFlags);
d97357e2036109245c83ba553d0290212e28ea40vboxsync pReqSubmit->u32TransferBufferLength = RT_H2N_U32(pReqSubmit->u32TransferBufferLength);
d97357e2036109245c83ba553d0290212e28ea40vboxsync pReqSubmit->u32StartFrame = RT_H2N_U32(pReqSubmit->u32StartFrame);
d97357e2036109245c83ba553d0290212e28ea40vboxsync pReqSubmit->u32NumIsocPkts = RT_H2N_U32(pReqSubmit->u32NumIsocPkts);
d97357e2036109245c83ba553d0290212e28ea40vboxsync pReqSubmit->u32Interval = RT_H2N_U32(pReqSubmit->u32Interval);
d97357e2036109245c83ba553d0290212e28ea40vboxsync * Converts a submit reply from network to host endianness.
d97357e2036109245c83ba553d0290212e28ea40vboxsync * @returns nothing.
d97357e2036109245c83ba553d0290212e28ea40vboxsync * @param pReqSubmit The submit reply to convert.
d97357e2036109245c83ba553d0290212e28ea40vboxsyncDECLINLINE(void) usbProxyUsbIpRetSubmitN2H(PUsbIpRetSubmit pRetSubmit)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pRetSubmit->u32Status = RT_N2H_U32(pRetSubmit->u32Status);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pRetSubmit->u32ActualLength = RT_N2H_U32(pRetSubmit->u32ActualLength);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pRetSubmit->u32StartFrame = RT_N2H_U32(pRetSubmit->u32StartFrame);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pRetSubmit->u32NumIsocPkts = RT_N2H_U32(pRetSubmit->u32NumIsocPkts);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pRetSubmit->u32ErrorCount = RT_N2H_U32(pRetSubmit->u32ErrorCount);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Convert the given exported device structure from host to network byte order.
e4e2d49b574b44c06b923b86fbfc12253d58e310vboxsync * @returns nothing.
e4e2d49b574b44c06b923b86fbfc12253d58e310vboxsync * @param pDevice The device structure to convert.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncDECLINLINE(void) usbProxyUsbIpExportedDeviceN2H(PUsbIpExportedDevice pDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pDevice->u32BusNum = RT_N2H_U32(pDevice->u32BusNum);
e4e2d49b574b44c06b923b86fbfc12253d58e310vboxsync pDevice->u32DevNum = RT_N2H_U32(pDevice->u32DevNum);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pDevice->u16VendorId = RT_N2H_U16(pDevice->u16VendorId);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pDevice->u16ProductId = RT_N2H_U16(pDevice->u16ProductId);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pDevice->u16BcdDevice = RT_N2H_U16(pDevice->u16BcdDevice);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Converts a USB/IP status code to VBox status code.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns VBox status code.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param u32Status The USB/IP status code from the reply.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncDECLINLINE(int) usbProxyUsbIpErrConvertFromStatus(uint32_t u32Status)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Gets the next free sequence number.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns Next free sequence number.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pProxyDevUsbIp The USB/IP proxy device data.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncDECLINLINE(uint32_t) usbProxyUsbIpSeqNumGet(PUSBPROXYDEVUSBIP pProxyDevUsbIp)
0da0539aeae9b2692f4967c4a8ef273018effb2evboxsync return ASMAtomicIncU32(&pProxyDevUsbIp->u32SeqNumNext);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Parse the string representation of the host address.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns VBox status code.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pProxyDevUsbIp The USB/IP proxy device data to parse the address for.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pszAddress The address string to parse.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic int usbProxyUsbIpParseAddress(PUSBPROXYDEVUSBIP pProxyDevUsbIp, const char *pszAddress)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTStrToUInt32Ex(pszPortStart, NULL, 10 /* uBase */, &pProxyDevUsbIp->uPort);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTStrAllocEx(&pDevUsbIp->pszHost, cbHost + 1);
945e2415c4f3b92c25b27f5568cd94e281353e5fvboxsync rc = RTStrCopyEx(pDevUsbIp->pszHost, cbHost + 1, pszAddress, cbHost);
d97357e2036109245c83ba553d0290212e28ea40vboxsync * Connects to the USB/IP host and claims the device given in the proxy device data.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns VBox status.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pProxyDevUsbIp The USB/IP proxy device data.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic int usbProxyUsbIpConnect(PUSBPROXYDEVUSBIP pProxyDevUsbIp)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpClientConnect(pDevUsbIp->pszHost, pDevUsbIp->uPort, &pDevUsbIp->hSocket);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Disable send coalescing. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpSetSendCoalescing(pDevUsbIp->hSocket, false);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync LogRel(("UsbIp: Disabling send coalescing failed (rc=%Rrc), continuing nevertheless but expect reduced performance\n", rc));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Import the device, i.e. claim it for our use. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ReqImport.u16Cmd = RT_H2N_U16(USBIP_INDICATOR_REQ |Â USBIP_REQ_RET_IMPORT);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTStrCopy(&ReqImport.aszBusId[0], sizeof(ReqImport.aszBusId[0]), pProxyDevUsbIp->pszBusId);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpWrite(pDevUsbIp->hSocket, &ReqImport, sizeof(ReqImport));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Read the reply. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpRead(pDevUsbIp->hSocket, &RetImport, sizeof(RetImport));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync RetImport.u16Version = RT_N2H_U16(RetImport.u16Version);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync RetImport.u32Status = RT_N2H_U16(RetImport.u32Status);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Read the device data. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpRead(pDevUsbIp->hSocket, &Device, sizeof(Device));
85668909c68b5d0e67c89d6042535b41c4bffeccvboxsync pProxyDevUsbIp->u32DevId = (Device.u32BusNum << 16) |Â Device.u32DevNum;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Check what went wrong and leave a meaningful error message in the log. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync LogRel(("UsbIp: Unexpected protocol version received from host (%#x vs. %#x)\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync LogRel(("UsbIp: Unexpected reply code received from host (%#x vs. %#x)\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync LogRel(("UsbIp: Claiming the device has failed on the host with an unspecified error\n"));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync AssertMsgFailed(("Something went wrong with if condition\n"));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync LogRel(("UsbIp: Given bus ID is exceeds permitted protocol length: %u vs %u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync strlen(pProxyDevUsbIp->pszBusId) + 1, sizeof(ReqImport.aszBusId[0])));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync RTTcpClientCloseEx(pDevUsbIp->hSocket, false /*fGracefulShutdown*/);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync LogRel(("UsbIp: Connecting to the host %s failed with %Rrc\n", pDevUsbIp->pszHost, rc));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Disconnects from the USB/IP host releasing the device given in the proxy device data.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns VBox status code.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pProxyDevUsbIp The USB/IP proxy device data.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic int usbProxyUsbIpDisconnect(PUSBPROXYDEVUSBIP pProxyDevUsbIp)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpClientCloseEx(pDevUsbIp->hSocket, false /*fGracefulShutdown*/);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Synchronously exchange a given control message with the remote device.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @eturns VBox status code.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pProxyDevUsbIp The USB/IP proxy device data.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pSetup The setup message.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @note This method is only used to implement the *SetConfig, *SetInterface and *ClearHaltedEp
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * callbacks because the USB/IP protocol lacks dedicated requests for these.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @remark It is assumed that this method is never called while usbProxyUsbIpUrbReap is called
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * on another thread.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic int usbProxyUsbIpCtrlUrbExchangeSync(PUSBPROXYDEVUSBIP pProxyDevUsbIp, PVUSBSETUP pSetup)
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync AssertMsg(!pProxyDevUsbIp->fWaiting, ("usbProxyUsbIpUrbReap is called on another thread\n"));
a6fc0ecba4e98bb619fc1d42bcdb4c37353ebf8evboxsync uint32_t u32SeqNum = usbProxyUsbIpSeqNumGet(pProxyDevUsbIp);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ReqSubmit.Hdr.u32Endpoint = 0; /* Only default control endpoint is allowed for these kind of messages. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync memcpy(&ReqSubmit.Setup, pSetup, sizeof(ReqSubmit.Setup));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Send the command. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpWrite(pProxyDevUsbIp->hSocket, &ReqSubmit, sizeof(ReqSubmit));
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync /* Wait for the response. */
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync /** @todo: Don't wait indefinitely long. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTTcpRead(pProxyDevUsbIp->hSocket, &RetSubmit, sizeof(RetSubmit));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = usbProxyUsbIpErrConvertFromStatus(RetSubmit.u32Status);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * The USB proxy device functions.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic DECLCALLBACK(int) usbProxyUsbIpOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync LogFlowFunc(("pProxyDev=%p pszAddress=%s, pvBackend=%p\n", pProxyDev, pszAddress, pvBackend));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync PUSBPROXYDEVUSBIP pDevUsbIp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Setup wakeup pipe and poll set first. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTPipeCreate(&pDevUsbIp->hPipeR, &pDevUsbIp->hPipeW, 0);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = RTPollSetAddPipe(pDevUsbIp->hPollSet, pDevUsbIp->hPipeR,
return rc;
return VERR_NOT_IMPLEMENTED;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_NOT_IMPLEMENTED;
return NULL;
ReqSubmit.Hdr.u32Endpoint = 0; /* Only default control endpoint is allowed for these kind of messages. */
return VERR_NOT_IMPLEMENTED;
return rc;
sizeof(USBPROXYDEVUSBIP),
NULL,