Page MenuHomeFreeBSD

D46737.diff
No OneTemporary

D46737.diff

diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h
@@ -72,6 +72,12 @@
#define IWMBT_HCI_MAX_CMD_SIZE 256
#define IWMBT_HCI_MAX_EVENT_SIZE 16
+#define IWMBT_MSEC2TS(msec) \
+ (struct timespec) { \
+ .tv_sec = (msec) / 1000, \
+ .tv_nsec = ((msec) % 1000) * 1000000 \
+ };
+#define IWMBT_TS2MSEC(ts) ((ts).tv_sec * 1000 + (ts).tv_nsec / 1000000)
#define IWMBT_HCI_CMD_TIMEOUT 2000 /* ms */
#define IWMBT_LOADCMPL_TIMEOUT 5000 /* ms */
diff --git a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
--- a/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
+++ b/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.c
@@ -37,10 +37,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
#include <libusb.h>
+#include <netgraph/bluetooth/include/ng_hci.h>
+
#include "iwmbt_fw.h"
#include "iwmbt_hw.h"
#include "iwmbt_dbg.h"
@@ -95,6 +98,7 @@
iwmbt_hci_command(struct libusb_device_handle *hdl, struct iwmbt_hci_cmd *cmd,
void *event, int size, int *transferred, int timeout)
{
+ struct timespec to, now, remains;
int ret;
ret = libusb_control_transfer(hdl,
@@ -112,18 +116,47 @@
return (ret);
}
- ret = libusb_interrupt_transfer(hdl,
- IWMBT_INTERRUPT_ENDPOINT_ADDR,
- event,
- size,
- transferred,
- timeout);
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ to = IWMBT_MSEC2TS(timeout);
+ timespecadd(&to, &now, &to);
- if (ret < 0)
- iwmbt_err("libusb_interrupt_transfer() failed: err=%s",
- libusb_strerror(ret));
+ do {
+ timespecsub(&to, &now, &remains);
+ ret = libusb_interrupt_transfer(hdl,
+ IWMBT_INTERRUPT_ENDPOINT_ADDR,
+ event,
+ size,
+ transferred,
+ IWMBT_TS2MSEC(remains) + 1);
- return (ret);
+ if (ret < 0) {
+ iwmbt_err("libusb_interrupt_transfer() failed: err=%s",
+ libusb_strerror(ret));
+ return (ret);
+ }
+
+ switch (((struct iwmbt_hci_event *)event)->header.event) {
+ case NG_HCI_EVENT_COMMAND_COMPL:
+ if (*transferred <
+ (int)offsetof(struct iwmbt_hci_event_cmd_compl, data))
+ break;
+ if (cmd->opcode !=
+ ((struct iwmbt_hci_event_cmd_compl *)event)->opcode)
+ break;
+ /* FALLTHROUGH */
+ case 0xFF:
+ return (0);
+ default:
+ break;
+ }
+ iwmbt_debug("Stray HCI event: %x",
+ ((struct iwmbt_hci_event *)event)->header.event);
+ } while (timespeccmp(&to, &now, >));
+
+ iwmbt_err("libusb_interrupt_transfer() failed: err=%s",
+ libusb_strerror(LIBUSB_ERROR_TIMEOUT));
+
+ return (LIBUSB_ERROR_TIMEOUT);
}
int
@@ -691,6 +724,7 @@
int size, sent = 0;
int ret, transferred;
uint8_t buf[IWMBT_HCI_MAX_CMD_SIZE];
+ uint8_t evt[IWMBT_HCI_MAX_CMD_SIZE];
struct iwmbt_hci_cmd *cmd = (struct iwmbt_hci_cmd *)buf;
size = ddc->len;
@@ -713,8 +747,8 @@
ret = iwmbt_hci_command(hdl,
cmd,
- buf,
- sizeof(buf),
+ evt,
+ sizeof(evt),
&transferred,
IWMBT_HCI_CMD_TIMEOUT);

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 27, 5:55 PM (16 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17820492
Default Alt Text
D46737.diff (3 KB)

Event Timeline