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

Collapse All | Expand All

(-)b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c (-2 / +166 lines)
Lines 252-257 static struct ng_type typestruct = Link Here
252
 ****************************************************************************/
252
 ****************************************************************************/
253
253
254
/* USB methods */
254
/* USB methods */
255
static usb_callback_t	ubt_probe_intr_callback;
255
static usb_callback_t	ubt_ctrl_write_callback;
256
static usb_callback_t	ubt_ctrl_write_callback;
256
static usb_callback_t	ubt_intr_read_callback;
257
static usb_callback_t	ubt_intr_read_callback;
257
static usb_callback_t	ubt_bulk_read_callback;
258
static usb_callback_t	ubt_bulk_read_callback;
Lines 421-426 static const STRUCT_USB_HOST_ID ubt_ignore_devs[] = Link Here
421
	/* Atheros AR5BBU12 with sflash firmware */
422
	/* Atheros AR5BBU12 with sflash firmware */
422
	{ USB_VPI(0x0489, 0xe03c, 0), USB_DEV_BCD_LTEQ(1) },
423
	{ USB_VPI(0x0489, 0xe03c, 0), USB_DEV_BCD_LTEQ(1) },
423
	{ USB_VPI(0x0489, 0xe036, 0), USB_DEV_BCD_LTEQ(1) },
424
	{ USB_VPI(0x0489, 0xe036, 0), USB_DEV_BCD_LTEQ(1) },
425
426
	/* Intel Wireless 8260/8265 and successors */
427
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0a2b, UBT_INTEL8265) },
428
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0aaa, UBT_INTEL8265) },
429
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0025, UBT_INTEL8265) },
430
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0026, UBT_INTEL8265) },
431
	{ USB_VPI(USB_VENDOR_INTEL2, 0x0029, UBT_INTEL8265) },
424
};
432
};
425
433
426
/* List of supported bluetooth devices */
434
/* List of supported bluetooth devices */
Lines 502-507 static const STRUCT_USB_HOST_ID ubt_devs[] = Link Here
502
	{ USB_VPI(USB_VENDOR_DELL, 0x8197, 0) },
510
	{ USB_VPI(USB_VENDOR_DELL, 0x8197, 0) },
503
};
511
};
504
512
513
/*
514
 * Does a synchronous (waits for completion event) execution of HCI command.
515
 * Size of both command and response buffers are passed in length field of
516
 * corresponding structures in "Parameter Total Length" format i.e.
517
 * not including HCI packet headers.
518
 *
519
 * Must not be used after USB transfers have been configured in attach routine.
520
 */
521
522
static usb_error_t
523
ubt_do_hci_request(struct usb_device *udev, struct ubt_hci_cmd *cmd,
524
    struct ubt_hci_event *evt, usb_timeout_t timeout)
