]>
Commit | Line | Data |
---|---|---|
e6f95ec8 SB |
1 | /* |
2 | * Copyright (C) ST-Ericsson AB 2010 | |
3 | * Author: Sjur Brendeland sjur.brandeland@stericsson.com | |
4 | * Per Sigmond per.sigmond@stericsson.com | |
5 | * License terms: GNU General Public License (GPL) version 2 | |
6 | */ | |
7 | ||
8 | #include <linux/fs.h> | |
9 | #include <linux/init.h> | |
10 | #include <linux/module.h> | |
11 | #include <linux/sched.h> | |
12 | #include <linux/spinlock.h> | |
13 | #include <linux/mutex.h> | |
14 | #include <linux/list.h> | |
15 | #include <linux/wait.h> | |
16 | #include <linux/poll.h> | |
17 | #include <linux/tcp.h> | |
18 | #include <linux/uaccess.h> | |
19 | #include <asm/atomic.h> | |
20 | ||
21 | #include <linux/caif/caif_socket.h> | |
22 | #include <net/caif/caif_layer.h> | |
23 | #include <net/caif/caif_dev.h> | |
24 | #include <net/caif/cfpkt.h> | |
25 | ||
26 | MODULE_LICENSE("GPL"); | |
27 | ||
28 | #define CHNL_SKT_READ_QUEUE_HIGH 200 | |
29 | #define CHNL_SKT_READ_QUEUE_LOW 100 | |
30 | ||
31 | static int caif_sockbuf_size = 40000; | |
32 | static atomic_t caif_nr_socks = ATOMIC_INIT(0); | |
33 | ||
34 | #define CONN_STATE_OPEN_BIT 1 | |
35 | #define CONN_STATE_PENDING_BIT 2 | |
36 | #define CONN_STATE_PEND_DESTROY_BIT 3 | |
37 | #define CONN_REMOTE_SHUTDOWN_BIT 4 | |
38 | ||
39 | #define TX_FLOW_ON_BIT 1 | |
40 | #define RX_FLOW_ON_BIT 2 | |
41 | ||
42 | #define STATE_IS_OPEN(cf_sk) test_bit(CONN_STATE_OPEN_BIT,\ | |
43 | (void *) &(cf_sk)->conn_state) | |
44 | #define STATE_IS_REMOTE_SHUTDOWN(cf_sk) test_bit(CONN_REMOTE_SHUTDOWN_BIT,\ | |
45 | (void *) &(cf_sk)->conn_state) | |
46 | #define STATE_IS_PENDING(cf_sk) test_bit(CONN_STATE_PENDING_BIT,\ | |
47 | (void *) &(cf_sk)->conn_state) | |
48 | #define STATE_IS_PENDING_DESTROY(cf_sk) test_bit(CONN_STATE_PEND_DESTROY_BIT,\ | |
49 | (void *) &(cf_sk)->conn_state) | |
50 | ||
51 | #define SET_STATE_PENDING_DESTROY(cf_sk) set_bit(CONN_STATE_PEND_DESTROY_BIT,\ | |
52 | (void *) &(cf_sk)->conn_state) | |
53 | #define SET_STATE_OPEN(cf_sk) set_bit(CONN_STATE_OPEN_BIT,\ | |
54 | (void *) &(cf_sk)->conn_state) | |
55 | #define SET_STATE_CLOSED(cf_sk) clear_bit(CONN_STATE_OPEN_BIT,\ | |
56 | (void *) &(cf_sk)->conn_state) | |
57 | #define SET_PENDING_ON(cf_sk) set_bit(CONN_STATE_PENDING_BIT,\ | |
58 | (void *) &(cf_sk)->conn_state) | |
59 | #define SET_PENDING_OFF(cf_sk) clear_bit(CONN_STATE_PENDING_BIT,\ | |
60 | (void *) &(cf_sk)->conn_state) | |
61 | #define SET_REMOTE_SHUTDOWN(cf_sk) set_bit(CONN_REMOTE_SHUTDOWN_BIT,\ | |
62 | (void *) &(cf_sk)->conn_state) | |
63 | ||
64 | #define SET_REMOTE_SHUTDOWN_OFF(dev) clear_bit(CONN_REMOTE_SHUTDOWN_BIT,\ | |
65 | (void *) &(dev)->conn_state) | |
66 | #define RX_FLOW_IS_ON(cf_sk) test_bit(RX_FLOW_ON_BIT,\ | |
67 | (void *) &(cf_sk)->flow_state) | |
68 | #define TX_FLOW_IS_ON(cf_sk) test_bit(TX_FLOW_ON_BIT,\ | |
69 | (void *) &(cf_sk)->flow_state) | |
70 | ||
71 | #define SET_RX_FLOW_OFF(cf_sk) clear_bit(RX_FLOW_ON_BIT,\ | |
72 | (void *) &(cf_sk)->flow_state) | |
73 | #define SET_RX_FLOW_ON(cf_sk) set_bit(RX_FLOW_ON_BIT,\ | |
74 | (void *) &(cf_sk)->flow_state) | |
75 | #define SET_TX_FLOW_OFF(cf_sk) clear_bit(TX_FLOW_ON_BIT,\ | |
76 | (void *) &(cf_sk)->flow_state) | |
77 | #define SET_TX_FLOW_ON(cf_sk) set_bit(TX_FLOW_ON_BIT,\ | |
78 | (void *) &(cf_sk)->flow_state) | |
79 | ||
80 | #define SKT_READ_FLAG 0x01 | |
81 | #define SKT_WRITE_FLAG 0x02 | |
82 | static struct dentry *debugfsdir; | |
83 | #include <linux/debugfs.h> | |
84 | ||
85 | #ifdef CONFIG_DEBUG_FS | |
86 | struct debug_fs_counter { | |
87 | atomic_t num_open; | |
88 | atomic_t num_close; | |
89 | atomic_t num_init; | |
90 | atomic_t num_init_resp; | |
91 | atomic_t num_init_fail_resp; | |
92 | atomic_t num_deinit; | |
93 | atomic_t num_deinit_resp; | |
94 | atomic_t num_remote_shutdown_ind; | |
95 | atomic_t num_tx_flow_off_ind; | |
96 | atomic_t num_tx_flow_on_ind; | |
97 | atomic_t num_rx_flow_off; | |
98 | atomic_t num_rx_flow_on; | |
99 | atomic_t skb_in_use; | |
100 | atomic_t skb_alloc; | |
101 | atomic_t skb_free; | |
102 | }; | |
103 | static struct debug_fs_counter cnt; | |
104 | #define dbfs_atomic_inc(v) atomic_inc(v) | |
105 | #define dbfs_atomic_dec(v) atomic_dec(v) | |
106 | #else | |
107 | #define dbfs_atomic_inc(v) | |
108 | #define dbfs_atomic_dec(v) | |
109 | #endif | |
110 | ||
111 | /* The AF_CAIF socket */ | |
112 | struct caifsock { | |
113 | /* NOTE: sk has to be the first member */ | |
114 | struct sock sk; | |
115 | struct cflayer layer; | |
116 | char name[CAIF_LAYER_NAME_SZ]; | |
117 | u32 conn_state; | |
118 | u32 flow_state; | |
119 | struct cfpktq *pktq; | |
120 | int file_mode; | |
121 | struct caif_connect_request conn_req; | |
122 | int read_queue_len; | |
123 | /* protect updates of read_queue_len */ | |
124 | spinlock_t read_queue_len_lock; | |
125 | struct dentry *debugfs_socket_dir; | |
126 | }; | |
127 | ||
128 | static void drain_queue(struct caifsock *cf_sk); | |
129 | ||
130 | /* Packet Receive Callback function called from CAIF Stack */ | |
131 | static int caif_sktrecv_cb(struct cflayer *layr, struct cfpkt *pkt) | |
132 | { | |
133 | struct caifsock *cf_sk; | |
134 | int read_queue_high; | |
135 | cf_sk = container_of(layr, struct caifsock, layer); | |
136 | ||
137 | if (!STATE_IS_OPEN(cf_sk)) { | |
138 | /*FIXME: This should be allowed finally!*/ | |
139 | pr_debug("CAIF: %s(): called after close request\n", __func__); | |
140 | cfpkt_destroy(pkt); | |
141 | return 0; | |
142 | } | |
143 | /* NOTE: This function may be called in Tasklet context! */ | |
144 | ||
145 | /* The queue has its own lock */ | |
146 | cfpkt_queue(cf_sk->pktq, pkt, 0); | |
147 | ||
148 | spin_lock(&cf_sk->read_queue_len_lock); | |
149 | cf_sk->read_queue_len++; | |
150 | ||
151 | read_queue_high = (cf_sk->read_queue_len > CHNL_SKT_READ_QUEUE_HIGH); | |
152 | spin_unlock(&cf_sk->read_queue_len_lock); | |
153 | ||
154 | if (RX_FLOW_IS_ON(cf_sk) && read_queue_high) { | |
155 | dbfs_atomic_inc(&cnt.num_rx_flow_off); | |
156 | SET_RX_FLOW_OFF(cf_sk); | |
157 | ||
158 | /* Send flow off (NOTE: must not sleep) */ | |
159 | pr_debug("CAIF: %s():" | |
160 | " sending flow OFF (queue len = %d)\n", | |
161 | __func__, | |
162 | cf_sk->read_queue_len); | |
163 | caif_assert(cf_sk->layer.dn); | |
164 | caif_assert(cf_sk->layer.dn->ctrlcmd); | |
165 | ||
166 | (void) cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, | |
167 | CAIF_MODEMCMD_FLOW_OFF_REQ); | |
168 | } | |
169 | ||
170 | /* Signal reader that data is available. */ | |
171 | ||
172 | wake_up_interruptible(cf_sk->sk.sk_sleep); | |
173 | ||
174 | return 0; | |
175 | } | |
176 | ||
177 | /* Packet Flow Control Callback function called from CAIF */ | |
178 | static void caif_sktflowctrl_cb(struct cflayer *layr, | |
179 | enum caif_ctrlcmd flow, | |
180 | int phyid) | |
181 | { | |
182 | struct caifsock *cf_sk; | |
183 | ||
184 | /* NOTE: This function may be called in Tasklet context! */ | |
185 | pr_debug("CAIF: %s(): flowctrl func called: %s.\n", | |
186 | __func__, | |
187 | flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" : | |
188 | flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" : | |
189 | flow == CAIF_CTRLCMD_INIT_RSP ? "INIT_RSP" : | |
190 | flow == CAIF_CTRLCMD_DEINIT_RSP ? "DEINIT_RSP" : | |
191 | flow == CAIF_CTRLCMD_INIT_FAIL_RSP ? "INIT_FAIL_RSP" : | |
192 | flow == | |
193 | CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ? "REMOTE_SHUTDOWN" : | |
194 | "UKNOWN CTRL COMMAND"); | |
195 | ||
196 | if (layr == NULL) | |
197 | return; | |
198 | ||
199 | cf_sk = container_of(layr, struct caifsock, layer); | |
200 | ||
201 | switch (flow) { | |
202 | case CAIF_CTRLCMD_FLOW_ON_IND: | |
203 | dbfs_atomic_inc(&cnt.num_tx_flow_on_ind); | |
204 | /* Signal reader that data is available. */ | |
205 | SET_TX_FLOW_ON(cf_sk); | |
206 | wake_up_interruptible(cf_sk->sk.sk_sleep); | |
207 | break; | |
208 | ||
209 | case CAIF_CTRLCMD_FLOW_OFF_IND: | |
210 | dbfs_atomic_inc(&cnt.num_tx_flow_off_ind); | |
211 | SET_TX_FLOW_OFF(cf_sk); | |
212 | break; | |
213 | ||
214 | case CAIF_CTRLCMD_INIT_RSP: | |
215 | dbfs_atomic_inc(&cnt.num_init_resp); | |
216 | /* Signal reader that data is available. */ | |
217 | caif_assert(STATE_IS_OPEN(cf_sk)); | |
218 | SET_PENDING_OFF(cf_sk); | |
219 | SET_TX_FLOW_ON(cf_sk); | |
220 | wake_up_interruptible(cf_sk->sk.sk_sleep); | |
221 | break; | |
222 | ||
223 | case CAIF_CTRLCMD_DEINIT_RSP: | |
224 | dbfs_atomic_inc(&cnt.num_deinit_resp); | |
225 | caif_assert(!STATE_IS_OPEN(cf_sk)); | |
226 | SET_PENDING_OFF(cf_sk); | |
227 | if (!STATE_IS_PENDING_DESTROY(cf_sk)) { | |
228 | if (cf_sk->sk.sk_sleep != NULL) | |
229 | wake_up_interruptible(cf_sk->sk.sk_sleep); | |
230 | } | |
231 | dbfs_atomic_inc(&cnt.num_deinit); | |
232 | sock_put(&cf_sk->sk); | |
233 | break; | |
234 | ||
235 | case CAIF_CTRLCMD_INIT_FAIL_RSP: | |
236 | dbfs_atomic_inc(&cnt.num_init_fail_resp); | |
237 | caif_assert(STATE_IS_OPEN(cf_sk)); | |
238 | SET_STATE_CLOSED(cf_sk); | |
239 | SET_PENDING_OFF(cf_sk); | |
240 | SET_TX_FLOW_OFF(cf_sk); | |
241 | wake_up_interruptible(cf_sk->sk.sk_sleep); | |
242 | break; | |
243 | ||
244 | case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: | |
245 | dbfs_atomic_inc(&cnt.num_remote_shutdown_ind); | |
246 | SET_REMOTE_SHUTDOWN(cf_sk); | |
247 | /* Use sk_shutdown to indicate remote shutdown indication */ | |
248 | cf_sk->sk.sk_shutdown |= RCV_SHUTDOWN; | |
249 | cf_sk->file_mode = 0; | |
250 | wake_up_interruptible(cf_sk->sk.sk_sleep); | |
251 | break; | |
252 | ||
253 | default: | |
254 | pr_debug("CAIF: %s(): Unexpected flow command %d\n", | |
255 | __func__, flow); | |
256 | } | |
257 | } | |
258 | ||
259 | static void skb_destructor(struct sk_buff *skb) | |
260 | { | |
261 | dbfs_atomic_inc(&cnt.skb_free); | |
262 | dbfs_atomic_dec(&cnt.skb_in_use); | |
263 | } | |
264 | ||
265 | ||
266 | static int caif_recvmsg(struct kiocb *iocb, struct socket *sock, | |
267 | struct msghdr *m, size_t buf_len, int flags) | |
268 | ||
269 | { | |
270 | struct sock *sk = sock->sk; | |
271 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | |
272 | struct cfpkt *pkt = NULL; | |
273 | size_t len; | |
274 | int result; | |
275 | struct sk_buff *skb; | |
276 | ssize_t ret = -EIO; | |
277 | int read_queue_low; | |
278 | ||
279 | if (cf_sk == NULL) { | |
280 | pr_debug("CAIF: %s(): private_data not set!\n", | |
281 | __func__); | |
282 | ret = -EBADFD; | |
283 | goto read_error; | |
284 | } | |
285 | ||
286 | /* Don't do multiple iovec entries yet */ | |
287 | if (m->msg_iovlen != 1) | |
288 | return -EOPNOTSUPP; | |
289 | ||
290 | if (unlikely(!buf_len)) | |
291 | return -EINVAL; | |
292 | ||
293 | lock_sock(&(cf_sk->sk)); | |
294 | ||
295 | caif_assert(cf_sk->pktq); | |
296 | ||
297 | if (!STATE_IS_OPEN(cf_sk)) { | |
298 | /* Socket is closed or closing. */ | |
299 | if (!STATE_IS_PENDING(cf_sk)) { | |
300 | pr_debug("CAIF: %s(): socket is closed (by remote)\n", | |
301 | __func__); | |
302 | ret = -EPIPE; | |
303 | } else { | |
304 | pr_debug("CAIF: %s(): socket is closing..\n", __func__); | |
305 | ret = -EBADF; | |
306 | } | |
307 | goto read_error; | |
308 | } | |
309 | /* Socket is open or opening. */ | |
310 | if (STATE_IS_PENDING(cf_sk)) { | |
311 | pr_debug("CAIF: %s(): socket is opening...\n", __func__); | |
312 | ||
313 | if (flags & MSG_DONTWAIT) { | |
314 | /* We can't block. */ | |
315 | pr_debug("CAIF: %s():state pending and MSG_DONTWAIT\n", | |
316 | __func__); | |
317 | ret = -EAGAIN; | |
318 | goto read_error; | |
319 | } | |
320 | ||
321 | /* | |
322 | * Blocking mode; state is pending and we need to wait | |
323 | * for its conclusion. | |
324 | */ | |
325 | release_sock(&cf_sk->sk); | |
326 | ||
327 | result = | |
328 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
329 | !STATE_IS_PENDING(cf_sk)); | |
330 | ||
331 | lock_sock(&(cf_sk->sk)); | |
332 | ||
333 | if (result == -ERESTARTSYS) { | |
334 | pr_debug("CAIF: %s(): wait_event_interruptible" | |
335 | " woken by a signal (1)", __func__); | |
336 | ret = -ERESTARTSYS; | |
337 | goto read_error; | |
338 | } | |
339 | } | |
340 | ||
341 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk) || | |
342 | !STATE_IS_OPEN(cf_sk) || | |
343 | STATE_IS_PENDING(cf_sk)) { | |
344 | ||
345 | pr_debug("CAIF: %s(): socket closed\n", | |
346 | __func__); | |
347 | ret = -ESHUTDOWN; | |
348 | goto read_error; | |
349 | } | |
350 | ||
351 | /* | |
352 | * Block if we don't have any received buffers. | |
353 | * The queue has its own lock. | |
354 | */ | |
355 | while ((pkt = cfpkt_qpeek(cf_sk->pktq)) == NULL) { | |
356 | ||
357 | if (flags & MSG_DONTWAIT) { | |
358 | pr_debug("CAIF: %s(): MSG_DONTWAIT\n", __func__); | |
359 | ret = -EAGAIN; | |
360 | goto read_error; | |
361 | } | |
362 | trace_printk("CAIF: %s() wait_event\n", __func__); | |
363 | ||
364 | /* Let writers in. */ | |
365 | release_sock(&cf_sk->sk); | |
366 | ||
367 | /* Block reader until data arrives or socket is closed. */ | |
368 | if (wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
369 | cfpkt_qpeek(cf_sk->pktq) | |
370 | || STATE_IS_REMOTE_SHUTDOWN(cf_sk) | |
371 | || !STATE_IS_OPEN(cf_sk)) == | |
372 | -ERESTARTSYS) { | |
373 | pr_debug("CAIF: %s():" | |
374 | " wait_event_interruptible woken by " | |
375 | "a signal, signal_pending(current) = %d\n", | |
376 | __func__, | |
377 | signal_pending(current)); | |
378 | return -ERESTARTSYS; | |
379 | } | |
380 | ||
381 | trace_printk("CAIF: %s() awake\n", __func__); | |
382 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) { | |
383 | pr_debug("CAIF: %s(): " | |
384 | "received remote_shutdown indication\n", | |
385 | __func__); | |
386 | ret = -ESHUTDOWN; | |
387 | goto read_error_no_unlock; | |
388 | } | |
389 | ||
390 | /* I want to be alone on cf_sk (except status and queue). */ | |
391 | lock_sock(&(cf_sk->sk)); | |
392 | ||
393 | if (!STATE_IS_OPEN(cf_sk)) { | |
394 | /* Someone closed the link, report error. */ | |
395 | pr_debug("CAIF: %s(): remote end shutdown!\n", | |
396 | __func__); | |
397 | ret = -EPIPE; | |
398 | goto read_error; | |
399 | } | |
400 | } | |
401 | ||
402 | /* The queue has its own lock. */ | |
403 | len = cfpkt_getlen(pkt); | |
404 | ||
405 | /* Check max length that can be copied. */ | |
406 | if (len <= buf_len) | |
407 | pkt = cfpkt_dequeue(cf_sk->pktq); | |
408 | else { | |
409 | pr_debug("CAIF: %s(): user buffer too small (%ld,%ld)\n", | |
410 | __func__, (long) len, (long) buf_len); | |
411 | if (sock->type == SOCK_SEQPACKET) { | |
412 | ret = -EMSGSIZE; | |
413 | goto read_error; | |
414 | } | |
415 | len = buf_len; | |
416 | } | |
417 | ||
418 | ||
419 | spin_lock(&cf_sk->read_queue_len_lock); | |
420 | cf_sk->read_queue_len--; | |
421 | read_queue_low = (cf_sk->read_queue_len < CHNL_SKT_READ_QUEUE_LOW); | |
422 | spin_unlock(&cf_sk->read_queue_len_lock); | |
423 | ||
424 | if (!RX_FLOW_IS_ON(cf_sk) && read_queue_low) { | |
425 | dbfs_atomic_inc(&cnt.num_rx_flow_on); | |
426 | SET_RX_FLOW_ON(cf_sk); | |
427 | ||
428 | /* Send flow on. */ | |
429 | pr_debug("CAIF: %s(): sending flow ON (queue len = %d)\n", | |
430 | __func__, cf_sk->read_queue_len); | |
431 | caif_assert(cf_sk->layer.dn); | |
432 | caif_assert(cf_sk->layer.dn->ctrlcmd); | |
433 | (void) cf_sk->layer.dn->modemcmd(cf_sk->layer.dn, | |
434 | CAIF_MODEMCMD_FLOW_ON_REQ); | |
435 | ||
436 | caif_assert(cf_sk->read_queue_len >= 0); | |
437 | } | |
438 | ||
439 | skb = cfpkt_tonative(pkt); | |
440 | result = skb_copy_datagram_iovec(skb, 0, m->msg_iov, len); | |
441 | skb_pull(skb, len); | |
442 | ||
443 | if (result) { | |
444 | pr_debug("CAIF: %s(): copy to_iovec failed\n", __func__); | |
445 | cfpkt_destroy(pkt); | |
446 | ret = -EFAULT; | |
447 | goto read_error; | |
448 | } | |
449 | ||
450 | /* Free packet and remove from queue */ | |
451 | if (skb->len == 0) | |
452 | skb_free_datagram(sk, skb); | |
453 | ||
454 | /* Let the others in. */ | |
455 | release_sock(&cf_sk->sk); | |
456 | return len; | |
457 | ||
458 | read_error: | |
459 | release_sock(&cf_sk->sk); | |
460 | read_error_no_unlock: | |
461 | return ret; | |
462 | } | |
463 | ||
464 | /* Send a signal as a consequence of sendmsg, sendto or caif_sendmsg. */ | |
465 | static int caif_sendmsg(struct kiocb *kiocb, struct socket *sock, | |
466 | struct msghdr *msg, size_t len) | |
467 | { | |
468 | ||
469 | struct sock *sk = sock->sk; | |
470 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | |
471 | size_t payload_size = msg->msg_iov->iov_len; | |
472 | struct cfpkt *pkt = NULL; | |
473 | struct caif_payload_info info; | |
474 | unsigned char *txbuf; | |
475 | ssize_t ret = -EIO; | |
476 | int result; | |
477 | struct sk_buff *skb; | |
478 | caif_assert(msg->msg_iovlen == 1); | |
479 | ||
480 | if (cf_sk == NULL) { | |
481 | pr_debug("CAIF: %s(): private_data not set!\n", | |
482 | __func__); | |
483 | ret = -EBADFD; | |
484 | goto write_error_no_unlock; | |
485 | } | |
486 | ||
487 | if (unlikely(msg->msg_iov->iov_base == NULL)) { | |
488 | pr_warning("CAIF: %s(): Buffer is NULL.\n", __func__); | |
489 | ret = -EINVAL; | |
490 | goto write_error_no_unlock; | |
491 | } | |
492 | ||
493 | if (payload_size > CAIF_MAX_PAYLOAD_SIZE) { | |
494 | pr_debug("CAIF: %s(): buffer too long\n", __func__); | |
495 | if (sock->type == SOCK_SEQPACKET) { | |
496 | ret = -EINVAL; | |
497 | goto write_error_no_unlock; | |
498 | } | |
499 | payload_size = CAIF_MAX_PAYLOAD_SIZE; | |
500 | } | |
501 | ||
502 | /* I want to be alone on cf_sk (except status and queue) */ | |
503 | lock_sock(&(cf_sk->sk)); | |
504 | ||
505 | caif_assert(cf_sk->pktq); | |
506 | ||
507 | if (!STATE_IS_OPEN(cf_sk)) { | |
508 | /* Socket is closed or closing */ | |
509 | if (!STATE_IS_PENDING(cf_sk)) { | |
510 | pr_debug("CAIF: %s(): socket is closed (by remote)\n", | |
511 | __func__); | |
512 | ret = -EPIPE; | |
513 | } else { | |
514 | pr_debug("CAIF: %s(): socket is closing...\n", | |
515 | __func__); | |
516 | ret = -EBADF; | |
517 | } | |
518 | goto write_error; | |
519 | } | |
520 | ||
521 | /* Socket is open or opening */ | |
522 | if (STATE_IS_PENDING(cf_sk)) { | |
523 | pr_debug("CAIF: %s(): socket is opening...\n", __func__); | |
524 | ||
525 | if (msg->msg_flags & MSG_DONTWAIT) { | |
526 | /* We can't block */ | |
527 | trace_printk("CAIF: %s():state pending:" | |
528 | "state=MSG_DONTWAIT\n", __func__); | |
529 | ret = -EAGAIN; | |
530 | goto write_error; | |
531 | } | |
532 | /* Let readers in */ | |
533 | release_sock(&cf_sk->sk); | |
534 | ||
535 | /* | |
536 | * Blocking mode; state is pending and we need to wait | |
537 | * for its conclusion. | |
538 | */ | |
539 | result = | |
540 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
541 | !STATE_IS_PENDING(cf_sk)); | |
542 | /* I want to be alone on cf_sk (except status and queue) */ | |
543 | lock_sock(&(cf_sk->sk)); | |
544 | ||
545 | if (result == -ERESTARTSYS) { | |
546 | pr_debug("CAIF: %s(): wait_event_interruptible" | |
547 | " woken by a signal (1)", __func__); | |
548 | ret = -ERESTARTSYS; | |
549 | goto write_error; | |
550 | } | |
551 | } | |
552 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk) || | |
553 | !STATE_IS_OPEN(cf_sk) || | |
554 | STATE_IS_PENDING(cf_sk)) { | |
555 | ||
556 | pr_debug("CAIF: %s(): socket closed\n", | |
557 | __func__); | |
558 | ret = -ESHUTDOWN; | |
559 | goto write_error; | |
560 | } | |
561 | ||
562 | if (!TX_FLOW_IS_ON(cf_sk)) { | |
563 | ||
564 | /* Flow is off. Check non-block flag */ | |
565 | if (msg->msg_flags & MSG_DONTWAIT) { | |
566 | trace_printk("CAIF: %s(): MSG_DONTWAIT and tx flow off", | |
567 | __func__); | |
568 | ret = -EAGAIN; | |
569 | goto write_error; | |
570 | } | |
571 | ||
572 | /* release lock before waiting */ | |
573 | release_sock(&cf_sk->sk); | |
574 | ||
575 | /* Wait until flow is on or socket is closed */ | |
576 | if (wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
577 | TX_FLOW_IS_ON(cf_sk) | |
578 | || !STATE_IS_OPEN(cf_sk) | |
579 | || STATE_IS_REMOTE_SHUTDOWN(cf_sk) | |
580 | ) == -ERESTARTSYS) { | |
581 | pr_debug("CAIF: %s():" | |
582 | " wait_event_interruptible woken by a signal", | |
583 | __func__); | |
584 | ret = -ERESTARTSYS; | |
585 | goto write_error_no_unlock; | |
586 | } | |
587 | ||
588 | /* I want to be alone on cf_sk (except status and queue) */ | |
589 | lock_sock(&(cf_sk->sk)); | |
590 | ||
591 | if (!STATE_IS_OPEN(cf_sk)) { | |
592 | /* someone closed the link, report error */ | |
593 | pr_debug("CAIF: %s(): remote end shutdown!\n", | |
594 | __func__); | |
595 | ret = -EPIPE; | |
596 | goto write_error; | |
597 | } | |
598 | ||
599 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) { | |
600 | pr_debug("CAIF: %s(): " | |
601 | "received remote_shutdown indication\n", | |
602 | __func__); | |
603 | ret = -ESHUTDOWN; | |
604 | goto write_error; | |
605 | } | |
606 | } | |
607 | ||
608 | pkt = cfpkt_create(payload_size); | |
609 | skb = (struct sk_buff *)pkt; | |
610 | skb->destructor = skb_destructor; | |
611 | skb->sk = sk; | |
612 | dbfs_atomic_inc(&cnt.skb_alloc); | |
613 | dbfs_atomic_inc(&cnt.skb_in_use); | |
614 | if (cfpkt_raw_append(pkt, (void **) &txbuf, payload_size) < 0) { | |
615 | pr_debug("CAIF: %s(): cfpkt_raw_append failed\n", __func__); | |
616 | cfpkt_destroy(pkt); | |
617 | ret = -EINVAL; | |
618 | goto write_error; | |
619 | } | |
620 | ||
621 | /* Copy data into buffer. */ | |
622 | if (copy_from_user(txbuf, msg->msg_iov->iov_base, payload_size)) { | |
623 | pr_debug("CAIF: %s(): copy_from_user returned non zero.\n", | |
624 | __func__); | |
625 | cfpkt_destroy(pkt); | |
626 | ret = -EINVAL; | |
627 | goto write_error; | |
628 | } | |
629 | memset(&info, 0, sizeof(info)); | |
630 | ||
631 | /* Send the packet down the stack. */ | |
632 | caif_assert(cf_sk->layer.dn); | |
633 | caif_assert(cf_sk->layer.dn->transmit); | |
634 | ||
635 | do { | |
636 | ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt); | |
637 | ||
638 | if (likely((ret >= 0) || (ret != -EAGAIN))) | |
639 | break; | |
640 | ||
641 | /* EAGAIN - retry */ | |
642 | if (msg->msg_flags & MSG_DONTWAIT) { | |
643 | pr_debug("CAIF: %s(): NONBLOCK and transmit failed," | |
644 | " error = %ld\n", __func__, (long) ret); | |
645 | ret = -EAGAIN; | |
646 | goto write_error; | |
647 | } | |
648 | ||
649 | /* Let readers in */ | |
650 | release_sock(&cf_sk->sk); | |
651 | ||
652 | /* Wait until flow is on or socket is closed */ | |
653 | if (wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
654 | TX_FLOW_IS_ON(cf_sk) | |
655 | || !STATE_IS_OPEN(cf_sk) | |
656 | || STATE_IS_REMOTE_SHUTDOWN(cf_sk) | |
657 | ) == -ERESTARTSYS) { | |
658 | pr_debug("CAIF: %s(): wait_event_interruptible" | |
659 | " woken by a signal", __func__); | |
660 | ret = -ERESTARTSYS; | |
661 | goto write_error_no_unlock; | |
662 | } | |
663 | ||
664 | /* I want to be alone on cf_sk (except status and queue) */ | |
665 | lock_sock(&(cf_sk->sk)); | |
666 | ||
667 | } while (ret == -EAGAIN); | |
668 | ||
669 | if (ret < 0) { | |
670 | cfpkt_destroy(pkt); | |
671 | pr_debug("CAIF: %s(): transmit failed, error = %ld\n", | |
672 | __func__, (long) ret); | |
673 | ||
674 | goto write_error; | |
675 | } | |
676 | ||
677 | release_sock(&cf_sk->sk); | |
678 | return payload_size; | |
679 | ||
680 | write_error: | |
681 | release_sock(&cf_sk->sk); | |
682 | write_error_no_unlock: | |
683 | return ret; | |
684 | } | |
685 | ||
686 | static unsigned int caif_poll(struct file *file, struct socket *sock, | |
687 | poll_table *wait) | |
688 | { | |
689 | struct sock *sk = sock->sk; | |
690 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | |
691 | u32 mask = 0; | |
692 | poll_wait(file, sk->sk_sleep, wait); | |
693 | lock_sock(&(cf_sk->sk)); | |
694 | if (!STATE_IS_OPEN(cf_sk)) { | |
695 | if (!STATE_IS_PENDING(cf_sk)) | |
696 | mask |= POLLHUP; | |
697 | } else { | |
698 | if (cfpkt_qpeek(cf_sk->pktq) != NULL) | |
699 | mask |= (POLLIN | POLLRDNORM); | |
700 | if (TX_FLOW_IS_ON(cf_sk)) | |
701 | mask |= (POLLOUT | POLLWRNORM); | |
702 | } | |
703 | release_sock(&cf_sk->sk); | |
704 | trace_printk("CAIF: %s(): poll mask=0x%04x\n", | |
705 | __func__, mask); | |
706 | return mask; | |
707 | } | |
708 | ||
709 | static void drain_queue(struct caifsock *cf_sk) | |
710 | { | |
711 | struct cfpkt *pkt = NULL; | |
712 | ||
713 | /* Empty the queue */ | |
714 | do { | |
715 | /* The queue has its own lock */ | |
716 | if (!cf_sk->pktq) | |
717 | break; | |
718 | ||
719 | pkt = cfpkt_dequeue(cf_sk->pktq); | |
720 | if (!pkt) | |
721 | break; | |
722 | pr_debug("CAIF: %s(): freeing packet from read queue\n", | |
723 | __func__); | |
724 | cfpkt_destroy(pkt); | |
725 | ||
726 | } while (1); | |
727 | ||
728 | cf_sk->read_queue_len = 0; | |
729 | } | |
730 | ||
731 | static int setsockopt(struct socket *sock, | |
732 | int lvl, int opt, char __user *ov, unsigned int ol) | |
733 | { | |
734 | struct sock *sk = sock->sk; | |
735 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | |
736 | int prio, linksel; | |
737 | struct ifreq ifreq; | |
738 | ||
739 | if (STATE_IS_OPEN(cf_sk)) { | |
740 | pr_debug("CAIF: %s(): setsockopt " | |
741 | "cannot be done on a connected socket\n", | |
742 | __func__); | |
743 | return -ENOPROTOOPT; | |
744 | } | |
745 | switch (opt) { | |
746 | case CAIFSO_LINK_SELECT: | |
747 | if (ol < sizeof(int)) { | |
748 | pr_debug("CAIF: %s(): setsockopt" | |
749 | " CAIFSO_CHANNEL_CONFIG bad size\n", __func__); | |
750 | return -EINVAL; | |
751 | } | |
752 | if (lvl != SOL_CAIF) | |
753 | goto bad_sol; | |
754 | if (copy_from_user(&linksel, ov, sizeof(int))) | |
755 | return -EINVAL; | |
756 | lock_sock(&(cf_sk->sk)); | |
757 | cf_sk->conn_req.link_selector = linksel; | |
758 | release_sock(&cf_sk->sk); | |
759 | return 0; | |
760 | ||
761 | case SO_PRIORITY: | |
762 | if (lvl != SOL_SOCKET) | |
763 | goto bad_sol; | |
764 | if (ol < sizeof(int)) { | |
765 | pr_debug("CAIF: %s(): setsockopt" | |
766 | " SO_PRIORITY bad size\n", __func__); | |
767 | return -EINVAL; | |
768 | } | |
769 | if (copy_from_user(&prio, ov, sizeof(int))) | |
770 | return -EINVAL; | |
771 | lock_sock(&(cf_sk->sk)); | |
772 | cf_sk->conn_req.priority = prio; | |
773 | pr_debug("CAIF: %s(): Setting sockopt priority=%d\n", __func__, | |
774 | cf_sk->conn_req.priority); | |
775 | release_sock(&cf_sk->sk); | |
776 | return 0; | |
777 | ||
778 | case SO_BINDTODEVICE: | |
779 | if (lvl != SOL_SOCKET) | |
780 | goto bad_sol; | |
781 | if (ol < sizeof(struct ifreq)) { | |
782 | pr_debug("CAIF: %s(): setsockopt" | |
783 | " SO_PRIORITY bad size\n", __func__); | |
784 | return -EINVAL; | |
785 | } | |
786 | if (copy_from_user(&ifreq, ov, sizeof(ifreq))) | |
787 | return -EFAULT; | |
788 | lock_sock(&(cf_sk->sk)); | |
789 | strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name, | |
790 | sizeof(cf_sk->conn_req.link_name)); | |
791 | cf_sk->conn_req.link_name | |
792 | [sizeof(cf_sk->conn_req.link_name)-1] = 0; | |
793 | release_sock(&cf_sk->sk); | |
794 | return 0; | |
795 | ||
796 | case CAIFSO_REQ_PARAM: | |
797 | if (lvl != SOL_CAIF) | |
798 | goto bad_sol; | |
799 | if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL) | |
800 | return -ENOPROTOOPT; | |
801 | if (ol > sizeof(cf_sk->conn_req.param.data)) | |
802 | goto req_param_bad_size; | |
803 | ||
804 | lock_sock(&(cf_sk->sk)); | |
805 | cf_sk->conn_req.param.size = ol; | |
806 | if (copy_from_user(&cf_sk->conn_req.param.data, ov, ol)) { | |
807 | release_sock(&cf_sk->sk); | |
808 | req_param_bad_size: | |
809 | pr_debug("CAIF: %s(): setsockopt" | |
810 | " CAIFSO_CHANNEL_CONFIG bad size\n", __func__); | |
811 | return -EINVAL; | |
812 | } | |
813 | ||
814 | release_sock(&cf_sk->sk); | |
815 | return 0; | |
816 | ||
817 | default: | |
818 | pr_debug("CAIF: %s(): unhandled option %d\n", __func__, opt); | |
819 | return -EINVAL; | |
820 | } | |
821 | ||
822 | return 0; | |
823 | bad_sol: | |
824 | pr_debug("CAIF: %s(): setsockopt bad level\n", __func__); | |
825 | return -ENOPROTOOPT; | |
826 | ||
827 | } | |
828 | ||
829 | static int caif_connect(struct socket *sock, struct sockaddr *uservaddr, | |
830 | int sockaddr_len, int flags) | |
831 | { | |
832 | struct caifsock *cf_sk = NULL; | |
833 | int result = -1; | |
834 | int mode = 0; | |
835 | int ret = -EIO; | |
836 | struct sock *sk = sock->sk; | |
837 | BUG_ON(sk == NULL); | |
838 | ||
839 | cf_sk = container_of(sk, struct caifsock, sk); | |
840 | ||
841 | trace_printk("CAIF: %s(): cf_sk=%p OPEN=%d, TX_FLOW=%d, RX_FLOW=%d\n", | |
842 | __func__, cf_sk, | |
843 | STATE_IS_OPEN(cf_sk), | |
844 | TX_FLOW_IS_ON(cf_sk), RX_FLOW_IS_ON(cf_sk)); | |
845 | ||
846 | ||
847 | if (sock->type == SOCK_SEQPACKET || sock->type == SOCK_STREAM) | |
848 | sock->state = SS_CONNECTING; | |
849 | else | |
850 | goto out; | |
851 | ||
852 | /* I want to be alone on cf_sk (except status and queue) */ | |
853 | lock_sock(&(cf_sk->sk)); | |
854 | ||
855 | if (sockaddr_len != sizeof(struct sockaddr_caif)) { | |
856 | pr_debug("CAIF: %s(): Bad address len (%ld,%lu)\n", | |
857 | __func__, (long) sockaddr_len, | |
858 | (long unsigned) sizeof(struct sockaddr_caif)); | |
859 | ret = -EINVAL; | |
860 | goto open_error; | |
861 | } | |
862 | ||
863 | if (uservaddr->sa_family != AF_CAIF) { | |
864 | pr_debug("CAIF: %s(): Bad address family (%d)\n", | |
865 | __func__, uservaddr->sa_family); | |
866 | ret = -EAFNOSUPPORT; | |
867 | goto open_error; | |
868 | } | |
869 | ||
870 | memcpy(&cf_sk->conn_req.sockaddr, uservaddr, | |
871 | sizeof(struct sockaddr_caif)); | |
872 | ||
873 | dbfs_atomic_inc(&cnt.num_open); | |
874 | mode = SKT_READ_FLAG | SKT_WRITE_FLAG; | |
875 | ||
876 | /* If socket is not open, make sure socket is in fully closed state */ | |
877 | if (!STATE_IS_OPEN(cf_sk)) { | |
878 | /* Has link close response been received (if we ever sent it)?*/ | |
879 | if (STATE_IS_PENDING(cf_sk)) { | |
880 | /* | |
881 | * Still waiting for close response from remote. | |
882 | * If opened non-blocking, report "would block" | |
883 | */ | |
884 | if (flags & O_NONBLOCK) { | |
885 | pr_debug("CAIF: %s(): O_NONBLOCK" | |
886 | " && close pending\n", __func__); | |
887 | ret = -EAGAIN; | |
888 | goto open_error; | |
889 | } | |
890 | ||
891 | pr_debug("CAIF: %s(): Wait for close response" | |
892 | " from remote...\n", __func__); | |
893 | ||
894 | release_sock(&cf_sk->sk); | |
895 | ||
896 | /* | |
897 | * Blocking mode; close is pending and we need to wait | |
898 | * for its conclusion. | |
899 | */ | |
900 | result = | |
901 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
902 | !STATE_IS_PENDING(cf_sk)); | |
903 | ||
904 | lock_sock(&(cf_sk->sk)); | |
905 | if (result == -ERESTARTSYS) { | |
906 | pr_debug("CAIF: %s(): wait_event_interruptible" | |
907 | "woken by a signal (1)", __func__); | |
908 | ret = -ERESTARTSYS; | |
909 | goto open_error; | |
910 | } | |
911 | } | |
912 | } | |
913 | ||
914 | /* socket is now either closed, pending open or open */ | |
915 | if (STATE_IS_OPEN(cf_sk) && !STATE_IS_PENDING(cf_sk)) { | |
916 | /* Open */ | |
917 | pr_debug("CAIF: %s(): Socket is already opened (cf_sk=%p)" | |
918 | " check access f_flags = 0x%x file_mode = 0x%x\n", | |
919 | __func__, cf_sk, mode, cf_sk->file_mode); | |
920 | ||
921 | } else { | |
922 | /* We are closed or pending open. | |
923 | * If closed: send link setup | |
924 | * If pending open: link setup already sent (we could have been | |
925 | * interrupted by a signal last time) | |
926 | */ | |
927 | if (!STATE_IS_OPEN(cf_sk)) { | |
928 | /* First opening of file; connect lower layers: */ | |
929 | /* Drain queue (very unlikely) */ | |
930 | drain_queue(cf_sk); | |
931 | ||
932 | cf_sk->layer.receive = caif_sktrecv_cb; | |
933 | SET_STATE_OPEN(cf_sk); | |
934 | SET_PENDING_ON(cf_sk); | |
935 | ||
936 | /* Register this channel. */ | |
937 | result = | |
938 | caif_connect_client(&cf_sk->conn_req, | |
939 | &cf_sk->layer); | |
940 | if (result < 0) { | |
941 | pr_debug("CAIF: %s(): can't register channel\n", | |
942 | __func__); | |
943 | ret = -EIO; | |
944 | SET_STATE_CLOSED(cf_sk); | |
945 | SET_PENDING_OFF(cf_sk); | |
946 | goto open_error; | |
947 | } | |
948 | dbfs_atomic_inc(&cnt.num_init); | |
949 | } | |
950 | ||
951 | /* If opened non-blocking, report "success". | |
952 | */ | |
953 | if (flags & O_NONBLOCK) { | |
954 | pr_debug("CAIF: %s(): O_NONBLOCK success\n", | |
955 | __func__); | |
956 | ret = -EINPROGRESS; | |
957 | cf_sk->sk.sk_err = -EINPROGRESS; | |
958 | goto open_error; | |
959 | } | |
960 | ||
961 | trace_printk("CAIF: %s(): Wait for connect response\n", | |
962 | __func__); | |
963 | ||
964 | /* release lock before waiting */ | |
965 | release_sock(&cf_sk->sk); | |
966 | ||
967 | result = | |
968 | wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
969 | !STATE_IS_PENDING(cf_sk)); | |
970 | ||
971 | lock_sock(&(cf_sk->sk)); | |
972 | ||
973 | if (result == -ERESTARTSYS) { | |
974 | pr_debug("CAIF: %s(): wait_event_interruptible" | |
975 | "woken by a signal (2)", __func__); | |
976 | ret = -ERESTARTSYS; | |
977 | goto open_error; | |
978 | } | |
979 | ||
980 | if (!STATE_IS_OPEN(cf_sk)) { | |
981 | /* Lower layers said "no" */ | |
982 | pr_debug("CAIF: %s(): Closed received\n", __func__); | |
983 | ret = -EPIPE; | |
984 | goto open_error; | |
985 | } | |
986 | ||
987 | trace_printk("CAIF: %s(): Connect received\n", __func__); | |
988 | } | |
989 | /* Open is ok */ | |
990 | cf_sk->file_mode |= mode; | |
991 | ||
992 | trace_printk("CAIF: %s(): Connected - file mode = %x\n", | |
993 | __func__, cf_sk->file_mode); | |
994 | ||
995 | release_sock(&cf_sk->sk); | |
996 | return 0; | |
997 | open_error: | |
998 | sock->state = SS_UNCONNECTED; | |
999 | release_sock(&cf_sk->sk); | |
1000 | out: | |
1001 | return ret; | |
1002 | } | |
1003 | ||
1004 | static int caif_shutdown(struct socket *sock, int how) | |
1005 | { | |
1006 | struct caifsock *cf_sk = NULL; | |
1007 | int result = 0; | |
1008 | int tx_flow_state_was_on; | |
1009 | struct sock *sk = sock->sk; | |
1010 | ||
1011 | trace_printk("CAIF: %s(): enter\n", __func__); | |
1012 | pr_debug("f_flags=%x\n", sock->file->f_flags); | |
1013 | ||
1014 | if (how != SHUT_RDWR) | |
1015 | return -EOPNOTSUPP; | |
1016 | ||
1017 | cf_sk = container_of(sk, struct caifsock, sk); | |
1018 | if (cf_sk == NULL) { | |
1019 | pr_debug("CAIF: %s(): COULD NOT FIND SOCKET\n", __func__); | |
1020 | return -EBADF; | |
1021 | } | |
1022 | ||
1023 | /* I want to be alone on cf_sk (except status queue) */ | |
1024 | lock_sock(&(cf_sk->sk)); | |
1025 | sock_hold(&cf_sk->sk); | |
1026 | ||
1027 | /* IS_CLOSED have double meaning: | |
1028 | * 1) Spontanous Remote Shutdown Request. | |
1029 | * 2) Ack on a channel teardown(disconnect) | |
1030 | * Must clear bit in case we previously received | |
1031 | * remote shudown request. | |
1032 | */ | |
1033 | if (STATE_IS_OPEN(cf_sk) && !STATE_IS_PENDING(cf_sk)) { | |
1034 | SET_STATE_CLOSED(cf_sk); | |
1035 | SET_PENDING_ON(cf_sk); | |
1036 | tx_flow_state_was_on = TX_FLOW_IS_ON(cf_sk); | |
1037 | SET_TX_FLOW_OFF(cf_sk); | |
1038 | ||
1039 | /* Hold the socket until DEINIT_RSP is received */ | |
1040 | sock_hold(&cf_sk->sk); | |
1041 | result = caif_disconnect_client(&cf_sk->layer); | |
1042 | ||
1043 | if (result < 0) { | |
1044 | pr_debug("CAIF: %s(): " | |
1045 | "caif_disconnect_client() failed\n", | |
1046 | __func__); | |
1047 | SET_STATE_CLOSED(cf_sk); | |
1048 | SET_PENDING_OFF(cf_sk); | |
1049 | SET_TX_FLOW_OFF(cf_sk); | |
1050 | release_sock(&cf_sk->sk); | |
1051 | sock_put(&cf_sk->sk); | |
1052 | return -EIO; | |
1053 | } | |
1054 | ||
1055 | } | |
1056 | if (STATE_IS_REMOTE_SHUTDOWN(cf_sk)) { | |
1057 | SET_PENDING_OFF(cf_sk); | |
1058 | SET_REMOTE_SHUTDOWN_OFF(cf_sk); | |
1059 | } | |
1060 | ||
1061 | /* | |
1062 | * Socket is no longer in state pending close, | |
1063 | * and we can release the reference. | |
1064 | */ | |
1065 | ||
1066 | dbfs_atomic_inc(&cnt.num_close); | |
1067 | drain_queue(cf_sk); | |
1068 | SET_RX_FLOW_ON(cf_sk); | |
1069 | cf_sk->file_mode = 0; | |
1070 | sock_put(&cf_sk->sk); | |
1071 | release_sock(&cf_sk->sk); | |
1072 | if (!result && (sock->file->f_flags & O_NONBLOCK)) { | |
1073 | pr_debug("nonblocking shutdown returing -EAGAIN\n"); | |
1074 | return -EAGAIN; | |
1075 | } else | |
1076 | return result; | |
1077 | } | |
1078 | ||
1079 | static ssize_t caif_sock_no_sendpage(struct socket *sock, | |
1080 | struct page *page, | |
1081 | int offset, size_t size, int flags) | |
1082 | { | |
1083 | return -EOPNOTSUPP; | |
1084 | } | |
1085 | ||
1086 | /* This function is called as part of close. */ | |
1087 | static int caif_release(struct socket *sock) | |
1088 | { | |
1089 | struct sock *sk = sock->sk; | |
1090 | struct caifsock *cf_sk = NULL; | |
1091 | int res; | |
1092 | caif_assert(sk != NULL); | |
1093 | cf_sk = container_of(sk, struct caifsock, sk); | |
1094 | ||
1095 | if (cf_sk->debugfs_socket_dir != NULL) | |
1096 | debugfs_remove_recursive(cf_sk->debugfs_socket_dir); | |
1097 | ||
1098 | res = caif_shutdown(sock, SHUT_RDWR); | |
1099 | if (res && res != -EINPROGRESS) | |
1100 | return res; | |
1101 | ||
1102 | /* | |
1103 | * FIXME: Shutdown should probably be possible to do async | |
1104 | * without flushing queues, allowing reception of frames while | |
1105 | * waiting for DEINIT_IND. | |
1106 | * Release should always block, to allow secure decoupling of | |
1107 | * CAIF stack. | |
1108 | */ | |
1109 | if (!(sock->file->f_flags & O_NONBLOCK)) { | |
1110 | res = wait_event_interruptible(*cf_sk->sk.sk_sleep, | |
1111 | !STATE_IS_PENDING(cf_sk)); | |
1112 | ||
1113 | if (res == -ERESTARTSYS) { | |
1114 | pr_debug("CAIF: %s(): wait_event_interruptible" | |
1115 | "woken by a signal (1)", __func__); | |
1116 | } | |
1117 | } | |
1118 | lock_sock(&(cf_sk->sk)); | |
1119 | ||
1120 | sock->sk = NULL; | |
1121 | ||
1122 | /* Detach the socket from its process context by making it orphan. */ | |
1123 | sock_orphan(sk); | |
1124 | ||
1125 | /* | |
1126 | * Setting SHUTDOWN_MASK means that both send and receive are shutdown | |
1127 | * for the socket. | |
1128 | */ | |
1129 | sk->sk_shutdown = SHUTDOWN_MASK; | |
1130 | ||
1131 | /* | |
1132 | * Set the socket state to closed, the TCP_CLOSE macro is used when | |
1133 | * closing any socket. | |
1134 | */ | |
1135 | ||
1136 | /* Flush out this sockets receive queue. */ | |
1137 | drain_queue(cf_sk); | |
1138 | ||
1139 | /* Finally release the socket. */ | |
1140 | SET_STATE_PENDING_DESTROY(cf_sk); | |
1141 | ||
1142 | release_sock(&cf_sk->sk); | |
1143 | ||
1144 | sock_put(sk); | |
1145 | ||
1146 | /* | |
1147 | * The rest of the cleanup will be handled from the | |
1148 | * caif_sock_destructor | |
1149 | */ | |
1150 | return res; | |
1151 | } | |
1152 | ||
1153 | static const struct proto_ops caif_ops = { | |
1154 | .family = PF_CAIF, | |
1155 | .owner = THIS_MODULE, | |
1156 | .release = caif_release, | |
1157 | .bind = sock_no_bind, | |
1158 | .connect = caif_connect, | |
1159 | .socketpair = sock_no_socketpair, | |
1160 | .accept = sock_no_accept, | |
1161 | .getname = sock_no_getname, | |
1162 | .poll = caif_poll, | |
1163 | .ioctl = sock_no_ioctl, | |
1164 | .listen = sock_no_listen, | |
1165 | .shutdown = caif_shutdown, | |
1166 | .setsockopt = setsockopt, | |
1167 | .getsockopt = sock_no_getsockopt, | |
1168 | .sendmsg = caif_sendmsg, | |
1169 | .recvmsg = caif_recvmsg, | |
1170 | .mmap = sock_no_mmap, | |
1171 | .sendpage = caif_sock_no_sendpage, | |
1172 | }; | |
1173 | ||
1174 | /* This function is called when a socket is finally destroyed. */ | |
1175 | static void caif_sock_destructor(struct sock *sk) | |
1176 | { | |
1177 | struct caifsock *cf_sk = NULL; | |
1178 | cf_sk = container_of(sk, struct caifsock, sk); | |
1179 | /* Error checks. */ | |
1180 | caif_assert(!atomic_read(&sk->sk_wmem_alloc)); | |
1181 | caif_assert(sk_unhashed(sk)); | |
1182 | caif_assert(!sk->sk_socket); | |
1183 | if (!sock_flag(sk, SOCK_DEAD)) { | |
1184 | pr_debug("CAIF: %s(): 0x%p", __func__, sk); | |
1185 | return; | |
1186 | } | |
1187 | ||
1188 | if (STATE_IS_OPEN(cf_sk)) { | |
1189 | pr_debug("CAIF: %s(): socket is opened (cf_sk=%p)" | |
1190 | " file_mode = 0x%x\n", __func__, | |
1191 | cf_sk, cf_sk->file_mode); | |
1192 | return; | |
1193 | } | |
1194 | drain_queue(cf_sk); | |
1195 | kfree(cf_sk->pktq); | |
1196 | ||
1197 | trace_printk("CAIF: %s(): caif_sock_destructor: Removing socket %s\n", | |
1198 | __func__, cf_sk->name); | |
1199 | atomic_dec(&caif_nr_socks); | |
1200 | } | |
1201 | ||
1202 | static int caif_create(struct net *net, struct socket *sock, int protocol, | |
1203 | int kern) | |
1204 | { | |
1205 | struct sock *sk = NULL; | |
1206 | struct caifsock *cf_sk = NULL; | |
1207 | int result = 0; | |
1208 | static struct proto prot = {.name = "PF_CAIF", | |
1209 | .owner = THIS_MODULE, | |
1210 | .obj_size = sizeof(struct caifsock), | |
1211 | }; | |
1212 | ||
1213 | /* | |
1214 | * The sock->type specifies the socket type to use. | |
1215 | * in SEQPACKET mode packet boundaries are enforced. | |
1216 | */ | |
1217 | if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) | |
1218 | return -ESOCKTNOSUPPORT; | |
1219 | ||
1220 | if (net != &init_net) | |
1221 | return -EAFNOSUPPORT; | |
1222 | ||
1223 | if (protocol < 0 || protocol >= CAIFPROTO_MAX) | |
1224 | return -EPROTONOSUPPORT; | |
1225 | /* | |
1226 | * Set the socket state to unconnected. The socket state is really | |
1227 | * not used at all in the net/core or socket.c but the | |
1228 | * initialization makes sure that sock->state is not uninitialized. | |
1229 | */ | |
1230 | sock->state = SS_UNCONNECTED; | |
1231 | ||
1232 | sk = sk_alloc(net, PF_CAIF, GFP_KERNEL, &prot); | |
1233 | if (!sk) | |
1234 | return -ENOMEM; | |
1235 | ||
1236 | cf_sk = container_of(sk, struct caifsock, sk); | |
1237 | ||
1238 | /* Store the protocol */ | |
1239 | sk->sk_protocol = (unsigned char) protocol; | |
1240 | ||
1241 | spin_lock_init(&cf_sk->read_queue_len_lock); | |
1242 | ||
1243 | /* Fill in some information concerning the misc socket. */ | |
1244 | snprintf(cf_sk->name, sizeof(cf_sk->name), "cf_sk%d", | |
1245 | atomic_read(&caif_nr_socks)); | |
1246 | ||
1247 | /* | |
1248 | * Lock in order to try to stop someone from opening the socket | |
1249 | * too early. | |
1250 | */ | |
1251 | lock_sock(&(cf_sk->sk)); | |
1252 | ||
1253 | /* Initialize the nozero default sock structure data. */ | |
1254 | sock_init_data(sock, sk); | |
1255 | sock->ops = &caif_ops; | |
1256 | sk->sk_destruct = caif_sock_destructor; | |
1257 | sk->sk_sndbuf = caif_sockbuf_size; | |
1258 | sk->sk_rcvbuf = caif_sockbuf_size; | |
1259 | ||
1260 | cf_sk->pktq = cfpktq_create(); | |
1261 | ||
1262 | if (!cf_sk->pktq) { | |
1263 | pr_err("CAIF: %s(): queue create failed.\n", __func__); | |
1264 | result = -ENOMEM; | |
1265 | release_sock(&cf_sk->sk); | |
1266 | goto err_failed; | |
1267 | } | |
1268 | cf_sk->layer.ctrlcmd = caif_sktflowctrl_cb; | |
1269 | SET_STATE_CLOSED(cf_sk); | |
1270 | SET_PENDING_OFF(cf_sk); | |
1271 | SET_TX_FLOW_OFF(cf_sk); | |
1272 | SET_RX_FLOW_ON(cf_sk); | |
1273 | ||
1274 | /* Set default options on configuration */ | |
1275 | cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; | |
1276 | cf_sk->conn_req.link_selector = CAIF_LINK_HIGH_BANDW; | |
1277 | cf_sk->conn_req.protocol = protocol; | |
1278 | /* Increase the number of sockets created. */ | |
1279 | atomic_inc(&caif_nr_socks); | |
1280 | if (!IS_ERR(debugfsdir)) { | |
1281 | cf_sk->debugfs_socket_dir = | |
1282 | debugfs_create_dir(cf_sk->name, debugfsdir); | |
1283 | debugfs_create_u32("conn_state", S_IRUSR | S_IWUSR, | |
1284 | cf_sk->debugfs_socket_dir, &cf_sk->conn_state); | |
1285 | debugfs_create_u32("flow_state", S_IRUSR | S_IWUSR, | |
1286 | cf_sk->debugfs_socket_dir, &cf_sk->flow_state); | |
1287 | debugfs_create_u32("read_queue_len", S_IRUSR | S_IWUSR, | |
1288 | cf_sk->debugfs_socket_dir, | |
1289 | (u32 *) &cf_sk->read_queue_len); | |
1290 | debugfs_create_u32("identity", S_IRUSR | S_IWUSR, | |
1291 | cf_sk->debugfs_socket_dir, | |
1292 | (u32 *) &cf_sk->layer.id); | |
1293 | } | |
1294 | release_sock(&cf_sk->sk); | |
1295 | return 0; | |
1296 | err_failed: | |
1297 | sk_free(sk); | |
1298 | return result; | |
1299 | } | |
1300 | ||
1301 | static struct net_proto_family caif_family_ops = { | |
1302 | .family = PF_CAIF, | |
1303 | .create = caif_create, | |
1304 | .owner = THIS_MODULE, | |
1305 | }; | |
1306 | ||
1307 | static int af_caif_init(void) | |
1308 | { | |
1309 | int err; | |
1310 | err = sock_register(&caif_family_ops); | |
1311 | ||
1312 | if (!err) | |
1313 | return err; | |
1314 | ||
1315 | return 0; | |
1316 | } | |
1317 | ||
1318 | static int __init caif_sktinit_module(void) | |
1319 | { | |
1320 | int stat; | |
1321 | #ifdef CONFIG_DEBUG_FS | |
1322 | debugfsdir = debugfs_create_dir("chnl_skt", NULL); | |
1323 | if (!IS_ERR(debugfsdir)) { | |
1324 | debugfs_create_u32("skb_inuse", S_IRUSR | S_IWUSR, | |
1325 | debugfsdir, | |
1326 | (u32 *) &cnt.skb_in_use); | |
1327 | debugfs_create_u32("skb_alloc", S_IRUSR | S_IWUSR, | |
1328 | debugfsdir, | |
1329 | (u32 *) &cnt.skb_alloc); | |
1330 | debugfs_create_u32("skb_free", S_IRUSR | S_IWUSR, | |
1331 | debugfsdir, | |
1332 | (u32 *) &cnt.skb_free); | |
1333 | debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR, | |
1334 | debugfsdir, | |
1335 | (u32 *) &caif_nr_socks); | |
1336 | debugfs_create_u32("num_open", S_IRUSR | S_IWUSR, | |
1337 | debugfsdir, | |
1338 | (u32 *) &cnt.num_open); | |
1339 | debugfs_create_u32("num_close", S_IRUSR | S_IWUSR, | |
1340 | debugfsdir, | |
1341 | (u32 *) &cnt.num_close); | |
1342 | debugfs_create_u32("num_init", S_IRUSR | S_IWUSR, | |
1343 | debugfsdir, | |
1344 | (u32 *) &cnt.num_init); | |
1345 | debugfs_create_u32("num_init_resp", S_IRUSR | S_IWUSR, | |
1346 | debugfsdir, | |
1347 | (u32 *) &cnt.num_init_resp); | |
1348 | debugfs_create_u32("num_init_fail_resp", S_IRUSR | S_IWUSR, | |
1349 | debugfsdir, | |
1350 | (u32 *) &cnt.num_init_fail_resp); | |
1351 | debugfs_create_u32("num_deinit", S_IRUSR | S_IWUSR, | |
1352 | debugfsdir, | |
1353 | (u32 *) &cnt.num_deinit); | |
1354 | debugfs_create_u32("num_deinit_resp", S_IRUSR | S_IWUSR, | |
1355 | debugfsdir, | |
1356 | (u32 *) &cnt.num_deinit_resp); | |
1357 | debugfs_create_u32("num_remote_shutdown_ind", | |
1358 | S_IRUSR | S_IWUSR, debugfsdir, | |
1359 | (u32 *) &cnt.num_remote_shutdown_ind); | |
1360 | debugfs_create_u32("num_tx_flow_off_ind", S_IRUSR | S_IWUSR, | |
1361 | debugfsdir, | |
1362 | (u32 *) &cnt.num_tx_flow_off_ind); | |
1363 | debugfs_create_u32("num_tx_flow_on_ind", S_IRUSR | S_IWUSR, | |
1364 | debugfsdir, | |
1365 | (u32 *) &cnt.num_tx_flow_on_ind); | |
1366 | debugfs_create_u32("num_rx_flow_off", S_IRUSR | S_IWUSR, | |
1367 | debugfsdir, | |
1368 | (u32 *) &cnt.num_rx_flow_off); | |
1369 | debugfs_create_u32("num_rx_flow_on", S_IRUSR | S_IWUSR, | |
1370 | debugfsdir, | |
1371 | (u32 *) &cnt.num_rx_flow_on); | |
1372 | } | |
1373 | #endif | |
1374 | stat = af_caif_init(); | |
1375 | if (stat) { | |
1376 | pr_err("CAIF: %s(): Failed to initialize CAIF socket layer.", | |
1377 | __func__); | |
1378 | return stat; | |
1379 | } | |
1380 | return 0; | |
1381 | } | |
1382 | ||
1383 | static void __exit caif_sktexit_module(void) | |
1384 | { | |
1385 | sock_unregister(PF_CAIF); | |
1386 | if (debugfsdir != NULL) | |
1387 | debugfs_remove_recursive(debugfsdir); | |
1388 | } | |
1389 | ||
1390 | module_init(caif_sktinit_module); | |
1391 | module_exit(caif_sktexit_module); |