After acquisition start, DSLogic stores samples in memory, and when done it
sends a USB packet with the trigger position.
This initial fillup can take some time. If the user requests a session stop
in between, the USB transfer is cancelled and the session hangs because it
is not closed properly.
This commit manages this case and closes the session properly when
acquisition is stopped by the user.
Signed-off-by: Diego F. Asanza <redacted>
static void LIBUSB_CALL dslogic_trigger_receive(struct libusb_transfer *transfer)
{
const struct sr_dev_inst *sdi;
static void LIBUSB_CALL dslogic_trigger_receive(struct libusb_transfer *transfer)
{
const struct sr_dev_inst *sdi;
+ struct sr_datafeed_packet packet;
struct dslogic_trigger_pos *tpos;
struct dslogic_trigger_pos *tpos;
+ struct dev_context *devc;
sdi = transfer->user_data;
sdi = transfer->user_data;
-
- if (transfer->status == LIBUSB_TRANSFER_COMPLETED
+ devc = sdi->priv;
+ if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
+ sr_dbg("Trigger transfer canceled.");
+ /* Terminate session. */
+ packet.type = SR_DF_END;
+ sr_session_send(sdi, &packet);
+ usb_source_remove(sdi->session, devc->ctx);
+ devc->num_transfers = 0;
+ g_free(devc->transfers);
+ if (devc->stl) {
+ soft_trigger_logic_free(devc->stl);
+ devc->stl = NULL;
+ }
+ } else if (transfer->status == LIBUSB_TRANSFER_COMPLETED
&& transfer->actual_length == sizeof(struct dslogic_trigger_pos)) {
tpos = (struct dslogic_trigger_pos *)transfer->buffer;
sr_dbg("tpos real_pos %.8x ram_saddr %.8x", tpos->real_pos, tpos->ram_saddr);
&& transfer->actual_length == sizeof(struct dslogic_trigger_pos)) {
tpos = (struct dslogic_trigger_pos *)transfer->buffer;
sr_dbg("tpos real_pos %.8x ram_saddr %.8x", tpos->real_pos, tpos->ram_saddr);
struct sr_usb_dev_inst *usb;
struct libusb_transfer *transfer;
struct dslogic_trigger_pos *tpos;
struct sr_usb_dev_inst *usb;
struct libusb_transfer *transfer;
struct dslogic_trigger_pos *tpos;
+ struct dev_context *devc;
int ret;
usb = sdi->conn;
int ret;
usb = sdi->conn;
if ((ret = dslogic_stop_acquisition(sdi)) != SR_OK)
return ret;
if ((ret = dslogic_stop_acquisition(sdi)) != SR_OK)
return ret;
+ devc->transfers = g_try_malloc0(sizeof(*devc->transfers));
+ if (!devc->transfers) {
+ sr_err("USB trigger_pos transfer malloc failed.");
+ return SR_ERR_MALLOC;
+ }
+ devc->num_transfers = 1;
+ devc->submitted_transfers++;
+ devc->transfers[0] = transfer;
+
+ dslogic_stop_acquisition(sdi);
fx2lafw_abort_acquisition(sdi->priv);
return SR_OK;
fx2lafw_abort_acquisition(sdi->priv);
return SR_OK;