Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/btattach Derive the firmware name from the device's...
details: https://anonhg.NetBSD.org/src/rev/1e741043518c
branches: trunk
changeset: 355710:1e741043518c
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Thu Aug 10 20:43:12 2017 +0000
description:
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.
diffstat:
usr.sbin/btattach/Makefile | 8 +-
usr.sbin/btattach/firmload.c | 84 ++++++++++++++++++++++++++++++++++++++++
usr.sbin/btattach/firmload.h | 44 ++++++++++++++++++++
usr.sbin/btattach/init_bcm43xx.c | 45 +++++++++++++++++++--
4 files changed, 172 insertions(+), 9 deletions(-)
diffs (243 lines):
diff -r 27a841dc0826 -r 1e741043518c usr.sbin/btattach/Makefile
--- a/usr.sbin/btattach/Makefile Thu Aug 10 19:42:53 2017 +0000
+++ b/usr.sbin/btattach/Makefile Thu Aug 10 20:43:12 2017 +0000
@@ -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
diff -r 27a841dc0826 -r 1e741043518c usr.sbin/btattach/firmload.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.sbin/btattach/firmload.c Thu Aug 10 20:43:12 2017 +0000
@@ -0,0 +1,84 @@
+/* $NetBSD: firmload.c,v 1.1 2017/08/10 20:43:12 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
+ * 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;
+}
diff -r 27a841dc0826 -r 1e741043518c usr.sbin/btattach/firmload.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.sbin/btattach/firmload.h Thu Aug 10 20:43:12 2017 +0000
@@ -0,0 +1,44 @@
+/* $NetBSD: firmload.h,v 1.1 2017/08/10 20:43:12 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
+ * 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 */
diff -r 27a841dc0826 -r 1e741043518c usr.sbin/btattach/init_bcm43xx.c
--- a/usr.sbin/btattach/init_bcm43xx.c Thu Aug 10 19:42:53 2017 +0000
+++ b/usr.sbin/btattach/init_bcm43xx.c Thu Aug 10 20:43:12 2017 +0000
@@ -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 @@
#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 @@
#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;
}
Home |
Main Index |
Thread Index |
Old Index