diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 38 | ||||
-rw-r--r-- | net/bluetooth/bnep/core.c | 4 | ||||
-rw-r--r-- | net/bluetooth/bnep/sock.c | 69 | ||||
-rw-r--r-- | net/bluetooth/cmtp/sock.c | 35 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 6 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 15 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 17 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 8 | ||||
-rw-r--r-- | net/bluetooth/hidp/sock.c | 80 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 5 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 3 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 6 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 7 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 6 |
15 files changed, 240 insertions, 61 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 305a099b7477..67df99e2e5c8 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -48,41 +48,56 @@ | |||
48 | #define BT_DBG(D...) | 48 | #define BT_DBG(D...) |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #define VERSION "2.10" | 51 | #define VERSION "2.11" |
52 | 52 | ||
53 | /* Bluetooth sockets */ | 53 | /* Bluetooth sockets */ |
54 | #define BT_MAX_PROTO 8 | 54 | #define BT_MAX_PROTO 8 |
55 | static struct net_proto_family *bt_proto[BT_MAX_PROTO]; | 55 | static struct net_proto_family *bt_proto[BT_MAX_PROTO]; |
56 | static DEFINE_RWLOCK(bt_proto_lock); | ||
56 | 57 | ||
57 | int bt_sock_register(int proto, struct net_proto_family *ops) | 58 | int bt_sock_register(int proto, struct net_proto_family *ops) |
58 | { | 59 | { |
60 | int err = 0; | ||
61 | |||
59 | if (proto < 0 || proto >= BT_MAX_PROTO) | 62 | if (proto < 0 || proto >= BT_MAX_PROTO) |
60 | return -EINVAL; | 63 | return -EINVAL; |
61 | 64 | ||
65 | write_lock(&bt_proto_lock); | ||
66 | |||
62 | if (bt_proto[proto]) | 67 | if (bt_proto[proto]) |
63 | return -EEXIST; | 68 | err = -EEXIST; |
69 | else | ||
70 | bt_proto[proto] = ops; | ||
64 | 71 | ||
65 | bt_proto[proto] = ops; | 72 | write_unlock(&bt_proto_lock); |
66 | return 0; | 73 | |
74 | return err; | ||
67 | } | 75 | } |
68 | EXPORT_SYMBOL(bt_sock_register); | 76 | EXPORT_SYMBOL(bt_sock_register); |
69 | 77 | ||
70 | int bt_sock_unregister(int proto) | 78 | int bt_sock_unregister(int proto) |
71 | { | 79 | { |
80 | int err = 0; | ||
81 | |||
72 | if (proto < 0 || proto >= BT_MAX_PROTO) | 82 | if (proto < 0 || proto >= BT_MAX_PROTO) |
73 | return -EINVAL; | 83 | return -EINVAL; |
74 | 84 | ||
85 | write_lock(&bt_proto_lock); | ||
86 | |||
75 | if (!bt_proto[proto]) | 87 | if (!bt_proto[proto]) |
76 | return -ENOENT; | 88 | err = -ENOENT; |
89 | else | ||
90 | bt_proto[proto] = NULL; | ||
77 | 91 | ||
78 | bt_proto[proto] = NULL; | 92 | write_unlock(&bt_proto_lock); |
79 | return 0; | 93 | |
94 | return err; | ||
80 | } | 95 | } |
81 | EXPORT_SYMBOL(bt_sock_unregister); | 96 | EXPORT_SYMBOL(bt_sock_unregister); |
82 | 97 | ||
83 | static int bt_sock_create(struct socket *sock, int proto) | 98 | static int bt_sock_create(struct socket *sock, int proto) |
84 | { | 99 | { |
85 | int err = 0; | 100 | int err; |
86 | 101 | ||
87 | if (proto < 0 || proto >= BT_MAX_PROTO) | 102 | if (proto < 0 || proto >= BT_MAX_PROTO) |
88 | return -EINVAL; | 103 | return -EINVAL; |
@@ -92,11 +107,18 @@ static int bt_sock_create(struct socket *sock, int proto) | |||
92 | request_module("bt-proto-%d", proto); | 107 | request_module("bt-proto-%d", proto); |
93 | } | 108 | } |
94 | #endif | 109 | #endif |
110 | |||
95 | err = -EPROTONOSUPPORT; | 111 | err = -EPROTONOSUPPORT; |
112 | |||
113 | read_lock(&bt_proto_lock); | ||
114 | |||
96 | if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { | 115 | if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { |
97 | err = bt_proto[proto]->create(sock, proto); | 116 | err = bt_proto[proto]->create(sock, proto); |
98 | module_put(bt_proto[proto]->owner); | 117 | module_put(bt_proto[proto]->owner); |
99 | } | 118 | } |
119 | |||
120 | read_unlock(&bt_proto_lock); | ||
121 | |||
100 | return err; | 122 | return err; |
101 | } | 123 | } |
102 | 124 | ||
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 2312d050eeed..4d3424c2421c 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -528,12 +528,10 @@ static struct device *bnep_get_device(struct bnep_session *session) | |||
528 | return NULL; | 528 | return NULL; |
529 | 529 | ||
530 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 530 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
531 | if (!conn) | ||
532 | return NULL; | ||
533 | 531 | ||
534 | hci_dev_put(hdev); | 532 | hci_dev_put(hdev); |
535 | 533 | ||
536 | return &conn->dev; | 534 | return conn ? &conn->dev : NULL; |
537 | } | 535 | } |
538 | 536 | ||
539 | int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | 537 | int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) |
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 28c55835422a..5563db1bf526 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/ioctl.h> | 43 | #include <linux/ioctl.h> |
44 | #include <linux/file.h> | 44 | #include <linux/file.h> |
45 | #include <linux/init.h> | 45 | #include <linux/init.h> |
46 | #include <linux/compat.h> | ||
46 | #include <net/sock.h> | 47 | #include <net/sock.h> |
47 | 48 | ||
48 | #include <asm/system.h> | 49 | #include <asm/system.h> |
@@ -146,24 +147,56 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
148 | 149 | ||
150 | #ifdef CONFIG_COMPAT | ||
151 | static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
152 | { | ||
153 | if (cmd == BNEPGETCONNLIST) { | ||
154 | struct bnep_connlist_req cl; | ||
155 | uint32_t uci; | ||
156 | int err; | ||
157 | |||
158 | if (get_user(cl.cnum, (uint32_t __user *) arg) || | ||
159 | get_user(uci, (u32 __user *) (arg + 4))) | ||
160 | return -EFAULT; | ||
161 | |||
162 | cl.ci = compat_ptr(uci); | ||
163 | |||
164 | if (cl.cnum <= 0) | ||
165 | return -EINVAL; | ||
166 | |||
167 | err = bnep_get_connlist(&cl); | ||
168 | |||
169 | if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) | ||
170 | err = -EFAULT; | ||
171 | |||
172 | return err; | ||
173 | } | ||
174 | |||
175 | return bnep_sock_ioctl(sock, cmd, arg); | ||
176 | } | ||
177 | #endif | ||
178 | |||
149 | static const struct proto_ops bnep_sock_ops = { | 179 | static const struct proto_ops bnep_sock_ops = { |
150 | .family = PF_BLUETOOTH, | 180 | .family = PF_BLUETOOTH, |
151 | .owner = THIS_MODULE, | 181 | .owner = THIS_MODULE, |
152 | .release = bnep_sock_release, | 182 | .release = bnep_sock_release, |
153 | .ioctl = bnep_sock_ioctl, | 183 | .ioctl = bnep_sock_ioctl, |
154 | .bind = sock_no_bind, | 184 | #ifdef CONFIG_COMPAT |
155 | .getname = sock_no_getname, | 185 | .compat_ioctl = bnep_sock_compat_ioctl, |
156 | .sendmsg = sock_no_sendmsg, | 186 | #endif |
157 | .recvmsg = sock_no_recvmsg, | 187 | .bind = sock_no_bind, |
158 | .poll = sock_no_poll, | 188 | .getname = sock_no_getname, |
159 | .listen = sock_no_listen, | 189 | .sendmsg = sock_no_sendmsg, |
160 | .shutdown = sock_no_shutdown, | 190 | .recvmsg = sock_no_recvmsg, |
161 | .setsockopt = sock_no_setsockopt, | 191 | .poll = sock_no_poll, |
162 | .getsockopt = sock_no_getsockopt, | 192 | .listen = sock_no_listen, |
163 | .connect = sock_no_connect, | 193 | .shutdown = sock_no_shutdown, |
164 | .socketpair = sock_no_socketpair, | 194 | .setsockopt = sock_no_setsockopt, |
165 | .accept = sock_no_accept, | 195 | .getsockopt = sock_no_getsockopt, |
166 | .mmap = sock_no_mmap | 196 | .connect = sock_no_connect, |
197 | .socketpair = sock_no_socketpair, | ||
198 | .accept = sock_no_accept, | ||
199 | .mmap = sock_no_mmap | ||
167 | }; | 200 | }; |
168 | 201 | ||
169 | static struct proto bnep_proto = { | 202 | static struct proto bnep_proto = { |
@@ -181,7 +214,7 @@ static int bnep_sock_create(struct socket *sock, int protocol) | |||
181 | if (sock->type != SOCK_RAW) | 214 | if (sock->type != SOCK_RAW) |
182 | return -ESOCKTNOSUPPORT; | 215 | return -ESOCKTNOSUPPORT; |
183 | 216 | ||
184 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &bnep_proto, 1); | 217 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1); |
185 | if (!sk) | 218 | if (!sk) |
186 | return -ENOMEM; | 219 | return -ENOMEM; |
187 | 220 | ||
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 10ad7fd91d83..53295d33dc5c 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/socket.h> | 34 | #include <linux/socket.h> |
35 | #include <linux/ioctl.h> | 35 | #include <linux/ioctl.h> |
36 | #include <linux/file.h> | 36 | #include <linux/file.h> |
37 | #include <linux/compat.h> | ||
37 | #include <net/sock.h> | 38 | #include <net/sock.h> |
38 | 39 | ||
39 | #include <linux/isdn/capilli.h> | 40 | #include <linux/isdn/capilli.h> |
@@ -137,11 +138,43 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
137 | return -EINVAL; | 138 | return -EINVAL; |
138 | } | 139 | } |
139 | 140 | ||
141 | #ifdef CONFIG_COMPAT | ||
142 | static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
143 | { | ||
144 | if (cmd == CMTPGETCONNLIST) { | ||
145 | struct cmtp_connlist_req cl; | ||
146 | uint32_t uci; | ||
147 | int err; | ||
148 | |||
149 | if (get_user(cl.cnum, (uint32_t __user *) arg) || | ||
150 | get_user(uci, (u32 __user *) (arg + 4))) | ||
151 | return -EFAULT; | ||
152 | |||
153 | cl.ci = compat_ptr(uci); | ||
154 | |||
155 | if (cl.cnum <= 0) | ||
156 | return -EINVAL; | ||
157 | |||
158 | err = cmtp_get_connlist(&cl); | ||
159 | |||
160 | if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) | ||
161 | err = -EFAULT; | ||
162 | |||
163 | return err; | ||
164 | } | ||
165 | |||
166 | return cmtp_sock_ioctl(sock, cmd, arg); | ||
167 | } | ||
168 | #endif | ||
169 | |||
140 | static const struct proto_ops cmtp_sock_ops = { | 170 | static const struct proto_ops cmtp_sock_ops = { |
141 | .family = PF_BLUETOOTH, | 171 | .family = PF_BLUETOOTH, |
142 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
143 | .release = cmtp_sock_release, | 173 | .release = cmtp_sock_release, |
144 | .ioctl = cmtp_sock_ioctl, | 174 | .ioctl = cmtp_sock_ioctl, |
175 | #ifdef CONFIG_COMPAT | ||
176 | .compat_ioctl = cmtp_sock_compat_ioctl, | ||
177 | #endif | ||
145 | .bind = sock_no_bind, | 178 | .bind = sock_no_bind, |
146 | .getname = sock_no_getname, | 179 | .getname = sock_no_getname, |
147 | .sendmsg = sock_no_sendmsg, | 180 | .sendmsg = sock_no_sendmsg, |
@@ -172,7 +205,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol) | |||
172 | if (sock->type != SOCK_RAW) | 205 | if (sock->type != SOCK_RAW) |
173 | return -ESOCKTNOSUPPORT; | 206 | return -ESOCKTNOSUPPORT; |
174 | 207 | ||
175 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &cmtp_proto, 1); | 208 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1); |
176 | if (!sk) | 209 | if (!sk) |
177 | return -ENOMEM; | 210 | return -ENOMEM; |
178 | 211 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 90e3a285a17e..6cd5711fa28a 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #define BT_DBG(D...) | 51 | #define BT_DBG(D...) |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | static void hci_acl_connect(struct hci_conn *conn) | 54 | void hci_acl_connect(struct hci_conn *conn) |
55 | { | 55 | { |
56 | struct hci_dev *hdev = conn->hdev; | 56 | struct hci_dev *hdev = conn->hdev; |
57 | struct inquiry_entry *ie; | 57 | struct inquiry_entry *ie; |
@@ -63,6 +63,8 @@ static void hci_acl_connect(struct hci_conn *conn) | |||
63 | conn->out = 1; | 63 | conn->out = 1; |
64 | conn->link_mode = HCI_LM_MASTER; | 64 | conn->link_mode = HCI_LM_MASTER; |
65 | 65 | ||
66 | conn->attempt++; | ||
67 | |||
66 | memset(&cp, 0, sizeof(cp)); | 68 | memset(&cp, 0, sizeof(cp)); |
67 | bacpy(&cp.bdaddr, &conn->dst); | 69 | bacpy(&cp.bdaddr, &conn->dst); |
68 | cp.pscan_rep_mode = 0x02; | 70 | cp.pscan_rep_mode = 0x02; |
@@ -80,7 +82,7 @@ static void hci_acl_connect(struct hci_conn *conn) | |||
80 | cp.role_switch = 0x01; | 82 | cp.role_switch = 0x01; |
81 | else | 83 | else |
82 | cp.role_switch = 0x00; | 84 | cp.role_switch = 0x00; |
83 | 85 | ||
84 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); | 86 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); |
85 | } | 87 | } |
86 | 88 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d43d0c890975..65f094845719 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -414,9 +414,12 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | |||
414 | 414 | ||
415 | if (status) { | 415 | if (status) { |
416 | if (conn && conn->state == BT_CONNECT) { | 416 | if (conn && conn->state == BT_CONNECT) { |
417 | conn->state = BT_CLOSED; | 417 | if (status != 0x0c || conn->attempt > 2) { |
418 | hci_proto_connect_cfm(conn, status); | 418 | conn->state = BT_CLOSED; |
419 | hci_conn_del(conn); | 419 | hci_proto_connect_cfm(conn, status); |
420 | hci_conn_del(conn); | ||
421 | } else | ||
422 | conn->state = BT_CONNECT2; | ||
420 | } | 423 | } |
421 | } else { | 424 | } else { |
422 | if (!conn) { | 425 | if (!conn) { |
@@ -728,7 +731,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
728 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 731 | static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
729 | { | 732 | { |
730 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; | 733 | struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data; |
731 | struct hci_conn *conn; | 734 | struct hci_conn *conn, *pend; |
732 | 735 | ||
733 | BT_DBG("%s", hdev->name); | 736 | BT_DBG("%s", hdev->name); |
734 | 737 | ||
@@ -801,6 +804,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
801 | if (ev->status) | 804 | if (ev->status) |
802 | hci_conn_del(conn); | 805 | hci_conn_del(conn); |
803 | 806 | ||
807 | pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | ||
808 | if (pend) | ||
809 | hci_acl_connect(pend); | ||
810 | |||
804 | hci_dev_unlock(hdev); | 811 | hci_dev_unlock(hdev); |
805 | } | 812 | } |
806 | 813 | ||
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 1a35d343e08a..f26a9eb49945 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -618,7 +618,7 @@ static int hci_sock_create(struct socket *sock, int protocol) | |||
618 | 618 | ||
619 | sock->ops = &hci_sock_ops; | 619 | sock->ops = &hci_sock_ops; |
620 | 620 | ||
621 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hci_sk_proto, 1); | 621 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1); |
622 | if (!sk) | 622 | if (!sk) |
623 | return -ENOMEM; | 623 | return -ENOMEM; |
624 | 624 | ||
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 989b22d9042e..954eb74eb370 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -242,10 +242,14 @@ static void add_conn(void *data) | |||
242 | struct hci_conn *conn = data; | 242 | struct hci_conn *conn = data; |
243 | int i; | 243 | int i; |
244 | 244 | ||
245 | device_register(&conn->dev); | 245 | if (device_register(&conn->dev) < 0) { |
246 | BT_ERR("Failed to register connection device"); | ||
247 | return; | ||
248 | } | ||
246 | 249 | ||
247 | for (i = 0; conn_attrs[i]; i++) | 250 | for (i = 0; conn_attrs[i]; i++) |
248 | device_create_file(&conn->dev, conn_attrs[i]); | 251 | if (device_create_file(&conn->dev, conn_attrs[i]) < 0) |
252 | BT_ERR("Failed to create connection attribute"); | ||
249 | } | 253 | } |
250 | 254 | ||
251 | void hci_conn_add_sysfs(struct hci_conn *conn) | 255 | void hci_conn_add_sysfs(struct hci_conn *conn) |
@@ -295,11 +299,7 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
295 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); | 299 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); |
296 | 300 | ||
297 | dev->class = bt_class; | 301 | dev->class = bt_class; |
298 | 302 | dev->parent = hdev->parent; | |
299 | if (hdev->parent) | ||
300 | dev->parent = hdev->parent; | ||
301 | else | ||
302 | dev->parent = &bt_platform->dev; | ||
303 | 303 | ||
304 | strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); | 304 | strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); |
305 | 305 | ||
@@ -312,7 +312,8 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
312 | return err; | 312 | return err; |
313 | 313 | ||
314 | for (i = 0; bt_attrs[i]; i++) | 314 | for (i = 0; bt_attrs[i]; i++) |
315 | device_create_file(dev, bt_attrs[i]); | 315 | if (device_create_file(dev, bt_attrs[i]) < 0) |
316 | BT_ERR("Failed to create device attribute"); | ||
316 | 317 | ||
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 03b5dadb4951..9a562cf7406b 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -510,11 +510,11 @@ static int hidp_session(void *arg) | |||
510 | if (intr_sk->sk_state != BT_CONNECTED) | 510 | if (intr_sk->sk_state != BT_CONNECTED) |
511 | wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ); | 511 | wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ); |
512 | 512 | ||
513 | fput(session->ctrl_sock->file); | 513 | fput(session->intr_sock->file); |
514 | 514 | ||
515 | wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ); | 515 | wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ); |
516 | 516 | ||
517 | fput(session->intr_sock->file); | 517 | fput(session->ctrl_sock->file); |
518 | 518 | ||
519 | __hidp_unlink_session(session); | 519 | __hidp_unlink_session(session); |
520 | 520 | ||
@@ -541,12 +541,10 @@ static struct device *hidp_get_device(struct hidp_session *session) | |||
541 | return NULL; | 541 | return NULL; |
542 | 542 | ||
543 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 543 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
544 | if (!conn) | ||
545 | return NULL; | ||
546 | 544 | ||
547 | hci_dev_put(hdev); | 545 | hci_dev_put(hdev); |
548 | 546 | ||
549 | return &conn->dev; | 547 | return conn ? &conn->dev : NULL; |
550 | } | 548 | } |
551 | 549 | ||
552 | static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) | 550 | static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) |
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index 099646e4e2ef..407fba43c1b9 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/ioctl.h> | 35 | #include <linux/ioctl.h> |
36 | #include <linux/file.h> | 36 | #include <linux/file.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/compat.h> | ||
38 | #include <net/sock.h> | 39 | #include <net/sock.h> |
39 | 40 | ||
40 | #include "hidp.h" | 41 | #include "hidp.h" |
@@ -143,11 +144,88 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
143 | return -EINVAL; | 144 | return -EINVAL; |
144 | } | 145 | } |
145 | 146 | ||
147 | #ifdef CONFIG_COMPAT | ||
148 | struct compat_hidp_connadd_req { | ||
149 | int ctrl_sock; // Connected control socket | ||
150 | int intr_sock; // Connteted interrupt socket | ||
151 | __u16 parser; | ||
152 | __u16 rd_size; | ||
153 | compat_uptr_t rd_data; | ||
154 | __u8 country; | ||
155 | __u8 subclass; | ||
156 | __u16 vendor; | ||
157 | __u16 product; | ||
158 | __u16 version; | ||
159 | __u32 flags; | ||
160 | __u32 idle_to; | ||
161 | char name[128]; | ||
162 | }; | ||
163 | |||
164 | static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
165 | { | ||
166 | if (cmd == HIDPGETCONNLIST) { | ||
167 | struct hidp_connlist_req cl; | ||
168 | uint32_t uci; | ||
169 | int err; | ||
170 | |||
171 | if (get_user(cl.cnum, (uint32_t __user *) arg) || | ||
172 | get_user(uci, (u32 __user *) (arg + 4))) | ||
173 | return -EFAULT; | ||
174 | |||
175 | cl.ci = compat_ptr(uci); | ||
176 | |||
177 | if (cl.cnum <= 0) | ||
178 | return -EINVAL; | ||
179 | |||
180 | err = hidp_get_connlist(&cl); | ||
181 | |||
182 | if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) | ||
183 | err = -EFAULT; | ||
184 | |||
185 | return err; | ||
186 | } else if (cmd == HIDPCONNADD) { | ||
187 | struct compat_hidp_connadd_req ca; | ||
188 | struct hidp_connadd_req __user *uca; | ||
189 | |||
190 | uca = compat_alloc_user_space(sizeof(*uca)); | ||
191 | |||
192 | if (copy_from_user(&ca, (void *) arg, sizeof(ca))) | ||
193 | return -EFAULT; | ||
194 | |||
195 | if (put_user(ca.ctrl_sock, &uca->ctrl_sock) || | ||
196 | put_user(ca.intr_sock, &uca->intr_sock) || | ||
197 | put_user(ca.parser, &uca->parser) || | ||
198 | put_user(ca.rd_size, &uca->parser) || | ||
199 | put_user(compat_ptr(ca.rd_data), &uca->rd_data) || | ||
200 | put_user(ca.country, &uca->country) || | ||
201 | put_user(ca.subclass, &uca->subclass) || | ||
202 | put_user(ca.vendor, &uca->vendor) || | ||
203 | put_user(ca.product, &uca->product) || | ||
204 | put_user(ca.version, &uca->version) || | ||
205 | put_user(ca.flags, &uca->flags) || | ||
206 | put_user(ca.idle_to, &uca->idle_to) || | ||
207 | copy_to_user(&uca->name[0], &ca.name[0], 128)) | ||
208 | return -EFAULT; | ||
209 | |||
210 | arg = (unsigned long) uca; | ||
211 | |||
212 | /* Fall through. We don't actually write back any _changes_ | ||
213 | to the structure anyway, so there's no need to copy back | ||
214 | into the original compat version */ | ||
215 | } | ||
216 | |||
217 | return hidp_sock_ioctl(sock, cmd, arg); | ||
218 | } | ||
219 | #endif | ||
220 | |||
146 | static const struct proto_ops hidp_sock_ops = { | 221 | static const struct proto_ops hidp_sock_ops = { |
147 | .family = PF_BLUETOOTH, | 222 | .family = PF_BLUETOOTH, |
148 | .owner = THIS_MODULE, | 223 | .owner = THIS_MODULE, |
149 | .release = hidp_sock_release, | 224 | .release = hidp_sock_release, |
150 | .ioctl = hidp_sock_ioctl, | 225 | .ioctl = hidp_sock_ioctl, |
226 | #ifdef CONFIG_COMPAT | ||
227 | .compat_ioctl = hidp_sock_compat_ioctl, | ||
228 | #endif | ||
151 | .bind = sock_no_bind, | 229 | .bind = sock_no_bind, |
152 | .getname = sock_no_getname, | 230 | .getname = sock_no_getname, |
153 | .sendmsg = sock_no_sendmsg, | 231 | .sendmsg = sock_no_sendmsg, |
@@ -178,7 +256,7 @@ static int hidp_sock_create(struct socket *sock, int protocol) | |||
178 | if (sock->type != SOCK_RAW) | 256 | if (sock->type != SOCK_RAW) |
179 | return -ESOCKTNOSUPPORT; | 257 | return -ESOCKTNOSUPPORT; |
180 | 258 | ||
181 | sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hidp_proto, 1); | 259 | sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1); |
182 | if (!sk) | 260 | if (!sk) |
183 | return -ENOMEM; | 261 | return -ENOMEM; |
184 | 262 | ||
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index d56f60b392ac..2b3dcb8f90fa 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -559,7 +559,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol) | |||
559 | 559 | ||
560 | sock->ops = &l2cap_sock_ops; | 560 | sock->ops = &l2cap_sock_ops; |
561 | 561 | ||
562 | sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL); | 562 | sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC); |
563 | if (!sk) | 563 | if (!sk) |
564 | return -ENOMEM; | 564 | return -ENOMEM; |
565 | 565 | ||
@@ -2216,7 +2216,8 @@ static int __init l2cap_init(void) | |||
2216 | goto error; | 2216 | goto error; |
2217 | } | 2217 | } |
2218 | 2218 | ||
2219 | class_create_file(bt_class, &class_attr_l2cap); | 2219 | if (class_create_file(bt_class, &class_attr_l2cap) < 0) |
2220 | BT_ERR("Failed to create L2CAP info file"); | ||
2220 | 2221 | ||
2221 | BT_INFO("L2CAP ver %s", VERSION); | 2222 | BT_INFO("L2CAP ver %s", VERSION); |
2222 | BT_INFO("L2CAP socket layer initialized"); | 2223 | BT_INFO("L2CAP socket layer initialized"); |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 468df3b953f6..ddc4e9d5963e 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -2058,7 +2058,8 @@ static int __init rfcomm_init(void) | |||
2058 | 2058 | ||
2059 | kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); | 2059 | kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); |
2060 | 2060 | ||
2061 | class_create_file(bt_class, &class_attr_rfcomm_dlc); | 2061 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) |
2062 | BT_ERR("Failed to create RFCOMM info file"); | ||
2062 | 2063 | ||
2063 | rfcomm_init_sockets(); | 2064 | rfcomm_init_sockets(); |
2064 | 2065 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 220fee04e7f2..544d65b7baa7 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -336,7 +336,8 @@ static int rfcomm_sock_create(struct socket *sock, int protocol) | |||
336 | 336 | ||
337 | sock->ops = &rfcomm_sock_ops; | 337 | sock->ops = &rfcomm_sock_ops; |
338 | 338 | ||
339 | if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL))) | 339 | sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC); |
340 | if (!sk) | ||
340 | return -ENOMEM; | 341 | return -ENOMEM; |
341 | 342 | ||
342 | rfcomm_sock_init(sk, NULL); | 343 | rfcomm_sock_init(sk, NULL); |
@@ -944,7 +945,8 @@ int __init rfcomm_init_sockets(void) | |||
944 | if (err < 0) | 945 | if (err < 0) |
945 | goto error; | 946 | goto error; |
946 | 947 | ||
947 | class_create_file(bt_class, &class_attr_rfcomm); | 948 | if (class_create_file(bt_class, &class_attr_rfcomm) < 0) |
949 | BT_ERR("Failed to create RFCOMM info file"); | ||
948 | 950 | ||
949 | BT_INFO("RFCOMM socket layer initialized"); | 951 | BT_INFO("RFCOMM socket layer initialized"); |
950 | 952 | ||
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 1958ad1b8541..b8e3a5f1c8a8 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -172,12 +172,10 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) | |||
172 | return NULL; | 172 | return NULL; |
173 | 173 | ||
174 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); | 174 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst); |
175 | if (!conn) | ||
176 | return NULL; | ||
177 | 175 | ||
178 | hci_dev_put(hdev); | 176 | hci_dev_put(hdev); |
179 | 177 | ||
180 | return &conn->dev; | 178 | return conn ? &conn->dev : NULL; |
181 | } | 179 | } |
182 | 180 | ||
183 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | 181 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) |
@@ -767,6 +765,9 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old) | |||
767 | 765 | ||
768 | BT_DBG("tty %p termios %p", tty, old); | 766 | BT_DBG("tty %p termios %p", tty, old); |
769 | 767 | ||
768 | if (!dev) | ||
769 | return; | ||
770 | |||
770 | /* Handle turning off CRTSCTS */ | 771 | /* Handle turning off CRTSCTS */ |
771 | if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS)) | 772 | if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS)) |
772 | BT_DBG("Turning off CRTSCTS unsupported"); | 773 | BT_DBG("Turning off CRTSCTS unsupported"); |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 7714a2ec3854..5d13d4f31753 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -452,7 +452,8 @@ static int sco_sock_create(struct socket *sock, int protocol) | |||
452 | 452 | ||
453 | sock->ops = &sco_sock_ops; | 453 | sock->ops = &sco_sock_ops; |
454 | 454 | ||
455 | if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL))) | 455 | sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC); |
456 | if (!sk) | ||
456 | return -ENOMEM; | 457 | return -ENOMEM; |
457 | 458 | ||
458 | sco_sock_init(sk, NULL); | 459 | sco_sock_init(sk, NULL); |
@@ -967,7 +968,8 @@ static int __init sco_init(void) | |||
967 | goto error; | 968 | goto error; |
968 | } | 969 | } |
969 | 970 | ||
970 | class_create_file(bt_class, &class_attr_sco); | 971 | if (class_create_file(bt_class, &class_attr_sco) < 0) |
972 | BT_ERR("Failed to create SCO info file"); | ||
971 | 973 | ||
972 | BT_INFO("SCO (Voice Link) ver %s", VERSION); | 974 | BT_INFO("SCO (Voice Link) ver %s", VERSION); |
973 | BT_INFO("SCO socket layer initialized"); | 975 | BT_INFO("SCO socket layer initialized"); |