From dd9e9d9bb46758670737a808c06da9f31a435ad6 Mon Sep 17 00:00:00 2001 From: Howard Su Date: Tue, 9 Jul 2024 06:20:16 -0700 Subject: [PATCH] Fix USB Crash developed by Franco VENTURI --- Core/arch/linux/FX3handler.cpp | 5 ++--- Core/arch/linux/streaming.c | 27 +++++++++++++-------------- Core/config.h | 5 +++-- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Core/arch/linux/FX3handler.cpp b/Core/arch/linux/FX3handler.cpp index b609acad..8870484d 100644 --- a/Core/arch/linux/FX3handler.cpp +++ b/Core/arch/linux/FX3handler.cpp @@ -78,8 +78,7 @@ bool fx3handler::GetHardwareInfo(uint32_t *data) void fx3handler::StartStream(ringbuffer &input, int numofblock) { inputbuffer = &input; - auto readsize = 32 * 1024; // input.getWriteCount() * sizeof(uint16_t); - stream = streaming_open_async(this->dev, readsize, 0, PacketRead, this); + stream = streaming_open_async(this->dev, transferSize, concurrentTransfers, PacketRead, this); input.setBlockSize(streaming_framesize(stream) / sizeof(int16_t)); DbgPrintf("StartStream blocksize=%d\n", input.getBlockSize()); @@ -142,4 +141,4 @@ bool fx3handler::Enumerate(unsigned char &idx, char *lbuf) devidx = idx; return true; -} +} \ No newline at end of file diff --git a/Core/arch/linux/streaming.c b/Core/arch/linux/streaming.c index 483dda57..7caba16b 100644 --- a/Core/arch/linux/streaming.c +++ b/Core/arch/linux/streaming.c @@ -71,8 +71,6 @@ typedef struct streaming { static const uint32_t DEFAULT_SAMPLE_RATE = 64000000; /* 64Msps */ -static const uint32_t DEFAULT_FRAME_SIZE = (2 * 64000000 / 1000); /* ~ 1 ms */ -static const uint32_t DEFAULT_NUM_FRAMES = 96; /* we should not exceed 120 ms in total! */ const unsigned int BULK_XFER_TIMEOUT = 5000; // timeout (in ms) for each bulk transfer @@ -121,17 +119,14 @@ streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, return ret_val; } - /* frame size must be a multiple of max_packet_size * max_burst */ + /* frame size must be a multiple of max_packet_size * (max_burst + 1) */ uint32_t max_xfer_size = usb_device->bulk_in_max_packet_size * - usb_device->bulk_in_max_burst; + (usb_device->bulk_in_max_burst + 1); if ( !max_xfer_size ) { fprintf(stderr, "ERROR: maximum transfer size is 0. probably not connected at USB 3 port?!\n"); return ret_val; } - num_frames = num_frames > 0 ? num_frames : DEFAULT_NUM_FRAMES; - frame_size = frame_size > 0 ? frame_size : DEFAULT_FRAME_SIZE; - frame_size = max_xfer_size * ((frame_size +max_xfer_size -1) / max_xfer_size); // round up int iso_packets_per_frame = frame_size / usb_device->bulk_in_max_packet_size; fprintf(stderr, "frame_size = %u, iso_packets_per_frame = %d\n", (unsigned)frame_size, iso_packets_per_frame); @@ -159,8 +154,8 @@ streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, this->random = 0; this->usb_device = usb_device; this->sample_rate = DEFAULT_SAMPLE_RATE; - this->frame_size = frame_size > 0 ? frame_size : DEFAULT_FRAME_SIZE; - this->num_frames = num_frames > 0 ? num_frames : DEFAULT_NUM_FRAMES; + this->frame_size = frame_size; + this->num_frames = num_frames; this->callback = callback; this->callback_context = callback_context; this->frames = frames; @@ -273,10 +268,13 @@ int streaming_stop(streaming_t *this) /* flush all the events */ struct timeval noblock = { 0, 0 }; - int ret = libusb_handle_events_timeout_completed(this->usb_device->context, &noblock, 0); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - this->status = STREAMING_STATUS_FAILED; + while (this->active_transfers > 0) { + int ret = libusb_handle_events_timeout_completed(this->usb_device->context, &noblock, 0); + if (ret < 0) { + log_usb_error(ret, __func__, __FILE__, __LINE__); + this->status = STREAMING_STATUS_FAILED; + } + usleep(100); } return 0; @@ -364,6 +362,7 @@ static void LIBUSB_CALL streaming_read_async_callback(struct libusb_transfer *tr break; case LIBUSB_TRANSFER_CANCELLED: /* librtlsdr does also ignore LIBUSB_TRANSFER_CANCELLED */ + atomic_fetch_sub(&this->active_transfers, 1); return; case LIBUSB_TRANSFER_ERROR: case LIBUSB_TRANSFER_TIMED_OUT: @@ -388,4 +387,4 @@ static void LIBUSB_CALL streaming_read_async_callback(struct libusb_transfer *tr } } return; -} +} \ No newline at end of file diff --git a/Core/config.h b/Core/config.h index 7c29f576..6692b9d9 100644 --- a/Core/config.h +++ b/Core/config.h @@ -76,8 +76,10 @@ enum rf_mode { NOMODE = 0, HFMODE = 0x1, VHFMODE = 0x2 }; extern bool saveADCsamplesflag; extern uint32_t adcnominalfreq; +// transferSize must be a multiple of 16 (maxBurst) * 1024 (SS packet size) = 16384 const uint32_t transferSize = 131072; -const uint32_t transferSamples = 131072 / sizeof(int16_t); +const uint32_t transferSamples = transferSize / sizeof(int16_t); +const uint32_t concurrentTransfers = 16; // used to be 96, but I think it is too high const uint32_t DEFAULT_ADC_FREQ = 64000000; // ADC sampling frequency @@ -87,4 +89,3 @@ extern uint32_t MIN_ADC_FREQ; // ADC sampling frequency minimum extern uint32_t MAX_ADC_FREQ; // ADC sampling frequency minimum extern uint32_t N2_BANDSWITCH; // threshold 5 or 6 SR bandwidths #endif // _CONFIG_H_ -