Module Name: src
Committed By: jmcneill
Date: Thu Aug 10 20:43:12 UTC 2017
Modified Files:
src/usr.sbin/btattach: Makefile init_bcm43xx.c
Added Files:
src/usr.sbin/btattach: firmload.c firmload.h
Log Message:
Derive the firmware name from the device's local name instead of
hard-coding BCM4340A1. Search hw.firmware.path for the firmware image
instead of loading it from the current directory.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/btattach/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.sbin/btattach/firmload.c \
src/usr.sbin/btattach/firmload.h
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/btattach/init_bcm43xx.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/btattach/Makefile
diff -u src/usr.sbin/btattach/Makefile:1.3 src/usr.sbin/btattach/Makefile:1.4
--- src/usr.sbin/btattach/Makefile:1.3 Thu Aug 10 13:34:29 2017
+++ src/usr.sbin/btattach/Makefile Thu Aug 10 20:43:12 2017
@@ -1,10 +1,10 @@
-# $NetBSD: Makefile,v 1.3 2017/08/10 13:34:29 nat Exp $
+# $NetBSD: Makefile,v 1.4 2017/08/10 20:43:12 jmcneill Exp $
PROG= btattach
MAN= btattach.8
-SRCS= btattach.c init_bcm2035.c init_bgb2xx.c init_csr.c init_digi.c \
- init_ericsson.c init_st.c init_stlc2500.c init_swave.c init_unistone.c \
- init_bcm43xx.c
+SRCS= btattach.c firmload.c init_bcm2035.c init_bcm43xx.c init_bgb2xx.c \
+ init_csr.c init_digi.c init_ericsson.c init_st.c init_stlc2500.c \
+ init_swave.c init_unistone.c
DPADD+= ${LIBBLUETOOTH} ${LIBUTIL}
LDADD+= -lbluetooth -lutil
Index: src/usr.sbin/btattach/init_bcm43xx.c
diff -u src/usr.sbin/btattach/init_bcm43xx.c:1.2 src/usr.sbin/btattach/init_bcm43xx.c:1.3
--- src/usr.sbin/btattach/init_bcm43xx.c:1.2 Thu Aug 10 18:45:20 2017
+++ src/usr.sbin/btattach/init_bcm43xx.c Thu Aug 10 20:43:12 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: init_bcm43xx.c,v 1.2 2017/08/10 18:45:20 jakllsch Exp $ */
+/* $NetBSD: init_bcm43xx.c,v 1.3 2017/08/10 20:43:12 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Iain Hibbert
@@ -34,7 +34,9 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: init_bcm43xx.c,v 1.2 2017/08/10 18:45:20 jakllsch Exp $");
+__RCSID("$NetBSD: init_bcm43xx.c,v 1.3 2017/08/10 20:43:12 jmcneill Exp $");
+
+#include <sys/param.h>
#include <bluetooth.h>
#include <err.h>
@@ -46,6 +48,7 @@ __RCSID("$NetBSD: init_bcm43xx.c,v 1.2 2
#include <unistd.h>
#include "btattach.h"
+#include "firmload.h"
#define HCI_CMD_BCM43XX_SET_UART_BAUD_RATE \
HCI_OPCODE(HCI_OGF_VENDOR, 0x018)
@@ -56,25 +59,57 @@ __RCSID("$NetBSD: init_bcm43xx.c,v 1.2 2
#define HCI_CMD_43XXFWDN \
HCI_OPCODE(HCI_OGF_VENDOR, 0x02e)
+#define HCI_CMD_GET_LOCAL_NAME 0x0c14
+
+static int
+bcm43xx_get_local_name(int fd, char *name, size_t namelen)
+{
+ char buf[256];
+ size_t len;
+
+ memset(buf, 0, sizeof(buf));
+
+ uart_send_cmd(fd, HCI_CMD_GET_LOCAL_NAME, NULL, 0);
+ len = uart_recv_cc(fd, HCI_CMD_GET_LOCAL_NAME, buf, sizeof(buf));
+ if (len == 0)
+ return EIO;
+
+ strlcpy(name, &buf[1], MIN(len - 1, namelen));
+
+ if (strlen(name) == 0)
+ return EIO;
+
+ return 0;
+}
+
void
init_bcm43xx(int fd, unsigned int speed)
{
uint8_t rate[6];
uint8_t fw_buf[1024];
- char fw[] = "./BCM43430A1.hcd";
int fwfd, fw_len;
uint8_t resp[7];
uint16_t fw_cmd;
+ char local_name[256];
+ char fw[260];
memset(rate, 0, sizeof(rate));
+ memset(local_name, 0, sizeof(local_name));
uart_send_cmd(fd, HCI_CMD_RESET, NULL, 0);
uart_recv_cc(fd, HCI_CMD_RESET, &resp, sizeof(resp));
/* assume it succeeded? */
- fwfd = open(fw, O_RDONLY);
+ if (bcm43xx_get_local_name(fd, local_name, sizeof(local_name)) != 0) {
+ fprintf(stderr, "Couldn't read local name\n");
+ return;
+ }
+ snprintf(fw, sizeof(fw), "%s.hcd", local_name);
+
+ fwfd = firmware_open("bcm43xx", fw);
if (fwfd < 0) {
- fprintf(stderr, "Unable to open firmware: %s\n", fw);
+ fprintf(stderr, "Unable to open firmware bcm43xx/%s: %s\n",
+ fw, strerror(errno));
return;
}
Added files:
Index: src/usr.sbin/btattach/firmload.c
diff -u /dev/null src/usr.sbin/btattach/firmload.c:1.1
--- /dev/null Thu Aug 10 20:43:12 2017
+++ src/usr.sbin/btattach/firmload.c Thu Aug 10 20:43:12 2017
@@ -0,0 +1,84 @@
+/* $NetBSD: firmload.c,v 1.1 2017/08/10 20:43:12 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared McNeill <[email protected]>
+ * 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 ``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 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.
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "firmload.h"
+
+#define HW_FIRMWARE_PATH "hw.firmware.path"
+#define HW_FIRMWARE_PATH_DELIM ":"
+
+static int
+firmware_search(char *paths, const char *drvname, const char *imgname)
+{
+ char *p, *f;
+ const int debug = getenv("FIRMWARE_DEBUG") != NULL;
+ int fd;
+
+ p = strtok(paths, HW_FIRMWARE_PATH_DELIM);
+ while (p) {
+ if (asprintf(&f, "%s/%s/%s", p, drvname, imgname) == -1)
+ return -1;
+ if (debug)
+ printf("%s: trying %s...\n", __func__, f);
+ fd = open(f, O_RDONLY);
+ free(f);
+ if (fd != -1) {
+ if (debug)
+ printf("%s: using image at %s\n", __func__, f);
+ return fd;
+ }
+ p = strtok(NULL, HW_FIRMWARE_PATH_DELIM);
+ }
+
+ /* Not found */
+ return -1;
+}
+
+int
+firmware_open(const char *drvname, const char *imgname)
+{
+ size_t len;
+ char *paths;
+ int fd;
+
+ paths = asysctlbyname(HW_FIRMWARE_PATH, &len);
+ if (paths == NULL)
+ return -1;
+
+ fd = firmware_search(paths, drvname, imgname);
+
+ free(paths);
+
+ return fd;
+}
Index: src/usr.sbin/btattach/firmload.h
diff -u /dev/null src/usr.sbin/btattach/firmload.h:1.1
--- /dev/null Thu Aug 10 20:43:12 2017
+++ src/usr.sbin/btattach/firmload.h Thu Aug 10 20:43:12 2017
@@ -0,0 +1,44 @@
+/* $NetBSD: firmload.h,v 1.1 2017/08/10 20:43:12 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared McNeill <[email protected]>
+ * 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 ``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 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.
+ */
+
+#ifndef _HAVE_FIRMLOAD_H
+#define _HAVE_FIRMLOAD_H
+
+/*
+ * firmware_open(drvname, imgname)
+ *
+ * Open the firmware image specified by the second parameter for the driver
+ * specified by the first parameter. The path to the firmware file is created
+ * by appending the string "/drvname/imgname" each path in the sysctl node
+ * hw.firmware.path until opening the firmware image succeeds.
+ *
+ * Returns a file descriptor on success, and -1 on failure.
+ */
+int firmware_open(const char *, const char *);
+
+#endif /* !_HAVE_FIRMLOAD_H */