525
{
526
	static const struct usb_config ubt_probe_config = {
527
		.type = UE_INTERRUPT,
528
		.endpoint = UE_ADDR_ANY,
529
		.direction = UE_DIR_IN,
530
		.flags = { .pipe_bof = 1, .short_xfer_ok = 1 },
531
		.bufsize = UBT_INTR_BUFFER_SIZE,
532
		.callback = &ubt_probe_intr_callback,
533
	};
534
	struct usb_device_request req;
535
	struct usb_xfer *xfer[1];
536
	struct mtx mtx;
537
	usb_error_t error = USB_ERR_NORMAL_COMPLETION;
538
	uint8_t iface_index = 0;
539
540
	/* Initialize a USB control request and then do it */
541
	bzero(&req, sizeof(req));
542
	req.bmRequestType = UBT_HCI_REQUEST;
543
	req.wIndex[0] = iface_index;
544
	USETW(req.wLength, UBT_HCI_CMD_SIZE(cmd));
545
546
	error = usbd_do_request(udev, NULL, &req, cmd);
547
	if (error != USB_ERR_NORMAL_COMPLETION) {
548
		printf("ng_ubt: usbd_do_request error=%s\n",
549
			usbd_errstr(error));
550
		return (error);
551
	}
552
553
	if (evt == NULL)
554
		return (USB_ERR_NORMAL_COMPLETION);
555
556
	/* Initialize INTR endpoint xfer and wait for response */
557
	mtx_init(&mtx, "ubt pb", NULL, MTX_DEF);
558
559
	error = usbd_transfer_setup(udev, &iface_index, xfer,
560
	    &ubt_probe_config, 1, evt, &mtx);
561
	if (error == USB_ERR_NORMAL_COMPLETION) {
562
563
		mtx_lock(&mtx);
564
		usbd_transfer_start(*xfer);
565
566
		if (msleep_sbt(evt, &mtx, 0, "ubt pb", SBT_1MS * timeout,
567
				0, C_HARDCLOCK) == EWOULDBLOCK) {
568
			printf("ng_ubt: HCI command 0x%04x timed out\n",
569
				le16toh(cmd->opcode));
570
			error = USB_ERR_TIMEOUT;
571
		}
572
573
		usbd_transfer_stop(*xfer);
574
		mtx_unlock(&mtx);
575
576
		usbd_transfer_unsetup(xfer, 1);
577
	} else
578
		printf("ng_ubt: usbd_transfer_setup error=%s\n",
579
			usbd_errstr(error));
580
581
	mtx_destroy(&mtx);
582
583
	return (error);
584
}
585
586
/*
587
 * Find if the Intel Wireless 8260/8265 device is in bootloader mode or is
588
 * running operational firmware with checking of 7-th byte "Intel version"
589
 * HCI command response. The value 0x23 identifies the operational firmware.
590
 * Attempt to initialize bluetooth stack while device is in bootloader mode
591
 * (7-th byte is 0x06) locks the adapter hardly and requires power on/off
592
 * cycle to restore.
593
 */
594
595
static bool
596
ubt_check_intel8265_firmware_state(struct usb_device *udev)
597
{
598
#define	UBT_INTEL_VER_LEN		13
599
#define UBT_INTEL_HCICMD_TIMEOUT	2000	/* ms */
600
	struct ubt_hci_event *evt;
601
	uint8_t buf[offsetof(struct ubt_hci_event, data) + UBT_INTEL_VER_LEN];
602
	static struct ubt_hci_cmd cmd = {
603
		.opcode = htole16(NG_HCI_OPCODE(NG_HCI_OGF_VENDOR, 0x05)),
604
		.length = 0,
605
	};
606
	usb_error_t error;
607
608
	bzero(buf, sizeof(buf));
609
	evt = (struct ubt_hci_event *)buf;
610
	evt->length = UBT_INTEL_VER_LEN;
611
612
	error = ubt_do_hci_request(udev, &cmd, evt, UBT_INTEL_HCICMD_TIMEOUT);
613
	if (error != USB_ERR_NORMAL_COMPLETION)
614
		return false;
615
616
	return (evt->event == NG_HCI_EVENT_COMMAND_COMPL &&
617
		evt->length == UBT_INTEL_VER_LEN &&
618
		evt->data[7] == 0x23);
619
}
620
505
/*
621
/*
506
 * Probe for a USB Bluetooth device.
622
 * Probe for a USB Bluetooth device.
507
 * USB context.
623
 * USB context.
Lines 520-527 ubt_probe(device_t dev) Link Here
520
		return (ENXIO);
636
		return (ENXIO);
521
637
522
	if (usbd_lookup_id_by_uaa(ubt_ignore_devs,
638
	if (usbd_lookup_id_by_uaa(ubt_ignore_devs,
523
			sizeof(ubt_ignore_devs), uaa) == 0)
639
			sizeof(ubt_ignore_devs), uaa) == 0) {
524
		return (ENXIO);
640
		if ((USB_GET_DRIVER_INFO(uaa) & UBT_INTEL8265) != 0) {
641
			if (!ubt_check_intel8265_firmware_state(uaa->device))
642
				return (ENXIO);
643
		} else
644
			return (ENXIO);
645
	}
525
646
526
	error = usbd_lookup_id_by_uaa(ubt_devs, sizeof(ubt_devs), uaa);
647
	error = usbd_lookup_id_by_uaa(ubt_devs, sizeof(ubt_devs), uaa);
527
	if (error == 0)
648
	if (error == 0)
Lines 717-722 ubt_detach(device_t dev) Link Here
717
	return (0);
838
	return (0);
718
} /* ubt_detach */
839
} /* ubt_detach */
719
840
841
/*
842
 * Called when incoming interrupt transfer (HCI event) has completed, i.e.
843
 * HCI event was received from the device during device probe stage.
844
 * USB context.
845
 */
