View | Details | Raw Unified | Return to bug 228787 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c (-3 / +6 lines)
Lines 423-429 static const STRUCT_USB_HOST_ID ubt_ignore_devs[] = Link Here
423
	{ USB_VPI(0x0489, 0xe03c, 0), USB_DEV_BCD_LTEQ(1) },
423
	{ USB_VPI(0x0489, 0xe03c, 0), USB_DEV_BCD_LTEQ(1) },
424
	{ USB_VPI(0x0489, 0xe036, 0), USB_DEV_BCD_LTEQ(1) },
424
	{ USB_VPI(0x0489, 0xe036, 0), USB_DEV_BCD_LTEQ(1) },
425
425
426
	/* Intel Wireless 8260 and successors are handled in ng_ubt_intel.c */
426
	/* Intel Wireless controllers are handled in ng_ubt_intel.c */
427
	{ USB_VPI(USB_VENDOR_INTEL2, 0x07dc, 0) },
428
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0a2a, 0) },
429
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0aa7, 0) },
427
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0a2b, 0) },
430
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0a2b, 0) },
428
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0aaa, 0) },
431
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0aaa, 0) },
429
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0025, 0) },
432
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0025, 0) },
Lines 825-832 ubt_probe_intr_callback(struct usb_xfer *xfer, usb_error_t error) Link Here
825
828
826
        case USB_ST_SETUP:
829
        case USB_ST_SETUP:
827
submit_next:
830
submit_next:
828
		/* Try clear stall first */
829
		usbd_xfer_set_stall(xfer);
830
		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
831
		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
831
		usbd_transfer_submit(xfer);
832
		usbd_transfer_submit(xfer);
832
		break;
833
		break;
Lines 835-840 ubt_probe_intr_callback(struct usb_xfer *xfer, usb_error_t error) Link Here
835
		if (error != USB_ERR_CANCELLED) {
836
		if (error != USB_ERR_CANCELLED) {
836
			printf("ng_ubt: interrupt transfer failed: %s\n",
837
			printf("ng_ubt: interrupt transfer failed: %s\n",
837
				usbd_errstr(error));
838
				usbd_errstr(error));
839
			/* Try clear stall first */
840
			usbd_xfer_set_stall(xfer);
838
			goto submit_next;
841
			goto submit_next;
839
		}
842
		}
840
		break;
843
		break;
(-)b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_intel.c (-36 / +97 lines)
Lines 5-11 Link Here
5
/*-
5
/*-
6
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7
 *
7
 *
8
 * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org>
8
 * Copyright (c) 2019, 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
9
 *
9
 *
10
 * Redistribution and use in source and binary forms, with or without
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
11
 * modification, are permitted provided that the following conditions
Lines 58-63 Link Here
58
#include <netgraph/bluetooth/include/ng_ubt.h>
58
#include <netgraph/bluetooth/include/ng_ubt.h>
59
#include <netgraph/bluetooth/drivers/ubt/ng_ubt_var.h>
59
#include <netgraph/bluetooth/drivers/ubt/ng_ubt_var.h>
60
60
61
enum {
62
	UBT_INTEL_DEVICE_7260,
63
	UBT_INTEL_DEVICE_8260,
64
};
65
66
struct ubt_intel_version_rp {
67
	uint8_t status;
68
	uint8_t hw_platform;
69
	uint8_t hw_variant;
70
	uint8_t hw_revision;
71
	uint8_t fw_variant;
72
	uint8_t fw_revision;
73
	uint8_t fw_build_num;
74
	uint8_t fw_build_ww;
75
	uint8_t fw_build_yy;
76
	uint8_t fw_patch_num;
77
} __attribute__ ((packed));
78
61
static device_probe_t	ubt_intel_probe;
79
static device_probe_t	ubt_intel_probe;
62
80
63
/*
81
/*
Lines 67-110 static device_probe_t ubt_intel_probe; Link Here
67
85
68
static const STRUCT_USB_HOST_ID ubt_intel_devs[] =
86
static const STRUCT_USB_HOST_ID ubt_intel_devs[] =
69
{
87
{
88
	/* Intel Wireless 7260/7265 and successors */
89
	{ USB_VPI(USB_VENDOR_INTEL2, 0x07dc, UBT_INTEL_DEVICE_7260) },
90
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0a2a, UBT_INTEL_DEVICE_7260) },
91
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0aa7, UBT_INTEL_DEVICE_7260) },
70
	/* Intel Wireless 8260/8265 and successors */
