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_free
fpi_ssm_start fpi_ssm_start
fpi_ssm_start_subsm fpi_ssm_start_subsm
fpi_ssm_set_critical
fpi_ssm_next_state fpi_ssm_next_state
fpi_ssm_next_state_delayed fpi_ssm_next_state_delayed
fpi_ssm_jump_to_state 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; self->old_data.line_ptr += 1;
/* if there is still data, continue from check lineready */ /* if there is still data, continue from check lineready */
if (self->old_data.line_ptr < self->sensor_height) if (self->old_data.line_ptr < self->sensor_height)
{ fpi_ssm_jump_to_state (transfer->ssm, ELANSPI_CAPTOLD_CHECK_LINEREADY);
fpi_ssm_jump_to_state (transfer->ssm, ELANSPI_CAPTOLD_CHECK_LINEREADY);
}
else else
{ fpi_ssm_mark_completed (transfer->ssm);
/* 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 static void
@@ -607,6 +595,7 @@ elanspi_calibrate_old_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBOLD_DACFINE_CAPTURE: case ELANSPI_CALIBOLD_DACFINE_CAPTURE:
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES); chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld); fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld); fpi_ssm_start_subsm (ssm, chld);
return; return;
@@ -862,6 +851,7 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBHV_CAPTURE: case ELANSPI_CALIBHV_CAPTURE:
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES); chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
fpi_ssm_silence_debug (chld); fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld); fpi_ssm_start_subsm (ssm, chld);
return; return;
@@ -1118,6 +1108,7 @@ do_sw_reset:
else else
chld = fpi_ssm_new_full (dev, elanspi_calibrate_old_handler, ELANSPI_CALIBOLD_NSTATES, ELANSPI_CALIBOLD_PROTECT, "old calibrate"); 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_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld); fpi_ssm_start_subsm (ssm, chld);
return; return;
@@ -1127,6 +1118,7 @@ do_sw_reset:
else else
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES); chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld); fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld); fpi_ssm_start_subsm (ssm, chld);
return; return;
@@ -1500,6 +1492,7 @@ elanspi_fp_capture_ssm_handler (FpiSsm *ssm, FpDevice *dev)
else else
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES); chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld); fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld); fpi_ssm_start_subsm (ssm, chld);
return; return;

View File

@@ -81,6 +81,7 @@ struct _FpiSsm
int start_cleanup; int start_cleanup;
int cur_state; int cur_state;
gboolean completed; gboolean completed;
gboolean critical;
gboolean silence; gboolean silence;
GSource *timeout; GSource *timeout;
GError *error; GError *error;
@@ -277,6 +278,10 @@ fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
ssm->cur_state = 0; ssm->cur_state = 0;
ssm->completed = FALSE; ssm->completed = FALSE;
ssm->error = NULL; ssm->error = NULL;
if (ssm->critical)
fpi_device_critical_enter (ssm->dev);
__ssm_call_handler (ssm, TRUE); __ssm_call_handler (ssm, TRUE);
} }
@@ -366,6 +371,10 @@ fpi_ssm_mark_completed (FpiSsm *machine)
machine->callback (machine, machine->dev, error); machine->callback (machine, machine->dev, error);
} }
if (machine->critical)
fpi_device_critical_leave (machine->dev);
fpi_ssm_free (machine); fpi_ssm_free (machine);
} }
@@ -660,6 +669,23 @@ fpi_ssm_silence_debug (FpiSsm *machine)
machine->silence = TRUE; 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: * fpi_ssm_usb_transfer_cb:
* @transfer: a #FpiUsbTransfer * @transfer: a #FpiUsbTransfer

View File

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