diff mbox series

[v2,30/33] qmi: combine qmux_client_create_data into qmi_request

Message ID 20240618200231.1129282-30-denkenz@gmail.com (mailing list archive)
State Superseded
Headers show
Series [v2,01/33] qmi: Remove qmi_free() | expand

Commit Message

Denis Kenzior June 18, 2024, 8:02 p.m. UTC
Similarly to the previous commit, do not allocate a separate data
structure to hold client creation details, and instead allocate it as
a qmi_request specialization.  Since the lifetime of struct
qmux_client_create_data was already tied to the lifetime of the request
(and vice-versa), this change allows the extra allocation to be
optimized away.

While here, remove all vestiges of discovery and discovery_queue.  This
functionality is no longer needed since any data associated with the
request will be freed when struct qmi_request is freed.
---
 drivers/qmimodem/qmi.c | 153 ++++++++++++++---------------------------
 1 file changed, 51 insertions(+), 102 deletions(-)
diff mbox series

Patch

diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 3742e8fc4b73..e3a8b225140f 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -42,10 +42,6 @@  struct qmi_request;
 typedef void (*response_func_t)(struct qmi_request *, uint16_t message,
 				uint16_t length, const void *buffer);
 
-struct discovery {
-	qmi_destroy_func_t destroy;
-};
-
 struct qmi_service_info {
 	uint32_t service_type;
 	uint32_t qrtr_port;		/* Always 0 on qmux */
@@ -90,7 +86,6 @@  struct qmi_device {
 	struct l_io *io;
 	struct l_queue *req_queue;
 	struct l_queue *service_queue;
-	struct l_queue *discovery_queue;
 	unsigned int next_group_id;	/* Matches requests with services */
 	unsigned int next_service_handle;
 	uint16_t next_service_tid;
@@ -268,11 +263,12 @@  static void *__request_alloc(uint32_t service_type,
 	return mem;
 }
 
-static struct qmi_request *__control_request_alloc(uint16_t message,
-					const void *data, uint16_t length)
+static void *__control_request_alloc(uint16_t message,
+					const void *data, uint16_t length,
+					size_t offset)
 {
 	return __request_alloc(QMI_SERVICE_CONTROL, 0x00, message,
-					data, length, 0);
+					data, length, offset);
 }
 
 static void __request_free(void *data)
@@ -293,14 +289,6 @@  static bool __request_compare(const void *a, const void *b)
 	return req->tid == tid;
 }
 
