From 9a0066579270584108f1f2f97d98fe989d8117df Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 9 Mar 2012 12:12:12 +0200 Subject: Bluetooth: Correct type for ediv to __le16 Correct type warnings reported by sparse to show that this functions takes ediv argument in __le16 format. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index edfd61addce..af55ea1b688 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1336,7 +1336,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, } int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, - int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16 + int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8]) { struct smp_ltk *key, *old_key; -- cgit v1.2.3-70-g09d2 From 1036b89042df96e71c0cb941be212f8053ecccc0 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 12 Mar 2012 15:59:33 +0200 Subject: Bluetooth: Fix opcode access in hci_complete opcode to be accessed is in le16 format so convert it first to cpu byte order. Signed-off-by: Andrei Emeltchenko Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index af55ea1b688..47a4e9b26b9 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -83,6 +83,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) */ if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) { struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; + u16 opcode = __le16_to_cpu(sent->opcode); struct sk_buff *skb; /* Some CSR based controllers generate a spontaneous @@ -92,7 +93,7 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) * command. */ - if (cmd != HCI_OP_RESET || sent->opcode == HCI_OP_RESET) + if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET) return; skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC); -- cgit v1.2.3-70-g09d2 From 7dbfac1d720d3ea68e00e187bbd2f1147257528b Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 15 Mar 2012 16:52:07 -0300 Subject: Bluetooth: Add hci_cancel_le_scan() to hci_core This patch adds to hci_core the hci_cancel_le_scan function which should be used to cancel an ongoing LE scan. Signed-off-by: Andre Guedes Acked-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'net/bluetooth/hci_core.c') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index c8e24a9b176..f7cf928ab6f 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1078,5 +1078,6 @@ int hci_do_inquiry(struct hci_dev *hdev, u8 length); int hci_cancel_inquiry(struct hci_dev *hdev); int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout); +int hci_cancel_le_scan(struct hci_dev *hdev); #endif /* __HCI_CORE_H */ diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 47a4e9b26b9..e3920b693f0 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1671,6 +1671,24 @@ static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, return 0; } +int hci_cancel_le_scan(struct hci_dev *hdev) +{ + BT_DBG("%s", hdev->name); + + if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) + return -EALREADY; + + if (cancel_delayed_work(&hdev->le_scan_disable)) { + struct hci_cp_le_set_scan_enable cp; + + /* Send HCI command to disable LE Scan */ + memset(&cp, 0, sizeof(cp)); + hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); + } + + return 0; +} + static void le_scan_disable_work(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, -- cgit v1.2.3-70-g09d2 From 7537e5c3064c5a5751a7b26aba82ad83c5e89190 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 20 Mar 2012 00:13:38 -0300 Subject: Bluetooth: Replace EPERM by EALREADY in hci_cancel_inquiry We should return -EALREADY in hci_cancel_inquiry since it is more suitable than -EPERM error code. Signed-off-by: Andre Guedes Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e3920b693f0..cc3d164f56f 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2956,7 +2956,7 @@ int hci_cancel_inquiry(struct hci_dev *hdev) BT_DBG("%s", hdev->name); if (!test_bit(HCI_INQUIRY, &hdev->flags)) - return -EPERM; + return -EALREADY; return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); } -- cgit v1.2.3-70-g09d2 From b24c62471c276b7ac6105e832eb6fe3c41a654ef Mon Sep 17 00:00:00 2001 From: Hemant Gupta Date: Thu, 5 Apr 2012 10:27:21 +0530 Subject: Bluetooth: Fix clearing discovery type when stopping discovery This patch prevents resetting of discovery type while stopping discovery, since otherwise the wrong type might be send in case of discovery failure. It also doesn't matter that we are "lazy" with updating the type since it is anyway reset when starting discovery again and it's not needed to know the current discovery state. Signed-off-by: Hemant Gupta Signed-off-by: Johan Hedberg --- net/bluetooth/hci_core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index cc3d164f56f..a6108469e9e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -385,7 +385,6 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state) case DISCOVERY_STOPPED: if (hdev->discovery.state != DISCOVERY_STARTING) mgmt_discovering(hdev, 0); - hdev->discovery.type = 0; break; case DISCOVERY_STARTING: break; -- cgit v1.2.3-70-g09d2 From 6bcbc4893fe8a6be3c3c5a83449d79dc9e9a51ac Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Wed, 28 Mar 2012 16:31:24 +0300 Subject: Bluetooth: Add Read Local AMP Info to init AMP Info will be used in Discovery Response. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a6108469e9e..3b3d9a882db 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -252,6 +252,9 @@ static void amp_init(struct hci_dev *hdev) /* Read Local Version */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); + + /* Read Local AMP Info */ + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); } static void hci_init_req(struct hci_dev *hdev, unsigned long opt) -- cgit v1.2.3-70-g09d2 From abc5de8f4e68ea785e32b91e456f467d2a2fb7db Mon Sep 17 00:00:00 2001 From: Mikel Astiz Date: Wed, 11 Apr 2012 08:48:47 +0200 Subject: Bluetooth: Use unsigned int instead of signed int The involved values are all unsigned and thus unsigned int should be used instead of signed int. Assigning ~0 to a signed int results in -1, which is confusing and error-prone, while the code is trying to set the maximum value possible. The code still works because the C standard defines that unsigned comparison will be performed in these cases, when comparing an unsigned int and a signed int. Signed-off-by: Mikel Astiz Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 3b3d9a882db..f7911e9224c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2334,7 +2334,7 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL, *c; - int num = 0, min = ~0; + unsigned int num = 0, min = ~0; /* We don't have to lock device here. Connections are always * added and removed with TX task disabled. */ @@ -2415,7 +2415,7 @@ static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_chan *chan = NULL; - int num = 0, min = ~0, cur_prio = 0; + unsigned int num = 0, min = ~0, cur_prio = 0; struct hci_conn *conn; int cnt, q, conn_num = 0; -- cgit v1.2.3-70-g09d2 From 2d8b3a11623cf5203bc063927b6fc742625f1ebf Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 16 Apr 2012 16:32:04 +0300 Subject: Bluetooth: Fix debug printing unallocated name It does make sense to print hdev name after allocation. Signed-off-by: Andrei Emeltchenko Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index f7911e9224c..544c7e3a40d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1741,8 +1741,6 @@ int hci_register_dev(struct hci_dev *hdev) struct list_head *head = &hci_dev_list, *p; int i, id, error; - BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); - if (!hdev->open || !hdev->close) return -EINVAL; @@ -1762,6 +1760,9 @@ int hci_register_dev(struct hci_dev *hdev) sprintf(hdev->name, "hci%d", id); hdev->id = id; + + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + list_add_tail(&hdev->list, head); mutex_init(&hdev->lock); -- cgit v1.2.3-70-g09d2 From fc50744c1e518adfb4ff2eda156f941e20aea36d Mon Sep 17 00:00:00 2001 From: Ulisses Furquim Date: Wed, 18 Apr 2012 12:13:04 -0300 Subject: Bluetooth: Fix registering hci with duplicate name When adding HCI devices hci_register_dev assigns the same name hci1 for subsequently added AMP devices. ... [ 6958.381886] sysfs: cannot create duplicate filename '/devices/virtual/bluetooth/hci1 ... We assume id starts with the number we'll try to add the new device and keep iterating until we find the proper place. The only difference is we start with 0 for BR/EDR device and 1 for AMP devices (thus AMP devices will never receive register as index 0). Then every hdev->id in the _ordered_ list <= to the id we want we increment id and move the variable head. In the end we'll have id as the first available one and head is where you need to add hdev after to keep the list ordered. Reported-by: Andrei Emeltchenko Signed-off-by: Ulisses Furquim Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 544c7e3a40d..22581823e61 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1738,24 +1738,28 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, /* Register HCI device */ int hci_register_dev(struct hci_dev *hdev) { - struct list_head *head = &hci_dev_list, *p; + struct list_head *head, *p; int i, id, error; if (!hdev->open || !hdev->close) return -EINVAL; + write_lock(&hci_dev_list_lock); + /* Do not allow HCI_AMP devices to register at index 0, * so the index can be used as the AMP controller ID. */ id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; - - write_lock(&hci_dev_list_lock); + head = &hci_dev_list; /* Find first available device id */ list_for_each(p, &hci_dev_list) { - if (list_entry(p, struct hci_dev, list)->id != id) + int nid = list_entry(p, struct hci_dev, list)->id; + if (nid > id) break; - head = p; id++; + if (nid == id) + id++; + head = p; } sprintf(hdev->name, "hci%d", id); @@ -1763,7 +1767,7 @@ int hci_register_dev(struct hci_dev *hdev) BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); - list_add_tail(&hdev->list, head); + list_add(&hdev->list, head); mutex_init(&hdev->lock); -- cgit v1.2.3-70-g09d2 From 9be0dab793f52615274c357fce542b3cbf78f6d7 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 22 Apr 2012 14:39:57 +0200 Subject: Bluetooth: Move hci_alloc/free_dev close to hci_register/unregister_dev alloc() and register() (and free() and unregister()) are closely related so move them more closely together. This will also allow to move functionality from register() to alloc() without needing forward-declarations. Signed-off-by: David Herrmann Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 52 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 22581823e61..d3fb986d6b2 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1092,32 +1092,6 @@ static const struct rfkill_ops hci_rfkill_ops = { .set_block = hci_rfkill_set_block, }; -/* Alloc HCI device */ -struct hci_dev *hci_alloc_dev(void) -{ - struct hci_dev *hdev; - - hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); - if (!hdev) - return NULL; - - hci_init_sysfs(hdev); - skb_queue_head_init(&hdev->driver_init); - - return hdev; -} -EXPORT_SYMBOL(hci_alloc_dev); - -/* Free HCI device */ -void hci_free_dev(struct hci_dev *hdev) -{ - skb_queue_purge(&hdev->driver_init); - - /* will free via device release */ - put_device(&hdev->dev); -} -EXPORT_SYMBOL(hci_free_dev); - static void hci_power_on(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); @@ -1735,6 +1709,32 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, return 0; } +/* Alloc HCI device */ +struct hci_dev *hci_alloc_dev(void) +{ + struct hci_dev *hdev; + + hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); + if (!hdev) + return NULL; + + hci_init_sysfs(hdev); + skb_queue_head_init(&hdev->driver_init); + + return hdev; +} +EXPORT_SYMBOL(hci_alloc_dev); + +/* Free HCI device */ +void hci_free_dev(struct hci_dev *hdev) +{ + skb_queue_purge(&hdev->driver_init); + + /* will free via device release */ + put_device(&hdev->dev); +} +EXPORT_SYMBOL(hci_free_dev); + /* Register HCI device */ int hci_register_dev(struct hci_dev *hdev) { -- cgit v1.2.3-70-g09d2 From b1b813d4777f4843af2acce9a1b62d486e1d3ffc Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 22 Apr 2012 14:39:58 +0200 Subject: Bluetooth: Move device initialization to hci_alloc_dev() We currently initialize locks, lists, works, etc. in hci_register_dev() (hci_alloc_dev() was added later) which is bogus because an hdev is in an invalid state if it is not registered. This patch moves all memory initialization to hci_alloc_dev(). Device registering and registration of sub-modules is still left in hci_register_dev() as it belongs there. The benefit is (despite cleaning up the code-base) we can now always be sure that an hdev is a valid object and can be locked and worked on even though it may not be registered. This patch also reorders the initialization to be easier to understand. First the memory is initialized, then all generic structures and as last step the sub-init functions are called. This guarantees that all dependencies are initialized in the right order and makes it also easier to find a specific line. We previously initialized it in the same order as the "struct hci_dev" is declared which seems pretty random. Signed-off-by: David Herrmann Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 115 +++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 63 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d3fb986d6b2..a362f01bf08 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1713,13 +1713,63 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, struct hci_dev *hci_alloc_dev(void) { struct hci_dev *hdev; + int i; hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); if (!hdev) return NULL; - hci_init_sysfs(hdev); + hdev->flags = 0; + hdev->dev_flags = 0; + hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); + hdev->esco_type = (ESCO_HV1); + hdev->link_mode = (HCI_LM_ACCEPT); + hdev->io_capability = 0x03; /* No Input No Output */ + + hdev->idle_timeout = 0; + hdev->sniff_max_interval = 800; + hdev->sniff_min_interval = 80; + + mutex_init(&hdev->lock); + mutex_init(&hdev->req_lock); + + INIT_LIST_HEAD(&hdev->mgmt_pending); + INIT_LIST_HEAD(&hdev->blacklist); + INIT_LIST_HEAD(&hdev->uuids); + INIT_LIST_HEAD(&hdev->link_keys); + INIT_LIST_HEAD(&hdev->long_term_keys); + INIT_LIST_HEAD(&hdev->remote_oob_data); + INIT_LIST_HEAD(&hdev->adv_entries); + + INIT_WORK(&hdev->rx_work, hci_rx_work); + INIT_WORK(&hdev->cmd_work, hci_cmd_work); + INIT_WORK(&hdev->tx_work, hci_tx_work); + INIT_WORK(&hdev->power_on, hci_power_on); + INIT_WORK(&hdev->le_scan, le_scan_work); + + INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); + INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); + INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); + INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); + skb_queue_head_init(&hdev->driver_init); + skb_queue_head_init(&hdev->rx_q); + skb_queue_head_init(&hdev->cmd_q); + skb_queue_head_init(&hdev->raw_q); + + init_waitqueue_head(&hdev->req_wait_q); + + setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); + + memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); + atomic_set(&hdev->promisc, 0); + + for (i = 0; i < NUM_REASSEMBLY; i++) + hdev->reassembly[i] = NULL; + + hci_init_sysfs(hdev); + discovery_init(hdev); + hci_conn_hash_init(hdev); return hdev; } @@ -1739,7 +1789,7 @@ EXPORT_SYMBOL(hci_free_dev); int hci_register_dev(struct hci_dev *hdev) { struct list_head *head, *p; - int i, id, error; + int id, error; if (!hdev->open || !hdev->close) return -EINVAL; @@ -1769,67 +1819,6 @@ int hci_register_dev(struct hci_dev *hdev) list_add(&hdev->list, head); - mutex_init(&hdev->lock); - - hdev->flags = 0; - hdev->dev_flags = 0; - hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); - hdev->esco_type = (ESCO_HV1); - hdev->link_mode = (HCI_LM_ACCEPT); - hdev->io_capability = 0x03; /* No Input No Output */ - - hdev->idle_timeout = 0; - hdev->sniff_max_interval = 800; - hdev->sniff_min_interval = 80; - - INIT_WORK(&hdev->rx_work, hci_rx_work); - INIT_WORK(&hdev->cmd_work, hci_cmd_work); - INIT_WORK(&hdev->tx_work, hci_tx_work); - - - skb_queue_head_init(&hdev->rx_q); - skb_queue_head_init(&hdev->cmd_q); - skb_queue_head_init(&hdev->raw_q); - - setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); - - for (i = 0; i < NUM_REASSEMBLY; i++) - hdev->reassembly[i] = NULL; - - init_waitqueue_head(&hdev->req_wait_q); - mutex_init(&hdev->req_lock); - - discovery_init(hdev); - - hci_conn_hash_init(hdev); - - INIT_LIST_HEAD(&hdev->mgmt_pending); - - INIT_LIST_HEAD(&hdev->blacklist); - - INIT_LIST_HEAD(&hdev->uuids); - - INIT_LIST_HEAD(&hdev->link_keys); - INIT_LIST_HEAD(&hdev->long_term_keys); - - INIT_LIST_HEAD(&hdev->remote_oob_data); - - INIT_LIST_HEAD(&hdev->adv_entries); - - INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); - INIT_WORK(&hdev->power_on, hci_power_on); - INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); - - INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); - - memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); - - atomic_set(&hdev->promisc, 0); - - INIT_WORK(&hdev->le_scan, le_scan_work); - - INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); - write_unlock(&hci_dev_list_lock); hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | -- cgit v1.2.3-70-g09d2 From d8ce9395252fa9a264c04e7ab9949f4f7ec96f5b Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 22 Apr 2012 14:39:59 +0200 Subject: Bluetooth: Remove unneeded initialization in hci_alloc_dev() We allocate memory with kzalloc() so there is no need to call memset(..., 0, ...) or similar. Signed-off-by: David Herrmann Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a362f01bf08..aa45ea496f8 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1713,20 +1713,16 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, struct hci_dev *hci_alloc_dev(void) { struct hci_dev *hdev; - int i; hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); if (!hdev) return NULL; - hdev->flags = 0; - hdev->dev_flags = 0; hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); hdev->esco_type = (ESCO_HV1); hdev->link_mode = (HCI_LM_ACCEPT); hdev->io_capability = 0x03; /* No Input No Output */ - hdev->idle_timeout = 0; hdev->sniff_max_interval = 800; hdev->sniff_min_interval = 80; @@ -1761,12 +1757,6 @@ struct hci_dev *hci_alloc_dev(void) setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); - memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); - atomic_set(&hdev->promisc, 0); - - for (i = 0; i < NUM_REASSEMBLY; i++) - hdev->reassembly[i] = NULL; - hci_init_sysfs(hdev); discovery_init(hdev); hci_conn_hash_init(hdev); -- cgit v1.2.3-70-g09d2 From 31f7956c6648fbae9c9550e91d1c348d28276309 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 24 Apr 2012 21:02:53 -0300 Subject: Bluetooth: Move bdaddr_to_le to hci_core This patch moves the helper function bdaddr_to_le to hci_core, so it can be used in mgmt.c and hci_conn.c. Signed-off-by: Andre Guedes Acked-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_core.c | 12 ++++++++++++ net/bluetooth/mgmt.c | 12 ------------ 3 files changed, 14 insertions(+), 12 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 6777432ca61..7e7fe3f221f 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1073,4 +1073,6 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout); int hci_cancel_le_scan(struct hci_dev *hdev); +u8 bdaddr_to_le(u8 bdaddr_type); + #endif /* __HCI_CORE_H */ diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index aa45ea496f8..7bbd5c5767b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2946,3 +2946,15 @@ int hci_cancel_inquiry(struct hci_dev *hdev) return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); } + +u8 bdaddr_to_le(u8 bdaddr_type) +{ + switch (bdaddr_type) { + case BDADDR_LE_PUBLIC: + return ADDR_LE_DEV_PUBLIC; + + default: + /* Fallback to LE Random address type */ + return ADDR_LE_DEV_RANDOM; + } +} diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 605a35b284f..4e26c258581 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1644,18 +1644,6 @@ static u8 link_to_bdaddr(u8 link_type, u8 addr_type) } } -static u8 bdaddr_to_le(u8 bdaddr_type) -{ - switch (bdaddr_type) { - case BDADDR_LE_PUBLIC: - return ADDR_LE_DEV_PUBLIC; - - default: - /* Fallback to LE Random address type */ - return ADDR_LE_DEV_RANDOM; - } -} - static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data, u16 data_len) { -- cgit v1.2.3-70-g09d2 From 479453d5fe3a5b911b7f56474764988100f9f650 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Tue, 24 Apr 2012 21:02:56 -0300 Subject: Bluetooth: Remove advertising cache User-space pass the remote device address type to kernel through struct sockaddr_l2 what makes the advertising useless. This patch removes all advertising cache code. Signed-off-by: Andre Guedes Acked-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 9 ----- net/bluetooth/hci_core.c | 74 ---------------------------------------- net/bluetooth/hci_event.c | 7 ---- 3 files changed, 90 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e69a9eed082..d1e744f3b9b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -255,9 +255,6 @@ struct hci_dev { struct list_head remote_oob_data; - struct list_head adv_entries; - struct delayed_work adv_work; - struct hci_dev_stats stat; struct sk_buff_head driver_init; @@ -692,12 +689,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, u8 *randomizer); int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); -#define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */ -int hci_adv_entries_clear(struct hci_dev *hdev); -struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_add_adv_entry(struct hci_dev *hdev, - struct hci_ev_le_advertising_info *ev); - void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_frame(struct sk_buff *skb); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 7bbd5c5767b..83d3d3563bc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1521,75 +1521,6 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) return mgmt_device_unblocked(hdev, bdaddr, type); } -static void hci_clear_adv_cache(struct work_struct *work) -{ - struct hci_dev *hdev = container_of(work, struct hci_dev, - adv_work.work); - - hci_dev_lock(hdev); - - hci_adv_entries_clear(hdev); - - hci_dev_unlock(hdev); -} - -int hci_adv_entries_clear(struct hci_dev *hdev) -{ - struct adv_entry *entry, *tmp; - - list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) { - list_del(&entry->list); - kfree(entry); - } - - BT_DBG("%s adv cache cleared", hdev->name); - - return 0; -} - -struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr) -{ - struct adv_entry *entry; - - list_for_each_entry(entry, &hdev->adv_entries, list) - if (bacmp(bdaddr, &entry->bdaddr) == 0) - return entry; - - return NULL; -} - -static inline int is_connectable_adv(u8 evt_type) -{ - if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND) - return 1; - - return 0; -} - -int hci_add_adv_entry(struct hci_dev *hdev, - struct hci_ev_le_advertising_info *ev) { struct adv_entry *entry; if (!is_connectable_adv(ev->evt_type)) - return -EINVAL; - - /* Only new entries should be added to adv_entries. So, if - * bdaddr was found, don't add it. */ - if (hci_find_adv_entry(hdev, &ev->bdaddr)) - return 0; - - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - bacpy(&entry->bdaddr, &ev->bdaddr); - entry->bdaddr_type = ev->bdaddr_type; - - list_add(&entry->list, &hdev->adv_entries); - - BT_DBG("%s adv entry added: address %s type %u", hdev->name, - batostr(&entry->bdaddr), entry->bdaddr_type); - - return 0; -} - static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt) { struct le_scan_params *param = (struct le_scan_params *) opt; @@ -1735,7 +1666,6 @@ struct hci_dev *hci_alloc_dev(void) INIT_LIST_HEAD(&hdev->link_keys); INIT_LIST_HEAD(&hdev->long_term_keys); INIT_LIST_HEAD(&hdev->remote_oob_data); - INIT_LIST_HEAD(&hdev->adv_entries); INIT_WORK(&hdev->rx_work, hci_rx_work); INIT_WORK(&hdev->cmd_work, hci_cmd_work); @@ -1743,7 +1673,6 @@ struct hci_dev *hci_alloc_dev(void) INIT_WORK(&hdev->power_on, hci_power_on); INIT_WORK(&hdev->le_scan, le_scan_work); - INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); @@ -1889,8 +1818,6 @@ void hci_unregister_dev(struct hci_dev *hdev) hci_del_sysfs(hdev); - cancel_delayed_work_sync(&hdev->adv_work); - destroy_workqueue(hdev->workqueue); hci_dev_lock(hdev); @@ -1899,7 +1826,6 @@ void hci_unregister_dev(struct hci_dev *hdev) hci_link_keys_clear(hdev); hci_smp_ltks_clear(hdev); hci_remote_oob_data_clear(hdev); - hci_adv_entries_clear(hdev); hci_dev_unlock(hdev); hci_dev_put(hdev); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 054b1ad7449..ae0a57d21ec 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1100,10 +1100,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, set_bit(HCI_LE_SCAN, &hdev->dev_flags); - cancel_delayed_work_sync(&hdev->adv_work); - hci_dev_lock(hdev); - hci_adv_entries_clear(hdev); hci_discovery_set_state(hdev, DISCOVERY_FINDING); hci_dev_unlock(hdev); break; @@ -1118,8 +1115,6 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, clear_bit(HCI_LE_SCAN, &hdev->dev_flags); - schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT); - if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && hdev->discovery.state == DISCOVERY_FINDING) { mgmt_interleaved_discovery(hdev); @@ -3353,8 +3348,6 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev, while (num_reports--) { struct hci_ev_le_advertising_info *ev = ptr; - hci_add_adv_entry(hdev, ev); - rssi = ev->data[ev->length]; mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, NULL, rssi, 0, 1, ev->data, ev->length); -- cgit v1.2.3-70-g09d2 From 087bfd99f75c5f7d5430e7e122c2f288f03d6c23 Mon Sep 17 00:00:00 2001 From: Gustavo Padovan Date: Fri, 11 May 2012 13:16:11 -0300 Subject: Bluetooth: Fix packet size provided to the controller When building fragmented skb's skb->len keeps track of the size of head plus all fragments combined, however when queueing the skb for sending we need to report the head size instead of the total size, so we just set skb->len to skb_headlen(). This bug appeared when implementing MSG_MORE support for L2CAP sockets, it never showed up before because l2cap_skbuff_fromiovec() never accounted skb size correctly. A following patch will fix this. Signed-off-by: Gustavo Padovan Reviewed-by: Mat Martineau Signed-off-by: Johan Hedberg --- net/bluetooth/hci_core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'net/bluetooth/hci_core.c') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a8962382f9c..411ace8e647 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2162,6 +2162,12 @@ static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, struct hci_dev *hdev = conn->hdev; struct sk_buff *list; + skb->len = skb_headlen(skb); + skb->data_len = 0; + + bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; + hci_add_acl_hdr(skb, conn->handle, flags); + list = skb_shinfo(skb)->frag_list; if (!list) { /* Non fragmented */ @@ -2205,8 +2211,6 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); skb->dev = (void *) hdev; - bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; - hci_add_acl_hdr(skb, conn->handle, flags); hci_queue_acl(conn, &chan->data_q, skb, flags); -- cgit v1.2.3-70-g09d2