aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-04-17 08:00:51 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-04-17 23:26:20 -0400
commitcad718ed2f6fd204b2c5cac6b611fc3fcde7b183 (patch)
tree3772acb4f9dc18f9a4c5dc4687aeba039eb2a1a0 /net/bluetooth
parentfa5513be2b709c8ce6ff0b11d0715760a9a70ffd (diff)
Bluetooth: Track feature pages in a single table
The local and remote features are organized by page number. Page 0 are the LMP features, page 1 the host features, and any pages beyond 1 features that future core specification versions may define. So far we've only had the first two pages and two separate variables has been convenient enough, however with the introduction of Core Specification Addendum 4 there are features defined on page 2. Instead of requiring the addition of a new variable each time a new page number is defined, this patch refactors the code to use a single table for the features. The patch needs to update both the hci_dev and hci_conn structures since there are macros that depend on the features being represented in the same way in both of them. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_event.c58
-rw-r--r--net/bluetooth/hci_sysfs.c16
2 files changed, 38 insertions, 36 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e4d4d231fd8a..8adc3915ece4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -433,9 +433,9 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
433 433
434 if (!status) { 434 if (!status) {
435 if (sent->mode) 435 if (sent->mode)
436 hdev->host_features[0] |= LMP_HOST_SSP; 436 hdev->features[1][0] |= LMP_HOST_SSP;
437 else 437 else
438 hdev->host_features[0] &= ~LMP_HOST_SSP; 438 hdev->features[1][0] &= ~LMP_HOST_SSP;
439 } 439 }
440 440
441 if (test_bit(HCI_MGMT, &hdev->dev_flags)) 441 if (test_bit(HCI_MGMT, &hdev->dev_flags))
@@ -493,18 +493,18 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
493 /* Adjust default settings according to features 493 /* Adjust default settings according to features
494 * supported by device. */ 494 * supported by device. */
495 495
496 if (hdev->features[0] & LMP_3SLOT) 496 if (hdev->features[0][0] & LMP_3SLOT)
497 hdev->pkt_type |= (HCI_DM3 | HCI_DH3); 497 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
498 498
499 if (hdev->features[0] & LMP_5SLOT) 499 if (hdev->features[0][0] & LMP_5SLOT)
500 hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 500 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
501 501
502 if (hdev->features[1] & LMP_HV2) { 502 if (hdev->features[0][1] & LMP_HV2) {
503 hdev->pkt_type |= (HCI_HV2); 503 hdev->pkt_type |= (HCI_HV2);
504 hdev->esco_type |= (ESCO_HV2); 504 hdev->esco_type |= (ESCO_HV2);
505 } 505 }
506 506
507 if (hdev->features[1] & LMP_HV3) { 507 if (hdev->features[0][1] & LMP_HV3) {
508 hdev->pkt_type |= (HCI_HV3); 508 hdev->pkt_type |= (HCI_HV3);
509 hdev->esco_type |= (ESCO_HV3); 509 hdev->esco_type |= (ESCO_HV3);
510 } 510 }
@@ -512,26 +512,26 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
512 if (lmp_esco_capable(hdev)) 512 if (lmp_esco_capable(hdev))
513 hdev->esco_type |= (ESCO_EV3); 513 hdev->esco_type |= (ESCO_EV3);
514 514
515 if (hdev->features[4] & LMP_EV4) 515 if (hdev->features[0][4] & LMP_EV4)
516 hdev->esco_type |= (ESCO_EV4); 516 hdev->esco_type |= (ESCO_EV4);
517 517
518 if (hdev->features[4] & LMP_EV5) 518 if (hdev->features[0][4] & LMP_EV5)
519 hdev->esco_type |= (ESCO_EV5); 519 hdev->esco_type |= (ESCO_EV5);
520 520
521 if (hdev->features[5] & LMP_EDR_ESCO_2M) 521 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
522 hdev->esco_type |= (ESCO_2EV3); 522 hdev->esco_type |= (ESCO_2EV3);
523 523
524 if (hdev->features[5] & LMP_EDR_ESCO_3M) 524 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
525 hdev->esco_type |= (ESCO_3EV3); 525 hdev->esco_type |= (ESCO_3EV3);
526 526
527 if (hdev->features[5] & LMP_EDR_3S_ESCO) 527 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
528 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); 528 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
529 529
530 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, 530 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
531 hdev->features[0], hdev->features[1], 531 hdev->features[0][0], hdev->features[0][1],
532 hdev->features[2], hdev->features[3], 532 hdev->features[0][2], hdev->features[0][3],
533 hdev->features[4], hdev->features[5], 533 hdev->features[0][4], hdev->features[0][5],
534 hdev->features[6], hdev->features[7]); 534 hdev->features[0][6], hdev->features[0][7]);
535} 535}
536 536
537static void hci_cc_read_local_ext_features(struct hci_dev *hdev, 537static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
@@ -544,14 +544,8 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
544 if (rp->status) 544 if (rp->status)
545 return; 545 return;
546 546
547 switch (rp->page) { 547 if (rp->page < HCI_MAX_PAGES)
548 case 0: 548 memcpy(hdev->features[rp->page], rp->features, 8);
549 memcpy(hdev->features, rp->features, 8);
550 break;
551 case 1:
552 memcpy(hdev->host_features, rp->features, 8);
553 break;
554 }
555} 549}
556 550
557static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, 551static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
@@ -1046,14 +1040,14 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1046 1040
1047 if (!status) { 1041 if (!status) {
1048 if (sent->le) 1042 if (sent->le)
1049 hdev->host_features[0] |= LMP_HOST_LE; 1043 hdev->features[1][0] |= LMP_HOST_LE;
1050 else 1044 else
1051 hdev->host_features[0] &= ~LMP_HOST_LE; 1045 hdev->features[1][0] &= ~LMP_HOST_LE;
1052 1046
1053 if (sent->simul) 1047 if (sent->simul)
1054 hdev->host_features[0] |= LMP_HOST_LE_BREDR; 1048 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
1055 else 1049 else
1056 hdev->host_features[0] &= ~LMP_HOST_LE_BREDR; 1050 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
1057 } 1051 }
1058 1052
1059 if (test_bit(HCI_MGMT, &hdev->dev_flags) && 1053 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
@@ -2076,7 +2070,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev,
2076 goto unlock; 2070 goto unlock;
2077 2071
2078 if (!ev->status) 2072 if (!ev->status)
2079 memcpy(conn->features, ev->features, 8); 2073 memcpy(conn->features[0], ev->features, 8);
2080 2074
2081 if (conn->state != BT_CONFIG) 2075 if (conn->state != BT_CONFIG)
2082 goto unlock; 2076 goto unlock;
@@ -2888,6 +2882,9 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2888 if (!conn) 2882 if (!conn)
2889 goto unlock; 2883 goto unlock;
2890 2884
2885 if (ev->page < HCI_MAX_PAGES)
2886 memcpy(conn->features[ev->page], ev->features, 8);
2887
2891 if (!ev->status && ev->page == 0x01) { 2888 if (!ev->status && ev->page == 0x01) {
2892 struct inquiry_entry *ie; 2889 struct inquiry_entry *ie;
2893 2890
@@ -3346,11 +3343,16 @@ static void hci_remote_host_features_evt(struct hci_dev *hdev,
3346{ 3343{
3347 struct hci_ev_remote_host_features *ev = (void *) skb->data; 3344 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3348 struct inquiry_entry *ie; 3345 struct inquiry_entry *ie;
3346 struct hci_conn *conn;
3349 3347
3350 BT_DBG("%s", hdev->name); 3348 BT_DBG("%s", hdev->name);
3351 3349
3352 hci_dev_lock(hdev); 3350 hci_dev_lock(hdev);
3353 3351
3352 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3353 if (conn)
3354 memcpy(conn->features[1], ev->features, 8);
3355
3354 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); 3356 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3355 if (ie) 3357 if (ie)
3356 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP); 3358 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 6fe15c822847..7ad6ecf36f20 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -48,10 +48,10 @@ static ssize_t show_link_features(struct device *dev,
48 struct hci_conn *conn = to_hci_conn(dev); 48 struct hci_conn *conn = to_hci_conn(dev);
49 49
50 return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", 50 return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
51 conn->features[0], conn->features[1], 51 conn->features[0][0], conn->features[0][1],
52 conn->features[2], conn->features[3], 52 conn->features[0][2], conn->features[0][3],
53 conn->features[4], conn->features[5], 53 conn->features[0][4], conn->features[0][5],
54 conn->features[6], conn->features[7]); 54 conn->features[0][6], conn->features[0][7]);
55} 55}
56 56
57#define LINK_ATTR(_name, _mode, _show, _store) \ 57#define LINK_ATTR(_name, _mode, _show, _store) \
@@ -233,10 +233,10 @@ static ssize_t show_features(struct device *dev,
233 struct hci_dev *hdev = to_hci_dev(dev); 233 struct hci_dev *hdev = to_hci_dev(dev);
234 234
235 return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", 235 return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
236 hdev->features[0], hdev->features[1], 236 hdev->features[0][0], hdev->features[0][1],
237 hdev->features[2], hdev->features[3], 237 hdev->features[0][2], hdev->features[0][3],
238 hdev->features[4], hdev->features[5], 238 hdev->features[0][4], hdev->features[0][5],
239 hdev->features[6], hdev->features[7]); 239 hdev->features[0][6], hdev->features[0][7]);
240} 240}
241 241
242static ssize_t show_manufacturer(struct device *dev, 242static ssize_t show_manufacturer(struct device *dev,