Commit 3b8384070ea1dc358f6da6233b3b6c0926ae1bf4

Authored by Evgeniy Polyakov
Committed by Linus Torvalds
1 parent 9be62e0b2f

w1: list slaves commands

Initiates search (or alarm search) and returns all found devices to
userspace.  Found devices are not added into the system (i.e.  they are
not attached to family devices or bus masters), it will be done via (if
was not done yet) usual timed searching.

Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 85 additions and 17 deletions Side-by-side Diff

drivers/w1/w1_netlink.c
... ... @@ -47,19 +47,97 @@
47 47 cn_netlink_send(m, 0, GFP_KERNEL);
48 48 }
49 49  
50   -static int w1_process_command_master(struct w1_master *dev, struct cn_msg *msg,
51   - struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd)
  50 +static void w1_send_slave(struct w1_master *dev, u64 rn)
52 51 {
53   - dev_dbg(&dev->dev, "%s: %s: cmd=%02x, len=%u.\n",
54   - __func__, dev->name, cmd->cmd, cmd->len);
  52 + struct cn_msg *msg = dev->priv;
  53 + struct w1_netlink_msg *hdr = (struct w1_netlink_msg *)(msg + 1);
  54 + struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)(hdr + 1);
  55 + int avail;
55 56  
56   - if (cmd->cmd != W1_CMD_SEARCH && cmd->cmd != W1_CMD_ALARM_SEARCH)
57   - return -EINVAL;
  57 + avail = dev->priv_size - cmd->len;
58 58  
59   - w1_search_process(dev, (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH);
  59 + if (avail > 8) {
  60 + u64 *data = (void *)(cmd + 1) + cmd->len;
  61 +
  62 + *data = rn;
  63 + cmd->len += 8;
  64 + hdr->len += 8;
  65 + msg->len += 8;
  66 + return;
  67 + }
  68 +
  69 + msg->ack++;
  70 + cn_netlink_send(msg, 0, GFP_KERNEL);
  71 +
  72 + msg->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd);
  73 + hdr->len = sizeof(struct w1_netlink_cmd);
  74 + cmd->len = 0;
  75 +}
  76 +
  77 +static int w1_process_search_command(struct w1_master *dev, struct cn_msg *msg,
  78 + unsigned int avail)
  79 +{
  80 + struct w1_netlink_msg *hdr = (struct w1_netlink_msg *)(msg + 1);
  81 + struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)(hdr + 1);
  82 + int search_type = (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH;
  83 +
  84 + dev->priv = msg;
  85 + dev->priv_size = avail;
  86 +
  87 + w1_search_devices(dev, search_type, w1_send_slave);
  88 +
  89 + msg->ack = 0;
  90 + cn_netlink_send(msg, 0, GFP_KERNEL);
  91 +
  92 + dev->priv = NULL;
  93 + dev->priv_size = 0;
  94 +
60 95 return 0;
61 96 }
62 97  
  98 +static int w1_process_command_master(struct w1_master *dev, struct cn_msg *req_msg,
  99 + struct w1_netlink_msg *req_hdr, struct w1_netlink_cmd *req_cmd)
  100 +{
  101 + int err = -EINVAL;
  102 + struct cn_msg *msg;
  103 + struct w1_netlink_msg *hdr;
  104 + struct w1_netlink_cmd *cmd;
  105 +
  106 + msg = kzalloc(PAGE_SIZE, GFP_KERNEL);
  107 + if (!msg)
  108 + return -ENOMEM;
  109 +
  110 + msg->id = req_msg->id;
  111 + msg->seq = req_msg->seq;
  112 + msg->ack = 0;
  113 + msg->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd);
  114 +
  115 + hdr = (struct w1_netlink_msg *)(msg + 1);
  116 + cmd = (struct w1_netlink_cmd *)(hdr + 1);
  117 +
  118 + hdr->type = W1_MASTER_CMD;
  119 + hdr->id = req_hdr->id;
  120 + hdr->len = sizeof(struct w1_netlink_cmd);
  121 +
  122 + cmd->cmd = req_cmd->cmd;
  123 + cmd->len = 0;
  124 +
  125 + switch (cmd->cmd) {
  126 + case W1_CMD_SEARCH:
  127 + case W1_CMD_ALARM_SEARCH:
  128 + err = w1_process_search_command(dev, msg,
  129 + PAGE_SIZE - msg->len - sizeof(struct cn_msg));
  130 + break;
  131 + default:
  132 + cmd->res = EINVAL;
  133 + cn_netlink_send(msg, 0, GFP_KERNEL);
  134 + break;
  135 + }
  136 +
  137 + kfree(msg);
  138 + return err;
  139 +}
  140 +
63 141 static int w1_send_read_reply(struct w1_slave *sl, struct cn_msg *msg,
64 142 struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd)
65 143 {
... ... @@ -119,11 +197,6 @@
119 197 case W1_CMD_WRITE:
120 198 w1_write_block(sl->master, cmd->data, cmd->len);
121 199 break;
122   - case W1_CMD_SEARCH:
123   - case W1_CMD_ALARM_SEARCH:
124   - w1_search_process(sl->master,
125   - (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH);
126   - break;
127 200 default:
128 201 err = -1;
129 202 break;
... ... @@ -270,11 +343,6 @@
270 343 if (err == -ENODEV)
271 344 err = 0;
272 345 }
273   -#if 0
274   - if (err) {
275   - printk("%s: malformed message. Dropping.\n", __func__);
276   - }
277   -#endif
278 346 }
279 347  
280 348 int w1_init_netlink(void)