/**
 * Uninit USB subsystem.
 */
static int usbProxyFreeBSDFsUnInit(PUSBPROXYDEV pProxyDev)
{
    struct usb_fs_uninit UsbFsUninit;
    PUSBPROXYDEVFBSD pDevFBSD = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVFBSD);
    int rc;

    LogFlow(("usbProxyFreeBSDFsUnInit: ProxyDev=%p\n", (void *)pProxyDev));

    /* Sanity check */
    AssertPtrReturn(pDevFBSD, VERR_INVALID_PARAMETER);

    if (pDevFBSD->fInit != true)
        return VINF_SUCCESS;

    /* Close any open endpoints. */
    for (unsigned n = 0; n != USBFBSD_MAXENDPOINTS; n++)
        usbProxyFreeBSDEndpointClose(pProxyDev, n);

    /* Zero default */
    memset(&UsbFsUninit, 0, sizeof(UsbFsUninit));

    /* Uninit USB subsystem */
    rc = usbProxyFreeBSDDoIoCtl(pProxyDev, USB_FS_UNINIT, &UsbFsUninit, false);
    if (RT_SUCCESS(rc))
        pDevFBSD->fInit = false;

    return rc;
}
/**
 * Cancels the URB.
 * The URB requires reaping, so we don't change its state.
 */
static DECLCALLBACK(int) usbProxyFreeBSDUrbCancel(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
{
    int index;

    index = (int)(long)pUrb->Dev.pvPrivate - 1;

    if (index < 0 || index >= USBFBSD_MAXENDPOINTS)
        return VINF_SUCCESS; /* invalid index, pretend success. */

    LogFlow(("usbProxyFreeBSDUrbCancel: epindex=%u\n", (unsigned)index));
    return usbProxyFreeBSDEndpointClose(pProxyDev, index);
}
/**
 * Cancels the URB.
 * The URB requires reaping, so we don't change its state.
 */
static void usbProxyFreeBSDUrbCancel(PVUSBURB pUrb)
{
    PUSBPROXYDEV pProxyDev = PDMINS_2_DATA(pUrb->pUsbIns, PUSBPROXYDEV);
    int index;

    index = (int)(long)pUrb->Dev.pvPrivate - 1;

    if (index < 0 || index >= USBFBSD_MAXENDPOINTS)
        return;

    LogFlow(("usbProxyFreeBSDUrbCancel: epindex=%u\n", (unsigned)index));

    usbProxyFreeBSDEndpointClose(pProxyDev, index);
}