Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: hidp: remove old session-management

We have the full new session-management now available so lets switch over
and remove all the old code. Few semantics changed, so we need to adjust
the sock.c callers a bit. But this mostly simplifies the logic.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

authored by

David Herrmann and committed by
Gustavo Padovan
5205185d b4f34d8d

+18 -348
+12 -327
net/bluetooth/hidp/core.c
··· 77 77 wake_up_interruptible(sk_sleep(intr_sk)); 78 78 } 79 79 80 - static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr) 81 - { 82 - struct hidp_session *session; 83 - 84 - BT_DBG(""); 85 - 86 - list_for_each_entry(session, &hidp_session_list, list) { 87 - if (!bacmp(bdaddr, &session->bdaddr)) 88 - return session; 89 - } 90 - 91 - return NULL; 92 - } 93 - 94 - static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) 80 + static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) 95 81 { 96 82 memset(ci, 0, sizeof(*ci)); 97 83 bacpy(&ci->bdaddr, &session->bdaddr); ··· 442 456 { 443 457 struct hidp_session *session = (struct hidp_session *) arg; 444 458 445 - atomic_inc(&session->terminate); 446 - wake_up_process(session->task); 459 + hidp_session_terminate(session); 447 460 } 448 461 449 462 static void hidp_set_timer(struct hidp_session *session) ··· 510 525 skb_queue_purge(&session->ctrl_transmit); 511 526 skb_queue_purge(&session->intr_transmit); 512 527 513 - atomic_inc(&session->terminate); 514 - wake_up_process(current); 528 + hidp_session_terminate(session); 515 529 } 516 530 } 517 531 ··· 670 686 } 671 687 } 672 688 673 - static int hidp_session(void *arg) 674 - { 675 - struct hidp_session *session = arg; 676 - struct sock *ctrl_sk = session->ctrl_sock->sk; 677 - struct sock *intr_sk = session->intr_sock->sk; 678 - struct sk_buff *skb; 679 - wait_queue_t ctrl_wait, intr_wait; 680 - 681 - BT_DBG("session %p", session); 682 - 683 - __module_get(THIS_MODULE); 684 - set_user_nice(current, -15); 685 - 686 - init_waitqueue_entry(&ctrl_wait, current); 687 - init_waitqueue_entry(&intr_wait, current); 688 - add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); 689 - add_wait_queue(sk_sleep(intr_sk), &intr_wait); 690 - session->waiting_for_startup = 0; 691 - wake_up_interruptible(&session->startup_queue); 692 - set_current_state(TASK_INTERRUPTIBLE); 693 - while (!atomic_read(&session->terminate)) { 694 - if (ctrl_sk->sk_state != BT_CONNECTED || 695 - intr_sk->sk_state != BT_CONNECTED) 696 - break; 697 - 698 - while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { 699 - skb_orphan(skb); 700 - if (!skb_linearize(skb)) 701 - hidp_recv_intr_frame(session, skb); 702 - else 703 - kfree_skb(skb); 704 - } 705 - 706 - hidp_process_intr_transmit(session); 707 - 708 - while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { 709 - skb_orphan(skb); 710 - if (!skb_linearize(skb)) 711 - hidp_recv_ctrl_frame(session, skb); 712 - else 713 - kfree_skb(skb); 714 - } 715 - 716 - hidp_process_ctrl_transmit(session); 717 - 718 - schedule(); 719 - set_current_state(TASK_INTERRUPTIBLE); 720 - } 721 - set_current_state(TASK_RUNNING); 722 - atomic_inc(&session->terminate); 723 - remove_wait_queue(sk_sleep(intr_sk), &intr_wait); 724 - remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); 725 - 726 - clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); 727 - clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); 728 - wake_up_interruptible(&session->report_queue); 729 - 730 - down_write(&hidp_session_sem); 731 - 732 - hidp_del_timer(session); 733 - 734 - if (session->input) { 735 - input_unregister_device(session->input); 736 - session->input = NULL; 737 - } 738 - 739 - if (session->hid) { 740 - hid_destroy_device(session->hid); 741 - session->hid = NULL; 742 - } 743 - 744 - /* Wakeup user-space polling for socket errors */ 745 - session->intr_sock->sk->sk_err = EUNATCH; 746 - session->ctrl_sock->sk->sk_err = EUNATCH; 747 - 748 - hidp_schedule(session); 749 - 750 - fput(session->intr_sock->file); 751 - 752 - wait_event_timeout(*(sk_sleep(ctrl_sk)), 753 - (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500)); 754 - 755 - fput(session->ctrl_sock->file); 756 - 757 - list_del(&session->list); 758 - 759 - up_write(&hidp_session_sem); 760 - 761 - kfree(session->rd_data); 762 - kfree(session); 763 - module_put_and_exit(0); 764 - return 0; 765 - } 766 - 767 - static struct hci_conn *hidp_get_connection(struct hidp_session *session) 768 - { 769 - bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src; 770 - bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst; 771 - struct hci_conn *conn; 772 - struct hci_dev *hdev; 773 - 774 - hdev = hci_get_route(dst, src); 775 - if (!hdev) 776 - return NULL; 777 - 778 - hci_dev_lock(hdev); 779 - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); 780 - hci_dev_unlock(hdev); 781 - 782 - hci_dev_put(hdev); 783 - 784 - return conn; 785 - } 786 - 787 689 static int hidp_setup_input(struct hidp_session *session, 788 690 struct hidp_connadd_req *req) 789 691 { ··· 717 847 input->relbit[0] |= BIT_MASK(REL_WHEEL); 718 848 } 719 849 720 - input->dev.parent = &session->hconn->dev; 850 + input->dev.parent = &session->conn->hcon->dev; 721 851 722 852 input->event = hidp_input_event; 723 853 ··· 821 951 snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", 822 952 &bt_sk(session->ctrl_sock->sk)->dst); 823 953 824 - hid->dev.parent = &session->hconn->dev; 954 + hid->dev.parent = &session->conn->hcon->dev; 825 955 hid->ll_driver = &hidp_hid_driver; 826 956 827 957 hid->hid_get_raw_report = hidp_get_raw_report; ··· 1380 1510 return 0; 1381 1511 } 1382 1512 1383 - int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) 1384 - { 1385 - struct hidp_session *session, *s; 1386 - int vendor, product; 1387 - int err; 1388 - 1389 - BT_DBG(""); 1390 - 1391 - if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock)) 1392 - return -EINVAL; 1393 - if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) || 1394 - bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) 1395 - return -ENOTUNIQ; 1396 - 1397 - BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); 1398 - 1399 - down_write(&hidp_session_sem); 1400 - 1401 - s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); 1402 - if (s) { 1403 - up_write(&hidp_session_sem); 1404 - return -EEXIST; 1405 - } 1406 - 1407 - session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); 1408 - if (!session) { 1409 - up_write(&hidp_session_sem); 1410 - return -ENOMEM; 1411 - } 1412 - 1413 - bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); 1414 - 1415 - session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->chan->omtu, 1416 - l2cap_pi(ctrl_sock->sk)->chan->imtu); 1417 - session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->chan->omtu, 1418 - l2cap_pi(intr_sock->sk)->chan->imtu); 1419 - 1420 - BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu); 1421 - 1422 - session->ctrl_sock = ctrl_sock; 1423 - session->intr_sock = intr_sock; 1424 - 1425 - session->hconn = hidp_get_connection(session); 1426 - if (!session->hconn) { 1427 - err = -ENOTCONN; 1428 - goto failed; 1429 - } 1430 - 1431 - setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session); 1432 - 1433 - skb_queue_head_init(&session->ctrl_transmit); 1434 - skb_queue_head_init(&session->intr_transmit); 1435 - 1436 - mutex_init(&session->report_mutex); 1437 - init_waitqueue_head(&session->report_queue); 1438 - init_waitqueue_head(&session->startup_queue); 1439 - session->waiting_for_startup = 1; 1440 - session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); 1441 - session->idle_to = req->idle_to; 1442 - 1443 - list_add(&session->list, &hidp_session_list); 1444 - 1445 - if (req->rd_size > 0) { 1446 - err = hidp_setup_hid(session, req); 1447 - if (err && err != -ENODEV) 1448 - goto purge; 1449 - } 1450 - 1451 - if (!session->hid) { 1452 - err = hidp_setup_input(session, req); 1453 - if (err < 0) 1454 - goto purge; 1455 - } 1456 - 1457 - hidp_set_timer(session); 1458 - 1459 - if (session->hid) { 1460 - vendor = session->hid->vendor; 1461 - product = session->hid->product; 1462 - } else if (session->input) { 1463 - vendor = session->input->id.vendor; 1464 - product = session->input->id.product; 1465 - } else { 1466 - vendor = 0x0000; 1467 - product = 0x0000; 1468 - } 1469 - 1470 - session->task = kthread_run(hidp_session, session, "khidpd_%04x%04x", 1471 - vendor, product); 1472 - if (IS_ERR(session->task)) { 1473 - err = PTR_ERR(session->task); 1474 - goto unlink; 1475 - } 1476 - 1477 - while (session->waiting_for_startup) { 1478 - wait_event_interruptible(session->startup_queue, 1479 - !session->waiting_for_startup); 1480 - } 1481 - 1482 - if (session->hid) 1483 - err = hid_add_device(session->hid); 1484 - else 1485 - err = input_register_device(session->input); 1486 - 1487 - if (err < 0) { 1488 - atomic_inc(&session->terminate); 1489 - wake_up_process(session->task); 1490 - up_write(&hidp_session_sem); 1491 - return err; 1492 - } 1493 - 1494 - if (session->input) { 1495 - hidp_send_ctrl_message(session, 1496 - HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0); 1497 - session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); 1498 - 1499 - session->leds = 0xff; 1500 - hidp_input_event(session->input, EV_LED, 0, 0); 1501 - } 1502 - 1503 - up_write(&hidp_session_sem); 1504 - return 0; 1505 - 1506 - unlink: 1507 - hidp_del_timer(session); 1508 - 1509 - if (session->input) { 1510 - input_unregister_device(session->input); 1511 - session->input = NULL; 1512 - } 1513 - 1514 - if (session->hid) { 1515 - hid_destroy_device(session->hid); 1516 - session->hid = NULL; 1517 - } 1518 - 1519 - kfree(session->rd_data); 1520 - session->rd_data = NULL; 1521 - 1522 - purge: 1523 - list_del(&session->list); 1524 - 1525 - skb_queue_purge(&session->ctrl_transmit); 1526 - skb_queue_purge(&session->intr_transmit); 1527 - 1528 - failed: 1529 - up_write(&hidp_session_sem); 1530 - 1531 - kfree(session); 1532 - return err; 1533 - } 1534 - 1535 - int hidp_del_connection(struct hidp_conndel_req *req) 1536 - { 1537 - struct hidp_session *session; 1538 - int err = 0; 1539 - 1540 - BT_DBG(""); 1541 - 1542 - down_read(&hidp_session_sem); 1543 - 1544 - session = __hidp_get_session(&req->bdaddr); 1545 - if (session) { 1546 - if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) { 1547 - hidp_send_ctrl_message(session, 1548 - HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0); 1549 - } else { 1550 - /* Flush the transmit queues */ 1551 - skb_queue_purge(&session->ctrl_transmit); 1552 - skb_queue_purge(&session->intr_transmit); 1553 - 1554 - atomic_inc(&session->terminate); 1555 - wake_up_process(session->task); 1556 - } 1557 - } else 1558 - err = -ENOENT; 1559 - 1560 - up_read(&hidp_session_sem); 1561 - return err; 1562 - } 1563 - 1564 1513 int hidp_get_connlist(struct hidp_connlist_req *req) 1565 1514 { 1566 1515 struct hidp_session *session; ··· 1392 1703 list_for_each_entry(session, &hidp_session_list, list) { 1393 1704 struct hidp_conninfo ci; 1394 1705 1395 - __hidp_copy_session(session, &ci); 1706 + hidp_copy_session(session, &ci); 1396 1707 1397 1708 if (copy_to_user(req->ci, &ci, sizeof(ci))) { 1398 1709 err = -EFAULT; ··· 1413 1724 int hidp_get_conninfo(struct hidp_conninfo *ci) 1414 1725 { 1415 1726 struct hidp_session *session; 1416 - int err = 0; 1417 1727 1418 - down_read(&hidp_session_sem); 1728 + session = hidp_session_find(&ci->bdaddr); 1729 + if (session) { 1730 + hidp_copy_session(session, ci); 1731 + hidp_session_put(session); 1732 + } 1419 1733 1420 - session = __hidp_get_session(&ci->bdaddr); 1421 - if (session) 1422 - __hidp_copy_session(session, ci); 1423 - else 1424 - err = -ENOENT; 1425 - 1426 - up_read(&hidp_session_sem); 1427 - return err; 1734 + return session ? 0 : -ENOENT; 1428 1735 } 1429 1736 1430 1737 static int __init hidp_init(void)
-6
net/bluetooth/hidp/hidp.h
··· 123 123 124 124 int hidp_connection_add(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); 125 125 int hidp_connection_del(struct hidp_conndel_req *req); 126 - int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); 127 - int hidp_del_connection(struct hidp_conndel_req *req); 128 126 int hidp_get_connlist(struct hidp_connlist_req *req); 129 127 int hidp_get_conninfo(struct hidp_conninfo *ci); 130 128 ··· 145 147 146 148 /* connection management */ 147 149 bdaddr_t bdaddr; 148 - struct hci_conn *hconn; 149 150 struct l2cap_conn *conn; 150 151 struct l2cap_user user; 151 152 struct socket *ctrl_sock; ··· 177 180 178 181 /* Used in hidp_output_raw_report() */ 179 182 int output_report_success; /* boolean */ 180 - 181 - wait_queue_head_t startup_queue; 182 - int waiting_for_startup; 183 183 }; 184 184 185 185 /* HIDP init defines */
+6 -15
net/bluetooth/hidp/sock.c
··· 77 77 return err; 78 78 } 79 79 80 - if (csock->sk->sk_state != BT_CONNECTED || 81 - isock->sk->sk_state != BT_CONNECTED) { 82 - sockfd_put(csock); 83 - sockfd_put(isock); 84 - return -EBADFD; 85 - } 80 + err = hidp_connection_add(&ca, csock, isock); 81 + if (!err && copy_to_user(argp, &ca, sizeof(ca))) 82 + err = -EFAULT; 86 83 87 - err = hidp_add_connection(&ca, csock, isock); 88 - if (!err) { 89 - if (copy_to_user(argp, &ca, sizeof(ca))) 90 - err = -EFAULT; 91 - } else { 92 - sockfd_put(csock); 93 - sockfd_put(isock); 94 - } 84 + sockfd_put(csock); 85 + sockfd_put(isock); 95 86 96 87 return err; 97 88 ··· 93 102 if (copy_from_user(&cd, argp, sizeof(cd))) 94 103 return -EFAULT; 95 104 96 - return hidp_del_connection(&cd); 105 + return hidp_connection_del(&cd); 97 106 98 107 case HIDPGETCONNLIST: 99 108 if (copy_from_user(&cl, argp, sizeof(cl)))