summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2017-01-16 14:30:16 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-01-16 22:16:38 +0100
commit6c1384ad4c21b5e7e2fe7e2651dfd00f13c203dd (patch)
treecaa546cbf0757396d2337c334f8a6e18867c5fc3
parent0fe1d178b3607ab614fab607b7d20aa0a0df6057 (diff)
downloadlibqmi-6c1384ad4c21b5e7e2fe7e2651dfd00f13c203dd.tar.gz
qmi-firmware-update: offline+reset based power cycle as helper
-rw-r--r--src/qmi-firmware-update/qfu-updater.c87
-rw-r--r--src/qmi-firmware-update/qfu-utils.c119
-rw-r--r--src/qmi-firmware-update/qfu-utils.h8
3 files changed, 151 insertions, 63 deletions
diff --git a/src/qmi-firmware-update/qfu-updater.c b/src/qmi-firmware-update/qfu-updater.c
index 7ccd8445..21b45590 100644
--- a/src/qmi-firmware-update/qfu-updater.c
+++ b/src/qmi-firmware-update/qfu-updater.c
@@ -83,8 +83,7 @@ typedef enum {
RUN_CONTEXT_STEP_QMI_CLIENT,
RUN_CONTEXT_STEP_GET_FIRMWARE_PREFERENCE,
RUN_CONTEXT_STEP_SET_FIRMWARE_PREFERENCE,
- RUN_CONTEXT_STEP_OFFLINE,
- RUN_CONTEXT_STEP_RESET,
+ RUN_CONTEXT_STEP_POWER_CYCLE,
RUN_CONTEXT_STEP_CLEANUP_QMI_DEVICE,
RUN_CONTEXT_STEP_WAIT_FOR_TTY,
RUN_CONTEXT_STEP_QDL_DEVICE,
@@ -600,41 +599,32 @@ run_context_step_cleanup_qmi_device (GTask *task)
run_context_step_next (task, ctx->step + 1);
}
+
static void
-reset_or_offline_ready (QmiClientDms *client,
- GAsyncResult *res,
- GTask *task)
+reseter_run_ready (QfuReseter *reseter,
+ GAsyncResult *res,
+ GTask *task)
{
- QmiMessageDmsSetOperatingModeOutput *output;
- GError *error = NULL;
- RunContext *ctx;
+ GError *error = NULL;
+ RunContext *ctx;
ctx = (RunContext *) g_task_get_task_data (task);
- output = qmi_client_dms_set_operating_mode_finish (client, res, &error);
- if (!output) {
- g_prefix_error (&error, "QMI operation failed: couldn't set operating mode: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- if (!qmi_message_dms_set_operating_mode_output_get_result (output, &error)) {
- g_prefix_error (&error, "couldn't set operating mode: ");
+ if (!qfu_reseter_run_finish (reseter, res, &error)) {
+ g_prefix_error (&error, "boothold reseter operation failed: ");
g_task_return_error (task, error);
g_object_unref (task);
- qmi_message_dms_set_operating_mode_output_unref (output);
return;
}
- g_debug ("[qfu-updater] operating mode set successfully...");
+ g_debug ("[qfu-updater] boothold reset requested successfully...");
/* Go on */
run_context_step_next (task, ctx->step + 1);
}
static void
-reseter_run_ready (QfuReseter *reseter,
+power_cycle_ready (QmiClientDms *qmi_client,
GAsyncResult *res,
GTask *task)
{
@@ -643,41 +633,34 @@ reseter_run_ready (QfuReseter *reseter,
ctx = (RunContext *) g_task_get_task_data (task);
- if (!qfu_reseter_run_finish (reseter, res, &error)) {
- g_prefix_error (&error, "boothold reseter operation failed: ");
+ if (!qfu_utils_power_cycle_finish (qmi_client, res, &error)) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
- g_debug ("[qfu-updater] boothold reset requested successfully...");
+ g_debug ("[qfu-updater] reset requested successfully...");
/* Go on */
run_context_step_next (task, ctx->step + 1);
}
static void
-run_context_step_reset (GTask *task)
+run_context_step_power_cycle (GTask *task)
{
- QfuUpdater *self;
- RunContext *ctx;
- QmiMessageDmsSetOperatingModeInput *input;
- QfuReseter *reseter;
+ RunContext *ctx;
+ QfuUpdater *self;
+ QfuReseter *reseter;
ctx = (RunContext *) g_task_get_task_data (task);
self = g_task_get_source_object (task);
+ g_debug ("[qfu-updater] power cycling...");
if (!ctx->boothold_reset) {
- g_debug ("[qfu-updater] setting operating mode 'reset'...");
- input = qmi_message_dms_set_operating_mode_input_new ();
- qmi_message_dms_set_operating_mode_input_set_mode (input, QMI_DMS_OPERATING_MODE_RESET, NULL);
- qmi_client_dms_set_operating_mode (ctx->qmi_client,
- input,
- 10,
- g_task_get_cancellable (task),
- (GAsyncReadyCallback) reset_or_offline_ready,
- task);
- qmi_message_dms_set_operating_mode_input_unref (input);
+ qfu_utils_power_cycle (ctx->qmi_client,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) power_cycle_ready,
+ task);
return;
}
@@ -690,27 +673,6 @@ run_context_step_reset (GTask *task)
g_object_unref (reseter);
}
-
-static void
-run_context_step_offline (GTask *task)
-{
- RunContext *ctx;
- QmiMessageDmsSetOperatingModeInput *input;
-
- ctx = (RunContext *) g_task_get_task_data (task);
-
- g_debug ("[qfu-updater] setting operating mode 'offline'...");
- input = qmi_message_dms_set_operating_mode_input_new ();
- qmi_message_dms_set_operating_mode_input_set_mode (input, QMI_DMS_OPERATING_MODE_OFFLINE, NULL);
- qmi_client_dms_set_operating_mode (ctx->qmi_client,
- input,
- 10,
- g_task_get_cancellable (task),
- (GAsyncReadyCallback) reset_or_offline_ready,
- task);
- qmi_message_dms_set_operating_mode_input_unref (input);
-}
-
static void
set_firmware_preference_ready (QmiClientDms *client,
GAsyncResult *res,
@@ -1011,7 +973,7 @@ run_context_step_get_firmware_preference (GTask *task)
/* Jump to the reset step and run boothold there */
ctx->boothold_reset = TRUE;
- run_context_step_next (task, RUN_CONTEXT_STEP_RESET);
+ run_context_step_next (task, RUN_CONTEXT_STEP_POWER_CYCLE);
return;
}
@@ -1082,8 +1044,7 @@ static const RunContextStepFunc run_context_step_func[] = {
[RUN_CONTEXT_STEP_QMI_CLIENT] = run_context_step_qmi_client,
[RUN_CONTEXT_STEP_GET_FIRMWARE_PREFERENCE] = run_context_step_get_firmware_preference,
[RUN_CONTEXT_STEP_SET_FIRMWARE_PREFERENCE] = run_context_step_set_firmware_preference,
- [RUN_CONTEXT_STEP_OFFLINE] = run_context_step_offline,
- [RUN_CONTEXT_STEP_RESET] = run_context_step_reset,
+ [RUN_CONTEXT_STEP_POWER_CYCLE] = run_context_step_power_cycle,
[RUN_CONTEXT_STEP_CLEANUP_QMI_DEVICE] = run_context_step_cleanup_qmi_device,
[RUN_CONTEXT_STEP_WAIT_FOR_TTY] = run_context_step_wait_for_tty,
[RUN_CONTEXT_STEP_QDL_DEVICE] = run_context_step_qdl_device,
diff --git a/src/qmi-firmware-update/qfu-utils.c b/src/qmi-firmware-update/qfu-utils.c
index de47ee35..14b19b76 100644
--- a/src/qmi-firmware-update/qfu-utils.c
+++ b/src/qmi-firmware-update/qfu-utils.c
@@ -540,3 +540,122 @@ qfu_utils_new_client_dms (GFile *cdc_wdm_file,
(GAsyncReadyCallback) qmi_device_ready,
task);
}
+
+/******************************************************************************/
+
+typedef enum {
+ POWER_CYCLE_STEP_OFFLINE,
+ POWER_CYCLE_STEP_RESET,
+ POWER_CYCLE_STEP_DONE,
+} PowerCycleStep;
+
+typedef struct {
+ QmiClientDms *qmi_client;
+ PowerCycleStep step;
+} PowerCycleContext;
+
+static void
+power_cycle_context_free (PowerCycleContext *ctx)
+{
+ g_object_unref (ctx->qmi_client);
+ g_slice_free (PowerCycleContext, ctx);
+}
+
+gboolean
+qfu_utils_power_cycle_finish (QmiClientDms *qmi_client,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void power_cycle_step (GTask *task);
+
+static void
+power_cycle_step_ready (QmiClientDms *qmi_client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ QmiMessageDmsSetOperatingModeOutput *output;
+ GError *error = NULL;
+ PowerCycleContext *ctx;
+
+ ctx = (PowerCycleContext *) g_task_get_task_data (task);
+
+ output = qmi_client_dms_set_operating_mode_finish (qmi_client, res, &error);
+ if (!output) {
+ g_prefix_error (&error, "QMI operation failed: couldn't set operating mode: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (!qmi_message_dms_set_operating_mode_output_get_result (output, &error)) {
+ g_prefix_error (&error, "couldn't set operating mode: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ qmi_message_dms_set_operating_mode_output_unref (output);
+ return;
+ }
+
+ g_debug ("[qfu,utils] operating mode set successfully...");
+
+ /* Go on */
+ ctx->step++;
+ power_cycle_step (task);
+}
+
+static void
+power_cycle_step (GTask *task)
+{
+ QmiMessageDmsSetOperatingModeInput *input;
+ QmiDmsOperatingMode mode;
+ PowerCycleContext *ctx;
+
+ ctx = (PowerCycleContext *) g_task_get_task_data (task);
+
+ switch (ctx->step) {
+ case POWER_CYCLE_STEP_OFFLINE:
+ mode = QMI_DMS_OPERATING_MODE_OFFLINE;
+ break;
+ case POWER_CYCLE_STEP_RESET:
+ mode = QMI_DMS_OPERATING_MODE_RESET;
+ break;
+ case POWER_CYCLE_STEP_DONE:
+ /* Finished! */
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ default:
+ g_assert_not_reached ();
+ }
+
+ input = qmi_message_dms_set_operating_mode_input_new ();
+ qmi_message_dms_set_operating_mode_input_set_mode (input, mode, NULL);
+ qmi_client_dms_set_operating_mode (ctx->qmi_client,
+ input,
+ 10,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) power_cycle_step_ready,
+ task);
+ qmi_message_dms_set_operating_mode_input_unref (input);
+}
+
+void
+qfu_utils_power_cycle (QmiClientDms *qmi_client,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ PowerCycleContext *ctx;
+
+ ctx = g_slice_new0 (PowerCycleContext);
+ ctx->step = POWER_CYCLE_STEP_OFFLINE;
+ ctx->qmi_client = g_object_ref (qmi_client);
+
+ task = g_task_new (NULL, cancellable, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify) power_cycle_context_free);
+
+ power_cycle_step (task);
+}
diff --git a/src/qmi-firmware-update/qfu-utils.h b/src/qmi-firmware-update/qfu-utils.h
index 95e7c2f3..45dbb391 100644
--- a/src/qmi-firmware-update/qfu-utils.h
+++ b/src/qmi-firmware-update/qfu-utils.h
@@ -59,6 +59,14 @@ gboolean qfu_utils_new_client_dms_finish (GAsyncResult *res,
gboolean *supports_firmware_preference_management,
GError **error);
+void qfu_utils_power_cycle (QmiClientDms *qmi_client,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean qfu_utils_power_cycle_finish (QmiClientDms *qmi_client,
+ GAsyncResult *res,
+ GError **error);
+
G_END_DECLS
#endif /* QFU_UTILS_H */