aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Schrock <steve.schrock@getcruise.com>2024-02-29 09:31:41 -0600
committerDenis Kenzior <denkenz@gmail.com>2024-02-29 10:27:28 -0600
commit03160ab1fc34af98964ac62a25f68d6f43e59acd (patch)
tree83efbcc4d2330e14cbe2639f3e54dec43bcb5ed9
parenta6b18b9e922be3e97bebebd370b58cdd5df253ce (diff)
downloadofono-03160ab1fc34af98964ac62a25f68d6f43e59acd.tar.gz
qmi: Enable basic client creation if it is not subclassed
QRTR does not require client ID allocation requests.
-rw-r--r--drivers/qmimodem/qmi.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 82e99ed22..23a5fee71 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -1387,6 +1387,25 @@ static uint8_t __ctl_request_submit(struct qmi_device_qmux *qmux,
return req->tid;
}
+static struct qmi_service *service_create(struct qmi_device *device,
+ const struct qmi_service_info *info, uint8_t client_id)
+{
+ struct qmi_service *service = l_new(struct qmi_service, 1);
+
+ service->ref_count = 1;
+ service->device = device;
+ service->client_id = client_id;
+ service->notify_list = l_queue_new();
+
+ memcpy(&service->info, info, sizeof(service->info));
+
+ __debug_device(device, "service created [client=%d,type=%d]",
+ service->client_id,
+ service->info.service_type);
+
+ return service;
+}
+
static void service_create_shared_reply(struct l_idle *idle, void *user_data)
{
struct service_create_shared_data *data = user_data;
@@ -1663,6 +1682,7 @@ static void qmux_client_create_callback(uint16_t message, uint16_t length,
struct qmi_device *device = data->device;
struct qmi_service *service = NULL;
struct qmi_service *old_service = NULL;
+ struct qmi_service_info info;
const struct qmi_result_code *result_code;
const struct qmi_client_id *client_id;
uint16_t len;
@@ -1685,21 +1705,12 @@ static void qmux_client_create_callback(uint16_t message, uint16_t length,
if (client_id->service != data->type)
goto done;
- service = l_new(struct qmi_service, 1);
-
- service->ref_count = 1;
- service->device = data->device;
-
- service->info.service_type = data->type;
- service->info.major = data->major;
- service->info.minor = data->minor;
+ memset(&info, 0, sizeof(service->info));
+ info.service_type = data->type;
+ info.major = data->major;
+ info.minor = data->minor;
- service->client_id = client_id->client;
- service->notify_list = l_queue_new();
-
- __debug_device(device, "service created [client=%d,type=%d]",
- service->client_id,
- service->info.service_type);
+ service = service_create(device, &info, client_id->client);
hash_id = service_list_create_hash(service->info.service_type,
service->client_id);
@@ -2442,6 +2453,45 @@ bool qmi_service_create_shared(struct qmi_device *device, uint16_t type,
if (type == QMI_SERVICE_CONTROL)
return false;
+ if (!device->ops->client_create) {
+ struct service_create_shared_data *data;
+
+ /*
+ * The hash id is simply the service type in this case. There
+ * is no "pending" state for discovery and no client id.
+ */
+ service = l_hashmap_lookup(device->service_list,
+ L_UINT_TO_PTR(type_val));
+ if (!service) {
+ const struct qmi_service_info *info;
+
+ info = __find_service_info_by_type(device, type);
+ if (!info)
+ return false;
+
+ service = service_create(device, info, 0);
+ l_hashmap_insert(device->service_list,
+ L_UINT_TO_PTR(type_val), service);
+ }
+
+ data = l_new(struct service_create_shared_data, 1);
+
+ data->super.destroy = service_create_shared_data_free;
+ data->device = device;
+ data->func = func;
+ data->user_data = user_data;
+ data->destroy = destroy;
+
+ data->service = qmi_service_ref(service);
+ data->idle = l_idle_create(service_create_shared_reply,
+ data, NULL);
+
+ /* Not really discovery... just tracking the idle callback. */
+ __qmi_device_discovery_started(device, &data->super);
+
+ return true;
+ }
+
shared = l_hashmap_lookup(device->service_list,
L_UINT_TO_PTR(type_val | 0x80000000));
@@ -2485,9 +2535,6 @@ bool qmi_service_create_shared(struct qmi_device *device, uint16_t type,
return true;
}
- if (!device->ops->client_create)
- return -ENOTSUP;
-
r = device->ops->client_create(device, type, func, user_data, destroy);
return r == 0;
}