92
	/* Intel Wireless 8260/8265 and successors */
71
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0a2b, 0) },
93
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0a2b, UBT_INTEL_DEVICE_8260) },
72
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0aaa, 0) },
94
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0aaa, UBT_INTEL_DEVICE_8260) },
73
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0025, 0) },
95
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0025, UBT_INTEL_DEVICE_8260) },
74
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0026, 0) },
96
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0026, UBT_INTEL_DEVICE_8260) },
75
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0029, 0) },
97
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0029, UBT_INTEL_DEVICE_8260) },
76
};
98
};
77
99
78
/*
100
/*
79
 * Find if the Intel Wireless 8260/8265 device is in bootloader mode or is
101
 * Execute generic HCI command and return response in provided buffer.
80
 * running operational firmware with checking of 4-th byte "Intel version"
81
 * HCI command response. The value 0x23 identifies the operational firmware.
82
 */
102
 */
83
103
84
static bool
104
static usb_error_t
85
ubt_intel_check_firmware_state(struct usb_device *udev)
105
ubt_intel_do_hci_request(struct usb_device *udev, uint16_t opcode,
106
    void *resp, uint8_t resp_len)
86
{
107
{
87
#define	UBT_INTEL_VER_LEN		13
88
#define	UBT_INTEL_HCICMD_TIMEOUT	2000	/* ms */
108
#define	UBT_INTEL_HCICMD_TIMEOUT	2000	/* ms */
89
	struct ubt_hci_event_command_compl *evt;
109
	struct ubt_hci_event_command_compl *evt;
90
	uint8_t buf[offsetof(struct ubt_hci_event, data) + UBT_INTEL_VER_LEN];
110
	struct ubt_hci_cmd cmd;
91
	static struct ubt_hci_cmd cmd = {
92
		.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_VENDOR, 0x05)),
93
		.length = 0,
94
	};
95
	usb_error_t error;
111
	usb_error_t error;
96
112
97
	bzero(buf, sizeof(buf));
113
	memset(&cmd, 0, sizeof(cmd));
98
	evt = (struct ubt_hci_event_command_compl *)buf;
114
	cmd.opcode = htole16(opcode);
99
	evt->header.length = UBT_INTEL_VER_LEN;
115
	evt = malloc(offsetof(struct ubt_hci_event_command_compl, data) +
116
	    resp_len, M_TEMP, M_ZERO | M_WAITOK);
117
	evt->header.length = resp_len + UBT_HCI_EVENT_COMPL_HEAD_SIZE;
100
118
101
	error = ubt_do_hci_request(udev, &cmd, evt, UBT_INTEL_HCICMD_TIMEOUT);
119
	error = ubt_do_hci_request(udev, &cmd, evt, UBT_INTEL_HCICMD_TIMEOUT);
102
	if (error != USB_ERR_NORMAL_COMPLETION)
120
	if (error != USB_ERR_NORMAL_COMPLETION)
103
		return false;
121
		goto exit;
104
122
105
	return (evt->header.event == NG_HCI_EVENT_COMMAND_COMPL &&
123
	if (evt->header.event == NG_HCI_EVENT_COMMAND_COMPL &&
106
		evt->header.length == UBT_INTEL_VER_LEN &&
124
	    evt->header.length == resp_len + UBT_HCI_EVENT_COMPL_HEAD_SIZE)
107
		evt->data[4] == 0x23);
125
		memcpy(resp, evt->data, resp_len);
126
	else
127
		error = USB_ERR_INVAL;
128
exit:
129
	free(evt, M_TEMP);
130
	return (error);
108
}
131
}
109
132
110
/*
133
/*
Lines 115-120 static int Link Here
115
ubt_intel_probe(device_t dev)
138
ubt_intel_probe(device_t dev)
116
{
139
{
117
	struct usb_attach_arg	*uaa = device_get_ivars(dev);
140
	struct usb_attach_arg	*uaa = device_get_ivars(dev);
141
	struct ubt_intel_version_rp version;
142
	ng_hci_reset_rp reset;
118
	int error;
143
	int error;
119
144
120
	if (uaa->usb_mode != USB_MODE_HOST)
145
	if (uaa->usb_mode != USB_MODE_HOST)
Lines 128-135 ubt_intel_probe(device_t dev) Link Here
128
	if (error != 0)
153
	if (error != 0)
129
		return (error);
154
		return (error);
130
155
131
	if (!ubt_intel_check_firmware_state(uaa->device))
156
	switch (USB_GET_DRIVER_INFO(uaa)) {
132
		return (ENXIO);
157
	case UBT_INTEL_DEVICE_7260:
158
		/*
159
		 * Send HCI Reset command to workaround controller bug with the
160
		 * first HCI command sent to it returning number of completed
161
		 * commands as zero.  This will reset the number of completed
162
		 * commands and allow further normal command processing.
163
		 */
