9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * USB device proxy - the Solaris backend.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Copyright (C) 2009-2014 Oracle Corporation
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * available from http://www.virtualbox.org. This file is free software;
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * General Public License (GPL) as published by the Free Software
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3f1f30f349c6d9ef74ba8d16ff0c5b0ac47def6cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Header Files *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Defined Constants And Macros *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/** Log Prefix. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync/*******************************************************************************
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync* Structures and Typedefs *
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync*******************************************************************************/
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Wrapper around the solaris urb request structure.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * This is required to track in-flight and landed URBs.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the Solaris device. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /** Pointer to the VUSB URB (set to NULL if canceled). */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the next solaris URB. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the previous solaris URB. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Data for the solaris usb proxy backend.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Path of the USB device in the devices tree (persistent). */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /** The connection to the client driver. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Pointer to the proxy device instance. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** Critical section protecting the two lists. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The list of free solaris URBs. Singly linked. */
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 /** The list of landed solaris URBs. Doubly linked.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Only the split head will appear in this list. */
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync /** The tail of the landed solaris URBs. */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /** Pipe handle for waking up - writing end. */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /** Pipe handle for waking up - reading end. */
07a38a36071e285664891c195d2c44003dc19b1avboxsyncstatic PVUSBURB usbProxySolarisUrbComplete(PUSBPROXYDEVSOL pDevSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Allocates a Solaris URB request structure.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns Pointer to an active URB request.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns NULL on failure.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The solaris USB device.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic PUSBPROXYURBSOL usbProxySolarisUrbAlloc(PUSBPROXYDEVSOL pDevSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Try remove a Solaris URB from the free list, if none there allocate a new one.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrbSol = (PUSBPROXYURBSOL)RTMemAlloc(sizeof(*pUrbSol));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Link it into the active list
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Frees a Solaris URB request structure.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris USB device.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pUrbSol The Solaris URB to free.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic void usbProxySolarisUrbFree(PUSBPROXYDEVSOL pDevSol, PUSBPROXYURBSOL pUrbSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Remove from the active or taxing list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Link it into the free list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Close the connection to the USB client driver.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * This is required because our userland enumeration relies on drivers/device trees
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * to recognize active devices, and hence if this device is unplugged we should no
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * longer keep the client driver loaded.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic void usbProxySolarisCloseFile(PUSBPROXYDEVSOL pDevSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * The client driver IOCtl Wrapper function.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris device instance.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param Function The Function.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pvData Opaque pointer to the data.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param cbData Size of the data pointed to by pvData.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic int usbProxySolarisIOCtl(PUSBPROXYDEVSOL pDevSol, unsigned Function, void *pvData, size_t cbData)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisIOCtl connection to driver gone!\n"));
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync int rc = RTFileIoCtl(pDevSol->hFile, Function, &Req, sizeof(Req), &Ret);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Command %#x failed, USB Device '%s' disconnected!\n", Function, pDevSol->pProxyDev->pUsbIns->pszName));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Command %#x failed. Req.rc=%Rrc\n", Function, Req.rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Function %#x failed. rc=%Rrc\n", Function, rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Get the active configuration from the device. The first time this is called
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * our client driver would returned the cached configuration since the device is first plugged in.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Subsequent get configuration requests are passed on to the device.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris device instance.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsyncstatic inline int usbProxySolarisGetActiveConfig(PUSBPROXYDEVSOL pDevSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_CONFIG, &GetConfigReq, sizeof(GetConfigReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pDevSol->pProxyDev->iActiveCfg = GetConfigReq.bConfigValue;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Failed to get configuration. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Opens the USB device.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device instance.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pszAddress The unique device identifier.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * The format of this string is "VendorId:ProducIt:Release:StaticPath".
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pvBackend Backend specific pointer, unused for the solaris backend.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend)
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisOpen pProxyDev=%p pszAddress=%s pvBackend=%p\n", pProxyDev, pszAddress, pvBackend));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Initialize our USB R3 lib.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Allocate and initialize the solaris backend data.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = RTStrPrintf(szDeviceIdent, sizeof(szDeviceIdent), "%s", pszAddress);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Create wakeup pipe.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = RTPipeCreate(&pDevSol->hPipeWakeupR, &pDevSol->hPipeWakeupW, 0);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = USBLibGetClientInfo(szDeviceIdent, &pszDevicePath, &Instance);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Open the client driver.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = RTFileOpen(&hFile, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Verify client driver version.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_VERSION, &GetVersionReq, sizeof(GetVersionReq));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync if ( GetVersionReq.u32Major == VBOXUSB_VERSION_MAJOR
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync && GetVersionReq.u32Minor >= VBOXUSB_VERSION_MINOR)
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync * Try & get the current cached config from Solaris.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":version mismatch! driver v%d.%d expecting ~v%d.%d\n", GetVersionReq.u32Major,
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync GetVersionReq.u32Minor, VBOXUSB_VERSION_MAJOR, VBOXUSB_VERSION_MINOR));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":failed to query driver version. rc=%Rrc\n", rc));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":failed to open device. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":failed to get client info. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":RTCritSectInit failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync LogRel((USBPROXY ":RTStrAPrintf failed. rc=%Rrc pszAddress=%s\n", rc, pszAddress));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":USBLibInit failed. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Close the USB device.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device instance.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(void) usbProxySolarisClose(PUSBPROXYDEV pProxyDev)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisClose: pProxyDev=%p\n", pProxyDev));
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Close the device (do not re-enumerate). */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLOSE_DEVICE, &CloseReq, sizeof(CloseReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Now we can close it and free all the resources.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Reset the device.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns VBox status code.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device to reset.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param fRootHubReset Is this a root hub reset or device specific reset request.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisReset(PUSBPROXYDEV pProxyDev, bool fRootHubReset)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisReset pProxyDev=%s fRootHubReset=%d\n", pProxyDev->pUsbIns->pszName, fRootHubReset));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /** Pass all resets to the device. The Trekstor USB (1.1) stick requires this to work. */
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Soft reset the device. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLOSE_DEVICE, &CloseReq, sizeof(CloseReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Get the active config. Solaris USBA sets a default config. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisReset failed. rc=%d\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Set the active configuration.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * The caller makes sure that it's not called first time after open or reset
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * with the active interface.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pProxyDev The device instance data.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param iCfg The configuration value to set.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisSetConfig(PUSBPROXYDEV pProxyDev, int iCfg)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisSetConfig: pProxyDev=%p iCfg=%#x\n", pProxyDev, iCfg));
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_SET_CONFIG, &SetConfigReq, sizeof(SetConfigReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisSetConfig failed to switch configuration. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Claims an interface.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * This is a stub on Solaris since we release/claim all interfaces at
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * as and when required with endpoint opens.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator (always true).
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisClaimInterface(PUSBPROXYDEV pProxyDev, int iIf)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Releases an interface.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * This is a stub on Solaris since we release/claim all interfaces at
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * as and when required with endpoint opens.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisReleaseInterface(PUSBPROXYDEV pProxyDev, int iIf)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Specify an alternate setting for the specified interface of the current configuration.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @returns success indicator.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(int) usbProxySolarisSetInterface(PUSBPROXYDEV pProxyDev, int iIf, int iAlt)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisSetInterface: pProxyDev=%p iIf=%d iAlt=%d\n", pProxyDev, iIf, iAlt));
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_SET_INTERFACE, &SetInterfaceReq, sizeof(SetInterfaceReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisSetInterface failed to set interface. rc=%Rrc\n", rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Clears the halted endpoint 'EndPt'.
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsyncstatic DECLCALLBACK(int) usbProxySolarisClearHaltedEp(PUSBPROXYDEV pProxyDev, unsigned int EndPt)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisClearHaltedEp pProxyDev=%p EndPt=%#x\n", pProxyDev, EndPt));
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_CLEAR_EP, &ClearEpReq, sizeof(ClearEpReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisClearHaltedEp failed! rc=%Rrc\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * @copydoc USBPROXYBACK::pfnUrbQueue
938ff344730f28b89abcc18ee7b629cdae335d33vboxsyncstatic DECLCALLBACK(int) usbProxySolarisUrbQueue(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ": usbProxySolarisUrbQueue: pProxyDev=%s pUrb=%p EndPt=%#x enmDir=%d cbData=%d pvData=%p\n",
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pProxyDev->pUsbIns->pszName, pUrb, pUrb->EndPt, pUrb->enmDir, pUrb->cbData, pUrb->abData));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = usbProxySolarisUrbAlloc(pDevSol);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisUrbQueue: Failed to allocate URB.\n"));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync EndPt |= pUrb->enmDir == VUSBDIRECTION_IN ? VUSB_DIR_TO_HOST : VUSB_DIR_TO_DEVICE;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync UrbReq.aIsocPkts[i].enmStatus = VUSBSTATUS_INVALID;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_SEND_URB, &UrbReq, sizeof(UrbReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisUrbQueue success cbData=%d.\n", pUrb->cbData));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":usbProxySolarisUrbQueue Failed!! pProxyDev=%s pUrb=%p EndPt=%#x bEndpoint=%#x enmType=%d enmDir=%d cbData=%u rc=%Rrc\n",
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pProxyDev->pUsbIns->pszName, pUrb, pUrb->EndPt, UrbReq.bEndpoint, pUrb->enmType, pUrb->enmDir, pUrb->cbData, rc));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Cancels a URB.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The URB requires reaping, so we don't change its state.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @remark There isn't any way to cancel a specific asynchronous request
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * on Solaris. So we just abort pending URBs on the pipe.
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsyncstatic DECLCALLBACK(int) usbProxySolarisUrbCancel(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync PUSBPROXYURBSOL pUrbSol = (PUSBPROXYURBSOL)pUrb->Dev.pvPrivate;
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisUrbCancel pUrb=%p pUrbSol=%p pDevSol=%p\n", pUrb, pUrbSol, pUrbSol->pDevSol));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync /* Aborting the control pipe isn't supported, pretend success. */
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync AbortPipeReq.bEndpoint = pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? VUSB_DIR_TO_HOST : VUSB_DIR_TO_DEVICE);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_ABORT_PIPE, &AbortPipeReq, sizeof(AbortPipeReq));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync LogRel((USBPROXY ":usbProxySolarisUrbCancel failed to abort pipe. rc=%Rrc\n", rc));
0aefc1b31a411a6cdfa560b5d95d96b47f6fd9e4vboxsync LogFlow((USBPROXY ":usbProxySolarisUrbCancel: rc=%Rrc.\n", rc));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Reap URBs in-flight on a device.
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.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic DECLCALLBACK(PVUSBURB) usbProxySolarisUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync //LogFlowFunc((USBPROXY ":usbProxySolarisUrbReap pProxyDev=%p cMillies=%u\n", pProxyDev, cMillies));
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Don't block if nothing is in the air.
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Deque URBs inflight or those landed.
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync int cMilliesWait = cMillies == RT_INDEFINITE_WAIT ? -1 : cMillies;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Reaping failed, USB Device '%s' disconnected!\n", pDevSol->pProxyDev->pUsbIns->pszName));
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync /* Got woken up, drain pipe. */
fdd4de0a765fab2da4919899d85d8aae4084afafvboxsync RTPipeRead(pDevSol->hPipeWakeupR, &bRead, 1, &cbIgnored);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync * It is possible that we got woken up and have an URB pending
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync * for completion. Do it on the way out. Otherwise return
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync * immediately to the caller.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync //LogFlow((USBPROXY ":usbProxySolarisUrbReap: Timed out\n"));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisUrbReap Poll rc=%d errno=%d\n", rc, errno));
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * Any URBs pending delivery?
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Reads a completed/error'd URB from the client driver (no waiting).
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * @param pDevSol The Solaris device instance.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsyncstatic PVUSBURB usbProxySolarisUrbComplete(PUSBPROXYDEVSOL pDevSol)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlowFunc((USBPROXY ":usbProxySolarisUrbComplete pDevSol=%p\n", pDevSol));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync int rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_REAP_URB, &UrbReq, sizeof(UrbReq));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync PUSBPROXYURBSOL pUrbSol = (PUSBPROXYURBSOL)UrbReq.pvUrbR3;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Update the URB.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->aIsocPkts[i].cb = UrbReq.aIsocPkts[i].cbActPkt;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->aIsocPkts[i].enmStatus = UrbReq.aIsocPkts[i].enmStatus;
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY ":usbProxySolarisUrbComplete ISOC cbData=%d cbActPktSum=%d\n", pUrb->cbData, cbData));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Remove from the active list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync * Link it into the taxing list.
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogFlow((USBPROXY "usbProxySolarisUrbComplete: cb=%d EndPt=%#x enmDir=%d enmStatus=%s (%d) \n",
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync pUrb->cbData, pUrb->EndPt, pUrb->enmDir, pUrb->enmStatus == VUSBSTATUS_OK ? "OK" : "** Failed **", pUrb->enmStatus));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync// if (pUrb->cbData < 2049)
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync// LogFlow((USBPROXY "%.*Rhxd\n", pUrb->cbData, pUrb->abData));
ef18b2695476bf69da3b80e961a45532302ce14fvboxsync LogRel((USBPROXY ":Reaping URB failed. rc=%Rrc\n", rc));
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsyncstatic DECLCALLBACK(int) usbProxySolarisWakeup(PUSBPROXYDEV pProxyDev)
500703d73a19206f687846716a3923350c87c09evboxsync PUSBPROXYDEVSOL pDevSol = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVSOL);
d0e467f88aeb4288b409908dbe1b96d07c7133b2vboxsync return RTPipeWrite(pDevSol->hPipeWakeupW, "", 1, &cbIgnored);
9de2fa82343af2df7df171b18afbe32b6f37ed84vboxsync * The Solaris USB Proxy Backend.
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /* pszName */
9576fc6de57fa406fdcc1600a55480e997b27444vboxsync /* cbBackend */