aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_core.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:18:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:18:44 -0400
commit252f4bf400df1712408fe83ba199a66a1b57ab1d (patch)
treee07fa00abdd55b31e22567786c78635f32c6a66c /net/bluetooth/hci_core.c
parent6ba1037c3d871ab70e342631516dbf841c35b086 (diff)
parentb37e3b6d64358604960b35e8ecbb7aed22e0926e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/ath/ar9170/main.c drivers/net/wireless/ath/ar9170/phy.c drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
Diffstat (limited to 'net/bluetooth/hci_core.c')
-rw-r--r--net/bluetooth/hci_core.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c83f618282f..1ad4907766c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -56,7 +56,6 @@
56static void hci_cmd_task(unsigned long arg); 56static void hci_cmd_task(unsigned long arg);
57static void hci_rx_task(unsigned long arg); 57static void hci_rx_task(unsigned long arg);
58static void hci_tx_task(unsigned long arg); 58static void hci_tx_task(unsigned long arg);
59static void hci_notify(struct hci_dev *hdev, int event);
60 59
61static DEFINE_RWLOCK(hci_task_lock); 60static DEFINE_RWLOCK(hci_task_lock);
62 61
@@ -1083,6 +1082,70 @@ static void hci_cmd_timer(unsigned long arg)
1083 tasklet_schedule(&hdev->cmd_task); 1082 tasklet_schedule(&hdev->cmd_task);
1084} 1083}
1085 1084
1085struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
1086 bdaddr_t *bdaddr)
1087{
1088 struct oob_data *data;
1089
1090 list_for_each_entry(data, &hdev->remote_oob_data, list)
1091 if (bacmp(bdaddr, &data->bdaddr) == 0)
1092 return data;
1093
1094 return NULL;
1095}
1096
1097int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
1098{
1099 struct oob_data *data;
1100
1101 data = hci_find_remote_oob_data(hdev, bdaddr);
1102 if (!data)
1103 return -ENOENT;
1104
1105 BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1106
1107 list_del(&data->list);
1108 kfree(data);
1109
1110 return 0;
1111}
1112
1113int hci_remote_oob_data_clear(struct hci_dev *hdev)
1114{
1115 struct oob_data *data, *n;
1116
1117 list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
1118 list_del(&data->list);
1119 kfree(data);
1120 }
1121
1122 return 0;
1123}
1124
1125int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
1126 u8 *randomizer)
1127{
1128 struct oob_data *data;
1129
1130 data = hci_find_remote_oob_data(hdev, bdaddr);
1131
1132 if (!data) {
1133 data = kmalloc(sizeof(*data), GFP_ATOMIC);
1134 if (!data)
1135 return -ENOMEM;
1136
1137 bacpy(&data->bdaddr, bdaddr);
1138 list_add(&data->list, &hdev->remote_oob_data);
1139 }
1140
1141 memcpy(data->hash, hash, sizeof(data->hash));
1142 memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
1143
1144 BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
1145
1146 return 0;
1147}
1148
1086/* Register HCI device */ 1149/* Register HCI device */
1087int hci_register_dev(struct hci_dev *hdev) 1150int hci_register_dev(struct hci_dev *hdev)
1088{ 1151{
@@ -1147,6 +1210,8 @@ int hci_register_dev(struct hci_dev *hdev)
1147 1210
1148 INIT_LIST_HEAD(&hdev->link_keys); 1211 INIT_LIST_HEAD(&hdev->link_keys);
1149 1212
1213 INIT_LIST_HEAD(&hdev->remote_oob_data);
1214
1150 INIT_WORK(&hdev->power_on, hci_power_on); 1215 INIT_WORK(&hdev->power_on, hci_power_on);
1151 INIT_WORK(&hdev->power_off, hci_power_off); 1216 INIT_WORK(&hdev->power_off, hci_power_off);
1152 setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); 1217 setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1226,6 +1291,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
1226 hci_blacklist_clear(hdev); 1291 hci_blacklist_clear(hdev);
1227 hci_uuids_clear(hdev); 1292 hci_uuids_clear(hdev);
1228 hci_link_keys_clear(hdev); 1293 hci_link_keys_clear(hdev);
1294 hci_remote_oob_data_clear(hdev);
1229 hci_dev_unlock_bh(hdev); 1295 hci_dev_unlock_bh(hdev);
1230 1296
1231 __hci_dev_put(hdev); 1297 __hci_dev_put(hdev);
@@ -1275,7 +1341,7 @@ int hci_recv_frame(struct sk_buff *skb)
1275EXPORT_SYMBOL(hci_recv_frame); 1341EXPORT_SYMBOL(hci_recv_frame);
1276 1342
1277static int hci_reassembly(struct hci_dev *hdev, int type, void *data, 1343static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
1278 int count, __u8 index, gfp_t gfp_mask) 1344 int count, __u8 index)
1279{ 1345{
1280 int len = 0; 1346 int len = 0;
1281 int hlen = 0; 1347 int hlen = 0;
@@ -1305,7 +1371,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
1305 break; 1371 break;
1306 } 1372 }
1307 1373
1308 skb = bt_skb_alloc(len, gfp_mask); 1374 skb = bt_skb_alloc(len, GFP_ATOMIC);
1309 if (!skb) 1375 if (!skb)
1310 return -ENOMEM; 1376 return -ENOMEM;
1311 1377
@@ -1391,8 +1457,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1391 return -EILSEQ; 1457 return -EILSEQ;
1392 1458
1393 while (count) { 1459 while (count) {
1394 rem = hci_reassembly(hdev, type, data, count, 1460 rem = hci_reassembly(hdev, type, data, count, type - 1);
1395 type - 1, GFP_ATOMIC);
1396 if (rem < 0) 1461 if (rem < 0)
1397 return rem; 1462 return rem;
1398 1463
@@ -1426,8 +1491,8 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
1426 } else 1491 } else
1427 type = bt_cb(skb)->pkt_type; 1492 type = bt_cb(skb)->pkt_type;
1428 1493
1429 rem = hci_reassembly(hdev, type, data, 1494 rem = hci_reassembly(hdev, type, data, count,
1430 count, STREAM_REASSEMBLY, GFP_ATOMIC); 1495 STREAM_REASSEMBLY);
1431 if (rem < 0) 1496 if (rem < 0)
1432 return rem; 1497 return rem;
1433 1498