Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6

+61 -31
+1
include/net/bluetooth/hci.h
··· 101 101 /* HCI timeouts */ 102 102 #define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */ 103 103 #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ 104 + #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ 104 105 #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ 105 106 #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ 106 107
+5 -3
include/net/bluetooth/hci_core.h
··· 171 171 __u8 auth_type; 172 172 __u8 sec_level; 173 173 __u8 power_save; 174 + __u16 disc_timeout; 174 175 unsigned long pend; 175 176 176 177 unsigned int sent; ··· 181 180 struct timer_list disc_timer; 182 181 struct timer_list idle_timer; 183 182 184 - struct work_struct work; 183 + struct work_struct work_add; 184 + struct work_struct work_del; 185 185 186 186 struct device dev; 187 187 ··· 350 348 if (conn->type == ACL_LINK) { 351 349 del_timer(&conn->idle_timer); 352 350 if (conn->state == BT_CONNECTED) { 353 - timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT); 351 + timeo = msecs_to_jiffies(conn->disc_timeout); 354 352 if (!conn->out) 355 - timeo *= 5; 353 + timeo *= 2; 356 354 } else 357 355 timeo = msecs_to_jiffies(10); 358 356 } else
+4 -6
net/bluetooth/hci_conn.c
··· 215 215 conn->state = BT_OPEN; 216 216 217 217 conn->power_save = 1; 218 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 218 219 219 220 switch (type) { 220 221 case ACL_LINK: ··· 425 424 if (sec_level == BT_SECURITY_SDP) 426 425 return 1; 427 426 428 - if (sec_level == BT_SECURITY_LOW) { 429 - if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) 430 - return hci_conn_auth(conn, sec_level, auth_type); 431 - else 432 - return 1; 433 - } 427 + if (sec_level == BT_SECURITY_LOW && 428 + (!conn->ssp_mode || !conn->hdev->ssp_mode)) 429 + return 1; 434 430 435 431 if (conn->link_mode & HCI_LM_ENCRYPT) 436 432 return hci_conn_auth(conn, sec_level, auth_type);
+35 -1
net/bluetooth/hci_event.c
··· 883 883 if (conn->type == ACL_LINK) { 884 884 conn->state = BT_CONFIG; 885 885 hci_conn_hold(conn); 886 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 886 887 } else 887 888 conn->state = BT_CONNECTED; 888 889 ··· 1064 1063 hci_proto_connect_cfm(conn, ev->status); 1065 1064 hci_conn_put(conn); 1066 1065 } 1067 - } else 1066 + } else { 1068 1067 hci_auth_cfm(conn, ev->status); 1068 + 1069 + hci_conn_hold(conn); 1070 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1071 + hci_conn_put(conn); 1072 + } 1069 1073 1070 1074 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { 1071 1075 if (!ev->status) { ··· 1485 1479 1486 1480 static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 1487 1481 { 1482 + struct hci_ev_pin_code_req *ev = (void *) skb->data; 1483 + struct hci_conn *conn; 1484 + 1488 1485 BT_DBG("%s", hdev->name); 1486 + 1487 + hci_dev_lock(hdev); 1488 + 1489 + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 1490 + if (conn) { 1491 + hci_conn_hold(conn); 1492 + conn->disc_timeout = HCI_PAIRING_TIMEOUT; 1493 + hci_conn_put(conn); 1494 + } 1495 + 1496 + hci_dev_unlock(hdev); 1489 1497 } 1490 1498 1491 1499 static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ··· 1509 1489 1510 1490 static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 1511 1491 { 1492 + struct hci_ev_link_key_notify *ev = (void *) skb->data; 1493 + struct hci_conn *conn; 1494 + 1512 1495 BT_DBG("%s", hdev->name); 1496 + 1497 + hci_dev_lock(hdev); 1498 + 1499 + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 1500 + if (conn) { 1501 + hci_conn_hold(conn); 1502 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1503 + hci_conn_put(conn); 1504 + } 1505 + 1506 + hci_dev_unlock(hdev); 1513 1507 } 1514 1508 1515 1509 static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
+16 -21
net/bluetooth/hci_sysfs.c
··· 9 9 struct class *bt_class = NULL; 10 10 EXPORT_SYMBOL_GPL(bt_class); 11 11 12 - static struct workqueue_struct *btaddconn; 13 - static struct workqueue_struct *btdelconn; 12 + static struct workqueue_struct *bluetooth; 14 13 15 14 static inline char *link_typetostr(int type) 16 15 { ··· 87 88 88 89 static void add_conn(struct work_struct *work) 89 90 { 90 - struct hci_conn *conn = container_of(work, struct hci_conn, work); 91 + struct hci_conn *conn = container_of(work, struct hci_conn, work_add); 91 92 92 - flush_workqueue(btdelconn); 93 + /* ensure previous add/del is complete */ 94 + flush_workqueue(bluetooth); 93 95 94 96 if (device_add(&conn->dev) < 0) { 95 97 BT_ERR("Failed to register connection device"); ··· 114 114 115 115 device_initialize(&conn->dev); 116 116 117 - INIT_WORK(&conn->work, add_conn); 117 + INIT_WORK(&conn->work_add, add_conn); 118 118 119 - queue_work(btaddconn, &conn->work); 119 + queue_work(bluetooth, &conn->work_add); 120 120 } 121 121 122 122 /* ··· 131 131 132 132 static void del_conn(struct work_struct *work) 133 133 { 134 - struct hci_conn *conn = container_of(work, struct hci_conn, work); 134 + struct hci_conn *conn = container_of(work, struct hci_conn, work_del); 135 135 struct hci_dev *hdev = conn->hdev; 136 + 137 + /* ensure previous add/del is complete */ 138 + flush_workqueue(bluetooth); 136 139 137 140 while (1) { 138 141 struct device *dev; ··· 159 156 if (!device_is_registered(&conn->dev)) 160 157 return; 161 158 162 - INIT_WORK(&conn->work, del_conn); 159 + INIT_WORK(&conn->work_del, del_conn); 163 160 164 - queue_work(btdelconn, &conn->work); 161 + queue_work(bluetooth, &conn->work_del); 165 162 } 166 163 167 164 static inline char *host_typetostr(int type) ··· 438 435 439 436 int __init bt_sysfs_init(void) 440 437 { 441 - btaddconn = create_singlethread_workqueue("btaddconn"); 442 - if (!btaddconn) 438 + bluetooth = create_singlethread_workqueue("bluetooth"); 439 + if (!bluetooth) 443 440 return -ENOMEM; 444 - 445 - btdelconn = create_singlethread_workqueue("btdelconn"); 446 - if (!btdelconn) { 447 - destroy_workqueue(btaddconn); 448 - return -ENOMEM; 449 - } 450 441 451 442 bt_class = class_create(THIS_MODULE, "bluetooth"); 452 443 if (IS_ERR(bt_class)) { 453 - destroy_workqueue(btdelconn); 454 - destroy_workqueue(btaddconn); 444 + destroy_workqueue(bluetooth); 455 445 return PTR_ERR(bt_class); 456 446 } 457 447 ··· 453 457 454 458 void bt_sysfs_cleanup(void) 455 459 { 456 - destroy_workqueue(btaddconn); 457 - destroy_workqueue(btdelconn); 460 + destroy_workqueue(bluetooth); 458 461 459 462 class_destroy(bt_class); 460 463 }