aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/connector
diff options
context:
space:
mode:
authorDavid Fries <David@Fries.net>2014-01-15 23:29:19 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-07 18:40:17 -0500
commitac8f73305eea8a12fdcb6090417eb93a74efbcbd (patch)
tree62e1686b23716165be9ab5de335a0a59bab12908 /drivers/connector
parent9fcbbac5ded489c3a4e121343db999dd51cd6c75 (diff)
connector: add portid to unicast in addition to broadcasting
This allows replying only to the requestor portid while still supporting broadcasting. Pass 0 to portid for the previous behavior. Signed-off-by: David Fries <David@Fries.net> Acked-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/connector')
-rw-r--r--drivers/connector/cn_proc.c18
-rw-r--r--drivers/connector/connector.c20
2 files changed, 22 insertions, 16 deletions
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 18c5b9b16645..148d707a1d43 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -95,7 +95,7 @@ void proc_fork_connector(struct task_struct *task)
95 msg->len = sizeof(*ev); 95 msg->len = sizeof(*ev);
96 msg->flags = 0; /* not used */ 96 msg->flags = 0; /* not used */
97 /* If cn_netlink_send() failed, the data is not sent */ 97 /* If cn_netlink_send() failed, the data is not sent */
98 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 98 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
99} 99}
100 100
101void proc_exec_connector(struct task_struct *task) 101void proc_exec_connector(struct task_struct *task)
@@ -122,7 +122,7 @@ void proc_exec_connector(struct task_struct *task)
122 msg->ack = 0; /* not used */ 122 msg->ack = 0; /* not used */
123 msg->len = sizeof(*ev); 123 msg->len = sizeof(*ev);
124 msg->flags = 0; /* not used */ 124 msg->flags = 0; /* not used */
125 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 125 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
126} 126}
127 127
128void proc_id_connector(struct task_struct *task, int which_id) 128void proc_id_connector(struct task_struct *task, int which_id)
@@ -163,7 +163,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
163 msg->ack = 0; /* not used */ 163 msg->ack = 0; /* not used */
164 msg->len = sizeof(*ev); 164 msg->len = sizeof(*ev);
165 msg->flags = 0; /* not used */ 165 msg->flags = 0; /* not used */
166 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 166 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
167} 167}
168 168
169void proc_sid_connector(struct task_struct *task) 169void proc_sid_connector(struct task_struct *task)
@@ -190,7 +190,7 @@ void proc_sid_connector(struct task_struct *task)
190 msg->ack = 0; /* not used */ 190 msg->ack = 0; /* not used */
191 msg->len = sizeof(*ev); 191 msg->len = sizeof(*ev);
192 msg->flags = 0; /* not used */ 192 msg->flags = 0; /* not used */
193 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 193 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
194} 194}
195 195
196void proc_ptrace_connector(struct task_struct *task, int ptrace_id) 196void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
@@ -225,7 +225,7 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
225 msg->ack = 0; /* not used */ 225 msg->ack = 0; /* not used */
226 msg->len = sizeof(*ev); 226 msg->len = sizeof(*ev);
227 msg->flags = 0; /* not used */ 227 msg->flags = 0; /* not used */
228 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 228 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
229} 229}
230 230
231void proc_comm_connector(struct task_struct *task) 231void proc_comm_connector(struct task_struct *task)
@@ -253,7 +253,7 @@ void proc_comm_connector(struct task_struct *task)
253 msg->ack = 0; /* not used */ 253 msg->ack = 0; /* not used */
254 msg->len = sizeof(*ev); 254 msg->len = sizeof(*ev);
255 msg->flags = 0; /* not used */ 255 msg->flags = 0; /* not used */
256 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 256 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
257} 257}
258 258
259void proc_coredump_connector(struct task_struct *task) 259void proc_coredump_connector(struct task_struct *task)
@@ -280,7 +280,7 @@ void proc_coredump_connector(struct task_struct *task)
280 msg->ack = 0; /* not used */ 280 msg->ack = 0; /* not used */
281 msg->len = sizeof(*ev); 281 msg->len = sizeof(*ev);
282 msg->flags = 0; /* not used */ 282 msg->flags = 0; /* not used */
283 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 283 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
284} 284}
285 285
286void proc_exit_connector(struct task_struct *task) 286void proc_exit_connector(struct task_struct *task)
@@ -309,7 +309,7 @@ void proc_exit_connector(struct task_struct *task)
309 msg->ack = 0; /* not used */ 309 msg->ack = 0; /* not used */
310 msg->len = sizeof(*ev); 310 msg->len = sizeof(*ev);
311 msg->flags = 0; /* not used */ 311 msg->flags = 0; /* not used */
312 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 312 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
313} 313}
314 314
315/* 315/*
@@ -343,7 +343,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
343 msg->ack = rcvd_ack + 1; 343 msg->ack = rcvd_ack + 1;
344 msg->len = sizeof(*ev); 344 msg->len = sizeof(*ev);
345 msg->flags = 0; /* not used */ 345 msg->flags = 0; /* not used */
346 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 346 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
347} 347}
348 348
349/** 349/**
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index a36749f1e44a..77afe7487d34 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -50,7 +50,7 @@ static int cn_already_initialized;
50 * 50 *
51 * Sequence number is incremented with each message to be sent. 51 * Sequence number is incremented with each message to be sent.
52 * 52 *
53 * If we expect reply to our message then the sequence number in 53 * If we expect a reply to our message then the sequence number in
54 * received message MUST be the same as in original message, and 54 * received message MUST be the same as in original message, and
55 * acknowledge number MUST be the same + 1. 55 * acknowledge number MUST be the same + 1.
56 * 56 *
@@ -62,8 +62,11 @@ static int cn_already_initialized;
62 * the acknowledgement number in the original message + 1, then it is 62 * the acknowledgement number in the original message + 1, then it is
63 * a new message. 63 * a new message.
64 * 64 *
65 * The message is sent to, the portid if given, the group if given, both if
66 * both, or if both are zero then the group is looked up and sent there.
65 */ 67 */
66int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask) 68int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group,
69 gfp_t gfp_mask)
67{ 70{
68 struct cn_callback_entry *__cbq; 71 struct cn_callback_entry *__cbq;
69 unsigned int size; 72 unsigned int size;
@@ -74,7 +77,9 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
74 u32 group = 0; 77 u32 group = 0;
75 int found = 0; 78 int found = 0;
76 79
77 if (!__group) { 80 if (portid || __group) {
81 group = __group;
82 } else {
78 spin_lock_bh(&dev->cbdev->queue_lock); 83 spin_lock_bh(&dev->cbdev->queue_lock);
79 list_for_each_entry(__cbq, &dev->cbdev->queue_list, 84 list_for_each_entry(__cbq, &dev->cbdev->queue_list,
80 callback_entry) { 85 callback_entry) {
@@ -88,11 +93,9 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
88 93
89 if (!found) 94 if (!found)
90 return -ENODEV; 95 return -ENODEV;
91 } else {
92 group = __group;
93 } 96 }
94 97
95 if (!netlink_has_listeners(dev->nls, group)) 98 if (!portid && !netlink_has_listeners(dev->nls, group))
96 return -ESRCH; 99 return -ESRCH;
97 100
98 size = sizeof(*msg) + msg->len; 101 size = sizeof(*msg) + msg->len;
@@ -113,7 +116,10 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
113 116
114 NETLINK_CB(skb).dst_group = group; 117 NETLINK_CB(skb).dst_group = group;
115 118
116 return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask); 119 if (group)
120 return netlink_broadcast(dev->nls, skb, portid, group,
121 gfp_mask);
122 return netlink_unicast(dev->nls, skb, portid, !(gfp_mask&__GFP_WAIT));
117} 123}
118EXPORT_SYMBOL_GPL(cn_netlink_send); 124EXPORT_SYMBOL_GPL(cn_netlink_send);
119 125