- return err;
-}
-
-static void w1_cn_callback(void *data)
-{
- struct cn_msg *msg = data;
- struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1);
- struct w1_netlink_cmd *cmd;
- struct w1_slave *sl;
- struct w1_master *dev;
- int err = 0;
-
- while (msg->len && !err) {
- struct w1_reg_num id;
- u16 mlen = m->len;
- u8 *cmd_data = m->data;
-
- dev = NULL;
- sl = NULL;
-
- memcpy(&id, m->id.id, sizeof(id));
-#if 0
- printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n",
- __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len);
-#endif
- if (m->len + sizeof(struct w1_netlink_msg) > msg->len) {
- err = -E2BIG;
- break;
- }
-
- if (!mlen)
- goto out_cont;
-
- if (m->type == W1_MASTER_CMD) {
- dev = w1_search_master_id(m->id.mst.id);
- } else if (m->type == W1_SLAVE_CMD) {
- sl = w1_search_slave(&id);
- if (sl)
- dev = sl->master;
- }
-
- if (!dev) {
- err = -ENODEV;
- goto out_cont;
- }
-
- mutex_lock(&dev->mutex);
-
- if (sl && w1_reset_select_slave(sl)) {
- err = -ENODEV;
- goto out_up;
- }
-
- while (mlen) {
- cmd = (struct w1_netlink_cmd *)cmd_data;
-
- if (cmd->len + sizeof(struct w1_netlink_cmd) > mlen) {
- err = -E2BIG;
- break;
- }
-
- if (sl)
- w1_process_command_slave(sl, msg, m, cmd);
- else
- w1_process_command_master(dev, msg, m, cmd);
-
- cmd_data += cmd->len + sizeof(struct w1_netlink_cmd);
- mlen -= cmd->len + sizeof(struct w1_netlink_cmd);
- }
-out_up:
- atomic_dec(&dev->refcnt);
- if (sl)
- atomic_dec(&sl->refcnt);
- mutex_unlock(&dev->mutex);
-out_cont:
- msg->len -= sizeof(struct w1_netlink_msg) + m->len;
- m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len);
-
- /*
- * Let's allow requests for nonexisting devices.
- */
- if (err == -ENODEV)
- err = 0;
- }
-#if 0
- if (err) {
- printk("%s: malformed message. Dropping.\n", __func__);
- }
-#endif
-}
-
-int w1_init_netlink(void)
-{
- struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL};
-
- return cn_add_callback(&w1_id, "w1", &w1_cn_callback);