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 <jmcne...@invisible.ca>
+ * 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 <jmcne...@invisible.ca>
+ * 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 */

Reply via email to