1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2017 Linaro Ltd.
5 #include <linux/kernel.h>
6 #include <linux/module.h>
7 #include <linux/device.h>
8 #include <linux/qrtr.h>
10 #include <linux/completion.h>
11 #include <linux/idr.h>
12 #include <linux/string.h>
14 #include <linux/workqueue.h>
15 #include <linux/soc/qcom/qmi.h>
17 static struct socket
*qmi_sock_create(struct qmi_handle
*qmi
,
18 struct sockaddr_qrtr
*sq
);
21 * qmi_recv_new_server() - handler of NEW_SERVER control message
23 * @service: service id of the new server
24 * @instance: instance id of the new server
25 * @node: node of the new server
26 * @port: port of the new server
28 * Calls the new_server callback to inform the client about a newly registered
29 * server matching the currently registered service lookup.
31 static void qmi_recv_new_server(struct qmi_handle
*qmi
,
32 unsigned int service
, unsigned int instance
,
33 unsigned int node
, unsigned int port
)
35 struct qmi_ops
*ops
= &qmi
->ops
;
36 struct qmi_service
*svc
;
42 /* Ignore EOF marker */
46 svc
= kzalloc(sizeof(*svc
), GFP_KERNEL
);
50 svc
->service
= service
;
51 svc
->version
= instance
& 0xff;
52 svc
->instance
= instance
>> 8;
56 ret
= ops
->new_server(qmi
, svc
);
60 list_add(&svc
->list_node
, &qmi
->lookup_results
);
64 * qmi_recv_del_server() - handler of DEL_SERVER control message
66 * @node: node of the dying server, a value of -1 matches all nodes
67 * @port: port of the dying server, a value of -1 matches all ports
69 * Calls the del_server callback for each previously seen server, allowing the
70 * client to react to the disappearing server.
72 static void qmi_recv_del_server(struct qmi_handle
*qmi
,
73 unsigned int node
, unsigned int port
)
75 struct qmi_ops
*ops
= &qmi
->ops
;
76 struct qmi_service
*svc
;
77 struct qmi_service
*tmp
;
79 list_for_each_entry_safe(svc
, tmp
, &qmi
->lookup_results
, list_node
) {
80 if (node
!= -1 && svc
->node
!= node
)
82 if (port
!= -1 && svc
->port
!= port
)
86 ops
->del_server(qmi
, svc
);
88 list_del(&svc
->list_node
);
94 * qmi_recv_bye() - handler of BYE control message
96 * @node: id of the dying node
98 * Signals the client that all previously registered services on this node are
99 * now gone and then calls the bye callback to allow the client client further
100 * cleaning up resources associated with this remote.
102 static void qmi_recv_bye(struct qmi_handle
*qmi
,
105 struct qmi_ops
*ops
= &qmi
->ops
;
107 qmi_recv_del_server(qmi
, node
, -1);
114 * qmi_recv_del_client() - handler of DEL_CLIENT control message
116 * @node: node of the dying client
117 * @port: port of the dying client
119 * Signals the client about a dying client, by calling the del_client callback.
121 static void qmi_recv_del_client(struct qmi_handle
*qmi
,
122 unsigned int node
, unsigned int port
)
124 struct qmi_ops
*ops
= &qmi
->ops
;
127 ops
->del_client(qmi
, node
, port
);
130 static void qmi_recv_ctrl_pkt(struct qmi_handle
*qmi
,
131 const void *buf
, size_t len
)
133 const struct qrtr_ctrl_pkt
*pkt
= buf
;
135 if (len
< sizeof(struct qrtr_ctrl_pkt
)) {
136 pr_debug("ignoring short control packet\n");
140 switch (le32_to_cpu(pkt
->cmd
)) {
142 qmi_recv_bye(qmi
, le32_to_cpu(pkt
->client
.node
));
144 case QRTR_TYPE_NEW_SERVER
:
145 qmi_recv_new_server(qmi
,
146 le32_to_cpu(pkt
->server
.service
),
147 le32_to_cpu(pkt
->server
.instance
),
148 le32_to_cpu(pkt
->server
.node
),
149 le32_to_cpu(pkt
->server
.port
));
151 case QRTR_TYPE_DEL_SERVER
:
152 qmi_recv_del_server(qmi
,
153 le32_to_cpu(pkt
->server
.node
),
154 le32_to_cpu(pkt
->server
.port
));
156 case QRTR_TYPE_DEL_CLIENT
:
157 qmi_recv_del_client(qmi
,
158 le32_to_cpu(pkt
->client
.node
),
159 le32_to_cpu(pkt
->client
.port
));
164 static void qmi_send_new_lookup(struct qmi_handle
*qmi
, struct qmi_service
*svc
)
166 struct qrtr_ctrl_pkt pkt
;
167 struct sockaddr_qrtr sq
;
168 struct msghdr msg
= { };
169 struct kvec iv
= { &pkt
, sizeof(pkt
) };
172 memset(&pkt
, 0, sizeof(pkt
));
173 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_NEW_LOOKUP
);
174 pkt
.server
.service
= cpu_to_le32(svc
->service
);
175 pkt
.server
.instance
= cpu_to_le32(svc
->version
| svc
->instance
<< 8);
177 sq
.sq_family
= qmi
->sq
.sq_family
;
178 sq
.sq_node
= qmi
->sq
.sq_node
;
179 sq
.sq_port
= QRTR_PORT_CTRL
;
182 msg
.msg_namelen
= sizeof(sq
);
184 mutex_lock(&qmi
->sock_lock
);
186 ret
= kernel_sendmsg(qmi
->sock
, &msg
, &iv
, 1, sizeof(pkt
));
188 pr_err("failed to send lookup registration: %d\n", ret
);
190 mutex_unlock(&qmi
->sock_lock
);
194 * qmi_add_lookup() - register a new lookup with the name service
196 * @service: service id of the request
197 * @instance: instance id of the request
198 * @version: version number of the request
200 * Registering a lookup query with the name server will cause the name server
201 * to send NEW_SERVER and DEL_SERVER control messages to this socket as
202 * matching services are registered.
204 * Return: 0 on success, negative errno on failure.
206 int qmi_add_lookup(struct qmi_handle
*qmi
, unsigned int service
,
207 unsigned int version
, unsigned int instance
)
209 struct qmi_service
*svc
;
211 svc
= kzalloc(sizeof(*svc
), GFP_KERNEL
);
215 svc
->service
= service
;
216 svc
->version
= version
;
217 svc
->instance
= instance
;
219 list_add(&svc
->list_node
, &qmi
->lookups
);
221 qmi_send_new_lookup(qmi
, svc
);
225 EXPORT_SYMBOL(qmi_add_lookup
);
227 static void qmi_send_new_server(struct qmi_handle
*qmi
, struct qmi_service
*svc
)
229 struct qrtr_ctrl_pkt pkt
;
230 struct sockaddr_qrtr sq
;
231 struct msghdr msg
= { };
232 struct kvec iv
= { &pkt
, sizeof(pkt
) };
235 memset(&pkt
, 0, sizeof(pkt
));
236 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_NEW_SERVER
);
237 pkt
.server
.service
= cpu_to_le32(svc
->service
);
238 pkt
.server
.instance
= cpu_to_le32(svc
->version
| svc
->instance
<< 8);
239 pkt
.server
.node
= cpu_to_le32(qmi
->sq
.sq_node
);
240 pkt
.server
.port
= cpu_to_le32(qmi
->sq
.sq_port
);
242 sq
.sq_family
= qmi
->sq
.sq_family
;
243 sq
.sq_node
= qmi
->sq
.sq_node
;
244 sq
.sq_port
= QRTR_PORT_CTRL
;
247 msg
.msg_namelen
= sizeof(sq
);
249 mutex_lock(&qmi
->sock_lock
);
251 ret
= kernel_sendmsg(qmi
->sock
, &msg
, &iv
, 1, sizeof(pkt
));
253 pr_err("send service registration failed: %d\n", ret
);
255 mutex_unlock(&qmi
->sock_lock
);
259 * qmi_add_server() - register a service with the name service
261 * @service: type of the service
262 * @instance: instance of the service
263 * @version: version of the service
265 * Register a new service with the name service. This allows clients to find
266 * and start sending messages to the client associated with @qmi.
268 * Return: 0 on success, negative errno on failure.
270 int qmi_add_server(struct qmi_handle
*qmi
, unsigned int service
,
271 unsigned int version
, unsigned int instance
)
273 struct qmi_service
*svc
;
275 svc
= kzalloc(sizeof(*svc
), GFP_KERNEL
);
279 svc
->service
= service
;
280 svc
->version
= version
;
281 svc
->instance
= instance
;
283 list_add(&svc
->list_node
, &qmi
->services
);
285 qmi_send_new_server(qmi
, svc
);
289 EXPORT_SYMBOL(qmi_add_server
);
292 * qmi_txn_init() - allocate transaction id within the given QMI handle
294 * @txn: transaction context
295 * @ei: description of how to decode a matching response (optional)
296 * @c_struct: pointer to the object to decode the response into (optional)
298 * This allocates a transaction id within the QMI handle. If @ei and @c_struct
299 * are specified any responses to this transaction will be decoded as described
300 * by @ei into @c_struct.
302 * A client calling qmi_txn_init() must call either qmi_txn_wait() or
303 * qmi_txn_cancel() to free up the allocated resources.
305 * Return: Transaction id on success, negative errno on failure.
307 int qmi_txn_init(struct qmi_handle
*qmi
, struct qmi_txn
*txn
,
308 struct qmi_elem_info
*ei
, void *c_struct
)
312 memset(txn
, 0, sizeof(*txn
));
314 mutex_init(&txn
->lock
);
315 init_completion(&txn
->completion
);
318 txn
->dest
= c_struct
;
320 mutex_lock(&qmi
->txn_lock
);
321 ret
= idr_alloc_cyclic(&qmi
->txns
, txn
, 0, U16_MAX
, GFP_KERNEL
);
323 pr_err("failed to allocate transaction id\n");
326 mutex_unlock(&qmi
->txn_lock
);
330 EXPORT_SYMBOL(qmi_txn_init
);
333 * qmi_txn_wait() - wait for a response on a transaction
334 * @txn: transaction handle
335 * @timeout: timeout, in jiffies
337 * If the transaction is decoded by the means of @ei and @c_struct the return
338 * value will be the returned value of qmi_decode_message(), otherwise it's up
339 * to the specified message handler to fill out the result.
341 * Return: the transaction response on success, negative errno on failure.
343 int qmi_txn_wait(struct qmi_txn
*txn
, unsigned long timeout
)
345 struct qmi_handle
*qmi
= txn
->qmi
;
348 ret
= wait_for_completion_timeout(&txn
->completion
, timeout
);
350 mutex_lock(&qmi
->txn_lock
);
351 mutex_lock(&txn
->lock
);
352 idr_remove(&qmi
->txns
, txn
->id
);
353 mutex_unlock(&txn
->lock
);
354 mutex_unlock(&qmi
->txn_lock
);
361 EXPORT_SYMBOL(qmi_txn_wait
);
364 * qmi_txn_cancel() - cancel an ongoing transaction
365 * @txn: transaction id
367 void qmi_txn_cancel(struct qmi_txn
*txn
)
369 struct qmi_handle
*qmi
= txn
->qmi
;
371 mutex_lock(&qmi
->txn_lock
);
372 mutex_lock(&txn
->lock
);
373 idr_remove(&qmi
->txns
, txn
->id
);
374 mutex_unlock(&txn
->lock
);
375 mutex_unlock(&qmi
->txn_lock
);
377 EXPORT_SYMBOL(qmi_txn_cancel
);
380 * qmi_invoke_handler() - find and invoke a handler for a message
382 * @sq: sockaddr of the sender
383 * @txn: transaction object for the message
384 * @buf: buffer containing the message
385 * @len: length of @buf
387 * Find handler and invoke handler for the incoming message.
389 static void qmi_invoke_handler(struct qmi_handle
*qmi
, struct sockaddr_qrtr
*sq
,
390 struct qmi_txn
*txn
, const void *buf
, size_t len
)
392 const struct qmi_msg_handler
*handler
;
393 const struct qmi_header
*hdr
= buf
;
400 for (handler
= qmi
->handlers
; handler
->fn
; handler
++) {
401 if (handler
->type
== hdr
->type
&&
402 handler
->msg_id
== hdr
->msg_id
)
409 dest
= kzalloc(handler
->decoded_size
, GFP_KERNEL
);
413 ret
= qmi_decode_message(buf
, len
, handler
->ei
, dest
);
415 pr_err("failed to decode incoming message\n");
417 handler
->fn(qmi
, sq
, txn
, dest
);
423 * qmi_handle_net_reset() - invoked to handle ENETRESET on a QMI handle
424 * @qmi: the QMI context
426 * As a result of registering a name service with the QRTR all open sockets are
427 * flagged with ENETRESET and this function will be called. The typical case is
428 * the initial boot, where this signals that the local node id has been
429 * configured and as such any bound sockets needs to be rebound. So close the
430 * socket, inform the client and re-initialize the socket.
432 * For clients it's generally sufficient to react to the del_server callbacks,
433 * but server code is expected to treat the net_reset callback as a "bye" from
436 * Finally the QMI handle will send out registration requests for any lookups
439 static void qmi_handle_net_reset(struct qmi_handle
*qmi
)
441 struct sockaddr_qrtr sq
;
442 struct qmi_service
*svc
;
445 sock
= qmi_sock_create(qmi
, &sq
);
449 mutex_lock(&qmi
->sock_lock
);
450 sock_release(qmi
->sock
);
452 mutex_unlock(&qmi
->sock_lock
);
454 qmi_recv_del_server(qmi
, -1, -1);
456 if (qmi
->ops
.net_reset
)
457 qmi
->ops
.net_reset(qmi
);
459 mutex_lock(&qmi
->sock_lock
);
462 mutex_unlock(&qmi
->sock_lock
);
464 list_for_each_entry(svc
, &qmi
->lookups
, list_node
)
465 qmi_send_new_lookup(qmi
, svc
);
467 list_for_each_entry(svc
, &qmi
->services
, list_node
)
468 qmi_send_new_server(qmi
, svc
);
471 static void qmi_handle_message(struct qmi_handle
*qmi
,
472 struct sockaddr_qrtr
*sq
,
473 const void *buf
, size_t len
)
475 const struct qmi_header
*hdr
;
476 struct qmi_txn tmp_txn
;
477 struct qmi_txn
*txn
= NULL
;
480 if (len
< sizeof(*hdr
)) {
481 pr_err("ignoring short QMI packet\n");
487 /* If this is a response, find the matching transaction handle */
488 if (hdr
->type
== QMI_RESPONSE
) {
489 mutex_lock(&qmi
->txn_lock
);
490 txn
= idr_find(&qmi
->txns
, hdr
->txn_id
);
492 /* Ignore unexpected responses */
494 mutex_unlock(&qmi
->txn_lock
);
498 mutex_lock(&txn
->lock
);
499 mutex_unlock(&qmi
->txn_lock
);
501 if (txn
->dest
&& txn
->ei
) {
502 ret
= qmi_decode_message(buf
, len
, txn
->ei
, txn
->dest
);
504 pr_err("failed to decode incoming message\n");
507 complete(&txn
->completion
);
509 qmi_invoke_handler(qmi
, sq
, txn
, buf
, len
);
512 mutex_unlock(&txn
->lock
);
514 /* Create a txn based on the txn_id of the incoming message */
515 memset(&tmp_txn
, 0, sizeof(tmp_txn
));
516 tmp_txn
.id
= hdr
->txn_id
;
518 qmi_invoke_handler(qmi
, sq
, &tmp_txn
, buf
, len
);
522 static void qmi_data_ready_work(struct work_struct
*work
)
524 struct qmi_handle
*qmi
= container_of(work
, struct qmi_handle
, work
);
525 struct qmi_ops
*ops
= &qmi
->ops
;
526 struct sockaddr_qrtr sq
;
527 struct msghdr msg
= { .msg_name
= &sq
, .msg_namelen
= sizeof(sq
) };
532 iv
.iov_base
= qmi
->recv_buf
;
533 iv
.iov_len
= qmi
->recv_buf_size
;
535 mutex_lock(&qmi
->sock_lock
);
537 msglen
= kernel_recvmsg(qmi
->sock
, &msg
, &iv
, 1,
538 iv
.iov_len
, MSG_DONTWAIT
);
541 mutex_unlock(&qmi
->sock_lock
);
542 if (msglen
== -EAGAIN
)
545 if (msglen
== -ENETRESET
) {
546 qmi_handle_net_reset(qmi
);
548 /* The old qmi->sock is gone, our work is done */
553 pr_err("qmi recvmsg failed: %zd\n", msglen
);
557 if (sq
.sq_node
== qmi
->sq
.sq_node
&&
558 sq
.sq_port
== QRTR_PORT_CTRL
) {
559 qmi_recv_ctrl_pkt(qmi
, qmi
->recv_buf
, msglen
);
560 } else if (ops
->msg_handler
) {
561 ops
->msg_handler(qmi
, &sq
, qmi
->recv_buf
, msglen
);
563 qmi_handle_message(qmi
, &sq
, qmi
->recv_buf
, msglen
);
568 static void qmi_data_ready(struct sock
*sk
)
570 struct qmi_handle
*qmi
= sk
->sk_user_data
;
573 * This will be NULL if we receive data while being in
574 * qmi_handle_release()
579 queue_work(qmi
->wq
, &qmi
->work
);
582 static struct socket
*qmi_sock_create(struct qmi_handle
*qmi
,
583 struct sockaddr_qrtr
*sq
)
588 ret
= sock_create_kern(&init_net
, AF_QIPCRTR
, SOCK_DGRAM
,
593 ret
= kernel_getsockname(sock
, (struct sockaddr
*)sq
);
599 sock
->sk
->sk_user_data
= qmi
;
600 sock
->sk
->sk_data_ready
= qmi_data_ready
;
601 sock
->sk
->sk_error_report
= qmi_data_ready
;
607 * qmi_handle_init() - initialize a QMI client handle
608 * @qmi: QMI handle to initialize
609 * @recv_buf_size: maximum size of incoming message
610 * @ops: reference to callbacks for QRTR notifications
611 * @handlers: NULL-terminated list of QMI message handlers
613 * This initializes the QMI client handle to allow sending and receiving QMI
614 * messages. As messages are received the appropriate handler will be invoked.
616 * Return: 0 on success, negative errno on failure.
618 int qmi_handle_init(struct qmi_handle
*qmi
, size_t recv_buf_size
,
619 const struct qmi_ops
*ops
,
620 const struct qmi_msg_handler
*handlers
)
624 mutex_init(&qmi
->txn_lock
);
625 mutex_init(&qmi
->sock_lock
);
627 idr_init(&qmi
->txns
);
629 INIT_LIST_HEAD(&qmi
->lookups
);
630 INIT_LIST_HEAD(&qmi
->lookup_results
);
631 INIT_LIST_HEAD(&qmi
->services
);
633 INIT_WORK(&qmi
->work
, qmi_data_ready_work
);
635 qmi
->handlers
= handlers
;
639 /* Make room for the header */
640 recv_buf_size
+= sizeof(struct qmi_header
);
641 /* Must also be sufficient to hold a control packet */
642 if (recv_buf_size
< sizeof(struct qrtr_ctrl_pkt
))
643 recv_buf_size
= sizeof(struct qrtr_ctrl_pkt
);
645 qmi
->recv_buf_size
= recv_buf_size
;
646 qmi
->recv_buf
= kzalloc(recv_buf_size
, GFP_KERNEL
);
650 qmi
->wq
= alloc_workqueue("qmi_msg_handler", WQ_UNBOUND
, 1);
653 goto err_free_recv_buf
;
656 qmi
->sock
= qmi_sock_create(qmi
, &qmi
->sq
);
657 if (IS_ERR(qmi
->sock
)) {
658 if (PTR_ERR(qmi
->sock
) == -EAFNOSUPPORT
) {
661 pr_err("failed to create QMI socket\n");
662 ret
= PTR_ERR(qmi
->sock
);
670 destroy_workqueue(qmi
->wq
);
672 kfree(qmi
->recv_buf
);
676 EXPORT_SYMBOL(qmi_handle_init
);
679 * qmi_handle_release() - release the QMI client handle
680 * @qmi: QMI client handle
682 * This closes the underlying socket and stops any handling of QMI messages.
684 void qmi_handle_release(struct qmi_handle
*qmi
)
686 struct socket
*sock
= qmi
->sock
;
687 struct qmi_service
*svc
, *tmp
;
689 sock
->sk
->sk_user_data
= NULL
;
690 cancel_work_sync(&qmi
->work
);
692 qmi_recv_del_server(qmi
, -1, -1);
694 mutex_lock(&qmi
->sock_lock
);
697 mutex_unlock(&qmi
->sock_lock
);
699 destroy_workqueue(qmi
->wq
);
701 idr_destroy(&qmi
->txns
);
703 kfree(qmi
->recv_buf
);
705 /* Free registered lookup requests */
706 list_for_each_entry_safe(svc
, tmp
, &qmi
->lookups
, list_node
) {
707 list_del(&svc
->list_node
);
711 /* Free registered service information */
712 list_for_each_entry_safe(svc
, tmp
, &qmi
->services
, list_node
) {
713 list_del(&svc
->list_node
);
717 EXPORT_SYMBOL(qmi_handle_release
);
720 * qmi_send_message() - send a QMI message
721 * @qmi: QMI client handle
722 * @sq: destination sockaddr
723 * @txn: transaction object to use for the message
724 * @type: type of message to send
725 * @msg_id: message id
726 * @len: max length of the QMI message
727 * @ei: QMI message description
728 * @c_struct: object to be encoded
730 * This function encodes @c_struct using @ei into a message of type @type,
731 * with @msg_id and @txn into a buffer of maximum size @len, and sends this to
734 * Return: 0 on success, negative errno on failure.
736 static ssize_t
qmi_send_message(struct qmi_handle
*qmi
,
737 struct sockaddr_qrtr
*sq
, struct qmi_txn
*txn
,
738 int type
, int msg_id
, size_t len
,
739 struct qmi_elem_info
*ei
, const void *c_struct
)
741 struct msghdr msghdr
= {};
746 msg
= qmi_encode_message(type
,
757 msghdr
.msg_name
= sq
;
758 msghdr
.msg_namelen
= sizeof(*sq
);
761 mutex_lock(&qmi
->sock_lock
);
763 ret
= kernel_sendmsg(qmi
->sock
, &msghdr
, &iv
, 1, len
);
765 pr_err("failed to send QMI message\n");
769 mutex_unlock(&qmi
->sock_lock
);
773 return ret
< 0 ? ret
: 0;
777 * qmi_send_request() - send a request QMI message
778 * @qmi: QMI client handle
779 * @sq: destination sockaddr
780 * @txn: transaction object to use for the message
781 * @msg_id: message id
782 * @len: max length of the QMI message
783 * @ei: QMI message description
784 * @c_struct: object to be encoded
786 * Return: 0 on success, negative errno on failure.
788 ssize_t
qmi_send_request(struct qmi_handle
*qmi
, struct sockaddr_qrtr
*sq
,
789 struct qmi_txn
*txn
, int msg_id
, size_t len
,
790 struct qmi_elem_info
*ei
, const void *c_struct
)
792 return qmi_send_message(qmi
, sq
, txn
, QMI_REQUEST
, msg_id
, len
, ei
,
795 EXPORT_SYMBOL(qmi_send_request
);
798 * qmi_send_response() - send a response QMI message
799 * @qmi: QMI client handle
800 * @sq: destination sockaddr
801 * @txn: transaction object to use for the message
802 * @msg_id: message id
803 * @len: max length of the QMI message
804 * @ei: QMI message description
805 * @c_struct: object to be encoded
807 * Return: 0 on success, negative errno on failure.
809 ssize_t
qmi_send_response(struct qmi_handle
*qmi
, struct sockaddr_qrtr
*sq
,
810 struct qmi_txn
*txn
, int msg_id
, size_t len
,
811 struct qmi_elem_info
*ei
, const void *c_struct
)
813 return qmi_send_message(qmi
, sq
, txn
, QMI_RESPONSE
, msg_id
, len
, ei
,
816 EXPORT_SYMBOL(qmi_send_response
);
819 * qmi_send_indication() - send an indication QMI message
820 * @qmi: QMI client handle
821 * @sq: destination sockaddr
822 * @msg_id: message id
823 * @len: max length of the QMI message
824 * @ei: QMI message description
825 * @c_struct: object to be encoded
827 * Return: 0 on success, negative errno on failure.
829 ssize_t
qmi_send_indication(struct qmi_handle
*qmi
, struct sockaddr_qrtr
*sq
,
830 int msg_id
, size_t len
, struct qmi_elem_info
*ei
,
831 const void *c_struct
)
837 ret
= qmi_txn_init(qmi
, &txn
, NULL
, NULL
);
841 rval
= qmi_send_message(qmi
, sq
, &txn
, QMI_INDICATION
, msg_id
, len
, ei
,
844 /* We don't care about future messages on this txn */
845 qmi_txn_cancel(&txn
);
849 EXPORT_SYMBOL(qmi_send_indication
);