+
+ sdi = transfer->user_data;
+ devc = sdi->priv;
+ usb = sdi->conn;
+
+ sr_dbg("receive_transfer(): status %s received %d bytes.",
+ libusb_error_name(transfer->status), transfer->actual_length);
+
+ if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
+ sr_err("USB bulk transfer timeout.");
+ devc->transfer_finished = 1;
+ }
+ send_chunk(sdi, transfer->buffer, transfer->actual_length / TRANSFER_PACKET_LENGTH);
+
+ devc->n_bytes_to_read -= transfer->actual_length;
+ if (devc->n_bytes_to_read) {
+ uint32_t to_read = devc->n_bytes_to_read;
+ /*
+ * Determine read size for the next USB transfer. Make
+ * the buffer size a multiple of the endpoint packet
+ * size. Don't exceed a maximum value.
+ */
+ if (to_read >= LA2016_USB_BUFSZ)
+ to_read = LA2016_USB_BUFSZ;
+ else
+ to_read = (to_read + (LA2016_EP6_PKTSZ-1)) & ~(LA2016_EP6_PKTSZ-1);
+ libusb_fill_bulk_transfer(
+ transfer, usb->devhdl,
+ 0x86, transfer->buffer, to_read,
+ receive_transfer, (void *)sdi, DEFAULT_TIMEOUT_MS);
+
+ if ((ret = libusb_submit_transfer(transfer)) == 0)
+ return;
+ sr_err("Cannot submit another USB transfer: %s.",
+ libusb_error_name(ret));
+ }
+
+ g_free(transfer->buffer);
+ libusb_free_transfer(transfer);
+ devc->transfer_finished = 1;
+}
+
+SR_PRIV int la2016_receive_data(int fd, int revents, void *cb_data)
+{
+ const struct sr_dev_inst *sdi;
+ struct dev_context *devc;
+ struct drv_context *drvc;
+ struct timeval tv;
+
+ (void)fd;
+ (void)revents;
+
+ sdi = cb_data;
+ devc = sdi->priv;
+ drvc = sdi->driver->context;
+
+ if (devc->have_trigger == 0) {
+ if (la2016_has_triggered(sdi) == 0) {
+ /* Not yet ready for sample data download. */
+ return TRUE;
+ }
+ devc->have_trigger = 1;
+ devc->transfer_finished = 0;
+ devc->reading_behind_trigger = 0;
+ devc->total_samples = 0;
+ /* We can start downloading sample data. */
+ if (la2016_start_retrieval(sdi, receive_transfer) != SR_OK) {
+ sr_err("Cannot start acquisition data download.");
+ return FALSE;
+ }
+ sr_dbg("Acquisition data download started.");
+ std_session_send_df_frame_begin(sdi);
+
+ return TRUE;
+ }
+
+ tv.tv_sec = tv.tv_usec = 0;
+ libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);
+
+ if (devc->transfer_finished) {
+ sr_dbg("Download finished, post processing.");
+ std_session_send_df_frame_end(sdi);
+
+ usb_source_remove(sdi->session, drvc->sr_ctx);
+ std_session_send_df_end(sdi);
+
+ la2016_stop_acquisition(sdi);
+
+ g_free(devc->convbuffer);
+ devc->convbuffer = NULL;
+
+ devc->transfer = NULL;
+
+ sr_dbg("Download finished, done post processing.");
+ }
+
+ return TRUE;
+}
+
+SR_PRIV int la2016_init_device(const struct sr_dev_inst *sdi)
+{
+ struct dev_context *devc;