Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758606AbYLDOwa (ORCPT ); Thu, 4 Dec 2008 09:52:30 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756131AbYLDOuO (ORCPT ); Thu, 4 Dec 2008 09:50:14 -0500 Received: from cavolo.yandex.ru ([87.250.244.45]:54007 "EHLO cavolo.yandex.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755563AbYLDOuN (ORCPT ); Thu, 4 Dec 2008 09:50:13 -0500 From: Evgeniy Polyakov To: Andrew Morton Cc: linux-kernel@vger.kernel.org, Evgeniy Polyakov Subject: [W1] List slaves commands. Date: Thu, 4 Dec 2008 17:50:09 +0300 Message-Id: <1228402214589-git-send-email-zbr@ioremap.net> X-Mailer: git-send-email 1.5.2.5 In-Reply-To: <12284022141659-git-send-email-zbr@ioremap.net> References: <12284022104086-git-send-email-zbr@ioremap.net> <122840221468-git-send-email-zbr@ioremap.net> <12284022143564-git-send-email-zbr@ioremap.net> <12284022144105-git-send-email-zbr@ioremap.net> <12284022141659-git-send-email-zbr@ioremap.net> X-Antivirus: Dr.Web (R) for Mail Servers on cavolo.yandex.ru host X-Antivirus-Code: 100000 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4058 Lines: 147 Signed-off-by: Evgeniy Polyakov --- drivers/w1/w1_netlink.c | 102 +++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 85 insertions(+), 17 deletions(-) diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c index cae556c..24ad6bb 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) cn_netlink_send(m, 0, GFP_KERNEL); } -static int w1_process_command_master(struct w1_master *dev, struct cn_msg *msg, - struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) +static void w1_send_slave(struct w1_master *dev, u64 rn) { - dev_dbg(&dev->dev, "%s: %s: cmd=%02x, len=%u.\n", - __func__, dev->name, cmd->cmd, cmd->len); + struct cn_msg *msg = dev->priv; + struct w1_netlink_msg *hdr = (struct w1_netlink_msg *)(msg + 1); + struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)(hdr + 1); + int avail; + + avail = dev->priv_size - cmd->len; + + if (avail > 8) { + u64 *data = (void *)(cmd + 1) + cmd->len; + + *data = rn; + cmd->len += 8; + hdr->len += 8; + msg->len += 8; + return; + } + + msg->ack++; + cn_netlink_send(msg, 0, GFP_KERNEL); + + msg->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd); + hdr->len = sizeof(struct w1_netlink_cmd); + cmd->len = 0; +} + +static int w1_process_search_command(struct w1_master *dev, struct cn_msg *msg, + unsigned int avail) +{ + struct w1_netlink_msg *hdr = (struct w1_netlink_msg *)(msg + 1); + struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)(hdr + 1); + int search_type = (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH; + + dev->priv = msg; + dev->priv_size = avail; + + w1_search_devices(dev, search_type, w1_send_slave); - if (cmd->cmd != W1_CMD_SEARCH && cmd->cmd != W1_CMD_ALARM_SEARCH) - return -EINVAL; + msg->ack = 0; + cn_netlink_send(msg, 0, GFP_KERNEL); + + dev->priv = NULL; + dev->priv_size = 0; - w1_search_process(dev, (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH); return 0; } +static int w1_process_command_master(struct w1_master *dev, struct cn_msg *req_msg, + struct w1_netlink_msg *req_hdr, struct w1_netlink_cmd *req_cmd) +{ + int err = -EINVAL; + struct cn_msg *msg; + struct w1_netlink_msg *hdr; + struct w1_netlink_cmd *cmd; + + msg = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->id = req_msg->id; + msg->seq = req_msg->seq; + msg->ack = 0; + msg->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd); + + hdr = (struct w1_netlink_msg *)(msg + 1); + cmd = (struct w1_netlink_cmd *)(hdr + 1); + + hdr->type = W1_MASTER_CMD; + hdr->id = req_hdr->id; + hdr->len = sizeof(struct w1_netlink_cmd); + + cmd->cmd = req_cmd->cmd; + cmd->len = 0; + + switch (cmd->cmd) { + case W1_CMD_SEARCH: + case W1_CMD_ALARM_SEARCH: + err = w1_process_search_command(dev, msg, + PAGE_SIZE - msg->len - sizeof(struct cn_msg)); + break; + default: + cmd->res = EINVAL; + cn_netlink_send(msg, 0, GFP_KERNEL); + break; + } + + kfree(msg); + return err; +} + static int w1_send_read_reply(struct w1_slave *sl, struct cn_msg *msg, struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) { @@ -119,11 +197,6 @@ static int w1_process_command_slave(struct w1_slave *sl, struct cn_msg *msg, case W1_CMD_WRITE: w1_write_block(sl->master, cmd->data, cmd->len); break; - case W1_CMD_SEARCH: - case W1_CMD_ALARM_SEARCH: - w1_search_process(sl->master, - (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH); - break; default: err = -1; break; @@ -270,11 +343,6 @@ out_cont: if (err == -ENODEV) err = 0; } -#if 0 - if (err) { - printk("%s: malformed message. Dropping.\n", __func__); - } -#endif } int w1_init_netlink(void) -- 1.5.2.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/