Lines 53-59
#undef BT_DBG
Link Here
|
53 |
#define BT_DBG(D...) |
53 |
#define BT_DBG(D...) |
54 |
#endif |
54 |
#endif |
55 |
|
55 |
|
56 |
#define VERSION "0.5" |
56 |
#define VERSION "0.6" |
|
|
57 |
|
58 |
#define MAX_SCO_TXBUFS 200 |
59 |
#define MAX_SCO_RXBUFS 200 |
60 |
|
61 |
#define DEFAULT_SCO_TXBUFS 5 |
62 |
#define DEFAULT_SCO_RXBUFS 5 |
57 |
|
63 |
|
58 |
static const struct proto_ops sco_sock_ops; |
64 |
static const struct proto_ops sco_sock_ops; |
59 |
|
65 |
|
Lines 69-74
static int sco_conn_del(struct hci_conn
Link Here
|
69 |
static void sco_sock_close(struct sock *sk); |
75 |
static void sco_sock_close(struct sock *sk); |
70 |
static void sco_sock_kill(struct sock *sk); |
76 |
static void sco_sock_kill(struct sock *sk); |
71 |
|
77 |
|
|
|
78 |
/* |
79 |
* Write buffer destructor automatically called from kfree_skb. |
80 |
*/ |
81 |
void sco_sock_wfree(struct sk_buff *skb) |
82 |
{ |
83 |
struct sock *sk = skb->sk; |
84 |
|
85 |
atomic_dec(&sk->sk_wmem_alloc); |
86 |
sk->sk_write_space(sk); |
87 |
sock_put(sk); |
88 |
} |
89 |
|
90 |
static void sco_sock_write_space(struct sock *sk) |
91 |
{ |
92 |
read_lock(&sk->sk_callback_lock); |
93 |
|
94 |
if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { |
95 |
if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
96 |
wake_up_interruptible(sk->sk_sleep); |
97 |
|
98 |
if (sock_writeable(sk)) |
99 |
sk_wake_async(sk, 2, POLL_OUT); |
100 |
} |
101 |
|
102 |
read_unlock(&sk->sk_callback_lock); |
103 |
} |
104 |
|
72 |
/* ---- SCO timers ---- */ |
105 |
/* ---- SCO timers ---- */ |
73 |
static void sco_sock_timeout(unsigned long arg) |
106 |
static void sco_sock_timeout(unsigned long arg) |
74 |
{ |
107 |
{ |
Lines 234-266
static inline int sco_send_frame(struct
Link Here
|
234 |
{ |
267 |
{ |
235 |
struct sco_conn *conn = sco_pi(sk)->conn; |
268 |
struct sco_conn *conn = sco_pi(sk)->conn; |
236 |
struct sk_buff *skb; |
269 |
struct sk_buff *skb; |
237 |
int err, count; |
270 |
int err; |
238 |
|
|
|
239 |
/* Check outgoing MTU */ |
240 |
if (len > conn->mtu) |
241 |
return -EINVAL; |
242 |
|
271 |
|
243 |
BT_DBG("sk %p len %d", sk, len); |
272 |
BT_DBG("sk %p len %d", sk, len); |
244 |
|
273 |
|
245 |
count = min_t(unsigned int, conn->mtu, len); |
274 |
if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) |
246 |
if (!(skb = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err))) |
|
|
247 |
return err; |
275 |
return err; |
248 |
|
276 |
|
249 |
if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) { |
277 |
/* fix sk_wmem_alloc value : by default it is increased by skb->truesize, but |
|
|
278 |
we want it only increased by 1 */ |
279 |
atomic_sub(skb->truesize - 1, &sk->sk_wmem_alloc); |
280 |
/* fix destructor */ |
281 |
skb->destructor = sco_sock_wfree; |
282 |
|
283 |
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { |
250 |
err = -EFAULT; |
284 |
err = -EFAULT; |
251 |
goto fail; |
285 |
goto fail; |
252 |
} |
286 |
} |
253 |
|
287 |
|
254 |
if ((err = hci_send_sco(conn->hcon, skb)) < 0) |
288 |
err = hci_send_sco(conn->hcon, skb); |
255 |
return err; |
289 |
|
|
|
290 |
if (err < 0) |
291 |
goto fail; |
256 |
|
292 |
|
257 |
return count; |
293 |
return len; |
258 |
|
294 |
|
259 |
fail: |
295 |
fail: |
260 |
kfree_skb(skb); |
296 |
kfree_skb(skb); |
261 |
return err; |
297 |
return err; |
262 |
} |
298 |
} |
263 |
|
299 |
|
|
|
300 |
static int sco_sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) |
301 |
{ |
302 |
BT_DBG("sock %p, sk_rcvbuf %d, qlen %d", sk, sk->sk_rcvbuf, skb_queue_len(&sk->sk_receive_queue)); |
303 |
|
304 |
if (skb_queue_len(&sk->sk_receive_queue) + 1 > (unsigned)sk->sk_rcvbuf) |
305 |
return -ENOMEM; |
306 |
|
307 |
skb->dev = NULL; |
308 |
skb->sk = sk; |
309 |
skb->destructor = NULL; |
310 |
|
311 |
skb_queue_tail(&sk->sk_receive_queue, skb); |
312 |
|
313 |
if (!sock_flag(sk, SOCK_DEAD)) |
314 |
sk->sk_data_ready(sk, 1); |
315 |
|
316 |
return 0; |
317 |
} |
318 |
|
264 |
static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) |
319 |
static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) |
265 |
{ |
320 |
{ |
266 |
struct sock *sk = sco_chan_get(conn); |
321 |
struct sock *sk = sco_chan_get(conn); |
Lines 273-279
static inline void sco_recv_frame(struct
Link Here
|
273 |
if (sk->sk_state != BT_CONNECTED) |
328 |
if (sk->sk_state != BT_CONNECTED) |
274 |
goto drop; |
329 |
goto drop; |
275 |
|
330 |
|
276 |
if (!sock_queue_rcv_skb(sk, skb)) |
331 |
if (!sco_sock_queue_rcv_skb(sk, skb)) |
277 |
return; |
332 |
return; |
278 |
|
333 |
|
279 |
drop: |
334 |
drop: |
Lines 328-334
static void sco_sock_destruct(struct soc
Link Here
|
328 |
BT_DBG("sk %p", sk); |
383 |
BT_DBG("sk %p", sk); |
329 |
|
384 |
|
330 |
skb_queue_purge(&sk->sk_receive_queue); |
385 |
skb_queue_purge(&sk->sk_receive_queue); |
331 |
skb_queue_purge(&sk->sk_write_queue); |
|
|
332 |
} |
386 |
} |
333 |
|
387 |
|
334 |
static void sco_sock_cleanup_listen(struct sock *parent) |
388 |
static void sco_sock_cleanup_listen(struct sock *parent) |
Lines 426-431
static struct sock *sco_sock_alloc(struc
Link Here
|
426 |
INIT_LIST_HEAD(&bt_sk(sk)->accept_q); |
480 |
INIT_LIST_HEAD(&bt_sk(sk)->accept_q); |
427 |
|
481 |
|
428 |
sk->sk_destruct = sco_sock_destruct; |
482 |
sk->sk_destruct = sco_sock_destruct; |
|
|
483 |
sk->sk_write_space = sco_sock_write_space; |
484 |
|
485 |
sk->sk_sndbuf = DEFAULT_SCO_TXBUFS; |
486 |
sk->sk_rcvbuf = DEFAULT_SCO_RXBUFS; |
429 |
sk->sk_sndtimeo = SCO_CONN_TIMEOUT; |
487 |
sk->sk_sndtimeo = SCO_CONN_TIMEOUT; |
430 |
|
488 |
|
431 |
sock_reset_flag(sk, SOCK_ZAPPED); |
489 |
sock_reset_flag(sk, SOCK_ZAPPED); |
Lines 656-661
static int sco_sock_sendmsg(struct kiocb
Link Here
|
656 |
static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) |
714 |
static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) |
657 |
{ |
715 |
{ |
658 |
struct sock *sk = sock->sk; |
716 |
struct sock *sk = sock->sk; |
|
|
717 |
u32 opt; |
659 |
int err = 0; |
718 |
int err = 0; |
660 |
|
719 |
|
661 |
BT_DBG("sk %p", sk); |
720 |
BT_DBG("sk %p", sk); |
Lines 663-668
static int sco_sock_setsockopt(struct so
Link Here
|
663 |
lock_sock(sk); |
722 |
lock_sock(sk); |
664 |
|
723 |
|
665 |
switch (optname) { |
724 |
switch (optname) { |
|
|
725 |
case SO_SNDBUF: |
726 |
if (get_user(opt, (u32 __user *) optval)) { |
727 |
err = -EFAULT; |
728 |
break; |
729 |
} |
730 |
if (opt > MAX_SCO_TXBUFS) { |
731 |
err = -EINVAL; |
732 |
break; |
733 |
} |
734 |
|
735 |
sk->sk_sndbuf = opt; |
736 |
/* Wake up sending tasks if we upped the value */ |
737 |
sk->sk_write_space(sk); |
738 |
break; |
739 |
case SO_RCVBUF: |
740 |
if (get_user(opt, (u32 __user *) optval)) { |
741 |
err = -EFAULT; |
742 |
break; |
743 |
} |
744 |
if (opt > MAX_SCO_RXBUFS) { |
745 |
err = -EINVAL; |
746 |
break; |
747 |
} |
748 |
|
749 |
sk->sk_rcvbuf = opt; |
750 |
break; |
666 |
default: |
751 |
default: |
667 |
err = -ENOPROTOOPT; |
752 |
err = -ENOPROTOOPT; |
668 |
break; |
753 |
break; |
Lines 678-683
static int sco_sock_getsockopt(struct so
Link Here
|
678 |
struct sco_options opts; |
763 |
struct sco_options opts; |
679 |
struct sco_conninfo cinfo; |
764 |
struct sco_conninfo cinfo; |
680 |
int len, err = 0; |
765 |
int len, err = 0; |
|
|
766 |
int val; |
681 |
|
767 |
|
682 |
BT_DBG("sk %p", sk); |
768 |
BT_DBG("sk %p", sk); |
683 |
|
769 |
|
Lines 687-692
static int sco_sock_getsockopt(struct so
Link Here
|
687 |
lock_sock(sk); |
773 |
lock_sock(sk); |
688 |
|
774 |
|
689 |
switch (optname) { |
775 |
switch (optname) { |
|
|
776 |
case SO_RCVBUF: |
777 |
val = sk->sk_rcvbuf; |
778 |
|
779 |
len = min_t(unsigned int, len, sizeof(val)); |
780 |
if (copy_to_user(optval, (char *) &val, len)) |
781 |
err = -EFAULT; |
782 |
|
783 |
break; |
784 |
|
785 |
case SO_SNDBUF: |
786 |
val = sk->sk_sndbuf; |
787 |
|
788 |
len = min_t(unsigned int, len, sizeof(val)); |
789 |
if (copy_to_user(optval, (char *) &val, len)) |
790 |
err = -EFAULT; |
791 |
|
792 |
break; |
793 |
|
690 |
case SCO_OPTIONS: |
794 |
case SCO_OPTIONS: |
691 |
if (sk->sk_state != BT_CONNECTED) { |
795 |
if (sk->sk_state != BT_CONNECTED) { |
692 |
err = -ENOTCONN; |
796 |
err = -ENOTCONN; |
Lines 698-704
static int sco_sock_getsockopt(struct so
Link Here
|
698 |
BT_DBG("mtu %d", opts.mtu); |
802 |
BT_DBG("mtu %d", opts.mtu); |
699 |
|
803 |
|
700 |
len = min_t(unsigned int, len, sizeof(opts)); |
804 |
len = min_t(unsigned int, len, sizeof(opts)); |
701 |
if (copy_to_user(optval, (char *)&opts, len)) |
805 |
if (copy_to_user(optval, (char *) &opts, len)) |
702 |
err = -EFAULT; |
806 |
err = -EFAULT; |
703 |
|
807 |
|
704 |
break; |
808 |
break; |
Lines 713-719
static int sco_sock_getsockopt(struct so
Link Here
|
713 |
memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); |
817 |
memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); |
714 |
|
818 |
|
715 |
len = min_t(unsigned int, len, sizeof(cinfo)); |
819 |
len = min_t(unsigned int, len, sizeof(cinfo)); |
716 |
if (copy_to_user(optval, (char *)&cinfo, len)) |
820 |
if (copy_to_user(optval, (char *) &cinfo, len)) |
717 |
err = -EFAULT; |
821 |
err = -EFAULT; |
718 |
|
822 |
|
719 |
break; |
823 |
break; |