Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: hci_h5: avoid sending two SYNC messages

Previously, h5_open() called h5_link_control() to send a SYNC message.
But h5_link_control() only enqueues the packet and requires the caller
to call hci_uart_tx_wakeup(). Thus, after H5_SYNC_TIMEOUT ran out
(100ms), h5_timed_event() would be called and, realizing that the state
was still H5_UNINITIALIZED, it would re-enqueue the SYNC and call
hci_uart_tx_wakeup(). Consequently, two SYNC packets would be sent and
initialization would unnecessarily wait for 100ms.

The naive solution of calling hci_uart_tx_wakeup() in h5_open() does not
work because it will only schedule tx work if the HCI_PROTO_READY bit is
set and hci_serdev only sets it after h5_open() returns. This patch
removes the extraneous SYNC being enqueued and makes h5_timed_event()
wake up on the next jiffy.

Signed-off-by: Javier Nieto <jgnieto@cs.stanford.edu>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Javier Nieto and committed by
Luiz Augusto von Dentz
01622e9a 484f1176

+5 -4
+5 -4
drivers/bluetooth/hci_h5.c
··· 213 213 static int h5_open(struct hci_uart *hu) 214 214 { 215 215 struct h5 *h5; 216 - const unsigned char sync[] = { 0x01, 0x7e }; 217 216 218 217 BT_DBG("hu %p", hu); 219 218 ··· 242 243 243 244 set_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags); 244 245 245 - /* Send initial sync request */ 246 - h5_link_control(hu, sync, sizeof(sync)); 247 - mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT); 246 + /* 247 + * Wait one jiffy because the UART layer won't set HCI_UART_PROTO_READY, 248 + * which allows us to send link packets, until this function returns. 249 + */ 250 + mod_timer(&h5->timer, jiffies + 1); 248 251 249 252 return 0; 250 253 }