164
		if (ubt_intel_do_hci_request(uaa->device,
165
		    NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_RESET),
166
		    &reset, sizeof(reset)) != USB_ERR_NORMAL_COMPLETION)
167
			return (ENXIO);
168
		if (reset.status != 0)
169
			return (ENXIO);
170
		/*
171
		 * fw_patch_num indicates the version of patch the device
172
		 * currently have.  If there is no patch data in the device,
173
		 * it is always 0x00 and we need to patch the device again.
174
		 */
175
		if (ubt_intel_do_hci_request(uaa->device,
176
		    NG_HCI_OPCODE(NG_HCI_OGF_VENDOR, 0x05),
177
		    &version, sizeof(version)) != USB_ERR_NORMAL_COMPLETION)
178
			return (ENXIO);
179
		if (version.fw_patch_num == 0)
180
			return (ENXIO);
181
		break;
182
183
	case UBT_INTEL_DEVICE_8260:
184
		/*
185
		 * Find if the Intel Wireless 8260/8265 device is in bootloader
186
		 * mode or is running operational firmware with checking of
187
		 * variant byte of "Intel version" HCI command response.
188
		 * The value 0x23 identifies the operational firmware.
189
		 */
190
		if (ubt_intel_do_hci_request(uaa->device,
191
		    NG_HCI_OPCODE(NG_HCI_OGF_VENDOR, 0x05),
192
		    &version, sizeof(version)) != USB_ERR_NORMAL_COMPLETION)
193
			return (ENXIO);
194
		if (version.fw_variant != 0x23)
195
			return (ENXIO);
196
		break;
197
198
	default:
199
		KASSERT(0 == 1, ("Unknown DRIVER_INFO"));
200
	}
133
201
134
	return (BUS_PROBE_DEFAULT);
202
	return (BUS_PROBE_DEFAULT);
135
}
203
}
Lines 145-159 static device_method_t ubt_intel_methods[] = Link Here
145
	DEVMETHOD_END
213
	DEVMETHOD_END
146
};
214
};
147
215
148
static kobj_class_t ubt_baseclasses[] = { &ubt_driver, NULL };
216
DEFINE_CLASS_1(ubt, ubt_intel_driver, ubt_intel_methods,
149
static driver_t		ubt_intel_driver =
217
    sizeof(struct ubt_softc), ubt_driver);
150
{
151
	.name =	   "ubt",
152
	.methods = ubt_intel_methods,
153
	.size =	   sizeof(struct ubt_softc),
154
	.baseclasses = ubt_baseclasses,
155
};
156
157
DRIVER_MODULE(ng_ubt_intel, uhub, ubt_intel_driver, ubt_devclass, 0, 0);
218
DRIVER_MODULE(ng_ubt_intel, uhub, ubt_intel_driver, ubt_devclass, 0, 0);
158
MODULE_VERSION(ng_ubt_intel, NG_BLUETOOTH_VERSION);
219
MODULE_VERSION(ng_ubt_intel, NG_BLUETOOTH_VERSION);
159
MODULE_DEPEND(ng_ubt_intel, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
220
MODULE_DEPEND(ng_ubt_intel, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
(-)b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h (+4 lines)
Lines 102-107 struct ubt_hci_event_command_compl { Link Here
102
} __attribute__ ((packed));
102
} __attribute__ ((packed));
103
#define	UBT_HCI_EVENT_SIZE(evt) \
103
#define	UBT_HCI_EVENT_SIZE(evt) \
104
	((evt)->header.length + offsetof(struct ubt_hci_event, data))
104
	((evt)->header.length + offsetof(struct ubt_hci_event, data))
105
#define	UBT_HCI_EVENT_COMPL_HEAD_SIZE \
106
	(offsetof(struct ubt_hci_event_command_compl, data) - \
107
	 offsetof(struct ubt_hci_event_command_compl, numpkt))
108
105
109
106
/* USB device softc structure */
110
/* USB device softc structure */
107
struct ubt_softc {
111
struct ubt_softc {

Return to bug 228787