From f1803fe10f5017e5bf3528d69229d37472a024c8 Mon Sep 17 00:00:00 2001 From: Steve Markgraf Date: Sun, 17 Feb 2013 16:43:29 +0100 Subject: [PATCH] lib: special handling of dongle disconnect for OS != win32 libusb reacts differently to a device loss during runtime, and sporadic errors can happen when starting a second instance interfacing another dongle, thus we need to wait for all transfers to fail before assuming the dongle has been removed. Signed-off-by: Steve Markgraf --- src/librtlsdr.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index b0185d2..8badd23 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -90,6 +90,7 @@ struct rtlsdr_dev { int gain; /* tenth dB */ struct e4k_state e4k_s; int dev_lost; + unsigned int xfer_errors; }; void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val); @@ -1507,11 +1508,22 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer) dev->cb(xfer->buffer, xfer->actual_length, dev->cb_ctx); libusb_submit_transfer(xfer); /* resubmit transfer */ - } else if (LIBUSB_TRANSFER_CANCELLED != xfer->status && - LIBUSB_TRANSFER_COMPLETED != xfer->status) { - dev->dev_lost = 1; - rtlsdr_cancel_async(dev); - fprintf(stderr, "cb transfer status: %d, canceling...\n", xfer->status); + dev->xfer_errors = 0; + } else if (LIBUSB_TRANSFER_CANCELLED != xfer->status) { +#ifndef _WIN32 + if (LIBUSB_TRANSFER_ERROR == xfer->status) + dev->xfer_errors++; + + if (dev->xfer_errors >= dev->xfer_buf_num || + LIBUSB_TRANSFER_NO_DEVICE == xfer->status) { +#endif + dev->dev_lost = 1; + rtlsdr_cancel_async(dev); + fprintf(stderr, "cb transfer status: %d, " + "canceling...\n", xfer->status); +#ifndef _WIN32 + } +#endif } }