-static void __discovery_free(void *data)
-{
-	struct discovery *d = data;
-	qmi_destroy_func_t destroy = d->destroy;
-
-	destroy(d);
-}
-
 static void __notify_free(void *data)
 {
 	struct qmi_notify *notify = data;
@@ -815,33 +803,6 @@  static void __rx_message(struct qmi_device *device,
 	__request_free(req);
 }
 
-static void __qmi_device_discovery_started(struct qmi_device *device,
-						struct discovery *d)
-{
-	l_queue_push_tail(device->discovery_queue, d);
-}
-
-static void __qmi_device_discovery_complete(struct qmi_device *device,
-						struct discovery *d)
-{
-	if (!l_queue_remove(device->discovery_queue, d))
-		return;
-}
-
-/*
- * Prevents re-entrancy problems by removing the entry from the discovery_queue
- * before calling the callback.
- */
-#define DISCOVERY_DONE(data, ...)\
-do {\
-	__qmi_device_discovery_complete(data->device, &data->super);\
-\
-	if (data->func)\
-		data->func(__VA_ARGS__);\
-\
-	__discovery_free(&data->super);\
-} while (0)
-
 static void family_destroy(void *data)
 {
 	struct service_family *family = data;
@@ -873,7 +834,6 @@  static int qmi_device_init(struct qmi_device *device, int fd,
 
 	device->req_queue = l_queue_new();
 	device->service_queue = l_queue_new();
-	device->discovery_queue = l_queue_new();
 	device->service_infos = l_queue_new();
 	device->family_list = l_hashmap_new();
 
@@ -888,7 +848,6 @@  static void __qmi_device_free(struct qmi_device *device)
 {
 	l_queue_destroy(device->service_queue, __request_free);
 	l_queue_destroy(device->req_queue, __request_free);
-	l_queue_destroy(device->discovery_queue, __discovery_free);
 
 	l_io_destroy(device->io);
 
@@ -1301,7 +1260,7 @@  done:
 	if ((qmux->control_major == 1 && qmux->control_minor >= 5) ||
 			qmux->control_major > 1) {
 		struct qmi_request *req =
-			__control_request_alloc(QMI_CTL_SYNC, NULL, 0);
+			__control_request_alloc(QMI_CTL_SYNC, NULL, 0, 0);
 
 		req->user_data = qmux;
 
@@ -1345,7 +1304,7 @@  int qmi_qmux_device_discover(struct qmi_qmux_device *qmux,
 	if (l_queue_length(qmux->super.service_infos) > 0 || qmux->discover.tid)
 		return -EALREADY;
 
-	req = __control_request_alloc(QMI_CTL_GET_VERSION_INFO, NULL, 0);
+	req = __control_request_alloc(QMI_CTL_GET_VERSION_INFO, NULL, 0, 0);
 	req->user_data = qmux;
 
 	qmux->discover.func = func;
@@ -1360,9 +1319,8 @@  int qmi_qmux_device_discover(struct qmi_qmux_device *qmux,
 	return 0;
 }
 
-struct qmux_client_create_data {
-	struct discovery super;
-	struct qmi_device *device;
+struct qmux_create_client_request {
+	struct qmi_qmux_device *qmux;
 	uint8_t type;
 	uint16_t major;
 	uint16_t minor;
@@ -1370,52 +1328,46 @@  struct qmux_client_create_data {
 	void *user_data;
 	qmi_destroy_func_t destroy;
 	struct l_timeout *timeout;
-	uint16_t tid;
+	struct qmi_request super;
 };
 
-static void qmux_client_create_data_free(void *user_data)
+static void qmux_create_client_request_free(struct qmi_request *r)
 {
-	struct qmux_client_create_data *data = user_data;
+	struct qmux_create_client_request *req =
+		l_container_of(r, struct qmux_create_client_request, super);
 
-	if (data->timeout)
-		l_timeout_remove(data->timeout);
+	if (req->timeout)
+		l_timeout_remove(req->timeout);
 
-	if (data->destroy)
-		data->destroy(data->user_data);
+	if (req->destroy)
+		req->destroy(req->user_data);
 
-	l_free(data);
+	l_free(req);
 }
 
-static void qmux_client_create_timeout(struct l_timeout *timeout,
+static void qmux_create_client_timeout(struct l_timeout *timeout,
 							void *user_data)
 {
-	struct qmux_client_create_data *data = user_data;
-	struct qmi_device *device = data->device;
-	struct qmi_qmux_device *qmux =
-		l_container_of(device, struct qmi_qmux_device, super);
-	struct qmi_request *req;
+	struct qmux_create_client_request *req = user_data;
+	struct qmi_qmux_device *qmux = req->qmux;
 
 	DEBUG(&qmux->debug, "");
 
-	l_timeout_remove(data->timeout);
-	data->timeout = NULL;
+	l_timeout_remove(req->timeout);
+	req->timeout = NULL;
 
 	/* remove request from queues */
-	req = find_control_request(qmux, data->tid);
-	if (req)
-		__request_free(req);
-
-	DISCOVERY_DONE(data, NULL, data->user_data);
+	find_control_request(qmux, req->super.tid);
+	__request_free(&req->super);
 }
 
-static void qmux_client_create_callback(struct qmi_request *req,
+static void qmux_create_client_callback(struct qmi_request *r,
 					uint16_t message, uint16_t length,
 					const void *buffer)
 {
-	struct qmux_client_create_data *data = req->user_data;
-	struct qmi_device *device = data->device;
-	struct qmi_qmux_device *qmux =
-		l_container_of(device, struct qmi_qmux_device, super);
+	struct qmux_create_client_request *req =
+		l_container_of(r, struct qmux_create_client_request, super);
+	struct qmi_qmux_device *qmux = req->qmux;
 	struct service_family *family = NULL;
 	struct qmi_service *service = NULL;
 	struct qmi_service_info info;
@@ -1438,13 +1390,13 @@  static void qmux_client_create_callback(struct qmi_request *req,
 	if (len != QMI_CLIENT_ID_SIZE)
 		goto done;
 
-	if (client_id->service != data->type)
+	if (client_id->service != req->type)
 		goto done;
 
 	memset(&info, 0, sizeof(family->info));
-	info.service_type = data->type;
-	info.major = data->major;
-	info.minor = data->minor;
+	info.service_type = req->type;
+	info.major = req->major;
+	info.minor = req->minor;
 
 	family = service_family_create(&qmux->super, &info, client_id->client);
 	DEBUG(&qmux->debug, "service family created [client=%d,type=%d]",
@@ -1460,7 +1412,8 @@  done:
 	if (family)
 		service = service_create(family);
 
-	DISCOVERY_DONE(data, service, data->user_data);
+	if (req->func)
+		req->func(service, req->user_data);
 
 	if (family)
 		service_family_unref(family);
@@ -1473,8 +1426,7 @@  bool qmi_qmux_device_create_client(struct qmi_qmux_device *qmux,
 {
 	unsigned char client_req[] = { 0x01, 0x01, 0x00, service_type };
 	const struct qmi_service_info *info;
-	struct qmi_request *req;
-	struct qmux_client_create_data *create_data;
+	struct qmux_create_client_request *req;
 
 	if (!qmux || !func)
 		return false;
@@ -1486,28 +1438,25 @@  bool qmi_qmux_device_create_client(struct qmi_qmux_device *qmux,
 	if (!info)
 		return false;
 
-	create_data = l_new(struct qmux_client_create_data, 1);
-	create_data->super.destroy = qmux_client_create_data_free;
-	create_data->device = &qmux->super;
-	create_data->type = service_type;
-	create_data->major = info->major;
-	create_data->minor = info->minor;
-	create_data->func = func;
-	create_data->user_data = user_data;
-	create_data->destroy = destroy;
-
 	DEBUG(&qmux->debug, "creating client [type=%d]", service_type);
 
 	req = __control_request_alloc(QMI_CTL_GET_CLIENT_ID,
-					client_req, sizeof(client_req));
-	req->user_data = create_data;
-
-	create_data->tid = __ctl_request_submit(qmux, req,
-						qmux_client_create_callback);
-	create_data->timeout = l_timeout_create(8, qmux_client_create_timeout,
-							create_data, NULL);
+				client_req, sizeof(client_req),
+				offsetof(struct qmux_create_client_request,
+						super));
+	req->super.free_request = qmux_create_client_request_free;
+	req->qmux = qmux;
+	req->type = service_type;
+	req->major = info->major;
+	req->minor = info->minor;
+	req->func = func;
+	req->user_data = user_data;
+	req->destroy = destroy;
+	req->timeout = l_timeout_create(8, qmux_create_client_timeout,
+					req, NULL);
+
+	__ctl_request_submit(qmux, &req->super, qmux_create_client_callback);
 
-	__qmi_device_discovery_started(&qmux->super, &create_data->super);
 	return true;
 }
 
@@ -1532,7 +1481,7 @@  static void qmi_qmux_device_client_release(struct qmi_device *device,
 	qmux->shutdown.release_users++;
 
 	req = __control_request_alloc(QMI_CTL_RELEASE_CLIENT_ID,
-					release_req, sizeof(release_req));
+					release_req, sizeof(release_req), 0);
 	req->user_data = qmux;
 
 	__ctl_request_submit(qmux, req, qmux_client_release_callback);