brintos

brintos / linux-shallow public Read only

0
0
Text · 21.1 KiB · bb98b06 Raw
855 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2017 Linaro Ltd.4 */5#include <linux/kernel.h>6#include <linux/module.h>7#include <linux/device.h>8#include <linux/qrtr.h>9#include <linux/net.h>10#include <linux/completion.h>11#include <linux/idr.h>12#include <linux/string.h>13#include <net/sock.h>14#include <linux/workqueue.h>15#include <trace/events/sock.h>16#include <linux/soc/qcom/qmi.h>17 18static struct socket *qmi_sock_create(struct qmi_handle *qmi,19				      struct sockaddr_qrtr *sq);20 21/**22 * qmi_recv_new_server() - handler of NEW_SERVER control message23 * @qmi:	qmi handle24 * @service:	service id of the new server25 * @instance:	instance id of the new server26 * @node:	node of the new server27 * @port:	port of the new server28 *29 * Calls the new_server callback to inform the client about a newly registered30 * server matching the currently registered service lookup.31 */32static void qmi_recv_new_server(struct qmi_handle *qmi,33				unsigned int service, unsigned int instance,34				unsigned int node, unsigned int port)35{36	struct qmi_ops *ops = &qmi->ops;37	struct qmi_service *svc;38	int ret;39 40	if (!ops->new_server)41		return;42 43	/* Ignore EOF marker */44	if (!node && !port)45		return;46 47	svc = kzalloc(sizeof(*svc), GFP_KERNEL);48	if (!svc)49		return;50 51	svc->service = service;52	svc->version = instance & 0xff;53	svc->instance = instance >> 8;54	svc->node = node;55	svc->port = port;56 57	ret = ops->new_server(qmi, svc);58	if (ret < 0)59		kfree(svc);60	else61		list_add(&svc->list_node, &qmi->lookup_results);62}63 64/**65 * qmi_recv_del_server() - handler of DEL_SERVER control message66 * @qmi:	qmi handle67 * @node:	node of the dying server, a value of -1 matches all nodes68 * @port:	port of the dying server, a value of -1 matches all ports69 *70 * Calls the del_server callback for each previously seen server, allowing the71 * client to react to the disappearing server.72 */73static void qmi_recv_del_server(struct qmi_handle *qmi,74				unsigned int node, unsigned int port)75{76	struct qmi_ops *ops = &qmi->ops;77	struct qmi_service *svc;78	struct qmi_service *tmp;79 80	list_for_each_entry_safe(svc, tmp, &qmi->lookup_results, list_node) {81		if (node != -1 && svc->node != node)82			continue;83		if (port != -1 && svc->port != port)84			continue;85 86		if (ops->del_server)87			ops->del_server(qmi, svc);88 89		list_del(&svc->list_node);90		kfree(svc);91	}92}93 94/**95 * qmi_recv_bye() - handler of BYE control message96 * @qmi:	qmi handle97 * @node:	id of the dying node98 *99 * Signals the client that all previously registered services on this node are100 * now gone and then calls the bye callback to allow the client further101 * cleaning up resources associated with this remote.102 */103static void qmi_recv_bye(struct qmi_handle *qmi,104			 unsigned int node)105{106	struct qmi_ops *ops = &qmi->ops;107 108	qmi_recv_del_server(qmi, node, -1);109 110	if (ops->bye)111		ops->bye(qmi, node);112}113 114/**115 * qmi_recv_del_client() - handler of DEL_CLIENT control message116 * @qmi:	qmi handle117 * @node:	node of the dying client118 * @port:	port of the dying client119 *120 * Signals the client about a dying client, by calling the del_client callback.121 */122static void qmi_recv_del_client(struct qmi_handle *qmi,123				unsigned int node, unsigned int port)124{125	struct qmi_ops *ops = &qmi->ops;126 127	if (ops->del_client)128		ops->del_client(qmi, node, port);129}130 131static void qmi_recv_ctrl_pkt(struct qmi_handle *qmi,132			      const void *buf, size_t len)133{134	const struct qrtr_ctrl_pkt *pkt = buf;135 136	if (len < sizeof(struct qrtr_ctrl_pkt)) {137		pr_debug("ignoring short control packet\n");138		return;139	}140 141	switch (le32_to_cpu(pkt->cmd)) {142	case QRTR_TYPE_BYE:143		qmi_recv_bye(qmi, le32_to_cpu(pkt->client.node));144		break;145	case QRTR_TYPE_NEW_SERVER:146		qmi_recv_new_server(qmi,147				    le32_to_cpu(pkt->server.service),148				    le32_to_cpu(pkt->server.instance),149				    le32_to_cpu(pkt->server.node),150				    le32_to_cpu(pkt->server.port));151		break;152	case QRTR_TYPE_DEL_SERVER:153		qmi_recv_del_server(qmi,154				    le32_to_cpu(pkt->server.node),155				    le32_to_cpu(pkt->server.port));156		break;157	case QRTR_TYPE_DEL_CLIENT:158		qmi_recv_del_client(qmi,159				    le32_to_cpu(pkt->client.node),160				    le32_to_cpu(pkt->client.port));161		break;162	}163}164 165static void qmi_send_new_lookup(struct qmi_handle *qmi, struct qmi_service *svc)166{167	struct qrtr_ctrl_pkt pkt;168	struct sockaddr_qrtr sq;169	struct msghdr msg = { };170	struct kvec iv = { &pkt, sizeof(pkt) };171	int ret;172 173	memset(&pkt, 0, sizeof(pkt));174	pkt.cmd = cpu_to_le32(QRTR_TYPE_NEW_LOOKUP);175	pkt.server.service = cpu_to_le32(svc->service);176	pkt.server.instance = cpu_to_le32(svc->version | svc->instance << 8);177 178	sq.sq_family = qmi->sq.sq_family;179	sq.sq_node = qmi->sq.sq_node;180	sq.sq_port = QRTR_PORT_CTRL;181 182	msg.msg_name = &sq;183	msg.msg_namelen = sizeof(sq);184 185	mutex_lock(&qmi->sock_lock);186	if (qmi->sock) {187		ret = kernel_sendmsg(qmi->sock, &msg, &iv, 1, sizeof(pkt));188		if (ret < 0)189			pr_err("failed to send lookup registration: %d\n", ret);190	}191	mutex_unlock(&qmi->sock_lock);192}193 194/**195 * qmi_add_lookup() - register a new lookup with the name service196 * @qmi:	qmi handle197 * @service:	service id of the request198 * @instance:	instance id of the request199 * @version:	version number of the request200 *201 * Registering a lookup query with the name server will cause the name server202 * to send NEW_SERVER and DEL_SERVER control messages to this socket as203 * matching services are registered.204 *205 * Return: 0 on success, negative errno on failure.206 */207int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service,208		   unsigned int version, unsigned int instance)209{210	struct qmi_service *svc;211 212	svc = kzalloc(sizeof(*svc), GFP_KERNEL);213	if (!svc)214		return -ENOMEM;215 216	svc->service = service;217	svc->version = version;218	svc->instance = instance;219 220	list_add(&svc->list_node, &qmi->lookups);221 222	qmi_send_new_lookup(qmi, svc);223 224	return 0;225}226EXPORT_SYMBOL_GPL(qmi_add_lookup);227 228static void qmi_send_new_server(struct qmi_handle *qmi, struct qmi_service *svc)229{230	struct qrtr_ctrl_pkt pkt;231	struct sockaddr_qrtr sq;232	struct msghdr msg = { };233	struct kvec iv = { &pkt, sizeof(pkt) };234	int ret;235 236	memset(&pkt, 0, sizeof(pkt));237	pkt.cmd = cpu_to_le32(QRTR_TYPE_NEW_SERVER);238	pkt.server.service = cpu_to_le32(svc->service);239	pkt.server.instance = cpu_to_le32(svc->version | svc->instance << 8);240	pkt.server.node = cpu_to_le32(qmi->sq.sq_node);241	pkt.server.port = cpu_to_le32(qmi->sq.sq_port);242 243	sq.sq_family = qmi->sq.sq_family;244	sq.sq_node = qmi->sq.sq_node;245	sq.sq_port = QRTR_PORT_CTRL;246 247	msg.msg_name = &sq;248	msg.msg_namelen = sizeof(sq);249 250	mutex_lock(&qmi->sock_lock);251	if (qmi->sock) {252		ret = kernel_sendmsg(qmi->sock, &msg, &iv, 1, sizeof(pkt));253		if (ret < 0)254			pr_err("send service registration failed: %d\n", ret);255	}256	mutex_unlock(&qmi->sock_lock);257}258 259/**260 * qmi_add_server() - register a service with the name service261 * @qmi:	qmi handle262 * @service:	type of the service263 * @instance:	instance of the service264 * @version:	version of the service265 *266 * Register a new service with the name service. This allows clients to find267 * and start sending messages to the client associated with @qmi.268 *269 * Return: 0 on success, negative errno on failure.270 */271int qmi_add_server(struct qmi_handle *qmi, unsigned int service,272		   unsigned int version, unsigned int instance)273{274	struct qmi_service *svc;275 276	svc = kzalloc(sizeof(*svc), GFP_KERNEL);277	if (!svc)278		return -ENOMEM;279 280	svc->service = service;281	svc->version = version;282	svc->instance = instance;283 284	list_add(&svc->list_node, &qmi->services);285 286	qmi_send_new_server(qmi, svc);287 288	return 0;289}290EXPORT_SYMBOL_GPL(qmi_add_server);291 292/**293 * qmi_txn_init() - allocate transaction id within the given QMI handle294 * @qmi:	QMI handle295 * @txn:	transaction context296 * @ei:		description of how to decode a matching response (optional)297 * @c_struct:	pointer to the object to decode the response into (optional)298 *299 * This allocates a transaction id within the QMI handle. If @ei and @c_struct300 * are specified any responses to this transaction will be decoded as described301 * by @ei into @c_struct.302 *303 * A client calling qmi_txn_init() must call either qmi_txn_wait() or304 * qmi_txn_cancel() to free up the allocated resources.305 *306 * Return: Transaction id on success, negative errno on failure.307 */308int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn,309		 const struct qmi_elem_info *ei, void *c_struct)310{311	int ret;312 313	memset(txn, 0, sizeof(*txn));314 315	mutex_init(&txn->lock);316	init_completion(&txn->completion);317	txn->qmi = qmi;318	txn->ei = ei;319	txn->dest = c_struct;320 321	mutex_lock(&qmi->txn_lock);322	ret = idr_alloc_cyclic(&qmi->txns, txn, 0, U16_MAX, GFP_KERNEL);323	if (ret < 0)324		pr_err("failed to allocate transaction id\n");325 326	txn->id = ret;327	mutex_unlock(&qmi->txn_lock);328 329	return ret;330}331EXPORT_SYMBOL_GPL(qmi_txn_init);332 333/**334 * qmi_txn_wait() - wait for a response on a transaction335 * @txn:	transaction handle336 * @timeout:	timeout, in jiffies337 *338 * If the transaction is decoded by the means of @ei and @c_struct the return339 * value will be the returned value of qmi_decode_message(), otherwise it's up340 * to the specified message handler to fill out the result.341 *342 * Return: the transaction response on success, negative errno on failure.343 */344int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout)345{346	struct qmi_handle *qmi = txn->qmi;347	int ret;348 349	ret = wait_for_completion_timeout(&txn->completion, timeout);350 351	mutex_lock(&qmi->txn_lock);352	mutex_lock(&txn->lock);353	idr_remove(&qmi->txns, txn->id);354	mutex_unlock(&txn->lock);355	mutex_unlock(&qmi->txn_lock);356 357	if (ret == 0)358		return -ETIMEDOUT;359	else360		return txn->result;361}362EXPORT_SYMBOL_GPL(qmi_txn_wait);363 364/**365 * qmi_txn_cancel() - cancel an ongoing transaction366 * @txn:	transaction id367 */368void qmi_txn_cancel(struct qmi_txn *txn)369{370	struct qmi_handle *qmi = txn->qmi;371 372	mutex_lock(&qmi->txn_lock);373	mutex_lock(&txn->lock);374	idr_remove(&qmi->txns, txn->id);375	mutex_unlock(&txn->lock);376	mutex_unlock(&qmi->txn_lock);377}378EXPORT_SYMBOL_GPL(qmi_txn_cancel);379 380/**381 * qmi_invoke_handler() - find and invoke a handler for a message382 * @qmi:	qmi handle383 * @sq:		sockaddr of the sender384 * @txn:	transaction object for the message385 * @buf:	buffer containing the message386 * @len:	length of @buf387 *388 * Find handler and invoke handler for the incoming message.389 */390static void qmi_invoke_handler(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,391			       struct qmi_txn *txn, const void *buf, size_t len)392{393	const struct qmi_msg_handler *handler;394	const struct qmi_header *hdr = buf;395	void *dest;396	int ret;397 398	if (!qmi->handlers)399		return;400 401	for (handler = qmi->handlers; handler->fn; handler++) {402		if (handler->type == hdr->type &&403		    handler->msg_id == hdr->msg_id)404			break;405	}406 407	if (!handler->fn)408		return;409 410	dest = kzalloc(handler->decoded_size, GFP_KERNEL);411	if (!dest)412		return;413 414	ret = qmi_decode_message(buf, len, handler->ei, dest);415	if (ret < 0)416		pr_err("failed to decode incoming message\n");417	else418		handler->fn(qmi, sq, txn, dest);419 420	kfree(dest);421}422 423/**424 * qmi_handle_net_reset() - invoked to handle ENETRESET on a QMI handle425 * @qmi:	the QMI context426 *427 * As a result of registering a name service with the QRTR all open sockets are428 * flagged with ENETRESET and this function will be called. The typical case is429 * the initial boot, where this signals that the local node id has been430 * configured and as such any bound sockets needs to be rebound. So close the431 * socket, inform the client and re-initialize the socket.432 *433 * For clients it's generally sufficient to react to the del_server callbacks,434 * but server code is expected to treat the net_reset callback as a "bye" from435 * all nodes.436 *437 * Finally the QMI handle will send out registration requests for any lookups438 * and services.439 */440static void qmi_handle_net_reset(struct qmi_handle *qmi)441{442	struct sockaddr_qrtr sq;443	struct qmi_service *svc;444	struct socket *sock;445 446	sock = qmi_sock_create(qmi, &sq);447	if (IS_ERR(sock))448		return;449 450	mutex_lock(&qmi->sock_lock);451	sock_release(qmi->sock);452	qmi->sock = NULL;453	mutex_unlock(&qmi->sock_lock);454 455	qmi_recv_del_server(qmi, -1, -1);456 457	if (qmi->ops.net_reset)458		qmi->ops.net_reset(qmi);459 460	mutex_lock(&qmi->sock_lock);461	qmi->sock = sock;462	qmi->sq = sq;463	mutex_unlock(&qmi->sock_lock);464 465	list_for_each_entry(svc, &qmi->lookups, list_node)466		qmi_send_new_lookup(qmi, svc);467 468	list_for_each_entry(svc, &qmi->services, list_node)469		qmi_send_new_server(qmi, svc);470}471 472static void qmi_handle_message(struct qmi_handle *qmi,473			       struct sockaddr_qrtr *sq,474			       const void *buf, size_t len)475{476	const struct qmi_header *hdr;477	struct qmi_txn tmp_txn;478	struct qmi_txn *txn = NULL;479	int ret;480 481	if (len < sizeof(*hdr)) {482		pr_err("ignoring short QMI packet\n");483		return;484	}485 486	hdr = buf;487 488	/* If this is a response, find the matching transaction handle */489	if (hdr->type == QMI_RESPONSE) {490		mutex_lock(&qmi->txn_lock);491		txn = idr_find(&qmi->txns, hdr->txn_id);492 493		/* Ignore unexpected responses */494		if (!txn) {495			mutex_unlock(&qmi->txn_lock);496			return;497		}498 499		mutex_lock(&txn->lock);500		mutex_unlock(&qmi->txn_lock);501 502		if (txn->dest && txn->ei) {503			ret = qmi_decode_message(buf, len, txn->ei, txn->dest);504			if (ret < 0)505				pr_err("failed to decode incoming message\n");506 507			txn->result = ret;508			complete(&txn->completion);509		} else  {510			qmi_invoke_handler(qmi, sq, txn, buf, len);511		}512 513		mutex_unlock(&txn->lock);514	} else {515		/* Create a txn based on the txn_id of the incoming message */516		memset(&tmp_txn, 0, sizeof(tmp_txn));517		tmp_txn.id = hdr->txn_id;518 519		qmi_invoke_handler(qmi, sq, &tmp_txn, buf, len);520	}521}522 523static void qmi_data_ready_work(struct work_struct *work)524{525	struct qmi_handle *qmi = container_of(work, struct qmi_handle, work);526	struct qmi_ops *ops = &qmi->ops;527	struct sockaddr_qrtr sq;528	struct msghdr msg = { .msg_name = &sq, .msg_namelen = sizeof(sq) };529	struct kvec iv;530	ssize_t msglen;531 532	for (;;) {533		iv.iov_base = qmi->recv_buf;534		iv.iov_len = qmi->recv_buf_size;535 536		mutex_lock(&qmi->sock_lock);537		if (qmi->sock)538			msglen = kernel_recvmsg(qmi->sock, &msg, &iv, 1,539						iv.iov_len, MSG_DONTWAIT);540		else541			msglen = -EPIPE;542		mutex_unlock(&qmi->sock_lock);543		if (msglen == -EAGAIN)544			break;545 546		if (msglen == -ENETRESET) {547			qmi_handle_net_reset(qmi);548 549			/* The old qmi->sock is gone, our work is done */550			break;551		}552 553		if (msglen < 0) {554			pr_err("qmi recvmsg failed: %zd\n", msglen);555			break;556		}557 558		if (sq.sq_node == qmi->sq.sq_node &&559		    sq.sq_port == QRTR_PORT_CTRL) {560			qmi_recv_ctrl_pkt(qmi, qmi->recv_buf, msglen);561		} else if (ops->msg_handler) {562			ops->msg_handler(qmi, &sq, qmi->recv_buf, msglen);563		} else {564			qmi_handle_message(qmi, &sq, qmi->recv_buf, msglen);565		}566	}567}568 569static void qmi_data_ready(struct sock *sk)570{571	struct qmi_handle *qmi = sk->sk_user_data;572 573	trace_sk_data_ready(sk);574 575	/*576	 * This will be NULL if we receive data while being in577	 * qmi_handle_release()578	 */579	if (!qmi)580		return;581 582	queue_work(qmi->wq, &qmi->work);583}584 585static struct socket *qmi_sock_create(struct qmi_handle *qmi,586				      struct sockaddr_qrtr *sq)587{588	struct socket *sock;589	int ret;590 591	ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,592			       PF_QIPCRTR, &sock);593	if (ret < 0)594		return ERR_PTR(ret);595 596	ret = kernel_getsockname(sock, (struct sockaddr *)sq);597	if (ret < 0) {598		sock_release(sock);599		return ERR_PTR(ret);600	}601 602	sock->sk->sk_user_data = qmi;603	sock->sk->sk_data_ready = qmi_data_ready;604	sock->sk->sk_error_report = qmi_data_ready;605 606	return sock;607}608 609/**610 * qmi_handle_init() - initialize a QMI client handle611 * @qmi:	QMI handle to initialize612 * @recv_buf_size: maximum size of incoming message613 * @ops:	reference to callbacks for QRTR notifications614 * @handlers:	NULL-terminated list of QMI message handlers615 *616 * This initializes the QMI client handle to allow sending and receiving QMI617 * messages. As messages are received the appropriate handler will be invoked.618 *619 * Return: 0 on success, negative errno on failure.620 */621int qmi_handle_init(struct qmi_handle *qmi, size_t recv_buf_size,622		    const struct qmi_ops *ops,623		    const struct qmi_msg_handler *handlers)624{625	int ret;626 627	mutex_init(&qmi->txn_lock);628	mutex_init(&qmi->sock_lock);629 630	idr_init(&qmi->txns);631 632	INIT_LIST_HEAD(&qmi->lookups);633	INIT_LIST_HEAD(&qmi->lookup_results);634	INIT_LIST_HEAD(&qmi->services);635 636	INIT_WORK(&qmi->work, qmi_data_ready_work);637 638	qmi->handlers = handlers;639	if (ops)640		qmi->ops = *ops;641 642	/* Make room for the header */643	recv_buf_size += sizeof(struct qmi_header);644	/* Must also be sufficient to hold a control packet */645	if (recv_buf_size < sizeof(struct qrtr_ctrl_pkt))646		recv_buf_size = sizeof(struct qrtr_ctrl_pkt);647 648	qmi->recv_buf_size = recv_buf_size;649	qmi->recv_buf = kzalloc(recv_buf_size, GFP_KERNEL);650	if (!qmi->recv_buf)651		return -ENOMEM;652 653	qmi->wq = alloc_ordered_workqueue("qmi_msg_handler", 0);654	if (!qmi->wq) {655		ret = -ENOMEM;656		goto err_free_recv_buf;657	}658 659	qmi->sock = qmi_sock_create(qmi, &qmi->sq);660	if (IS_ERR(qmi->sock)) {661		if (PTR_ERR(qmi->sock) == -EAFNOSUPPORT) {662			ret = -EPROBE_DEFER;663		} else {664			pr_err("failed to create QMI socket\n");665			ret = PTR_ERR(qmi->sock);666		}667		goto err_destroy_wq;668	}669 670	return 0;671 672err_destroy_wq:673	destroy_workqueue(qmi->wq);674err_free_recv_buf:675	kfree(qmi->recv_buf);676 677	return ret;678}679EXPORT_SYMBOL_GPL(qmi_handle_init);680 681/**682 * qmi_handle_release() - release the QMI client handle683 * @qmi:	QMI client handle684 *685 * This closes the underlying socket and stops any handling of QMI messages.686 */687void qmi_handle_release(struct qmi_handle *qmi)688{689	struct socket *sock = qmi->sock;690	struct qmi_service *svc, *tmp;691 692	sock->sk->sk_user_data = NULL;693	cancel_work_sync(&qmi->work);694 695	qmi_recv_del_server(qmi, -1, -1);696 697	mutex_lock(&qmi->sock_lock);698	sock_release(sock);699	qmi->sock = NULL;700	mutex_unlock(&qmi->sock_lock);701 702	destroy_workqueue(qmi->wq);703 704	idr_destroy(&qmi->txns);705 706	kfree(qmi->recv_buf);707 708	/* Free registered lookup requests */709	list_for_each_entry_safe(svc, tmp, &qmi->lookups, list_node) {710		list_del(&svc->list_node);711		kfree(svc);712	}713 714	/* Free registered service information */715	list_for_each_entry_safe(svc, tmp, &qmi->services, list_node) {716		list_del(&svc->list_node);717		kfree(svc);718	}719}720EXPORT_SYMBOL_GPL(qmi_handle_release);721 722/**723 * qmi_send_message() - send a QMI message724 * @qmi:	QMI client handle725 * @sq:		destination sockaddr726 * @txn:	transaction object to use for the message727 * @type:	type of message to send728 * @msg_id:	message id729 * @len:	max length of the QMI message730 * @ei:		QMI message description731 * @c_struct:	object to be encoded732 *733 * This function encodes @c_struct using @ei into a message of type @type,734 * with @msg_id and @txn into a buffer of maximum size @len, and sends this to735 * @sq.736 *737 * Return: 0 on success, negative errno on failure.738 */739static ssize_t qmi_send_message(struct qmi_handle *qmi,740				struct sockaddr_qrtr *sq, struct qmi_txn *txn,741				int type, int msg_id, size_t len,742				const struct qmi_elem_info *ei,743				const void *c_struct)744{745	struct msghdr msghdr = {};746	struct kvec iv;747	void *msg;748	int ret;749 750	msg = qmi_encode_message(type,751				 msg_id, &len,752				 txn->id, ei,753				 c_struct);754	if (IS_ERR(msg))755		return PTR_ERR(msg);756 757	iv.iov_base = msg;758	iv.iov_len = len;759 760	if (sq) {761		msghdr.msg_name = sq;762		msghdr.msg_namelen = sizeof(*sq);763	}764 765	mutex_lock(&qmi->sock_lock);766	if (qmi->sock) {767		ret = kernel_sendmsg(qmi->sock, &msghdr, &iv, 1, len);768		if (ret < 0)769			pr_err("failed to send QMI message\n");770	} else {771		ret = -EPIPE;772	}773	mutex_unlock(&qmi->sock_lock);774 775	kfree(msg);776 777	return ret < 0 ? ret : 0;778}779 780/**781 * qmi_send_request() - send a request QMI message782 * @qmi:	QMI client handle783 * @sq:		destination sockaddr784 * @txn:	transaction object to use for the message785 * @msg_id:	message id786 * @len:	max length of the QMI message787 * @ei:		QMI message description788 * @c_struct:	object to be encoded789 *790 * Return: 0 on success, negative errno on failure.791 */792ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,793			 struct qmi_txn *txn, int msg_id, size_t len,794			 const struct qmi_elem_info *ei, const void *c_struct)795{796	return qmi_send_message(qmi, sq, txn, QMI_REQUEST, msg_id, len, ei,797				c_struct);798}799EXPORT_SYMBOL_GPL(qmi_send_request);800 801/**802 * qmi_send_response() - send a response QMI message803 * @qmi:	QMI client handle804 * @sq:		destination sockaddr805 * @txn:	transaction object to use for the message806 * @msg_id:	message id807 * @len:	max length of the QMI message808 * @ei:		QMI message description809 * @c_struct:	object to be encoded810 *811 * Return: 0 on success, negative errno on failure.812 */813ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,814			  struct qmi_txn *txn, int msg_id, size_t len,815			  const struct qmi_elem_info *ei, const void *c_struct)816{817	return qmi_send_message(qmi, sq, txn, QMI_RESPONSE, msg_id, len, ei,818				c_struct);819}820EXPORT_SYMBOL_GPL(qmi_send_response);821 822/**823 * qmi_send_indication() - send an indication QMI message824 * @qmi:	QMI client handle825 * @sq:		destination sockaddr826 * @msg_id:	message id827 * @len:	max length of the QMI message828 * @ei:		QMI message description829 * @c_struct:	object to be encoded830 *831 * Return: 0 on success, negative errno on failure.832 */833ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,834			    int msg_id, size_t len,835			    const struct qmi_elem_info *ei,836			    const void *c_struct)837{838	struct qmi_txn txn;839	ssize_t rval;840	int ret;841 842	ret = qmi_txn_init(qmi, &txn, NULL, NULL);843	if (ret < 0)844		return ret;845 846	rval = qmi_send_message(qmi, sq, &txn, QMI_INDICATION, msg_id, len, ei,847				c_struct);848 849	/* We don't care about future messages on this txn */850	qmi_txn_cancel(&txn);851 852	return rval;853}854EXPORT_SYMBOL_GPL(qmi_send_indication);855