aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c27
-rw-r--r--sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c5
2 files changed, 30 insertions, 2 deletions
diff --git a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
index 649c479d1d9f..64b41c0a328d 100644
--- a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
+++ b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
@@ -530,6 +530,7 @@ static const STRUCT_USB_HOST_ID ubt_devs[] =
* Size of both command and response buffers are passed in length field of
* corresponding structures in "Parameter Total Length" format i.e.
* not including HCI packet headers.
+ * Expected event code must be placed into "Event code" of the response buffer.
*
* Must not be used after USB transfers have been configured in attach routine.
*/
@@ -568,6 +569,12 @@ ubt_do_hci_request(struct usb_device *udev, struct ubt_hci_cmd *cmd,
if (evt == NULL)
return (USB_ERR_NORMAL_COMPLETION);
+ /* Save operation code if we expect completion event in response */
+ if(((struct ubt_hci_event *)evt)->header.event ==
+ NG_HCI_EVENT_COMMAND_COMPL)
+ ((struct ubt_hci_event_command_compl *)evt)->opcode =
+ cmd->opcode;
+
/* Initialize INTR endpoint xfer and wait for response */
mtx_init(&mtx, "ubt pb", NULL, MTX_DEF | MTX_NEW);
@@ -841,6 +848,8 @@ ubt_probe_intr_callback(struct usb_xfer *xfer, usb_error_t error)
struct ubt_hci_event *evt = usbd_xfer_softc(xfer);
struct usb_page_cache *pc;
int actlen;
+ struct ubt_hci_evhdr evhdr;
+ uint16_t opcode;
usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
@@ -848,7 +857,25 @@ ubt_probe_intr_callback(struct usb_xfer *xfer, usb_error_t error)
case USB_ST_TRANSFERRED:
if (actlen > UBT_HCI_EVENT_SIZE(evt))
actlen = UBT_HCI_EVENT_SIZE(evt);
+ if (actlen < sizeof(evhdr))
+ goto submit_next;
pc = usbd_xfer_get_frame(xfer, 0);
+ usbd_copy_out(pc, 0, &evhdr, sizeof(evhdr));
+ /* Check for expected event code */
+ if (evt->header.event != 0 &&
+ (evt->header.event != evhdr.event))
+ goto submit_next;
+ /* For completion events check operation code as well */
+ if (evt->header.event == NG_HCI_EVENT_COMMAND_COMPL) {
+ if (actlen < sizeof(struct ubt_hci_event_command_compl))
+ goto submit_next;
+ usbd_copy_out(pc,
+ offsetof(struct ubt_hci_event_command_compl, opcode),
+ &opcode, sizeof(opcode));
+ if (opcode !=
+ ((struct ubt_hci_event_command_compl *)evt)->opcode)
+ goto submit_next;
+ }
usbd_copy_out(pc, 0, evt, actlen);
/* OneShot mode */
wakeup(evt);
diff --git a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c
index f93b74b264ad..c4410b7b2c80 100644
--- a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c
+++ b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c
@@ -119,14 +119,14 @@ ubt_intel_do_hci_request(struct usb_device *udev, uint16_t opcode,
cmd.opcode = htole16(opcode);
evt = malloc(offsetof(struct ubt_hci_event_command_compl, data) +
resp_len, M_TEMP, M_ZERO | M_WAITOK);
+ evt->header.event = NG_HCI_EVENT_COMMAND_COMPL;
evt->header.length = resp_len + UBT_HCI_EVENT_COMPL_HEAD_SIZE;
error = ubt_do_hci_request(udev, &cmd, evt, UBT_INTEL_HCICMD_TIMEOUT);
if (error != USB_ERR_NORMAL_COMPLETION)
goto exit;
- if (evt->header.event == NG_HCI_EVENT_COMMAND_COMPL &&
- evt->header.length == resp_len + UBT_HCI_EVENT_COMPL_HEAD_SIZE)
+ if (evt->header.length == resp_len + UBT_HCI_EVENT_COMPL_HEAD_SIZE)
memcpy(resp, evt->data, resp_len);
else
error = USB_ERR_INVAL;
@@ -150,6 +150,7 @@ ubt_intel_get_img_type(struct usb_device *udev)
uint8_t *data;
evt = malloc(UBT_INTEL_MAX_EVT_SIZE, M_TEMP, M_ZERO | M_WAITOK);
+ evt->header.event = NG_HCI_EVENT_COMMAND_COMPL;
evt->header.length =
UBT_INTEL_MAX_EVT_SIZE - sizeof(struct ubt_hci_evhdr);