846
847
static void
848
ubt_probe_intr_callback(struct usb_xfer *xfer, usb_error_t error)
849
{
850
	struct ubt_hci_event	*evt = usbd_xfer_softc(xfer);
851
	struct usb_page_cache	*pc;
852
	int			actlen;
853
854
	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
855
856
	switch (USB_GET_STATE(xfer)) {
857
	case USB_ST_TRANSFERRED:
858
		if (actlen > UBT_HCI_EVENT_SIZE(evt))
859
			actlen = UBT_HCI_EVENT_SIZE(evt);
860
		pc = usbd_xfer_get_frame(xfer, 0);
861
		usbd_copy_out(pc, 0, evt, actlen);
862
		/* OneShot mode */
863
		wakeup(evt);
864
		break;
865
866
	case USB_ST_SETUP:
867
submit_next:
868
		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
869
		usbd_transfer_submit(xfer);
870
		break;
871
872
	default:
873
		if (error != USB_ERR_CANCELLED) {
874
			printf("ng_ubt: interrupt transfer failed: %s\n",
875
				usbd_errstr(error));
876
			/* Try clear stall first */
877
			usbd_xfer_set_stall(xfer);
878
			goto submit_next;
879
		}
880
		break;
881
	}
882
} /* ubt_probe_intr_callback */
883
720
/* 
884
/* 
721
 * Called when outgoing control request (HCI command) has completed, i.e.
885
 * Called when outgoing control request (HCI command) has completed, i.e.
722
 * HCI command was sent to the device.
886
 * HCI command was sent to the device.
(-)b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt_var.h (+21 lines)
Lines 57-62 do { \ Link Here
57
#define	UBT_DEFAULT_QLEN	64
57
#define	UBT_DEFAULT_QLEN	64
58
#define	UBT_ISOC_NFRAMES	32	/* should be factor of 8 */
58
#define	UBT_ISOC_NFRAMES	32	/* should be factor of 8 */
59
59
60
/* USB driver info flags */
61
#define	UBT_INTEL8265	(1 << 0)
62
60
/* Bluetooth USB defines */
63
/* Bluetooth USB defines */
61
enum {
64
enum {
62
	/* Interface #0 transfers */
65
	/* Interface #0 transfers */
Lines 74-79 enum { Link Here
74
	UBT_N_TRANSFER,		/* total number of transfers */
77
	UBT_N_TRANSFER,		/* total number of transfers */
75
};
78
};
76
79
80
/* USB control request (HCI command) structure */
81
struct ubt_hci_cmd {
82
	uint16_t	opcode;
83
	uint8_t		length;
84
	uint8_t		data[];
85
} __attribute__ ((packed));
86
#define	UBT_HCI_CMD_SIZE(cmd) \
87
	((cmd)->length + offsetof(struct ubt_hci_cmd, data))
88
89
/* USB interrupt transfer (HCI event) structure */
90
struct ubt_hci_event {
91
	uint8_t		event;
92
	uint8_t		length;
93
	uint8_t		data[];
94
} __attribute__ ((packed));
95
#define	UBT_HCI_EVENT_SIZE(evt) \
96
	((evt)->length + offsetof(struct ubt_hci_event, data))
97
77
/* USB device softc structure */
98
/* USB device softc structure */
78
struct ubt_softc {
99
struct ubt_softc {
79
	device_t		sc_dev;		/* for debug printf */
100
	device_t		sc_dev;		/* for debug printf */

Return to bug 237083