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