Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2003 Evgeniy Polyakov <zbr@ioremap.net>
0004  */
0005 
0006 #include <linux/slab.h>
0007 #include <linux/skbuff.h>
0008 #include <linux/netlink.h>
0009 #include <linux/connector.h>
0010 
0011 #include "w1_internal.h"
0012 #include "w1_netlink.h"
0013 
0014 #if defined(CONFIG_W1_CON) && (defined(CONFIG_CONNECTOR) || (defined(CONFIG_CONNECTOR_MODULE) && defined(CONFIG_W1_MODULE)))
0015 
0016 /* Bundle together everything required to process a request in one memory
0017  * allocation.
0018  */
0019 struct w1_cb_block {
0020     atomic_t refcnt;
0021     u32 portid; /* Sending process port ID */
0022     /* maximum value for first_cn->len */
0023     u16 maxlen;
0024     /* pointers to building up the reply message */
0025     struct cn_msg *first_cn; /* fixed once the structure is populated */
0026     struct cn_msg *cn; /* advances as cn_msg is appeneded */
0027     struct w1_netlink_msg *msg; /* advances as w1_netlink_msg is appened */
0028     struct w1_netlink_cmd *cmd; /* advances as cmds are appened */
0029     struct w1_netlink_msg *cur_msg; /* currently message being processed */
0030     /* copy of the original request follows */
0031     struct cn_msg request_cn;
0032     /* followed by variable length:
0033      * cn_msg, data (w1_netlink_msg and w1_netlink_cmd)
0034      * one or more struct w1_cb_node
0035      * reply first_cn, data (w1_netlink_msg and w1_netlink_cmd)
0036      */
0037 };
0038 struct w1_cb_node {
0039     struct w1_async_cmd async;
0040     /* pointers within w1_cb_block and cn data */
0041     struct w1_cb_block *block;
0042     struct w1_netlink_msg *msg;
0043     struct w1_slave *sl;
0044     struct w1_master *dev;
0045 };
0046 
0047 /**
0048  * w1_reply_len() - calculate current reply length, compare to maxlen
0049  * @block: block to calculate
0050  *
0051  * Calculates the current message length including possible multiple
0052  * cn_msg and data, excludes the first sizeof(struct cn_msg).  Direclty
0053  * compariable to maxlen and usable to send the message.
0054  */
0055 static u16 w1_reply_len(struct w1_cb_block *block)
0056 {
0057     if (!block->cn)
0058         return 0;
0059     return (u8 *)block->cn - (u8 *)block->first_cn + block->cn->len;
0060 }
0061 
0062 static void w1_unref_block(struct w1_cb_block *block)
0063 {
0064     if (atomic_sub_return(1, &block->refcnt) == 0) {
0065         u16 len = w1_reply_len(block);
0066         if (len) {
0067             cn_netlink_send_mult(block->first_cn, len,
0068                 block->portid, 0, GFP_KERNEL);
0069         }
0070         kfree(block);
0071     }
0072 }
0073 
0074 /**
0075  * w1_reply_make_space() - send message if needed to make space
0076  * @block: block to make space on
0077  * @space: how many bytes requested
0078  *
0079  * Verify there is enough room left for the caller to add "space" bytes to the
0080  * message, if there isn't send the message and reset.
0081  */
0082 static void w1_reply_make_space(struct w1_cb_block *block, u16 space)
0083 {
0084     u16 len = w1_reply_len(block);
0085     if (len + space >= block->maxlen) {
0086         cn_netlink_send_mult(block->first_cn, len, block->portid, 0, GFP_KERNEL);
0087         block->first_cn->len = 0;
0088         block->cn = NULL;
0089         block->msg = NULL;
0090         block->cmd = NULL;
0091     }
0092 }
0093 
0094 /* Early send when replies aren't bundled. */
0095 static void w1_netlink_check_send(struct w1_cb_block *block)
0096 {
0097     if (!(block->request_cn.flags & W1_CN_BUNDLE) && block->cn)
0098         w1_reply_make_space(block, block->maxlen);
0099 }
0100 
0101 /**
0102  * w1_netlink_setup_msg() - prepare to write block->msg
0103  * @block: block to operate on
0104  * @ack: determines if cn can be reused
0105  *
0106  * block->cn will be setup with the correct ack, advancing if needed
0107  * block->cn->len does not include space for block->msg
0108  * block->msg advances but remains uninitialized
0109  */
0110 static void w1_netlink_setup_msg(struct w1_cb_block *block, u32 ack)
0111 {
0112     if (block->cn && block->cn->ack == ack) {
0113         block->msg = (struct w1_netlink_msg *)(block->cn->data + block->cn->len);
0114     } else {
0115         /* advance or set to data */
0116         if (block->cn)
0117             block->cn = (struct cn_msg *)(block->cn->data +
0118                 block->cn->len);
0119         else
0120             block->cn = block->first_cn;
0121 
0122         memcpy(block->cn, &block->request_cn, sizeof(*block->cn));
0123         block->cn->len = 0;
0124         block->cn->ack = ack;
0125         block->msg = (struct w1_netlink_msg *)block->cn->data;
0126     }
0127 }
0128 
0129 /* Append cmd to msg, include cmd->data as well.  This is because
0130  * any following data goes with the command and in the case of a read is
0131  * the results.
0132  */
0133 static void w1_netlink_queue_cmd(struct w1_cb_block *block,
0134     struct w1_netlink_cmd *cmd)
0135 {
0136     u32 space;
0137     w1_reply_make_space(block, sizeof(struct cn_msg) +
0138         sizeof(struct w1_netlink_msg) + sizeof(*cmd) + cmd->len);
0139 
0140     /* There's a status message sent after each command, so no point
0141      * in trying to bundle this cmd after an existing one, because
0142      * there won't be one.  Allocate and copy over a new cn_msg.
0143      */
0144     w1_netlink_setup_msg(block, block->request_cn.seq + 1);
0145     memcpy(block->msg, block->cur_msg, sizeof(*block->msg));
0146     block->cn->len += sizeof(*block->msg);
0147     block->msg->len = 0;
0148     block->cmd = (struct w1_netlink_cmd *)(block->msg->data);
0149 
0150     space = sizeof(*cmd) + cmd->len;
0151     if (block->cmd != cmd)
0152         memcpy(block->cmd, cmd, space);
0153     block->cn->len += space;
0154     block->msg->len += space;
0155 }
0156 
0157 /* Append req_msg and req_cmd, no other commands and no data from req_cmd are
0158  * copied.
0159  */
0160 static void w1_netlink_queue_status(struct w1_cb_block *block,
0161     struct w1_netlink_msg *req_msg, struct w1_netlink_cmd *req_cmd,
0162     int error)
0163 {
0164     u16 space = sizeof(struct cn_msg) + sizeof(*req_msg) + sizeof(*req_cmd);
0165     w1_reply_make_space(block, space);
0166     w1_netlink_setup_msg(block, block->request_cn.ack);
0167 
0168     memcpy(block->msg, req_msg, sizeof(*req_msg));
0169     block->cn->len += sizeof(*req_msg);
0170     block->msg->len = 0;
0171     block->msg->status = (u8)-error;
0172     if (req_cmd) {
0173         struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)block->msg->data;
0174         memcpy(cmd, req_cmd, sizeof(*cmd));
0175         block->cn->len += sizeof(*cmd);
0176         block->msg->len += sizeof(*cmd);
0177         cmd->len = 0;
0178     }
0179     w1_netlink_check_send(block);
0180 }
0181 
0182 /**
0183  * w1_netlink_send_error() - sends the error message now
0184  * @cn: original cn_msg
0185  * @msg: original w1_netlink_msg
0186  * @portid: where to send it
0187  * @error: error status
0188  *
0189  * Use when a block isn't available to queue the message to and cn, msg
0190  * might not be contiguous.
0191  */
0192 static void w1_netlink_send_error(struct cn_msg *cn, struct w1_netlink_msg *msg,
0193     int portid, int error)
0194 {
0195     struct {
0196         struct cn_msg cn;
0197         struct w1_netlink_msg msg;
0198     } packet;
0199     memcpy(&packet.cn, cn, sizeof(packet.cn));
0200     memcpy(&packet.msg, msg, sizeof(packet.msg));
0201     packet.cn.len = sizeof(packet.msg);
0202     packet.msg.len = 0;
0203     packet.msg.status = (u8)-error;
0204     cn_netlink_send(&packet.cn, portid, 0, GFP_KERNEL);
0205 }
0206 
0207 /**
0208  * w1_netlink_send() - sends w1 netlink notifications
0209  * @dev: w1_master the even is associated with or for
0210  * @msg: w1_netlink_msg message to be sent
0211  *
0212  * This are notifications generated from the kernel.
0213  */
0214 void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
0215 {
0216     struct {
0217         struct cn_msg cn;
0218         struct w1_netlink_msg msg;
0219     } packet;
0220     memset(&packet, 0, sizeof(packet));
0221 
0222     packet.cn.id.idx = CN_W1_IDX;
0223     packet.cn.id.val = CN_W1_VAL;
0224 
0225     packet.cn.seq = dev->seq++;
0226     packet.cn.len = sizeof(*msg);
0227 
0228     memcpy(&packet.msg, msg, sizeof(*msg));
0229     packet.msg.len = 0;
0230 
0231     cn_netlink_send(&packet.cn, 0, 0, GFP_KERNEL);
0232 }
0233 
0234 static void w1_send_slave(struct w1_master *dev, u64 rn)
0235 {
0236     struct w1_cb_block *block = dev->priv;
0237     struct w1_netlink_cmd *cache_cmd = block->cmd;
0238     u64 *data;
0239 
0240     w1_reply_make_space(block, sizeof(*data));
0241 
0242     /* Add cmd back if the packet was sent */
0243     if (!block->cmd) {
0244         cache_cmd->len = 0;
0245         w1_netlink_queue_cmd(block, cache_cmd);
0246     }
0247 
0248     data = (u64 *)(block->cmd->data + block->cmd->len);
0249 
0250     *data = rn;
0251     block->cn->len += sizeof(*data);
0252     block->msg->len += sizeof(*data);
0253     block->cmd->len += sizeof(*data);
0254 }
0255 
0256 static void w1_found_send_slave(struct w1_master *dev, u64 rn)
0257 {
0258     /* update kernel slave list */
0259     w1_slave_found(dev, rn);
0260 
0261     w1_send_slave(dev, rn);
0262 }
0263 
0264 /* Get the current slave list, or search (with or without alarm) */
0265 static int w1_get_slaves(struct w1_master *dev, struct w1_netlink_cmd *req_cmd)
0266 {
0267     struct w1_slave *sl;
0268 
0269     req_cmd->len = 0;
0270     w1_netlink_queue_cmd(dev->priv, req_cmd);
0271 
0272     if (req_cmd->cmd == W1_CMD_LIST_SLAVES) {
0273         u64 rn;
0274         mutex_lock(&dev->list_mutex);
0275         list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
0276             memcpy(&rn, &sl->reg_num, sizeof(rn));
0277             w1_send_slave(dev, rn);
0278         }
0279         mutex_unlock(&dev->list_mutex);
0280     } else {
0281         w1_search_process_cb(dev, req_cmd->cmd == W1_CMD_ALARM_SEARCH ?
0282             W1_ALARM_SEARCH : W1_SEARCH, w1_found_send_slave);
0283     }
0284 
0285     return 0;
0286 }
0287 
0288 static int w1_process_command_io(struct w1_master *dev,
0289     struct w1_netlink_cmd *cmd)
0290 {
0291     int err = 0;
0292 
0293     switch (cmd->cmd) {
0294     case W1_CMD_TOUCH:
0295         w1_touch_block(dev, cmd->data, cmd->len);
0296         w1_netlink_queue_cmd(dev->priv, cmd);
0297         break;
0298     case W1_CMD_READ:
0299         w1_read_block(dev, cmd->data, cmd->len);
0300         w1_netlink_queue_cmd(dev->priv, cmd);
0301         break;
0302     case W1_CMD_WRITE:
0303         w1_write_block(dev, cmd->data, cmd->len);
0304         break;
0305     default:
0306         err = -EINVAL;
0307         break;
0308     }
0309 
0310     return err;
0311 }
0312 
0313 static int w1_process_command_addremove(struct w1_master *dev,
0314     struct w1_netlink_cmd *cmd)
0315 {
0316     struct w1_slave *sl;
0317     int err = 0;
0318     struct w1_reg_num *id;
0319 
0320     if (cmd->len != sizeof(*id))
0321         return -EINVAL;
0322 
0323     id = (struct w1_reg_num *)cmd->data;
0324 
0325     sl = w1_slave_search_device(dev, id);
0326     switch (cmd->cmd) {
0327     case W1_CMD_SLAVE_ADD:
0328         if (sl)
0329             err = -EINVAL;
0330         else
0331             err = w1_attach_slave_device(dev, id);
0332         break;
0333     case W1_CMD_SLAVE_REMOVE:
0334         if (sl)
0335             w1_slave_detach(sl);
0336         else
0337             err = -EINVAL;
0338         break;
0339     default:
0340         err = -EINVAL;
0341         break;
0342     }
0343 
0344     return err;
0345 }
0346 
0347 static int w1_process_command_master(struct w1_master *dev,
0348     struct w1_netlink_cmd *req_cmd)
0349 {
0350     int err = -EINVAL;
0351 
0352     /* drop bus_mutex for search (does it's own locking), and add/remove
0353      * which doesn't use the bus
0354      */
0355     switch (req_cmd->cmd) {
0356     case W1_CMD_SEARCH:
0357     case W1_CMD_ALARM_SEARCH:
0358     case W1_CMD_LIST_SLAVES:
0359         mutex_unlock(&dev->bus_mutex);
0360         err = w1_get_slaves(dev, req_cmd);
0361         mutex_lock(&dev->bus_mutex);
0362         break;
0363     case W1_CMD_READ:
0364     case W1_CMD_WRITE:
0365     case W1_CMD_TOUCH:
0366         err = w1_process_command_io(dev, req_cmd);
0367         break;
0368     case W1_CMD_RESET:
0369         err = w1_reset_bus(dev);
0370         break;
0371     case W1_CMD_SLAVE_ADD:
0372     case W1_CMD_SLAVE_REMOVE:
0373         mutex_unlock(&dev->bus_mutex);
0374         mutex_lock(&dev->mutex);
0375         err = w1_process_command_addremove(dev, req_cmd);
0376         mutex_unlock(&dev->mutex);
0377         mutex_lock(&dev->bus_mutex);
0378         break;
0379     default:
0380         err = -EINVAL;
0381         break;
0382     }
0383 
0384     return err;
0385 }
0386 
0387 static int w1_process_command_slave(struct w1_slave *sl,
0388         struct w1_netlink_cmd *cmd)
0389 {
0390     dev_dbg(&sl->master->dev, "%s: %02x.%012llx.%02x: cmd=%02x, len=%u.\n",
0391         __func__, sl->reg_num.family, (unsigned long long)sl->reg_num.id,
0392         sl->reg_num.crc, cmd->cmd, cmd->len);
0393 
0394     return w1_process_command_io(sl->master, cmd);
0395 }
0396 
0397 static int w1_process_command_root(struct cn_msg *req_cn, u32 portid)
0398 {
0399     struct w1_master *dev;
0400     struct cn_msg *cn;
0401     struct w1_netlink_msg *msg;
0402     u32 *id;
0403 
0404     cn = kmalloc(PAGE_SIZE, GFP_KERNEL);
0405     if (!cn)
0406         return -ENOMEM;
0407 
0408     cn->id.idx = CN_W1_IDX;
0409     cn->id.val = CN_W1_VAL;
0410 
0411     cn->seq = req_cn->seq;
0412     cn->ack = req_cn->seq + 1;
0413     cn->len = sizeof(struct w1_netlink_msg);
0414     msg = (struct w1_netlink_msg *)cn->data;
0415 
0416     msg->type = W1_LIST_MASTERS;
0417     msg->status = 0;
0418     msg->len = 0;
0419     id = (u32 *)msg->data;
0420 
0421     mutex_lock(&w1_mlock);
0422     list_for_each_entry(dev, &w1_masters, w1_master_entry) {
0423         if (cn->len + sizeof(*id) > PAGE_SIZE - sizeof(struct cn_msg)) {
0424             cn_netlink_send(cn, portid, 0, GFP_KERNEL);
0425             cn->len = sizeof(struct w1_netlink_msg);
0426             msg->len = 0;
0427             id = (u32 *)msg->data;
0428         }
0429 
0430         *id = dev->id;
0431         msg->len += sizeof(*id);
0432         cn->len += sizeof(*id);
0433         id++;
0434     }
0435     cn_netlink_send(cn, portid, 0, GFP_KERNEL);
0436     mutex_unlock(&w1_mlock);
0437 
0438     kfree(cn);
0439     return 0;
0440 }
0441 
0442 static void w1_process_cb(struct w1_master *dev, struct w1_async_cmd *async_cmd)
0443 {
0444     struct w1_cb_node *node = container_of(async_cmd, struct w1_cb_node,
0445         async);
0446     u16 mlen = node->msg->len;
0447     u16 len;
0448     int err = 0;
0449     struct w1_slave *sl = node->sl;
0450     struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)node->msg->data;
0451 
0452     mutex_lock(&dev->bus_mutex);
0453     dev->priv = node->block;
0454     if (sl && w1_reset_select_slave(sl))
0455         err = -ENODEV;
0456     node->block->cur_msg = node->msg;
0457 
0458     while (mlen && !err) {
0459         if (cmd->len + sizeof(struct w1_netlink_cmd) > mlen) {
0460             err = -E2BIG;
0461             break;
0462         }
0463 
0464         if (sl)
0465             err = w1_process_command_slave(sl, cmd);
0466         else
0467             err = w1_process_command_master(dev, cmd);
0468         w1_netlink_check_send(node->block);
0469 
0470         w1_netlink_queue_status(node->block, node->msg, cmd, err);
0471         err = 0;
0472 
0473         len = sizeof(*cmd) + cmd->len;
0474         cmd = (struct w1_netlink_cmd *)((u8 *)cmd + len);
0475         mlen -= len;
0476     }
0477 
0478     if (!cmd || err)
0479         w1_netlink_queue_status(node->block, node->msg, cmd, err);
0480 
0481     /* ref taken in w1_search_slave or w1_search_master_id when building
0482      * the block
0483      */
0484     if (sl)
0485         w1_unref_slave(sl);
0486     else
0487         atomic_dec(&dev->refcnt);
0488     dev->priv = NULL;
0489     mutex_unlock(&dev->bus_mutex);
0490 
0491     mutex_lock(&dev->list_mutex);
0492     list_del(&async_cmd->async_entry);
0493     mutex_unlock(&dev->list_mutex);
0494 
0495     w1_unref_block(node->block);
0496 }
0497 
0498 static void w1_list_count_cmds(struct w1_netlink_msg *msg, int *cmd_count,
0499     u16 *slave_len)
0500 {
0501     struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)msg->data;
0502     u16 mlen = msg->len;
0503     u16 len;
0504     int slave_list = 0;
0505     while (mlen) {
0506         if (cmd->len + sizeof(struct w1_netlink_cmd) > mlen)
0507             break;
0508 
0509         switch (cmd->cmd) {
0510         case W1_CMD_SEARCH:
0511         case W1_CMD_ALARM_SEARCH:
0512         case W1_CMD_LIST_SLAVES:
0513             ++slave_list;
0514         }
0515         ++*cmd_count;
0516         len = sizeof(*cmd) + cmd->len;
0517         cmd = (struct w1_netlink_cmd *)((u8 *)cmd + len);
0518         mlen -= len;
0519     }
0520 
0521     if (slave_list) {
0522         struct w1_master *dev = w1_search_master_id(msg->id.mst.id);
0523         if (dev) {
0524             /* Bytes, and likely an overstimate, and if it isn't
0525              * the results can still be split between packets.
0526              */
0527             *slave_len += sizeof(struct w1_reg_num) * slave_list *
0528                 (dev->slave_count + dev->max_slave_count);
0529             /* search incremented it */
0530             atomic_dec(&dev->refcnt);
0531         }
0532     }
0533 }
0534 
0535 static void w1_cn_callback(struct cn_msg *cn, struct netlink_skb_parms *nsp)
0536 {
0537     struct w1_netlink_msg *msg = (struct w1_netlink_msg *)(cn + 1);
0538     struct w1_slave *sl;
0539     struct w1_master *dev;
0540     u16 msg_len;
0541     u16 slave_len = 0;
0542     int err = 0;
0543     struct w1_cb_block *block = NULL;
0544     struct w1_cb_node *node = NULL;
0545     int node_count = 0;
0546     int cmd_count = 0;
0547 
0548     /* If any unknown flag is set let the application know, that way
0549      * applications can detect the absence of features in kernels that
0550      * don't know about them.  http://lwn.net/Articles/587527/
0551      */
0552     if (cn->flags & ~(W1_CN_BUNDLE)) {
0553         w1_netlink_send_error(cn, msg, nsp->portid, -EINVAL);
0554         return;
0555     }
0556 
0557     /* Count the number of master or slave commands there are to allocate
0558      * space for one cb_node each.
0559      */
0560     msg_len = cn->len;
0561     while (msg_len && !err) {
0562         if (msg->len + sizeof(struct w1_netlink_msg) > msg_len) {
0563             err = -E2BIG;
0564             break;
0565         }
0566 
0567         /* count messages for nodes and allocate any additional space
0568          * required for slave lists
0569          */
0570         if (msg->type == W1_MASTER_CMD || msg->type == W1_SLAVE_CMD) {
0571             ++node_count;
0572             w1_list_count_cmds(msg, &cmd_count, &slave_len);
0573         }
0574 
0575         msg_len -= sizeof(struct w1_netlink_msg) + msg->len;
0576         msg = (struct w1_netlink_msg *)(((u8 *)msg) +
0577             sizeof(struct w1_netlink_msg) + msg->len);
0578     }
0579     msg = (struct w1_netlink_msg *)(cn + 1);
0580     if (node_count) {
0581         int size;
0582         int reply_size = sizeof(*cn) + cn->len + slave_len;
0583         if (cn->flags & W1_CN_BUNDLE) {
0584             /* bundling duplicats some of the messages */
0585             reply_size += 2 * cmd_count * (sizeof(struct cn_msg) +
0586                 sizeof(struct w1_netlink_msg) +
0587                 sizeof(struct w1_netlink_cmd));
0588         }
0589         reply_size = min(CONNECTOR_MAX_MSG_SIZE, reply_size);
0590 
0591         /* allocate space for the block, a copy of the original message,
0592          * one node per cmd to point into the original message,
0593          * space for replies which is the original message size plus
0594          * space for any list slave data and status messages
0595          * cn->len doesn't include itself which is part of the block
0596          * */
0597         size =  /* block + original message */
0598             sizeof(struct w1_cb_block) + sizeof(*cn) + cn->len +
0599             /* space for nodes */
0600             node_count * sizeof(struct w1_cb_node) +
0601             /* replies */
0602             sizeof(struct cn_msg) + reply_size;
0603         block = kzalloc(size, GFP_KERNEL);
0604         if (!block) {
0605             /* if the system is already out of memory,
0606              * (A) will this work, and (B) would it be better
0607              * to not try?
0608              */
0609             w1_netlink_send_error(cn, msg, nsp->portid, -ENOMEM);
0610             return;
0611         }
0612         atomic_set(&block->refcnt, 1);
0613         block->portid = nsp->portid;
0614         memcpy(&block->request_cn, cn, sizeof(*cn) + cn->len);
0615         node = (struct w1_cb_node *)(block->request_cn.data + cn->len);
0616 
0617         /* Sneeky, when not bundling, reply_size is the allocated space
0618          * required for the reply, cn_msg isn't part of maxlen so
0619          * it should be reply_size - sizeof(struct cn_msg), however
0620          * when checking if there is enough space, w1_reply_make_space
0621          * is called with the full message size including cn_msg,
0622          * because it isn't known at that time if an additional cn_msg
0623          * will need to be allocated.  So an extra cn_msg is added
0624          * above in "size".
0625          */
0626         block->maxlen = reply_size;
0627         block->first_cn = (struct cn_msg *)(node + node_count);
0628         memset(block->first_cn, 0, sizeof(*block->first_cn));
0629     }
0630 
0631     msg_len = cn->len;
0632     while (msg_len && !err) {
0633 
0634         dev = NULL;
0635         sl = NULL;
0636 
0637         if (msg->len + sizeof(struct w1_netlink_msg) > msg_len) {
0638             err = -E2BIG;
0639             break;
0640         }
0641 
0642         /* execute on this thread, no need to process later */
0643         if (msg->type == W1_LIST_MASTERS) {
0644             err = w1_process_command_root(cn, nsp->portid);
0645             goto out_cont;
0646         }
0647 
0648         /* All following message types require additional data,
0649          * check here before references are taken.
0650          */
0651         if (!msg->len) {
0652             err = -EPROTO;
0653             goto out_cont;
0654         }
0655 
0656         /* both search calls take references */
0657         if (msg->type == W1_MASTER_CMD) {
0658             dev = w1_search_master_id(msg->id.mst.id);
0659         } else if (msg->type == W1_SLAVE_CMD) {
0660             sl = w1_search_slave((struct w1_reg_num *)msg->id.id);
0661             if (sl)
0662                 dev = sl->master;
0663         } else {
0664             pr_notice("%s: cn: %x.%x, wrong type: %u, len: %u.\n",
0665                 __func__, cn->id.idx, cn->id.val,
0666                 msg->type, msg->len);
0667             err = -EPROTO;
0668             goto out_cont;
0669         }
0670 
0671         if (!dev) {
0672             err = -ENODEV;
0673             goto out_cont;
0674         }
0675 
0676         err = 0;
0677 
0678         atomic_inc(&block->refcnt);
0679         node->async.cb = w1_process_cb;
0680         node->block = block;
0681         node->msg = (struct w1_netlink_msg *)((u8 *)&block->request_cn +
0682             (size_t)((u8 *)msg - (u8 *)cn));
0683         node->sl = sl;
0684         node->dev = dev;
0685 
0686         mutex_lock(&dev->list_mutex);
0687         list_add_tail(&node->async.async_entry, &dev->async_list);
0688         wake_up_process(dev->thread);
0689         mutex_unlock(&dev->list_mutex);
0690         ++node;
0691 
0692 out_cont:
0693         /* Can't queue because that modifies block and another
0694          * thread could be processing the messages by now and
0695          * there isn't a lock, send directly.
0696          */
0697         if (err)
0698             w1_netlink_send_error(cn, msg, nsp->portid, err);
0699         msg_len -= sizeof(struct w1_netlink_msg) + msg->len;
0700         msg = (struct w1_netlink_msg *)(((u8 *)msg) +
0701             sizeof(struct w1_netlink_msg) + msg->len);
0702 
0703         /*
0704          * Let's allow requests for nonexisting devices.
0705          */
0706         if (err == -ENODEV)
0707             err = 0;
0708     }
0709     if (block)
0710         w1_unref_block(block);
0711 }
0712 
0713 int w1_init_netlink(void)
0714 {
0715     struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL};
0716 
0717     return cn_add_callback(&w1_id, "w1", &w1_cn_callback);
0718 }
0719 
0720 void w1_fini_netlink(void)
0721 {
0722     struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL};
0723 
0724     cn_del_callback(&w1_id);
0725 }
0726 #else
0727 void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *cn)
0728 {
0729 }
0730 
0731 int w1_init_netlink(void)
0732 {
0733     return 0;
0734 }
0735 
0736 void w1_fini_netlink(void)
0737 {
0738 }
0739 #endif