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.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 65c5ebd0787e..2e07b59b9859 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -128,6 +128,59 @@ static int w1_process_command_slave(struct w1_slave *sl, struct cn_msg *msg,
128 return err; 128 return err;
129} 129}
130 130
131static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mcmd)
132{
133 struct w1_master *m;
134 struct cn_msg *cn;
135 struct w1_netlink_msg *w;
136 u32 *id;
137
138 if (mcmd->type != W1_LIST_MASTERS) {
139 printk(KERN_NOTICE "%s: msg: %x.%x, wrong type: %u, len: %u.\n",
140 __func__, msg->id.idx, msg->id.val, mcmd->type, mcmd->len);
141 return -EPROTO;
142 }
143
144 cn = kmalloc(PAGE_SIZE, GFP_KERNEL);
145 if (!cn)
146 return -ENOMEM;
147
148 cn->id.idx = CN_W1_IDX;
149 cn->id.val = CN_W1_VAL;
150
151 cn->seq = msg->seq;
152 cn->ack = 1;
153 cn->len = sizeof(struct w1_netlink_msg);
154 w = (struct w1_netlink_msg *)(cn + 1);
155
156 w->type = W1_LIST_MASTERS;
157 w->reserved = 0;
158 w->len = 0;
159 id = (u32 *)(w + 1);
160
161 mutex_lock(&w1_mlock);
162 list_for_each_entry(m, &w1_masters, w1_master_entry) {
163 if (cn->len + sizeof(*id) > PAGE_SIZE - sizeof(struct cn_msg)) {
164 cn_netlink_send(cn, 0, GFP_KERNEL);
165 cn->ack++;
166 cn->len = sizeof(struct w1_netlink_msg);
167 w->len = 0;
168 id = (u32 *)(w + 1);
169 }
170
171 *id = m->id;
172 w->len += sizeof(*id);
173 cn->len += sizeof(*id);
174 id++;
175 }
176 cn->ack = 0;
177 cn_netlink_send(cn, 0, GFP_KERNEL);
178 mutex_unlock(&w1_mlock);
179
180 kfree(cn);
181 return 0;
182}
183
131static void w1_cn_callback(void *data) 184static void w1_cn_callback(void *data)
132{ 185{
133 struct cn_msg *msg = data; 186 struct cn_msg *msg = data;
@@ -164,6 +217,9 @@ static void w1_cn_callback(void *data)
164 sl = w1_search_slave(&id); 217 sl = w1_search_slave(&id);
165 if (sl) 218 if (sl)
166 dev = sl->master; 219 dev = sl->master;
220 } else {
221 err = w1_process_command_root(msg, m);
222 goto out_cont;
167 } 223 }
168 224
169 if (!dev) { 225 if (!dev) {