Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (c) 2003 Evgeniy Polyakov <zbr@ioremap.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/connector.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "w1_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "w1_netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #if defined(CONFIG_W1_CON) && (defined(CONFIG_CONNECTOR) || (defined(CONFIG_CONNECTOR_MODULE) && defined(CONFIG_W1_MODULE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) /* Bundle together everything required to process a request in one memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) struct w1_cb_block {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	atomic_t refcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	u32 portid; /* Sending process port ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	/* maximum value for first_cn->len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	u16 maxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	/* pointers to building up the reply message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	struct cn_msg *first_cn; /* fixed once the structure is populated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	struct cn_msg *cn; /* advances as cn_msg is appeneded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct w1_netlink_msg *msg; /* advances as w1_netlink_msg is appened */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct w1_netlink_cmd *cmd; /* advances as cmds are appened */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	struct w1_netlink_msg *cur_msg; /* currently message being processed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	/* copy of the original request follows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct cn_msg request_cn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	/* followed by variable length:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	 * cn_msg, data (w1_netlink_msg and w1_netlink_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	 * one or more struct w1_cb_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	 * reply first_cn, data (w1_netlink_msg and w1_netlink_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) struct w1_cb_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	struct w1_async_cmd async;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	/* pointers within w1_cb_block and cn data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct w1_cb_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct w1_netlink_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct w1_slave *sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct w1_master *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * w1_reply_len() - calculate current reply length, compare to maxlen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * @block: block to calculate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * Calculates the current message length including possible multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * cn_msg and data, excludes the first sizeof(struct cn_msg).  Direclty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * compariable to maxlen and usable to send the message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static u16 w1_reply_len(struct w1_cb_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	if (!block->cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	return (u8 *)block->cn - (u8 *)block->first_cn + block->cn->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) static void w1_unref_block(struct w1_cb_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (atomic_sub_return(1, &block->refcnt) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		u16 len = w1_reply_len(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		if (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			cn_netlink_send_mult(block->first_cn, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 				block->portid, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		kfree(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * w1_reply_make_space() - send message if needed to make space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * @block: block to make space on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * @space: how many bytes requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * Verify there is enough room left for the caller to add "space" bytes to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * message, if there isn't send the message and reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static void w1_reply_make_space(struct w1_cb_block *block, u16 space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	u16 len = w1_reply_len(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (len + space >= block->maxlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		cn_netlink_send_mult(block->first_cn, len, block->portid, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		block->first_cn->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		block->cn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		block->msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		block->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) /* Early send when replies aren't bundled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static void w1_netlink_check_send(struct w1_cb_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (!(block->request_cn.flags & W1_CN_BUNDLE) && block->cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		w1_reply_make_space(block, block->maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * w1_netlink_setup_msg() - prepare to write block->msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * @block: block to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * @ack: determines if cn can be reused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * block->cn will be setup with the correct ack, advancing if needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * block->cn->len does not include space for block->msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * block->msg advances but remains uninitialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void w1_netlink_setup_msg(struct w1_cb_block *block, u32 ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (block->cn && block->cn->ack == ack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		block->msg = (struct w1_netlink_msg *)(block->cn->data + block->cn->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		/* advance or set to data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		if (block->cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			block->cn = (struct cn_msg *)(block->cn->data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				block->cn->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			block->cn = block->first_cn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		memcpy(block->cn, &block->request_cn, sizeof(*block->cn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		block->cn->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		block->cn->ack = ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		block->msg = (struct w1_netlink_msg *)block->cn->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Append cmd to msg, include cmd->data as well.  This is because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * any following data goes with the command and in the case of a read is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * the results.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void w1_netlink_queue_cmd(struct w1_cb_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct w1_netlink_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	u32 space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	w1_reply_make_space(block, sizeof(struct cn_msg) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		sizeof(struct w1_netlink_msg) + sizeof(*cmd) + cmd->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/* There's a status message sent after each command, so no point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * in trying to bundle this cmd after an existing one, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * there won't be one.  Allocate and copy over a new cn_msg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	w1_netlink_setup_msg(block, block->request_cn.seq + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	memcpy(block->msg, block->cur_msg, sizeof(*block->msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	block->cn->len += sizeof(*block->msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	block->msg->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	block->cmd = (struct w1_netlink_cmd *)(block->msg->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	space = sizeof(*cmd) + cmd->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (block->cmd != cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		memcpy(block->cmd, cmd, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	block->cn->len += space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	block->msg->len += space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Append req_msg and req_cmd, no other commands and no data from req_cmd are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  * copied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static void w1_netlink_queue_status(struct w1_cb_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	struct w1_netlink_msg *req_msg, struct w1_netlink_cmd *req_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	u16 space = sizeof(struct cn_msg) + sizeof(*req_msg) + sizeof(*req_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	w1_reply_make_space(block, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	w1_netlink_setup_msg(block, block->request_cn.ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	memcpy(block->msg, req_msg, sizeof(*req_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	block->cn->len += sizeof(*req_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	block->msg->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	block->msg->status = (u8)-error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (req_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)block->msg->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		memcpy(cmd, req_cmd, sizeof(*cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		block->cn->len += sizeof(*cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		block->msg->len += sizeof(*cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		cmd->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	w1_netlink_check_send(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * w1_netlink_send_error() - sends the error message now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * @cn: original cn_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * @msg: original w1_netlink_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * @portid: where to send it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * @error: error status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * Use when a block isn't available to queue the message to and cn, msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * might not be contiguous.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void w1_netlink_send_error(struct cn_msg *cn, struct w1_netlink_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	int portid, int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		struct cn_msg cn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		struct w1_netlink_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	} packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	memcpy(&packet.cn, cn, sizeof(packet.cn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	memcpy(&packet.msg, msg, sizeof(packet.msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	packet.cn.len = sizeof(packet.msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	packet.msg.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	packet.msg.status = (u8)-error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	cn_netlink_send(&packet.cn, portid, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * w1_netlink_send() - sends w1 netlink notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * @dev: w1_master the even is associated with or for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * @msg: w1_netlink_msg message to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  * This are notifications generated from the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		struct cn_msg cn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		struct w1_netlink_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	} packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	memset(&packet, 0, sizeof(packet));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	packet.cn.id.idx = CN_W1_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	packet.cn.id.val = CN_W1_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	packet.cn.seq = dev->seq++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	packet.cn.len = sizeof(*msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	memcpy(&packet.msg, msg, sizeof(*msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	packet.msg.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	cn_netlink_send(&packet.cn, 0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static void w1_send_slave(struct w1_master *dev, u64 rn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct w1_cb_block *block = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	struct w1_netlink_cmd *cache_cmd = block->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	u64 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	w1_reply_make_space(block, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	/* Add cmd back if the packet was sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (!block->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		cache_cmd->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		w1_netlink_queue_cmd(block, cache_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	data = (u64 *)(block->cmd->data + block->cmd->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	*data = rn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	block->cn->len += sizeof(*data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	block->msg->len += sizeof(*data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	block->cmd->len += sizeof(*data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static void w1_found_send_slave(struct w1_master *dev, u64 rn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	/* update kernel slave list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	w1_slave_found(dev, rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	w1_send_slave(dev, rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Get the current slave list, or search (with or without alarm) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int w1_get_slaves(struct w1_master *dev, struct w1_netlink_cmd *req_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	struct w1_slave *sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	req_cmd->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	w1_netlink_queue_cmd(dev->priv, req_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (req_cmd->cmd == W1_CMD_LIST_SLAVES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		u64 rn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		mutex_lock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			memcpy(&rn, &sl->reg_num, sizeof(rn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			w1_send_slave(dev, rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		mutex_unlock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		w1_search_process_cb(dev, req_cmd->cmd == W1_CMD_ALARM_SEARCH ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			W1_ALARM_SEARCH : W1_SEARCH, w1_found_send_slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int w1_process_command_io(struct w1_master *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	struct w1_netlink_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	switch (cmd->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	case W1_CMD_TOUCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		w1_touch_block(dev, cmd->data, cmd->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		w1_netlink_queue_cmd(dev->priv, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	case W1_CMD_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		w1_read_block(dev, cmd->data, cmd->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		w1_netlink_queue_cmd(dev->priv, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	case W1_CMD_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		w1_write_block(dev, cmd->data, cmd->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int w1_process_command_addremove(struct w1_master *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct w1_netlink_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	struct w1_slave *sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct w1_reg_num *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (cmd->len != sizeof(*id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	id = (struct w1_reg_num *)cmd->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	sl = w1_slave_search_device(dev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	switch (cmd->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	case W1_CMD_SLAVE_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		if (sl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			err = w1_attach_slave_device(dev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	case W1_CMD_SLAVE_REMOVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		if (sl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			w1_slave_detach(sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int w1_process_command_master(struct w1_master *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	struct w1_netlink_cmd *req_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	/* drop bus_mutex for search (does it's own locking), and add/remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	 * which doesn't use the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	switch (req_cmd->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	case W1_CMD_SEARCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	case W1_CMD_ALARM_SEARCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	case W1_CMD_LIST_SLAVES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		mutex_unlock(&dev->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		err = w1_get_slaves(dev, req_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		mutex_lock(&dev->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	case W1_CMD_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	case W1_CMD_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	case W1_CMD_TOUCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		err = w1_process_command_io(dev, req_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	case W1_CMD_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		err = w1_reset_bus(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	case W1_CMD_SLAVE_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	case W1_CMD_SLAVE_REMOVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		mutex_unlock(&dev->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		mutex_lock(&dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		err = w1_process_command_addremove(dev, req_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		mutex_unlock(&dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		mutex_lock(&dev->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int w1_process_command_slave(struct w1_slave *sl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		struct w1_netlink_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	dev_dbg(&sl->master->dev, "%s: %02x.%012llx.%02x: cmd=%02x, len=%u.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		__func__, sl->reg_num.family, (unsigned long long)sl->reg_num.id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		sl->reg_num.crc, cmd->cmd, cmd->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	return w1_process_command_io(sl->master, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static int w1_process_command_root(struct cn_msg *req_cn, u32 portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	struct w1_master *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct cn_msg *cn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	struct w1_netlink_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	u32 *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	cn = kmalloc(PAGE_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	if (!cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	cn->id.idx = CN_W1_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	cn->id.val = CN_W1_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	cn->seq = req_cn->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	cn->ack = req_cn->seq + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	cn->len = sizeof(struct w1_netlink_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	msg = (struct w1_netlink_msg *)cn->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	msg->type = W1_LIST_MASTERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	msg->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	msg->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	id = (u32 *)msg->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	mutex_lock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	list_for_each_entry(dev, &w1_masters, w1_master_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		if (cn->len + sizeof(*id) > PAGE_SIZE - sizeof(struct cn_msg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			cn_netlink_send(cn, portid, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			cn->len = sizeof(struct w1_netlink_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			msg->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			id = (u32 *)msg->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		*id = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		msg->len += sizeof(*id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		cn->len += sizeof(*id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	cn_netlink_send(cn, portid, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	mutex_unlock(&w1_mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	kfree(cn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static void w1_process_cb(struct w1_master *dev, struct w1_async_cmd *async_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	struct w1_cb_node *node = container_of(async_cmd, struct w1_cb_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		async);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	u16 mlen = node->msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	struct w1_slave *sl = node->sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)node->msg->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	mutex_lock(&dev->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	dev->priv = node->block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	if (sl && w1_reset_select_slave(sl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	node->block->cur_msg = node->msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	while (mlen && !err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		if (cmd->len + sizeof(struct w1_netlink_cmd) > mlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			err = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		if (sl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			err = w1_process_command_slave(sl, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			err = w1_process_command_master(dev, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		w1_netlink_check_send(node->block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		w1_netlink_queue_status(node->block, node->msg, cmd, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		len = sizeof(*cmd) + cmd->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		cmd = (struct w1_netlink_cmd *)((u8 *)cmd + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		mlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	if (!cmd || err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		w1_netlink_queue_status(node->block, node->msg, cmd, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	/* ref taken in w1_search_slave or w1_search_master_id when building
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	 * the block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	if (sl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		w1_unref_slave(sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		atomic_dec(&dev->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	dev->priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	mutex_unlock(&dev->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	mutex_lock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	list_del(&async_cmd->async_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	mutex_unlock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	w1_unref_block(node->block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static void w1_list_count_cmds(struct w1_netlink_msg *msg, int *cmd_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	u16 *slave_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)msg->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	u16 mlen = msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	int slave_list = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	while (mlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		if (cmd->len + sizeof(struct w1_netlink_cmd) > mlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		switch (cmd->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		case W1_CMD_SEARCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		case W1_CMD_ALARM_SEARCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		case W1_CMD_LIST_SLAVES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			++slave_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		++*cmd_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		len = sizeof(*cmd) + cmd->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		cmd = (struct w1_netlink_cmd *)((u8 *)cmd + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		mlen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	if (slave_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		struct w1_master *dev = w1_search_master_id(msg->id.mst.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		if (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 			/* Bytes, and likely an overstimate, and if it isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			 * the results can still be split between packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			*slave_len += sizeof(struct w1_reg_num) * slave_list *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 				(dev->slave_count + dev->max_slave_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 			/* search incremented it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			atomic_dec(&dev->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static void w1_cn_callback(struct cn_msg *cn, struct netlink_skb_parms *nsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	struct w1_netlink_msg *msg = (struct w1_netlink_msg *)(cn + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	struct w1_slave *sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	struct w1_master *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	u16 msg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	u16 slave_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	struct w1_cb_block *block = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	struct w1_cb_node *node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	int node_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	int cmd_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	/* If any unknown flag is set let the application know, that way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	 * applications can detect the absence of features in kernels that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	 * don't know about them.  http://lwn.net/Articles/587527/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	if (cn->flags & ~(W1_CN_BUNDLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		w1_netlink_send_error(cn, msg, nsp->portid, -EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	/* Count the number of master or slave commands there are to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	 * space for one cb_node each.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	msg_len = cn->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	while (msg_len && !err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		if (msg->len + sizeof(struct w1_netlink_msg) > msg_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			err = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		/* count messages for nodes and allocate any additional space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		 * required for slave lists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		if (msg->type == W1_MASTER_CMD || msg->type == W1_SLAVE_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			++node_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			w1_list_count_cmds(msg, &cmd_count, &slave_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		msg_len -= sizeof(struct w1_netlink_msg) + msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		msg = (struct w1_netlink_msg *)(((u8 *)msg) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 			sizeof(struct w1_netlink_msg) + msg->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	msg = (struct w1_netlink_msg *)(cn + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (node_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		int reply_size = sizeof(*cn) + cn->len + slave_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		if (cn->flags & W1_CN_BUNDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			/* bundling duplicats some of the messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			reply_size += 2 * cmd_count * (sizeof(struct cn_msg) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 				sizeof(struct w1_netlink_msg) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 				sizeof(struct w1_netlink_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		reply_size = min(CONNECTOR_MAX_MSG_SIZE, reply_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		/* allocate space for the block, a copy of the original message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		 * one node per cmd to point into the original message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		 * space for replies which is the original message size plus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		 * space for any list slave data and status messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		 * cn->len doesn't include itself which is part of the block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		 * */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		size =  /* block + original message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			sizeof(struct w1_cb_block) + sizeof(*cn) + cn->len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 			/* space for nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			node_count * sizeof(struct w1_cb_node) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 			/* replies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			sizeof(struct cn_msg) + reply_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		block = kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		if (!block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			/* if the system is already out of memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			 * (A) will this work, and (B) would it be better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 			 * to not try?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			w1_netlink_send_error(cn, msg, nsp->portid, -ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		atomic_set(&block->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		block->portid = nsp->portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		memcpy(&block->request_cn, cn, sizeof(*cn) + cn->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		node = (struct w1_cb_node *)(block->request_cn.data + cn->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		/* Sneeky, when not bundling, reply_size is the allocated space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		 * required for the reply, cn_msg isn't part of maxlen so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		 * it should be reply_size - sizeof(struct cn_msg), however
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		 * when checking if there is enough space, w1_reply_make_space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		 * is called with the full message size including cn_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		 * because it isn't known at that time if an additional cn_msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		 * will need to be allocated.  So an extra cn_msg is added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		 * above in "size".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		block->maxlen = reply_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		block->first_cn = (struct cn_msg *)(node + node_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		memset(block->first_cn, 0, sizeof(*block->first_cn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	msg_len = cn->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	while (msg_len && !err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		sl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		if (msg->len + sizeof(struct w1_netlink_msg) > msg_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 			err = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		/* execute on this thread, no need to process later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		if (msg->type == W1_LIST_MASTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 			err = w1_process_command_root(cn, nsp->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			goto out_cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		/* All following message types require additional data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		 * check here before references are taken.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		if (!msg->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 			err = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 			goto out_cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		/* both search calls take references */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		if (msg->type == W1_MASTER_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 			dev = w1_search_master_id(msg->id.mst.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		} else if (msg->type == W1_SLAVE_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			sl = w1_search_slave((struct w1_reg_num *)msg->id.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			if (sl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 				dev = sl->master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			pr_notice("%s: cn: %x.%x, wrong type: %u, len: %u.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 				__func__, cn->id.idx, cn->id.val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 				msg->type, msg->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			err = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			goto out_cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 			err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 			goto out_cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		atomic_inc(&block->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		node->async.cb = w1_process_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		node->block = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		node->msg = (struct w1_netlink_msg *)((u8 *)&block->request_cn +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 			(size_t)((u8 *)msg - (u8 *)cn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		node->sl = sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		node->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		mutex_lock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		list_add_tail(&node->async.async_entry, &dev->async_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		wake_up_process(dev->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		mutex_unlock(&dev->list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		++node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) out_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		/* Can't queue because that modifies block and another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		 * thread could be processing the messages by now and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		 * there isn't a lock, send directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 			w1_netlink_send_error(cn, msg, nsp->portid, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 		msg_len -= sizeof(struct w1_netlink_msg) + msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		msg = (struct w1_netlink_msg *)(((u8 *)msg) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 			sizeof(struct w1_netlink_msg) + msg->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		 * Let's allow requests for nonexisting devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		if (err == -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 			err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	if (block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		w1_unref_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) int w1_init_netlink(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	return cn_add_callback(&w1_id, "w1", &w1_cn_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) void w1_fini_netlink(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	cn_del_callback(&w1_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *cn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) int w1_init_netlink(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) void w1_fini_netlink(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) #endif