aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2017-01-16 14:33:09 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-01-16 22:16:38 +0100
commit0c9688c28e7341e6f15f58398b1246a0491907b5 (patch)
tree5a94c8425e78da54dd574c4947472b3ad5225b88 /src
parent6c1384ad4c21b5e7e2fe7e2651dfd00f13c203dd (diff)
downloadexternal_libqmi-0c9688c28e7341e6f15f58398b1246a0491907b5.zip
external_libqmi-0c9688c28e7341e6f15f58398b1246a0491907b5.tar.gz
external_libqmi-0c9688c28e7341e6f15f58398b1246a0491907b5.tar.bz2
qmi-firmware-update: try to use DMS 0x0050 for boot and hold as well
This is what more generic Qualcomm software (E.g. Novatel E396) does to get into QDL download mode.
Diffstat (limited to 'src')
-rw-r--r--src/qmi-firmware-update/qfu-reseter.c93
1 files changed, 88 insertions, 5 deletions
diff --git a/src/qmi-firmware-update/qfu-reseter.c b/src/qmi-firmware-update/qfu-reseter.c
index fedd85e..769ab8e 100644
--- a/src/qmi-firmware-update/qfu-reseter.c
+++ b/src/qmi-firmware-update/qfu-reseter.c
@@ -188,6 +188,87 @@ run_context_step_at (GTask *task)
}
static void
+power_cycle_ready (QmiClientDms *qmi_client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ RunContext *ctx;
+
+ ctx = (RunContext *) g_task_get_task_data (task);
+
+ if (!qfu_utils_power_cycle_finish (qmi_client, res, &error)) {
+ g_debug ("[qfu-reseter] error: couldn't power cycle: %s", error->message);
+ g_error_free (error);
+ g_debug ("[qfu-reseter] skipping QMI-based boothold");
+ run_context_step_at (task);
+ return;
+ }
+
+ g_debug ("[qfu-reseter] reset requested successfully...");
+
+ ctx->ignore_release_cid = TRUE;
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+set_boot_image_download_mode_ready (QmiClientDms *client,
+ GAsyncResult *res,
+ GTask *task)
+{
+ QmiMessageDmsSetBootImageDownloadModeOutput *output;
+ GError *error = NULL;
+ RunContext *ctx;
+
+ ctx = (RunContext *) g_task_get_task_data (task);
+
+ output = qmi_client_dms_set_boot_image_download_mode_finish (client, res, &error);
+ if (!output || !qmi_message_dms_set_boot_image_download_mode_output_get_result (output, &error)) {
+ g_debug ("[qfu-reseter] error: couldn't run 'set boot image download mode' operation: %s", error->message);
+ g_error_free (error);
+ if (output)
+ qmi_message_dms_set_boot_image_download_mode_output_unref (output);
+ g_debug ("[qfu-reseter] skipping QMI-based boothold");
+ run_context_step_at (task);
+ return;
+ }
+
+ qmi_message_dms_set_boot_image_download_mode_output_unref (output);
+
+ g_debug ("[qfu-reseter] successfully run 'set boot image download mode' operation");
+
+ qfu_utils_power_cycle (ctx->qmi_client,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) power_cycle_ready,
+ task);
+}
+
+static void
+run_context_step_qmi_boot_image_download_mode (GTask *task)
+{
+ RunContext *ctx;
+ QfuReseter *self;
+ QmiMessageDmsSetBootImageDownloadModeInput *input;
+
+ ctx = (RunContext *) g_task_get_task_data (task);
+ self = g_task_get_source_object (task);
+
+ g_assert (ctx->qmi_client || self->priv->qmi_client);
+
+ /* Try DMS 0x0050 */
+ input = qmi_message_dms_set_boot_image_download_mode_input_new ();
+ qmi_message_dms_set_boot_image_download_mode_input_set_mode (input, QMI_DMS_BOOT_IMAGE_DOWNLOAD_MODE_BOOT_AND_RECOVERY, NULL);
+ qmi_client_dms_set_boot_image_download_mode (self->priv->qmi_client ? self->priv->qmi_client : ctx->qmi_client,
+ input,
+ 10,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) set_boot_image_download_mode_ready,
+ task);
+ qmi_message_dms_set_boot_image_download_mode_input_unref (input);
+}
+
+static void
set_firmware_id_ready (QmiClientDms *client,
GAsyncResult *res,
GTask *task)
@@ -204,11 +285,13 @@ set_firmware_id_ready (QmiClientDms *client,
g_error_free (error);
if (output)
qmi_message_dms_set_firmware_id_output_unref (output);
- g_debug ("[qfu-reseter] skipping QMI-based boothold");
- run_context_step_at (task);
+ g_debug ("[qfu-reseter] trying boot image download mode...");
+ run_context_step_qmi_boot_image_download_mode (task);
return;
}
+ qmi_message_dms_set_firmware_id_output_unref (output);
+
g_debug ("[qfu-reseter] successfully run 'set firmware id' operation");
ctx->ignore_release_cid = TRUE;
g_task_return_boolean (task, TRUE);
@@ -216,7 +299,7 @@ set_firmware_id_ready (QmiClientDms *client,
}
static void
-run_context_step_qmi (GTask *task)
+run_context_step_qmi_firmware_id (GTask *task)
{
RunContext *ctx;
QfuReseter *self;
@@ -258,7 +341,7 @@ new_client_dms_ready (gpointer unused,
return;
}
- run_context_step_qmi (task);
+ run_context_step_qmi_firmware_id (task);
}
void
@@ -296,7 +379,7 @@ qfu_reseter_run (QfuReseter *self,
/* If we already got a QMI client as input, try QMI directly */
if (self->priv->qmi_client) {
- run_context_step_qmi (task);
+ run_context_step_qmi_firmware_id (task);
return;
}