aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1
diff options
context:
space:
mode:
authorEvgeniy Polyakov <zbr@ioremap.net>2009-01-07 21:09:05 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-08 11:31:14 -0500
commit4037014e3fb71e998189374e19ca141c59d15323 (patch)
treec422a2c48bfa7b702a5e3927475cc3cb1bffc928 /drivers/w1
parentf89735c4e281e8642907b38640c076ae5048f3a6 (diff)
w1: send status messages after command processing
Send completion status of the commands to the userspace. Message and protocol are described in the documentation. Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net> Cc: Paul Alfille <paul.alfille@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/w1')
-rw-r--r--drivers/w1/w1_netlink.c53
-rw-r--r--drivers/w1/w1_netlink.h2
2 files changed, 47 insertions, 8 deletions
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index f978c7504004..fdf72851c574 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -152,7 +152,7 @@ static int w1_process_command_io(struct w1_master *dev, struct cn_msg *msg,
152 w1_write_block(dev, cmd->data, cmd->len); 152 w1_write_block(dev, cmd->data, cmd->len);
153 break; 153 break;
154 default: 154 default:
155 err = -1; 155 err = -EINVAL;
156 break; 156 break;
157 } 157 }
158 158
@@ -195,14 +195,13 @@ static int w1_process_command_master(struct w1_master *dev, struct cn_msg *req_m
195 case W1_CMD_READ: 195 case W1_CMD_READ:
196 case W1_CMD_WRITE: 196 case W1_CMD_WRITE:
197 case W1_CMD_TOUCH: 197 case W1_CMD_TOUCH:
198 err = w1_process_command_io(dev, msg, hdr, cmd); 198 err = w1_process_command_io(dev, req_msg, req_hdr, req_cmd);
199 break; 199 break;
200 case W1_CMD_RESET: 200 case W1_CMD_RESET:
201 err = w1_reset_bus(dev); 201 err = w1_reset_bus(dev);
202 break; 202 break;
203 default: 203 default:
204 cmd->res = EINVAL; 204 err = -EINVAL;
205 cn_netlink_send(msg, 0, GFP_KERNEL);
206 break; 205 break;
207 } 206 }
208 207
@@ -246,7 +245,7 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
246 w = (struct w1_netlink_msg *)(cn + 1); 245 w = (struct w1_netlink_msg *)(cn + 1);
247 246
248 w->type = W1_LIST_MASTERS; 247 w->type = W1_LIST_MASTERS;
249 w->reserved = 0; 248 w->status = 0;
250 w->len = 0; 249 w->len = 0;
251 id = (u32 *)(w + 1); 250 id = (u32 *)(w + 1);
252 251
@@ -273,6 +272,40 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
273 return 0; 272 return 0;
274} 273}
275 274
275static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rmsg,
276 struct w1_netlink_cmd *rcmd, int error)
277{
278 struct cn_msg *cmsg;
279 struct w1_netlink_msg *msg;
280 struct w1_netlink_cmd *cmd;
281
282 cmsg = kzalloc(sizeof(*msg) + sizeof(*cmd) + sizeof(*cmsg), GFP_KERNEL);
283 if (!cmsg)
284 return -ENOMEM;
285
286 msg = (struct w1_netlink_msg *)(cmsg + 1);
287 cmd = (struct w1_netlink_cmd *)(msg + 1);
288
289 memcpy(cmsg, rcmsg, sizeof(*cmsg));
290 cmsg->len = sizeof(*msg);
291
292 memcpy(msg, rmsg, sizeof(*msg));
293 msg->len = 0;
294 msg->status = (short)-error;
295
296 if (rcmd) {
297 memcpy(cmd, rcmd, sizeof(*cmd));
298 cmd->len = 0;
299 msg->len += sizeof(*cmd);
300 cmsg->len += sizeof(*cmd);
301 }
302
303 error = cn_netlink_send(cmsg, 0, GFP_KERNEL);
304 kfree(cmsg);
305
306 return error;
307}
308
276static void w1_cn_callback(void *data) 309static void w1_cn_callback(void *data)
277{ 310{
278 struct cn_msg *msg = data; 311 struct cn_msg *msg = data;
@@ -289,6 +322,7 @@ static void w1_cn_callback(void *data)
289 322
290 dev = NULL; 323 dev = NULL;
291 sl = NULL; 324 sl = NULL;
325 cmd = NULL;
292 326
293 memcpy(&id, m->id.id, sizeof(id)); 327 memcpy(&id, m->id.id, sizeof(id));
294#if 0 328#if 0
@@ -336,9 +370,12 @@ static void w1_cn_callback(void *data)
336 } 370 }
337 371
338 if (sl) 372 if (sl)
339 w1_process_command_slave(sl, msg, m, cmd); 373 err = w1_process_command_slave(sl, msg, m, cmd);
340 else 374 else
341 w1_process_command_master(dev, msg, m, cmd); 375 err = w1_process_command_master(dev, msg, m, cmd);
376
377 w1_netlink_send_error(msg, m, cmd, err);
378 err = 0;
342 379
343 cmd_data += cmd->len + sizeof(struct w1_netlink_cmd); 380 cmd_data += cmd->len + sizeof(struct w1_netlink_cmd);
344 mlen -= cmd->len + sizeof(struct w1_netlink_cmd); 381 mlen -= cmd->len + sizeof(struct w1_netlink_cmd);
@@ -349,6 +386,8 @@ out_up:
349 atomic_dec(&sl->refcnt); 386 atomic_dec(&sl->refcnt);
350 mutex_unlock(&dev->mutex); 387 mutex_unlock(&dev->mutex);
351out_cont: 388out_cont:
389 if (!cmd || err)
390 w1_netlink_send_error(msg, m, cmd, err);
352 msg->len -= sizeof(struct w1_netlink_msg) + m->len; 391 msg->len -= sizeof(struct w1_netlink_msg) + m->len;
353 m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len); 392 m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len);
354 393
diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h
index 68a4ff46cb96..27e950f935b1 100644
--- a/drivers/w1/w1_netlink.h
+++ b/drivers/w1/w1_netlink.h
@@ -40,7 +40,7 @@ enum w1_netlink_message_types {
40struct w1_netlink_msg 40struct w1_netlink_msg
41{ 41{
42 __u8 type; 42 __u8 type;
43 __u8 reserved; 43 __u8 status;
44 __u16 len; 44 __u16 len;
45 union { 45 union {
46 __u8 id[8]; 46 __u8 id[8];