port-qmi: use qmi_device_close_async() in the port open logic

The qmi_device_close() synchronous operation is deprecated.
This commit is contained in:
Aleksander Morgado
2020-01-22 12:30:39 +01:00
parent de8b6dd019
commit bf76fcd526

View File

@@ -195,46 +195,75 @@ typedef enum {
PORT_OPEN_STEP_GET_WDA_DATA_FORMAT, PORT_OPEN_STEP_GET_WDA_DATA_FORMAT,
PORT_OPEN_STEP_CHECK_DATA_FORMAT, PORT_OPEN_STEP_CHECK_DATA_FORMAT,
PORT_OPEN_STEP_SET_KERNEL_DATA_FORMAT, PORT_OPEN_STEP_SET_KERNEL_DATA_FORMAT,
PORT_OPEN_STEP_CLOSE_BEFORE_OPEN_WITH_DATA_FORMAT,
PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT, PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT,
PORT_OPEN_STEP_LAST PORT_OPEN_STEP_LAST
} PortOpenStep; } PortOpenStep;
typedef struct { typedef struct {
QmiDevice *device; QmiDevice *device;
QmiClient *wda; QmiClient *wda;
GError *error; GError *error;
PortOpenStep step; PortOpenStep step;
gboolean set_data_format; gboolean set_data_format;
QmiDeviceExpectedDataFormat kernel_data_format; QmiDeviceExpectedDataFormat kernel_data_format;
QmiWdaLinkLayerProtocol llp; QmiWdaLinkLayerProtocol llp;
} PortOpenContext; } PortOpenContext;
static void static void
port_open_context_free (PortOpenContext *ctx) port_open_context_free (PortOpenContext *ctx)
{ {
if (ctx->wda) { g_assert (!ctx->error);
g_assert (ctx->device); if (ctx->wda && ctx->device)
qmi_device_release_client (ctx->device, qmi_device_release_client (ctx->device,
ctx->wda, ctx->wda,
QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID, QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
3, NULL, NULL, NULL); 3, NULL, NULL, NULL);
g_object_unref (ctx->wda); g_clear_object (&ctx->wda);
} g_clear_object (&ctx->device);
if (ctx->device)
g_object_unref (ctx->device);
g_slice_free (PortOpenContext, ctx); g_slice_free (PortOpenContext, ctx);
} }
gboolean gboolean
mm_port_qmi_open_finish (MMPortQmi *self, mm_port_qmi_open_finish (MMPortQmi *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
return g_task_propagate_boolean (G_TASK (res), error); return g_task_propagate_boolean (G_TASK (res), error);
} }
static void port_open_step (GTask *task); static void port_open_step (GTask *task);
static void
port_open_complete_with_error (GTask *task)
{
MMPortQmi *self;
PortOpenContext *ctx;
self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
g_assert (ctx->error);
self->priv->opening = FALSE;
g_task_return_error (task, g_steal_pointer (&ctx->error));
g_object_unref (task);
}
static void
qmi_device_close_on_error_ready (QmiDevice *qmi_device,
GAsyncResult *res,
GTask *task)
{
GError *error = NULL;
if (!qmi_device_close_finish (qmi_device, res, &error)) {
mm_warn ("Couldn't close QMI device after failed open sequence: %s", error->message);
g_error_free (error);
}
port_open_complete_with_error (task);
}
static void static void
qmi_device_open_second_ready (QmiDevice *qmi_device, qmi_device_open_second_ready (QmiDevice *qmi_device,
GAsyncResult *res, GAsyncResult *res,
@@ -251,6 +280,23 @@ qmi_device_open_second_ready (QmiDevice *qmi_device,
port_open_step (task); port_open_step (task);
} }
static void
qmi_device_close_to_reopen_ready (QmiDevice *qmi_device,
GAsyncResult *res,
GTask *task)
{
PortOpenContext *ctx;
ctx = g_task_get_task_data (task);
if (!qmi_device_close_finish (qmi_device, res, &ctx->error)) {
mm_warn ("Couldn't close QMI device to reopen it");
ctx->step = PORT_OPEN_STEP_LAST;
} else
ctx->step++;
port_open_step (task);
}
static void static void
get_data_format_ready (QmiClientWda *client, get_data_format_ready (QmiClientWda *client,
GAsyncResult *res, GAsyncResult *res,
@@ -265,7 +311,7 @@ get_data_format_ready (QmiClientWda *client,
!qmi_message_wda_get_data_format_output_get_result (output, NULL) || !qmi_message_wda_get_data_format_output_get_result (output, NULL) ||
!qmi_message_wda_get_data_format_output_get_link_layer_protocol (output, &ctx->llp, NULL)) !qmi_message_wda_get_data_format_output_get_link_layer_protocol (output, &ctx->llp, NULL))
/* If loading WDA data format fails, fallback to 802.3 requested via CTL */ /* If loading WDA data format fails, fallback to 802.3 requested via CTL */
ctx->step = PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT; ctx->step = PORT_OPEN_STEP_CLOSE_BEFORE_OPEN_WITH_DATA_FORMAT;
else else
/* Go on to next step */ /* Go on to next step */
ctx->step++; ctx->step++;
@@ -288,7 +334,7 @@ allocate_client_wda_ready (QmiDevice *device,
if (!ctx->wda) { if (!ctx->wda) {
/* If no WDA supported, then we just fallback to reopening explicitly /* If no WDA supported, then we just fallback to reopening explicitly
* requesting 802.3 in the CTL service. */ * requesting 802.3 in the CTL service. */
ctx->step = PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT; ctx->step = PORT_OPEN_STEP_CLOSE_BEFORE_OPEN_WITH_DATA_FORMAT;
port_open_step (task); port_open_step (task);
return; return;
} }
@@ -417,7 +463,7 @@ port_open_step (GTask *task)
ctx->kernel_data_format = qmi_device_get_expected_data_format (ctx->device, NULL); ctx->kernel_data_format = qmi_device_get_expected_data_format (ctx->device, NULL);
/* If data format cannot be retrieved, we fallback to 802.3 via CTL */ /* If data format cannot be retrieved, we fallback to 802.3 via CTL */
if (ctx->kernel_data_format == QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN) { if (ctx->kernel_data_format == QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN) {
ctx->step = PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT; ctx->step = PORT_OPEN_STEP_CLOSE_BEFORE_OPEN_WITH_DATA_FORMAT;
port_open_step (task); port_open_step (task);
return; return;
} }
@@ -494,16 +540,17 @@ port_open_step (GTask *task)
port_open_step (task); port_open_step (task);
return; return;
case PORT_OPEN_STEP_CLOSE_BEFORE_OPEN_WITH_DATA_FORMAT:
mm_dbg ("Closing device to reopen it right away...");
qmi_device_close_async (ctx->device,
5,
g_task_get_cancellable (task),
(GAsyncReadyCallback) qmi_device_close_to_reopen_ready,
task);
return;
case PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT: case PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT:
/* Need to reopen setting 802.3 using CTL */ /* Need to reopen setting 802.3 using CTL */
mm_dbg ("Closing device to reopen it right away...");
if (!qmi_device_close (ctx->device, &ctx->error)) {
mm_warn ("Couldn't close QMI device to reopen it");
ctx->step = PORT_OPEN_STEP_LAST;
port_open_step (task);
return;
}
mm_dbg ("Reopening device with data format..."); mm_dbg ("Reopening device with data format...");
qmi_device_open (ctx->device, qmi_device_open (ctx->device,
(QMI_DEVICE_OPEN_FLAGS_VERSION_INFO | (QMI_DEVICE_OPEN_FLAGS_VERSION_INFO |
@@ -517,24 +564,30 @@ port_open_step (GTask *task)
return; return;
case PORT_OPEN_STEP_LAST: case PORT_OPEN_STEP_LAST:
mm_dbg ("QMI port open operation finished");
/* Reset opening flag */
self->priv->opening = FALSE;
if (ctx->error) { if (ctx->error) {
/* Propagate error */ mm_dbg ("QMI port open operation failed: %s", ctx->error->message);
if (ctx->device)
qmi_device_close (ctx->device, NULL); if (ctx->device) {
g_task_return_error (task, ctx->error); qmi_device_close_async (ctx->device,
ctx->error = NULL; 5,
} else { NULL,
/* Store device in private info */ (GAsyncReadyCallback) qmi_device_close_on_error_ready,
g_assert (ctx->device); task);
g_assert (!self->priv->qmi_device); return;
self->priv->qmi_device = g_object_ref (ctx->device); }
g_task_return_boolean (task, TRUE);
port_open_complete_with_error (task);
return;
} }
mm_dbg ("QMI port open operation finished successfully");
/* Store device in private info */
g_assert (ctx->device);
g_assert (!self->priv->qmi_device);
self->priv->qmi_device = g_steal_pointer (&ctx->device);
self->priv->opening = FALSE;
g_task_return_boolean (task, TRUE);
g_object_unref (task); g_object_unref (task);
return; return;
} }