/** * SET_INTERFACE. * * @returns success indicator. */ static DECLCALLBACK(int) usbProxyFreeBSDSetInterface(PUSBPROXYDEV pProxyDev, int iIf, int iAlt) { PUSBPROXYDEVFBSD pDevFBSD = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVFBSD); struct usb_alt_interface UsbIntAlt; int rc; LogFlow(("usbProxyFreeBSDSetInterface: pProxyDev=%p iIf=%x iAlt=%x\n", pProxyDev, iIf, iAlt)); /* We need to release kernel ressources first. */ rc = usbProxyFreeBSDFsUnInit(pProxyDev); if (RT_FAILURE(rc)) { LogFlow(("usbProxyFreeBSDSetInterface: Freeing kernel resources " "failed failed rc=%d\n", rc)); return rc; } memset(&UsbIntAlt, 0, sizeof(UsbIntAlt)); UsbIntAlt.uai_interface_index = iIf; UsbIntAlt.uai_alt_index = iAlt; rc = usbProxyFreeBSDDoIoCtl(pProxyDev, USB_SET_ALTINTERFACE, &UsbIntAlt, true); if (RT_FAILURE(rc)) { LogFlow(("usbProxyFreeBSDSetInterface: Setting interface %d %d " "failed rc=%d\n", iIf, iAlt, rc)); return rc; } return usbProxyFreeBSDFsInit(pProxyDev); }
/** * SET_CONFIGURATION. * * The caller makes sure that it's not called first time after open or reset * with the active interface. * * @returns success indicator. * @param pProxyDev The device instance data. * @param iCfg The configuration to set. */ static int usbProxyFreeBSDSetConfig(PUSBPROXYDEV pProxyDev, int iCfg) { PUSBPROXYDEVFBSD pDevFBSD = (PUSBPROXYDEVFBSD) pProxyDev->Backend.pv; int iCfgIndex; int rc; LogFlow(("usbProxyFreeBSDSetConfig: pProxyDev=%s cfg=%x\n", pProxyDev->pUsbIns->pszName, iCfg)); /* We need to release kernel ressources first. */ rc = usbProxyFreeBSDFsUnInit(pProxyDev); if (RT_FAILURE(rc)) { LogFlow(("usbProxyFreeBSDSetInterface: Freeing kernel resources " "failed failed rc=%d\n", rc)); return false; } if (iCfg == 0) { /* Unconfigure */ iCfgIndex = 255; } else { /* Get the configuration index matching the value. */ for (iCfgIndex = 0; iCfgIndex < pProxyDev->DevDesc.bNumConfigurations; iCfgIndex++) { if (pProxyDev->paCfgDescs[iCfgIndex].Core.bConfigurationValue == iCfg) break; } if (iCfgIndex == pProxyDev->DevDesc.bNumConfigurations) { LogFlow(("usbProxyFreeBSDSetConfig: configuration " "%d not found\n", iCfg)); return false; } } /* Set the config */ rc = usbProxyFreeBSDDoIoCtl(pProxyDev, USB_SET_CONFIG, &iCfgIndex, true); if (RT_FAILURE(rc)) return false; /* Allocate kernel ressources again. */ rc = usbProxyFreeBSDFsInit(pProxyDev); if (RT_FAILURE(rc)) return false; return true; }
/** * Reset a device. * * @returns VBox status code. * @param pDev The device to reset. */ static DECLCALLBACK(int) usbProxyFreeBSDReset(PUSBPROXYDEV pProxyDev, bool fResetOnFreeBSD) { PUSBPROXYDEVFBSD pDevFBSD = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVFBSD); int iParm; int rc = VINF_SUCCESS; LogFlow(("usbProxyFreeBSDReset: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName)); if (!fResetOnFreeBSD) goto done; /* We need to release kernel ressources first. */ rc = usbProxyFreeBSDFsUnInit(pProxyDev); if (RT_FAILURE(rc)) goto done; /* Resetting is only possible as super-user, ignore any failures: */ iParm = 0; rc = usbProxyFreeBSDDoIoCtl(pProxyDev, USB_DEVICEENUMERATE, &iParm, true); if (RT_FAILURE(rc)) { /* Set the config instead of bus reset */ iParm = 255; rc = usbProxyFreeBSDDoIoCtl(pProxyDev, USB_SET_CONFIG, &iParm, true); if (RT_SUCCESS(rc)) { iParm = 0; rc = usbProxyFreeBSDDoIoCtl(pProxyDev, USB_SET_CONFIG, &iParm, true); } } usleep(10000); /* nice it! */ /* Allocate kernel ressources again. */ rc = usbProxyFreeBSDFsInit(pProxyDev); if (RT_FAILURE(rc)) goto done; /* Retrieve current active configuration. */ rc = usbProxyFreeBSDInit(pProxyDev); done: pProxyDev->cIgnoreSetConfigs = 2; return rc; }
/** * Closes the proxy device. */ static DECLCALLBACK(void) usbProxyFreeBSDClose(PUSBPROXYDEV pProxyDev) { PUSBPROXYDEVFBSD pDevFBSD = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVFBSD); LogFlow(("usbProxyFreeBSDClose: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName)); /* sanity check */ AssertPtrReturnVoid(pDevFBSD); usbProxyFreeBSDFsUnInit(pProxyDev); RTPipeClose(pDevFBSD->hPipeWakeupR); RTPipeClose(pDevFBSD->hPipeWakeupW); RTFileClose(pDevFBSD->hFile); pDevFBSD->hFile = NIL_RTFILE; LogFlow(("usbProxyFreeBSDClose: returns\n")); }
/** * Closes the proxy device. */ static void usbProxyFreeBSDClose(PUSBPROXYDEV pProxyDev) { PUSBPROXYDEVFBSD pDevFBSD = (PUSBPROXYDEVFBSD)pProxyDev->Backend.pv; LogFlow(("usbProxyFreeBSDClose: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName)); /* sanity check */ AssertPtrReturnVoid(pDevFBSD); usbProxyFreeBSDFsUnInit(pProxyDev); RTFileClose(pDevFBSD->hFile); pDevFBSD->hFile = NIL_RTFILE; RTMemFree(pDevFBSD); pProxyDev->Backend.pv = NULL; LogFlow(("usbProxyFreeBSDClose: returns\n")); }