Bluetooth: Rotate outgoing ACL packets via a pending queue

To ensure that we never have more outgoing ACL buffers available than
the controller is willing to accept we should hold on to them between
calling drv->send() and getting the corresponding Number of Completed
Packets event. This patch adds a temporary FIFO in bt_dev for this.

Change-Id: I918119a03081d507de2bb4a731b2709ea99a648d
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2015-04-28 12:11:30 +03:00 committed by Anas Nashif
commit cb6b288252
3 changed files with 16 additions and 2 deletions

View file

@ -208,7 +208,7 @@ static void conn_tx_fiber(int arg1, int arg2)
}
dev->drv->send(buf);
bt_buf_put(buf);
nano_fiber_fifo_put(&dev->acl_pend, buf);
}
BT_DBG("handle %u disconnected - cleaning up\n", conn->handle);

View file

@ -357,14 +357,22 @@ static void hci_num_completed_packets(struct bt_buf *buf)
for (i = 0; i < num_handles; i++) {
uint16_t handle, count;
struct bt_buf *buf;
handle = sys_le16_to_cpu(evt->h[i].handle);
count = sys_le16_to_cpu(evt->h[i].count);
BT_DBG("handle %u count %u\n", handle, count);
while (count--)
while (count--) {
nano_fiber_sem_give(&dev.le_pkts_sem);
buf = nano_fiber_fifo_get(&dev.acl_pend);
if (!buf) {
BT_ERR("Mismatch with pending ACL buffers\n");
continue;
}
bt_buf_put(buf);
}
}
}
@ -647,6 +655,9 @@ int bt_init(void)
if (err)
return err;
/* Initialize pending ACL packets FIFO */
nano_fifo_init(&dev.acl_pend);
/* Re-initialize buffers now that we know the ACL counts */
if (dev.le_pkts > ACL_OUT_MAX)
acl_out = ACL_OUT_MAX;

View file

@ -71,6 +71,9 @@ struct bt_dev {
/* Queue for outgoing HCI commands */
struct nano_fifo cmd_queue;
/* Pending outgoing ACL packets */
struct nano_fifo acl_pend;
/* Registered HCI driver */
struct bt_driver *drv;
};