diff options
author | David S. Miller <davem@davemloft.net> | 2015-04-07 11:47:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-07 11:47:52 -0400 |
commit | 7abccdba25be45630eede85053496f1f48d36ec8 (patch) | |
tree | fd87c8b84b1c5fa2f5d1cc9ba36d33855f2a0a6b | |
parent | c85d6975ef923cffdd56de3e0e6aba0977282cff (diff) | |
parent | 38c8af60046edab4c9db5f26e79746b1bd52c837 (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says:
====================
pull request: bluetooth-next 2015-04-04
Here's what's probably the last bluetooth-next pull request for 4.1:
- Fixes for LE advertising data & advertising parameters
- Fix for race condition with HCI_RESET flag
- New BNEPGETSUPPFEAT ioctl, needed for certification
- New HCI request callback type to get the resulting skb
- Cleanups to use BIT() macro wherever possible
- Consolidate Broadcom device entries in the btusb HCI driver
- Check for valid flags in CMTP, HIDP & BNEP
- Disallow local privacy & OOB data combo to prevent a potential race
- Expose SMP & ECDH selftest results through debugfs
- Expose current Device ID info through debugfs
Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/bluetooth/btusb.c | 12 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 2 | ||||
-rw-r--r-- | fs/compat_ioctl.c | 2 | ||||
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 23 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 7 | ||||
-rw-r--r-- | net/bluetooth/bnep/bnep.h | 4 | ||||
-rw-r--r-- | net/bluetooth/bnep/core.c | 70 | ||||
-rw-r--r-- | net/bluetooth/bnep/sock.c | 7 | ||||
-rw-r--r-- | net/bluetooth/cmtp/capi.c | 2 | ||||
-rw-r--r-- | net/bluetooth/cmtp/core.c | 15 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 120 | ||||
-rw-r--r-- | net/bluetooth/hci_debugfs.c | 26 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 175 | ||||
-rw-r--r-- | net/bluetooth/hci_request.c | 20 | ||||
-rw-r--r-- | net/bluetooth/hci_request.h | 5 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 15 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 48 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 6 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 267 | ||||
-rw-r--r-- | net/bluetooth/selftest.c | 35 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 45 |
22 files changed, 570 insertions, 338 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 9bf4d6ae6c6b..6e4ff16e487b 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -111,13 +111,7 @@ static const struct usb_device_id btusb_table[] = { | |||
111 | { USB_DEVICE(0x0c10, 0x0000) }, | 111 | { USB_DEVICE(0x0c10, 0x0000) }, |
112 | 112 | ||
113 | /* Broadcom BCM20702A0 */ | 113 | /* Broadcom BCM20702A0 */ |
114 | { USB_DEVICE(0x0489, 0xe042) }, | ||
115 | { USB_DEVICE(0x04ca, 0x2003) }, | ||
116 | { USB_DEVICE(0x0b05, 0x17b5) }, | ||
117 | { USB_DEVICE(0x0b05, 0x17cb) }, | ||
118 | { USB_DEVICE(0x413c, 0x8197) }, | 114 | { USB_DEVICE(0x413c, 0x8197) }, |
119 | { USB_DEVICE(0x13d3, 0x3404), | ||
120 | .driver_info = BTUSB_BCM_PATCHRAM }, | ||
121 | 115 | ||
122 | /* Broadcom BCM20702B0 (Dynex/Insignia) */ | 116 | /* Broadcom BCM20702B0 (Dynex/Insignia) */ |
123 | { USB_DEVICE(0x19ff, 0x0239), .driver_info = BTUSB_BCM_PATCHRAM }, | 117 | { USB_DEVICE(0x19ff, 0x0239), .driver_info = BTUSB_BCM_PATCHRAM }, |
@@ -139,10 +133,12 @@ static const struct usb_device_id btusb_table[] = { | |||
139 | .driver_info = BTUSB_BCM_PATCHRAM }, | 133 | .driver_info = BTUSB_BCM_PATCHRAM }, |
140 | 134 | ||
141 | /* Belkin F8065bf - Broadcom based */ | 135 | /* Belkin F8065bf - Broadcom based */ |
142 | { USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) }, | 136 | { USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01), |
137 | .driver_info = BTUSB_BCM_PATCHRAM }, | ||
143 | 138 | ||
144 | /* IMC Networks - Broadcom based */ | 139 | /* IMC Networks - Broadcom based */ |
145 | { USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) }, | 140 | { USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01), |
141 | .driver_info = BTUSB_BCM_PATCHRAM }, | ||
146 | 142 | ||
147 | /* Intel Bluetooth USB Bootloader (RAM module) */ | 143 | /* Intel Bluetooth USB Bootloader (RAM module) */ |
148 | { USB_DEVICE(0x8087, 0x0a5a), | 144 | { USB_DEVICE(0x8087, 0x0a5a), |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 48a0c250d5b8..1363dc616ace 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -499,7 +499,7 @@ static int hci_uart_set_flags(struct hci_uart *hu, unsigned long flags) | |||
499 | BIT(HCI_UART_INIT_PENDING) | | 499 | BIT(HCI_UART_INIT_PENDING) | |
500 | BIT(HCI_UART_EXT_CONFIG); | 500 | BIT(HCI_UART_EXT_CONFIG); |
501 | 501 | ||
502 | if ((flags & ~valid_flags)) | 502 | if (flags & ~valid_flags) |
503 | return -EINVAL; | 503 | return -EINVAL; |
504 | 504 | ||
505 | hu->hdev_flags = flags; | 505 | hu->hdev_flags = flags; |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index afec6450450f..6b8e2f091f5b 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -570,6 +570,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp) | |||
570 | #define BNEPCONNDEL _IOW('B', 201, int) | 570 | #define BNEPCONNDEL _IOW('B', 201, int) |
571 | #define BNEPGETCONNLIST _IOR('B', 210, int) | 571 | #define BNEPGETCONNLIST _IOR('B', 210, int) |
572 | #define BNEPGETCONNINFO _IOR('B', 211, int) | 572 | #define BNEPGETCONNINFO _IOR('B', 211, int) |
573 | #define BNEPGETSUPPFEAT _IOR('B', 212, int) | ||
573 | 574 | ||
574 | #define CMTPCONNADD _IOW('C', 200, int) | 575 | #define CMTPCONNADD _IOW('C', 200, int) |
575 | #define CMTPCONNDEL _IOW('C', 201, int) | 576 | #define CMTPCONNDEL _IOW('C', 201, int) |
@@ -1247,6 +1248,7 @@ COMPATIBLE_IOCTL(BNEPCONNADD) | |||
1247 | COMPATIBLE_IOCTL(BNEPCONNDEL) | 1248 | COMPATIBLE_IOCTL(BNEPCONNDEL) |
1248 | COMPATIBLE_IOCTL(BNEPGETCONNLIST) | 1249 | COMPATIBLE_IOCTL(BNEPGETCONNLIST) |
1249 | COMPATIBLE_IOCTL(BNEPGETCONNINFO) | 1250 | COMPATIBLE_IOCTL(BNEPGETCONNINFO) |
1251 | COMPATIBLE_IOCTL(BNEPGETSUPPFEAT) | ||
1250 | COMPATIBLE_IOCTL(CMTPCONNADD) | 1252 | COMPATIBLE_IOCTL(CMTPCONNADD) |
1251 | COMPATIBLE_IOCTL(CMTPCONNDEL) | 1253 | COMPATIBLE_IOCTL(CMTPCONNDEL) |
1252 | COMPATIBLE_IOCTL(CMTPGETCONNLIST) | 1254 | COMPATIBLE_IOCTL(CMTPGETCONNLIST) |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 33a5e00025aa..7dba80546f16 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -269,11 +269,23 @@ struct l2cap_ctrl { | |||
269 | __u16 reqseq; | 269 | __u16 reqseq; |
270 | __u16 txseq; | 270 | __u16 txseq; |
271 | __u8 retries; | 271 | __u8 retries; |
272 | __le16 psm; | ||
273 | bdaddr_t bdaddr; | ||
274 | struct l2cap_chan *chan; | ||
272 | }; | 275 | }; |
273 | 276 | ||
274 | struct hci_dev; | 277 | struct hci_dev; |
275 | 278 | ||
276 | typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); | 279 | typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); |
280 | typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status, | ||
281 | u16 opcode, struct sk_buff *skb); | ||
282 | |||
283 | struct req_ctrl { | ||
284 | bool start; | ||
285 | u8 event; | ||
286 | hci_req_complete_t complete; | ||
287 | hci_req_complete_skb_t complete_skb; | ||
288 | }; | ||
277 | 289 | ||
278 | struct bt_skb_cb { | 290 | struct bt_skb_cb { |
279 | __u8 pkt_type; | 291 | __u8 pkt_type; |
@@ -281,13 +293,10 @@ struct bt_skb_cb { | |||
281 | __u16 opcode; | 293 | __u16 opcode; |
282 | __u16 expect; | 294 | __u16 expect; |
283 | __u8 incoming:1; | 295 | __u8 incoming:1; |
284 | __u8 req_start:1; | 296 | union { |
285 | u8 req_event; | 297 | struct l2cap_ctrl l2cap; |
286 | hci_req_complete_t req_complete; | 298 | struct req_ctrl req; |
287 | struct l2cap_chan *chan; | 299 | }; |
288 | struct l2cap_ctrl control; | ||
289 | bdaddr_t bdaddr; | ||
290 | __le16 psm; | ||
291 | }; | 300 | }; |
292 | #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) | 301 | #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) |
293 | 302 | ||
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 540c07feece7..93fd3e756b8a 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -326,7 +326,6 @@ struct hci_dev { | |||
326 | struct sk_buff_head raw_q; | 326 | struct sk_buff_head raw_q; |
327 | struct sk_buff_head cmd_q; | 327 | struct sk_buff_head cmd_q; |
328 | 328 | ||
329 | struct sk_buff *recv_evt; | ||
330 | struct sk_buff *sent_cmd; | 329 | struct sk_buff *sent_cmd; |
331 | struct sk_buff *reassembly[NUM_REASSEMBLY]; | 330 | struct sk_buff *reassembly[NUM_REASSEMBLY]; |
332 | 331 | ||
@@ -334,6 +333,7 @@ struct hci_dev { | |||
334 | wait_queue_head_t req_wait_q; | 333 | wait_queue_head_t req_wait_q; |
335 | __u32 req_status; | 334 | __u32 req_status; |
336 | __u32 req_result; | 335 | __u32 req_result; |
336 | struct sk_buff *req_skb; | ||
337 | 337 | ||
338 | void *smp_data; | 338 | void *smp_data; |
339 | void *smp_bredr_data; | 339 | void *smp_bredr_data; |
@@ -1284,8 +1284,6 @@ static inline int hci_check_conn_params(u16 min, u16 max, u16 latency, | |||
1284 | int hci_register_cb(struct hci_cb *hcb); | 1284 | int hci_register_cb(struct hci_cb *hcb); |
1285 | int hci_unregister_cb(struct hci_cb *hcb); | 1285 | int hci_unregister_cb(struct hci_cb *hcb); |
1286 | 1286 | ||
1287 | bool hci_req_pending(struct hci_dev *hdev); | ||
1288 | |||
1289 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, | 1287 | struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, |
1290 | const void *param, u32 timeout); | 1288 | const void *param, u32 timeout); |
1291 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | 1289 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, |
@@ -1393,9 +1391,6 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); | |||
1393 | void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, | 1391 | void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, |
1394 | u8 status); | 1392 | u8 status); |
1395 | void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); | 1393 | void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); |
1396 | void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, | ||
1397 | u8 *rand192, u8 *hash256, u8 *rand256, | ||
1398 | u8 status); | ||
1399 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 1394 | void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, |
1400 | u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, | 1395 | u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, |
1401 | u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len); | 1396 | u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len); |
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index 5a5b16f365e9..40854c99bc1e 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h | |||
@@ -111,6 +111,10 @@ struct bnep_ext_hdr { | |||
111 | #define BNEPCONNDEL _IOW('B', 201, int) | 111 | #define BNEPCONNDEL _IOW('B', 201, int) |
112 | #define BNEPGETCONNLIST _IOR('B', 210, int) | 112 | #define BNEPGETCONNLIST _IOR('B', 210, int) |
113 | #define BNEPGETCONNINFO _IOR('B', 211, int) | 113 | #define BNEPGETCONNINFO _IOR('B', 211, int) |
114 | #define BNEPGETSUPPFEAT _IOR('B', 212, int) | ||
115 | |||
116 | #define BNEP_SETUP_RESPONSE 0 | ||
117 | #define BNEP_SETUP_RSP_SENT 10 | ||
114 | 118 | ||
115 | struct bnep_connadd_req { | 119 | struct bnep_connadd_req { |
116 | int sock; /* Connected socket */ | 120 | int sock; /* Connected socket */ |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 05f57e491ccb..1641367e54ca 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -231,7 +231,14 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len) | |||
231 | break; | 231 | break; |
232 | 232 | ||
233 | case BNEP_SETUP_CONN_REQ: | 233 | case BNEP_SETUP_CONN_REQ: |
234 | err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, BNEP_CONN_NOT_ALLOWED); | 234 | /* Successful response should be sent only once */ |
235 | if (test_bit(BNEP_SETUP_RESPONSE, &s->flags) && | ||
236 | !test_and_set_bit(BNEP_SETUP_RSP_SENT, &s->flags)) | ||
237 | err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, | ||
238 | BNEP_SUCCESS); | ||
239 | else | ||
240 | err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, | ||
241 | BNEP_CONN_NOT_ALLOWED); | ||
235 | break; | 242 | break; |
236 | 243 | ||
237 | default: { | 244 | default: { |
@@ -239,7 +246,7 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len) | |||
239 | pkt[0] = BNEP_CONTROL; | 246 | pkt[0] = BNEP_CONTROL; |
240 | pkt[1] = BNEP_CMD_NOT_UNDERSTOOD; | 247 | pkt[1] = BNEP_CMD_NOT_UNDERSTOOD; |
241 | pkt[2] = cmd; | 248 | pkt[2] = cmd; |
242 | bnep_send(s, pkt, sizeof(pkt)); | 249 | err = bnep_send(s, pkt, sizeof(pkt)); |
243 | } | 250 | } |
244 | break; | 251 | break; |
245 | } | 252 | } |
@@ -292,29 +299,55 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) | |||
292 | { | 299 | { |
293 | struct net_device *dev = s->dev; | 300 | struct net_device *dev = s->dev; |
294 | struct sk_buff *nskb; | 301 | struct sk_buff *nskb; |
295 | u8 type; | 302 | u8 type, ctrl_type; |
296 | 303 | ||
297 | dev->stats.rx_bytes += skb->len; | 304 | dev->stats.rx_bytes += skb->len; |
298 | 305 | ||
299 | type = *(u8 *) skb->data; | 306 | type = *(u8 *) skb->data; |
300 | skb_pull(skb, 1); | 307 | skb_pull(skb, 1); |
308 | ctrl_type = *(u8 *)skb->data; | ||
301 | 309 | ||
302 | if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen)) | 310 | if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen)) |
303 | goto badframe; | 311 | goto badframe; |
304 | 312 | ||
305 | if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) { | 313 | if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) { |
306 | bnep_rx_control(s, skb->data, skb->len); | 314 | if (bnep_rx_control(s, skb->data, skb->len) < 0) { |
307 | kfree_skb(skb); | 315 | dev->stats.tx_errors++; |
308 | return 0; | 316 | kfree_skb(skb); |
309 | } | 317 | return 0; |
318 | } | ||
310 | 319 | ||
311 | skb_reset_mac_header(skb); | 320 | if (!(type & BNEP_EXT_HEADER)) { |
321 | kfree_skb(skb); | ||
322 | return 0; | ||
323 | } | ||
312 | 324 | ||
313 | /* Verify and pull out header */ | 325 | /* Verify and pull ctrl message since it's already processed */ |
314 | if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK])) | 326 | switch (ctrl_type) { |
315 | goto badframe; | 327 | case BNEP_SETUP_CONN_REQ: |
328 | /* Pull: ctrl type (1 b), len (1 b), data (len bytes) */ | ||
329 | if (!skb_pull(skb, 2 + *(u8 *)(skb->data + 1) * 2)) | ||
330 | goto badframe; | ||
331 | break; | ||
332 | case BNEP_FILTER_MULTI_ADDR_SET: | ||
333 | case BNEP_FILTER_NET_TYPE_SET: | ||
334 | /* Pull: ctrl type (1 b), len (2 b), data (len bytes) */ | ||
335 | if (!skb_pull(skb, 3 + *(u16 *)(skb->data + 1) * 2)) | ||
336 | goto badframe; | ||
337 | break; | ||
338 | default: | ||
339 | kfree_skb(skb); | ||
340 | return 0; | ||
341 | } | ||
342 | } else { | ||
343 | skb_reset_mac_header(skb); | ||
316 | 344 | ||
317 | s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2)); | 345 | /* Verify and pull out header */ |
346 | if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK])) | ||
347 | goto badframe; | ||
348 | |||
349 | s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2)); | ||
350 | } | ||
318 | 351 | ||
319 | if (type & BNEP_EXT_HEADER) { | 352 | if (type & BNEP_EXT_HEADER) { |
320 | if (bnep_rx_extension(s, skb) < 0) | 353 | if (bnep_rx_extension(s, skb) < 0) |
@@ -525,6 +558,7 @@ static struct device_type bnep_type = { | |||
525 | 558 | ||
526 | int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | 559 | int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) |
527 | { | 560 | { |
561 | u32 valid_flags = BIT(BNEP_SETUP_RESPONSE); | ||
528 | struct net_device *dev; | 562 | struct net_device *dev; |
529 | struct bnep_session *s, *ss; | 563 | struct bnep_session *s, *ss; |
530 | u8 dst[ETH_ALEN], src[ETH_ALEN]; | 564 | u8 dst[ETH_ALEN], src[ETH_ALEN]; |
@@ -535,6 +569,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | |||
535 | if (!l2cap_is_socket(sock)) | 569 | if (!l2cap_is_socket(sock)) |
536 | return -EBADFD; | 570 | return -EBADFD; |
537 | 571 | ||
572 | if (req->flags & ~valid_flags) | ||
573 | return -EINVAL; | ||
574 | |||
538 | baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); | 575 | baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); |
539 | baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); | 576 | baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); |
540 | 577 | ||
@@ -566,6 +603,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | |||
566 | s->sock = sock; | 603 | s->sock = sock; |
567 | s->role = req->role; | 604 | s->role = req->role; |
568 | s->state = BT_CONNECTED; | 605 | s->state = BT_CONNECTED; |
606 | s->flags = req->flags; | ||
569 | 607 | ||
570 | s->msg.msg_flags = MSG_NOSIGNAL; | 608 | s->msg.msg_flags = MSG_NOSIGNAL; |
571 | 609 | ||
@@ -611,11 +649,15 @@ failed: | |||
611 | 649 | ||
612 | int bnep_del_connection(struct bnep_conndel_req *req) | 650 | int bnep_del_connection(struct bnep_conndel_req *req) |
613 | { | 651 | { |
652 | u32 valid_flags = 0; | ||
614 | struct bnep_session *s; | 653 | struct bnep_session *s; |
615 | int err = 0; | 654 | int err = 0; |
616 | 655 | ||
617 | BT_DBG(""); | 656 | BT_DBG(""); |
618 | 657 | ||
658 | if (req->flags & ~valid_flags) | ||
659 | return -EINVAL; | ||
660 | |||
619 | down_read(&bnep_session_sem); | 661 | down_read(&bnep_session_sem); |
620 | 662 | ||
621 | s = __bnep_get_session(req->dst); | 663 | s = __bnep_get_session(req->dst); |
@@ -631,10 +673,12 @@ int bnep_del_connection(struct bnep_conndel_req *req) | |||
631 | 673 | ||
632 | static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s) | 674 | static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s) |
633 | { | 675 | { |
676 | u32 valid_flags = BIT(BNEP_SETUP_RESPONSE); | ||
677 | |||
634 | memset(ci, 0, sizeof(*ci)); | 678 | memset(ci, 0, sizeof(*ci)); |
635 | memcpy(ci->dst, s->eh.h_source, ETH_ALEN); | 679 | memcpy(ci->dst, s->eh.h_source, ETH_ALEN); |
636 | strcpy(ci->device, s->dev->name); | 680 | strcpy(ci->device, s->dev->name); |
637 | ci->flags = s->flags; | 681 | ci->flags = s->flags & valid_flags; |
638 | ci->state = s->state; | 682 | ci->state = s->state; |
639 | ci->role = s->role; | 683 | ci->role = s->role; |
640 | } | 684 | } |
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 5f051290daba..bde2bdd9e929 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c | |||
@@ -57,6 +57,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
57 | struct bnep_conninfo ci; | 57 | struct bnep_conninfo ci; |
58 | struct socket *nsock; | 58 | struct socket *nsock; |
59 | void __user *argp = (void __user *)arg; | 59 | void __user *argp = (void __user *)arg; |
60 | __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE); | ||
60 | int err; | 61 | int err; |
61 | 62 | ||
62 | BT_DBG("cmd %x arg %lx", cmd, arg); | 63 | BT_DBG("cmd %x arg %lx", cmd, arg); |
@@ -120,6 +121,12 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
120 | 121 | ||
121 | return err; | 122 | return err; |
122 | 123 | ||
124 | case BNEPGETSUPPFEAT: | ||
125 | if (copy_to_user(argp, &supp_feat, sizeof(supp_feat))) | ||
126 | return -EFAULT; | ||
127 | |||
128 | return 0; | ||
129 | |||
123 | default: | 130 | default: |
124 | return -EINVAL; | 131 | return -EINVAL; |
125 | } | 132 | } |
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 75bd2c42e3e7..b0c6c6af76ef 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
@@ -333,7 +333,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) | |||
333 | return; | 333 | return; |
334 | } | 334 | } |
335 | 335 | ||
336 | if (session->flags & (1 << CMTP_LOOPBACK)) { | 336 | if (session->flags & BIT(CMTP_LOOPBACK)) { |
337 | kfree_skb(skb); | 337 | kfree_skb(skb); |
338 | return; | 338 | return; |
339 | } | 339 | } |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 278a194e6af4..298ed37010e6 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -75,10 +75,11 @@ static void __cmtp_unlink_session(struct cmtp_session *session) | |||
75 | 75 | ||
76 | static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci) | 76 | static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci) |
77 | { | 77 | { |
78 | u32 valid_flags = BIT(CMTP_LOOPBACK); | ||
78 | memset(ci, 0, sizeof(*ci)); | 79 | memset(ci, 0, sizeof(*ci)); |
79 | bacpy(&ci->bdaddr, &session->bdaddr); | 80 | bacpy(&ci->bdaddr, &session->bdaddr); |
80 | 81 | ||
81 | ci->flags = session->flags; | 82 | ci->flags = session->flags & valid_flags; |
82 | ci->state = session->state; | 83 | ci->state = session->state; |
83 | 84 | ||
84 | ci->num = session->num; | 85 | ci->num = session->num; |
@@ -313,7 +314,7 @@ static int cmtp_session(void *arg) | |||
313 | 314 | ||
314 | down_write(&cmtp_session_sem); | 315 | down_write(&cmtp_session_sem); |
315 | 316 | ||
316 | if (!(session->flags & (1 << CMTP_LOOPBACK))) | 317 | if (!(session->flags & BIT(CMTP_LOOPBACK))) |
317 | cmtp_detach_device(session); | 318 | cmtp_detach_device(session); |
318 | 319 | ||
319 | fput(session->sock->file); | 320 | fput(session->sock->file); |
@@ -329,6 +330,7 @@ static int cmtp_session(void *arg) | |||
329 | 330 | ||
330 | int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | 331 | int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) |
331 | { | 332 | { |
333 | u32 valid_flags = BIT(CMTP_LOOPBACK); | ||
332 | struct cmtp_session *session, *s; | 334 | struct cmtp_session *session, *s; |
333 | int i, err; | 335 | int i, err; |
334 | 336 | ||
@@ -337,6 +339,9 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
337 | if (!l2cap_is_socket(sock)) | 339 | if (!l2cap_is_socket(sock)) |
338 | return -EBADFD; | 340 | return -EBADFD; |
339 | 341 | ||
342 | if (req->flags & ~valid_flags) | ||
343 | return -EINVAL; | ||
344 | |||
340 | session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); | 345 | session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); |
341 | if (!session) | 346 | if (!session) |
342 | return -ENOMEM; | 347 | return -ENOMEM; |
@@ -385,7 +390,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
385 | goto unlink; | 390 | goto unlink; |
386 | } | 391 | } |
387 | 392 | ||
388 | if (!(session->flags & (1 << CMTP_LOOPBACK))) { | 393 | if (!(session->flags & BIT(CMTP_LOOPBACK))) { |
389 | err = cmtp_attach_device(session); | 394 | err = cmtp_attach_device(session); |
390 | if (err < 0) { | 395 | if (err < 0) { |
391 | atomic_inc(&session->terminate); | 396 | atomic_inc(&session->terminate); |
@@ -409,11 +414,15 @@ failed: | |||
409 | 414 | ||
410 | int cmtp_del_connection(struct cmtp_conndel_req *req) | 415 | int cmtp_del_connection(struct cmtp_conndel_req *req) |
411 | { | 416 | { |
417 | u32 valid_flags = 0; | ||
412 | struct cmtp_session *session; | 418 | struct cmtp_session *session; |
413 | int err = 0; | 419 | int err = 0; |
414 | 420 | ||
415 | BT_DBG(""); | 421 | BT_DBG(""); |
416 | 422 | ||
423 | if (req->flags & ~valid_flags) | ||
424 | return -EINVAL; | ||
425 | |||
417 | down_read(&cmtp_session_sem); | 426 | down_read(&cmtp_session_sem); |
418 | 427 | ||
419 | session = __cmtp_get_session(&req->bdaddr); | 428 | session = __cmtp_get_session(&req->bdaddr); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e6bfeb7b4415..46b114c0140b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -141,13 +141,16 @@ static const struct file_operations dut_mode_fops = { | |||
141 | 141 | ||
142 | /* ---- HCI requests ---- */ | 142 | /* ---- HCI requests ---- */ |
143 | 143 | ||
144 | static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode) | 144 | static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode, |
145 | struct sk_buff *skb) | ||
145 | { | 146 | { |
146 | BT_DBG("%s result 0x%2.2x", hdev->name, result); | 147 | BT_DBG("%s result 0x%2.2x", hdev->name, result); |
147 | 148 | ||
148 | if (hdev->req_status == HCI_REQ_PEND) { | 149 | if (hdev->req_status == HCI_REQ_PEND) { |
149 | hdev->req_result = result; | 150 | hdev->req_result = result; |
150 | hdev->req_status = HCI_REQ_DONE; | 151 | hdev->req_status = HCI_REQ_DONE; |
152 | if (skb) | ||
153 | hdev->req_skb = skb_get(skb); | ||
151 | wake_up_interruptible(&hdev->req_wait_q); | 154 | wake_up_interruptible(&hdev->req_wait_q); |
152 | } | 155 | } |
153 | } | 156 | } |
@@ -163,66 +166,12 @@ static void hci_req_cancel(struct hci_dev *hdev, int err) | |||
163 | } | 166 | } |
164 | } | 167 | } |
165 | 168 | ||
166 | static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, | ||
167 | u8 event) | ||
168 | { | ||
169 | struct hci_ev_cmd_complete *ev; | ||
170 | struct hci_event_hdr *hdr; | ||
171 | struct sk_buff *skb; | ||
172 | |||
173 | hci_dev_lock(hdev); | ||
174 | |||
175 | skb = hdev->recv_evt; | ||
176 | hdev->recv_evt = NULL; | ||
177 | |||
178 | hci_dev_unlock(hdev); | ||
179 | |||
180 | if (!skb) | ||
181 | return ERR_PTR(-ENODATA); | ||
182 | |||
183 | if (skb->len < sizeof(*hdr)) { | ||
184 | BT_ERR("Too short HCI event"); | ||
185 | goto failed; | ||
186 | } | ||
187 | |||
188 | hdr = (void *) skb->data; | ||
189 | skb_pull(skb, HCI_EVENT_HDR_SIZE); | ||
190 | |||
191 | if (event) { | ||
192 | if (hdr->evt != event) | ||
193 | goto failed; | ||
194 | return skb; | ||
195 | } | ||
196 | |||
197 | if (hdr->evt != HCI_EV_CMD_COMPLETE) { | ||
198 | BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); | ||
199 | goto failed; | ||
200 | } | ||
201 | |||
202 | if (skb->len < sizeof(*ev)) { | ||
203 | BT_ERR("Too short cmd_complete event"); | ||
204 | goto failed; | ||
205 | } | ||
206 | |||
207 | ev = (void *) skb->data; | ||
208 | skb_pull(skb, sizeof(*ev)); | ||
209 | |||
210 | if (opcode == __le16_to_cpu(ev->opcode)) | ||
211 | return skb; | ||
212 | |||
213 | BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, | ||
214 | __le16_to_cpu(ev->opcode)); | ||
215 | |||
216 | failed: | ||
217 | kfree_skb(skb); | ||
218 | return ERR_PTR(-ENODATA); | ||
219 | } | ||
220 | |||
221 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | 169 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, |
222 | const void *param, u8 event, u32 timeout) | 170 | const void *param, u8 event, u32 timeout) |
223 | { | 171 | { |
224 | DECLARE_WAITQUEUE(wait, current); | 172 | DECLARE_WAITQUEUE(wait, current); |
225 | struct hci_request req; | 173 | struct hci_request req; |
174 | struct sk_buff *skb; | ||
226 | int err = 0; | 175 | int err = 0; |
227 | 176 | ||
228 | BT_DBG("%s", hdev->name); | 177 | BT_DBG("%s", hdev->name); |
@@ -236,7 +185,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | |||
236 | add_wait_queue(&hdev->req_wait_q, &wait); | 185 | add_wait_queue(&hdev->req_wait_q, &wait); |
237 | set_current_state(TASK_INTERRUPTIBLE); | 186 | set_current_state(TASK_INTERRUPTIBLE); |
238 | 187 | ||
239 | err = hci_req_run(&req, hci_req_sync_complete); | 188 | err = hci_req_run_skb(&req, hci_req_sync_complete); |
240 | if (err < 0) { | 189 | if (err < 0) { |
241 | remove_wait_queue(&hdev->req_wait_q, &wait); | 190 | remove_wait_queue(&hdev->req_wait_q, &wait); |
242 | set_current_state(TASK_RUNNING); | 191 | set_current_state(TASK_RUNNING); |
@@ -265,13 +214,20 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | |||
265 | } | 214 | } |
266 | 215 | ||
267 | hdev->req_status = hdev->req_result = 0; | 216 | hdev->req_status = hdev->req_result = 0; |
217 | skb = hdev->req_skb; | ||
218 | hdev->req_skb = NULL; | ||
268 | 219 | ||
269 | BT_DBG("%s end: err %d", hdev->name, err); | 220 | BT_DBG("%s end: err %d", hdev->name, err); |
270 | 221 | ||
271 | if (err < 0) | 222 | if (err < 0) { |
223 | kfree_skb(skb); | ||
272 | return ERR_PTR(err); | 224 | return ERR_PTR(err); |
225 | } | ||
226 | |||
227 | if (!skb) | ||
228 | return ERR_PTR(-ENODATA); | ||
273 | 229 | ||
274 | return hci_get_cmd_complete(hdev, opcode, event); | 230 | return skb; |
275 | } | 231 | } |
276 | EXPORT_SYMBOL(__hci_cmd_sync_ev); | 232 | EXPORT_SYMBOL(__hci_cmd_sync_ev); |
277 | 233 | ||
@@ -303,7 +259,7 @@ static int __hci_req_sync(struct hci_dev *hdev, | |||
303 | add_wait_queue(&hdev->req_wait_q, &wait); | 259 | add_wait_queue(&hdev->req_wait_q, &wait); |
304 | set_current_state(TASK_INTERRUPTIBLE); | 260 | set_current_state(TASK_INTERRUPTIBLE); |
305 | 261 | ||
306 | err = hci_req_run(&req, hci_req_sync_complete); | 262 | err = hci_req_run_skb(&req, hci_req_sync_complete); |
307 | if (err < 0) { | 263 | if (err < 0) { |
308 | hdev->req_status = 0; | 264 | hdev->req_status = 0; |
309 | 265 | ||
@@ -1690,9 +1646,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
1690 | hdev->sent_cmd = NULL; | 1646 | hdev->sent_cmd = NULL; |
1691 | } | 1647 | } |
1692 | 1648 | ||
1693 | kfree_skb(hdev->recv_evt); | ||
1694 | hdev->recv_evt = NULL; | ||
1695 | |||
1696 | /* After this point our queues are empty | 1649 | /* After this point our queues are empty |
1697 | * and no tasks are scheduled. */ | 1650 | * and no tasks are scheduled. */ |
1698 | hdev->close(hdev); | 1651 | hdev->close(hdev); |
@@ -3563,11 +3516,6 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | |||
3563 | } | 3516 | } |
3564 | } | 3517 | } |
3565 | 3518 | ||
3566 | bool hci_req_pending(struct hci_dev *hdev) | ||
3567 | { | ||
3568 | return (hdev->req_status == HCI_REQ_PEND); | ||
3569 | } | ||
3570 | |||
3571 | /* Send HCI command */ | 3519 | /* Send HCI command */ |
3572 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, | 3520 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, |
3573 | const void *param) | 3521 | const void *param) |
@@ -3585,7 +3533,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, | |||
3585 | /* Stand-alone HCI commands must be flagged as | 3533 | /* Stand-alone HCI commands must be flagged as |
3586 | * single-command requests. | 3534 | * single-command requests. |
3587 | */ | 3535 | */ |
3588 | bt_cb(skb)->req_start = 1; | 3536 | bt_cb(skb)->req.start = true; |
3589 | 3537 | ||
3590 | skb_queue_tail(&hdev->cmd_q, skb); | 3538 | skb_queue_tail(&hdev->cmd_q, skb); |
3591 | queue_work(hdev->workqueue, &hdev->cmd_work); | 3539 | queue_work(hdev->workqueue, &hdev->cmd_work); |
@@ -4263,7 +4211,7 @@ static bool hci_req_is_complete(struct hci_dev *hdev) | |||
4263 | if (!skb) | 4211 | if (!skb) |
4264 | return true; | 4212 | return true; |
4265 | 4213 | ||
4266 | return bt_cb(skb)->req_start; | 4214 | return bt_cb(skb)->req.start; |
4267 | } | 4215 | } |
4268 | 4216 | ||
4269 | static void hci_resend_last(struct hci_dev *hdev) | 4217 | static void hci_resend_last(struct hci_dev *hdev) |
@@ -4288,9 +4236,10 @@ static void hci_resend_last(struct hci_dev *hdev) | |||
4288 | queue_work(hdev->workqueue, &hdev->cmd_work); | 4236 | queue_work(hdev->workqueue, &hdev->cmd_work); |
4289 | } | 4237 | } |
4290 | 4238 | ||
4291 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) | 4239 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, |
4240 | hci_req_complete_t *req_complete, | ||
4241 | hci_req_complete_skb_t *req_complete_skb) | ||
4292 | { | 4242 | { |
4293 | hci_req_complete_t req_complete = NULL; | ||
4294 | struct sk_buff *skb; | 4243 | struct sk_buff *skb; |
4295 | unsigned long flags; | 4244 | unsigned long flags; |
4296 | 4245 | ||
@@ -4322,36 +4271,29 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) | |||
4322 | * callback would be found in hdev->sent_cmd instead of the | 4271 | * callback would be found in hdev->sent_cmd instead of the |
4323 | * command queue (hdev->cmd_q). | 4272 | * command queue (hdev->cmd_q). |
4324 | */ | 4273 | */ |
4325 | if (hdev->sent_cmd) { | 4274 | if (bt_cb(hdev->sent_cmd)->req.complete) { |
4326 | req_complete = bt_cb(hdev->sent_cmd)->req_complete; | 4275 | *req_complete = bt_cb(hdev->sent_cmd)->req.complete; |
4327 | 4276 | return; | |
4328 | if (req_complete) { | 4277 | } |
4329 | /* We must set the complete callback to NULL to | ||
4330 | * avoid calling the callback more than once if | ||
4331 | * this function gets called again. | ||
4332 | */ | ||
4333 | bt_cb(hdev->sent_cmd)->req_complete = NULL; | ||
4334 | 4278 | ||
4335 | goto call_complete; | 4279 | if (bt_cb(hdev->sent_cmd)->req.complete_skb) { |
4336 | } | 4280 | *req_complete_skb = bt_cb(hdev->sent_cmd)->req.complete_skb; |
4281 | return; | ||
4337 | } | 4282 | } |
4338 | 4283 | ||
4339 | /* Remove all pending commands belonging to this request */ | 4284 | /* Remove all pending commands belonging to this request */ |
4340 | spin_lock_irqsave(&hdev->cmd_q.lock, flags); | 4285 | spin_lock_irqsave(&hdev->cmd_q.lock, flags); |
4341 | while ((skb = __skb_dequeue(&hdev->cmd_q))) { | 4286 | while ((skb = __skb_dequeue(&hdev->cmd_q))) { |
4342 | if (bt_cb(skb)->req_start) { | 4287 | if (bt_cb(skb)->req.start) { |
4343 | __skb_queue_head(&hdev->cmd_q, skb); | 4288 | __skb_queue_head(&hdev->cmd_q, skb); |
4344 | break; | 4289 | break; |
4345 | } | 4290 | } |
4346 | 4291 | ||
4347 | req_complete = bt_cb(skb)->req_complete; | 4292 | *req_complete = bt_cb(skb)->req.complete; |
4293 | *req_complete_skb = bt_cb(skb)->req.complete_skb; | ||
4348 | kfree_skb(skb); | 4294 | kfree_skb(skb); |
4349 | } | 4295 | } |
4350 | spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); | 4296 | spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); |
4351 | |||
4352 | call_complete: | ||
4353 | if (req_complete) | ||
4354 | req_complete(hdev, status, status ? opcode : HCI_OP_NOP); | ||
4355 | } | 4297 | } |
4356 | 4298 | ||
4357 | static void hci_rx_work(struct work_struct *work) | 4299 | static void hci_rx_work(struct work_struct *work) |
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c index e6255833a258..7db4220941cc 100644 --- a/net/bluetooth/hci_debugfs.c +++ b/net/bluetooth/hci_debugfs.c | |||
@@ -114,6 +114,30 @@ static const struct file_operations features_fops = { | |||
114 | .release = single_release, | 114 | .release = single_release, |
115 | }; | 115 | }; |
116 | 116 | ||
117 | static int device_id_show(struct seq_file *f, void *ptr) | ||
118 | { | ||
119 | struct hci_dev *hdev = f->private; | ||
120 | |||
121 | hci_dev_lock(hdev); | ||
122 | seq_printf(f, "%4.4x:%4.4x:%4.4x:%4.4x\n", hdev->devid_source, | ||
123 | hdev->devid_vendor, hdev->devid_product, hdev->devid_version); | ||
124 | hci_dev_unlock(hdev); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int device_id_open(struct inode *inode, struct file *file) | ||
130 | { | ||
131 | return single_open(file, device_id_show, inode->i_private); | ||
132 | } | ||
133 | |||
134 | static const struct file_operations device_id_fops = { | ||
135 | .open = device_id_open, | ||
136 | .read = seq_read, | ||
137 | .llseek = seq_lseek, | ||
138 | .release = single_release, | ||
139 | }; | ||
140 | |||
117 | static int device_list_show(struct seq_file *f, void *ptr) | 141 | static int device_list_show(struct seq_file *f, void *ptr) |
118 | { | 142 | { |
119 | struct hci_dev *hdev = f->private; | 143 | struct hci_dev *hdev = f->private; |
@@ -335,6 +359,8 @@ void hci_debugfs_create_common(struct hci_dev *hdev) | |||
335 | debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); | 359 | debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); |
336 | debugfs_create_u8("hardware_error", 0444, hdev->debugfs, | 360 | debugfs_create_u8("hardware_error", 0444, hdev->debugfs, |
337 | &hdev->hw_error_code); | 361 | &hdev->hw_error_code); |
362 | debugfs_create_file("device_id", 0444, hdev->debugfs, hdev, | ||
363 | &device_id_fops); | ||
338 | 364 | ||
339 | debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, | 365 | debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, |
340 | &device_list_fops); | 366 | &device_list_fops); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 62f92a508961..01031038eb0e 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1045,11 +1045,6 @@ static void hci_cc_read_local_oob_data(struct hci_dev *hdev, | |||
1045 | struct hci_rp_read_local_oob_data *rp = (void *) skb->data; | 1045 | struct hci_rp_read_local_oob_data *rp = (void *) skb->data; |
1046 | 1046 | ||
1047 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | 1047 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
1048 | |||
1049 | hci_dev_lock(hdev); | ||
1050 | mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->rand, NULL, NULL, | ||
1051 | rp->status); | ||
1052 | hci_dev_unlock(hdev); | ||
1053 | } | 1048 | } |
1054 | 1049 | ||
1055 | static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, | 1050 | static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, |
@@ -1058,15 +1053,8 @@ static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, | |||
1058 | struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; | 1053 | struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; |
1059 | 1054 | ||
1060 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | 1055 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
1061 | |||
1062 | hci_dev_lock(hdev); | ||
1063 | mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->rand192, | ||
1064 | rp->hash256, rp->rand256, | ||
1065 | rp->status); | ||
1066 | hci_dev_unlock(hdev); | ||
1067 | } | 1056 | } |
1068 | 1057 | ||
1069 | |||
1070 | static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) | 1058 | static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb) |
1071 | { | 1059 | { |
1072 | __u8 status = *((__u8 *) skb->data); | 1060 | __u8 status = *((__u8 *) skb->data); |
@@ -2732,17 +2720,19 @@ unlock: | |||
2732 | hci_dev_unlock(hdev); | 2720 | hci_dev_unlock(hdev); |
2733 | } | 2721 | } |
2734 | 2722 | ||
2735 | static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2723 | static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb, |
2724 | u16 *opcode, u8 *status, | ||
2725 | hci_req_complete_t *req_complete, | ||
2726 | hci_req_complete_skb_t *req_complete_skb) | ||
2736 | { | 2727 | { |
2737 | struct hci_ev_cmd_complete *ev = (void *) skb->data; | 2728 | struct hci_ev_cmd_complete *ev = (void *) skb->data; |
2738 | u8 status = skb->data[sizeof(*ev)]; | ||
2739 | __u16 opcode; | ||
2740 | 2729 | ||
2741 | skb_pull(skb, sizeof(*ev)); | 2730 | *opcode = __le16_to_cpu(ev->opcode); |
2731 | *status = skb->data[sizeof(*ev)]; | ||
2742 | 2732 | ||
2743 | opcode = __le16_to_cpu(ev->opcode); | 2733 | skb_pull(skb, sizeof(*ev)); |
2744 | 2734 | ||
2745 | switch (opcode) { | 2735 | switch (*opcode) { |
2746 | case HCI_OP_INQUIRY_CANCEL: | 2736 | case HCI_OP_INQUIRY_CANCEL: |
2747 | hci_cc_inquiry_cancel(hdev, skb); | 2737 | hci_cc_inquiry_cancel(hdev, skb); |
2748 | break; | 2738 | break; |
@@ -3020,32 +3010,36 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3020 | break; | 3010 | break; |
3021 | 3011 | ||
3022 | default: | 3012 | default: |
3023 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 3013 | BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); |
3024 | break; | 3014 | break; |
3025 | } | 3015 | } |
3026 | 3016 | ||
3027 | if (opcode != HCI_OP_NOP) | 3017 | if (*opcode != HCI_OP_NOP) |
3028 | cancel_delayed_work(&hdev->cmd_timer); | 3018 | cancel_delayed_work(&hdev->cmd_timer); |
3029 | 3019 | ||
3030 | hci_req_cmd_complete(hdev, opcode, status); | 3020 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) |
3031 | |||
3032 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { | ||
3033 | atomic_set(&hdev->cmd_cnt, 1); | 3021 | atomic_set(&hdev->cmd_cnt, 1); |
3034 | if (!skb_queue_empty(&hdev->cmd_q)) | 3022 | |
3035 | queue_work(hdev->workqueue, &hdev->cmd_work); | 3023 | hci_req_cmd_complete(hdev, *opcode, *status, req_complete, |
3036 | } | 3024 | req_complete_skb); |
3025 | |||
3026 | if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) | ||
3027 | queue_work(hdev->workqueue, &hdev->cmd_work); | ||
3037 | } | 3028 | } |
3038 | 3029 | ||
3039 | static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | 3030 | static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb, |
3031 | u16 *opcode, u8 *status, | ||
3032 | hci_req_complete_t *req_complete, | ||
3033 | hci_req_complete_skb_t *req_complete_skb) | ||
3040 | { | 3034 | { |
3041 | struct hci_ev_cmd_status *ev = (void *) skb->data; | 3035 | struct hci_ev_cmd_status *ev = (void *) skb->data; |
3042 | __u16 opcode; | ||
3043 | 3036 | ||
3044 | skb_pull(skb, sizeof(*ev)); | 3037 | skb_pull(skb, sizeof(*ev)); |
3045 | 3038 | ||
3046 | opcode = __le16_to_cpu(ev->opcode); | 3039 | *opcode = __le16_to_cpu(ev->opcode); |
3040 | *status = ev->status; | ||
3047 | 3041 | ||
3048 | switch (opcode) { | 3042 | switch (*opcode) { |
3049 | case HCI_OP_INQUIRY: | 3043 | case HCI_OP_INQUIRY: |
3050 | hci_cs_inquiry(hdev, ev->status); | 3044 | hci_cs_inquiry(hdev, ev->status); |
3051 | break; | 3045 | break; |
@@ -3115,22 +3109,29 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3115 | break; | 3109 | break; |
3116 | 3110 | ||
3117 | default: | 3111 | default: |
3118 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 3112 | BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode); |
3119 | break; | 3113 | break; |
3120 | } | 3114 | } |
3121 | 3115 | ||
3122 | if (opcode != HCI_OP_NOP) | 3116 | if (*opcode != HCI_OP_NOP) |
3123 | cancel_delayed_work(&hdev->cmd_timer); | 3117 | cancel_delayed_work(&hdev->cmd_timer); |
3124 | 3118 | ||
3119 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) | ||
3120 | atomic_set(&hdev->cmd_cnt, 1); | ||
3121 | |||
3122 | /* Indicate request completion if the command failed. Also, if | ||
3123 | * we're not waiting for a special event and we get a success | ||
3124 | * command status we should try to flag the request as completed | ||
3125 | * (since for this kind of commands there will not be a command | ||
3126 | * complete event). | ||
3127 | */ | ||
3125 | if (ev->status || | 3128 | if (ev->status || |
3126 | (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req_event)) | 3129 | (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) |
3127 | hci_req_cmd_complete(hdev, opcode, ev->status); | 3130 | hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, |
3131 | req_complete_skb); | ||
3128 | 3132 | ||
3129 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { | 3133 | if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) |
3130 | atomic_set(&hdev->cmd_cnt, 1); | 3134 | queue_work(hdev->workqueue, &hdev->cmd_work); |
3131 | if (!skb_queue_empty(&hdev->cmd_q)) | ||
3132 | queue_work(hdev->workqueue, &hdev->cmd_work); | ||
3133 | } | ||
3134 | } | 3135 | } |
3135 | 3136 | ||
3136 | static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) | 3137 | static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -5031,32 +5032,79 @@ static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
5031 | amp_read_loc_assoc_final_data(hdev, hcon); | 5032 | amp_read_loc_assoc_final_data(hdev, hcon); |
5032 | } | 5033 | } |
5033 | 5034 | ||
5034 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 5035 | static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, |
5036 | u8 event, struct sk_buff *skb) | ||
5035 | { | 5037 | { |
5036 | struct hci_event_hdr *hdr = (void *) skb->data; | 5038 | struct hci_ev_cmd_complete *ev; |
5037 | __u8 event = hdr->evt; | 5039 | struct hci_event_hdr *hdr; |
5038 | 5040 | ||
5039 | hci_dev_lock(hdev); | 5041 | if (!skb) |
5042 | return false; | ||
5040 | 5043 | ||
5041 | /* Received events are (currently) only needed when a request is | 5044 | if (skb->len < sizeof(*hdr)) { |
5042 | * ongoing so avoid unnecessary memory allocation. | 5045 | BT_ERR("Too short HCI event"); |
5043 | */ | 5046 | return false; |
5044 | if (hci_req_pending(hdev)) { | ||
5045 | kfree_skb(hdev->recv_evt); | ||
5046 | hdev->recv_evt = skb_clone(skb, GFP_KERNEL); | ||
5047 | } | 5047 | } |
5048 | 5048 | ||
5049 | hci_dev_unlock(hdev); | 5049 | hdr = (void *) skb->data; |
5050 | |||
5051 | skb_pull(skb, HCI_EVENT_HDR_SIZE); | 5050 | skb_pull(skb, HCI_EVENT_HDR_SIZE); |
5052 | 5051 | ||
5053 | if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req_event == event) { | 5052 | if (event) { |
5054 | struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; | 5053 | if (hdr->evt != event) |
5055 | u16 opcode = __le16_to_cpu(cmd_hdr->opcode); | 5054 | return false; |
5055 | return true; | ||
5056 | } | ||
5057 | |||
5058 | if (hdr->evt != HCI_EV_CMD_COMPLETE) { | ||
5059 | BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); | ||
5060 | return false; | ||
5061 | } | ||
5062 | |||
5063 | if (skb->len < sizeof(*ev)) { | ||
5064 | BT_ERR("Too short cmd_complete event"); | ||
5065 | return false; | ||
5066 | } | ||
5067 | |||
5068 | ev = (void *) skb->data; | ||
5069 | skb_pull(skb, sizeof(*ev)); | ||
5056 | 5070 | ||
5057 | hci_req_cmd_complete(hdev, opcode, 0); | 5071 | if (opcode != __le16_to_cpu(ev->opcode)) { |
5072 | BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, | ||
5073 | __le16_to_cpu(ev->opcode)); | ||
5074 | return false; | ||
5058 | } | 5075 | } |
5059 | 5076 | ||
5077 | return true; | ||
5078 | } | ||
5079 | |||
5080 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | ||
5081 | { | ||
5082 | struct hci_event_hdr *hdr = (void *) skb->data; | ||
5083 | hci_req_complete_t req_complete = NULL; | ||
5084 | hci_req_complete_skb_t req_complete_skb = NULL; | ||
5085 | struct sk_buff *orig_skb = NULL; | ||
5086 | u8 status = 0, event = hdr->evt, req_evt = 0; | ||
5087 | u16 opcode = HCI_OP_NOP; | ||
5088 | |||
5089 | if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { | ||
5090 | struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; | ||
5091 | opcode = __le16_to_cpu(cmd_hdr->opcode); | ||
5092 | hci_req_cmd_complete(hdev, opcode, status, &req_complete, | ||
5093 | &req_complete_skb); | ||
5094 | req_evt = event; | ||
5095 | } | ||
5096 | |||
5097 | /* If it looks like we might end up having to call | ||
5098 | * req_complete_skb, store a pristine copy of the skb since the | ||
5099 | * various handlers may modify the original one through | ||
5100 | * skb_pull() calls, etc. | ||
5101 | */ | ||
5102 | if (req_complete_skb || event == HCI_EV_CMD_STATUS || | ||
5103 | event == HCI_EV_CMD_COMPLETE) | ||
5104 | orig_skb = skb_clone(skb, GFP_KERNEL); | ||
5105 | |||
5106 | skb_pull(skb, HCI_EVENT_HDR_SIZE); | ||
5107 | |||
5060 | switch (event) { | 5108 | switch (event) { |
5061 | case HCI_EV_INQUIRY_COMPLETE: | 5109 | case HCI_EV_INQUIRY_COMPLETE: |
5062 | hci_inquiry_complete_evt(hdev, skb); | 5110 | hci_inquiry_complete_evt(hdev, skb); |
@@ -5099,11 +5147,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
5099 | break; | 5147 | break; |
5100 | 5148 | ||
5101 | case HCI_EV_CMD_COMPLETE: | 5149 | case HCI_EV_CMD_COMPLETE: |
5102 | hci_cmd_complete_evt(hdev, skb); | 5150 | hci_cmd_complete_evt(hdev, skb, &opcode, &status, |
5151 | &req_complete, &req_complete_skb); | ||
5103 | break; | 5152 | break; |
5104 | 5153 | ||
5105 | case HCI_EV_CMD_STATUS: | 5154 | case HCI_EV_CMD_STATUS: |
5106 | hci_cmd_status_evt(hdev, skb); | 5155 | hci_cmd_status_evt(hdev, skb, &opcode, &status, &req_complete, |
5156 | &req_complete_skb); | ||
5107 | break; | 5157 | break; |
5108 | 5158 | ||
5109 | case HCI_EV_HARDWARE_ERROR: | 5159 | case HCI_EV_HARDWARE_ERROR: |
@@ -5235,6 +5285,17 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
5235 | break; | 5285 | break; |
5236 | } | 5286 | } |
5237 | 5287 | ||
5288 | if (req_complete) { | ||
5289 | req_complete(hdev, status, opcode); | ||
5290 | } else if (req_complete_skb) { | ||
5291 | if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) { | ||
5292 | kfree_skb(orig_skb); | ||
5293 | orig_skb = NULL; | ||
5294 | } | ||
5295 | req_complete_skb(hdev, status, opcode, orig_skb); | ||
5296 | } | ||
5297 | |||
5298 | kfree_skb(orig_skb); | ||
5238 | kfree_skb(skb); | 5299 | kfree_skb(skb); |
5239 | hdev->stat.evt_rx++; | 5300 | hdev->stat.evt_rx++; |
5240 | } | 5301 | } |
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 55e096d20a0f..d6025d6e6d59 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c | |||
@@ -34,7 +34,8 @@ void hci_req_init(struct hci_request *req, struct hci_dev *hdev) | |||
34 | req->err = 0; | 34 | req->err = 0; |
35 | } | 35 | } |
36 | 36 | ||
37 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete) | 37 | static int req_run(struct hci_request *req, hci_req_complete_t complete, |
38 | hci_req_complete_skb_t complete_skb) | ||
38 | { | 39 | { |
39 | struct hci_dev *hdev = req->hdev; | 40 | struct hci_dev *hdev = req->hdev; |
40 | struct sk_buff *skb; | 41 | struct sk_buff *skb; |
@@ -55,7 +56,8 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete) | |||
55 | return -ENODATA; | 56 | return -ENODATA; |
56 | 57 | ||
57 | skb = skb_peek_tail(&req->cmd_q); | 58 | skb = skb_peek_tail(&req->cmd_q); |
58 | bt_cb(skb)->req_complete = complete; | 59 | bt_cb(skb)->req.complete = complete; |
60 | bt_cb(skb)->req.complete_skb = complete_skb; | ||
59 | 61 | ||
60 | spin_lock_irqsave(&hdev->cmd_q.lock, flags); | 62 | spin_lock_irqsave(&hdev->cmd_q.lock, flags); |
61 | skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); | 63 | skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); |
@@ -66,6 +68,16 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete) | |||
66 | return 0; | 68 | return 0; |
67 | } | 69 | } |
68 | 70 | ||
71 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete) | ||
72 | { | ||
73 | return req_run(req, complete, NULL); | ||
74 | } | ||
75 | |||
76 | int hci_req_run_skb(struct hci_request *req, hci_req_complete_skb_t complete) | ||
77 | { | ||
78 | return req_run(req, NULL, complete); | ||
79 | } | ||
80 | |||
69 | struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, | 81 | struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, |
70 | const void *param) | 82 | const void *param) |
71 | { | 83 | { |
@@ -116,9 +128,9 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, | |||
116 | } | 128 | } |
117 | 129 | ||
118 | if (skb_queue_empty(&req->cmd_q)) | 130 | if (skb_queue_empty(&req->cmd_q)) |
119 | bt_cb(skb)->req_start = 1; | 131 | bt_cb(skb)->req.start = true; |
120 | 132 | ||
121 | bt_cb(skb)->req_event = event; | 133 | bt_cb(skb)->req.event = event; |
122 | 134 | ||
123 | skb_queue_tail(&req->cmd_q, skb); | 135 | skb_queue_tail(&req->cmd_q, skb); |
124 | } | 136 | } |
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h index adf074d33544..bf6df92f42db 100644 --- a/net/bluetooth/hci_request.h +++ b/net/bluetooth/hci_request.h | |||
@@ -32,11 +32,14 @@ struct hci_request { | |||
32 | 32 | ||
33 | void hci_req_init(struct hci_request *req, struct hci_dev *hdev); | 33 | void hci_req_init(struct hci_request *req, struct hci_dev *hdev); |
34 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete); | 34 | int hci_req_run(struct hci_request *req, hci_req_complete_t complete); |
35 | int hci_req_run_skb(struct hci_request *req, hci_req_complete_skb_t complete); | ||
35 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, | 36 | void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, |
36 | const void *param); | 37 | const void *param); |
37 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, | 38 | void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, |
38 | const void *param, u8 event); | 39 | const void *param, u8 event); |
39 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); | 40 | void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, |
41 | hci_req_complete_t *req_complete, | ||
42 | hci_req_complete_skb_t *req_complete_skb); | ||
40 | 43 | ||
41 | struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, | 44 | struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, |
42 | const void *param); | 45 | const void *param); |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 85a44a7dc150..56f9edbf3d05 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -1164,7 +1164,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1164 | /* Stand-alone HCI commands must be flagged as | 1164 | /* Stand-alone HCI commands must be flagged as |
1165 | * single-command requests. | 1165 | * single-command requests. |
1166 | */ | 1166 | */ |
1167 | bt_cb(skb)->req_start = 1; | 1167 | bt_cb(skb)->req.start = true; |
1168 | 1168 | ||
1169 | skb_queue_tail(&hdev->cmd_q, skb); | 1169 | skb_queue_tail(&hdev->cmd_q, skb); |
1170 | queue_work(hdev->workqueue, &hdev->cmd_work); | 1170 | queue_work(hdev->workqueue, &hdev->cmd_work); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 07348e142f16..a05b9dbf14c9 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -70,10 +70,11 @@ static void hidp_session_terminate(struct hidp_session *s); | |||
70 | 70 | ||
71 | static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) | 71 | static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) |
72 | { | 72 | { |
73 | u32 valid_flags = 0; | ||
73 | memset(ci, 0, sizeof(*ci)); | 74 | memset(ci, 0, sizeof(*ci)); |
74 | bacpy(&ci->bdaddr, &session->bdaddr); | 75 | bacpy(&ci->bdaddr, &session->bdaddr); |
75 | 76 | ||
76 | ci->flags = session->flags; | 77 | ci->flags = session->flags & valid_flags; |
77 | ci->state = BT_CONNECTED; | 78 | ci->state = BT_CONNECTED; |
78 | 79 | ||
79 | if (session->input) { | 80 | if (session->input) { |
@@ -907,7 +908,7 @@ static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, | |||
907 | kref_init(&session->ref); | 908 | kref_init(&session->ref); |
908 | atomic_set(&session->state, HIDP_SESSION_IDLING); | 909 | atomic_set(&session->state, HIDP_SESSION_IDLING); |
909 | init_waitqueue_head(&session->state_queue); | 910 | init_waitqueue_head(&session->state_queue); |
910 | session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); | 911 | session->flags = req->flags & BIT(HIDP_BLUETOOTH_VENDOR_ID); |
911 | 912 | ||
912 | /* connection management */ | 913 | /* connection management */ |
913 | bacpy(&session->bdaddr, bdaddr); | 914 | bacpy(&session->bdaddr, bdaddr); |
@@ -1312,6 +1313,7 @@ int hidp_connection_add(struct hidp_connadd_req *req, | |||
1312 | struct socket *ctrl_sock, | 1313 | struct socket *ctrl_sock, |
1313 | struct socket *intr_sock) | 1314 | struct socket *intr_sock) |
1314 | { | 1315 | { |
1316 | u32 valid_flags = 0; | ||
1315 | struct hidp_session *session; | 1317 | struct hidp_session *session; |
1316 | struct l2cap_conn *conn; | 1318 | struct l2cap_conn *conn; |
1317 | struct l2cap_chan *chan; | 1319 | struct l2cap_chan *chan; |
@@ -1321,6 +1323,9 @@ int hidp_connection_add(struct hidp_connadd_req *req, | |||
1321 | if (ret) | 1323 | if (ret) |
1322 | return ret; | 1324 | return ret; |
1323 | 1325 | ||
1326 | if (req->flags & ~valid_flags) | ||
1327 | return -EINVAL; | ||
1328 | |||
1324 | chan = l2cap_pi(ctrl_sock->sk)->chan; | 1329 | chan = l2cap_pi(ctrl_sock->sk)->chan; |
1325 | conn = NULL; | 1330 | conn = NULL; |
1326 | l2cap_chan_lock(chan); | 1331 | l2cap_chan_lock(chan); |
@@ -1351,13 +1356,17 @@ out_conn: | |||
1351 | 1356 | ||
1352 | int hidp_connection_del(struct hidp_conndel_req *req) | 1357 | int hidp_connection_del(struct hidp_conndel_req *req) |
1353 | { | 1358 | { |
1359 | u32 valid_flags = BIT(HIDP_VIRTUAL_CABLE_UNPLUG); | ||
1354 | struct hidp_session *session; | 1360 | struct hidp_session *session; |
1355 | 1361 | ||
1362 | if (req->flags & ~valid_flags) | ||
1363 | return -EINVAL; | ||
1364 | |||
1356 | session = hidp_session_find(&req->bdaddr); | 1365 | session = hidp_session_find(&req->bdaddr); |
1357 | if (!session) | 1366 | if (!session) |
1358 | return -ENOENT; | 1367 | return -ENOENT; |
1359 | 1368 | ||
1360 | if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) | 1369 | if (req->flags & BIT(HIDP_VIRTUAL_CABLE_UNPLUG)) |
1361 | hidp_send_ctrl_message(session, | 1370 | hidp_send_ctrl_message(session, |
1362 | HIDP_TRANS_HID_CONTROL | | 1371 | HIDP_TRANS_HID_CONTROL | |
1363 | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, | 1372 | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d69861c89bb5..dad419782a12 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -292,7 +292,7 @@ static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head, | |||
292 | struct sk_buff *skb; | 292 | struct sk_buff *skb; |
293 | 293 | ||
294 | skb_queue_walk(head, skb) { | 294 | skb_queue_walk(head, skb) { |
295 | if (bt_cb(skb)->control.txseq == seq) | 295 | if (bt_cb(skb)->l2cap.txseq == seq) |
296 | return skb; | 296 | return skb; |
297 | } | 297 | } |
298 | 298 | ||
@@ -954,11 +954,11 @@ static inline void __unpack_control(struct l2cap_chan *chan, | |||
954 | { | 954 | { |
955 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) { | 955 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) { |
956 | __unpack_extended_control(get_unaligned_le32(skb->data), | 956 | __unpack_extended_control(get_unaligned_le32(skb->data), |
957 | &bt_cb(skb)->control); | 957 | &bt_cb(skb)->l2cap); |
958 | skb_pull(skb, L2CAP_EXT_CTRL_SIZE); | 958 | skb_pull(skb, L2CAP_EXT_CTRL_SIZE); |
959 | } else { | 959 | } else { |
960 | __unpack_enhanced_control(get_unaligned_le16(skb->data), | 960 | __unpack_enhanced_control(get_unaligned_le16(skb->data), |
961 | &bt_cb(skb)->control); | 961 | &bt_cb(skb)->l2cap); |
962 | skb_pull(skb, L2CAP_ENH_CTRL_SIZE); | 962 | skb_pull(skb, L2CAP_ENH_CTRL_SIZE); |
963 | } | 963 | } |
964 | } | 964 | } |
@@ -1200,8 +1200,8 @@ static void l2cap_move_setup(struct l2cap_chan *chan) | |||
1200 | 1200 | ||
1201 | chan->retry_count = 0; | 1201 | chan->retry_count = 0; |
1202 | skb_queue_walk(&chan->tx_q, skb) { | 1202 | skb_queue_walk(&chan->tx_q, skb) { |
1203 | if (bt_cb(skb)->control.retries) | 1203 | if (bt_cb(skb)->l2cap.retries) |
1204 | bt_cb(skb)->control.retries = 1; | 1204 | bt_cb(skb)->l2cap.retries = 1; |
1205 | else | 1205 | else |
1206 | break; | 1206 | break; |
1207 | } | 1207 | } |
@@ -1846,8 +1846,8 @@ static void l2cap_streaming_send(struct l2cap_chan *chan, | |||
1846 | 1846 | ||
1847 | skb = skb_dequeue(&chan->tx_q); | 1847 | skb = skb_dequeue(&chan->tx_q); |
1848 | 1848 | ||
1849 | bt_cb(skb)->control.retries = 1; | 1849 | bt_cb(skb)->l2cap.retries = 1; |
1850 | control = &bt_cb(skb)->control; | 1850 | control = &bt_cb(skb)->l2cap; |
1851 | 1851 | ||
1852 | control->reqseq = 0; | 1852 | control->reqseq = 0; |
1853 | control->txseq = chan->next_tx_seq; | 1853 | control->txseq = chan->next_tx_seq; |
@@ -1891,8 +1891,8 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1891 | 1891 | ||
1892 | skb = chan->tx_send_head; | 1892 | skb = chan->tx_send_head; |
1893 | 1893 | ||
1894 | bt_cb(skb)->control.retries = 1; | 1894 | bt_cb(skb)->l2cap.retries = 1; |
1895 | control = &bt_cb(skb)->control; | 1895 | control = &bt_cb(skb)->l2cap; |
1896 | 1896 | ||
1897 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) | 1897 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
1898 | control->final = 1; | 1898 | control->final = 1; |
@@ -1963,11 +1963,11 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) | |||
1963 | continue; | 1963 | continue; |
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | bt_cb(skb)->control.retries++; | 1966 | bt_cb(skb)->l2cap.retries++; |
1967 | control = bt_cb(skb)->control; | 1967 | control = bt_cb(skb)->l2cap; |
1968 | 1968 | ||
1969 | if (chan->max_tx != 0 && | 1969 | if (chan->max_tx != 0 && |
1970 | bt_cb(skb)->control.retries > chan->max_tx) { | 1970 | bt_cb(skb)->l2cap.retries > chan->max_tx) { |
1971 | BT_DBG("Retry limit exceeded (%d)", chan->max_tx); | 1971 | BT_DBG("Retry limit exceeded (%d)", chan->max_tx); |
1972 | l2cap_send_disconn_req(chan, ECONNRESET); | 1972 | l2cap_send_disconn_req(chan, ECONNRESET); |
1973 | l2cap_seq_list_clear(&chan->retrans_list); | 1973 | l2cap_seq_list_clear(&chan->retrans_list); |
@@ -2045,7 +2045,7 @@ static void l2cap_retransmit_all(struct l2cap_chan *chan, | |||
2045 | 2045 | ||
2046 | if (chan->unacked_frames) { | 2046 | if (chan->unacked_frames) { |
2047 | skb_queue_walk(&chan->tx_q, skb) { | 2047 | skb_queue_walk(&chan->tx_q, skb) { |
2048 | if (bt_cb(skb)->control.txseq == control->reqseq || | 2048 | if (bt_cb(skb)->l2cap.txseq == control->reqseq || |
2049 | skb == chan->tx_send_head) | 2049 | skb == chan->tx_send_head) |
2050 | break; | 2050 | break; |
2051 | } | 2051 | } |
@@ -2055,7 +2055,7 @@ static void l2cap_retransmit_all(struct l2cap_chan *chan, | |||
2055 | break; | 2055 | break; |
2056 | 2056 | ||
2057 | l2cap_seq_list_append(&chan->retrans_list, | 2057 | l2cap_seq_list_append(&chan->retrans_list, |
2058 | bt_cb(skb)->control.txseq); | 2058 | bt_cb(skb)->l2cap.txseq); |
2059 | } | 2059 | } |
2060 | 2060 | ||
2061 | l2cap_ertm_resend(chan); | 2061 | l2cap_ertm_resend(chan); |
@@ -2267,8 +2267,8 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | |||
2267 | return ERR_PTR(err); | 2267 | return ERR_PTR(err); |
2268 | } | 2268 | } |
2269 | 2269 | ||
2270 | bt_cb(skb)->control.fcs = chan->fcs; | 2270 | bt_cb(skb)->l2cap.fcs = chan->fcs; |
2271 | bt_cb(skb)->control.retries = 0; | 2271 | bt_cb(skb)->l2cap.retries = 0; |
2272 | return skb; | 2272 | return skb; |
2273 | } | 2273 | } |
2274 | 2274 | ||
@@ -2321,7 +2321,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, | |||
2321 | return PTR_ERR(skb); | 2321 | return PTR_ERR(skb); |
2322 | } | 2322 | } |
2323 | 2323 | ||
2324 | bt_cb(skb)->control.sar = sar; | 2324 | bt_cb(skb)->l2cap.sar = sar; |
2325 | __skb_queue_tail(seg_queue, skb); | 2325 | __skb_queue_tail(seg_queue, skb); |
2326 | 2326 | ||
2327 | len -= pdu_len; | 2327 | len -= pdu_len; |
@@ -2856,7 +2856,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
2856 | continue; | 2856 | continue; |
2857 | 2857 | ||
2858 | /* Don't send frame to the channel it came from */ | 2858 | /* Don't send frame to the channel it came from */ |
2859 | if (bt_cb(skb)->chan == chan) | 2859 | if (bt_cb(skb)->l2cap.chan == chan) |
2860 | continue; | 2860 | continue; |
2861 | 2861 | ||
2862 | nskb = skb_clone(skb, GFP_KERNEL); | 2862 | nskb = skb_clone(skb, GFP_KERNEL); |
@@ -5918,7 +5918,7 @@ static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) | |||
5918 | 5918 | ||
5919 | skb_unlink(skb, &chan->srej_q); | 5919 | skb_unlink(skb, &chan->srej_q); |
5920 | chan->buffer_seq = __next_seq(chan, chan->buffer_seq); | 5920 | chan->buffer_seq = __next_seq(chan, chan->buffer_seq); |
5921 | err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control); | 5921 | err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->l2cap); |
5922 | if (err) | 5922 | if (err) |
5923 | break; | 5923 | break; |
5924 | } | 5924 | } |
@@ -5952,7 +5952,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan, | |||
5952 | return; | 5952 | return; |
5953 | } | 5953 | } |
5954 | 5954 | ||
5955 | if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) { | 5955 | if (chan->max_tx != 0 && bt_cb(skb)->l2cap.retries >= chan->max_tx) { |
5956 | BT_DBG("Retry limit exceeded (%d)", chan->max_tx); | 5956 | BT_DBG("Retry limit exceeded (%d)", chan->max_tx); |
5957 | l2cap_send_disconn_req(chan, ECONNRESET); | 5957 | l2cap_send_disconn_req(chan, ECONNRESET); |
5958 | return; | 5958 | return; |
@@ -6005,7 +6005,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, | |||
6005 | skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq); | 6005 | skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq); |
6006 | 6006 | ||
6007 | if (chan->max_tx && skb && | 6007 | if (chan->max_tx && skb && |
6008 | bt_cb(skb)->control.retries >= chan->max_tx) { | 6008 | bt_cb(skb)->l2cap.retries >= chan->max_tx) { |
6009 | BT_DBG("Retry limit exceeded (%d)", chan->max_tx); | 6009 | BT_DBG("Retry limit exceeded (%d)", chan->max_tx); |
6010 | l2cap_send_disconn_req(chan, ECONNRESET); | 6010 | l2cap_send_disconn_req(chan, ECONNRESET); |
6011 | return; | 6011 | return; |
@@ -6565,7 +6565,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, | |||
6565 | 6565 | ||
6566 | static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) | 6566 | static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) |
6567 | { | 6567 | { |
6568 | struct l2cap_ctrl *control = &bt_cb(skb)->control; | 6568 | struct l2cap_ctrl *control = &bt_cb(skb)->l2cap; |
6569 | u16 len; | 6569 | u16 len; |
6570 | u8 event; | 6570 | u8 event; |
6571 | 6571 | ||
@@ -6864,8 +6864,8 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, | |||
6864 | goto drop; | 6864 | goto drop; |
6865 | 6865 | ||
6866 | /* Store remote BD_ADDR and PSM for msg_name */ | 6866 | /* Store remote BD_ADDR and PSM for msg_name */ |
6867 | bacpy(&bt_cb(skb)->bdaddr, &hcon->dst); | 6867 | bacpy(&bt_cb(skb)->l2cap.bdaddr, &hcon->dst); |
6868 | bt_cb(skb)->psm = psm; | 6868 | bt_cb(skb)->l2cap.psm = psm; |
6869 | 6869 | ||
6870 | if (!chan->ops->recv(chan, skb)) { | 6870 | if (!chan->ops->recv(chan, skb)) { |
6871 | l2cap_chan_put(chan); | 6871 | l2cap_chan_put(chan); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 9070720eedc8..a7278f05eafb 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1330,7 +1330,7 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, | |||
1330 | 1330 | ||
1331 | skb->priority = sk->sk_priority; | 1331 | skb->priority = sk->sk_priority; |
1332 | 1332 | ||
1333 | bt_cb(skb)->chan = chan; | 1333 | bt_cb(skb)->l2cap.chan = chan; |
1334 | 1334 | ||
1335 | return skb; | 1335 | return skb; |
1336 | } | 1336 | } |
@@ -1444,8 +1444,8 @@ static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name, | |||
1444 | 1444 | ||
1445 | memset(la, 0, sizeof(struct sockaddr_l2)); | 1445 | memset(la, 0, sizeof(struct sockaddr_l2)); |
1446 | la->l2_family = AF_BLUETOOTH; | 1446 | la->l2_family = AF_BLUETOOTH; |
1447 | la->l2_psm = bt_cb(skb)->psm; | 1447 | la->l2_psm = bt_cb(skb)->l2cap.psm; |
1448 | bacpy(&la->l2_bdaddr, &bt_cb(skb)->bdaddr); | 1448 | bacpy(&la->l2_bdaddr, &bt_cb(skb)->l2cap.bdaddr); |
1449 | 1449 | ||
1450 | *msg_namelen = sizeof(struct sockaddr_l2); | 1450 | *msg_namelen = sizeof(struct sockaddr_l2); |
1451 | } | 1451 | } |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index fb2e764c6211..845dfcc43a20 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -985,14 +985,27 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance) | |||
985 | /* Instance 0 always manages the "Tx Power" and "Flags" fields */ | 985 | /* Instance 0 always manages the "Tx Power" and "Flags" fields */ |
986 | flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS; | 986 | flags = MGMT_ADV_FLAG_TX_POWER | MGMT_ADV_FLAG_MANAGED_FLAGS; |
987 | 987 | ||
988 | /* For instance 0, assemble the flags from global settings */ | 988 | /* For instance 0, the HCI_ADVERTISING_CONNECTABLE setting corresponds |
989 | if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE) || | 989 | * to the "connectable" instance flag. |
990 | get_connectable(hdev)) | 990 | */ |
991 | if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE)) | ||
991 | flags |= MGMT_ADV_FLAG_CONNECTABLE; | 992 | flags |= MGMT_ADV_FLAG_CONNECTABLE; |
992 | 993 | ||
993 | return flags; | 994 | return flags; |
994 | } | 995 | } |
995 | 996 | ||
997 | static u8 get_adv_instance_scan_rsp_len(struct hci_dev *hdev, u8 instance) | ||
998 | { | ||
999 | /* Ignore instance 0 and other unsupported instances */ | ||
1000 | if (instance != 0x01) | ||
1001 | return 0; | ||
1002 | |||
1003 | /* TODO: Take into account the "appearance" and "local-name" flags here. | ||
1004 | * These are currently being ignored as they are not supported. | ||
1005 | */ | ||
1006 | return hdev->adv_instance.scan_rsp_len; | ||
1007 | } | ||
1008 | |||
996 | static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) | 1009 | static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) |
997 | { | 1010 | { |
998 | u8 ad_len = 0, flags = 0; | 1011 | u8 ad_len = 0, flags = 0; |
@@ -1030,6 +1043,14 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) | |||
1030 | } | 1043 | } |
1031 | } | 1044 | } |
1032 | 1045 | ||
1046 | if (instance) { | ||
1047 | memcpy(ptr, hdev->adv_instance.adv_data, | ||
1048 | hdev->adv_instance.adv_data_len); | ||
1049 | |||
1050 | ad_len += hdev->adv_instance.adv_data_len; | ||
1051 | ptr += hdev->adv_instance.adv_data_len; | ||
1052 | } | ||
1053 | |||
1033 | /* Provide Tx Power only if we can provide a valid value for it */ | 1054 | /* Provide Tx Power only if we can provide a valid value for it */ |
1034 | if (hdev->adv_tx_power != HCI_TX_POWER_INVALID && | 1055 | if (hdev->adv_tx_power != HCI_TX_POWER_INVALID && |
1035 | (instance_flags & MGMT_ADV_FLAG_TX_POWER)) { | 1056 | (instance_flags & MGMT_ADV_FLAG_TX_POWER)) { |
@@ -1041,12 +1062,6 @@ static u8 create_instance_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) | |||
1041 | ptr += 3; | 1062 | ptr += 3; |
1042 | } | 1063 | } |
1043 | 1064 | ||
1044 | if (instance) { | ||
1045 | memcpy(ptr, hdev->adv_instance.adv_data, | ||
1046 | hdev->adv_instance.adv_data_len); | ||
1047 | ad_len += hdev->adv_instance.adv_data_len; | ||
1048 | } | ||
1049 | |||
1050 | return ad_len; | 1065 | return ad_len; |
1051 | } | 1066 | } |
1052 | 1067 | ||
@@ -1242,7 +1257,12 @@ static void enable_advertising(struct hci_request *req) | |||
1242 | 1257 | ||
1243 | instance = get_current_adv_instance(hdev); | 1258 | instance = get_current_adv_instance(hdev); |
1244 | flags = get_adv_instance_flags(hdev, instance); | 1259 | flags = get_adv_instance_flags(hdev, instance); |
1245 | connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE); | 1260 | |
1261 | /* If the "connectable" instance flag was not set, then choose between | ||
1262 | * ADV_IND and ADV_NONCONN_IND based on the global connectable setting. | ||
1263 | */ | ||
1264 | connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE) || | ||
1265 | get_connectable(hdev); | ||
1246 | 1266 | ||
1247 | /* Set require_privacy to true only when non-connectable | 1267 | /* Set require_privacy to true only when non-connectable |
1248 | * advertising is used. In that case it is fine to use a | 1268 | * advertising is used. In that case it is fine to use a |
@@ -1254,7 +1274,14 @@ static void enable_advertising(struct hci_request *req) | |||
1254 | memset(&cp, 0, sizeof(cp)); | 1274 | memset(&cp, 0, sizeof(cp)); |
1255 | cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval); | 1275 | cp.min_interval = cpu_to_le16(hdev->le_adv_min_interval); |
1256 | cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval); | 1276 | cp.max_interval = cpu_to_le16(hdev->le_adv_max_interval); |
1257 | cp.type = connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND; | 1277 | |
1278 | if (connectable) | ||
1279 | cp.type = LE_ADV_IND; | ||
1280 | else if (get_adv_instance_scan_rsp_len(hdev, instance)) | ||
1281 | cp.type = LE_ADV_SCAN_IND; | ||
1282 | else | ||
1283 | cp.type = LE_ADV_NONCONN_IND; | ||
1284 | |||
1258 | cp.own_address_type = own_addr_type; | 1285 | cp.own_address_type = own_addr_type; |
1259 | cp.channel_map = hdev->le_adv_channel_map; | 1286 | cp.channel_map = hdev->le_adv_channel_map; |
1260 | 1287 | ||
@@ -2088,7 +2115,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2088 | 2115 | ||
2089 | no_scan_update: | 2116 | no_scan_update: |
2090 | /* Update the advertising parameters if necessary */ | 2117 | /* Update the advertising parameters if necessary */ |
2091 | if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) | 2118 | if (hci_dev_test_flag(hdev, HCI_ADVERTISING) || |
2119 | hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE)) | ||
2092 | enable_advertising(&req); | 2120 | enable_advertising(&req); |
2093 | 2121 | ||
2094 | err = hci_req_run(&req, set_connectable_complete); | 2122 | err = hci_req_run(&req, set_connectable_complete); |
@@ -3757,10 +3785,70 @@ failed: | |||
3757 | return err; | 3785 | return err; |
3758 | } | 3786 | } |
3759 | 3787 | ||
3788 | static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status, | ||
3789 | u16 opcode, struct sk_buff *skb) | ||
3790 | { | ||
3791 | struct mgmt_rp_read_local_oob_data mgmt_rp; | ||
3792 | size_t rp_size = sizeof(mgmt_rp); | ||
3793 | struct mgmt_pending_cmd *cmd; | ||
3794 | |||
3795 | BT_DBG("%s status %u", hdev->name, status); | ||
3796 | |||
3797 | cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); | ||
3798 | if (!cmd) | ||
3799 | return; | ||
3800 | |||
3801 | if (status || !skb) { | ||
3802 | mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3803 | status ? mgmt_status(status) : MGMT_STATUS_FAILED); | ||
3804 | goto remove; | ||
3805 | } | ||
3806 | |||
3807 | memset(&mgmt_rp, 0, sizeof(mgmt_rp)); | ||
3808 | |||
3809 | if (opcode == HCI_OP_READ_LOCAL_OOB_DATA) { | ||
3810 | struct hci_rp_read_local_oob_data *rp = (void *) skb->data; | ||
3811 | |||
3812 | if (skb->len < sizeof(*rp)) { | ||
3813 | mgmt_cmd_status(cmd->sk, hdev->id, | ||
3814 | MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3815 | MGMT_STATUS_FAILED); | ||
3816 | goto remove; | ||
3817 | } | ||
3818 | |||
3819 | memcpy(mgmt_rp.hash192, rp->hash, sizeof(rp->hash)); | ||
3820 | memcpy(mgmt_rp.rand192, rp->rand, sizeof(rp->rand)); | ||
3821 | |||
3822 | rp_size -= sizeof(mgmt_rp.hash256) + sizeof(mgmt_rp.rand256); | ||
3823 | } else { | ||
3824 | struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data; | ||
3825 | |||
3826 | if (skb->len < sizeof(*rp)) { | ||
3827 | mgmt_cmd_status(cmd->sk, hdev->id, | ||
3828 | MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3829 | MGMT_STATUS_FAILED); | ||
3830 | goto remove; | ||
3831 | } | ||
3832 | |||
3833 | memcpy(mgmt_rp.hash192, rp->hash192, sizeof(rp->hash192)); | ||
3834 | memcpy(mgmt_rp.rand192, rp->rand192, sizeof(rp->rand192)); | ||
3835 | |||
3836 | memcpy(mgmt_rp.hash256, rp->hash256, sizeof(rp->hash256)); | ||
3837 | memcpy(mgmt_rp.rand256, rp->rand256, sizeof(rp->rand256)); | ||
3838 | } | ||
3839 | |||
3840 | mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | ||
3841 | MGMT_STATUS_SUCCESS, &mgmt_rp, rp_size); | ||
3842 | |||
3843 | remove: | ||
3844 | mgmt_pending_remove(cmd); | ||
3845 | } | ||
3846 | |||
3760 | static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, | 3847 | static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, |
3761 | void *data, u16 data_len) | 3848 | void *data, u16 data_len) |
3762 | { | 3849 | { |
3763 | struct mgmt_pending_cmd *cmd; | 3850 | struct mgmt_pending_cmd *cmd; |
3851 | struct hci_request req; | ||
3764 | int err; | 3852 | int err; |
3765 | 3853 | ||
3766 | BT_DBG("%s", hdev->name); | 3854 | BT_DBG("%s", hdev->name); |
@@ -3791,12 +3879,14 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
3791 | goto unlock; | 3879 | goto unlock; |
3792 | } | 3880 | } |
3793 | 3881 | ||
3882 | hci_req_init(&req, hdev); | ||
3883 | |||
3794 | if (bredr_sc_enabled(hdev)) | 3884 | if (bredr_sc_enabled(hdev)) |
3795 | err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_EXT_DATA, | 3885 | hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_EXT_DATA, 0, NULL); |
3796 | 0, NULL); | ||
3797 | else | 3886 | else |
3798 | err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); | 3887 | hci_req_add(&req, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); |
3799 | 3888 | ||
3889 | err = hci_req_run_skb(&req, read_local_oob_data_complete); | ||
3800 | if (err < 0) | 3890 | if (err < 0) |
3801 | mgmt_pending_remove(cmd); | 3891 | mgmt_pending_remove(cmd); |
3802 | 3892 | ||
@@ -6388,46 +6478,41 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev, | |||
6388 | 6478 | ||
6389 | BT_DBG("%s", hdev->name); | 6479 | BT_DBG("%s", hdev->name); |
6390 | 6480 | ||
6391 | if (!hdev_is_powered(hdev)) | 6481 | if (hdev_is_powered(hdev)) { |
6392 | return mgmt_cmd_complete(sk, hdev->id, | 6482 | switch (cp->type) { |
6393 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | 6483 | case BIT(BDADDR_BREDR): |
6394 | MGMT_STATUS_NOT_POWERED, | 6484 | status = mgmt_bredr_support(hdev); |
6395 | &cp->type, sizeof(cp->type)); | 6485 | if (status) |
6396 | 6486 | eir_len = 0; | |
6397 | switch (cp->type) { | 6487 | else |
6398 | case BIT(BDADDR_BREDR): | 6488 | eir_len = 5; |
6399 | status = mgmt_bredr_support(hdev); | 6489 | break; |
6400 | if (status) | 6490 | case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)): |
6401 | return mgmt_cmd_complete(sk, hdev->id, | 6491 | status = mgmt_le_support(hdev); |
6402 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | 6492 | if (status) |
6403 | status, &cp->type, | 6493 | eir_len = 0; |
6404 | sizeof(cp->type)); | 6494 | else |
6405 | eir_len = 5; | 6495 | eir_len = 9 + 3 + 18 + 18 + 3; |
6406 | break; | 6496 | break; |
6407 | case (BIT(BDADDR_LE_PUBLIC) | BIT(BDADDR_LE_RANDOM)): | 6497 | default: |
6408 | status = mgmt_le_support(hdev); | 6498 | status = MGMT_STATUS_INVALID_PARAMS; |
6409 | if (status) | 6499 | eir_len = 0; |
6410 | return mgmt_cmd_complete(sk, hdev->id, | 6500 | break; |
6411 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | 6501 | } |
6412 | status, &cp->type, | 6502 | } else { |
6413 | sizeof(cp->type)); | 6503 | status = MGMT_STATUS_NOT_POWERED; |
6414 | eir_len = 9 + 3 + 18 + 18 + 3; | 6504 | eir_len = 0; |
6415 | break; | ||
6416 | default: | ||
6417 | return mgmt_cmd_complete(sk, hdev->id, | ||
6418 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | ||
6419 | MGMT_STATUS_INVALID_PARAMS, | ||
6420 | &cp->type, sizeof(cp->type)); | ||
6421 | } | 6505 | } |
6422 | 6506 | ||
6423 | hci_dev_lock(hdev); | ||
6424 | |||
6425 | rp_len = sizeof(*rp) + eir_len; | 6507 | rp_len = sizeof(*rp) + eir_len; |
6426 | rp = kmalloc(rp_len, GFP_ATOMIC); | 6508 | rp = kmalloc(rp_len, GFP_ATOMIC); |
6427 | if (!rp) { | 6509 | if (!rp) |
6428 | hci_dev_unlock(hdev); | ||
6429 | return -ENOMEM; | 6510 | return -ENOMEM; |
6430 | } | 6511 | |
6512 | if (status) | ||
6513 | goto complete; | ||
6514 | |||
6515 | hci_dev_lock(hdev); | ||
6431 | 6516 | ||
6432 | eir_len = 0; | 6517 | eir_len = 0; |
6433 | switch (cp->type) { | 6518 | switch (cp->type) { |
@@ -6439,20 +6524,30 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev, | |||
6439 | if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) && | 6524 | if (hci_dev_test_flag(hdev, HCI_SC_ENABLED) && |
6440 | smp_generate_oob(hdev, hash, rand) < 0) { | 6525 | smp_generate_oob(hdev, hash, rand) < 0) { |
6441 | hci_dev_unlock(hdev); | 6526 | hci_dev_unlock(hdev); |
6442 | err = mgmt_cmd_complete(sk, hdev->id, | 6527 | status = MGMT_STATUS_FAILED; |
6443 | MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | 6528 | goto complete; |
6444 | MGMT_STATUS_FAILED, | ||
6445 | &cp->type, sizeof(cp->type)); | ||
6446 | goto done; | ||
6447 | } | 6529 | } |
6448 | 6530 | ||
6531 | /* This should return the active RPA, but since the RPA | ||
6532 | * is only programmed on demand, it is really hard to fill | ||
6533 | * this in at the moment. For now disallow retrieving | ||
6534 | * local out-of-band data when privacy is in use. | ||
6535 | * | ||
6536 | * Returning the identity address will not help here since | ||
6537 | * pairing happens before the identity resolving key is | ||
6538 | * known and thus the connection establishment happens | ||
6539 | * based on the RPA and not the identity address. | ||
6540 | */ | ||
6449 | if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { | 6541 | if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { |
6450 | memcpy(addr, &hdev->rpa, 6); | 6542 | hci_dev_unlock(hdev); |
6451 | addr[6] = 0x01; | 6543 | status = MGMT_STATUS_REJECTED; |
6452 | } else if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || | 6544 | goto complete; |
6453 | !bacmp(&hdev->bdaddr, BDADDR_ANY) || | 6545 | } |
6454 | (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && | 6546 | |
6455 | bacmp(&hdev->static_addr, BDADDR_ANY))) { | 6547 | if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) || |
6548 | !bacmp(&hdev->bdaddr, BDADDR_ANY) || | ||
6549 | (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) && | ||
6550 | bacmp(&hdev->static_addr, BDADDR_ANY))) { | ||
6456 | memcpy(addr, &hdev->static_addr, 6); | 6551 | memcpy(addr, &hdev->static_addr, 6); |
6457 | addr[6] = 0x01; | 6552 | addr[6] = 0x01; |
6458 | } else { | 6553 | } else { |
@@ -6491,16 +6586,19 @@ static int read_local_oob_ext_data(struct sock *sk, struct hci_dev *hdev, | |||
6491 | break; | 6586 | break; |
6492 | } | 6587 | } |
6493 | 6588 | ||
6494 | rp->type = cp->type; | ||
6495 | rp->eir_len = cpu_to_le16(eir_len); | ||
6496 | |||
6497 | hci_dev_unlock(hdev); | 6589 | hci_dev_unlock(hdev); |
6498 | 6590 | ||
6499 | hci_sock_set_flag(sk, HCI_MGMT_OOB_DATA_EVENTS); | 6591 | hci_sock_set_flag(sk, HCI_MGMT_OOB_DATA_EVENTS); |
6500 | 6592 | ||
6593 | status = MGMT_STATUS_SUCCESS; | ||
6594 | |||
6595 | complete: | ||
6596 | rp->type = cp->type; | ||
6597 | rp->eir_len = cpu_to_le16(eir_len); | ||
6598 | |||
6501 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, | 6599 | err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_EXT_DATA, |
6502 | MGMT_STATUS_SUCCESS, rp, sizeof(*rp) + eir_len); | 6600 | status, rp, sizeof(*rp) + eir_len); |
6503 | if (err < 0) | 6601 | if (err < 0 || status) |
6504 | goto done; | 6602 | goto done; |
6505 | 6603 | ||
6506 | err = mgmt_limited_event(MGMT_EV_LOCAL_OOB_DATA_UPDATED, hdev, | 6604 | err = mgmt_limited_event(MGMT_EV_LOCAL_OOB_DATA_UPDATED, hdev, |
@@ -7899,43 +7997,6 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
7899 | cmd ? cmd->sk : NULL); | 7997 | cmd ? cmd->sk : NULL); |
7900 | } | 7998 | } |
7901 | 7999 | ||
7902 | void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192, | ||
7903 | u8 *rand192, u8 *hash256, u8 *rand256, | ||
7904 | u8 status) | ||
7905 | { | ||
7906 | struct mgmt_pending_cmd *cmd; | ||
7907 | |||
7908 | BT_DBG("%s status %u", hdev->name, status); | ||
7909 | |||
7910 | cmd = pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); | ||
7911 | if (!cmd) | ||
7912 | return; | ||
7913 | |||
7914 | if (status) { | ||
7915 | mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, | ||
7916 | mgmt_status(status)); | ||
7917 | } else { | ||
7918 | struct mgmt_rp_read_local_oob_data rp; | ||
7919 | size_t rp_size = sizeof(rp); | ||
7920 | |||
7921 | memcpy(rp.hash192, hash192, sizeof(rp.hash192)); | ||
7922 | memcpy(rp.rand192, rand192, sizeof(rp.rand192)); | ||
7923 | |||
7924 | if (bredr_sc_enabled(hdev) && hash256 && rand256) { | ||
7925 | memcpy(rp.hash256, hash256, sizeof(rp.hash256)); | ||
7926 | memcpy(rp.rand256, rand256, sizeof(rp.rand256)); | ||
7927 | } else { | ||
7928 | rp_size -= sizeof(rp.hash256) + sizeof(rp.rand256); | ||
7929 | } | ||
7930 | |||
7931 | mgmt_cmd_complete(cmd->sk, hdev->id, | ||
7932 | MGMT_OP_READ_LOCAL_OOB_DATA, 0, | ||
7933 | &rp, rp_size); | ||
7934 | } | ||
7935 | |||
7936 | mgmt_pending_remove(cmd); | ||
7937 | } | ||
7938 | |||
7939 | static inline bool has_uuid(u8 *uuid, u16 uuid_count, u8 (*uuids)[16]) | 8000 | static inline bool has_uuid(u8 *uuid, u16 uuid_count, u8 (*uuids)[16]) |
7940 | { | 8001 | { |
7941 | int i; | 8002 | int i; |
diff --git a/net/bluetooth/selftest.c b/net/bluetooth/selftest.c index 378f4064952c..dc688f13e496 100644 --- a/net/bluetooth/selftest.c +++ b/net/bluetooth/selftest.c | |||
@@ -21,6 +21,8 @@ | |||
21 | SOFTWARE IS DISCLAIMED. | 21 | SOFTWARE IS DISCLAIMED. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/debugfs.h> | ||
25 | |||
24 | #include <net/bluetooth/bluetooth.h> | 26 | #include <net/bluetooth/bluetooth.h> |
25 | #include <net/bluetooth/hci_core.h> | 27 | #include <net/bluetooth/hci_core.h> |
26 | 28 | ||
@@ -154,6 +156,21 @@ static int __init test_ecdh_sample(const u8 priv_a[32], const u8 priv_b[32], | |||
154 | return 0; | 156 | return 0; |
155 | } | 157 | } |
156 | 158 | ||
159 | static char test_ecdh_buffer[32]; | ||
160 | |||
161 | static ssize_t test_ecdh_read(struct file *file, char __user *user_buf, | ||
162 | size_t count, loff_t *ppos) | ||
163 | { | ||
164 | return simple_read_from_buffer(user_buf, count, ppos, test_ecdh_buffer, | ||
165 | strlen(test_ecdh_buffer)); | ||
166 | } | ||
167 | |||
168 | static const struct file_operations test_ecdh_fops = { | ||
169 | .open = simple_open, | ||
170 | .read = test_ecdh_read, | ||
171 | .llseek = default_llseek, | ||
172 | }; | ||
173 | |||
157 | static int __init test_ecdh(void) | 174 | static int __init test_ecdh(void) |
158 | { | 175 | { |
159 | ktime_t calltime, delta, rettime; | 176 | ktime_t calltime, delta, rettime; |
@@ -165,19 +182,19 @@ static int __init test_ecdh(void) | |||
165 | err = test_ecdh_sample(priv_a_1, priv_b_1, pub_a_1, pub_b_1, dhkey_1); | 182 | err = test_ecdh_sample(priv_a_1, priv_b_1, pub_a_1, pub_b_1, dhkey_1); |
166 | if (err) { | 183 | if (err) { |
167 | BT_ERR("ECDH sample 1 failed"); | 184 | BT_ERR("ECDH sample 1 failed"); |
168 | return err; | 185 | goto done; |
169 | } | 186 | } |
170 | 187 | ||
171 | err = test_ecdh_sample(priv_a_2, priv_b_2, pub_a_2, pub_b_2, dhkey_2); | 188 | err = test_ecdh_sample(priv_a_2, priv_b_2, pub_a_2, pub_b_2, dhkey_2); |
172 | if (err) { | 189 | if (err) { |
173 | BT_ERR("ECDH sample 2 failed"); | 190 | BT_ERR("ECDH sample 2 failed"); |
174 | return err; | 191 | goto done; |
175 | } | 192 | } |
176 | 193 | ||
177 | err = test_ecdh_sample(priv_a_3, priv_a_3, pub_a_3, pub_a_3, dhkey_3); | 194 | err = test_ecdh_sample(priv_a_3, priv_a_3, pub_a_3, pub_a_3, dhkey_3); |
178 | if (err) { | 195 | if (err) { |
179 | BT_ERR("ECDH sample 3 failed"); | 196 | BT_ERR("ECDH sample 3 failed"); |
180 | return err; | 197 | goto done; |
181 | } | 198 | } |
182 | 199 | ||
183 | rettime = ktime_get(); | 200 | rettime = ktime_get(); |
@@ -186,7 +203,17 @@ static int __init test_ecdh(void) | |||
186 | 203 | ||
187 | BT_INFO("ECDH test passed in %llu usecs", duration); | 204 | BT_INFO("ECDH test passed in %llu usecs", duration); |
188 | 205 | ||
189 | return 0; | 206 | done: |
207 | if (!err) | ||
208 | snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer), | ||
209 | "PASS (%llu usecs)\n", duration); | ||
210 | else | ||
211 | snprintf(test_ecdh_buffer, sizeof(test_ecdh_buffer), "FAIL\n"); | ||
212 | |||
213 | debugfs_create_file("selftest_ecdh", 0444, bt_debugfs, NULL, | ||
214 | &test_ecdh_fops); | ||
215 | |||
216 | return err; | ||
190 | } | 217 | } |
191 | 218 | ||
192 | #else | 219 | #else |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 1ec3f66b5a74..1ab3dc9c8f99 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -3017,7 +3017,7 @@ static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, | |||
3017 | return ERR_PTR(-ENOMEM); | 3017 | return ERR_PTR(-ENOMEM); |
3018 | 3018 | ||
3019 | skb->priority = HCI_PRIO_MAX; | 3019 | skb->priority = HCI_PRIO_MAX; |
3020 | bt_cb(skb)->chan = chan; | 3020 | bt_cb(skb)->l2cap.chan = chan; |
3021 | 3021 | ||
3022 | return skb; | 3022 | return skb; |
3023 | } | 3023 | } |
@@ -3549,6 +3549,21 @@ static int __init test_h6(struct crypto_hash *tfm_cmac) | |||
3549 | return 0; | 3549 | return 0; |
3550 | } | 3550 | } |
3551 | 3551 | ||
3552 | static char test_smp_buffer[32]; | ||
3553 | |||
3554 | static ssize_t test_smp_read(struct file *file, char __user *user_buf, | ||
3555 | size_t count, loff_t *ppos) | ||
3556 | { | ||
3557 | return simple_read_from_buffer(user_buf, count, ppos, test_smp_buffer, | ||
3558 | strlen(test_smp_buffer)); | ||
3559 | } | ||
3560 | |||
3561 | static const struct file_operations test_smp_fops = { | ||
3562 | .open = simple_open, | ||
3563 | .read = test_smp_read, | ||
3564 | .llseek = default_llseek, | ||
3565 | }; | ||
3566 | |||
3552 | static int __init run_selftests(struct crypto_blkcipher *tfm_aes, | 3567 | static int __init run_selftests(struct crypto_blkcipher *tfm_aes, |
3553 | struct crypto_hash *tfm_cmac) | 3568 | struct crypto_hash *tfm_cmac) |
3554 | { | 3569 | { |
@@ -3561,49 +3576,49 @@ static int __init run_selftests(struct crypto_blkcipher *tfm_aes, | |||
3561 | err = test_ah(tfm_aes); | 3576 | err = test_ah(tfm_aes); |
3562 | if (err) { | 3577 | if (err) { |
3563 | BT_ERR("smp_ah test failed"); | 3578 | BT_ERR("smp_ah test failed"); |
3564 | return err; | 3579 | goto done; |
3565 | } | 3580 | } |
3566 | 3581 | ||
3567 | err = test_c1(tfm_aes); | 3582 | err = test_c1(tfm_aes); |
3568 | if (err) { | 3583 | if (err) { |
3569 | BT_ERR("smp_c1 test failed"); | 3584 | BT_ERR("smp_c1 test failed"); |
3570 | return err; | 3585 | goto done; |
3571 | } | 3586 | } |
3572 | 3587 | ||
3573 | err = test_s1(tfm_aes); | 3588 | err = test_s1(tfm_aes); |
3574 | if (err) { | 3589 | if (err) { |
3575 | BT_ERR("smp_s1 test failed"); | 3590 | BT_ERR("smp_s1 test failed"); |
3576 | return err; | 3591 | goto done; |
3577 | } | 3592 | } |
3578 | 3593 | ||
3579 | err = test_f4(tfm_cmac); | 3594 | err = test_f4(tfm_cmac); |
3580 | if (err) { | 3595 | if (err) { |
3581 | BT_ERR("smp_f4 test failed"); | 3596 | BT_ERR("smp_f4 test failed"); |
3582 | return err; | 3597 | goto done; |
3583 | } | 3598 | } |
3584 | 3599 | ||
3585 | err = test_f5(tfm_cmac); | 3600 | err = test_f5(tfm_cmac); |
3586 | if (err) { | 3601 | if (err) { |
3587 | BT_ERR("smp_f5 test failed"); | 3602 | BT_ERR("smp_f5 test failed"); |
3588 | return err; | 3603 | goto done; |
3589 | } | 3604 | } |
3590 | 3605 | ||
3591 | err = test_f6(tfm_cmac); | 3606 | err = test_f6(tfm_cmac); |
3592 | if (err) { | 3607 | if (err) { |
3593 | BT_ERR("smp_f6 test failed"); | 3608 | BT_ERR("smp_f6 test failed"); |
3594 | return err; | 3609 | goto done; |
3595 | } | 3610 | } |
3596 | 3611 | ||
3597 | err = test_g2(tfm_cmac); | 3612 | err = test_g2(tfm_cmac); |
3598 | if (err) { | 3613 | if (err) { |
3599 | BT_ERR("smp_g2 test failed"); | 3614 | BT_ERR("smp_g2 test failed"); |
3600 | return err; | 3615 | goto done; |
3601 | } | 3616 | } |
3602 | 3617 | ||
3603 | err = test_h6(tfm_cmac); | 3618 | err = test_h6(tfm_cmac); |
3604 | if (err) { | 3619 | if (err) { |
3605 | BT_ERR("smp_h6 test failed"); | 3620 | BT_ERR("smp_h6 test failed"); |
3606 | return err; | 3621 | goto done; |
3607 | } | 3622 | } |
3608 | 3623 | ||
3609 | rettime = ktime_get(); | 3624 | rettime = ktime_get(); |
@@ -3612,7 +3627,17 @@ static int __init run_selftests(struct crypto_blkcipher *tfm_aes, | |||
3612 | 3627 | ||
3613 | BT_INFO("SMP test passed in %llu usecs", duration); | 3628 | BT_INFO("SMP test passed in %llu usecs", duration); |
3614 | 3629 | ||
3615 | return 0; | 3630 | done: |
3631 | if (!err) | ||
3632 | snprintf(test_smp_buffer, sizeof(test_smp_buffer), | ||
3633 | "PASS (%llu usecs)\n", duration); | ||
3634 | else | ||
3635 | snprintf(test_smp_buffer, sizeof(test_smp_buffer), "FAIL\n"); | ||
3636 | |||
3637 | debugfs_create_file("selftest_smp", 0444, bt_debugfs, NULL, | ||
3638 | &test_smp_fops); | ||
3639 | |||
3640 | return err; | ||
3616 | } | 3641 | } |
3617 | 3642 | ||
3618 | int __init bt_selftest_smp(void) | 3643 | int __init bt_selftest_smp(void) |