Пример #1
0
static int lusb_open(void **driver,
                     struct bladerf_devinfo *info_in,
                     struct bladerf_devinfo *info_out)
{
    int status;
    struct bladerf_lusb *lusb = NULL;
    libusb_context *context;

    /* Initialize libusb for device tree walking */
    status = libusb_init(&context);
    if (status) {
        log_error("Could not initialize libusb: %s\n",
                  libusb_error_name(status));
        return error_conv(status);
    }

    /* We can only print this out when log output is enabled, or else we'll
     * get snagged by -Werror=unused-but-set-variable */
#   ifdef LOGGING_ENABLED
    {
        char buf[64];
        get_libusb_version(buf, sizeof(buf));
        log_verbose("Using libusb version: %s\n", buf);
    }
#   endif

    status = find_and_open_device(context, info_in, &lusb, info_out);
    if (status != 0) {
        libusb_exit(context);

        if (status == BLADERF_ERR_NODEV) {
            log_debug("No devices available on the libusb backend.\n");
        } else {
            log_debug("Failed to open bladeRF on libusb backend: %s\n",
                    bladerf_strerror(status));
        }
    } else {
        assert(lusb != NULL);

        /* Cosmin and Marian from Null Team (null.ro) and YateBTS(.com) found
         * that it is possible to recover from "Issue #95: Not enough bandwidth
         * for altsetting" by performing a USB port reset prior to actually
         * trying to use the device.
         */
#       if ENABLE_USB_DEV_RESET_ON_OPEN
        if (bladerf_usb_reset_device_on_open) {
            status = reset_and_reopen(context, &lusb, info_out);
        }
#       endif

        if (status == 0) {
            *driver = (void *) lusb;
        }
    }

    return status;
}
Пример #2
0
static int reset_and_reopen(libusb_context *context,
                            struct bladerf_lusb **dev,
                            struct bladerf_devinfo *info)
{
    int status;

    status = libusb_reset_device((*dev)->handle);
    if (status == 0) {
        log_verbose("USB port reset succeeded for bladeRF %s\n", info->serial);
        return 0;
    } else if (status == LIBUSB_ERROR_NO_DEVICE) {
        struct bladerf_devinfo new_info;

        /* The reset has caused the device to drop out and re-enumerate.
         *
         * We'll find it again via the info we gathered about it via its
         * serial number, which is now stored in the devinfo
         */
        log_verbose("Re-scan required after port reset for bladeRF %s\n",
                    info->serial);


        libusb_release_interface((*dev)->handle, 0);
        libusb_close((*dev)->handle);
#if 1 == BLADERF_OS_WINDOWS
        ReleaseMutex((*dev)->mutex);
#endif // BLADERF_OS_WINDOWS

        *dev = NULL;

        memcpy(&new_info, info, sizeof(new_info));
        new_info.usb_bus  = DEVINFO_BUS_ANY;
        new_info.usb_addr = DEVINFO_ADDR_ANY;

        status = find_and_open_device(context, &new_info, dev, info);

    } else {
        status = BLADERF_ERR_IO;
        log_verbose("Port reset failed for bladerf %s: %s\n",
                    info->serial, libusb_error_name(status));
    }

    return status;
}