Compare commits

...

2 Commits

Author SHA1 Message Date
Benjamin Berg
664126b431 elanspi: Do not allow image captures to be interrupted
Avoid unexpected state changes during image capture. This also means
that the old line handler does not need to check for cancellation.
2021-12-27 12:19:10 +01:00
Benjamin Berg
7b1fe6ec19 ssm: Allow marking an SSM as being critical
This way the SSM cannot be interrupted while it is running.
2021-12-27 12:13:12 +01:00
4 changed files with 35 additions and 14 deletions

View File

@@ -247,6 +247,7 @@ fpi_ssm_new_full
fpi_ssm_free
fpi_ssm_start
fpi_ssm_start_subsm
fpi_ssm_set_critical
fpi_ssm_next_state
fpi_ssm_next_state_delayed
fpi_ssm_jump_to_state

View File

@@ -434,21 +434,9 @@ elanspi_capture_old_line_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpoin
self->old_data.line_ptr += 1;
/* if there is still data, continue from check lineready */
if (self->old_data.line_ptr < self->sensor_height)
{
fpi_ssm_jump_to_state (transfer->ssm, ELANSPI_CAPTOLD_CHECK_LINEREADY);
}
else
{
/* check for cancellation */
if (fpi_device_action_is_cancelled (dev))
{
g_cancellable_set_error_if_cancelled (fpi_device_get_cancellable (dev), &error);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* otherwise finish succesfully */
fpi_ssm_mark_completed (transfer->ssm);
}
}
static void
@@ -607,6 +595,7 @@ elanspi_calibrate_old_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBOLD_DACFINE_CAPTURE:
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -862,6 +851,7 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBHV_CAPTURE:
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -1118,6 +1108,7 @@ do_sw_reset:
else
chld = fpi_ssm_new_full (dev, elanspi_calibrate_old_handler, ELANSPI_CALIBOLD_NSTATES, ELANSPI_CALIBOLD_PROTECT, "old calibrate");
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -1127,6 +1118,7 @@ do_sw_reset:
else
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -1500,6 +1492,7 @@ elanspi_fp_capture_ssm_handler (FpiSsm *ssm, FpDevice *dev)
else
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;

View File

@@ -81,6 +81,7 @@ struct _FpiSsm
int start_cleanup;
int cur_state;
gboolean completed;
gboolean critical;
gboolean silence;
GSource *timeout;
GError *error;
@@ -277,6 +278,10 @@ fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
ssm->cur_state = 0;
ssm->completed = FALSE;
ssm->error = NULL;
if (ssm->critical)
fpi_device_critical_enter (ssm->dev);
__ssm_call_handler (ssm, TRUE);
}
@@ -366,6 +371,10 @@ fpi_ssm_mark_completed (FpiSsm *machine)
machine->callback (machine, machine->dev, error);
}
if (machine->critical)
fpi_device_critical_leave (machine->dev);
fpi_ssm_free (machine);
}
@@ -660,6 +669,23 @@ fpi_ssm_silence_debug (FpiSsm *machine)
machine->silence = TRUE;
}
/**
* fpi_ssm_set_critical:
* @machine: an #FpiSsm state machine
*
* Sets up the SSM to hold a critical section in the driver code. See
* fpi_device_critical_enter() for more details. This is useful if the SSM must
* not be interrupted in order to keep the device in a good state. You can e.g.
* guarantee that an image transfer is completed.
*
* This function must be called before starting the SSM.
*/
void
fpi_ssm_set_critical (FpiSsm *machine)
{
machine->critical = TRUE;
}
/**
* fpi_ssm_usb_transfer_cb:
* @transfer: a #FpiUsbTransfer

View File

@@ -97,6 +97,7 @@ GError * fpi_ssm_dup_error (FpiSsm *machine);
int fpi_ssm_get_cur_state (FpiSsm *machine);
void fpi_ssm_silence_debug (FpiSsm *machine);
void fpi_ssm_set_critical (FpiSsm *machine);
/* Callbacks to be used by the driver instead of implementing their own
* logic.