diff options
-rw-r--r-- | usr.sbin/bluetooth/bcmfw/BCM-LEGAL.txt | 8 | ||||
-rw-r--r-- | usr.sbin/bluetooth/bcmfw/Makefile | 23 | ||||
-rw-r--r-- | usr.sbin/bluetooth/bcmfw/README | 23 | ||||
-rw-r--r-- | usr.sbin/bluetooth/bcmfw/bcmfw.8 | 96 | ||||
-rw-r--r-- | usr.sbin/bluetooth/bcmfw/bcmfw.c | 305 |
5 files changed, 455 insertions, 0 deletions
diff --git a/usr.sbin/bluetooth/bcmfw/BCM-LEGAL.txt b/usr.sbin/bluetooth/bcmfw/BCM-LEGAL.txt new file mode 100644 index 000000000000..e3a235e0d82e --- /dev/null +++ b/usr.sbin/bluetooth/bcmfw/BCM-LEGAL.txt @@ -0,0 +1,8 @@ +$FreeBSD$ + +BCM firmware version 2.15 +Copyright (c) 2000-2002 Broadcom Corporation + +Permission to distribute from.. +Contact info: + bluetooth_help@broadcom.com diff --git a/usr.sbin/bluetooth/bcmfw/Makefile b/usr.sbin/bluetooth/bcmfw/Makefile new file mode 100644 index 000000000000..45d1c5f761b2 --- /dev/null +++ b/usr.sbin/bluetooth/bcmfw/Makefile @@ -0,0 +1,23 @@ +# $Id: Makefile,v 1.2 2003/04/27 00:44:54 max Exp $ +# $FreeBSD$ + +DESTDIR= /usr/sbin/ +MANDIR= ../share/man/man +PROG= bcmfw +MAN8= bcmfw.8 +WARNS?= 2 +CFLAGS+= -g -I${.CURDIR}/../../../sys/netgraph/bluetooth/include +SRCS= bcmfw.c + +FILESDIR= ../local/etc/ +FILES+= BCM2033-FW.bin BCM2033-MD.hex +CLEANFILES+= BCM2033-FW.bin BCM2033-MD.hex + +BCM2033-FW.bin: BCM2033-FW.bin.uue + uudecode BCM2033-FW.bin.uue + +BCM2033-MD.hex: BCM2033-MD.hex.uue + uudecode BCM2033-MD.hex.uue + +.include <bsd.prog.mk> +.include <bsd.files.mk> diff --git a/usr.sbin/bluetooth/bcmfw/README b/usr.sbin/bluetooth/bcmfw/README new file mode 100644 index 000000000000..c5a733621503 --- /dev/null +++ b/usr.sbin/bluetooth/bcmfw/README @@ -0,0 +1,23 @@ +$FreeBSD$ + +This directory is not complete until the legal status of the firmware +files that go here is confirmed. + +It WILL look like: +total 190 +drwxr-xr-x 3 julian wheel 512 May 10 00:40 . +drwxr-xr-x 11 julian wheel 512 May 10 14:48 .. +-rw-r--r-- 1 julian wheel 154 May 10 00:41 BCM-LEGAL.txt +-rw-r--r-- 1 julian wheel 56 May 10 00:14 BCM2033-FW.bin.md5 +-rw-r--r-- 1 julian wheel 158049 May 10 00:14 BCM2033-FW.bin.uue +-rw-r--r-- 1 julian wheel 56 May 10 00:14 BCM2033-MD.hex.md5 +-rw-r--r-- 1 julian wheel 4505 May 10 00:14 BCM2033-MD.hex.uue +drwxr-xr-x 2 julian wheel 512 May 10 00:52 CVS +-rw-r--r-- 1 julian wheel 516 May 10 00:14 Makefile +-rw-r--r-- 1 julian wheel 3013 May 10 00:14 bcmfw.8 +-rw-r--r-- 1 julian wheel 6806 May 10 00:14 bcmfw.c + +The extra files can be fetched from + http://bluez.sourceforge.net/download/bluez-bluefw-0.9.tar.gz + + diff --git a/usr.sbin/bluetooth/bcmfw/bcmfw.8 b/usr.sbin/bluetooth/bcmfw/bcmfw.8 new file mode 100644 index 000000000000..945fb21987a3 --- /dev/null +++ b/usr.sbin/bluetooth/bcmfw/bcmfw.8 @@ -0,0 +1,96 @@ +.\" bcmfw.8 +.\" +.\" Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: bcmfw.8,v 1.4 2003/04/28 17:10:56 max Exp $ +.\" $FreeBSD$ +.Dd March 31, 2003 +.Dt BCMFW 8 +.Os +.Sh NAME +.Nm BCMFW +.Nd Firmware download utility for Broadcom BCM2033 chip based Bluetooth USB devices +.Sh SYNOPSIS +.Nm +.Op Fl n Ar device name +.Op Fl m Ar mini-driver file name +.Op Fl f Ar firmware file name +.Op Fl h +.Sh DESCRIPTION +The +.Nm +utility downloads specified mini-driver and firmware files to the specified +device. +.Pp +This utility will +.Em only +work with Broadcom BCM2033 chip based Bluetooth USB devices. The identification +is currently based on USB vendor ID/product ID pair. The vendor ID should be +0x0a5c ( +.Dv USB_VENDOR_BROADCOM +) and the product ID should be 0x2033. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl n Ar device name +Specify device name. +.It Fl m Ar mini-driver file name +Specify mini-driver file name for download. +.It Fl f Ar firmware file name +Specify firmware file name for download. +.It Fl h +Display usage message and exit. +.El +.Sh FILES +.Bl -tag -width xxxxxxxxxxxxxxxxx -compact +.It BCM2033-MD.hex +Mini-driver image. +.It BCM2033-FW.bin +Firmware image. +.It Pa /dev/ubtbcmfw Ns Ar N Ns Pa \&. Ns Ar EE +Endpoint +.Ar EE +of device +.Ar N . +.El +.Sh Examples +.Bl -tag -width foo +.It bcmfw -n ubtbcmfw0 -m BCM2033-MD.hex -f BCM2033-FW.bin +.Pp +Will download firmware into +.Pa /dev/ubtbcmfw Ns Ar 0 +device. +.El +.Sh BUGS +Most likely. Please report if found. This code +.Em was not +tested on a real BCM2033 based hardware. +.Sh DIAGNOSTICS +.Ex -std +.Sh SEE ALSO +.Xr ugen 4 , +.Xr ubtbcmfw 4 +.Sh AUTHORS +.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com diff --git a/usr.sbin/bluetooth/bcmfw/bcmfw.c b/usr.sbin/bluetooth/bcmfw/bcmfw.c new file mode 100644 index 000000000000..e21c10ca35ac --- /dev/null +++ b/usr.sbin/bluetooth/bcmfw/bcmfw.c @@ -0,0 +1,305 @@ +/* + * bcmfw.c + * + * Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: bcmfw.c,v 1.4 2003/04/27 19:28:09 max Exp $ + * $FreeBSD$ + * + * Based on Linux BlueZ BlueFW-0.9 package + * + */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <dev/usb/usb.h> +#include <dev/usb/usbdevs.h> +#include <errno.h> +#include <fcntl.h> +#include <netgraph.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#define BCMFW "bcmfw" +#define BCMFW_INTR_EP 1 +#define BCMFW_BULK_EP 2 +#define BCMFW_BSIZE 4096 + +static int bcmfw_check_device + (char const *name); +static int bcmfw_load_firmware + (char const *name, char const *md, char const *fw); +static void bcmfw_usage + (void); + +/* + * Main + */ + +int +main(int argc, char *argv[]) +{ + char *name = NULL, *md = NULL, *fw = NULL; + int x; + + while ((x = getopt(argc, argv, "f:hn:m:")) != -1) { + switch (x) { + case 'f': /* firmware file */ + fw = optarg; + break; + + case 'n': /* name */ + name = optarg; + break; + + case 'm': /* Mini-driver */ + md = optarg; + break; + + case 'h': + default: + bcmfw_usage(); + /* NOT REACHED */ + } + } + + if (name == NULL || md == NULL || fw == NULL) + bcmfw_usage(); + /* NOT REACHED */ + + openlog(BCMFW, LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_USER); + + if (bcmfw_check_device(name) < 0) + exit(1); + + if (bcmfw_load_firmware(name, md, fw) < 0) + exit(1); + + closelog(); + + return (0); +} /* main */ + +/* + * Check device VendorID/ProductID + */ + +static int +bcmfw_check_device(char const *name) +{ + usb_device_descriptor_t desc; + char path[BCMFW_BSIZE]; + int fd = -1, error = -1; + + snprintf(path, sizeof(path), "/dev/%s", name); + + if ((fd = open(path, O_WRONLY)) < 0) { + syslog(LOG_ERR, "Could not open(%s). %s (%d)", + path, strerror(errno), errno); + goto out; + } + + if (ioctl(fd, USB_GET_DEVICE_DESC, &desc) < 0) { + syslog(LOG_ERR, "Could not ioctl(%d, %ld, %p). %s (%d)", + fd, USB_GET_DEVICE_DESC, &desc, + strerror(errno), errno); + goto out; + } + + if (UGETW(desc.idVendor) != USB_VENDOR_BROADCOM || + UGETW(desc.idProduct) != 0x2033) { + syslog(LOG_ERR, "Unsupported device, VendorID=%#x, " \ + "ProductID=%#x", UGETW(desc.idVendor), + UGETW(desc.idProduct)); + error = -1; + } else + error = 0; +out: + if (fd != -1) + close(fd); + + return (error); +} /* bcmfw_check_device */ + +/* + * Download minidriver and firmware + */ + +static int +bcmfw_load_firmware(char const *name, char const *md, char const *fw) +{ + char buf[BCMFW_BSIZE]; + int intr = -1, bulk = -1, fd = -1, error = -1, len; + + /* Open interrupt endpoint device */ + snprintf(buf, sizeof(buf), "/dev/%s.%d", name, BCMFW_INTR_EP); + if ((intr = open(buf, O_RDONLY)) < 0) { + syslog(LOG_ERR, "Could not open(%s). %s (%d)", + buf, strerror(errno), errno); + goto out; + } + + /* Open bulk endpoint device */ + snprintf(buf, sizeof(buf), "/dev/%s.%d", name, BCMFW_BULK_EP); + if ((bulk = open(buf, O_WRONLY)) < 0) { + syslog(LOG_ERR, "Could not open(%s). %s (%d)", + buf, strerror(errno), errno); + goto out; + } + + /* + * Load mini-driver + */ + + if ((fd = open(md, O_RDONLY)) < 0) { + syslog(LOG_ERR, "Could not open(%s). %s (%d)", + md, strerror(errno), errno); + goto out; + } + + for (;;) { + len = read(fd, buf, sizeof(buf)); + if (len < 0) { + syslog(LOG_ERR, "Could not read(%s). %s (%d)", + md, strerror(errno), errno); + goto out; + } + if (len == 0) + break; + + len = write(bulk, buf, len); + if (len < 0) { + syslog(LOG_ERR, "Could not write(/dev/%s.%d). %s (%d)", + name, BCMFW_BULK_EP, strerror(errno), + errno); + goto out; + } + } + + close(fd); + fd = -1; + + usleep(10); + + /* + * Memory select + */ + + if (write(bulk, "#", 1) < 0) { + syslog(LOG_ERR, "Could not write(/dev/%s.%d). %s (%d)", + name, BCMFW_BULK_EP, strerror(errno), errno); + goto out; + } + + if (read(intr, buf, sizeof(buf)) < 0) { + syslog(LOG_ERR, "Could not read(/dev/%s.%d). %s (%d)", + name, BCMFW_INTR_EP, strerror(errno), errno); + goto out; + } + + if (buf[0] != '#') { + syslog(LOG_ERR, "%s: Memory select failed (%c)", name, buf[0]); + goto out; + } + + /* + * Load firmware + */ + + if ((fd = open(fw, O_RDONLY)) < 0) { + syslog(LOG_ERR, "Could not open(%s). %s (%d)", + fw, strerror(errno), errno); + goto out; + } + + for (;;) { + len = read(fd, buf, sizeof(buf)); + if (len < 0) { + syslog(LOG_ERR, "Could not read(%s). %s (%d)", + fw, strerror(errno), errno); + goto out; + } + if (len == 0) + break; + + len = write(bulk, buf, len); + if (len < 0) { + syslog(LOG_ERR, "Could not write(/dev/%s.%d). %s (%d)", + name, BCMFW_BULK_EP, strerror(errno), + errno); + goto out; + } + } + + close(fd); + fd = -1; + + if (read(intr, buf, sizeof(buf)) < 0) { + syslog(LOG_ERR, "Could not read(/dev/%s.%d). %s (%d)", + name, BCMFW_INTR_EP, strerror(errno), errno); + goto out; + } + + if (buf[0] != '.') { + syslog(LOG_ERR, "%s: Could not load firmware (%c)", + name, buf[0]); + goto out; + } + + usleep(500000); + error = 0; +out: + if (fd != -1) + close(fd); + if (bulk != -1) + close(bulk); + if (intr != -1) + close(intr); + + return (error); +} /* bcmfw_load_firmware */ + +/* + * Display usage message and quit + */ + +static void +bcmfw_usage(void) +{ + fprintf(stdout, +"Usage: %s -n name -m md_file -f fw_file\n" +"Where:\n" \ +"\t-n name device name\n" \ +"\t-m mini-driver image mini-driver image file name for download\n" \ +"\t-f firmware image firmware image file name for download\n" \ +"\t-h display this message\n", BCMFW); + + exit(255); +} /* bcmfw_usage */ + |