diff options
author | David Fries <David@Fries.net> | 2014-01-15 23:29:19 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-07 18:40:17 -0500 |
commit | ac8f73305eea8a12fdcb6090417eb93a74efbcbd (patch) | |
tree | 62e1686b23716165be9ab5de335a0a59bab12908 /drivers/connector | |
parent | 9fcbbac5ded489c3a4e121343db999dd51cd6c75 (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.c | 18 | ||||
-rw-r--r-- | drivers/connector/connector.c | 20 |
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 | ||
101 | void proc_exec_connector(struct task_struct *task) | 101 | void 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 | ||
128 | void proc_id_connector(struct task_struct *task, int which_id) | 128 | void 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 | ||
169 | void proc_sid_connector(struct task_struct *task) | 169 | void 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 | ||
196 | void proc_ptrace_connector(struct task_struct *task, int ptrace_id) | 196 | void 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 | ||
231 | void proc_comm_connector(struct task_struct *task) | 231 | void 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 | ||
259 | void proc_coredump_connector(struct task_struct *task) | 259 | void 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 | ||
286 | void proc_exit_connector(struct task_struct *task) | 286 | void 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 | */ |
66 | int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask) | 68 | int 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 | } |
118 | EXPORT_SYMBOL_GPL(cn_netlink_send); | 124 | EXPORT_SYMBOL_GPL(cn_netlink_send); |
119 | 125 | ||