aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1_netlink.c
diff options
context:
space:
mode:
authorEvgeniy Polyakov <zbr@ioremap.net>2009-01-07 21:09:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-08 11:31:13 -0500
commit3b8384070ea1dc358f6da6233b3b6c0926ae1bf4 (patch)
tree00535e5b18029c95f59efb68612ff2e57bb7ac82 /drivers/w1/w1_netlink.c
parent9be62e0b2fadaf5ffeb32fd1b910ef1fe6bd43db (diff)
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>
Diffstat (limited to 'drivers/w1/w1_netlink.c')
-rw-r--r--drivers/w1/w1_netlink.c102
1 files changed, 85 insertions, 17 deletions
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index cae556c8577b..8a7021577f32 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -47,19 +47,97 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
47 cn_netlink_send(m, 0, GFP_KERNEL); 47 cn_netlink_send(m, 0, GFP_KERNEL);
48} 48}
49 49
50static int w1_process_command_master(struct w1_master *dev, struct cn_msg *msg, 50static void w1_send_slave(struct w1_master *dev, u64 rn)
51 struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) 51{
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;
56
57 avail = dev->priv_size - cmd->len;
58
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
77static int w1_process_search_command(struct w1_master *dev, struct cn_msg *msg,
78 unsigned int avail)
52{ 79{
53 dev_dbg(&dev->dev, "%s: %s: cmd=%02x, len=%u.\n", 80 struct w1_netlink_msg *hdr = (struct w1_netlink_msg *)(msg + 1);
54 __func__, dev->name, cmd->cmd, cmd->len); 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;
55 83
56 if (cmd->cmd != W1_CMD_SEARCH && cmd->cmd != W1_CMD_ALARM_SEARCH) 84 dev->priv = msg;
57 return -EINVAL; 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;
58 94
59 w1_search_process(dev, (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH);
60 return 0; 95 return 0;
61} 96}
62 97
98static 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
63static int w1_send_read_reply(struct w1_slave *sl, struct cn_msg *msg, 141static int w1_send_read_reply(struct w1_slave *sl, struct cn_msg *msg,
64 struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) 142 struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd)
65{ 143{
@@ -119,11 +197,6 @@ static int w1_process_command_slave(struct w1_slave *sl, struct cn_msg *msg,
119 case W1_CMD_WRITE: 197 case W1_CMD_WRITE:
120 w1_write_block(sl->master, cmd->data, cmd->len); 198 w1_write_block(sl->master, cmd->data, cmd->len);
121 break; 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 default: 200 default:
128 err = -1; 201 err = -1;
129 break; 202 break;
@@ -270,11 +343,6 @@ out_cont:
270 if (err == -ENODEV) 343 if (err == -ENODEV)
271 err = 0; 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
280int w1_init_netlink(void) 348int w1_init_netlink(void)