aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/connector/connector.c
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/connector.c
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/connector.c')
-rw-r--r--drivers/connector/connector.c20
1 files changed, 13 insertions, 7 deletions
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