Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 127631
b: refs/heads/master
c: 4037014
h: refs/heads/master
i:
  127629: 61ed39f
  127627: 368fc47
  127623: 9592f6b
  127615: 364791c
v: v3
  • Loading branch information
Evgeniy Polyakov authored and Linus Torvalds committed Jan 8, 2009
1 parent 6b14c9e commit 65ee349
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f89735c4e281e8642907b38640c076ae5048f3a6
refs/heads/master: 4037014e3fb71e998189374e19ca141c59d15323
29 changes: 29 additions & 0 deletions trunk/Documentation/w1/w1.netlink
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,35 @@ W1 reset command.
id is equal to the bus master id to use for searching]
[w1_netlink_cmd cmd = W1_CMD_RESET]


Command status replies.
======================

Each command (either root, master or slave with or without w1_netlink_cmd
structure) will be 'acked' by the w1 core. Format of the reply is the same
as request message except that length parameters do not account for data
requested by the user, i.e. read/write/touch IO requests will not contain
data, so w1_netlink_cmd.len will be 0, w1_netlink_msg.len will be size
of the w1_netlink_cmd structure and cn_msg.len will be equal to the sum
of the sizeof(struct w1_netlink_msg) and sizeof(struct w1_netlink_cmd).
If reply is generated for master or root command (which do not have
w1_netlink_cmd attached), reply will contain only cn_msg and w1_netlink_msg
structires.

w1_netlink_msg.status field will carry positive error value
(EINVAL for example) or zero in case of success.

All other fields in every structure will mirror the same parameters in the
request message (except lengths as described above).

Status reply is generated for every w1_netlink_cmd embedded in the
w1_netlink_msg, if there are no w1_netlink_cmd structures,
reply will be generated for the w1_netlink_msg.

All w1_netlink_cmd command structures are handled in every w1_netlink_msg,
even if there were errors, only length mismatch interrupts message processing.


Operation steps in w1 core when new command is received.
=======================================================

Expand Down
53 changes: 46 additions & 7 deletions trunk/drivers/w1/w1_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ static int w1_process_command_io(struct w1_master *dev, struct cn_msg *msg,
w1_write_block(dev, cmd->data, cmd->len);
break;
default:
err = -1;
err = -EINVAL;
break;
}

Expand Down Expand Up @@ -195,14 +195,13 @@ static int w1_process_command_master(struct w1_master *dev, struct cn_msg *req_m
case W1_CMD_READ:
case W1_CMD_WRITE:
case W1_CMD_TOUCH:
err = w1_process_command_io(dev, msg, hdr, cmd);
err = w1_process_command_io(dev, req_msg, req_hdr, req_cmd);
break;
case W1_CMD_RESET:
err = w1_reset_bus(dev);
break;
default:
cmd->res = EINVAL;
cn_netlink_send(msg, 0, GFP_KERNEL);
err = -EINVAL;
break;
}

Expand Down Expand Up @@ -246,7 +245,7 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
w = (struct w1_netlink_msg *)(cn + 1);

w->type = W1_LIST_MASTERS;
w->reserved = 0;
w->status = 0;
w->len = 0;
id = (u32 *)(w + 1);

Expand All @@ -273,6 +272,40 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
return 0;
}

static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rmsg,
struct w1_netlink_cmd *rcmd, int error)
{
struct cn_msg *cmsg;
struct w1_netlink_msg *msg;
struct w1_netlink_cmd *cmd;

cmsg = kzalloc(sizeof(*msg) + sizeof(*cmd) + sizeof(*cmsg), GFP_KERNEL);
if (!cmsg)
return -ENOMEM;

msg = (struct w1_netlink_msg *)(cmsg + 1);
cmd = (struct w1_netlink_cmd *)(msg + 1);

memcpy(cmsg, rcmsg, sizeof(*cmsg));
cmsg->len = sizeof(*msg);

memcpy(msg, rmsg, sizeof(*msg));
msg->len = 0;
msg->status = (short)-error;

if (rcmd) {
memcpy(cmd, rcmd, sizeof(*cmd));
cmd->len = 0;
msg->len += sizeof(*cmd);
cmsg->len += sizeof(*cmd);
}

error = cn_netlink_send(cmsg, 0, GFP_KERNEL);
kfree(cmsg);

return error;
}

static void w1_cn_callback(void *data)
{
struct cn_msg *msg = data;
Expand All @@ -289,6 +322,7 @@ static void w1_cn_callback(void *data)

dev = NULL;
sl = NULL;
cmd = NULL;

memcpy(&id, m->id.id, sizeof(id));
#if 0
Expand Down Expand Up @@ -336,9 +370,12 @@ static void w1_cn_callback(void *data)
}

if (sl)
w1_process_command_slave(sl, msg, m, cmd);
err = w1_process_command_slave(sl, msg, m, cmd);
else
w1_process_command_master(dev, msg, m, cmd);
err = w1_process_command_master(dev, msg, m, cmd);

w1_netlink_send_error(msg, m, cmd, err);
err = 0;

cmd_data += cmd->len + sizeof(struct w1_netlink_cmd);
mlen -= cmd->len + sizeof(struct w1_netlink_cmd);
Expand All @@ -349,6 +386,8 @@ static void w1_cn_callback(void *data)
atomic_dec(&sl->refcnt);
mutex_unlock(&dev->mutex);
out_cont:
if (!cmd || err)
w1_netlink_send_error(msg, m, cmd, err);
msg->len -= sizeof(struct w1_netlink_msg) + m->len;
m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len);

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/w1/w1_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ enum w1_netlink_message_types {
struct w1_netlink_msg
{
__u8 type;
__u8 reserved;
__u8 status;
__u16 len;
union {
__u8 id[8];
Expand Down

0 comments on commit 65ee349

Please sign in to comment.