diff options
Diffstat (limited to 'Documentation/connector')
-rw-r--r-- | Documentation/connector/Makefile | 5 | ||||
-rw-r--r-- | Documentation/connector/cn_test.c | 31 | ||||
-rw-r--r-- | Documentation/connector/ucon.c | 62 |
3 files changed, 76 insertions, 22 deletions
diff --git a/Documentation/connector/Makefile b/Documentation/connector/Makefile index 8df1a7285a06..d98e4df98e24 100644 --- a/Documentation/connector/Makefile +++ b/Documentation/connector/Makefile | |||
@@ -9,3 +9,8 @@ hostprogs-y := ucon | |||
9 | always := $(hostprogs-y) | 9 | always := $(hostprogs-y) |
10 | 10 | ||
11 | HOSTCFLAGS_ucon.o += -I$(objtree)/usr/include | 11 | HOSTCFLAGS_ucon.o += -I$(objtree)/usr/include |
12 | |||
13 | all: modules | ||
14 | |||
15 | modules clean: | ||
16 | $(MAKE) -C ../.. SUBDIRS=$(PWD) $@ | ||
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c index 50d5ce4899c8..6e73190af0be 100644 --- a/Documentation/connector/cn_test.c +++ b/Documentation/connector/cn_test.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) "cn_test: " fmt | ||
23 | |||
22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
24 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
@@ -27,16 +29,17 @@ | |||
27 | 29 | ||
28 | #include <linux/connector.h> | 30 | #include <linux/connector.h> |
29 | 31 | ||
30 | static struct cb_id cn_test_id = { 0x123, 0x456 }; | 32 | static struct cb_id cn_test_id = { CN_NETLINK_USERS + 3, 0x456 }; |
31 | static char cn_test_name[] = "cn_test"; | 33 | static char cn_test_name[] = "cn_test"; |
32 | static struct sock *nls; | 34 | static struct sock *nls; |
33 | static struct timer_list cn_test_timer; | 35 | static struct timer_list cn_test_timer; |
34 | 36 | ||
35 | void cn_test_callback(struct cn_msg *msg) | 37 | static void cn_test_callback(struct cn_msg *msg) |
36 | { | 38 | { |
37 | printk("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n", | 39 | pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n", |
38 | __func__, jiffies, msg->id.idx, msg->id.val, | 40 | __func__, jiffies, msg->id.idx, msg->id.val, |
39 | msg->seq, msg->ack, msg->len, (char *)msg->data); | 41 | msg->seq, msg->ack, msg->len, |
42 | msg->len ? (char *)msg->data : ""); | ||
40 | } | 43 | } |
41 | 44 | ||
42 | /* | 45 | /* |
@@ -61,9 +64,7 @@ static int cn_test_want_notify(void) | |||
61 | 64 | ||
62 | skb = alloc_skb(size, GFP_ATOMIC); | 65 | skb = alloc_skb(size, GFP_ATOMIC); |
63 | if (!skb) { | 66 | if (!skb) { |
64 | printk(KERN_ERR "Failed to allocate new skb with size=%u.\n", | 67 | pr_err("failed to allocate new skb with size=%u\n", size); |
65 | size); | ||
66 | |||
67 | return -ENOMEM; | 68 | return -ENOMEM; |
68 | } | 69 | } |
69 | 70 | ||
@@ -112,12 +113,12 @@ static int cn_test_want_notify(void) | |||
112 | //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC); | 113 | //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC); |
113 | netlink_unicast(nls, skb, 0, 0); | 114 | netlink_unicast(nls, skb, 0, 0); |
114 | 115 | ||
115 | printk(KERN_INFO "Request was sent. Group=0x%x.\n", ctl->group); | 116 | pr_info("request was sent: group=0x%x\n", ctl->group); |
116 | 117 | ||
117 | return 0; | 118 | return 0; |
118 | 119 | ||
119 | nlmsg_failure: | 120 | nlmsg_failure: |
120 | printk(KERN_ERR "Failed to send %u.%u\n", msg->seq, msg->ack); | 121 | pr_err("failed to send %u.%u\n", msg->seq, msg->ack); |
121 | kfree_skb(skb); | 122 | kfree_skb(skb); |
122 | return -EINVAL; | 123 | return -EINVAL; |
123 | } | 124 | } |
@@ -129,6 +130,8 @@ static void cn_test_timer_func(unsigned long __data) | |||
129 | struct cn_msg *m; | 130 | struct cn_msg *m; |
130 | char data[32]; | 131 | char data[32]; |
131 | 132 | ||
133 | pr_debug("%s: timer fired with data %lu\n", __func__, __data); | ||
134 | |||
132 | m = kzalloc(sizeof(*m) + sizeof(data), GFP_ATOMIC); | 135 | m = kzalloc(sizeof(*m) + sizeof(data), GFP_ATOMIC); |
133 | if (m) { | 136 | if (m) { |
134 | 137 | ||
@@ -148,7 +151,7 @@ static void cn_test_timer_func(unsigned long __data) | |||
148 | 151 | ||
149 | cn_test_timer_counter++; | 152 | cn_test_timer_counter++; |
150 | 153 | ||
151 | mod_timer(&cn_test_timer, jiffies + HZ); | 154 | mod_timer(&cn_test_timer, jiffies + msecs_to_jiffies(1000)); |
152 | } | 155 | } |
153 | 156 | ||
154 | static int cn_test_init(void) | 157 | static int cn_test_init(void) |
@@ -166,8 +169,10 @@ static int cn_test_init(void) | |||
166 | } | 169 | } |
167 | 170 | ||
168 | setup_timer(&cn_test_timer, cn_test_timer_func, 0); | 171 | setup_timer(&cn_test_timer, cn_test_timer_func, 0); |
169 | cn_test_timer.expires = jiffies + HZ; | 172 | mod_timer(&cn_test_timer, jiffies + msecs_to_jiffies(1000)); |
170 | add_timer(&cn_test_timer); | 173 | |
174 | pr_info("initialized with id={%u.%u}\n", | ||
175 | cn_test_id.idx, cn_test_id.val); | ||
171 | 176 | ||
172 | return 0; | 177 | return 0; |
173 | 178 | ||
diff --git a/Documentation/connector/ucon.c b/Documentation/connector/ucon.c index d738cde2a8d5..a8e4d5885ad4 100644 --- a/Documentation/connector/ucon.c +++ b/Documentation/connector/ucon.c | |||
@@ -30,18 +30,24 @@ | |||
30 | 30 | ||
31 | #include <arpa/inet.h> | 31 | #include <arpa/inet.h> |
32 | 32 | ||
33 | #include <stdbool.h> | ||
33 | #include <stdio.h> | 34 | #include <stdio.h> |
34 | #include <stdlib.h> | 35 | #include <stdlib.h> |
35 | #include <unistd.h> | 36 | #include <unistd.h> |
36 | #include <string.h> | 37 | #include <string.h> |
37 | #include <errno.h> | 38 | #include <errno.h> |
38 | #include <time.h> | 39 | #include <time.h> |
40 | #include <getopt.h> | ||
39 | 41 | ||
40 | #include <linux/connector.h> | 42 | #include <linux/connector.h> |
41 | 43 | ||
42 | #define DEBUG | 44 | #define DEBUG |
43 | #define NETLINK_CONNECTOR 11 | 45 | #define NETLINK_CONNECTOR 11 |
44 | 46 | ||
47 | /* Hopefully your userspace connector.h matches this kernel */ | ||
48 | #define CN_TEST_IDX CN_NETLINK_USERS + 3 | ||
49 | #define CN_TEST_VAL 0x456 | ||
50 | |||
45 | #ifdef DEBUG | 51 | #ifdef DEBUG |
46 | #define ulog(f, a...) fprintf(stdout, f, ##a) | 52 | #define ulog(f, a...) fprintf(stdout, f, ##a) |
47 | #else | 53 | #else |
@@ -83,6 +89,25 @@ static int netlink_send(int s, struct cn_msg *msg) | |||
83 | return err; | 89 | return err; |
84 | } | 90 | } |
85 | 91 | ||
92 | static void usage(void) | ||
93 | { | ||
94 | printf( | ||
95 | "Usage: ucon [options] [output file]\n" | ||
96 | "\n" | ||
97 | "\t-h\tthis help screen\n" | ||
98 | "\t-s\tsend buffers to the test module\n" | ||
99 | "\n" | ||
100 | "The default behavior of ucon is to subscribe to the test module\n" | ||
101 | "and wait for state messages. Any ones received are dumped to the\n" | ||
102 | "specified output file (or stdout). The test module is assumed to\n" | ||
103 | "have an id of {%u.%u}\n" | ||
104 | "\n" | ||
105 | "If you get no output, then verify the cn_test module id matches\n" | ||
106 | "the expected id above.\n" | ||
107 | , CN_TEST_IDX, CN_TEST_VAL | ||
108 | ); | ||
109 | } | ||
110 | |||
86 | int main(int argc, char *argv[]) | 111 | int main(int argc, char *argv[]) |
87 | { | 112 | { |
88 | int s; | 113 | int s; |
@@ -94,17 +119,34 @@ int main(int argc, char *argv[]) | |||
94 | FILE *out; | 119 | FILE *out; |
95 | time_t tm; | 120 | time_t tm; |
96 | struct pollfd pfd; | 121 | struct pollfd pfd; |
122 | bool send_msgs = false; | ||
97 | 123 | ||
98 | if (argc < 2) | 124 | while ((s = getopt(argc, argv, "hs")) != -1) { |
99 | out = stdout; | 125 | switch (s) { |
100 | else { | 126 | case 's': |
101 | out = fopen(argv[1], "a+"); | 127 | send_msgs = true; |
128 | break; | ||
129 | |||
130 | case 'h': | ||
131 | usage(); | ||
132 | return 0; | ||
133 | |||
134 | default: | ||
135 | /* getopt() outputs an error for us */ | ||
136 | usage(); | ||
137 | return 1; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | if (argc != optind) { | ||
142 | out = fopen(argv[optind], "a+"); | ||
102 | if (!out) { | 143 | if (!out) { |
103 | ulog("Unable to open %s for writing: %s\n", | 144 | ulog("Unable to open %s for writing: %s\n", |
104 | argv[1], strerror(errno)); | 145 | argv[1], strerror(errno)); |
105 | out = stdout; | 146 | out = stdout; |
106 | } | 147 | } |
107 | } | 148 | } else |
149 | out = stdout; | ||
108 | 150 | ||
109 | memset(buf, 0, sizeof(buf)); | 151 | memset(buf, 0, sizeof(buf)); |
110 | 152 | ||
@@ -115,9 +157,11 @@ int main(int argc, char *argv[]) | |||
115 | } | 157 | } |
116 | 158 | ||
117 | l_local.nl_family = AF_NETLINK; | 159 | l_local.nl_family = AF_NETLINK; |
118 | l_local.nl_groups = 0x123; /* bitmask of requested groups */ | 160 | l_local.nl_groups = -1; /* bitmask of requested groups */ |
119 | l_local.nl_pid = 0; | 161 | l_local.nl_pid = 0; |
120 | 162 | ||
163 | ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL); | ||
164 | |||
121 | if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { | 165 | if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { |
122 | perror("bind"); | 166 | perror("bind"); |
123 | close(s); | 167 | close(s); |
@@ -130,15 +174,15 @@ int main(int argc, char *argv[]) | |||
130 | setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on)); | 174 | setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on)); |
131 | } | 175 | } |
132 | #endif | 176 | #endif |
133 | if (0) { | 177 | if (send_msgs) { |
134 | int i, j; | 178 | int i, j; |
135 | 179 | ||
136 | memset(buf, 0, sizeof(buf)); | 180 | memset(buf, 0, sizeof(buf)); |
137 | 181 | ||
138 | data = (struct cn_msg *)buf; | 182 | data = (struct cn_msg *)buf; |
139 | 183 | ||
140 | data->id.idx = 0x123; | 184 | data->id.idx = CN_TEST_IDX; |
141 | data->id.val = 0x456; | 185 | data->id.val = CN_TEST_VAL; |
142 | data->seq = seq++; | 186 | data->seq = seq++; |
143 | data->ack = 0; | 187 | data->ack = 0; |
144 | data->len = 0; | 188 | data->len = 0; |