aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1/w1_netlink.c')
-rw-r--r--drivers/w1/w1_netlink.c53
1 files changed, 46 insertions, 7 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