Broadcom BCM2046B1 in HCI mode?

Brandon Gooch jamesbrandongooch at gmail.com
Sun Jun 26 15:56:42 UTC 2011


On Sat, Jun 25, 2011 at 11:51 PM, Hans Petter Selasky <hselasky at c2i.net> wrote:
> On Sunday 26 June 2011 05:46:35 Brandon Gooch wrote:
>> On Wed, Jun 22, 2011 at 11:17 AM, Maksim Yevmenkin
>>
>> <maksim.yevmenkin at gmail.com> wrote:
>> > On Tuesday, June 21, 2011, Brandon Gooch <jamesbrandongooch at gmail.com>
> wrote:
>> >> I have one of these in my notebook:
>> >>
>> >> uhub4: <Broadcom BCM2046B1, class 9/0, rev 2.00/1.00, addr 5> on usbus0
>> >>
>> >> This is a bluetooth device in HID mode, but I'd like to switch it to
>> >> HCI mode. I found the following in rc.conf(5):
>> >>
>> >>      ubthidhci_enable
>> >>                  (bool) If set to ``YES'', change the USB Bluetooth
>> >> controller from HID mode to HCI mode.  You also need to specify the
>> >> location of USB Bluetooth controller with the
>> >>                  ubthidhci_busnum and ubthidhci_addr variables.
>> >>
>> >>      ubthidhci_busnum
>> >>                  Bus number where the USB Bluetooth controller is
>> >> located. Check the output of usbconfig(8) on your system to find this
>> >> information.
>> >>
>> >>      ubthidhci_addr
>> >>                  Bus address of the USB Bluetooth controller.  Check the
>> >> out- put of usbconfig(8) on your system to find this information.
>> >>
>> >> So I added the appropriate directives to /etc/rc.conf, to no avail:
>> >>
>> >> ubthidhci_enable="YES"
>> >> ubthidhci_busnum="0"
>> >> ubthidhci_addr="5"
>> >>
>> >> This basically calls usbconfig(8) at system start-up in the following
>> >> way:
>> >>
>> >> /usr/sbin/usbconfig -u 0 -a 5 do_request 0x40 0 0 0 0 > /dev/null 2>&1
>> >>
>> >> Running this command manually, I see this output:
>> >>
>> >> REQUEST = <ERROR>
>> >>
>> >> ...which I've read as potentially being OK, as the operation still may
>> >> have successfully completed -- it hasn't :(
>> >>
>> >> So, has anyone had any luck using this rc.conf(5) directive, or does
>> >> anyone on this list have a modified usbconfig(8) command that may help
>> >> me coax HCI from this device?
>> >
>> > Switching device between hid and hci modes is s something that is
>> > device / manufacturer specific. It could be that this particular
>> > device need different request or something like that. I would suggest
>> > to look at linux tool called hid2hci. It has support for different
>> > devices from different manufacturers.
>> >
>> > Thanks,
>> > Max
>>
>> That was an excellent suggestion, so I went and checked it out. In
>> fact, I verified that it indeed does the trick in a couple of recent
>> Linux distros.
>>
>> So can someone help me decipher the byte sequence I need to provide to
>> usbconfig(8)?
>>
>> The hid2hci utility has this function defined for dealing with the
>> device in question:
>>
>> http://git.kernel.org/?p=bluetooth/bluez.git;a=blob;f=tools/hid2hci.c;h=45a
>> 3a3db8b29411ee193e480f5ce8a82a40103d1;hb=7822123d08b176ef8b3e8aaecbc3c8ff25
>> a33483#l122
>>
>> static int usb_switch_dell(struct usb_dev_handle *dev, enum mode mode)
>> ...
>>         char report[] = { 0x7f, 0x00, 0x00, 0x00 };
>> ...
>>         report[1] = 0x13;
>> ....
>>         err = usb_control_msg(dev,
>>             USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
>>             USB_REQ_SET_CONFIGURATION, 0x7f | (0x03 << 8), 0,
>>             report, sizeof(report), 5000);
>> ...
>>
>> And according to:
>>
>> http://lxr.linux.no/#linux+v2.6.39/include/linux/usb.h#L1400
>>
>> usb_control_msg() is prototyped:
>>
>> extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
>>          __u8 request, __u8 requesttype, __u16 value, __u16 index,
>>          void *data, __u16 size, int timeout);
>>
>> ...and I'd like to know what this means in terms of the following
>> (from src/usr.sbin/usbconfig/usbconfig.c):
>>
>> libusb20_dev_request_sync(pdev, &opt->setup,
>>     opt->buffer, &actlen, 5000 /* 5 seconds */ , 0))
>>
>> which is prototyped as:
>>
>> libusb20_dev_request_sync(struct libusb20_device *pdev,
>>          struct LIBUSB20_CONTROL_SETUP_DECODED *setup, void *data,
>>          uint16_t *pactlen, uint32_t timeout, uint8_t flags);
>>
>> I'm looking for something like the following:
>>
>> # usbconfig -u 0 -a 5 do_request 0x37f 0x13 0 0 0
>>
>> However, this isn't correct I know, but I could use some help sorting
>> it out -- any takers?
>>
>
> Hi,
>
> Try this:
>
> usbconfig -d X.Y do_request 0x21 0x09 0x037f 0x0000 0x04 0x7f 0x13 0x00 0x00
>
> --HPS

It worked, albeit after addressing the correct ugen(4) device:

dmesg(8):
...
ugen0.7: <vendor 0x413c> at usbus0
...

Then:
# usbconfig -d ugen0.7 do_request 0x21 0x09 0x037f 0x0000 0x04 0x7f
0x13 0x00 0x00

dmesg(8):
...
ugen0.8: <Dell Computer Corp> at usbus0
...

And after:

# kldload ng_ubt

dmesg(8):

ubt0: <Dell Computer Corp Dell Wireless 365 Bluetooth Module, class
224/1, rev 2.00/1.73, addr 8> on usbus0

For now, can we add another (optional) parameter for rc.conf, to allow
an override of the do_request parameters?

So, in /etc/rc.d/ubthidhci, we could pass a value in $ubthidhci_req
(or whatever) that could be worked into:

command_args="-u ${ubthidhci_busnum} -a ${ubthidhci_addr} do_request
${ubthidhci_req} > /dev/null 2>&1"

Further, we could document known devices somewhere, allowing users to
select the appropriate values themselves -- maybe even in the form of:

ubthidhci_enable="YES"
ubthidhci_busnum="0"
ubthidhci_addr="7"
ubthidhci_devtype="BCM2046B1"

Hans, I don't see an easy way to automate any of this for now,
although you're working on an auto-configuration system for USB
devices (possibly to be generalized for other devices later). Can this
be a facet of that system?

Thanks for the help everyone!

-Brandon


More information about the freebsd-bluetooth mailing list