From 166ed96648e982c164f333ae18c4f88732323ba0 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Tue, 11 Jul 2017 10:24:49 +0200 Subject: [PATCH 001/113] meta-digi-dey: bump distro version to 2.2-r3 Signed-off-by: Javier Viguera --- README.md | 6 +++++- meta-digi-dey/conf/distro/dey.conf | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2506de35..1df6888d6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Digi Embedded Yocto (DEY) 2.2 -## Release 2.2-r2 +## Release 2.2-r3 This document provides information about Digi Embedded Yocto, Digi International's professional embedded Yocto development environment. @@ -62,6 +62,10 @@ Documentation is available online on the Digi documentation site: # Release Changelog +## 2.2-r3 + +* TBC + ## 2.2-r2 * Digi Embedded Yocto diff --git a/meta-digi-dey/conf/distro/dey.conf b/meta-digi-dey/conf/distro/dey.conf index 2c5c10fe4..1a08724eb 100644 --- a/meta-digi-dey/conf/distro/dey.conf +++ b/meta-digi-dey/conf/distro/dey.conf @@ -1,6 +1,6 @@ DISTRO = "dey" DISTRO_NAME = "Digi Embedded Yocto" -DISTRO_VERSION = "2.2-r2" +DISTRO_VERSION = "2.2-r3" DISTRO_CODENAME = "morty" SDK_VENDOR = "-deysdk" SDK_VERSION := "${@'${DISTRO_VERSION}'}" From c62d5e1e42b774712bd54a267ffe6024065fd5ce Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 3 Aug 2017 17:56:29 +0200 Subject: [PATCH 002/113] qtbase: optimize libraries for size on CC6UL This patch makes smaller libQt libraries saving some space in the CC6UL rootfs. Libraries size before the patch: root@ccimx6ulsbc:~# ls -l /usr/lib/libQt*5.7.1 22448 Aug /usr/lib/libQt5Concurrent.so.5.7.1 5347036 Aug /usr/lib/libQt5Core.so.5.7.1 508464 Aug /usr/lib/libQt5DBus.so.5.7.1 4419712 Aug /usr/lib/libQt5Gui.so.5.7.1 1367776 Aug /usr/lib/libQt5Network.so.5.7.1 275900 Aug /usr/lib/libQt5OpenGL.so.5.7.1 341688 Aug /usr/lib/libQt5PrintSupport.so.5.7.1 88628 Aug /usr/lib/libQt5SerialPort.so.5.7.1 290960 Aug /usr/lib/libQt5Sql.so.5.7.1 212432 Aug /usr/lib/libQt5Test.so.5.7.1 5306588 Aug /usr/lib/libQt5Widgets.so.5.7.1 894928 Aug /usr/lib/libQt5XcbQpa.so.5.7.1 191404 Aug /usr/lib/libQt5Xml.so.5.7.1 Libraries size after the patch: root@ccimx6ulsbc:~# ls -l /usr/lib/libQt*5.7.1 18352 Aug /usr/lib/libQt5Concurrent.so.5.7.1 4032380 Aug /usr/lib/libQt5Core.so.5.7.1 303684 Aug /usr/lib/libQt5DBus.so.5.7.1 2867436 Aug /usr/lib/libQt5Gui.so.5.7.1 839428 Aug /usr/lib/libQt5Network.so.5.7.1 239044 Aug /usr/lib/libQt5OpenGL.so.5.7.1 267976 Aug /usr/lib/libQt5PrintSupport.so.5.7.1 59960 Aug /usr/lib/libQt5SerialPort.so.5.7.1 172192 Aug /usr/lib/libQt5Sql.so.5.7.1 171500 Aug /usr/lib/libQt5Test.so.5.7.1 4282740 Aug /usr/lib/libQt5Widgets.so.5.7.1 616420 Aug /usr/lib/libQt5XcbQpa.so.5.7.1 154556 Aug /usr/lib/libQt5Xml.so.5.7.1 https://jira.digi.com/browse/DEL-4644 Signed-off-by: Javier Viguera --- ...0001-gcc-base.conf-optimize-for-size.patch | 24 +++++++++++++++++++ .../recipes-qt/qt5/qtbase_%.bbappend | 1 + 2 files changed, 25 insertions(+) create mode 100644 meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/0001-gcc-base.conf-optimize-for-size.patch diff --git a/meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/0001-gcc-base.conf-optimize-for-size.patch b/meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/0001-gcc-base.conf-optimize-for-size.patch new file mode 100644 index 000000000..7ad545e8a --- /dev/null +++ b/meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/0001-gcc-base.conf-optimize-for-size.patch @@ -0,0 +1,24 @@ +From: Javier Viguera +Date: Thu, 3 Aug 2017 15:21:21 +0200 +Subject: [PATCH] gcc-base.conf: optimize for size + +Signed-off-by: Javier Viguera +--- + mkspecs/common/gcc-base.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf +index 6e043f558f1c..e77fb93326d4 100644 +--- a/mkspecs/common/gcc-base.conf ++++ b/mkspecs/common/gcc-base.conf +@@ -31,8 +31,8 @@ + # you can use the manual test in tests/manual/mkspecs. + # + +-QMAKE_CFLAGS_OPTIMIZE = -O2 +-QMAKE_CFLAGS_OPTIMIZE_FULL = -O3 ++QMAKE_CFLAGS_OPTIMIZE = -Os ++QMAKE_CFLAGS_OPTIMIZE_FULL = -Os + + QMAKE_CFLAGS += -pipe + QMAKE_CFLAGS_DEPS += -M diff --git a/meta-digi-dey/recipes-qt/qt5/qtbase_%.bbappend b/meta-digi-dey/recipes-qt/qt5/qtbase_%.bbappend index b4012bc2b..58da3e060 100644 --- a/meta-digi-dey/recipes-qt/qt5/qtbase_%.bbappend +++ b/meta-digi-dey/recipes-qt/qt5/qtbase_%.bbappend @@ -3,6 +3,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" SRC_URI_append = " file://qt5.sh" +SRC_URI_append_ccimx6ul = " file://0001-gcc-base.conf-optimize-for-size.patch" PACKAGECONFIG_append = " accessibility examples fontconfig sql-sqlite" PACKAGECONFIG_append_ccimx6 = " icu" From 02547c653061383e9e612b4560788d3f5904567b Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 3 Aug 2017 18:48:58 +0200 Subject: [PATCH 003/113] packagegroup-dey-qt: add fonts package In the past QT package did include some fonts, but not anymore. New versions of QT do rely on an external font package being installed in the rootfs. Without fonts the QT applications just show up in the screen but obviously with no text at all. https://jira.digi.com/browse/DEL-4724 Signed-off-by: Javier Viguera --- .../recipes-graphics/packagegroups/packagegroup-dey-qt.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb b/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb index bb4c9ef47..2e975d56c 100644 --- a/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb +++ b/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb @@ -30,6 +30,7 @@ QT5_DEMOS_append_ccimx6 = " \ " RDEPENDS_${PN} += " \ + liberation-fonts \ ${QT5_PKS} \ ${QT5_DEMOS} \ ${QT5_EXAMPLES} \ From 4bc9e7cbd54128c9844adabdda0dcd1281c1e4d5 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Fri, 4 Aug 2017 08:39:35 +0200 Subject: [PATCH 004/113] bluez5: port test-discovery and bluezutils.py to work with python3 https://jira.digi.com/browse/DEL-4039 Signed-off-by: Isaac Hermida --- .../0025-port-test-discovery-to-python3.patch | 99 +++++++++++++++++++ .../bluez/bluez5_5.41.bbappend | 3 +- 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0025-port-test-discovery-to-python3.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0025-port-test-discovery-to-python3.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0025-port-test-discovery-to-python3.patch new file mode 100644 index 000000000..25cc37ccf --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0025-port-test-discovery-to-python3.patch @@ -0,0 +1,99 @@ +From: Isaac Hermida +Date: Thu, 3 Aug 2017 14:10:43 +0200 +Subject: [PATCH] port test-discovery to python3 + +Signed-off-by: Isaac Hermida +--- + test/bluezutils.py | 4 ++-- + test/test-discovery | 16 +++++++++------- + 2 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/test/bluezutils.py b/test/bluezutils.py +index de08cbdcb712..cd8964082450 100644 +--- a/test/bluezutils.py ++++ b/test/bluezutils.py +@@ -15,7 +15,7 @@ def find_adapter(pattern=None): + + def find_adapter_in_objects(objects, pattern=None): + bus = dbus.SystemBus() +- for path, ifaces in objects.iteritems(): ++ for path, ifaces in objects.items(): + adapter = ifaces.get(ADAPTER_INTERFACE) + if adapter is None: + continue +@@ -35,7 +35,7 @@ def find_device_in_objects(objects, device_address, adapter_pattern=None): + if adapter_pattern: + adapter = find_adapter_in_objects(objects, adapter_pattern) + path_prefix = adapter.object_path +- for path, ifaces in objects.iteritems(): ++ for path, ifaces in objects.items(): + device = ifaces.get(DEVICE_INTERFACE) + if device is None: + continue +diff --git a/test/test-discovery b/test/test-discovery +index cea77683d726..852611c862ea 100755 +--- a/test/test-discovery ++++ b/test/test-discovery +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + + from __future__ import absolute_import, print_function, unicode_literals + +@@ -18,9 +18,9 @@ def print_compact(address, properties): + name = "" + address = "" + +- for key, value in properties.iteritems(): ++ for key, value in properties.items(): + if type(value) is dbus.String: +- value = unicode(value).encode('ascii', 'replace') ++ value = str(value) + if (key == "Name"): + name = value + elif (key == "Address"): +@@ -41,7 +41,7 @@ def print_normal(address, properties): + for key in properties.keys(): + value = properties[key] + if type(value) is dbus.String: +- value = unicode(value).encode('ascii', 'replace') ++ value = str(value) + if (key == "Class"): + print(" %s = 0x%06x" % (key, value)) + else: +@@ -61,6 +61,8 @@ def skip_dev(old_dev, new_dev): + return False + + def interfaces_added(path, interfaces): ++ if "org.bluez.Device1" not in interfaces.keys(): ++ return + properties = interfaces["org.bluez.Device1"] + if not properties: + return +@@ -70,7 +72,7 @@ def interfaces_added(path, interfaces): + + if compact and skip_dev(dev, properties): + return +- devices[path] = dict(devices[path].items() + properties.items()) ++ devices[path] = dict(list(devices[path].items()) + list(properties.items())) + else: + devices[path] = properties + +@@ -93,7 +95,7 @@ def properties_changed(interface, changed, invalidated, path): + + if compact and skip_dev(dev, changed): + return +- devices[path] = dict(devices[path].items() + changed.items()) ++ devices[path] = dict(list(devices[path].items()) + list(changed.items())) + else: + devices[path] = changed + +@@ -152,7 +154,7 @@ if __name__ == '__main__': + om = dbus.Interface(bus.get_object("org.bluez", "/"), + "org.freedesktop.DBus.ObjectManager") + objects = om.GetManagedObjects() +- for path, interfaces in objects.iteritems(): ++ for path, interfaces in objects.items(): + if "org.bluez.Device1" in interfaces: + devices[path] = interfaces["org.bluez.Device1"] + diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend index 2e7c7e210..7e54c309c 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Digi International. +# Copyright (C) 2015-2017 Digi International. FILESEXTRAPATHS_prepend := "${THISDIR}/${BP}:" @@ -7,6 +7,7 @@ SRC_URI += " \ file://main.conf \ file://0001-hcitool-do-not-show-unsupported-refresh-option.patch \ file://0002-hcitool-increase-the-shown-connection-limit-to-20.patch \ + file://0025-port-test-discovery-to-python3.patch \ " SRC_URI_append_ccimx6ul = " \ From 6b78236f423f174beaaa4f5285c647116071de53 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 29 Jun 2017 10:13:20 +0200 Subject: [PATCH 005/113] ccardimx28js removal: delete machine and configuration files https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- meta-digi-arm/conf/machine/ccardimx28js.conf | 28 -- .../conf/machine/include/ccardimx28.inc | 47 --- .../conf/machine/include/digi-defaults.inc | 1 - sdk/build-github.sh | 5 +- sdk/build.sh | 3 +- sdk/config/ccardimx28js/bblayers.conf.sample | 22 -- sdk/config/ccardimx28js/conf-notes.txt | 12 - sdk/config/ccardimx28js/local.conf.sample | 270 ------------------ sdk/mkproject.sh | 4 +- 9 files changed, 5 insertions(+), 387 deletions(-) delete mode 100644 meta-digi-arm/conf/machine/ccardimx28js.conf delete mode 100644 meta-digi-arm/conf/machine/include/ccardimx28.inc delete mode 100644 sdk/config/ccardimx28js/bblayers.conf.sample delete mode 100644 sdk/config/ccardimx28js/conf-notes.txt delete mode 100644 sdk/config/ccardimx28js/local.conf.sample diff --git a/meta-digi-arm/conf/machine/ccardimx28js.conf b/meta-digi-arm/conf/machine/ccardimx28js.conf deleted file mode 100644 index 0a111e0f0..000000000 --- a/meta-digi-arm/conf/machine/ccardimx28js.conf +++ /dev/null @@ -1,28 +0,0 @@ -#@TYPE: Machine -#@NAME: ConnectCore for MX28 JumpStart Kit. -#@DESCRIPTION: Machine configuration for Digi's ConnectCore for MX28 JSK. - -include conf/machine/include/ccardimx28.inc - -# U-Boot configurations -UBOOT_CONFIG ??= "ccardimx28js" -UBOOT_CONFIG[ccardimx28js] = "ccardimx28js_config" - -KERNEL_DEVICETREE = "imx28-${MACHINE}.dtb" - -# Serial console -SERIAL_CONSOLES ?= "115200;ttyAMA0" - -# Bluetooth tty -BT_TTY ?= "ttyAPP0" - -# U-Boot script to be copied to the SD image -BOOT_SCRIPTS = "boot.scr:boot.scr" - -# Flash image types -IMAGE_FSTYPES ?= "jffs2.sum sdcard tar.bz2 ubifs" - -# FLASH parameters -MKUBIFS_ARGS ?= "-m 2048 -e 126976 -c 2047" -EXTRA_IMAGECMD_jffs2 ?= "-l -e 128 -n" -JFFS2_SUM_EXTRA_ARGS ?= "${EXTRA_IMAGECMD_jffs2}" diff --git a/meta-digi-arm/conf/machine/include/ccardimx28.inc b/meta-digi-arm/conf/machine/include/ccardimx28.inc deleted file mode 100644 index ab0ce8835..000000000 --- a/meta-digi-arm/conf/machine/include/ccardimx28.inc +++ /dev/null @@ -1,47 +0,0 @@ -#@TYPE: Machine -#@NAME: ConnectCore for MX28 module. -#@DESCRIPTION: Machine configuration for Digi's ConnectCore for MX28 module. - -DIGI_FAMILY = "ccardimx28" -MACHINEOVERRIDES =. "mxs:mx28:${DIGI_FAMILY}:" - -include conf/machine/include/imx-digi-base.inc -include conf/machine/include/tune-arm926ejs.inc - -# Platform u-boot settings -UBOOT_ENTRYPOINT = "0x40008000" -UBOOT_SUFFIX = "sb" -UBOOT_SYMLINK = "u-boot-${MACHINE}.${UBOOT_SUFFIX}" - -# Wireless external module -WIRELESS_MODULE ?= "" -WIRELESS_MODULE_append = " ${@bb.utils.contains('MACHINE_FEATURES', 'wifi', 'kernel-module-atheros', '', d)}" - -# Firmware -MACHINE_FIRMWARE ?= "" -MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1' , 'firmware-atheros-ar3k', '', d)}" -MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1' , 'firmware-atheros-ath6kl', '', d)}" - -MACHINE_EXTRA_RDEPENDS += "mtd-utils-ubifs nvram ubootenv update-flash" -MACHINE_EXTRA_RRECOMMENDS += "${MACHINE_FIRMWARE} ${WIRELESS_MODULE}" - -# -# Supported variants -# -# Maintain in sync with the same table in platform local.conf template. -# -# Name WiFi Eth2 BT 1wire -# ------------------------------------------- -# - N N N N (empty MACHINE_VARIANT="") -# e N Y N N -# w Y N N N -# wb Y N Y N -# web Y Y Y N -# web1 Y Y Y Y - -# Per-variant machine features -MACHINE_FEATURES_append_e = " second-eth" -MACHINE_FEATURES_append_w = " wifi" -MACHINE_FEATURES_append_wb = " wifi bluetooth" -MACHINE_FEATURES_append_web = " wifi second-eth bluetooth" -MACHINE_FEATURES_append_web1 = " wifi second-eth bluetooth 1-wire" diff --git a/meta-digi-arm/conf/machine/include/digi-defaults.inc b/meta-digi-arm/conf/machine/include/digi-defaults.inc index 1780c8ec7..fe6f69e66 100644 --- a/meta-digi-arm/conf/machine/include/digi-defaults.inc +++ b/meta-digi-arm/conf/machine/include/digi-defaults.inc @@ -10,7 +10,6 @@ PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg" # # Platform Linux U-Boot # ------------------------------------------------- -# ccardimx28 3.10 2013.01 # ccimx6 4.1, 3.14 2015.04 # ccimx6ul 4.1 2015.04 # diff --git a/sdk/build-github.sh b/sdk/build-github.sh index f84156d02..ec71e09a3 100755 --- a/sdk/build-github.sh +++ b/sdk/build-github.sh @@ -3,7 +3,7 @@ # # build-github.sh # -# Copyright (C) 2015 by Digi International Inc. +# Copyright (C) 2015-2017 by Digi International Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ set -e -AVAILABLE_PLATFORMS="ccardimx28js ccimx6sbc ccimx6ulsbc ccimx6ulstarter" +AVAILABLE_PLATFORMS="ccimx6sbc ccimx6ulsbc ccimx6ulstarter" MANIFEST_URL="https://github.com/digi-embedded/dey-manifest.git" @@ -119,7 +119,6 @@ while read _pl _tgt; do [ -n "${DY_TARGET}" ] && _tgt="${DY_TARGET}" || true eval "${_pl}_tgt=\"${_tgt}\"" done<<-_EOF_ - ccardimx28js dey-image-qt ccimx6sbc dey-image-qt ccimx6ulsbc dey-image-qt ccimx6ulstarter core-image-base diff --git a/sdk/build.sh b/sdk/build.sh index a26f5c656..82d45c1c3 100755 --- a/sdk/build.sh +++ b/sdk/build.sh @@ -3,7 +3,7 @@ # # build.sh # -# Copyright (C) 2013 by Digi International Inc. +# Copyright (C) 2013-2017 by Digi International Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify it @@ -169,7 +169,6 @@ while read _pl _var _tgt; do eval "${_pl}_var=\"${_var//,/ }\"" eval "${_pl}_tgt=\"${_tgt//,/ }\"" done<<-_EOF_ - ccardimx28js -,e,w,wb,web,web1 dey-image-qt ccimx6sbc DONTBUILDVARIANTS dey-image-qt,dey-image-aws ccimx6ulsbc DONTBUILDVARIANTS dey-image-qt,dey-image-aws ccimx6ulstarter DONTBUILDVARIANTS core-image-base,dey-image-aws diff --git a/sdk/config/ccardimx28js/bblayers.conf.sample b/sdk/config/ccardimx28js/bblayers.conf.sample deleted file mode 100644 index bc2ef9645..000000000 --- a/sdk/config/ccardimx28js/bblayers.conf.sample +++ /dev/null @@ -1,22 +0,0 @@ -# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf -# changes incompatibly -POKY_BBLAYERS_CONF_VERSION = "2" - -BBPATH = "${TOPDIR}" -BBFILES ?= "" - -BBLAYERS ?= " \ - ##OEROOT##/meta \ - ##OEROOT##/meta-poky \ - ##OEROOT##/meta-yocto-bsp \ - ##DIGIBASE##/meta-openembedded/meta-oe \ - ##DIGIBASE##/meta-openembedded/meta-python \ - ##DIGIBASE##/meta-openembedded/meta-networking \ - ##DIGIBASE##/meta-openembedded/meta-webserver \ - ##DIGIBASE##/meta-qt5 \ - ##DIGIBASE##/meta-swupdate \ - ##DIGIBASE##/meta-freescale \ - ##DIGIBASE##/meta-fsl-demos \ - ##DIGIBASE##/meta-digi/meta-digi-arm \ - ##DIGIBASE##/meta-digi/meta-digi-dey \ - " diff --git a/sdk/config/ccardimx28js/conf-notes.txt b/sdk/config/ccardimx28js/conf-notes.txt deleted file mode 100644 index d8fa34f70..000000000 --- a/sdk/config/ccardimx28js/conf-notes.txt +++ /dev/null @@ -1,12 +0,0 @@ -Digi Embedded Yocto provides the following image recipes: - - * dey-image-qt: graphical QT image - - By default the image is X11-based so it provides a full SATO theme - desktop environment. - - To compile the image for the framebuffer (instead of X11) add the - following line to the project's conf/local.conf: - - DISTRO_FEATURES_remove = "x11" - diff --git a/sdk/config/ccardimx28js/local.conf.sample b/sdk/config/ccardimx28js/local.conf.sample deleted file mode 100644 index a77a66ace..000000000 --- a/sdk/config/ccardimx28js/local.conf.sample +++ /dev/null @@ -1,270 +0,0 @@ -# -# This file is your local configuration file and is where all local user settings -# are placed. The comments in this file give some guide to the options a new user -# to the system might want to change but pretty much any configuration option can -# be set in this file. More adventurous users can look at local.conf.extended -# which contains other examples of configuration which can be placed in this file -# but new users likely won't need any of them initially. -# -# Lines starting with the '#' character are commented out and in some cases the -# default values are provided as comments to show people example syntax. Enabling -# the option is a question of removing the # character and making any change to the -# variable as required. - -# -# Machine Selection -# -# You need to select a specific machine to target the build with. There are a selection -# of emulated machines available which can boot and run in the QEMU emulator: -# -#MACHINE ?= "qemuarm" -#MACHINE ?= "qemuarm64" -#MACHINE ?= "qemumips" -#MACHINE ?= "qemumips64" -#MACHINE ?= "qemuppc" -#MACHINE ?= "qemux86" -#MACHINE ?= "qemux86-64" -# -# There are also the following hardware board target machines included for -# demonstration purposes: -# -#MACHINE ?= "beaglebone" -#MACHINE ?= "genericx86" -#MACHINE ?= "genericx86-64" -#MACHINE ?= "mpc8315e-rdb" -#MACHINE ?= "edgerouter" -# -# This sets the default machine to be qemux86 if no other machine is selected: -#MACHINE ??= "qemux86" - -MACHINE = "ccardimx28js" - -# -# Supported variants -# -# Maintain in sync with the same table in platform machine config file. -# -# Name WiFi Eth2 BT 1wire -# ------------------------------------------- -# - N N N N (empty MACHINE_VARIANT="") -# e N Y N N -# w Y N N N -# wb Y N Y N -# web Y Y Y N -# web1 Y Y Y Y -MACHINE_VARIANT = "web1" - -# -# Use Digi's internal git repositories -# -#DIGI_INTERNAL_GIT ?= "1" - -# -# Where to place downloads -# -# During a first build the system will download many different source code tarballs -# from various upstream projects. This can take a while, particularly if your network -# connection is slow. These are all stored in DL_DIR. When wiping and rebuilding you -# can preserve this directory to speed up this part of subsequent builds. This directory -# is safe to share between multiple builds on the same machine too. -# -# The default is a downloads directory under TOPDIR which is the build directory. -# -#DL_DIR ?= "${TOPDIR}/downloads" - -# -# Where to place shared-state files -# -# BitBake has the capability to accelerate builds based on previously built output. -# This is done using "shared state" files which can be thought of as cache objects -# and this option determines where those files are placed. -# -# You can wipe out TMPDIR leaving this directory intact and the build would regenerate -# from these files if no changes were made to the configuration. If changes were made -# to the configuration, only shared state files where the state was still valid would -# be used (done using checksums). -# -# The default is a sstate-cache directory under TOPDIR. -# -#SSTATE_DIR ?= "${TOPDIR}/sstate-cache" - -# -# Where to place the build output -# -# This option specifies where the bulk of the building work should be done and -# where BitBake should place its temporary files and output. Keep in mind that -# this includes the extraction and compilation of many applications and the toolchain -# which can use Gigabytes of hard disk space. -# -# The default is a tmp directory under TOPDIR. -# -#TMPDIR = "${TOPDIR}/tmp" - -# -# Default policy config -# -# The distribution setting controls which policy settings are used as defaults. -# The default value is fine for general Yocto project use, at least initially. -# Ultimately when creating custom policy, people will likely end up subclassing -# these defaults. -# -DISTRO ?= "dey" -# As an example of a subclass there is a "bleeding" edge policy configuration -# where many versions are set to the absolute latest code from the upstream -# source control systems. This is just mentioned here as an example, its not -# useful to most new users. -# DISTRO ?= "poky-bleeding" - -# -# Package Management configuration -# -# This variable lists which packaging formats to enable. Multiple package backends -# can be enabled at once and the first item listed in the variable will be used -# to generate the root filesystems. -# Options are: -# - 'package_deb' for debian style deb files -# - 'package_ipk' for ipk files are used by opkg (a debian style embedded package manager) -# - 'package_rpm' for rpm style packages -# E.g.: PACKAGE_CLASSES ?= "package_rpm package_deb package_ipk" -# We default to rpm: -PACKAGE_CLASSES ?= "package_rpm" - -# -# SDK target architecture -# -# This variable specifies the architecture to build SDK items for and means -# you can build the SDK packages for architectures other than the machine you are -# running the build on (i.e. building i686 packages on an x86_64 host). -# Supported values are i686 and x86_64 -#SDKMACHINE ?= "i686" - -# -# Extra image configuration defaults -# -# The EXTRA_IMAGE_FEATURES variable allows extra packages to be added to the generated -# images. Some of these options are added to certain image types automatically. The -# variable can contain the following options: -# "dbg-pkgs" - add -dbg packages for all installed packages -# (adds symbol information for debugging/profiling) -# "dev-pkgs" - add -dev packages for all installed packages -# (useful if you want to develop against libs in the image) -# "ptest-pkgs" - add -ptest packages for all ptest-enabled packages -# (useful if you want to run the package test suites) -# "tools-sdk" - add development tools (gcc, make, pkgconfig etc.) -# "tools-debug" - add debugging tools (gdb, strace) -# "eclipse-debug" - add Eclipse remote debugging support -# "tools-profile" - add profiling tools (oprofile, lttng, valgrind) -# "tools-testapps" - add useful testing tools (ts_print, aplay, arecord etc.) -# "debug-tweaks" - make an image suitable for development -# e.g. ssh root access has a blank password -# There are other application targets that can be used here too, see -# meta/classes/image.bbclass and meta/classes/core-image.bbclass for more details. -# We default to enabling the debugging tweaks. -EXTRA_IMAGE_FEATURES ?= "debug-tweaks" - -# -# Additional image features -# -# The following is a list of additional classes to use when building images which -# enable extra features. Some available options which can be included in this variable -# are: -# - 'buildstats' collect build statistics -# - 'image-mklibs' to reduce shared library files size for an image -# - 'image-prelink' in order to prelink the filesystem image -# - 'image-swab' to perform host system intrusion detection -# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink -# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extended -USER_CLASSES ?= "buildstats image-mklibs image-prelink" - -# -# Runtime testing of images -# -# The build system can test booting virtual machine images under qemu (an emulator) -# after any root filesystems are created and run tests against those images. To -# enable this uncomment this line. See classes/testimage(-auto).bbclass for -# further details. -#TEST_IMAGE = "1" -# -# Interactive shell configuration -# -# Under certain circumstances the system may need input from you and to do this it -# can launch an interactive shell. It needs to do this since the build is -# multithreaded and needs to be able to handle the case where more than one parallel -# process may require the user's attention. The default is iterate over the available -# terminal types to find one that works. -# -# Examples of the occasions this may happen are when resolving patches which cannot -# be applied, to use the devshell or the kernel menuconfig -# -# Supported values are auto, gnome, xfce, rxvt, screen, konsole (KDE 3.x only), none -# Note: currently, Konsole support only works for KDE 3.x due to the way -# newer Konsole versions behave -#OE_TERMINAL = "auto" -# By default disable interactive patch resolution (tasks will just fail instead): -PATCHRESOLVE = "noop" - -# -# Disk Space Monitoring during the build -# -# Monitor the disk space during the build. If there is less that 1GB of space or less -# than 100K inodes in any key build location (TMPDIR, DL_DIR, SSTATE_DIR), gracefully -# shutdown the build. If there is less that 100MB or 1K inodes, perform a hard abort -# of the build. The reason for this is that running completely out of space can corrupt -# files and damages the build in ways which may not be easily recoverable. -# It's necesary to monitor /tmp, if there is no space left the build will fail -# with very exotic errors. -BB_DISKMON_DIRS = "\ - STOPTASKS,${TMPDIR},1G,100K \ - STOPTASKS,${DL_DIR},1G,100K \ - STOPTASKS,${SSTATE_DIR},1G,100K \ - STOPTASKS,/tmp,100M,100K \ - ABORT,${TMPDIR},100M,1K \ - ABORT,${DL_DIR},100M,1K \ - ABORT,${SSTATE_DIR},100M,1K \ - ABORT,/tmp,10M,1K" - -# -# Shared-state files from other locations -# -# As mentioned above, shared state files are prebuilt cache data objects which can -# used to accelerate build time. This variable can be used to configure the system -# to search other mirror locations for these objects before it builds the data itself. -# -# This can be a filesystem directory, or a remote url such as http or ftp. These -# would contain the sstate-cache results from previous builds (possibly from other -# machines). This variable works like fetcher MIRRORS/PREMIRRORS and points to the -# cache locations to check for the shared objects. -# NOTE: if the mirror uses the same structure as SSTATE_DIR, you need to add PATH -# at the end as shown in the examples below. This will be substituted with the -# correct path within the directory structure. -#SSTATE_MIRRORS ?= "\ -#file://.* http://someserver.tld/share/sstate/PATH;downloadfilename=PATH \n \ -#file://.* file:///some/local/dir/sstate/PATH" - - -# -# Qemu configuration -# -# By default qemu will build with a builtin VNC server where graphical output can be -# seen. The two lines below enable the SDL backend too. By default libsdl-native will -# be built, if you want to use your host's libSDL instead of the minimal libsdl built -# by libsdl-native then uncomment the ASSUME_PROVIDED line below. -PACKAGECONFIG_append_pn-qemu-native = " sdl" -PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl" -#ASSUME_PROVIDED += "libsdl-native" - - -# CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to -# track the version of this file when it was generated. This can safely be ignored if -# this doesn't mean anything to you. -CONF_VERSION = "1" - -# -# Enable local PR server -# -PRSERV_HOST = "localhost:0" - -# -# Some libraries and packages are covered by NXP EULA -# -#ACCEPT_FSL_EULA = "1" diff --git a/sdk/mkproject.sh b/sdk/mkproject.sh index 576e7cc7d..7ea2bd9bb 100755 --- a/sdk/mkproject.sh +++ b/sdk/mkproject.sh @@ -3,7 +3,7 @@ # # mkproject.sh # -# Copyright (C) 2013 by Digi International Inc. +# Copyright (C) 2013-2017 by Digi International Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ MKP_NONE="\033[0m" MKP_CONFIGPATH="${MKP_SCRIPTPATH}/sources/meta-digi/sdk/config" # Blacklist platforms (not officially supported in a DEY release) -MKP_BLACKLIST_PLATFORMS="ccardimx28js" +MKP_BLACKLIST_PLATFORMS="" MKP_SETUP_ENVIRONMENT='#!/bin/bash From d2df029153d20a5ece0c3820b71f1ac862f5696e Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 29 Jun 2017 10:22:30 +0200 Subject: [PATCH 006/113] ccardimx28js removal: clean image_type class Actually remove the code to generate SD card images. https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- .../classes/image_types_digi.bbclass | 60 ------------------- 1 file changed, 60 deletions(-) diff --git a/meta-digi-arm/classes/image_types_digi.bbclass b/meta-digi-arm/classes/image_types_digi.bbclass index 334ac0e79..999c10962 100644 --- a/meta-digi-arm/classes/image_types_digi.bbclass +++ b/meta-digi-arm/classes/image_types_digi.bbclass @@ -298,65 +298,5 @@ IMAGE_CMD_sdcard() { dd if=${SDIMG_ROOTFS} of=${SDIMG} conv=notrunc,fsync seek=1 bs=$(expr ${IMAGE_ROOTFS_ALIGNMENT} \* 1024 + ${BOOT_SPACE_ALIGNED} \* 1024) } -# -# Create an image that can by written onto a SD card using dd (for ccardimx28 family) -# -# The disk layout used is: -# -# 1. Not partitioned : reserved for bootloader (u-boot at 1MiB offset) -# 2. BOOT PARTITION : kernel and device tree blobs -# 3. ROOTFS PARTITION : rootfs -# -# 4MiB BOOT_SPACE ROOTFS_SIZE -# <----------------> <--------------------> <------------------------------> -# +---+--------------+----------------------+--------------------------------+ -# | | U-BOOT (RAW) | BOOT PARTITION (FAT) | ROOTFS PARTITION (EXT4) | -# +---+--------------+----------------------+--------------------------------+ -# ^ ^ ^ ^ ^ -# | | | | | -# 0 1MiB 4MiB 4MiB + BOOT_SPACE SDIMG_SIZE -# -IMAGE_CMD_sdcard_ccardimx28() { - # Align boot partition and calculate total sdcard image size - BOOT_SPACE_ALIGNED="$(expr \( \( ${BOARD_BOOTIMAGE_PARTITION_SIZE} + ${IMAGE_ROOTFS_ALIGNMENT} - 1 \) / ${IMAGE_ROOTFS_ALIGNMENT} \) \* ${IMAGE_ROOTFS_ALIGNMENT})" - SDIMG_SIZE="$(expr ${IMAGE_ROOTFS_ALIGNMENT} + ${BOOT_SPACE_ALIGNED} + $ROOTFS_SIZE)" - - # Initialize sdcard image file - dd if=/dev/zero of=${SDIMG} bs=1024 count=0 seek=${SDIMG_SIZE} - - # - # Bootstream header for u-boot at 1M offset - # - # The offset is coded in bytes 29-32 in little-endian. The - # value to set is the offset in 512 bytes blocks + 1. - # - # For 1M offset we can calculate the bytes: - # - # printf '%08x' 2049 | grep -o .. | tac | tr -d '\n' - # - BS_HDR="\x33\x22\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x08\x00\x00\x00\x00\x00\x00" - - # Use 'printf' command and not shell builtins because hexadecimal - # format does not work well with 'dash' shell - PRINTF="$(which printf)" - - # Create partition table, boot partition (with bootable flag) and rootfs partition (to the end of the disk) - parted -s ${SDIMG} mklabel msdos - parted -s ${SDIMG} unit KiB mkpart primary 1024 ${IMAGE_ROOTFS_ALIGNMENT} - parted -s ${SDIMG} unit KiB mkpart primary fat32 ${IMAGE_ROOTFS_ALIGNMENT} $(expr ${IMAGE_ROOTFS_ALIGNMENT} \+ ${BOOT_SPACE_ALIGNED}) - parted -s ${SDIMG} set 2 boot on - parted -s ${SDIMG} -- unit KiB mkpart primary ext2 $(expr ${IMAGE_ROOTFS_ALIGNMENT} \+ ${BOOT_SPACE_ALIGNED}) -1s - parted -s ${SDIMG} unit KiB print - - # Change partition type to 0x53 for mxs processor family and write bootstream header - echo -n S | dd of=${SDIMG} bs=1 count=1 seek=450 conv=notrunc - ${PRINTF} "${BS_HDR}" | dd of=${SDIMG} bs=512 seek=$(expr 1024 \* 2) conv=notrunc,sync - - # Burn bootloader, boot and rootfs partitions - dd if=${DEPLOY_DIR_IMAGE}/${UBOOT_SYMLINK} of=${SDIMG} conv=notrunc,fsync seek=$(expr 1024 \* 2 \+ 1) bs=512 - dd if=${SDIMG_BOOTFS} of=${SDIMG} conv=notrunc,fsync seek=1 bs=$(expr ${IMAGE_ROOTFS_ALIGNMENT} \* 1024) - dd if=${SDIMG_ROOTFS} of=${SDIMG} conv=notrunc,fsync seek=1 bs=$(expr ${IMAGE_ROOTFS_ALIGNMENT} \* 1024 + ${BOOT_SPACE_ALIGNED} \* 1024) -} - # The sdcard image requires the boot and rootfs images to be built before IMAGE_TYPEDEP_sdcard = "${SDIMG_BOOTFS_TYPE} ${SDIMG_ROOTFS_TYPE}" From 6a2699967cc3e45df2be1a5df13f6df8b1c03016 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 29 Jun 2017 10:46:47 +0200 Subject: [PATCH 007/113] ccardimx28js removal: delete recipes not used by other platforms https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- .../0001-makefile.am.patch | 29 - .../0002-fix-mtd-defines.patch | 84 - ...ion-detection-code-and-add-cpx2-supp.patch | 170 -- ...ot-ROM-version-from-FDT-if-available.patch | 128 -- .../0005-dump-v1-boot-structures.patch | 195 -- ...tion-to-verify-data-written-to-flash.patch | 454 ----- .../0007-disable-use-of-nfc_geometry.patch | 24 - ...-bit-ECC-for-4K-page-NAND-with-224-b.patch | 23 - .../kobs-ng/kobs-ng_3.0.35-4.1.0.bb | 25 - meta-digi-arm/recipes-bsp/libdigi/libdigi.bb | 39 - .../recipes-bsp/libdigi/libdigi/cmdopt.c | 366 ---- .../recipes-bsp/libdigi/libdigi/cmdopt.h | 54 - .../recipes-bsp/libdigi/libdigi/crc32.c | 86 - .../recipes-bsp/libdigi/libdigi/crc32.h | 24 - .../libdigi/libdigi/digi-platforms.h | 116 -- .../recipes-bsp/libdigi/libdigi/log.c | 129 -- .../recipes-bsp/libdigi/libdigi/log.h | 34 - .../recipes-bsp/libdigi/libdigi/mem.c | 90 - .../recipes-bsp/libdigi/libdigi/mem.h | 23 - .../recipes-bsp/libdigi/libdigi/misc_helper.h | 51 - .../recipes-bsp/libdigi/libdigi/platform.c | 110 - meta-digi-arm/recipes-bsp/nvram/nvram.inc | 46 - meta-digi-arm/recipes-bsp/nvram/nvram/main.c | 266 --- .../nvram/nvram/nvram_priv_linux.c | 302 --- .../recipes-bsp/nvram/nvram_2013.01.bb | 5 - .../u-boot-dey-2013.01/ccardimx28/boot.txt | 16 - .../u-boot/u-boot-dey-rev_2013.01.inc | 11 - .../recipes-bsp/u-boot/u-boot-dey_2013.01.bb | 26 - .../recipes-bsp/ubootenv/ubootenv.bb | 34 - .../recipes-bsp/ubootenv/ubootenv/env_funcs.c | 183 -- .../recipes-bsp/ubootenv/ubootenv/env_funcs.h | 29 - .../ubootenv/ubootenv/environment.h | 26 - .../recipes-bsp/ubootenv/ubootenv/main_env.c | 561 ------ .../recipes-bsp/update-flash/update-flash.bb | 26 - .../update-flash/update-flash/jffs2-user.h | 33 - .../update-flash/update-flash/update_flash.c | 1770 ----------------- .../kernel-module-atheros.bb | 50 - .../0001-atheros-convert-NLA_PUT-macros.patch | 1761 ---------------- ...theros-update-renamed-struct-members.patch | 235 --- .../kernel-module-atheros/Makefile | 42 - .../kernel-module-atheros/atheros-pre-up | 139 -- .../linux-dey-3.10/ccardimx28js/defconfig | 212 -- .../recipes-kernel/linux/linux-dey_3.10.bb | 61 - .../0001-enable-libnl3.patch | 74 - .../0002-cross-compile.patch | 85 - ...ilt_wan-Rewrite-the-netlink-listener.patch | 127 -- .../0004-add-fgnu89-flag-for-gcc5.patch | 29 - .../btfilter-v3.4p4-b3.4.0.158/btfilter-init | 33 - .../btfilter/btfilter_v3.4p4-b3.4.0.158.bb | 34 - 49 files changed, 8470 deletions(-) delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0001-makefile.am.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0002-fix-mtd-defines.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0007-disable-use-of-nfc_geometry.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0008-mtd-configure-16-bit-ECC-for-4K-page-NAND-with-224-b.patch delete mode 100644 meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi.bb delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.c delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.h delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.c delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.h delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/digi-platforms.h delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/log.c delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/log.h delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.c delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.h delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/misc_helper.h delete mode 100644 meta-digi-arm/recipes-bsp/libdigi/libdigi/platform.c delete mode 100644 meta-digi-arm/recipes-bsp/nvram/nvram.inc delete mode 100644 meta-digi-arm/recipes-bsp/nvram/nvram/main.c delete mode 100644 meta-digi-arm/recipes-bsp/nvram/nvram/nvram_priv_linux.c delete mode 100644 meta-digi-arm/recipes-bsp/nvram/nvram_2013.01.bb delete mode 100644 meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2013.01/ccardimx28/boot.txt delete mode 100644 meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-rev_2013.01.inc delete mode 100644 meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2013.01.bb delete mode 100644 meta-digi-arm/recipes-bsp/ubootenv/ubootenv.bb delete mode 100644 meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.c delete mode 100644 meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.h delete mode 100644 meta-digi-arm/recipes-bsp/ubootenv/ubootenv/environment.h delete mode 100644 meta-digi-arm/recipes-bsp/ubootenv/ubootenv/main_env.c delete mode 100644 meta-digi-arm/recipes-bsp/update-flash/update-flash.bb delete mode 100644 meta-digi-arm/recipes-bsp/update-flash/update-flash/jffs2-user.h delete mode 100644 meta-digi-arm/recipes-bsp/update-flash/update-flash/update_flash.c delete mode 100644 meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros.bb delete mode 100644 meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0001-atheros-convert-NLA_PUT-macros.patch delete mode 100644 meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0002-atheros-update-renamed-struct-members.patch delete mode 100644 meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/Makefile delete mode 100644 meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/atheros-pre-up delete mode 100644 meta-digi-arm/recipes-kernel/linux/linux-dey-3.10/ccardimx28js/defconfig delete mode 100644 meta-digi-arm/recipes-kernel/linux/linux-dey_3.10.bb delete mode 100644 meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0001-enable-libnl3.patch delete mode 100644 meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0002-cross-compile.patch delete mode 100644 meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0003-abtfilt_wan-Rewrite-the-netlink-listener.patch delete mode 100644 meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0004-add-fgnu89-flag-for-gcc5.patch delete mode 100755 meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/btfilter-init delete mode 100644 meta-digi-dey/recipes-connectivity/btfilter/btfilter_v3.4p4-b3.4.0.158.bb diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0001-makefile.am.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0001-makefile.am.patch deleted file mode 100644 index d5981d7bc..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0001-makefile.am.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Javier Viguera -Date: Fri, 11 Oct 2013 18:56:04 +0200 -Subject: [PATCH] makefile.am - -Yocto build system does not use the makefile.in directly. Instead it -uses autotools to regenerate it using the source makefile.am. - -But the makefile.in distributed in the package has some rules changed -that are not generated from the makefile.am, so adapt the makefile.am to -generate an equivalent makefile.in. - -Signed-off-by: Javier Viguera ---- - include/Makefile.am | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/include/Makefile.am b/include/Makefile.am -index 17d4d2c..dc3a466 100644 ---- a/include/Makefile.am -+++ b/include/Makefile.am -@@ -1,5 +1,8 @@ - noinst_HEADERS=version.h - -+all-local: -+ echo "const char *git_sha = \""`git rev-parse HEAD`"\";" > ../include/autoversion.h -+ - version.h: stamp-vh - @: - diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0002-fix-mtd-defines.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0002-fix-mtd-defines.patch deleted file mode 100644 index eeef870e3..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0002-fix-mtd-defines.patch +++ /dev/null @@ -1,84 +0,0 @@ -From: "Paul B. Henson" -Date: Fri, 11 Oct 2013 17:23:44 +0200 -Subject: [PATCH] fix-mtd-defines - -Newer kernel headers renamed mtd mode defines and no longer support -MEMSETOOBSEL. Allow code to work with both older and newer kernel -versions. - -Signed-off-by: Paul B. Henson -Signed-off-by: Javier Viguera ---- - src/mtd.c | 9 +++++++++ - src/mtd.h | 8 ++++++++ - 2 files changed, 17 insertions(+) - -diff --git a/src/mtd.c b/src/mtd.c -index 2974814..f9e60a3 100644 ---- a/src/mtd.c -+++ b/src/mtd.c -@@ -852,8 +852,11 @@ void mtd_close(struct mtd_data *md) - mp = &md->part[i]; - - if (mp->fd != -1) { -+/* Newer kernels dropped MEMSETOOBSEL */ -+#ifdef MEMSETOOBSEL - (void)ioctl(mp->fd, MEMSETOOBSEL, - &mp->old_oobinfo); -+#endif - close(mp->fd); - } - -@@ -896,6 +899,8 @@ int mtd_set_ecc_mode(struct mtd_data *md, int ecc) - continue; - } - -+/* Newer kernels dropped MEMSETOOBSEL */ -+#ifdef MEMSETOOBSEL - if (r == -ENOTTY) { - r = ioctl(mp->fd, MEMSETOOBSEL, &mp->old_oobinfo); - if (r != 0) { -@@ -904,6 +909,7 @@ int mtd_set_ecc_mode(struct mtd_data *md, int ecc) - } - mp->oobinfochanged = 0; - } -+#endif - } else { - r = ioctl(mp->fd, MTDFILEMODE, (void *)MTD_MODE_RAW); - if (r != 0 && r != -ENOTTY) { -@@ -911,6 +917,8 @@ int mtd_set_ecc_mode(struct mtd_data *md, int ecc) - continue; - } - -+/* Newer kernels dropped MEMSETOOBSEL */ -+#ifdef MEMSETOOBSEL - if (r == -ENOTTY) { - r = ioctl(mp->fd, MEMSETOOBSEL, &none_oobinfo); - if (r != 0) { -@@ -920,6 +928,7 @@ int mtd_set_ecc_mode(struct mtd_data *md, int ecc) - mp->oobinfochanged = 1; - } else - mp->oobinfochanged = 2; -+#endif - } - - mp->ecc = ecc; -diff --git a/src/mtd.h b/src/mtd.h -index 99d7887..bf6e53d 100644 ---- a/src/mtd.h -+++ b/src/mtd.h -@@ -31,6 +31,14 @@ - #include "BootControlBlocks.h" - #include "rom_nand_hamming_code_ecc.h" - -+// Newer kernel headers renamed define -+#ifndef MTD_MODE_NORMAL -+#define MTD_MODE_NORMAL MTD_FILE_MODE_NORMAL -+#endif -+#ifndef MTD_MODE_RAW -+#define MTD_MODE_RAW MTD_FILE_MODE_RAW -+#endif -+ - //------------------------------------------------------------------------------ - // Re-definitions of true and false, because the standard ones aren't good - // enough? diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch deleted file mode 100644 index d70fe428f..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch +++ /dev/null @@ -1,170 +0,0 @@ -From: Hector Palacios -Date: Fri, 18 Oct 2013 10:10:37 +0200 -Subject: cleanup ROM version detection code and add cpx2 support - -The original code flow was difficult to understand. -Now there is a main if-elseif to check for 'Hardware' or 'Revision' -strings from cpuinfo. -On the 'Hardware' section we first check if it is a CPX2, or else we -will parse the MX-- number to get the CPU model. -On the 'Revision' section we base on the revision number to get the -CPU model or, if unset (like when Linux is booted directly), we'll -rely on the previous hw_system_rev calculated before. - -Signed-off-by: Hector Palacios -Reviewed-by: Robert Hodaszi ---- - src/plat_boot_config.c | 119 ++++++++++++++++++++++++++----------------------- - 1 file changed, 63 insertions(+), 56 deletions(-) - -diff --git a/src/plat_boot_config.c b/src/plat_boot_config.c -index 76e65c8..e3bf242 100644 ---- a/src/plat_boot_config.c -+++ b/src/plat_boot_config.c -@@ -109,10 +109,11 @@ int discover_boot_rom_version(void) - { - FILE *cpuinfo; - char line_buffer[100]; -- static char *banner = "Revision"; -+ static char *banner_rev = "Revision"; - static char *banner_hw = "Hardware"; -+ static char *banner_digi_x2 = "Hardware\t: Digi ConnectPort X2"; - char *rev; -- int system_rev, hw_system_rev = 0; -+ int system_rev = 0, hw_system_rev = 0; - - cpuinfo = fopen("/proc/cpuinfo", "r"); - if (!cpuinfo) { -@@ -125,15 +126,20 @@ int discover_boot_rom_version(void) - if (!fgets(line_buffer, sizeof(line_buffer), cpuinfo)) - break; - -- /* Check if it's revision line */ -- if (strncmp(line_buffer, banner, strlen(banner))) { -- /* -- * Why use the `Hardware` to parse the system type ? -- * [1] If boot linux kernel directly from SD card not by uboot, -- * the `Revision` will be zero. -- * [2] The code does not change the old logic. -- */ -- if (!strncmp(line_buffer, banner_hw, strlen(banner))) { -+ /* Check if it's hardware line... */ -+ /* -+ * Why use the `Hardware` to parse the system type ? -+ * [1] If boot linux kernel directly from SD card not by uboot, -+ * the `Revision` will be zero. -+ * [2] The code does not change the old logic. -+ */ -+ if (!strncmp(line_buffer, banner_hw, strlen(banner_hw))) { -+ if (!strncmp(line_buffer, banner_digi_x2, -+ strlen(banner_digi_x2))) { -+ /* The cpx2 is an i.MX28 */ -+ hw_system_rev = MX28; -+ } -+ else { - rev = strstr(line_buffer, "MX"); - if (rev) { - char tmp[3] = {}; -@@ -143,56 +149,57 @@ int discover_boot_rom_version(void) - hw_system_rev = strtoul(tmp, NULL, 16); - } - } -- continue; - } -+ /* ... or Revision line */ -+ else if (!strncmp(line_buffer, banner_rev, strlen(banner_rev))) { -+ rev = index(line_buffer, ':'); -+ if (rev != NULL) { -+ rev++; -+ system_rev = strtoul(rev, NULL, 16); -+ system_rev = mxc_cpu(system_rev); -+ if (!system_rev) -+ system_rev = hw_system_rev; -+ -+ switch (system_rev) { -+ case MX23: -+ plat_config_data = &mx23_boot_config; -+ break; -+ -+ case MX28: -+ plat_config_data = &mx28_boot_config; -+ break; -+ -+ case MX53: -+ if (mxc_cpu_is_rev(system_rev, CHIP_REV_2_0) < 0) -+ plat_config_data = &mx53to1_boot_config; -+ else -+ plat_config_data = &mx53to2_boot_config; -+ break; -+ -+ case MX50: -+ plat_config_data = &mx50_boot_config; -+ break; -+ -+ case MX6: -+ case MX6Q: -+ case MX6DL: -+ plat_config_data = &mx6q_boot_config; -+ break; -+ -+ default: -+ fprintf(stderr, "Couldn't find Boot ROM version\n"); -+ break; -+ } - -- rev = index(line_buffer, ':'); -- if (rev != NULL) { -- rev++; -- system_rev = strtoul(rev, NULL, 16); -- system_rev = mxc_cpu(system_rev); -- if (!system_rev) -- system_rev = hw_system_rev; -- -- switch (system_rev) { -- case MX23: -- plat_config_data = &mx23_boot_config; -- break; -- -- case MX28: -- plat_config_data = &mx28_boot_config; -- break; -- -- case MX53: -- if (mxc_cpu_is_rev(system_rev, CHIP_REV_2_0) < 0) -- plat_config_data = &mx53to1_boot_config; -- else -- plat_config_data = &mx53to2_boot_config; -- break; -- -- case MX50: -- plat_config_data = &mx50_boot_config; -- break; -- -- case MX6: -- case MX6Q: -- case MX6DL: -- plat_config_data = &mx6q_boot_config; -- break; -- -- default: -- fprintf(stderr, "Couldn't find Boot ROM version\n"); -- break; -- } -- -- fclose(cpuinfo); -- if (plat_config_data) { -- plat_config_data->m_u32Arm_type = system_rev; -- return 0; -+ break; /* quit for loop */ - } -- return -1; - } - } -+ - fclose(cpuinfo); -+ if (plat_config_data) { -+ plat_config_data->m_u32Arm_type = system_rev; -+ return 0; -+ } - return -1; - } diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch deleted file mode 100644 index ce5954700..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0004-discover-boot-ROM-version-from-FDT-if-available.patch +++ /dev/null @@ -1,128 +0,0 @@ -From: Hector Palacios -Date: Fri, 18 Oct 2013 10:11:29 +0200 -Subject: discover boot ROM version from FDT if available - -New kernels don't get CPU information from U-Boot ATAGS and -so the /proc/cpuinfo file does not have the Hardware/Revision -lines filled in. -This patch gets the CPU model from the device tree information -at /proc/device-tree/compatible. -For backwards compatibility, if the CPU model cannot be retrieved -from this file, we try to get it from /proc/cpuinfo. - -Signed-off-by: Hector Palacios -Reviewed-by: Robert Hodaszi ---- - src/plat_boot_config.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 94 insertions(+), 1 deletion(-) - -diff --git a/src/plat_boot_config.c b/src/plat_boot_config.c -index e3bf242..af7e03a 100644 ---- a/src/plat_boot_config.c -+++ b/src/plat_boot_config.c -@@ -105,7 +105,91 @@ static platform_config mx6q_boot_config = { - .rom_mtd_commit_structures = v4_rom_mtd_commit_structures, - }; - --int discover_boot_rom_version(void) -+#define MAX_STRLEN 256 -+int get_rom_version_from_fdt(void) -+{ -+ FILE *fd; -+ char line_buffer[MAX_STRLEN]; -+ char *p; -+ static char *compatible = "fsl,imx"; -+ char *rev; -+ int system_rev; -+ -+ fd = fopen("/proc/device-tree/compatible", "r"); -+ if (!fd) -+ return -1; -+ -+ p = &line_buffer[0]; -+ if (fgets(p, MAX_STRLEN, fd)) { -+ /* -+ * The compatible string can contain more than one string. -+ * Each string value is separated from the next one by a -+ * NULL char. We must check all values one by one until -+ * we find two consecutive NULL chars. -+ */ -+ while (p[0] != 0) { -+ if (!strncmp(p, compatible, strlen(compatible))) { -+ rev = p + strlen(compatible); -+ /* -+ * check if it's an imx6 CPU series, or -+ * a parsable number. -+ */ -+ if (!strncmp(rev, "6q", 2)) -+ system_rev = MX6Q; -+ else if (!strncmp(rev, "6d", 2)) -+ system_rev = MX6DL; -+ else if (!strncmp(rev, "6s", 2)) -+ system_rev = MX6; -+ else -+ system_rev = strtoul(rev, NULL, 16); -+ -+ switch (system_rev) { -+ case MX23: -+ plat_config_data = &mx23_boot_config; -+ break; -+ -+ case MX28: -+ plat_config_data = &mx28_boot_config; -+ break; -+ -+ case MX53: -+ /* -+ * TODO: check CPU revision -+ * Consider it is a TO2 for the -+ * moment -+ */ -+ plat_config_data = &mx53to2_boot_config; -+ break; -+ -+ case MX50: -+ plat_config_data = &mx50_boot_config; -+ break; -+ -+ case MX6: -+ case MX6Q: -+ case MX6DL: -+ plat_config_data = &mx6q_boot_config; -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (plat_config_data) { -+ plat_config_data->m_u32Arm_type = system_rev; -+ return 0; -+ } -+ } -+ /* Move string pointer to next possible value */ -+ p += strlen(p) + 1; -+ } -+ } -+ -+ fclose(fd); -+ return -1; -+} -+ -+int get_rom_version_from_cpuinfo(void) - { - FILE *cpuinfo; - char line_buffer[100]; -@@ -203,3 +287,12 @@ int discover_boot_rom_version(void) - } - return -1; - } -+ -+int discover_boot_rom_version(void) -+{ -+ /* First, try to get ROM version from FDT */ -+ if (get_rom_version_from_fdt()) -+ return (get_rom_version_from_cpuinfo()); -+ -+ return 0; -+} diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch deleted file mode 100644 index 62c786998..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0005-dump-v1-boot-structures.patch +++ /dev/null @@ -1,195 +0,0 @@ -From: Hector Palacios -Date: Tue, 15 Oct 2013 18:58:11 +0200 -Subject: dump v1 boot structures - -The kobs-ng that we received from Freescale did not support reading the -boot structures on the mx28. It could write them, but the function that -reads them was never updated to handle the updated structures used by -the mx28. This change adds basic support for reading these structures, -enough so that the dump command works. - -(forward ported from kobs-ng-10.12.01 to kobs-ng-3.0.35_4.1.0) - -Signed-off-by: Hector Palacios -Reviewed-by: Robert Hodaszi ---- - src/main.c | 5 ++- - src/mtd.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - src/mtd.h | 1 + - 3 files changed, 131 insertions(+), 4 deletions(-) - -diff --git a/src/main.c b/src/main.c -index 82b6f9e..70517b0 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -152,7 +152,10 @@ int dump_main(int argc, char **argv) - if (flags & F_VERBOSE) - mtd_dump(md); - -- r = mtd_load_all_boot_structures(md); -+ if (ROM_Version_1 == plat_config_data->m_u32RomVer) -+ r = mtd_load_v1_boot_structures(md); -+ else -+ r = mtd_load_all_boot_structures(md); - if (r != 0) { - fprintf(stderr, "Unable to load boot structures\n"); - exit(5); -diff --git a/src/mtd.c b/src/mtd.c -index f9e60a3..9ea92ad 100644 ---- a/src/mtd.c -+++ b/src/mtd.c -@@ -975,6 +975,130 @@ void dump(const void *data, int size) - printf("\n"); - } - -+/* -+ * This function is a hack written by Digi because the original code from -+ * Freescale did not supporting reading the bootlet structures at all. -+ * This function reads the search areas for a given BCB. It will read the first -+ * search area and use it if the read succeeds. If the read fails, then it will -+ * try again with the second search area. -+ * -+ * md A pointer to the current struct mtd_data. -+ * bcb_name A pointer to a human-readable string that indicates what kind of -+ * BCB we're reading. This string will only be used in log messages. -+ * ofs1 If there is one chips, the index of the search area to read -+ * ofs2 -+ * ofs_mchip If there are multiple chips, the index of the search area to read -+ * on both chips. -+ * end The number of consecutive search areas to be read. -+ * size The size of the BCB data to be read. -+ * ecc Indicates whether or not to use hardware ECC. -+ */ -+int mtd_read_bcb(struct mtd_data *md, char *bcb_name, -+ loff_t ofs1, loff_t ofs2, loff_t ofs_mchip, -+ loff_t end, size_t size, int ecc) -+{ -+ int chip; -+ loff_t end_index, search_area_indices[2], o; -+ int r; -+ int i; -+ int j; -+ unsigned stride_size_in_bytes; -+ unsigned search_area_size_in_strides; -+ unsigned search_area_size_in_bytes; -+ -+ /* Compute some important facts about geometry */ -+ if (plat_config_data->m_u32RomVer == ROM_Version_2) { -+ stride_size_in_bytes = mtd_erasesize(md); -+ search_area_size_in_strides = 4; -+ search_area_size_in_bytes = search_area_size_in_strides * stride_size_in_bytes; -+ } else { -+ stride_size_in_bytes = PAGES_PER_STRIDE * mtd_writesize(md); -+ search_area_size_in_strides = 1 << md->cfg.search_exponent; -+ search_area_size_in_bytes = search_area_size_in_strides * stride_size_in_bytes; -+ } -+ -+ /* -+ * Check whether there are multiple chips and set up the two search area -+ * indices accordingly. -+ */ -+ if (multichip(md)) -+ search_area_indices[0] = search_area_indices[1] = ofs_mchip; -+ else { -+ search_area_indices[0] = ofs1; -+ search_area_indices[1] = ofs2; -+ } -+ -+ /* Loop over search areas for this BCB. */ -+ for (i = 0; i < 2; i++) { -+ /* -+ * Compute the search area index that marks the end of the -+ * writing on this chip. -+ */ -+ end_index = search_area_indices[i] + end; -+ -+ /* Figure out which chip we're writing */ -+ chip = multichip(md) ? i : 0; -+ -+ /* Loop over consecutive search areas to write. */ -+ for (; search_area_indices[i] < end_index; search_area_indices[i]++) { -+ /* -+ * Compute the byte offset of the beginning of this -+ * search area -+ */ -+ o = search_area_indices[i] * search_area_size_in_bytes; -+ -+ /* Loop over strides in this search area. */ -+ for (j = 0; j < search_area_size_in_strides; j++, o += stride_size_in_bytes) { -+ /* -+ * If we're crossing into a new block, erase it -+ * first. -+ */ -+ -+ /* Write the page */ -+ vp(md, "mtd: Reading %s%d @%d:0x%llx(%x)\n", -+ bcb_name, j, chip, o, size); -+ -+ r = mtd_read_page(md, chip, o, ecc); -+ if (r != size) { -+ fprintf(stderr, "\n%s r = 0x%8.8X, size = 0x%8.8X\n", __func__, r, size); -+ fprintf(stderr, "mtd: Failed to read %s @%d: 0x%llx (%d)\n", -+ bcb_name, chip, o, r); -+ } else -+ break; -+ } -+ } -+ } -+ -+ return !(r == size); -+} -+ -+/* -+ * This function is a hack by Digi, written because the original code from -+ * Freescale did not support reading the v1 boot structures at all. Do not -+ * use the results from this function for anything other than browsing the -+ * boot structures. -+ */ -+int mtd_load_v1_boot_structures(struct mtd_data *md) -+{ -+ int err = 0; -+ -+ /* read the FCB search area */ -+ err = mtd_read_bcb(md, "FCB", 0, 0, 0, 1, -+ mtd_writesize(md) + mtd_oobsize(md), false); -+ memcpy(&md->fcb, md->buf, sizeof(md->fcb)); -+ -+ /* read the DBBT search area */ -+ err |= mtd_read_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true); -+ memcpy(&md->dbbt28, md->buf, sizeof(md->dbbt28)); -+ -+ if ((err != 0) || -+ (md->dbbt28.m_u32FingerPrint != DBBT_FINGERPRINT2)) { -+ err = -1; -+ } -+ -+ return err; -+} -+ - void *mtd_load_boot_structure(struct mtd_data *md, int chip, loff_t *ofsp, loff_t end, - uint32_t magic1, uint32_t magic2, uint32_t magic3, int use_ecc, - int magic_offset) -@@ -1083,9 +1207,8 @@ int mtd_load_all_boot_structures(struct mtd_data *md) - md->curr_ncb = NULL; - md->ncb_version = ncb_get_version(buf, &md->curr_ncb); - -- if (md->flags & F_VERBOSE) -- printf("mtd: found NCB%d candidate version %d @%d:0x%llx\n", -- i, md->ncb_version, chip, ofs); -+ vp(md, "mtd: found NCB%d candidate version %d @%d:0x%llx\n", -+ i, md->ncb_version, chip, ofs); - - if (md->ncb_version >= 0) - break; -diff --git a/src/mtd.h b/src/mtd.h -index bf6e53d..18e4d70 100644 ---- a/src/mtd.h -+++ b/src/mtd.h -@@ -276,6 +276,7 @@ void *mtd_load_boot_structure(struct mtd_data *md, int chip, loff_t *ofsp, loff_ - uint32_t magic1, uint32_t magic2, uint32_t magic3, int use_ecc, - int magic_offset); - int mtd_load_all_boot_structures(struct mtd_data *md); -+int mtd_load_v1_boot_structures(struct mtd_data *md); - int mtd_dump_structure(struct mtd_data *md); - - int v0_rom_mtd_init(struct mtd_data *md, FILE *fp); diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch deleted file mode 100644 index 945f30ecf..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0006-added-option-to-verify-data-written-to-flash.patch +++ /dev/null @@ -1,454 +0,0 @@ -From: Hector Palacios -Date: Wed, 16 Oct 2013 10:30:14 +0200 -Subject: added option to verify data written to flash - -This patch adds a -c (check) option to the update command. -This option will read back the data written to the flash and -compare to the original contents in RAM, to verify the write -operation was successful. - -Signed-off-by: Hector Palacios -Reviewed-by: Robert Hodaszi ---- - src/main.c | 22 ++++++-- - src/mtd.c | 138 +++++++++++++++++++++++++++++++++++++++---------- - src/mtd.h | 10 ++-- - src/plat_boot_config.h | 2 +- - 4 files changed, 136 insertions(+), 36 deletions(-) - -diff --git a/src/main.c b/src/main.c -index 70517b0..8774045 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -82,10 +82,12 @@ void usage(void) - " -x .................................... Add 1k-padding in the head\n" - " -n .................................... Dry run (don't commit to flash)\n" - " -w .................................... Commit to flash\n" -+ " -c .................................... Check committed data in flash\n" - "\n" - " update [-v] [KEY] [KOBS] [-0|1] .. Update a single bootstream\n" - " -v .................................... Verbose mode\n" - " -0|1 .................................. Update specified bootstream #\n" -+ " -c .................................... Check committed data in flash\n" - "\n" - " extract [-v] [KEY] [KOBS] [-0|1] . Extract a bootstream from flash\n" - " -v .................................... Verbose mode\n" -@@ -390,7 +392,8 @@ int extract_main(int argc, char **argv) - return 0; - } - --static int perform_bootstream_update(struct mtd_data *md, FILE *infp, int image_mask) -+static int perform_bootstream_update(struct mtd_data *md, FILE *infp, -+ int image_mask, int check) - { - int i, r; - unsigned int size, start, avail, end, update; -@@ -435,7 +438,8 @@ static int perform_bootstream_update(struct mtd_data *md, FILE *infp, int image_ - update |= UPDATE_BS(i); - } - -- r = plat_config_data->rom_mtd_commit_structures(md, infp, UPDATE_LDLB | update); -+ r = plat_config_data->rom_mtd_commit_structures(md, infp, -+ UPDATE_LDLB | update, check); - if (r < 0) { - fprintf(stderr, "FAILED to commit structures\n"); - return -1; -@@ -457,6 +461,7 @@ int update_main(int argc, char **argv) - char ascii[20 * 2 + 1]; - int device_key; - uint8_t *keyp; -+ int check; - - memset(key, 0, sizeof(key)); - device_key = 0; -@@ -473,6 +478,7 @@ int update_main(int argc, char **argv) - image_mask = 0; /* no image */ - flags = 0; - j = 0; -+ check = 0; - for (i = 1; i < argc; i++) { - - if (argv[i][0] != '-') { -@@ -500,6 +506,9 @@ int update_main(int argc, char **argv) - exit(5); - } - break; -+ case 'c': -+ check = 1; -+ break; - case 'v': - flags |= F_VERBOSE; - break; -@@ -545,7 +554,7 @@ int update_main(int argc, char **argv) - if (flags & F_VERBOSE) - mtd_dump(md); - -- r = perform_bootstream_update(md, infp, image_mask); -+ r = perform_bootstream_update(md, infp, image_mask, check); - if (r != 0) { - fprintf(stderr, "Unable to perform bootstream update\n"); - usage(); -@@ -597,6 +606,7 @@ int init_main(int argc, char **argv) - FILE *infp; - loff_t ofs; - int dryrun; -+ int check; - int padding = 0; - struct mtd_config cfg; - uint8_t key[16]; -@@ -619,6 +629,7 @@ int init_main(int argc, char **argv) - image = 0; /* first image */ - flags = 0; - dryrun = 0; -+ check = 0; - j = 0; - for (i = 1; i < argc; i++) { - -@@ -640,6 +651,9 @@ int init_main(int argc, char **argv) - case 'w': - dryrun = 0; - break; -+ case 'c': -+ check = 1; -+ break; - case 'n': - dryrun = 1; - break; -@@ -738,7 +752,7 @@ int init_main(int argc, char **argv) - mtd_dump_structure(md); - - if (!dryrun) { -- r = plat_config_data->rom_mtd_commit_structures(md, infp, UPDATE_ALL); -+ r = plat_config_data->rom_mtd_commit_structures(md, infp, UPDATE_ALL, check); - if (r < 0) { - fprintf(stderr, "FAILED to commit structures\n"); - exit(5); -diff --git a/src/mtd.c b/src/mtd.c -index 9ea92ad..77ba307 100644 ---- a/src/mtd.c -+++ b/src/mtd.c -@@ -2344,7 +2344,7 @@ int v4_rom_mtd_init(struct mtd_data *md, FILE *fp) - - int mtd_commit_bcb(struct mtd_data *md, char *bcb_name, - loff_t ofs1, loff_t ofs2, loff_t ofs_mchip, -- loff_t end, size_t size, int ecc) -+ loff_t end, size_t size, int ecc, int verify) - { - int chip; - loff_t end_index, search_area_indices[2], o; -@@ -2355,6 +2355,13 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name, - unsigned search_area_size_in_strides; - unsigned search_area_size_in_bytes; - unsigned count; -+ char *readbuf = NULL; -+ -+ if (verify) { -+ readbuf = malloc(mtd_writesize(md)); -+ if (NULL == readbuf) -+ return -1; -+ } - - vp(md, "-------------- Start to write the [ %s ] -----\n", bcb_name); - //---------------------------------------------------------------------- -@@ -2457,6 +2464,20 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name, - err ++; - } - -+ if (verify) { -+ //------------------------------------------------------ -+ // Verify the written data -+ //------------------------------------------------------ -+ r = pread(md->part[chip].fd, readbuf, mtd_writesize(md), o); -+ if (r != mtd_writesize(md)) { -+ fprintf(stderr, "mtd: Failed to read @0x%llx (%d)\n", o, r); -+ goto err_free; -+ } -+ if (memcmp(md->buf, readbuf, mtd_writesize(md))) { -+ fprintf(stderr, "mtd: Verification error @0x%llx\n", o); -+ goto err_free; -+ } -+ } - } - - } -@@ -2466,16 +2487,31 @@ int mtd_commit_bcb(struct mtd_data *md, char *bcb_name, - if (md->flags & F_VERBOSE) - printf("%s(%s): status %d\n\n", __func__, bcb_name, err); - -- return err; -+err_free: -+ if (verify) -+ free(readbuf); -+ if (err) { -+ fprintf(stderr, "mtd: %d errors\n", err); -+ return -1; -+ } -+ else -+ return 0; - } - --int write_boot_stream(struct mtd_data *md, FILE *fp) -+int write_boot_stream(struct mtd_data *md, FILE *fp, int verify) - { - int startpage, start, size; - loff_t ofs, end; -- int i, r, chunk; -+ int i, r = 0, chunk; - int chip = 0; - struct fcb_block *fcb = &md->fcb.FCB_Block; -+ char *readbuf = NULL; -+ -+ if (verify) { -+ readbuf = malloc(mtd_writesize(md)); -+ if (NULL == readbuf) -+ return -1; -+ } - - vp(md, "---------- Start to write the [ %s ]----\n", (char*)md->private); - for (i = 0; i < 2; i++) { -@@ -2530,7 +2566,7 @@ int write_boot_stream(struct mtd_data *md, FILE *fp) - r = fread(md->buf, 1, chunk, fp); - if (r < 0) { - fprintf(stderr, "mtd: Failed %d (fread %d)\n", r, chunk); -- return -1; -+ goto err_free; - } - if (r < chunk) { - memset(md->buf + r, 0, chunk - r); -@@ -2539,10 +2575,30 @@ int write_boot_stream(struct mtd_data *md, FILE *fp) - - /* write page */ - r = mtd_write_page(md, chip, ofs, 1); -- if (r != mtd_writesize(md)) -+ if (r != mtd_writesize(md)) { - fprintf(stderr, "mtd: Failed to write BS @0x%llx (%d)\n", - ofs, r); -+ r = -1; -+ goto err_free; -+ } - -+ if (verify) { -+ //------------------------------------------------------ -+ // Verify the written data -+ //------------------------------------------------------ -+ r = pread(md->part[chip].fd, readbuf, -+ mtd_writesize(md), ofs); -+ if (r != mtd_writesize(md)) { -+ fprintf(stderr, "mtd: Failed to read BS @0x%llx (%d)\n", ofs, r); -+ r = -1; -+ goto err_free; -+ } -+ if (memcmp(md->buf, readbuf, mtd_writesize(md))) { -+ fprintf(stderr, "mtd: Verification error @0x%llx\n", ofs); -+ r = -1; -+ goto err_free; -+ } -+ } - ofs += mtd_writesize(md); - size -= chunk; - } -@@ -2555,19 +2611,26 @@ int write_boot_stream(struct mtd_data *md, FILE *fp) - */ - memset(md->buf, 0, mtd_writesize(md)); - r = mtd_write_page(md, chip, ofs, 1); -- if (r != mtd_writesize(md)) -+ if (r != mtd_writesize(md)) { - fprintf(stderr, "Failed to write safe page\n"); -+ r = -1; -+ goto err_free; -+ } - vp(md, "mtd: We write one page for save guard. *\n"); -- - if (ofs >= end) { - fprintf(stderr, "mtd: Failed to write BS#%d\n", i); -- return -1; -+ r = -1; -+ goto err_free; - } - } -- return 0; -+ -+err_free: -+ if (verify) -+ free(readbuf); -+ return r; - } - --int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) -+int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify) - { - int startpage, start, size; - unsigned int search_area_sz, stride; -@@ -2666,7 +2729,9 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - if (r < 0) - return r; - -- mtd_commit_bcb(md, "NCB", 0, 1, 0, 1, size, false); -+ r = mtd_commit_bcb(md, "NCB", 0, 1, 0, 1, size, false, verify); -+ if (r < 0) -+ return r; - } - - if (flags & UPDATE_LDLB) { -@@ -2675,7 +2740,10 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - memset(md->buf, 0, mtd_writesize(md)); - memcpy(md->buf, md->curr_ldlb, sizeof(*md->curr_ldlb)); - -- mtd_commit_bcb(md, "LDLB", 2, 3, 1, 1, mtd_writesize(md), true); -+ r = mtd_commit_bcb(md, "LDLB", 2, 3, 1, 1, mtd_writesize(md), true, -+ verify); -+ if (r < 0) -+ return r; - } - - if (flags & UPDATE_DBBT) { -@@ -2684,7 +2752,11 @@ int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - memset(md->buf, 0, mtd_writesize(md)); - memcpy(md->buf, md->curr_dbbt, sizeof(*md->curr_dbbt)); - -- mtd_commit_bcb(md, "DBBT", 4, 5, 2, 1, mtd_writesize(md), true); -+ r = mtd_commit_bcb(md, "DBBT", 4, 5, 2, 1, mtd_writesize(md), true, -+ verify); -+ if (r < 0) -+ return r; -+ - for (i = 0; i < 2; i++) { - for (j = 0; j < 2; j++) { - if (md->flags & F_MULTICHIP) { -@@ -2766,7 +2838,7 @@ static void write_dbbt(struct mtd_data *md, int dbbt_num) - } - } - --int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) -+int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify) - { - int size ,r; - -@@ -2779,8 +2851,11 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - size = mtd_writesize(md) + mtd_oobsize(md); - r = fcb_encrypt(&md->fcb, md->buf, size, 1); - if (r < 0) -- return r; -- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false); -+ return -1; -+ -+ r = mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false, verify); -+ if (r < 0) -+ return -1; - - //---------------------------------------------------------------------- - // Write the DBBT search area. -@@ -2788,14 +2863,17 @@ int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - memset(md->buf, 0, mtd_writesize(md)); - memcpy(md->buf, &(md->dbbt28), sizeof(md->dbbt28)); - dbbt_checksum(md, &md->dbbt28); -- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true); -+ r = mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true, -+ verify); -+ if (r < 0) -+ return -1; - write_dbbt(md, 1); /* only write the DBBT for nand0 */ - - /* write the boot image. */ -- return write_boot_stream(md, fp); -+ return write_boot_stream(md, fp, verify); - } - --int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) -+int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify) - { - int startpage, start, size; - unsigned int search_area_size_in_bytes, stride_size_in_bytes; -@@ -2832,7 +2910,9 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - memset(md->buf, 0, mtd_writesize(md)); - memcpy(md->buf, &(md->fcb), sizeof(md->fcb)); - -- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, mtd_writesize(md), true); -+ r = mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, mtd_writesize(md), true, verify); -+ if (r < 0) -+ return -1; - - //---------------------------------------------------------------------- - // Write the DBBT search area. -@@ -2841,7 +2921,9 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - memset(md->buf, 0, mtd_writesize(md)); - memcpy(md->buf, &(md->dbbt28), sizeof(md->dbbt28)); - -- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true); -+ r = mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true, verify); -+ if (r < 0) -+ return -1; - - //---------------------------------------------------------------------- - // Write the DBBT table area. -@@ -2985,7 +3067,7 @@ int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - return 0; - } - --int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) -+int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify) - { - int size, i, r, chip = 0; - loff_t ofs; -@@ -2997,12 +3079,16 @@ int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - r = fcb_encrypt(&md->fcb, md->buf, size, 1); - if (r < 0) - return r; -- mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false); -+ r = mtd_commit_bcb(md, "FCB", 0, 0, 0, 1, size, false, verify); -+ if (r < 0) -+ return r; - - /* [2] Write the DBBT search area. */ - memset(md->buf, 0, mtd_writesize(md)); - memcpy(md->buf, &(md->dbbt50), sizeof(md->dbbt50)); -- mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true); -+ r = mtd_commit_bcb(md, "DBBT", 1, 1, 1, 1, mtd_writesize(md), true, verify); -+ if (r < 0) -+ return -1; - - /* Write the DBBT table area. */ - memset(md->buf, 0, mtd_writesize(md)); -@@ -3023,7 +3109,7 @@ int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags) - } - - /* [3] Write the two boot streams. */ -- return write_boot_stream(md, fp); -+ return write_boot_stream(md, fp, verify); - } - - #undef ARG -diff --git a/src/mtd.h b/src/mtd.h -index 18e4d70..699e505 100644 ---- a/src/mtd.h -+++ b/src/mtd.h -@@ -295,11 +295,11 @@ int mtd_markbad(struct mtd_data *md, int chip, loff_t ofs); - #define UPDATE_BS(x) (0x08 << ((x) & 1)) - #define UPDATE_ALL (UPDATE_NCB | UPDATE_LDLB | UPDATE_DBBT | UPDATE_BS0 | UPDATE_BS1) - --int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags); --int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags); --int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags); --int v3_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags); --int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags); -+int v0_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify); -+int v1_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify); -+int v2_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify); -+int v3_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify); -+int v4_rom_mtd_commit_structures(struct mtd_data *md, FILE *fp, int flags, int verify); - - int mtd_set_ecc_mode(struct mtd_data *md, int ecc); - -diff --git a/src/plat_boot_config.h b/src/plat_boot_config.h -index 8242ede..a3c03a7 100644 ---- a/src/plat_boot_config.h -+++ b/src/plat_boot_config.h -@@ -55,7 +55,7 @@ typedef struct _platform_config_t { - uint32_t m_u32Arm_type; - uint32_t m_u32DBBT_FingerPrint; - int (* rom_mtd_init)(struct mtd_data *md, FILE *fp); -- int (* rom_mtd_commit_structures)(struct mtd_data *md, FILE *fp, int flags); -+ int (* rom_mtd_commit_structures)(struct mtd_data *md, FILE *fp, int flags, int verify); - } platform_config; - - extern platform_config *plat_config_data; diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0007-disable-use-of-nfc_geometry.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0007-disable-use-of-nfc_geometry.patch deleted file mode 100644 index 5d2e8bb9d..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0007-disable-use-of-nfc_geometry.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Javier Viguera -Date: Thu, 14 Nov 2013 16:46:01 +0100 -Subject: [PATCH] disable use of nfc_geometry - -Not supported in kernel v3.10 - -Signed-off-by: Javier Viguera ---- - src/plat_boot_config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/plat_boot_config.c b/src/plat_boot_config.c -index af7e03a47f1b..463045f0bc75 100644 ---- a/src/plat_boot_config.c -+++ b/src/plat_boot_config.c -@@ -46,7 +46,7 @@ static platform_config mx28_boot_config = { - .m_u32EnDISBBM = 0, - .m_u32EnSoftEcc = 1, - .m_u32EnBootStreamVerify = 1, -- .m_u32UseNfcGeo = 1, -+ .m_u32UseNfcGeo = 0, - .m_u32UseMultiBootArea = 0, - .m_u32UseSinglePageStride = 1, - .m_u32DBBT_FingerPrint = DBBT_FINGERPRINT2, diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0008-mtd-configure-16-bit-ECC-for-4K-page-NAND-with-224-b.patch b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0008-mtd-configure-16-bit-ECC-for-4K-page-NAND-with-224-b.patch deleted file mode 100644 index 23dcad30b..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng-3.0.35-4.1.0/0008-mtd-configure-16-bit-ECC-for-4K-page-NAND-with-224-b.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 62d43285dd08709c86b91ba0ae23c974e96c2905 Mon Sep 17 00:00:00 2001 -From: Hector Palacios -Date: Thu, 15 Oct 2015 12:31:24 +0200 -Subject: [PATCH] mtd: configure 16-bit ECC for 4K page NAND with 224-byte OOB - -Signed-off-by: Hector Palacios ---- - src/mtd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/mtd.c b/src/mtd.c -index 77ba3070de7a..4d04f4c2921d 100644 ---- a/src/mtd.c -+++ b/src/mtd.c -@@ -2124,7 +2124,7 @@ int v1_rom_mtd_init(struct mtd_data *md, FILE *fp) - if (mtd_writesize(md) == 2048) { - geo->ecc_strength = ROM_BCH_Ecc_8bit << 1; - } else if (mtd_writesize(md) == 4096) { -- if (mtd_oobsize(md) == 218) -+ if (mtd_oobsize(md) == 218 || mtd_oobsize(md) == 224) - geo->ecc_strength = ROM_BCH_Ecc_16bit << 1; - else if ((mtd_oobsize(md) == 128)) - geo->ecc_strength = ROM_BCH_Ecc_8bit << 1; diff --git a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb b/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb deleted file mode 100644 index 889e36673..000000000 --- a/meta-digi-arm/recipes-bsp/kobs-ng/kobs-ng_3.0.35-4.1.0.bb +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2013 Digi International. All rights reserved. - -SUMMARY = "Freescale's mxs nand update utility" -SECTION = "base" -LICENSE = "GPLv2" -LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833" - -inherit autotools - -SRC_URI = " \ - ${DIGI_PKG_SRC}/${PN}-${PV}.tar.gz \ - file://0001-makefile.am.patch \ - file://0002-fix-mtd-defines.patch \ - file://0003-cleanup-ROM-version-detection-code-and-add-cpx2-supp.patch \ - file://0004-discover-boot-ROM-version-from-FDT-if-available.patch \ - file://0005-dump-v1-boot-structures.patch \ - file://0006-added-option-to-verify-data-written-to-flash.patch \ - file://0007-disable-use-of-nfc_geometry.patch \ - file://0008-mtd-configure-16-bit-ECC-for-4K-page-NAND-with-224-b.patch \ -" - -SRC_URI[md5sum] = "2a0e55b5063605b2664fd67c95a6c686" -SRC_URI[sha256sum] = "92d2f23add8c5d3102c77f241cae26ca55871ccc613a7af833bebbbac7afb8ea" - -COMPATIBLE_MACHINE = "mxs" diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi.bb b/meta-digi-arm/recipes-bsp/libdigi/libdigi.bb deleted file mode 100644 index 6f9c00945..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi.bb +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2013,2017 Digi International. - -SUMMARY = "Digi's utilities library" -SECTION = "libs" -LICENSE = "GPL-2.0" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -SRC_URI = " \ - file://cmdopt.c \ - file://cmdopt.h \ - file://crc32.c \ - file://crc32.h \ - file://digi-platforms.h \ - file://log.c \ - file://log.h \ - file://mem.c \ - file://mem.h \ - file://misc_helper.h \ - file://platform.c \ -" - -S = "${WORKDIR}" - -do_compile() { - ${CC} -O2 -Wall ${LDFLAGS} -c -o log.o log.c - ${CC} -O2 -Wall ${LDFLAGS} -c -o cmdopt.o cmdopt.c - ${CC} -O2 -Wall ${LDFLAGS} -c -o mem.o mem.c - ${CC} -O2 -Wall ${LDFLAGS} -c -o crc32.o crc32.c - ${CC} -O2 -Wall ${LDFLAGS} -c -o platform.o platform.c - ${AR} -rcs libdigi.a log.o cmdopt.o mem.o crc32.o platform.o -} - -do_install() { - mkdir -p ${D}${includedir}/libdigi ${D}${libdir} - install -m 0644 libdigi.a ${D}${libdir} - install -m 0644 cmdopt.h crc32.h digi-platforms.h log.h mem.h misc_helper.h ${D}${includedir}/libdigi -} - -RDEPENDS_${PN}-dev = "" diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.c b/meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.c deleted file mode 100644 index 5deadbe5b..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.c +++ /dev/null @@ -1,366 +0,0 @@ -/*********************************************************************** - * - * Copyright 2001,2002 by FS-Forth Systeme GmbH. - * All rights reserved. - * - * $Id: cmdopt.c,v 1.4 2007-01-23 15:13:27 mpietrek Exp $ - * @Author: Markus Pietrek - * @Descr: Provides some helper functions to access the command line - * options. The results are stored in global variables. - * This file is not thread safe. - * - ********************************************************************** */ -/*********************************************************************** * - * @History: - * 2002/10/21 : Purified for splint. Changed to new variable - * naming convention. - * - *********************************************************************** */ - -#include -#include // toupper -#include // getopt -#include -#include // atoi -#include // strlen - -#include "cmdopt.h" -#include "log.h" -#include "misc_helper.h" - -#define BUFFER_SIZE 1024 -#define MAX_ENTRIES 32 - -/*@observer@*/ -void (*fnCmdOptExtendedUsage) (char bCmdLine) = NULL; -const char* szCmdOptVersion = "$Revision: 1.4 $"; // if not - // overwritten take - // at least the - // revision of cmdopt - -static CmdOptEntry cmdOptEntries[ MAX_ENTRIES ]; // to avoid malloc we - // use a static buffer -/*@noreturn@*/ -static void usageAndExit( int argc, - char* argv[], - const CmdOptEntry entries[], - const char* szDescr, - char cWrongNumber ); -static void updateVar( const CmdOptEntry entries[], - int nOptIndex, - const char* szStr ); - - -/*********************************************************************** - * @Function: cmdOptParse - * @Return: only if command line could be parsed otherwise ends - * the application. Result is only set if COT_MORE is specified - * and points to the first unprocessed entry - * @Descr: reads the command line and sets the variables. Displays a usage - * if values are wrong. - ***********************************************************************/ - -int cmdOptParse( int argc, - char* argv[], - const CmdOptEntry entries[], - const char* szDescr ) -{ - char szOptLine[ BUFFER_SIZE ]; - struct option axLongOptions[ MAX_ENTRIES ]; - int nOptIndex = 0; - int nSize = 0; - int nSizeLong = 0; - signed char cOptChar; - int nOptIndexStatic = 0; - int nOptLongIndex = 0; - char cPrintVersion = 0; - char cPrintHelp = 0; - - CmdOptEntry coePrintVersion = - {COT_BOOL, -1, &cPrintVersion, "version", "print version and exit" }; - CmdOptEntry coePrintHelp = - {COT_BOOL, 'h', &cPrintHelp, "help", "print help" }; - CmdOptEntry coeLogLevel = - {COT_INT, 'l', &logLevel, "log-level", "log level for messages" }; - - CLEAR( axLongOptions ); - - // add global default command line arguments - cmdOptEntries[ nOptIndexStatic++ ] = coePrintVersion; - cmdOptEntries[ nOptIndexStatic++ ] = coePrintHelp; - cmdOptEntries[ nOptIndexStatic++ ] = coeLogLevel; - - // copy default command line entries - // will break when all entries are copied to global area - // or too much arguments - while( 1 ) - { - if( nOptIndexStatic == MAX_ENTRIES ) - { - logMsg( LOG_ERR, "cmdOptParse: too many command line options" ); - exit( EXIT_FAILURE ); - } - - cmdOptEntries[ nOptIndexStatic ] = entries[ nOptIndex ]; - if( entries[ nOptIndex ].type == COT_NONE ) - // no more entries - break; - - nOptIndexStatic++; - nOptIndex++; - } - - // create parameter list for getopt - - nOptIndex = 0; - szOptLine[ nOptIndex ] = 0; - - while( cmdOptEntries[ nSize ].type != COT_NONE ) - { - if( ( cmdOptEntries[ nSize ].type != COT_MORE ) && - ( cmdOptEntries[ nSize ].type != COT_MORE_OPT ) ) { - axLongOptions[ nSizeLong ].name = cmdOptEntries[ nSize ].szLabelStr; - axLongOptions[ nSizeLong ].has_arg = - ((cmdOptEntries[ nSize ].type != COT_BOOL ) ? required_argument : no_argument); - axLongOptions[ nSizeLong ].flag = NULL; - axLongOptions[ nSizeLong ].val = -2 - nSize; - nSizeLong++; - } - - if( NULL != cmdOptEntries[ nSize ].pbPresent ) - *cmdOptEntries[ nSize ].pbPresent = 0; - if( !cmdOptEntries[ nSize ].cOptChar ) - { - // parameter is not mandatory - nSize++; - continue; - } - - if( nOptIndex >= BUFFER_SIZE - 2 ) - { - logMsg( LOG_ERR, - "cmdOptParse: too long command line" ); - exit( EXIT_FAILURE ); - } - - if( -1 != cmdOptEntries[ nSize ].cOptChar ) { - szOptLine[ nOptIndex++ ] = cmdOptEntries[ nSize ].cOptChar; - if( cmdOptEntries[ nSize ].type != COT_BOOL ) - szOptLine[ nOptIndex++ ] = ':'; - } - - szOptLine[ nOptIndex ] = 0; - - nSize++; - } - - // parse optional command line options - - while( ( cOptChar = getopt_long( argc, argv, szOptLine, axLongOptions, &nOptLongIndex ) ) != -1 ) - { - char cFound = 0; - - if( cOptChar < 0 ) { - cFound = 1; - updateVar( cmdOptEntries, -2 - cOptChar, optarg ); - } else { - for( nOptIndex = 0; nOptIndex < nSize; nOptIndex++ ) - { - if( cmdOptEntries[ nOptIndex ].cOptChar == cOptChar ) - { - // optional arguments only - cFound = 1; - updateVar( cmdOptEntries, nOptIndex, optarg ); - } - } - } - - if( !cFound ) - usageAndExit( argc, argv, cmdOptEntries, szDescr, 0 ); - } - - if( cPrintVersion ) - { - fprintf( stdout, "%s %s\n", - argv[ 0 ], - szCmdOptVersion ); - exit( EXIT_SUCCESS ); - } - - if( cPrintHelp ) - usageAndExit( argc, argv, cmdOptEntries, szDescr, 0 ); - - // parse mandatory command line options - - nOptIndex = 0; - for( nOptIndex = 0; nOptIndex < nSize; nOptIndex++ ) - if( !cmdOptEntries[ nOptIndex ].cOptChar ) - { - if( cmdOptEntries[ nOptIndex ].type == COT_MORE_OPT ) - // don't parse the following arguments as they - // can't be covered by this lib yet - return optind; - - if( !( argc - optind ) ) - usageAndExit( argc, argv, cmdOptEntries, szDescr, 1 ); - - if( cmdOptEntries[ nOptIndex ].type == COT_MORE ) - // don't parse the following arguments as they - // can't be covered by this lib yet - return optind; - - updateVar( cmdOptEntries, nOptIndex, argv[ optind++ ] ); - } - - if( argc - optind ) - // COT_MORE is aborted before - usageAndExit( argc, argv, cmdOptEntries, szDescr, 1 ); - - return 0; -} - -void cmdOptUsageAndExit( - int argc, - char* argv[], - const CmdOptEntry entries[], - const char* szDescr ) -{ - usageAndExit( argc, argv, entries, szDescr, 0 ); -} - - -/*********************************************************************** - * @Function: usageAndExit - * @Return: never - * @Descr: displays usage and exits with EXIT_FAILURE. If wrongNumber is 1, - * a message "too many arguments is displayed". - ***********************************************************************/ - -static void usageAndExit( /*@unused@*/ int argc, - char* argv[], - const CmdOptEntry entries[], - const char* szDescr, - char cWrongNumber ) -{ - int nOptIndex = 0; - size_t maxStrLen = 0; - - fprintf( stdout, "Usage: %s ", argv[ 0 ] ); - - // print command line arguments - while( entries[ nOptIndex ].type != COT_NONE ) - { - if( entries[ nOptIndex ].szLabelStr != NULL ) - { - // determine max len of labelStr for formatted output - size_t strLen = strlen( entries[ nOptIndex ].szLabelStr ); - - if( strLen > maxStrLen ) - maxStrLen = strLen; - } - - switch( entries[ nOptIndex ].type ) - { - case COT_BOOL: - case COT_INT: - case COT_STRING: - fprintf( stdout, "[--%s] ", entries[ nOptIndex ].szLabelStr ); - break; - case COT_MORE: - case COT_MORE_OPT: - fprintf( stdout, - "%s ", - entries[ nOptIndex ].szLabelStr ); - break; - case COT_NONE: - // will never happen but satisfies compiler - break; - } - nOptIndex++; - } - if( NULL != fnCmdOptExtendedUsage ) - fnCmdOptExtendedUsage( 1 ); - - fprintf( stdout, "\n" ); - - // explain command line options - nOptIndex = 0; - while( entries[ nOptIndex ].type != COT_NONE ) - { - fprintf( stdout, " " ); - fprintf( stdout, " %-*s", - (int) maxStrLen, - entries[ nOptIndex ].szLabelStr ); - - if( entries[ nOptIndex ].cOptChar > 0) - fprintf( stdout, " [-%c]", entries[ nOptIndex ].cOptChar ); - else - fprintf( stdout, " " ); - /*@+matchanyintegral*/ // maxStrLen is size_t. We shall - // unrestrict for this case the - // behaviour of splint because the - // compiler should do some - // checking, too - /*@-matchanyintegral*/ - - if( entries[ nOptIndex ].szHelpStr != NULL ) - fprintf( stdout, " : %s", entries[ nOptIndex ].szHelpStr ); - - fprintf( stdout, "\n" ); - nOptIndex++; - } - - if( NULL != fnCmdOptExtendedUsage ) - fnCmdOptExtendedUsage( 0 ); - - fprintf( stdout, "\n%s\n", szDescr ); - - // explain failure - if( cWrongNumber ) - fprintf( stderr, "\n*** Wrong # arguments ***\n" ); - - exit( EXIT_FAILURE ); -} - - -/*********************************************************************** - * @Function: updateVar - * @Return: nothing - * @Descr: sets the variable in entries[ index ] to the value in str - * and does conversion if necessary - ***********************************************************************/ - -static void updateVar( const CmdOptEntry entries[], - int nOptIndex, - const char* szStr ) -{ - switch( entries[ nOptIndex ].type ) - { - case COT_BOOL: - *((char*) entries[ nOptIndex ].vValuePtr) = 1; - break; - case COT_INT: - if( (int) strlen( szStr ) > 2 && - ((szStr[ 0 ] == '0' && (toupper( szStr[ 1 ] ) == 'X' )))) - { - sscanf( &szStr[ 2 ], - "%x", - ((int*) entries[ nOptIndex ].vValuePtr ) ); - break; - } - *((int*) entries[ nOptIndex ].vValuePtr) = atoi( szStr ); - break; - case COT_STRING: - *((const char**) entries[ nOptIndex ].vValuePtr) = szStr; - break; - case COT_MORE: - case COT_MORE_OPT: - case COT_NONE: - // will never happen but satisfies compiler - break; - } - - if( NULL != entries[ nOptIndex ].pbPresent ) - *entries[ nOptIndex ].pbPresent = 1; -} - diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.h b/meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.h deleted file mode 100644 index 7f9ca2ab5..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/cmdopt.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * libdigi/cmdopt.h - * - * Copyright (C) 2001,2002 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: Helper functions to access command line options. - * The results are stored in global variables. - * - */ - -#ifndef DG_CMDOPT_H -#define DG_CMDOPT_H - -typedef enum { - COT_BOOL, // if present,bool is set 1, otherwise unchanged - COT_INT, // sets *valuePtr to the int value - // with conversions (if 0x - // prefix is present) - COT_STRING, // sets *valuePtr to the string - COT_MORE, // to end the array. Any additional arguments - // are allowed - COT_MORE_OPT, // to end the array. Any optional arguments - // are allowed - COT_NONE // to end the array. Any additional arguments - // are considered as failures -} CmdOptTypes; - -typedef struct { - CmdOptTypes type; // type of option to be read - signed char cOptChar; // character to identify that option, if 0, then - // no option is used but parameter is required - void *vValuePtr; // ptr to the variable where value is stored - const char *szLabelStr; // label displayed in command line - const char *szHelpStr; // displays this help string for the variable - char *pbPresent; // will be set to if this option is present -} CmdOptEntry; - -/* can be set to display additional usage */ -extern void (*fnCmdOptExtendedUsage) (char bCmdLine); - -extern const char *szCmdOptVersion; // overwrite it before calling cmdOptParse to - // define version of application - -int cmdOptParse(int argc, char *argv[], const CmdOptEntry entries[], const char *szDescr); - -void cmdOptUsageAndExit(int argc, - char *argv[], const CmdOptEntry entries[], const char *szDescr); - -#endif /* DG_CMDOPT_H */ diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.c b/meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.c deleted file mode 100644 index 52d7aa710..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * crc32.c - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: Flash Test Util - * - */ - -#include "crc32.h" - -static const crc32_t crc32_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -crc32_t crc32(crc32_t uiCRC, const void *pvBuf, size_t iLen) -{ - const unsigned char *pcBuf = (const unsigned char *)pvBuf; - - /* uiCRC starts with 0 on first block. If run on a block, undoes the - previous uiCRC ^ 0xffffffff. */ - uiCRC ^= 0xffffffff; - - while (iLen-- > 0) - uiCRC = crc32_table[(uiCRC ^ *pcBuf++) & 0xff] ^ (uiCRC >> 8); - - /* if last block, this is the result. Otherwise this will be undone - on next crc32 call */ - return uiCRC ^ 0xffffffff; -} diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.h b/meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.h deleted file mode 100644 index 6cf7e1197..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/crc32.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * libdigi/crc32.h - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: CRC32 functions - * - */ - -#ifndef DG_CRC32_H -#define DG_CRC32_H - -#include /* uint32_t */ -#include /* size_t */ - -typedef uint32_t crc32_t; -extern crc32_t crc32(crc32_t uiCRC, const void *pvBuf, size_t iLen); - -#endif /* DG_CRC32_H */ diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/digi-platforms.h b/meta-digi-arm/recipes-bsp/libdigi/libdigi/digi-platforms.h deleted file mode 100644 index 6b4639e72..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/digi-platforms.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * libdigi/digi-platforms.h - * - * Copyright (C) 2011 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: Digi platforms - * - */ - -#ifndef DIGI_PLATFORMS_H -#define DIGI_PLATFORMS_H - -#define PLATFORM_NAME(x) x ## _NAME - -#define MACH_TYPE_CC7U 1017 -#define MACH_TYPE_CC7U_NAME "cc7u" -#define MACH_TYPE_CWIEM 1033 -#define MACH_TYPE_CWIEM_NAME "cwiem" -#define MACH_TYPE_CCW9C 1110 -#define MACH_TYPE_CCW9C_NAME "ccw9c" -#define MACH_TYPE_CC9P9360DEV 1114 -#define MACH_TYPE_CC9P9360DEV_NAME "cc9p9360dev" -#define MACH_TYPE_CC9P9750DEV 1115 -#define MACH_TYPE_CC9P9750DEV_NAME "cc9p9750dev" -#define MACH_TYPE_CC9P9360VAL 1116 -#define MACH_TYPE_CC9P9360VAL_NAME "cc9p9360val" -#define MACH_TYPE_CC9P9750VAL 1117 -#define MACH_TYPE_CC9P9750VAL_NAME "cc9p9750val" -#define MACH_TYPE_CC9P9360JS 1264 -#define MACH_TYPE_CC9P9360JS_NAME "cc9p9360js" -#define MACH_TYPE_CC9P9215 1445 -#define MACH_TYPE_CC9P9215_NAME "cc9p9215" -#define MACH_TYPE_CC9P9210 1446 -#define MACH_TYPE_CC9P9210_NAME "cc9p9210" -#define MACH_TYPE_CC9P9215JS 1447 -#define MACH_TYPE_CC9P9215JS_NAME "cc9p9215js" -#define MACH_TYPE_CC9P9210JS 1448 -#define MACH_TYPE_CC9P9210JS_NAME "cc9p9210js" -#define MACH_TYPE_CC7UCAMRY 1493 -#define MACH_TYPE_CC7UCAMRY_NAME "cc7ucamry" -#define MACH_TYPE_CC9M2443JS 1663 -#define MACH_TYPE_CC9M2443JS_NAME "cc9m2443js" -#define MACH_TYPE_CME9210 1712 -#define MACH_TYPE_CME9210_NAME "cme9210" -#define MACH_TYPE_CCW9P9215JS 1811 -#define MACH_TYPE_CCW9P9215JS_NAME "ccw9p9215js" -#define MACH_TYPE_CC9M2443 1815 -#define MACH_TYPE_CC9M2443_NAME "cc9m2443" -#define MACH_TYPE_CME9210JS 1854 -#define MACH_TYPE_CME9210JS_NAME "cme9210js" -#define MACH_TYPE_CC9P9360 1855 -#define MACH_TYPE_CC9P9360_NAME "cc9p9360" -#define MACH_TYPE_CCW9P9215 2137 -#define MACH_TYPE_CCW9P9215_NAME "ccw9p9215" -#define MACH_TYPE_CCW9M2443 2145 -#define MACH_TYPE_CCW9M2443_NAME "ccw9m2443" -#define MACH_TYPE_CCW9M2443JS 2146 -#define MACH_TYPE_CCW9M2443JS_NAME "ccw9m2443js" -#define MACH_TYPE_CC9P9215_3G 2397 -#define MACH_TYPE_CC9P9215_3G_NAME "cc9p9215_3g" -#define MACH_TYPE_CC9P9215_3GJS 2398 -#define MACH_TYPE_CC9P9215_3GJS_NAME "cc9p9215_3gjs" -#define MACH_TYPE_CCMX51 2516 -#define MACH_TYPE_CCMX51_NAME "ccmx51" -#define MACH_TYPE_CCMX51JS 2517 -#define MACH_TYPE_CCMX51JS_NAME "ccmx51js" -#define MACH_TYPE_CCWMX51 2518 -#define MACH_TYPE_CCWMX51_NAME "ccwmx51" -#define MACH_TYPE_CCWMX51JS 2519 -#define MACH_TYPE_CCWMX51JS_NAME "ccwmx51js" -#define MACH_TYPE_CWME9210 3320 -#define MACH_TYPE_CWME9210_NAME "cwme9210" -#define MACH_TYPE_CWME9210JS 3321 -#define MACH_TYPE_CWME9210JS_NAME "cwme9210js" -#define MACH_TYPE_CCMX53 3346 -#define MACH_TYPE_CCMX53_NAME "ccmx53" -#define MACH_TYPE_CCMX53JS 3347 -#define MACH_TYPE_CCMX53JS_NAME "ccmx53js" -#define MACH_TYPE_CCWMX53 3348 -#define MACH_TYPE_CCWMX53_NAME "ccwmx53" -#define MACH_TYPE_CCWMX53JS 3349 -#define MACH_TYPE_CCWMX53JS_NAME "ccwmx53js" -#define MACH_TYPE_CPX2 3419 -#define MACH_TYPE_CPX2_NAME "cpx2" -#define MACH_TYPE_WR21 3737 -#define MACH_TYPE_WR21_NAME "wr21" -#define MACH_TYPE_CCARDWMX28 3893 -#define MACH_TYPE_CCARDWMX28_NAME "ccardwmx28" -#define MACH_TYPE_CCARDMX28 3894 -#define MACH_TYPE_CCARDMX28_NAME "ccardmx28" -#define MACH_TYPE_CCARDWMX28JS 3917 -#define MACH_TYPE_CCARDWMX28JS_NAME "ccardwmx28js" -#define MACH_TYPE_CCARDMX28JS 3918 -#define MACH_TYPE_CCARDMX28JS_NAME "ccardmx28js" -#define MACH_TYPE_CCIMX53 9980 -#define MACH_TYPE_CCIMX53_NAME "ccimx53" -#define MACH_TYPE_CCIMX53JS 9981 -#define MACH_TYPE_CCIMX53JS_NAME "ccimx53js" -#define MACH_TYPE_CCIMX51 9982 -#define MACH_TYPE_CCIMX51_NAME "ccimx51" -#define MACH_TYPE_CCIMX51JS 9983 -#define MACH_TYPE_CCIMX51JS_NAME "ccimx51js" -#define MACH_TYPE_CCARDIMX28 9984 -#define MACH_TYPE_CCARDIMX28_NAME "ccardimx28" -#define MACH_TYPE_CCARDIMX28JS 9985 -#define MACH_TYPE_CCARDIMX28JS_NAME "ccardimx28js" - -int get_platform_id(void); -char is_nand_oob_atomic(void); - -#endif /* DIGI_PLATFORMS_H */ diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/log.c b/meta-digi-arm/recipes-bsp/libdigi/libdigi/log.c deleted file mode 100644 index 5aeebafc2..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/log.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * log.c - * - * Copyright (C) 2001,2002 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: implements logging interface - * - */ - -#include // fprintf -#include // EXIT_FAILURE -#include // errno -#include // h_errno -#include // strerror -#include // vprintf - -#include "log.h" - -/* Globaly visible */ -LogLevel logLevel = LOG_STATUS; - - -/*********************************************************************** - * @Function: log - * @Return: nothing - * @Descr: format and arg1..arg3 are printed on stderr only if level - * is <= logLevel - * format may not contain any newline character. - ***********************************************************************/ -void logMsg(LogLevel level, const char *szFormat, ...) -{ - if (level <= logLevel) { - va_list ap; - - /*@-formatconst@ */ - va_start(ap, szFormat); - vfprintf(stderr, szFormat, ap); - va_end(ap); - /*@-formatconst@ */ - fputs("\n", stderr); - } -} - -/*********************************************************************** - * @Function: systemLog - * @Return: nothing - * @Descr: dumps the system error that happened just before - ***********************************************************************/ -void systemLog(const char *szFormat, ...) -{ - char *szError = NULL; - va_list ap; - - if (errno) - szError = strdup(strerror(errno)); - else if (h_errno) - szError = strdup(hstrerror(h_errno)); - - /*@-formatconst@ */ - va_start(ap, szFormat); - vfprintf(stderr, szFormat, ap); - va_end(ap); - /*@-formatconst@ */ - if (NULL != szError) - fprintf(stderr, " (%s)", szError); - - fputs("\n", stderr); - - if (NULL != szError) - free(szError); -} - -/*********************************************************************** - * @Function: error - * @Return: never - * @Descr: format and arg1..arg3 are printed on stderr only if level - * is <= logLevel - * format may not contain any newline character. - ***********************************************************************/ -void error(const char *szFormat, ...) -{ - va_list ap; - - fprintf(stderr, "*** Error: "); - /*@-formatconst@ */ - va_start(ap, szFormat); - vfprintf(stderr, szFormat, ap); - va_end(ap); - /*@-formatconst@ */ - fputs("\n", stderr); - - exit(EXIT_FAILURE); -} - -/*********************************************************************** - * @Function: systemError - * @Return: never - * @Descr: dumps the system error that happened just before and exits the - * application - ***********************************************************************/ -void systemError(const char *szFormat, ...) -{ - char *szError = NULL; - va_list ap; - - if (errno) - szError = strdup(strerror(errno)); - else if (h_errno) - szError = strdup(hstrerror(h_errno)); - - fprintf(stderr, "*** Error: "); - /*@-formatconst@ */ - va_start(ap, szFormat); - vfprintf(stderr, szFormat, ap); - va_end(ap); - /*@-formatconst@ */ - if (NULL != szError) - fprintf(stderr, " (%s)", szError); - - fputs("\n", stderr); - free(szError); - - exit(EXIT_FAILURE); -} diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/log.h b/meta-digi-arm/recipes-bsp/libdigi/libdigi/log.h deleted file mode 100644 index 26f573f64..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/log.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * libdigi/log.h - * - * Copyright (C) 2001,2002 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: Logging facility for applications - * - */ - -#ifndef DG_LOG_H -#define DG_LOG_H - -typedef enum { - LOG_ERR = 0, - LOG_STATUS, - LOG_HARDWARE1, - LOG_HARDWARE2, - LOG_PACKET, - LOG_LAST -} LogLevel; - -extern LogLevel logLevel; - -extern void logMsg(LogLevel level, const char *szFormat, ...); -extern void systemLog(const char *szFormat, ...); -extern void error(const char *szFormat, ...); -extern void systemError(const char *szFormat, ...); - -#endif /* DG_LOG_H */ diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.c b/meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.c deleted file mode 100644 index df4a853f9..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * mem.c - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: provides MemCmp() and MemDump() - * - */ - -#include /* printf */ - -#include "mem.h" - -/*********************************************************************** - * !Function: MemCmp - * !Descr: compares memory - * !Return: offset of failure or -1 if none - ***********************************************************************/ -loff_t MemCmp(const void *pvS1, const void *pvS2, size_t iSize) -{ - const char *pcS2 = (const char *)pvS2; - const char *pcS1 = (const char *)pvS1; - loff_t iOffset = 0; - - while (iOffset < iSize) { - if (*pcS2 != *pcS1) - return iOffset; - - pcS2++; - pcS1++; - iOffset++; - } - - return -1; -} - -/*********************************************************************** - * !Function: MemDump - * !Descr: Prints memory from pvbase + iOffset to pvBase + iOffset + iLen - ***********************************************************************/ -void MemDump(const void *pvBase, loff_t iOffset, size_t iLen) -{ - const unsigned char *pucBuf = (const unsigned char *)pvBase + iOffset; - const int COLUMN_COUNT = 16; - int i; - - for (i = 0; i < iLen; i += COLUMN_COUNT) { - /* print one row */ - int j, iRowLen; - - if ((i + COLUMN_COUNT) <= iLen) - iRowLen = COLUMN_COUNT; - else - iRowLen = iLen - i; - - printf("%08llx ", (long long)iOffset); - - /* print hexadecimal representation */ - for (j = 0; j < iRowLen; j++) { - printf("%02x ", *(pucBuf + j)); - if (((COLUMN_COUNT / 2) - 1) == j) - /* additional separator */ - printf(" "); - } - - printf(" "); - - /* print character representation row */ - for (j = 0; j < iRowLen; j++) { - unsigned char c = *(pucBuf + j); - if ((c < 32) || (c > 127)) - c = '.'; - - if (((COLUMN_COUNT / 2) - 1) == j) - /* additional separator */ - printf(" "); - - printf("%c", c); - } - - printf("\r\n"); - pucBuf += iRowLen; - iOffset += iRowLen; - } -} diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.h b/meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.h deleted file mode 100644 index 0316e6d56..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/mem.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * libdigi/mem.h - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: provides MemCmp() and MemDump() - * - */ - -#ifndef DG_MEM_H -#define DG_MEM_H - -#include /* size_t */ - -extern loff_t MemCmp(const void *pvS1, const void *pvS2, size_t iSize); -extern void MemDump(const void *pvBase, loff_t iOffset, size_t iLen); - -#endif /* DG_MEM_H */ diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/misc_helper.h b/meta-digi-arm/recipes-bsp/libdigi/libdigi/misc_helper.h deleted file mode 100644 index d809980f6..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/misc_helper.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * libdigi/misc_helper.h - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: miscellaneous definitions that simplifies developing - * May require 'string.h' or 'log.h' - * - */ - -#ifndef DG_MISC_HELPER_H -#define DG_MISC_HELPER_H - -#include /* snprintf */ -#include /* memset */ - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x))) -#define CLEAR(x) memset( &x, 0, sizeof( x ) ) - -/* round up to kB */ -#define TO_KiB(x) (((x) + 1023) / 1024) - -/* to bytes */ -#define KiB(x) ((x) * 1024) -#define MiB(x) (KiB(x) * 1024) - -#define MAX(a, b) ((a) < (b) ? (b) : (a)) -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -#define FREE(x) \ - do { \ - free((void *)x); \ - x = NULL; \ - } while (0) - -#define CLOSE(x) \ - do { \ - if (close(x)) \ - systemError("close"); \ - x = -1; \ - } while (0) - -#define SPRINTF(acStr, args...) \ - snprintf(acStr, sizeof(acStr), args) - -#endif /* DG_MISC_HELPER_H */ diff --git a/meta-digi-arm/recipes-bsp/libdigi/libdigi/platform.c b/meta-digi-arm/recipes-bsp/libdigi/libdigi/platform.c deleted file mode 100644 index 25d37c514..000000000 --- a/meta-digi-arm/recipes-bsp/libdigi/libdigi/platform.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2011 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version2 as published by - * the Free Software Foundation. -*/ - -#include -#include -#include -#include - -#include "digi-platforms.h" -#include "log.h" - -/* - * Gets the platform ID from the file /proc/cpuinfo - * (the kernel needs to write the machine ID in this file). - * Returns the machine ID or -1 on error - */ -int get_platform_id(void) -{ - char buffer[80]; - FILE *fp; - long id = -1; - - fp = popen("cat /proc/cpuinfo | grep \"Machine ID\" | cut -f 2 -d :", "r"); - if (fp == NULL) - systemError("cannot access /proc/cpuinfo"); - - if (fgets(buffer, sizeof(buffer) - 1, fp)) { - errno = 0; /* to distinguish success/failure after call */ - id = strtol(buffer, NULL, 10); - if (errno != 0) - id = -1; /* don't care about the error code */ - } - fclose(fp); - - return id; -} - -/* - * get_platform_name_from_fdt - * - * Read the device tree and return platform name or NULL - */ -static char *get_platform_name_from_fdt(void) -{ - static const char *fdt = "/proc/device-tree/digi,machine,name"; - static char buffer[64]; /* static buffer so it can be used in the caller function */ - char *plat_name = NULL; - FILE *fp; - - fp = fopen(fdt, "r"); - if (fp == NULL) - goto out; - - plat_name = fgets(buffer, sizeof(buffer), fp); - fclose(fp); - -out: - return plat_name; -} - -/* - * Checks whether platform requires an atomic access to NAND OOB - */ -char is_nand_oob_atomic(void) -{ - int platform_id; - - platform_id = get_platform_id(); - if (platform_id != -1) { - /* The following platforms require atomic access to NAND OOB */ - if (MACH_TYPE_CPX2 == platform_id || - MACH_TYPE_WR21 == platform_id || - MACH_TYPE_CCMX51 == platform_id || - MACH_TYPE_CCMX51JS == platform_id || - MACH_TYPE_CCWMX51 == platform_id || - MACH_TYPE_CCWMX51JS == platform_id || - MACH_TYPE_CCIMX51 == platform_id || - MACH_TYPE_CCIMX51JS == platform_id || - MACH_TYPE_CCMX53 == platform_id || - MACH_TYPE_CCMX53JS == platform_id || - MACH_TYPE_CCWMX53 == platform_id || - MACH_TYPE_CCWMX53JS == platform_id || - MACH_TYPE_CCIMX53 == platform_id || - MACH_TYPE_CCIMX53JS == platform_id || - MACH_TYPE_CCARDMX28 == platform_id || - MACH_TYPE_CCARDMX28JS == platform_id || - MACH_TYPE_CCARDWMX28 == platform_id || - MACH_TYPE_CCARDWMX28JS == platform_id || - MACH_TYPE_CCARDIMX28 == platform_id || - MACH_TYPE_CCARDIMX28JS == platform_id) - return 1; - } else { - /* - * Workaround to detect is_nand_oob_atomic in ccardimx28 using - * linux 3.x - * TODO: generalize this. - */ - char *platform_name = get_platform_name_from_fdt(); - if (platform_name && !strcmp(platform_name, "ccardimx28")) - return 1; - } - - return 0; -} diff --git a/meta-digi-arm/recipes-bsp/nvram/nvram.inc b/meta-digi-arm/recipes-bsp/nvram/nvram.inc deleted file mode 100644 index 8b0506d23..000000000 --- a/meta-digi-arm/recipes-bsp/nvram/nvram.inc +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (C) 2013 Digi International. - -SUMMARY = "Digi's NVRAM tool" -SECTION = "base" -LICENSE = "GPL-2.0" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -require recipes-bsp/u-boot/u-boot-dey-rev_${PV}.inc - -DEPENDS = "libdigi" - -SRC_URI += " \ - file://main.c \ - file://nvram_priv_linux.c \ -" - -S = "${WORKDIR}" - -CMD_GIT_SHA1 = "$(cd ${THISDIR} && git rev-parse --short=7 HEAD)" -LIB_GIT_SHA1 = "$(cd ${WORKDIR}/git && git rev-parse --short=7 HEAD)" - -EXTRA_CFLAGS = "-Wall -DLINUX -DCMD_GIT_SHA1=\"${CMD_GIT_SHA1}\" -DLIB_GIT_SHA1=\"${LIB_GIT_SHA1}\" -Ilib/include -I${STAGING_INCDIR}/libdigi" - -do_configure() { - rm -f lib && ln -s ${UBOOT_NVRAM_LIBPATH} -} - -do_compile() { - # 'libnvram.a' static library - ${CC} ${CFLAGS} ${EXTRA_CFLAGS} -c -o nvram.o lib/src/nvram.c - ${CC} ${CFLAGS} ${EXTRA_CFLAGS} -c -o nvram_cmdline.o lib/src/nvram_cmdline.c - ${CC} ${CFLAGS} ${EXTRA_CFLAGS} -c -o nvram_priv_linux.o nvram_priv_linux.c - ${AR} -rcs libnvram.a nvram.o nvram_cmdline.o nvram_priv_linux.o - # 'nvram' command-line tool - ${CC} ${CFLAGS} ${EXTRA_CFLAGS} -c -o main.o main.c - ${CC} ${LDFLAGS} -o nvram main.o libnvram.a -ldigi -} - -do_install() { - mkdir -p ${D}${base_sbindir} ${D}${includedir} ${D}${libdir} - install -m 0644 libnvram.a ${D}${libdir}/ - install -m 0644 lib/include/nvram.h lib/include/nvram_types.h ${D}${includedir}/ - install -m 0755 nvram ${D}${base_sbindir}/ -} - -PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/meta-digi-arm/recipes-bsp/nvram/nvram/main.c b/meta-digi-arm/recipes-bsp/nvram/nvram/main.c deleted file mode 100644 index f3627cf0f..000000000 --- a/meta-digi-arm/recipes-bsp/nvram/nvram/main.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * nvram/src/main.c - * - * Copyright (C) 2006-2013 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version2 as published by - * the Free Software Foundation. - */ -/* - * !Author: Markus Pietrek - * !Descr: main() and user code for nvram. - */ - -#include /* errno */ -#include /* open */ -#include /* vprintf */ -#include /* snprintf */ -#include /* EXIT_SUCCESS */ -#include /* strdup */ -#include - -/* from libdigi */ -#include -#include -#include - -#include "nvram.h" /* Nv* */ - -#define CA(cmd) \ - do { \ - if( !cmd ) \ - ExitError( #cmd ); \ - } while( 0 ) - -#define VERSION "1.15" "-g"CMD_GIT_SHA1 - -/* Hack to change priv_linux mode */ -void NvPrivLinuxSetMode(char bManufMode); - -/* local functions */ -static void ExitError(const char *szFormat, ...); -static void OnExit(void); -static void ExtendedUsage(char bCmdLine); -static void OSLoadFromFile(nv_os_type_e eOS, const char *szFile); -static void OSSaveToFile(nv_os_type_e eOS, const char *szFile); - -static char l_bOptDetailed = 0; -static char quiet = 0; -static char l_bManufMode = 0; - -int main(int argc, char *argv[]) -{ - char acVersion[128]; - uint32_t uiLibVerMajor; - uint32_t uiLibVerMinor; - int iExtendedArgs; - const char *xPrintAll[] = { "printall" }; - const char *szOSOutFile = NULL; - const char *szOSInFile = NULL; - const char *szOS = NULL; - char bSave = 0; - nv_os_type_e eOS = NVOS_NONE; - int ret; - - CmdOptEntry aCmdEntries[] = { - /*@@-nullassign@@ */// only COT_NONE may have a NULL for vValuePtr - {COT_BOOL, 'e', &l_bOptDetailed, "error_detailed", - "detailed error messages"}, - {COT_BOOL, 'b', &g_markBadBlocks, "bad-block-marking", - "On repeated error, mark block as bad."}, - {COT_STRING, 'g', &szOSOutFile, "get_os_cfg", - "copies the os configuration block to file"}, - {COT_STRING, 's', &szOSInFile, "set_os_cfg", - "copies the os configuration block from file"}, - {COT_STRING, 'o', &szOS, "os", - "select's the OS to get configuration from"}, - {COT_BOOL, 'q', &quiet, "quiet", - "display no error messages"}, - {COT_BOOL, 'm', &l_bManufMode, "manuf-mode", - "manufacturing mode (no auto-repair, permit reset)"}, - {COT_MORE_OPT, 0, NULL, "", ""}, - {COT_NONE, 0, NULL, NULL, NULL}, - /*@@+nullassign@@ */ - }; - - NvGetLibVersion(&uiLibVerMajor, &uiLibVerMinor); - snprintf(acVersion, - sizeof(acVersion) - 1, - "Version: " VERSION ", NVRAM Library %u.%u-g" LIB_GIT_SHA1 ", compiled on " - __DATE__ "," __TIME__, uiLibVerMajor, uiLibVerMinor); - acVersion[sizeof(acVersion) - 1] = 0U; - szCmdOptVersion = acVersion; - fnCmdOptExtendedUsage = ExtendedUsage; - - iExtendedArgs = cmdOptParse(argc, argv, aCmdEntries, - "NVRAM Tool for updating nvram settings"); - logMsg(LOG_HARDWARE1, - "Sizes: Critical: %i\n" - " Module ID: %i\n" - " IP: %i\n" - " IP Device: %i\n" - " Partition Table: %i\n" - " Partition Entry: %i\n" - " OS Cfg Table: %i\n" - " OS Cfg: %i\n", - sizeof(nv_critical_t), - sizeof(nv_param_module_id_t), - sizeof(nv_param_ip_t), - sizeof(nv_param_ip_device_t), - sizeof(nv_param_part_table_t), - sizeof(nv_param_part_t), - sizeof(nv_param_os_cfg_table_t), - sizeof(nv_param_os_cfg_t)); - - /* so we can close everything even on error() or on return of main */ - atexit(OnExit); - - NvPrivLinuxSetMode(l_bManufMode); - - /* In manufacturing mode, do not let library auto-repair the NVRAM */ - ret = NvInit(l_bManufMode ? NVR_MANUAL : NVR_AUTO); - if (!ret) { - /* If NVRAM was not initialized, only continue if - * we are requesting a reset. - */ - if (argc == iExtendedArgs) { - ExitError("NvInit"); - } else { - if (strcmp("reset", argv[iExtendedArgs])) - ExitError("NvInit"); - } - } - - if (NULL != szOS) { - if (!NvToOS(&eOS, szOS)) - error("OS not known: %s\n", szOS); - } - - if (NULL != szOSInFile) { - bSave = 1; - OSLoadFromFile(eOS, szOSInFile); - } - - if (NULL != szOSOutFile) - /* it's load from NVRAM view */ - OSSaveToFile(eOS, szOSOutFile); - - if (argc == iExtendedArgs) { - if ((NULL == szOSInFile) && (NULL == szOSOutFile)) - /* on -o, the user likes to read/write something */ - CA(NvCmdLine(ARRAY_SIZE(xPrintAll), xPrintAll)); - } else { - CA(NvCmdLine(argc - iExtendedArgs, (const char **)&argv[iExtendedArgs])); - - if (!strcmp("set", argv[iExtendedArgs]) || - !strcmp("reset", argv[iExtendedArgs]) || - !strcmp("init", argv[iExtendedArgs])) - bSave = 1; - } - - if (bSave) - CA(NvSave()); - - return EXIT_SUCCESS; -} - -/* ********** local functions ********** */ - -static void ExtendedUsage(char bCmdLine) -{ - if (bCmdLine == 1) - CA(NvPrintHelp()); -} - -static void ExitError(const char *szFormat, ...) -{ - const char *szError = NULL; - const char *szWhat = NULL; - const char *szFunc = NULL; - const char *szFile = NULL; - int iLine; - - va_list ap; - - if (!quiet || l_bOptDetailed) { - fprintf(stderr, "*** Error: "); - if (l_bOptDetailed) { - /*@-formatconst@ */ - va_start(ap, szFormat); - vfprintf(stderr, szFormat, ap); - va_end(ap); - fprintf(stderr, ": "); - /*@+formatconst@ */ - } - - if (NVE_GOOD != NvErrorMsg(&szError, &szWhat, &szFunc, &szFile, &iLine)) { - if (l_bOptDetailed) - fprintf(stderr, " %s: (%s) @ %s:%i (%s)", - szError, szWhat, szFile, iLine, szFunc); - else - fprintf(stderr, " %s: (%s)", szError, szWhat); - } - - fprintf(stderr, "\n"); - } - - exit(EXIT_FAILURE); -} - -static void OSLoadFromFile(nv_os_type_e eOS, const char *szFile) -{ - int iFd; - nv_param_os_cfg_t xCfg; - void *pvTmp; - - CA(NvOSCfgFind(&xCfg, eOS)); - pvTmp = malloc(xCfg.uiSize); - if (NULL == pvTmp) - systemError("malloc: %i", xCfg.uiSize); - - iFd = open(szFile, O_RDONLY); - if (-1 == iFd) - systemError("%s", szFile); - if (-1 == read(iFd, pvTmp, xCfg.uiSize)) - systemError("read"); - CLOSE(iFd); - - CA(NvOSCfgSet(eOS, pvTmp, xCfg.uiSize)); - - FREE(pvTmp); - - printf("Loaded from %s\n", szFile); -} - -static void OSSaveToFile(nv_os_type_e eOS, const char *szFile) -{ - int iFd; - nv_param_os_cfg_t xCfg; - void *pvTmp; - size_t iSize; - - CA(NvOSCfgFind(&xCfg, eOS)); - pvTmp = malloc(xCfg.uiSize); - if (NULL == pvTmp) - systemError("malloc: %i", xCfg.uiSize); - - CA(NvOSCfgGet(eOS, pvTmp, xCfg.uiSize, &iSize)); - - iFd = open(szFile, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (-1 == iFd) - systemError("%s", szFile); - if (xCfg.uiSize != write(iFd, pvTmp, xCfg.uiSize)) - systemError("write"); - CLOSE(iFd); - FREE(pvTmp); - - printf("Stored to %s\n", szFile); -} - -/*! \brief closes all descriptors on any exit */ -static void OnExit(void) -{ - NvFinish(); -} diff --git a/meta-digi-arm/recipes-bsp/nvram/nvram/nvram_priv_linux.c b/meta-digi-arm/recipes-bsp/nvram/nvram/nvram_priv_linux.c deleted file mode 100644 index 47cbffe65..000000000 --- a/meta-digi-arm/recipes-bsp/nvram/nvram/nvram_priv_linux.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * nvram/src/nvram_priv_linux.c - * - * Copyright (C) 2006-2013 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version2 as published by - * the Free Software Foundation. - */ -/* - * !Author: Markus Pietrek - * !Descr: Defines the private functions needed by the nvram core to - * access I2C, Flash and a console for linux userspace. - */ - -#define _XOPEN_SOURCE 500 /* for pread/pwrite */ - -#include /* ENOTSUP */ -#include /* open */ -#include /* MEMERASE */ -#include /* vprintf */ -#include /* ioctl */ -#include /* stat */ - -/* from libdigi */ -#include /* systemError */ -#include /* CLEAR */ - -#include "nvram_priv.h" - -#define NVRAM_PARTITION 1 - -char g_markBadBlocks = 0; - -/* ********** local variables ********** */ -static char l_acMtd[32]; -static int l_iFdMtd = -1; -static mtd_info_t l_xMtdInfo; -static unsigned char bbMaxRetries = 3; -extern void MemDump(const void *pvBase, loff_t iOffset, size_t iLen); - -static char l_bManufMode = 0; - -/* ********** global functions ********** */ -void NvPrivLinuxSetMode(char bManufMode) -{ - /* Hack so linux nvram can change behavior of priv_linux */ - /* without ubootenv also changing. */ - l_bManufMode = bManufMode; -} - -int NvPrivOSInit(void) -{ - struct stat xStat; - - CLEAR(xStat); - - /* detect NVRAM partition */ - SPRINTF(l_acMtd, "/dev/mtd/%i", NVRAM_PARTITION); - - /* determine whether we are /dev/mtd/ or /dev/mtd */ - if (-1 == stat(l_acMtd, &xStat)) { - SPRINTF(l_acMtd, "/dev/mtd%i", NVRAM_PARTITION); - /* not dev fs */ - if (-1 == stat(l_acMtd, &xStat)) - return NV_SET_ERROR(NVE_NO_DEV, strerror(errno)); - } - - return 1; -} - -int NvPrivOSFinish(void) -{ - return 1; -} - -int NvPrivOSPostInit(void) -{ - return 1; -} - -int NvPrivOSCriticalPostReset(struct nv_critical *pParams) -{ - /* nothing to do */ - return 1; -} - -int NvPrivOSCriticalPartReset(struct nv_critical *pCrit, nv_os_type_e eForOS) -{ - if (l_bManufMode) { - /* - * In manufacturing mode, don't return an error, assuming - * that caller knows what they're doing. - */ - return 1; - } else { - /* - * Retain previous behavior of returning an error, which - * will cause us to exit before calling NvSave(); this is - * done to prevent 'nvram reset' from linux from erasing the - * OSCfgTable, since we won't properly restore the ubootenv - * section. - */ - RETURN_NOT_IMPLEMENTED(); - } -} - -int NvPrivOSFlashOpen(char bForWrite) -{ - l_iFdMtd = open(l_acMtd, bForWrite ? (O_RDWR | O_SYNC) : O_RDONLY); - if (-1 == l_iFdMtd) - return NV_SET_ERROR(NVE_NO_DEV, strerror(errno)); - - CLEAR(l_xMtdInfo); - /* read partition info */ - if (ioctl(l_iFdMtd, MEMGETINFO, &l_xMtdInfo)) { - CLOSE(l_iFdMtd); - return NV_SET_ERROR(NVE_NO_DEV, strerror(errno)); - } - - return 1; -} - -int NvPrivOSFlashClose(void) -{ - CLOSE(l_iFdMtd); - - return 1; -} - -/* A block is marked as bad as a consequence of consecutive read/write errors, - * for example unrecoverable CRC errors, or if the data verification after a - * write finds data mismatch after a number of retries. */ -static int NvPrivMarkBadBlock(int fd, loff_t iOffset) -{ - logMsg(LOG_STATUS, "Marking offset %d as bad\n", (int)iOffset); - return (ioctl(fd, MEMSETBADBLOCK, &iOffset)); -} - -int NvPrivOSFlashRead(void *pvBuf, loff_t iOffs, size_t iLength) -{ - int iRead; - int i, iRet; - - for (i = 0; i < bbMaxRetries; i++) { - iRead = pread(l_iFdMtd, pvBuf, iLength, iOffs); - - if (iRead != iLength) { - if (g_markBadBlocks) { - systemLog("Retrying failed read:Got %i " - "Bytes instead of %i.\n", iRead, iLength); - continue; - } else { - systemLog("read failed. Got %i Bytes " - "instead of %i\n", iRead, iLength); - return NV_SET_ERROR(NVE_IO, strerror(errno)); - } - } - break; - } - - if (g_markBadBlocks && (i >= bbMaxRetries)) { - /* Read error, for example unrecoverable ECC */ - iRet = NvPrivMarkBadBlock(l_iFdMtd, iOffs); - return NV_SET_ERROR(NVE_IO, strerror(iRet)); - } - - return 1; -} - -int NvPrivOSFlashErase(loff_t iOffs) -{ - erase_info_t xErase; - CLEAR(xErase); - - xErase.length = l_xMtdInfo.erasesize; - xErase.start = iOffs; - if (ioctl(l_iFdMtd, MEMERASE, &xErase)) - return NV_SET_ERROR(NVE_IO, strerror(errno)); - - return 1; -} - -int NvPrivOSFlashWrite( /*@in@ */ const void *pvBuf, loff_t iOffs, size_t iLength) -{ - int iWritten, iRead; - int i, iRet; - unsigned char *pvRdBuf; - - /* we are not called for bad sectors */ - - for (i = 0; i < bbMaxRetries; i++) { - iWritten = pwrite(l_iFdMtd, pvBuf, iLength, iOffs); - if (iWritten != iLength) { - if (g_markBadBlocks) { - systemLog("Retrying failed write:" - "Wrote %i Bytes" - " instead of %i.\n", iWritten, iLength); - continue; - } else { - logMsg(LOG_ERR, "write failed." - " Wrote %i Bytes" " instead of %i\n", iWritten, iLength); - return NV_SET_ERROR(NVE_IO, strerror(errno)); - } - } - - if (g_markBadBlocks) { - pvRdBuf = (unsigned char *)malloc(iLength); - if (NULL == pvRdBuf) { - systemLog("Malloc failed.\n"); - return NV_SET_ERROR(NVE_IO, strerror(errno)); - } - for (i = 0; i < bbMaxRetries; i++) { - iRead = pread(l_iFdMtd, pvRdBuf, iLength, iOffs); - if (iRead != iLength) { - systemLog("Retrying failed read:" - "%i < > %i.\n", iRead, iLength); - continue; - } - if (memcmp(pvRdBuf, pvBuf, iLength) != 0) { - logMsg(LOG_ERR, - "\nData mismatch at offset 0x%08x\n", iOffs); - logMsg(LOG_ERR, "Source is"); - MemDump(pvBuf, iOffs & ~0xf, MIN(iLength, 0x20)); - logMsg(LOG_ERR, "Flash is"); - MemDump(pvRdBuf, iOffs & ~0xf, MIN(iRead, 0x20)); - continue; - } - break; - } - FREE(pvRdBuf); - } - break; - } - - if (g_markBadBlocks && (i >= bbMaxRetries)) { - iRet = NvPrivMarkBadBlock(l_iFdMtd, iOffs); - return NV_SET_ERROR(NVE_IO, strerror(iRet)); - } - - return 1; -} - -int NvPrivOSFlashProtect(loff_t iOffs, size_t iLength, char bProtect) -{ - erase_info_t xErase; - CLEAR(xErase); - - xErase.length = l_xMtdInfo.erasesize; - xErase.start = iOffs; - if (ioctl(l_iFdMtd, (bProtect ? MEMLOCK : MEMUNLOCK), &xErase)) { - if (ENOTSUP != errno) - /* e.g. NAND */ - return NV_SET_ERROR(NVE_IO, strerror(errno)); - } - - return 1; -} - -int NvPrivOSFlashInfo(loff_t iOffs, -/*@out@*/ struct nv_priv_flash_status *pStatus) -{ - int iRes; - - CLEAR(*pStatus); - - /* linux hasn't an interface yet to determine erase size at iOffs. - Anyway, we place NVRAM immediately after U-Boot, so we have unique - erase sizes */ - pStatus->iEraseSize = l_xMtdInfo.erasesize; - pStatus->type = l_xMtdInfo.type; - - /* determine whether block at iOffs is bad */ - iRes = ioctl(l_iFdMtd, MEMGETBADBLOCK, &iOffs); - - if (iRes > 0) - pStatus->bBad = 1; - else if ((iRes < 0) && (ENOTSUP != errno)) - return NV_SET_ERROR(NVE_IO, strerror(errno)); - /* else if not supported (NOR), is is assumed good */ - - return 1; -} - -void NvPrivOSPrintf(const char *szFormat, ...) -{ - va_list ap; - - va_start(ap, szFormat); - vprintf(szFormat, ap); - va_end(ap); -} - -void NvPrivOSPrintfError(const char *szFormat, ...) -{ - va_list ap; - - va_start(ap, szFormat); - vfprintf(stderr, szFormat, ap); - va_end(ap); -} diff --git a/meta-digi-arm/recipes-bsp/nvram/nvram_2013.01.bb b/meta-digi-arm/recipes-bsp/nvram/nvram_2013.01.bb deleted file mode 100644 index e0667c69d..000000000 --- a/meta-digi-arm/recipes-bsp/nvram/nvram_2013.01.bb +++ /dev/null @@ -1,5 +0,0 @@ -PV = "2013.01" - -require recipes-bsp/nvram/nvram.inc - -COMPATIBLE_MACHINE = "(ccardimx28)" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2013.01/ccardimx28/boot.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2013.01/ccardimx28/boot.txt deleted file mode 100644 index fa6d69123..000000000 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2013.01/ccardimx28/boot.txt +++ /dev/null @@ -1,16 +0,0 @@ -# -# U-Boot bootscript for SD images created by Yocto. -# -# Layout: -# * U-Boot (raw copied) -# * Boot partion (FAT) with kernel images and DTB -# * Rootfs partion (EXT4) -# -# +--------------+----------------------+-------------------------+ -# | U-BOOT (RAW) | BOOT_PARTITION (FAT) | ROOTFS_PARTITION (EXT4) | -# +--------------+----------------------+-------------------------+ -# -setenv fdtimg uimage-imx28-ccardimx28js.dtb -setenv kimg uimage-ccardimx28js.bin -setenv mmc_rpart /dev/mmcblk0p3 -dboot linux mmc 0:2 diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-rev_2013.01.inc b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-rev_2013.01.inc deleted file mode 100644 index 03d459756..000000000 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-rev_2013.01.inc +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) 2013 Digi International - -SRCBRANCH = "v2013.01/dub-2.0/maint" -SRCREV = "${AUTOREV}" - -# Select internal or Github U-Boot repo -UBOOT_GIT_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${DIGI_GIT}u-boot-denx.git', '${DIGI_GITHUB_GIT}/u-boot.git', d)}" - -SRC_URI = "${UBOOT_GIT_URI};branch=${SRCBRANCH}" - -UBOOT_NVRAM_LIBPATH = "git/board/digi/common/cmd_nvram/lib" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2013.01.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2013.01.bb deleted file mode 100644 index d78543dbc..000000000 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2013.01.bb +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2012 Digi International - -DESCRIPTION = "Bootloader for Digi platforms" -require recipes-bsp/u-boot/u-boot.inc -include u-boot-dey-rev_${PV}.inc - -PROVIDES += "u-boot" - -LICENSE = "GPLv2+" -LIC_FILES_CHKSUM = "file://COPYING;md5=1707d6db1d42237583f50183a5651ecb" - -SRC_URI += "file://boot.txt" - -S = "${WORKDIR}/git" - -DEPENDS += "elftosb-native u-boot-mkimage-native" - -do_compile_prepend() { - ${S}/tools/setlocalversion --save-scmversion ${S} -} - -do_deploy_append() { - mkimage -T script -n bootscript -C none -d ${WORKDIR}/boot.txt ${DEPLOYDIR}/boot.scr -} - -COMPATIBLE_MACHINE = "(ccardimx28)" diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv.bb b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv.bb deleted file mode 100644 index 680a4bb24..000000000 --- a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv.bb +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2013 Digi International. - -SUMMARY = "Digi's ubootenv tool" -SECTION = "base" -LICENSE = "GPL-2.0" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -DEPENDS = "libdigi nvram" - -SRC_URI = " \ - file://env_funcs.c \ - file://env_funcs.h \ - file://environment.h \ - file://main_env.c \ -" - -S = "${WORKDIR}" - -GIT_SHA1 = "$(cd ${THISDIR} && git rev-parse --short=7 HEAD)" - -EXTRA_CFLAGS = "-Wall -DLINUX -DGIT_SHA1=\"${GIT_SHA1}\" -I${STAGING_INCDIR}/libdigi" - -do_compile() { - ${CC} ${CFLAGS} ${EXTRA_CFLAGS} -c -o main_env.o main_env.c - ${CC} ${CFLAGS} ${EXTRA_CFLAGS} -c -o env_funcs.o env_funcs.c - ${CC} ${LDFLAGS} -o ubootenv main_env.o env_funcs.o -lnvram -ldigi -} - -do_install() { - mkdir -p ${D}${base_sbindir} - install -m 0755 ubootenv ${D}${base_sbindir}/ -} - -PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.c b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.c deleted file mode 100644 index 588c9b6c6..000000000 --- a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * env_funcs.c - * - * Copyright (C) 2006-2013 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: Function prototypes for all the flavors of the NVRAM tool - * - */ - -#include -#include - -#include "env_funcs.h" - -/* - * Function: get_var_value - * Return: NULL on failure/ pointer where var value starts on succes - * Description: Checks if the variable name is contained on the string and - * returns a pointer where the variable value starts. - */ -char *get_var_value(const char *from, const char *var_name, char sep) -{ - char *separator; - char *start; - - if (((separator = strchr(from, sep)) != NULL) && - ((start = strstr(from, var_name)) != NULL)) { - if (start < separator) - return (++separator); - } - - return NULL; -} - -/* - * Function: get_var_name - * Return: 1 on success, 0 otherwise - * Description: Retrieves the var name from a var string - */ -int get_var_name(const char *from, char *var_name, char sep) -{ - char *separator; - - if ((separator = strchr(from, sep)) != NULL) { - while (from < separator) - *var_name++ = *from++; - *var_name = 0; - return 1; - } - return 0; -} - -/* - * Function: get_next_env_string - * Return: the string to the next environment variable in UBOOT or - * NULL on failure - * Description: returns the addr of the next string in a data structure - * \0\0\0 - * It does an offset calculation to check for overflow. - */ -char *get_next_env_string(char *from, char *till) -{ - if (*from == 0) - return NULL; - - while (from < till && *from) - from++; - - if (from == till && *from) - return NULL; // Indicate string to long - - return (++from); -} - -/* - * Function: get_var_addr - * Return: the pointer to the address string or NULL if not found. - * Description: Returns the addr of the variable in a data structure - * \0\0\0 - * It does an offset calculation to check for overflow. - */ -char *get_var_addr(char *from, char *till, char *var_name) -{ - char *data = from; - char *var_addr; - char var_name_temp[ENV_MAX_VAR_NAME_LEN + 1]; - - sprintf(var_name_temp, "%s%s", var_name, "="); - - do { - if (*data && data < till) { - if ((var_addr = strstr(data, var_name_temp)) != NULL - && (var_addr == data)) - return var_addr < till ? var_addr : NULL; - } - } while ((data = get_next_env_string(data, till)) != NULL); - - return NULL; -} - -/* - * Function: get_end_mark - * Description: - */ -char *get_end_mark(char *from, char *till) -{ - while (from < till) { - while (*from) - from++; - if (from >= till) - return NULL; - if (*(++from) == 0) - return from; - } - return NULL; -} - -/* - * Function: remove_var - * Return: 1 on success, 0 otherwise - * Description: Remove environment variables - */ -int remove_var(char *from, char *till, char *var_name) -{ - char *var_addr; - char *env_end; - char *var_end; - - /* Check if variable already exists */ - if ((var_addr = get_var_addr(from, till, var_name)) != NULL) { - if ((env_end = get_end_mark(var_addr, till)) != NULL) { - if ((var_end = get_next_env_string(var_addr, till)) != NULL) { - while (var_end <= env_end) - *var_addr++ = *var_end++; - while (var_addr <= env_end) - *var_addr++ = 0; /* Just to have a clean environment :-) */ - return 1; - } - } - } - - return 0; -} - -/* - * Function: add_var - * Return: 1 on success, 0 otherwise - * Description: Add a new environment variable - */ -int add_var(char *from, char *till, char *var_str) -{ - char *var_addr; - char var_name[ENV_MAX_VAR_NAME_LEN]; - - if (get_var_name(var_str, var_name, '=')) { - /* Check if variable already exists */ - if ((var_addr = get_var_addr(from, till, var_name)) != NULL) { - /* @TODO: remove more?? could be that it were there more than once?? */ - if (!remove_var(var_addr, till, var_name)) - return 0; - } - /* Append the variable to the end */ - if ((var_addr = get_end_mark(from, till)) != NULL) { - /* Check if environment is empty. If yes, start from the beginning */ - if (var_addr == (from + 1)) - var_addr--; - while (var_addr < till && *var_str) - *var_addr++ = *var_str++; - *var_addr++ = 0; - *var_addr = 0; - return 1; - } else { - fprintf(stderr, "Unable to find environment end\n"); - } - } - - return 0; -} diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.h b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.h deleted file mode 100644 index 051ca0662..000000000 --- a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/env_funcs.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * env_funcs.h - * - * Copyright (C) 2006-2013 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: Data types and prototypes for parsing the NVRAM environment - * - */ - -#ifndef ENV_FUNCS_H -#define ENV_FUNCS_H - -#define ENV_MAX_VAR_NAME_LEN 50 -#define ENV_MAX_VAR_VAL_LEN 256 - -char *get_var_value(const char *from, const char *var_name, char sep); -char *get_next_env_string(char *from, char *till); -char *get_var_addr(char *from, char *till, char *var_name); -char *get_end_mark(char *from, char *till); -int get_var_name(const char *from, char *var_name, char sep); -int add_var(char *from, char *till, char *var_str); -int remove_var(char *from, char *till, char *var_name); - -#endif diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/environment.h b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/environment.h deleted file mode 100644 index ea60bd84a..000000000 --- a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/environment.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * environment.h - * - * Copyright (C) 2006-2013 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: Data types and definitions for environment in NVRAM - * - */ - -#ifndef __ENV_TOOL_H_ -#define __ENV_TOOL_H_ - -#define VAR_SEP '\0' -#define VAR_ASIGN '=' - -typedef struct { - unsigned long crc; - char data[]; -} env_t; - -#endif diff --git a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/main_env.c b/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/main_env.c deleted file mode 100644 index 1e5a7257f..000000000 --- a/meta-digi-arm/recipes-bsp/ubootenv/ubootenv/main_env.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - * main_env.c - * - * Copyright (C) 2006-2013 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Description: main() and user code to manage u-boot and linux environment - * - */ - -#define VERSION "1.8" "-g"GIT_SHA1 - -#include -#include -#include -#include /* MEMERASE */ -#include -#include -#include -#include /* ioctl */ -#include - -#include - -#include /* Nv* */ - -#include "env_funcs.h" -#include "environment.h" - -#define APP_UBOOTENV "ubootenv" -#define APP_PRODINFOENV "prodinfoenv" - -static char *fileadd = NULL; -static char *printlist = NULL; -static char *setstring = NULL; -static char *eraselist = NULL; -static char *cmdname = NULL; -static int dump = 0, clean = 0; -static nv_os_type_e envType; - -static const char *envTypes[] = { - [NVOS_NONE] = "None", - [NVOS_UBOOT] = "U-Boot", - [NVOS_PROD_INFO] = "Product Info", -}; - -static const size_t envDefaultSizes[] = { - [NVOS_NONE] = 0, - [NVOS_UBOOT] = 8192, /* Default value is CONFIG_ENV_SIZE, normally set by U-Boot */ - [NVOS_PROD_INFO] = PROD_INFO_DATA_SIZE, /* Defined in nvram.h but shouldn't be except uboot needs it */ -}; - -static const char* excludeVars[][2] = { - {"ethaddr", "ethaddr1" }, - {"wlanaddr", "ethaddr2" }, - {"eth1addr", "ethaddr3" }, - {"ipaddr", "ip1" }, - {"ipaddr_wlan", "ip2" }, - {"ipaddr1", "ip3" }, - {"netmask", "netmask1" }, - {"netmask_wlan","netmask2" }, - {"netmask1", "netmask3" }, - {"serverip", "server" }, - {"gatewayip", "gateway" }, - {"dnsip", "dns1" }, - {"dnsip2", "dns2" }, - {"dhcp", "dhcp1" }, - {"dhcp_wlan", "dhcp2" }, - {"dhcp1", "dhcp3" }, -}; - -static const char *env_os_type_to_string(void) -{ - return envTypes[envType]; -} - -static int env_onetime_writable(void) -{ - if (NVOS_PROD_INFO == envType) - return 1; - - return 0; -} - -static int env_is_empty(env_t * env, unsigned int envlen) -{ - char *from = (char *)&env->data; - char *till = (char *)&env->data + envlen; - char *end; - - end = get_end_mark(from, till); - /* Check if environment is empty. If yes, start from the beginning */ - if (end == (from + 1)) - return 1; - - return 0; -} - -static int env_have_to_use_nvram(const char *varname) -{ - int j; - - if (envType == NVOS_UBOOT) { - for (j = 0; j < ARRAY_SIZE(excludeVars); j++) { - if (strcmp(varname, excludeVars[j][0]) == 0) - return j; - } - } - return -1; -} - -static void show_usage(void) -{ - fprintf(stdout, "Usage: %s [options]\n" - "%s %s Copyright Digi International Inc.\n\n" - "Prints or updates the %s environment\n" - "\n" - " -d, --dump Prints the values of all the environment\n" - " -p, --print 'var_name_list' Prints the value of the list of variables\n" - " The list has to be simple quoted ('')\n" - " -s, --set 'var_name=var_value' Sets var_value in the variable var_name\n" - " The string has to be simple quoted ('') to allow\n" - " spaces\n" - " -e --erase 'var_name_list' Removes the list of variables (simple quoted)\n" - " -c --clean Removes all variables\n" - " -a --fileadd file_name Adds variables from file_name. To init the full\n" - " environment from file use -c -a simultaneously\n" - " -h --help Displays usage information\n\n", - cmdname, cmdname, VERSION, env_os_type_to_string()); - - if (env_onetime_writable()) { - fprintf(stdout, " WARNING: Variables can only be set the first time\n" - " and become read-only afterwards.\n"); - } -} - -static void show_usage_and_exit(int exit_code) -{ - show_usage(); - exit(exit_code); -} - -static void process_options(int argc, char *argv[]) -{ - int opt_index, opt, optcount = 0; - static const char *short_options = "?hdcp:s:e:a:"; - static const struct option long_options[] = { - {"dump", no_argument, NULL, 'd'}, - {"help", no_argument, NULL, 'h'}, - {"erase", required_argument, NULL, 'e'}, - {"clean", no_argument, NULL, 'c'}, - {"fileadd", required_argument, NULL, 'a'}, - {"print", required_argument, NULL, 'p'}, - {"set", required_argument, NULL, 's'}, - {0, 0, 0, 0}, - }; - - for (opt_index = 0;;) { - - opt = getopt_long(argc, argv, short_options, long_options, &opt_index); - if (opt == EOF) - break; - - switch (opt) { - case 'd': - dump = 1; - break; - case 'p': - printlist = optarg; - break; - case 's': - setstring = optarg; - break; - case 'a': - fileadd = optarg; - break; - case 'e': - eraselist = optarg; - break; - case 'c': - clean = 1; - break; - case 'h': - case '?': - show_usage_and_exit(EXIT_SUCCESS); - break; - } - optcount++; - } - - if (optcount == 0) - show_usage_and_exit(EXIT_FAILURE); - - /* Check options */ - if (dump && (printlist != NULL)) { - fprintf(stderr, "--dump and --print can't be used simultaneously\n"); - show_usage_and_exit(EXIT_FAILURE); - } - if (clean && (eraselist != NULL)) { - fprintf(stderr, "--clean and --erase can't be used simultaneously\n"); - show_usage_and_exit(EXIT_FAILURE); - } -} - -static int env_add_var(const char *varstring, env_t * env, unsigned int envlen) -{ - char *nvramCmd[3] = { "set", "network", NULL }; - char tmpstr[50]; - - char *varval; - int j; - - if (varstring == NULL) - return -EINVAL; - - if (!get_var_name(varstring, tmpstr, VAR_ASIGN)) - return -EINVAL; - - /* Check if is a special variable */ - if ((j = env_have_to_use_nvram(tmpstr)) != -1) { - if ((varval = get_var_value(varstring, excludeVars[j][0], VAR_ASIGN)) != NULL) { - /* Define command to be used by nvram */ - sprintf(tmpstr, "%s=%s", excludeVars[j][1], varval); - nvramCmd[2] = tmpstr; - if (!NvCmdLine(3, (const char **)nvramCmd)) { - return -EINVAL; - } - } - } else { - if (!add_var(env->data, env->data + envlen, (char *)varstring)) { - return -EINVAL; - } - } - - return 0; -} - -static int env_add_vars_from_file(char *filename, env_t * env, unsigned int envlen) -{ - FILE *fp; - char line[ENV_MAX_VAR_NAME_LEN + ENV_MAX_VAR_VAL_LEN + 3]; - int ret = EXIT_SUCCESS; - - if ((fp = fopen(filename, "r")) == NULL) - return -errno; - - while (!feof(fp)) { - if (fgets(line, sizeof(line), fp)) { - /* TODO should we remove comments starting with # ?? */ - /* Remove '\n' */ - if (line[strlen(line) - 1] == '\n') - line[strlen(line) - 1] = 0; - if (env_add_var((const char *)line, env, envlen)) { - fprintf(stderr, "Unable to add environment variable %s\n", - line); - ret = -EINVAL; - goto out; - } - } - } - - out: - if (fp) - fclose(fp); - return ret; -} - -static void env_remove_varlist(const char *varlist, env_t * env, unsigned int envlen) -{ - char *var; - - var = strtok((char *)varlist, " "); - - while (var != NULL) { - if (!remove_var(env->data, env->data + envlen, var)) - fprintf(stderr, "Unable to remove environment variable %s\n", var); - var = strtok(NULL, " "); - } -} - -static int env_validate(env_t * env, int datalen, int verbose) -{ - unsigned long new_crc; - - /* Check stored crc with data */ - new_crc = crc32(0, (const unsigned char *)env->data, datalen); - - if ((unsigned int)env->crc != new_crc) { - if ( verbose ) { - fprintf(stderr, "CRC failure: got 0x%08x expected 0x%08x\n", - (unsigned int)env->crc, (unsigned int)new_crc); - } - return 1; - } - return 0; -} - -static void env_printenv_nvram_vars(char *varname) -{ - struct nv_critical *crit; - nv_param_ip_t *ip_params; - int index; - int oneloop = 0; - - if (NvCriticalGet(&crit)) { - - ip_params = &crit->s.p.xIP; - for (index = 3; index < ARRAY_SIZE(excludeVars); index++) { - if (varname != NULL) { - if ((index = env_have_to_use_nvram(varname)) == -1) - break; - oneloop = 1; - } - - switch (index) { - case 3: - fprintf(stdout, "ipaddr=%s\n", - NvToStringIP(ip_params->axDevice[0].uiIP)); - break; - case 4: - fprintf(stdout, "ipaddr_wlan=%s\n", - NvToStringIP(ip_params->axDevice[1].uiIP)); - break; - case 5: - fprintf(stdout, "ipaddr1=%s\n", - NvToStringIP(crit->s.p.eth1dev.uiIP)); - break; - case 6: - fprintf(stdout, "netmask=%s\n", - NvToStringIP(ip_params->axDevice[0].uiNetMask)); - break; - case 7: - fprintf(stdout, "netmask_wlan=%s\n", - NvToStringIP(ip_params->axDevice[1].uiNetMask)); - break; - case 8: - fprintf(stdout, "netmask1=%s\n", - NvToStringIP(crit->s.p.eth1dev.uiNetMask)); - break; - case 9: - fprintf(stdout, "serverip=%s\n", - NvToStringIP(ip_params->uiIPServer)); - break; - case 10: - fprintf(stdout, "gatewayip=%s\n", - NvToStringIP(ip_params->uiIPGateway)); - break; - case 11: - fprintf(stdout, "dnsip=%s\n", - NvToStringIP(ip_params->auiIPDNS[0])); - break; - case 12: - fprintf(stdout, "dnsip2=%s\n", - NvToStringIP(ip_params->auiIPDNS[1])); - break; - case 13: - fprintf(stdout, "dhcp=%s\n", - (ip_params->axDevice[0].flags.bDHCP ? "on" : "off")); - break; - case 14: - fprintf(stdout, "dhcp_wlan=%s\n", - (ip_params->axDevice[1].flags.bDHCP ? "on" : "off")); - break; - case 15: - fprintf(stdout, "dhcp1=%s\n", - (crit->s.p.eth1dev.flags.bDHCP ? "on" : "off")); - break; - } - if (oneloop) - break; - } - } -} - -static void env_printenv(int dump, char *varlist, env_t * env, unsigned int envlen) -{ - char *var; - char *data = env->data; - char *varinenv; - - if (dump) { - /* print the full environment */ - while (data != NULL && *data) { - fprintf(stdout, "%s\n", data); - data = get_next_env_string(data, env->data + envlen); - } - if (envType == NVOS_UBOOT) - env_printenv_nvram_vars(NULL); - return; - } else { - var = strtok((char *)varlist, " "); - - while (var != NULL) { - - if (envType == NVOS_UBOOT) - env_printenv_nvram_vars(var); - if ((varinenv = - get_var_addr(env->data, env->data + envlen, var)) != NULL) { - fprintf(stdout, "%s\n", varinenv); - } - var = strtok(NULL, " "); - } - } -} - -int main(int argc, char *argv[]) -{ - unsigned int envlen = 0; - env_t *env = NULL; - nv_param_os_cfg_t xCfg; - size_t iSize; - int save_env = 0; - int ret = EXIT_SUCCESS; - int found; - char *cmdstart; - - cmdname = argv[0]; - - cmdname = *argv; - - if ((cmdstart = strrchr(cmdname, '/')) != NULL) { - cmdname = cmdstart + 1; - } - - if (strcmp(cmdname, APP_UBOOTENV) == 0) - envType = NVOS_UBOOT; - else if (strcmp(cmdname, APP_PRODINFOENV) == 0) - envType = NVOS_PROD_INFO; - else { - fprintf(stderr, "This application can be invoked as:\n" - "%s\n%s\n\n", APP_UBOOTENV, APP_PRODINFOENV); - return EXIT_FAILURE; - } - - /* read and process command line */ - process_options(argc, argv); - - if (!NvInit(NVR_AUTO)) { - fprintf(stderr, "Unable to initialize nvram\n"); - return EXIT_FAILURE; - } - - found = NvOSCfgFind(&xCfg, envType); - - if (!found && clean) { - /* Add missing section to nvram if --clean specified */ - - if (envDefaultSizes[envType] != 0 ) { - if (!NvOSCfgAdd(envType, envDefaultSizes[envType])) { - fprintf(stderr, "Unable to add missing %s environment to flash\n", - env_os_type_to_string()); - return EXIT_FAILURE; - } - - /* Try again to find our section */ - found = NvOSCfgFind(&xCfg, envType); - } - } - - if (!found) { - fprintf(stderr, "Unable to detect %s environment in flash\n", - env_os_type_to_string()); - return EXIT_FAILURE; - } - - env = malloc(xCfg.uiSize); - if (NULL == env) { - perror("malloc"); - return EXIT_FAILURE; - } - - memset(env, 0, xCfg.uiSize); - /* Adjust envlen for just for data, crc32 value not included */ - envlen = xCfg.uiSize - sizeof(unsigned long); - - if (!NvOSCfgGet(envType, (void *)env, xCfg.uiSize, &iSize)) { - /* This can't fail; we either found it, created it, or exited. */ - /* But just to be safe... */ - fprintf(stderr, "Unable to get %s environment from flash\n", - env_os_type_to_string()); - ret = EXIT_FAILURE; - goto free_and_ret; - } - - /* Check if env is one-time writable, is valid, and was already written */ - if (env_onetime_writable() && !env_validate(env, envlen, 0) && - !env_is_empty(env, envlen)) { - if ( clean || fileadd || eraselist || setstring ) { - fprintf(stderr, "Environment is one-time writable only\n"); - ret = EXIT_FAILURE; - goto free_and_ret; - } - } - - if (clean) { - memset(env, 0, xCfg.uiSize); - save_env = 1; - } else { - if (env_validate(env, envlen, 1)) { - fprintf(stderr, "Invalid %s environment found\n", - env_os_type_to_string()); - ret = EXIT_FAILURE; - goto free_and_ret; - } - } - - if (fileadd != NULL) { - if (env_add_vars_from_file(fileadd, env, envlen) < 0) { - fprintf(stderr, "Unable to add %s environment from file %s\n", - env_os_type_to_string(), fileadd); - ret = EXIT_FAILURE; - goto free_and_ret; - } - save_env = 1; - } - - if (eraselist != NULL) { - env_remove_varlist(eraselist, env, envlen); - save_env = 1; - } - - if (setstring != NULL) { - if (env_add_var(setstring, env, envlen)) { - fprintf(stderr, "Unable to add environment variable %s\n", setstring); - ret = EXIT_FAILURE; - goto free_and_ret; - } - save_env = 1; - } - - if (dump) { - env_printenv(1, NULL, env, envlen); - } else if (printlist != NULL) { - env_printenv(0, printlist, env, envlen); - } - - if (save_env) { - /* Compute new crc32 value just in case we are going to update the value in flash */ - env->crc = crc32(0, (const unsigned char *)env->data, envlen); - - if (!NvOSCfgSet(envType, env, xCfg.uiSize)) { - fprintf(stderr, "Unable to set %s environment to store in flash\n", - env_os_type_to_string()); - ret = EXIT_FAILURE; - } - if (!NvSave()) { - fprintf(stderr, "Unable to save %s environment in flash\n", - env_os_type_to_string()); - ret = EXIT_FAILURE; - } - } - - free_and_ret: - free(env); - return ret; -} - diff --git a/meta-digi-arm/recipes-bsp/update-flash/update-flash.bb b/meta-digi-arm/recipes-bsp/update-flash/update-flash.bb deleted file mode 100644 index 49194d0b7..000000000 --- a/meta-digi-arm/recipes-bsp/update-flash/update-flash.bb +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2013,2017 Digi International. - -SUMMARY = "Digi's update test utility" -SECTION = "base" -LICENSE = "GPL-2.0" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" - -DEPENDS += "libdigi" -RDEPENDS_${PN}_append_mxs = " kobs-ng" - -SRC_URI = "file://update_flash.c \ - file://jffs2-user.h \ - " - -GIT_SHA1 = "$(cd ${THISDIR} && git rev-parse --short HEAD)" - -S = "${WORKDIR}" - -do_compile() { - ${CC} -O2 -Wall ${LDFLAGS} -DGIT_SHA1=\"${GIT_SHA1}\" update_flash.c -o update_flash -ldigi -} - -do_install() { - install -d ${D}${bindir} - install -m 0755 update_flash ${D}${bindir} -} diff --git a/meta-digi-arm/recipes-bsp/update-flash/update-flash/jffs2-user.h b/meta-digi-arm/recipes-bsp/update-flash/update-flash/jffs2-user.h deleted file mode 100644 index 001685d7f..000000000 --- a/meta-digi-arm/recipes-bsp/update-flash/update-flash/jffs2-user.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * JFFS2 definitions for use in user space only - */ - -#ifndef __JFFS2_USER_H__ -#define __JFFS2_USER_H__ - -/* This file is blessed for inclusion by userspace */ -#include -#include -#include - -#undef cpu_to_je16 -#undef cpu_to_je32 -#undef cpu_to_jemode -#undef je16_to_cpu -#undef je32_to_cpu -#undef jemode_to_cpu - -extern int target_endian; - -#define t16(x) ({ uint16_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_16(__b); }) -#define t32(x) ({ uint32_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_32(__b); }) - -#define cpu_to_je16(x) ((jint16_t){t16(x)}) -#define cpu_to_je32(x) ((jint32_t){t32(x)}) -#define cpu_to_jemode(x) ((jmode_t){t32(x)}) - -#define je16_to_cpu(x) (t16((x).v16)) -#define je32_to_cpu(x) (t32((x).v32)) -#define jemode_to_cpu(x) (t32((x).m)) - -#endif /* __JFFS2_USER_H__ */ diff --git a/meta-digi-arm/recipes-bsp/update-flash/update-flash/update_flash.c b/meta-digi-arm/recipes-bsp/update-flash/update-flash/update_flash.c deleted file mode 100644 index 4c91ab90f..000000000 --- a/meta-digi-arm/recipes-bsp/update-flash/update-flash/update_flash.c +++ /dev/null @@ -1,1770 +0,0 @@ -/* - * update_flash.c - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -/* - * - * !Revision: $Revision: 1.25 $ - * !Descr: Flash Test Util - * !References: [1] mtd-utils/flash_eraseall.c - * [2] http://www.linux-mtd.infradead.org/doc/nand.html - * [3] http://www.linux-mtd.infradead.org/tech/mtdnand/x255.html - */ - -#define _XOPEN_SOURCE 500 /* for pread/pwrite */ - -#include /* ENOENT */ -#include /* open */ -#include /* basename */ -#include /* regexp */ -#include /* kill */ -#include /* varg */ -#include /* printf */ -#include /* EXIT_SUCCESS */ -#include /* memset */ -#include /* close */ -#include /* reboot */ - -#include /* ntohl */ -#include /* setmntent */ -#include /* ioctl */ -#include /* mount */ -#include /* stat */ -#include /* statfs */ - -#include /* MEMERASE */ - -static int target_endian = __BYTE_ORDER; /* for jffs2-user.h, cpu_to_je16 */ -#include "jffs2-user.h" /* jffs2_unknown_node */ - -/* libdigi */ -#include -#include -#include -#include -#include -#include - -#define VERSION "1.25" "-g"GIT_SHA1 - -/* man statfs does mention them, but they are only defined inside kernel */ -#define NFS_SUPER_MAGIC 0x6969 /* linux/nfs_fs.h */ -#define JFFS2_SUPER_MAGIC 0x72b6 /* linux/jffs2.h */ - -#define IO_BLOCK_SIZE 65536 - -#define FLASH_ERASED_BYTE 0xff - -#define WARNING "!!! " -#define INFO "--- " - -#define PRINTF(...) \ - do { \ - if (!cSilent) \ - printf(__VA_ARGS__); \ - } while (0) - -#define PERCENTAGE(iCurrent, iTotal) ((iCurrent * 100) / (iTotal ? iTotal : 1)) - -#define SET_CRC32(pMtd, uiCRC32) \ - do { \ - pMtd->uiCRC32 = uiCRC32; \ - pMtd->cChecksumSet = 1; \ - } while (0) - -/* open it at least read-only so we can see whether open fails or not */ -#define OPEN_READWRITE_IF_NOT_DRY ((cDryRun ? O_RDONLY : O_RDWR) | O_SYNC) - -/* ********** data types ********** */ - -typedef enum { - PTUBoot = 0, - PTKernel, - PTEnvironment, - PTFPGA, - PTBootstream, - PTUnknown /* always last */ -} PartType_e; - -typedef enum { - FTUBoot = 0, - FTKernel, - FTFPGA, - FTNVRAM, - FTJFFS2, - FTSQUASHFS, - FTUBI, - FTBootstream, - FTUnknown /* always last */ -} FileType_e; - -typedef struct { - /* configuration data */ - const char *szOrigImageFileName; - const char *szImageFileName; /* may later be /tmp/ */ - unsigned int uiPartition; - char cChecksumSet; - char cEraseAll; - uint32_t uiCRC32; - - /* auto-detected */ - char cChecksumCalculated; - char acName[64]; - char cIsNAND; - char cWriteCleanMarker; - char cFileType; - char cIsJFFS2; - loff_t iSize; - loff_t iFileSize; - size_t iPageSize; - mtd_info_t xInfo; - unsigned int uiBadBlocks; - PartType_e ePartType; - FileType_e eFileType; - FileType_e eFileTypeNeeded; - - /* open handles */ - int iFd; /* of Partition */ - - /* status */ - char cAlreadyPrintedVerifyWarning; - char cAlreadyRemounted; - - unsigned int uiClMPos; - unsigned int uiClMLen; - struct jffs2_unknown_node xCleanMarker; -} mtdPartition_t; - - -/* ********** function definitions ********** */ - -/* top level functions */ -static void DoPrintChecksums(void); -static void DoMtdUpdate(void); -static void DoMtdVerify(void); - -static void OnExit(void); - -/* helper functions */ -static void MtdInit(void); -static void MtdPartInit( /*@out@ */ mtdPartition_t * pMtd, unsigned int uiPartition, - const char *szImageFileName); -static void MtdPartOpen( /*@inout@ */ mtdPartition_t * pMtd, char cReadOnly); -static void MtdPartClose( /*@inout@ */ mtdPartition_t * pMtd); -static int MtdPartIsBadBlock(const mtdPartition_t * pMtd, loff_t iOffset); -static void MtdPartUseFile( /*@inout@ */ mtdPartition_t * pMtd, const char *szImageFileName); -static void MtdPartErase(const mtdPartition_t * pMtd); -static void MtdPartWrite(mtdPartition_t * pMtd); -static int MtdPartVerify(mtdPartition_t * pMtd); -static void MtdPartCheckCRC32(mtdPartition_t * pMtd); -static void MtdPartCopyFile(mtdPartition_t * pMtd, const char *szDstFileName); -static void MtdPartInitCleanMarker(const mtdPartition_t * pMtd, - struct jffs2_unknown_node *pCleanMarker, - unsigned int *puiClMPos, unsigned int *puiClMLen); -static void MtdPartInitJFFS2Node(struct jffs2_unknown_node *pNode, unsigned short uhNodeType, - size_t iLen); -static void MtdPartCompareCRC32(mtdPartition_t * pMtd, uint32_t uiCRC32); -static void MtdPartRemountAllReadOnly(mtdPartition_t * pMtd); -static void MtdPartDeterminePartType(mtdPartition_t * pMtd); -static void MtdPartDetermineAndCheckFileType(mtdPartition_t * pMtd); -static void MtdPartVerifyFile(mtdPartition_t * pMtd); -static void MtdPartVerifyJFFS2Block(mtdPartition_t * pMtd, unsigned char *pucData, - size_t iSize); -static int MtdPartGetThrottle(const mtdPartition_t * pMtd, uint64_t ullSize); -static void PrintProgress(int iPercentage, int iThrottle, const char *szFmt, ...); -static void VerifyTmpDir(void); -static uint32_t CalcCRC32OfFile(const char *szFileName); -static const char *GetRootDevice(void); -static void mtd_part_write_ubi(mtdPartition_t * pMtd); - -/* ********** local variables ********** */ - -/* set by command line */ -static const char *szTmpDir = NULL; -static const char *szKey = NULL; -static char cNoImageTypeCheck = 0; -static char cProgressInNewLine = 0; -static char cSilent = 0; -static char cChecksumOnly = 0; -static char cDoReboot = 0; -static char cHasChecksum = 0; -static char cWriteCleanMarker = 0; -static char cDryRun = 0; -static char cVerify = 0; -static char cVerifyOnly = 0; -static char cEraseAll = 0; -static char cMaxRetries = 3; -static char cMarkBadBlocks = 0; - -/* calculated */ -static mtdPartition_t axMtdParts[64]; -static mtdPartition_t *pMtdPartLastToUpdate = axMtdParts; -static const char *szMtdPrefix = "/dev/mtd/"; -static const char *szMtdBlockPrefix = "/dev/mtdblock/"; -static unsigned int uiMtdPartsCount = 0; - -#define MK(x, szName)[x] = szName -static const char *aszPartType[PTUnknown + 1] = { - MK(PTUBoot, "U-Boot"), - MK(PTKernel, "Kernel"), - MK(PTEnvironment, "NVRAM"), - MK(PTFPGA, "FPGA"), - MK(PTBootstream, "Bstrm-U-Boot"), - MK(PTUnknown, "Unknown"), -}; -#undef MK - -#define MK(x, szRegExp, szName)[x] = {szRegExp, szName} -static const struct { - const char *szExp; - const char *szName; -} axFileType[FTUnknown + 1] = { - MK(FTUBoot, "u-boot-.*\\.bin", "UBoot"), - MK(FTNVRAM, "nvram-.*", "NVRAM"), - MK(FTKernel, "uImage-.*", "Kernel"), - MK(FTFPGA, ".*\\.biu", "FPGA"), - MK(FTJFFS2, ".*\\.jffs2", "JFFS2"), - MK(FTSQUASHFS, ".*\\.squashfs", "SQUASHFS"), - MK(FTUBI, ".*\\.ubi", "UBI"), - MK(FTBootstream, ".*\\.sb", "Bootstream"), - MK(FTUnknown, ".*", "Unknown"), -}; -#undef MK - -/* ********** function implementations ********** */ - -int main(int argc, char *argv[]) -{ - int iPartListIndex; - - CmdOptEntry aCmdEntries[] = { - {COT_BOOL, 'C', &cChecksumOnly, "checksum-only", - "calculates only CRC32 checksum of image"}, - {COT_BOOL, 'R', &cDoReboot, "reboot", - "reboots the system"}, - {COT_BOOL, 'V', &cVerifyOnly, "verify-only", - "verifies current contents, no updates are done"}, - {COT_BOOL, 'v', &cVerify, "verify", - "After flashing, compare flash contents with image on byte-to-byte"}, - {COT_BOOL, 'c', &cHasChecksum, "checksum", - "flashes only when checksum matches"}, - {COT_BOOL, -1, &cDryRun, "dry-run", - "don't erase or write to the flash"}, - {COT_BOOL, -1, &cProgressInNewLine, "progress-in-new-line", - "each percentage is printed in an own line"}, - {COT_BOOL, 'i', &cNoImageTypeCheck, "no-image-type-check", - "doesn't check image type for partition"}, - {COT_BOOL, 'f', &cEraseAll, "erase-all", - "erases the partition, not only the parts being written"}, - {COT_BOOL, -1, &cWriteCleanMarker, "clean-marker", - "writes clean markers to every partition (implies -f)"}, - {COT_BOOL, 'b' , &cMarkBadBlocks, "bad-block-marking", - "On repeated error, marks block as bad."}, - {COT_BOOL, 's', &cSilent, "silent", - "Silent Mode"}, - {COT_STRING, 't', &szTmpDir, "tmpdir", - "copy files to temporary directory before flashing"}, - {COT_STRING, 'k', &szKey, "encrypt_key", - "Verify bootstream image against encryption key"}, - {COT_MORE, 0, NULL, "", - "file to flash to partition and check for checksum"}, - {COT_NONE, 0, NULL, NULL, NULL}, - }; - - CLEAR(axMtdParts); - - szCmdOptVersion = "Version: " VERSION ", compiled on " __DATE__ "," __TIME__; - iPartListIndex = cmdOptParse(argc, argv, aCmdEntries, - "Flash Update Tool\n\n" - "Examples of use cases:\n" - " update_flash rootfs-ccw9cjsnand-128.jffs2 4\n" - " => updates partition /dev/mtd4 with rootfs image\n" - "\n" - " update_flash -C uImage-ccw9cjsnand\n" - " => calculates file CRC32 only\n" - "\n" - " update_flash -c uImage-ccw9cjsnand 3 0x1051e3c9\n" - " => updates partition /dev/mtd3 only if CRC32 of file is 0x1051e3c9\n" - "\n" - " update_flash uImage-ccw9cjsnand 3 rootfs-ccw9cjsnand-128.jffs2 4:\n" - " => updates kernel at partition 3 and rootfs at partition 4\n" - "\n" - " update_flash u-boot-cpx2-ivt.sb 0 -k 48855699413545113545511513300447\n" - " => updates bootstream file on partition 0 if the encryption key matches\n"); - - /* so we can close everything even on error() or on return of main */ - atexit(OnExit); - - /* Force disable writing clean markers for platforms that require atomic - * access to the OOB */ - if (cWriteCleanMarker && is_nand_oob_atomic()) { - PRINTF(WARNING "JFFS2 clean markers disabled for this platform\n"); - cWriteCleanMarker = 0; - } - - if (cWriteCleanMarker) - cEraseAll = 1; - - if (!cChecksumOnly) - MtdInit(); - - /* check what files to write to what partition */ - while (iPartListIndex < argc) { - unsigned int uiPartition = 0; - - if ((pMtdPartLastToUpdate - axMtdParts) >= ARRAY_SIZE(axMtdParts)) - error("Too many partitions to update on command line"); - - if (iPartListIndex > (argc - (1 + (cChecksumOnly ? 0 : 1) + (cHasChecksum ? 1 : 0)))) - error("Require filename%s%s", (cChecksumOnly ? "" : " and partition"), - (cHasChecksum ? " and checksum" : "")); - - if (!cChecksumOnly) { - /* check partition argument */ - if (sscanf(argv[iPartListIndex + 1], "%u", &uiPartition) != 1) - error("Wrong partition number\n"); - - if (uiPartition >= uiMtdPartsCount) - error("Have only %u mtd partitions", uiMtdPartsCount); - - MtdPartInit(pMtdPartLastToUpdate, uiPartition, argv[iPartListIndex]); - iPartListIndex++; - } else { - /* initialize it partly */ - CLEAR(*pMtdPartLastToUpdate); - pMtdPartLastToUpdate->iFd = -1; - MtdPartUseFile(pMtdPartLastToUpdate, argv[iPartListIndex]); - } - - if (cHasChecksum) { - /* parse checksum argument */ - const char *szCRC32 = argv[iPartListIndex + 1]; - uint32_t uiCRC32; - - if (sscanf(szCRC32, "%x", &uiCRC32) != 1) - error("Invalid Checksum: %s", szCRC32); - SET_CRC32(pMtdPartLastToUpdate, uiCRC32); - iPartListIndex++; - } - - iPartListIndex++; - pMtdPartLastToUpdate++; - } /* while( iPartListIndex ) */ - - /* all command line parsing verifications complete */ - - /* report what will be done */ - if (cNoImageTypeCheck || cDryRun || cWriteCleanMarker || cEraseAll) { - PRINTF("\nEnabled command line options:\n"); - if (cNoImageTypeCheck) - PRINTF(INFO "do not check image type\n"); - if (cDryRun) - PRINTF(INFO "dry-run: flash content is not changed\n"); - if (cWriteCleanMarker) - PRINTF(INFO "write JFFS2 clean markers\n"); - if (cEraseAll) - PRINTF(INFO "erase complete partition\n"); - PRINTF("\n"); - } - - if (cChecksumOnly) - DoPrintChecksums(); - else if (cVerifyOnly) - DoMtdVerify(); - else - DoMtdUpdate(); - - PRINTF("Done\n"); - - if (cDoReboot) { - sync(); - reboot(RB_AUTOBOOT); - } - - /* may not be reached in case of kill */ - return EXIT_SUCCESS; -} - -/*********************************************************************** - * !Function: DoPrintChecksums - * !Descr: Calculates CRC32 of files (and compares them to -c option) - ***********************************************************************/ -static void DoPrintChecksums(void) -{ - mtdPartition_t *pMtd = NULL; - - PRINTF("CRC32 Results:\n"); - - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) { - uint32_t uiCRC32 = 0; - - uiCRC32 = CalcCRC32OfFile(pMtd->szImageFileName); - PRINTF(" %-20s : 0x%08x\n", pMtd->szImageFileName, uiCRC32); - - if (pMtd->cChecksumSet) - MtdPartCompareCRC32(pMtd, uiCRC32); - } -} - -/*********************************************************************** - * !Function: DoMtdUpdate - * !Descr: Updates all flash partitions - ***********************************************************************/ -static void DoMtdUpdate(void) -{ - mtdPartition_t *pMtd = NULL; - - if (NULL != szTmpDir) { - /* checksum is checked or calculated while copying to tmp */ - VerifyTmpDir(); - - /* copy all files to tmp before starting to update */ - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) { - /* copy it to temp */ - char acTmpFileName[256]; - char *szFileName = strdup(pMtd->szImageFileName); - snprintf(acTmpFileName, sizeof(acTmpFileName) - 1, - "%s/%s", szTmpDir, basename(szFileName)); - acTmpFileName[sizeof(acTmpFileName) - 1] = 0; - FREE(szFileName); - - PRINTF("Copying %s to %s\n", pMtd->szImageFileName, szTmpDir); - MtdPartCopyFile(pMtd, acTmpFileName); - - /* use temporary file name from name */ - FREE(pMtd->szImageFileName); /* get rid of const* */ - pMtd->szImageFileName = strdup(acTmpFileName); - } - } else if (cHasChecksum || !cNoImageTypeCheck) { - /* verify checksum before starting to update */ - PRINTF("Verifying File(s): "); - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) { - PRINTF(" %s\n", pMtd->szImageFileName); - MtdPartVerifyFile(pMtd); - } - } - - /* make it read-only so no one can destroy the data */ - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) - MtdPartRemountAllReadOnly(pMtd); - - PRINTF("Updating:\n"); - - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) { - PRINTF(" %s (%lli KiB)\n", pMtd->szImageFileName, TO_KiB(pMtd->iFileSize)); - - MtdPartOpen(pMtd, 0); - /* For UBI images 'ubiformat' takes care of erasing the partition */ - if (pMtd->eFileType != FTUBI) { - MtdPartErase(pMtd); - } - if (PTBootstream == pMtd->ePartType) { - char cmd[1024]; - - /* Bootstream partitions must be updated by Freescale kobs-ng application */ - /* Close open mtd device */ - MtdPartClose(pMtd); - /* Build command to call kobs-ng - * Use 'strcat' because -O2 compiler optimization - * creates problems with 'sprintf' */ - strcpy(cmd, "kobs-ng init -w"); - if (cVerify) - strcat(cmd, " -c"); - if (NULL != szKey) { - strcat(cmd, " -k"); - strcat(cmd, szKey); - } - strcat(cmd, " --chip_0_device_path="); - strcat(cmd, pMtd->acName); - strcat(cmd, " "); - strcat(cmd, pMtd->szImageFileName); - strcat(cmd, " > /dev/null"); - if (!system(cmd)) { - PRINTF("\r Flashing: complete \n"); - if (cVerify) { - PRINTF("\r Verifying: complete \n"); - } - } - else { - PRINTF("\r Flashing: FAILED! \n"); - exit(EXIT_FAILURE); - } - } else if (pMtd->eFileType == FTUBI) { - /* UBI images are flashed using 'ubiformat' command */ - MtdPartClose(pMtd); - mtd_part_write_ubi(pMtd); - } else { - MtdPartWrite(pMtd); - if (cVerify) { - if (!MtdPartVerify(pMtd)) - exit(EXIT_FAILURE); - /* if CRC32 is given, it has been already checked on - the input files. And Mtd is now same to them. So no - need to check CRC32 again. */ - } else if (cHasChecksum) - MtdPartCheckCRC32(pMtd); - MtdPartClose(pMtd); - } - - PRINTF(" CRC32: 0x%08x\n", pMtd->uiCRC32); - } - - if (NULL != szTmpDir) { - /* delete all temporary files */ - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) - if (unlink(pMtd->szImageFileName)) { - /* - * Do not exit with error in case the file to remove does not - * exist. - * Try to address corner cases like CCORE_MX53_EXTENSIONS-170 - * (using same file to flash several different partitions) - */ - if (ENOENT == errno) { - systemLog("%s", pMtd->szImageFileName); - } else { - systemError("%s", pMtd->szImageFileName); - } - } - } -} - -/*********************************************************************** - * !Function: DoMtdVerify - * !Descr: Verifies the flash images - ***********************************************************************/ -static void DoMtdVerify(void) -{ - mtdPartition_t *pMtd = NULL; - - PRINTF("Verifying Images:\n"); - - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) { - MtdPartOpen(pMtd, 1); - MtdPartVerify(pMtd); - MtdPartClose(pMtd); - } -} - -/*********************************************************************** - * !Function: OnExit - * !Descr: Closes all open mtd partitions - ***********************************************************************/ -static void OnExit(void) -{ - mtdPartition_t *pMtd; - - for (pMtd = axMtdParts; pMtd < pMtdPartLastToUpdate; pMtd++) { - if (-1 != pMtd->iFd) - MtdPartClose(pMtd); - - FREE(pMtd->szImageFileName); - } -} - -/*********************************************************************** - * !Function: MtdInit - * !Descr: Checks where the partitions (devfs or not) and how many we have - ***********************************************************************/ -static void MtdInit(void) -{ - struct stat xStat; - - CLEAR(xStat); - - /* determine whether we are /dev/mtd/ or /dev/mtd */ - if (-1 == stat(szMtdPrefix, &xStat)) { - /* not dev fs */ - if (-1 == stat("/dev/mtd0", &xStat)) - error("No MTD devices available"); - - szMtdPrefix = "/dev/mtd"; - szMtdBlockPrefix = "/dev/mtdblock"; - } - - /* determine number of partitions */ - while (uiMtdPartsCount < ARRAY_SIZE(axMtdParts)) { - char acName[64]; - - axMtdParts[uiMtdPartsCount].iFd = -1; /* not open yet */ - - sprintf(acName, "%s%u", szMtdPrefix, uiMtdPartsCount); - if (-1 == stat(acName, &xStat)) - break; - - uiMtdPartsCount++; - } - - if (!uiMtdPartsCount) - error("No MTD partitions found"); -} - -/*********************************************************************** - * !Function: MtdPartInit - * !Descr: opens partition and initializes all sizes and bad blocks - ***********************************************************************/ -static void MtdPartInit( /*@out@ */ mtdPartition_t * pMtd, unsigned int uiPartition, - const char *szImageFileName) -{ - CLEAR(*pMtd); - pMtd->iFd = -1; - pMtd->uiPartition = uiPartition; - - /* open mtd (may be /dev/mtd0 or /dev/mtd/0) */ - MtdPartOpen(pMtd, 0); - - /* read partition info */ - if (ioctl(pMtd->iFd, MEMGETINFO, &pMtd->xInfo)) - systemError("ioctl( MEMGETINFO )"); - - pMtd->iSize = pMtd->xInfo.size; - pMtd->cIsNAND = (MTD_NANDFLASH == pMtd->xInfo.type); - pMtd->uiBadBlocks = 0; - pMtd->cEraseAll = cEraseAll; - pMtd->cWriteCleanMarker = cWriteCleanMarker; - - if (pMtd->cIsNAND) { - /* determine bad block count */ - /* !TODO. in 2.6.18 there already exists - mtd_ecc_stats/ECCGETLAYOUT */ - loff_t iOffset = 0; - - while (iOffset < pMtd->xInfo.size) { - if (MtdPartIsBadBlock(pMtd, iOffset)) { - logMsg(LOG_HARDWARE1, - "Bad Block 0x%08llx on partition %u", - iOffset, pMtd->uiPartition); - pMtd->uiBadBlocks++; - } - iOffset += pMtd->xInfo.erasesize; - } - } - - pMtd->iPageSize = (pMtd->cIsNAND ? pMtd->xInfo.writesize : pMtd->xInfo.erasesize); - - MtdPartDeterminePartType(pMtd); - - PRINTF("Partition %u is %s (%s)\n", pMtd->uiPartition, - (pMtd->cIsNAND ? "NAND" : ((MTD_NORFLASH == pMtd->xInfo.type) ? "NOR" : "???")), - (pMtd->ePartType != PTUnknown) ? aszPartType[pMtd->ePartType] : ""); - PRINTF(" Full Size: %llu KiB\n", TO_KiB(pMtd->iSize)); - - if (pMtd->uiBadBlocks) { - /* determine effective (good) size */ - PRINTF(" %u bad blocks\n", pMtd->uiBadBlocks); - pMtd->iSize -= pMtd->xInfo.erasesize * pMtd->uiBadBlocks; - } - - PRINTF(" Good Size: %llu KiB\n", TO_KiB(pMtd->iSize)); - - if (!is_nand_oob_atomic()) - MtdPartInitCleanMarker(pMtd, &pMtd->xCleanMarker, &pMtd->uiClMPos, &pMtd->uiClMLen); - - MtdPartUseFile(pMtd, szImageFileName); - - /* close it to not leave an unused file descriptor open too long. - The partition info is not gonna change anyway. */ - MtdPartClose(pMtd); - - if (!cVerifyOnly && pMtd->cIsJFFS2) { - PRINTF(INFO "JFFS2 partition %u will be fully erased", - pMtd->uiPartition); - /* clean rootfs completely */ - pMtd->cEraseAll = 1; - if (!is_nand_oob_atomic()) { - pMtd->cWriteCleanMarker = 1; - PRINTF(" and clean markers written\n"); - } else { - PRINTF("\n"); - } - } -} - -/*********************************************************************** - * !Function: MtdPartOpen - * !Descr: Opens the partition, either read only or read-writable - ***********************************************************************/ -static void MtdPartOpen( /*@inout@ */ mtdPartition_t * pMtd, char cReadOnly) -{ - char cReallyReadOnly = cReadOnly || cVerifyOnly; - if (-1 != pMtd->iFd) - error("Partition %u already open", pMtd->uiPartition); - - sprintf(pMtd->acName, "%s%u", szMtdPrefix, pMtd->uiPartition); - pMtd->iFd = open(pMtd->acName, (cReallyReadOnly ? O_RDONLY : OPEN_READWRITE_IF_NOT_DRY)); - if (-1 == pMtd->iFd) - systemError(": %s", pMtd->acName); -} - -/*********************************************************************** - * !Function: MtdPartClose - * !Descr: closes the Mtd Partition - ***********************************************************************/ -static void MtdPartClose( /*@inout@ */ mtdPartition_t * pMtd) -{ - CLOSE(pMtd->iFd); -} - -/*********************************************************************** - * !Function: MtdPartIsBadBlock - * !Return: 1 if the block at iOffset is bad and mustn't be used - * !TODO: on first run, all bad blocks can be stored in a "bad" list and - * reused later to reduce kernel calls - ***********************************************************************/ -static int MtdPartIsBadBlock(const mtdPartition_t * pMtd, loff_t iOffset) -{ - char cIsBad = 0; - int iRes = ioctl(pMtd->iFd, MEMGETBADBLOCK, &iOffset); - - if (iRes > 0) - cIsBad = 1; - else if ((iRes < 0) && (ENOTSUP != errno)) - /* if not supported (NOR), assume it is good */ - systemError("ioctl( MEMGETBADBLOCK )"); - - return cIsBad; -} - -/*********************************************************************** - * !Function: MtdMarkBadBlock - * !Return: 0 on success, <1 on error - ***********************************************************************/ -static int MtdMarkBadBlock(const mtdPartition_t * pMtd, loff_t iOffset) -{ - PRINTF("Marking offset %d as bad\n",(int)iOffset); - return ( ioctl(pMtd->iFd, MEMSETBADBLOCK, &iOffset) ); -} - -/*********************************************************************** - * !Function: MtdPartUseFile - * !Descr: Checks whether szImageFileName can be used for updating. - * E.g. if !cNoImageTypeCheck is set, the prefixes of the image - * file names are checked. - ***********************************************************************/ -static void MtdPartUseFile( /*@inout@ */ mtdPartition_t * pMtd, const char *szImageFileName) -{ - struct stat xStat; - - CLEAR(xStat); - if (stat(szImageFileName, &xStat)) - systemError("%s", szImageFileName); - - pMtdPartLastToUpdate->szOrigImageFileName = szImageFileName; - pMtd->szImageFileName = strdup(szImageFileName); - pMtd->iFileSize = xStat.st_size; - pMtd->eFileType = FTUnknown; - - if (-1 != pMtd->iFd) { - if (xStat.st_size > pMtd->iSize) - error("File %s is %lu KiB, but partition %u has only %lu KiB good free", - pMtd->szImageFileName, - TO_KiB(xStat.st_size), pMtd->uiPartition, TO_KiB(pMtd->iSize)); - - if (!cNoImageTypeCheck) - MtdPartDetermineAndCheckFileType(pMtd); - } -} - -/*********************************************************************** - * !Function: MtdPartErase - * !Descr: erases the flash partition. - * !see [1] - ***********************************************************************/ -static void MtdPartErase(const mtdPartition_t * pMtd) -{ - erase_info_t xErase; - loff_t iEraseSize = 0; - loff_t iBytesErasedTotal = 0; - char cLastWasBad = 0; - struct mtd_oob_buf xoob; - int iThrottle = MtdPartGetThrottle(pMtd, pMtd->xInfo.erasesize); - - CLEAR(xErase); - - xErase.length = pMtd->xInfo.erasesize; - /* bad sectors have already been removed in pMtd->iSize */ - iEraseSize = (pMtd->cEraseAll ? pMtd->iSize : pMtd->iFileSize); - - CLEAR(xoob); - xoob.length = pMtd->uiClMLen; - xoob.ptr = (unsigned char *)&pMtd->xCleanMarker; - - while (iBytesErasedTotal < iEraseSize) { - if (!MtdPartIsBadBlock(pMtd, xErase.start)) { - PrintProgress((((iBytesErasedTotal) * 100) / iEraseSize), - iThrottle, - " Erasing%s %i KiB @ 0x%08x:", - (pMtd->cWriteCleanMarker ? " (CM)" : ""), - TO_KiB(xErase.length), xErase.start); - - if (!cDryRun && ioctl(pMtd->iFd, MEMERASE, &xErase)) - systemError("ioctl(MEMERASE)"); - - iBytesErasedTotal += xErase.length; - cLastWasBad = 0; - - if (!cDryRun && pMtd->cWriteCleanMarker) { - /* write cleanmarker */ - if (pMtd->cIsNAND) { - xoob.start = xErase.start + pMtd->uiClMPos; - if (ioctl(pMtd->iFd, MEMWRITEOOB, &xoob)) - systemError("ioctl( MEMWRITEOOB )"); - } else { - /* the NOR image already contains them. */ - if (pwrite(pMtd->iFd, &pMtd->xCleanMarker, - sizeof(pMtd->xCleanMarker), - xErase.start) != sizeof(pMtd->xCleanMarker)) - systemError("pwrite"); - } - } - } else { - logMsg(LOG_HARDWARE1, - "%s" WARNING "Skipping bad sector @ 0x%08x ", - (!cLastWasBad ? "\r" : ""), xErase.start); - cLastWasBad = 1; - } - - xErase.start += xErase.length; - } - - PRINTF("\r Erasing: complete \n"); -} - -/*********************************************************************** - * !Function: mtd_part_write_ubi - * !Descr: writes an UBI image file to partition - ***********************************************************************/ -static void mtd_part_write_ubi(mtdPartition_t * pMtd) -{ - char line[256]; - FILE *fpin; - int ret; - - snprintf(line, sizeof(line), "ubiformat %s -f %s -y -q 2>&1 >/dev/null", pMtd->acName, - pMtd->szImageFileName); - fpin = popen(line, "r"); - if (fgets(line, sizeof(line) - 1, fpin) != NULL) { - line[strlen(line) - 1] = 0; - } - ret = pclose(fpin); - if (!WEXITSTATUS(ret)) { - PRINTF("\r Flashing: complete \n"); - } else { - PRINTF("\r Flashing: FAILED! (%s)\n", line); - exit(EXIT_FAILURE); - } -} - -/*********************************************************************** - * !Function: MtdPartWrite - * !Descr: writes the image file to partition - ***********************************************************************/ -static void MtdPartWrite(mtdPartition_t * pMtd) -{ - loff_t iBytesReadTotal = 0; - loff_t iCurrentOffs = 0; - int iFdSrc = -1; - char cLastWasBad = 0; - int iBytesRead = 0; - uint32_t uiCRC32 = 0; - unsigned char *pucBuffer = NULL; - const size_t iBlockSize = pMtd->iPageSize; - int iThrottle = MtdPartGetThrottle(pMtd, pMtd->iFileSize); - unsigned int i,iRet; - unsigned int ref_uicrc32 = 0,new_uicrc32 = 0; - unsigned char *pucBufferMtd = NULL; - - pucBuffer = (unsigned char *)malloc(iBlockSize); - if (NULL == pucBuffer) - systemError("malloc"); - - iFdSrc = open(pMtd->szImageFileName, O_RDONLY); - if (-1 == iFdSrc) - systemError("%s", pMtd->szImageFileName); - - /* rewind because descriptor was open and we don't know the state */ - if (lseek(pMtd->iFd, 0, SEEK_SET)) - systemError("%s", pMtd->acName); - - do { - /* write one sector */ - if (!MtdPartIsBadBlock(pMtd, iCurrentOffs)) { - int iBytesWritten; - - PrintProgress(PERCENTAGE(iBytesReadTotal, pMtd->iFileSize), - iThrottle, " Flashing:"); - - iBytesRead = read(iFdSrc, pucBuffer, iBlockSize); - if (!iBytesRead) - break; - else if (-1 == iBytesRead) - systemError("%s", pMtd->szImageFileName); - - if (!pMtd->cChecksumCalculated) - uiCRC32 = crc32(uiCRC32, pucBuffer, iBytesRead); - - if (iBytesRead < iBlockSize) { - char cEmptyChar = FLASH_ERASED_BYTE; - char bJFFS2Padding = 0; - - if (pMtd->cIsJFFS2 && - (iBytesRead + sizeof(struct jffs2_unknown_node) < - iBlockSize)) { - bJFFS2Padding = 1; - cEmptyChar = 0; /* see wbuf.c */ - } - - /* fill block with empty characters */ - memset(pucBuffer + iBytesRead, - cEmptyChar, iBlockSize - iBytesRead); - - if (bJFFS2Padding) { - /* write padding to avoid Empty block messages. - see linux/fs/jffs2/wbuf.c:flush_wbuf */ - struct jffs2_unknown_node *pNode = - (struct jffs2_unknown_node *)(pucBuffer + - iBytesRead); - logMsg(LOG_HARDWARE1, "\nPadding last sector"); - MtdPartInitJFFS2Node(pNode, - JFFS2_NODETYPE_PADDING, - iBlockSize - iBytesRead); - } - } - - /* at least nand writes should be aligned */ - - if( !cDryRun && cMarkBadBlocks ) { - ref_uicrc32 = crc32(0, pucBuffer, iBlockSize); - pucBufferMtd = (unsigned char *)malloc(iBlockSize); - if (NULL == pucBufferMtd) - systemError("malloc"); - } - - for( i = 0 ; i < cMaxRetries ; i++ ) { - int iBytesReadMtd; - - iBytesWritten = (!cDryRun ? - pwrite(pMtd->iFd, - pucBuffer, iBlockSize, - iCurrentOffs) : iBlockSize); - - if (iBytesWritten != iBlockSize) { - if( !cDryRun && cMarkBadBlocks ) { - PRINTF("[%s:%d] %s: Retrying failed write %d.\n", - __FUNCTION__,__LINE__,pMtd->acName,i); - continue; - } - else { - systemError("%s", pMtd->acName); - } - } - - if (!cDryRun && cMarkBadBlocks) { - iBytesReadMtd = pread(pMtd->iFd, pucBufferMtd, iBlockSize, - iCurrentOffs); - if ( iBytesReadMtd < 0 ) { - PRINTF("[%s:%d] %s: Read error.\n", - __FUNCTION__,__LINE__,pMtd->acName); - continue; - } - - new_uicrc32 = crc32(0, pucBufferMtd, iBlockSize); - if( new_uicrc32 != ref_uicrc32 ) { - PRINTF("[%s:%d] %s: CRC mismatch %08x <> %08x.\n", - __FUNCTION__,__LINE__,pMtd->acName,ref_uicrc32, - new_uicrc32); - continue; - } - FREE(pucBufferMtd); - } - break; - } - - if( !cDryRun && cMarkBadBlocks && (i >= cMaxRetries) ) { - PRINTF("[%s:%d] %s: Marking as bad block.\n", - __FUNCTION__,__LINE__,pMtd->acName); - iRet = MtdMarkBadBlock( pMtd , iCurrentOffs ); - systemError("%s: Bad block marking %s.", pMtd->acName, - strerror(iRet)); - } - - iBytesReadTotal += iBytesRead; - - cLastWasBad = 0; - } else { - logMsg(LOG_HARDWARE1, - "%s" WARNING "Skipping bad sector @ 0x%08x ", - (!cLastWasBad ? "\r" : ""), iCurrentOffs); - - cLastWasBad = 1; - } - - iCurrentOffs += iBlockSize; - } while (iCurrentOffs < pMtd->xInfo.size); - - CLOSE(iFdSrc); - FREE(pucBuffer); - - if (pMtd->iFileSize != iBytesReadTotal) - error("Filesize changed while updating: %s", pMtd->szImageFileName); - - if (!pMtd->cChecksumCalculated) { - SET_CRC32(pMtd, uiCRC32); - pMtd->cChecksumCalculated = 1; - } - - PRINTF("\r Flashing: complete \n"); -} - -/*********************************************************************** - * !Function: MtdPartVerify - * !Return: 1 if identical in the used sectors of szOrigImageFileName - * otherwise 0 - * !Descr: compares contents of MtdPartition with szOrigImageFileName - * Only checks the last used sector whether the parts the source - * file not uses are empty. Other blocks are not checked. - ***********************************************************************/ -static int MtdPartVerify(mtdPartition_t * pMtd) -{ - unsigned char *pucBufferSrc; - unsigned char *pucBufferMtd; - int iFdSrc = -1; - loff_t iBytesReadTotal = 0; - loff_t iOffsMtd = 0; - char cRes = 0; - char cLastWasBad = 0; - const size_t iBlockSize = pMtd->iPageSize; - int iThrottle = MtdPartGetThrottle(pMtd, pMtd->iFileSize); - unsigned int i,iRet; - - pucBufferSrc = (unsigned char *)malloc(iBlockSize); - if (NULL == pucBufferSrc) - systemError("malloc"); - - pucBufferMtd = (unsigned char *)malloc(iBlockSize); - if (NULL == pucBufferMtd) - systemError("malloc"); - - /* sync everything */ - MtdPartClose(pMtd); - MtdPartOpen(pMtd, 1); /* also rewinds read pointer */ - - iFdSrc = open(pMtd->szOrigImageFileName, O_RDONLY); - if (-1 == iFdSrc) - systemError("%s", pMtd->szOrigImageFileName); - - do { - if (!MtdPartIsBadBlock(pMtd, iOffsMtd)) { - int iBytesReadSrc; - int iBytesReadMtd; - loff_t iOffs; - - PrintProgress(PERCENTAGE(iBytesReadTotal, pMtd->iFileSize), - iThrottle, " Verifying:"); - - iBytesReadSrc = read(iFdSrc, pucBufferSrc, iBlockSize); - if (!iBytesReadSrc) - /* nothing left */ - break; - else if (iBytesReadSrc < 0) - systemError("%s", pMtd->szOrigImageFileName); - - for( i = 0 ; i < cMaxRetries ; i++ ) { - iBytesReadMtd = pread(pMtd->iFd, pucBufferMtd, iBlockSize, iOffsMtd); - if (iBytesReadMtd < 0) { - if( !cDryRun && cMarkBadBlocks ) { - printf("[%s:%d] %s: Retrying failed read %d, %s.\n", - __FUNCTION__,__LINE__,pMtd->acName,i,strerror(errno)); - continue; - } - else - systemError("%s", pMtd->acName); - } - break; - } - - if( !cDryRun && cMarkBadBlocks && (i >= cMaxRetries) ) { - PRINTF("[%s:%d] %s: Marking as bad block.\n", - __FUNCTION__,__LINE__,pMtd->acName); - iRet = MtdMarkBadBlock( pMtd , iOffsMtd ); - systemError("%s: Bad block marking %s.", pMtd->acName, strerror(iRet)); - } - - if (iBytesReadSrc > iBytesReadMtd) { - logMsg(LOG_ERR, - "\nSize mismatch. Source has %i Bytes but flash only %i bytes", - iBytesReadSrc, iBytesReadMtd); - goto ret; - } - - iOffs = MemCmp(pucBufferSrc, pucBufferMtd, iBytesReadSrc); - if (-1 != iOffs) { - logMsg(LOG_ERR, - "\nData mismatch @ 0x%08x\n", iBytesReadTotal + iOffs); - logMsg(LOG_ERR, "Source is"); - MemDump(pucBufferSrc, iOffs & ~0xf, MIN(iBytesReadSrc, 0x20)); - logMsg(LOG_ERR, "Flash is"); - MemDump(pucBufferMtd, iOffs & ~0xf, MIN(iBytesReadMtd, 0x20)); - goto ret; - } - - if (!pMtd->cIsJFFS2 && (iBytesReadSrc < iBytesReadMtd)) { - /* !TODO. JFFS2 is padded. - This is not yet checked. */ - int i; - - /* check for emptiness of block. */ - /* !TODO. This works only for NOR and NAND */ - for (i = iBytesReadSrc; i < iBytesReadMtd; i++) - if (FLASH_ERASED_BYTE != pucBufferMtd[i]) { - logMsg(LOG_ERR, - "Mtd is not empty @ 0x%llx\n", - iBytesReadTotal + i); - goto ret; - } - } /* if( iBytesReadSrc < iBytesReadMtd */ - iBytesReadTotal += iBytesReadSrc; - - cLastWasBad = 0; - } else { - logMsg(LOG_HARDWARE1, - "%s" WARNING "Skipping bad sector @ 0x%08x ", - (!cLastWasBad ? "\r" : ""), iOffsMtd); - cLastWasBad = 1; - } - - iOffsMtd += iBlockSize; - } while (iOffsMtd < pMtd->xInfo.size); - - if (pMtd->iFileSize != iBytesReadTotal) { - logMsg(LOG_ERR, "Filesize changed while updating: %s", pMtd->szImageFileName); - goto ret; - } - - PRINTF("\r Verifying: complete \n"); - - cRes = 1; - -ret: - CLOSE(iFdSrc); - - FREE(pucBufferMtd); - FREE(pucBufferSrc); - - return cRes; -} - -/*********************************************************************** - * !Function: MtdPartCheckCRC32 - * !Descr: calculates checksum of mtd partition up to filesize - ***********************************************************************/ -static void MtdPartCheckCRC32(mtdPartition_t * pMtd) -{ - unsigned char *pucBufferMtd; - loff_t iBytesReadTotal = 0; - loff_t iOffsMtd = 0; - uint32_t uiCRC32 = 0; - const size_t iBlockSize = pMtd->xInfo.erasesize; - int iThrottle = MtdPartGetThrottle(pMtd, pMtd->iFileSize); - - pucBufferMtd = (unsigned char *)malloc(iBlockSize); - if (NULL == pucBufferMtd) - systemError("malloc"); - - /* sync everything */ - MtdPartClose(pMtd); - MtdPartOpen(pMtd, 1); /* also rewinds read pointer */ - - do { - if (!MtdPartIsBadBlock(pMtd, iOffsMtd)) { - int iBytesReadMtd; - - PrintProgress(PERCENTAGE(iBytesReadTotal, pMtd->iFileSize), - iThrottle, " CRC32: "); - - iBytesReadMtd = pread(pMtd->iFd, pucBufferMtd, iBlockSize, iOffsMtd); - if (iBytesReadMtd < 0) - systemError("%s", pMtd->acName); - - if ((iBytesReadTotal + iBytesReadMtd) > pMtd->iFileSize) - iBytesReadMtd = (pMtd->iFileSize - iBytesReadTotal); - - uiCRC32 = crc32(uiCRC32, pucBufferMtd, iBytesReadMtd); - iBytesReadTotal += iBytesReadMtd; - } - iOffsMtd += iBlockSize; - } while (pMtd->iFileSize > iBytesReadTotal); - - PRINTF("\r CRC32: complete \n"); - - FREE(pucBufferMtd); - - MtdPartCompareCRC32(pMtd, uiCRC32); -} - -/*********************************************************************** - * !Function: MtdPartCopyFile - * !Descr: copies the image file to szDstFileName and calculates its - * check sum - ***********************************************************************/ -static void MtdPartCopyFile(mtdPartition_t * pMtd, const char *szDstFileName) -{ - unsigned char *pucBuffer = NULL; - int iFdDst = -1; - int iFdSrc = -1; - loff_t iBytesReadTotal = 0; - int iBytesRead; - uint32_t uiCRC32 = 0; - const size_t iBlockSize = pMtd->xInfo.erasesize; - - pucBuffer = (unsigned char *)malloc(iBlockSize); - if (NULL == pucBuffer) - systemError("malloc"); - - iFdSrc = open(pMtd->szImageFileName, O_RDONLY); - if (-1 == iFdSrc) - systemError("%s", pMtd->szImageFileName); - - iFdDst = open(szDstFileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (-1 == iFdDst) - systemError("%s", szDstFileName); - - do { - int iBytesWritten; - - iBytesRead = read(iFdSrc, pucBuffer, iBlockSize); - if (!iBytesRead) - break; - else if (-1 == iBytesRead) - systemError("%s", pMtd->szImageFileName); - - if (pMtd->cIsJFFS2) - MtdPartVerifyJFFS2Block(pMtd, pucBuffer, iBytesRead); - - uiCRC32 = crc32(uiCRC32, pucBuffer, iBytesRead); - - iBytesWritten = write(iFdDst, pucBuffer, iBytesRead); - if (iBytesWritten != iBytesRead) - systemError("%s", szDstFileName); - - iBytesReadTotal += iBytesRead; - } while (1); - - CLOSE(iFdDst); - CLOSE(iFdSrc); - - FREE(pucBuffer); - - if (pMtd->iFileSize != iBytesReadTotal) - error("Filesize changed while updating: %s", pMtd->szImageFileName); - - if (!pMtd->cChecksumSet) { - SET_CRC32(pMtd, uiCRC32); - pMtd->cChecksumCalculated = 1; - } else - MtdPartCompareCRC32(pMtd, uiCRC32); -} - -/*********************************************************************** - * !Function: MtdPartInitCleanMarker - * !Descr: initializes the clean marker - * !see [1] - ***********************************************************************/ -static void MtdPartInitCleanMarker(const mtdPartition_t * pMtd, - struct jffs2_unknown_node *pCleanMarker, - unsigned int *puiClMPos, unsigned int *puiClMLen) -{ - *puiClMPos = 0; - *puiClMLen = 8; - - if (pMtd->cIsNAND) { - struct nand_oobinfo xoobInfo; - - CLEAR(xoobInfo); - if (ioctl(pMtd->iFd, MEMGETOOBSEL, &xoobInfo)) - systemError("ioctl( MEMGETOOBSEL )"); - - /* check for autoplacement */ - if (MTD_NANDECC_AUTOPLACE == xoobInfo.useecc) { - /* get the position of the free bytes */ - if (!xoobInfo.oobfree[0][1]) - error("Autoplacement selected and no empty space in oob\n"); - - *puiClMPos = xoobInfo.oobfree[0][0]; - *puiClMLen = xoobInfo.oobfree[0][1]; - - if (*puiClMLen > 8) - *puiClMLen = 8; - else { - /* legacy mode, detect autoplacement ourselves [3] */ - switch (pMtd->xInfo.oobsize) { - case 8: - *puiClMPos = 6; - *puiClMLen = 2; - break; - case 16: - *puiClMPos = 8; - *puiClMLen = 8; - break; - case 64: - *puiClMPos = 16; - *puiClMLen = 8; - break; - default: - error("unsupported oobsize %i\n", pMtd->xInfo.oobsize); - break; - } /* switch */ - } /* if( *piClMPos ) */ - } /* if( NAND_AUTOPLACE */ - } else - MtdPartInitJFFS2Node(pCleanMarker, - JFFS2_NODETYPE_CLEANMARKER, - sizeof(struct jffs2_unknown_node)); - - logMsg(LOG_HARDWARE2, - " OOB has %i bytes, CleanMarker is from 0x%02x to 0x%02x", - pMtd->xInfo.oobsize, *puiClMPos, *puiClMPos + *puiClMLen); -} - -/*********************************************************************** - * !Function: MtdPartInitJFFS2Node - * !Descr: initializes a node and generates hdr checksum - ***********************************************************************/ -static void MtdPartInitJFFS2Node(struct jffs2_unknown_node *pNode, unsigned short uhNodeType, - size_t iLen) -{ - uint32_t uiStart = 0xffffffff; /* JFFS CRC32 starts from 0xfffffff, our crc32 from 0x0 */ - - CLEAR(*pNode); - - pNode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - pNode->nodetype = cpu_to_je16(uhNodeType); - - pNode->totlen = cpu_to_je32(iLen); - /* don't CRC32 the hdr_crc itself */ - pNode->hdr_crc = - cpu_to_je32(crc32(uiStart, pNode, sizeof(struct jffs2_unknown_node) - 4) ^ uiStart); -} - -/*********************************************************************** - * !Function: MtdPartCompareCRC32 - * !Descr: checks whether the CRC32 is same as previously calculated. - ***********************************************************************/ -static void MtdPartCompareCRC32(mtdPartition_t * pMtd, uint32_t uiCRC32) -{ - if (uiCRC32 != pMtd->uiCRC32) - error("CRC32 mismatch on %s.\n Expected 0x%08x, have 0x%08x\n", - pMtd->szImageFileName, pMtd->uiCRC32, uiCRC32); -} - -/*********************************************************************** - * !Function: MtdPartRemountAllReadOnly - * !Descr: remounts all uses of the partition as read-only - ***********************************************************************/ -static void MtdPartRemountAllReadOnly(mtdPartition_t * pMtd) -{ - static const char *szMount = "/proc/mounts"; - char acMtdBlock[20]; - FILE *fhMount = NULL; - const char *szRootDev = GetRootDevice(); - - if (pMtd->cAlreadyRemounted) - /* nothing to do */ - return; - - fhMount = setmntent(szMount, "r"); - if (NULL == fhMount) - systemError(szMount); - - sprintf(acMtdBlock, "%s%u", szMtdBlockPrefix, pMtd->uiPartition); - - /* scan all mount entries */ - do { - char bIsRootDev = 0; - char bRemount = 0; - - struct mntent *pxEnt = getmntent(fhMount); - if (NULL == pxEnt) - break; - - bIsRootDev = (!strcmp(pxEnt->mnt_fsname, "/dev/root") && - !strcmp(szRootDev, acMtdBlock)); - if (!bIsRootDev && !strcmp(pxEnt->mnt_fsname, acMtdBlock)) { - PRINTF(WARNING "Umounting %s\n", pxEnt->mnt_dir); - if (umount(pxEnt->mnt_dir) || bIsRootDev) { - /* rootdev can't be unmounted */ - /* it's for our mtd partition, remount it */ - PRINTF(WARNING "Failed, trying to remount read-only\n"); - bRemount = 1; - } - } - if (bIsRootDev || bRemount) { - PRINTF(WARNING "Remounting %s\n", pxEnt->mnt_dir); - if (mount(pxEnt->mnt_fsname, pxEnt->mnt_dir, - NULL, MS_REMOUNT | MS_RDONLY, NULL)) { - if (EBUSY == errno) - error("Partition in use, can't update it\n"); - else - systemError("%s", pxEnt->mnt_fsname); - } - } - } while (1); - - endmntent(fhMount); - - pMtd->cAlreadyRemounted = 1; -} - -/*********************************************************************** - * !Function: MtdPartDeterminePartType - * !Descr: Determine partition type (rootfs, uboot, etc.) based on - * partition name in /proc/mtd - ***********************************************************************/ -static void MtdPartDeterminePartType(mtdPartition_t * pMtd) -{ - static const char *szMtd = "/proc/mtd"; - FILE *fhMtd = NULL; - unsigned int uiPart; - char acBuffer[200]; - int iPart; - loff_t uiSize; - loff_t uiEraseSize; - char acName[200]; - static const struct { - PartType_e eType; - FileType_e eFileType; - const char *szName; - } axTypes[] = { - {PTUBoot, FTUBoot, "\"U-Boot"}, - {PTKernel, FTKernel, "\"Kernel"}, - {PTEnvironment, FTNVRAM, "\"NVRAM"}, - {PTFPGA, FTFPGA, "\"FPGA"}, - {PTBootstream, FTBootstream, "\"Bstrm-U-Boot"}, - }; - int i; - - /* open /proc/mtd */ - fhMtd = fopen(szMtd, "r"); - if (NULL == fhMtd) - systemError(szMtd); - - /* skip table header (check return value to avoid compiler warning) */ - if (fgets(acBuffer, sizeof(acBuffer), fhMtd)); - - /* seek partition description */ - for (iPart = 0; iPart <= pMtd->uiPartition; iPart++) - if (NULL == fgets(acBuffer, sizeof(acBuffer) - 1, fhMtd)) - systemError(szMtd); - - /* break it into parts */ - acBuffer[sizeof(acBuffer) - 1] = 0; - if (sscanf(acBuffer, "mtd%u: %llx %llx %199s", - &uiPart, &uiSize, &uiEraseSize, acName) != 4) - error("Wrong /proc/mtd line: %s", acBuffer); - if (uiPart != pMtd->uiPartition) - error("Wrong partition: %s", acBuffer); - - /* determine partition type */ - pMtd->ePartType = PTUnknown; - pMtd->eFileTypeNeeded = FTUnknown; - for (i = 0; i < ARRAY_SIZE(axTypes); i++) { - if (!strncmp(axTypes[i].szName, acName, strlen(axTypes[i].szName))) { - pMtd->ePartType = axTypes[i].eType; - pMtd->eFileTypeNeeded = axTypes[i].eFileType; - break; - } - } - - if (fclose(fhMtd) < 0) - systemError(szMtd); -} - -/*********************************************************************** - * !Function: MtdPartDetermineAndCheckFileType - * !Descr: Determine file type (rootfs, uboot, etc.) and checks whether it - * is ok for the partition. Done by looking at filename - ***********************************************************************/ -static void MtdPartDetermineAndCheckFileType(mtdPartition_t * pMtd) -{ - FileType_e eType = 0; - int iMatch = 0; - regex_t regexp; - - CLEAR(regexp); - - /* !TODO: Verify File Type, JFFS2, uimage, u-boot by looking into it */ - - while (eType < ARRAY_SIZE(axFileType)) { - /* does axFileType[ eType ] matches pMtd->szImageFileName? */ - int iError = regcomp(®exp, - axFileType[eType].szExp, - REG_NOSUB); - if (iError) { - char acError[200]; - regerror(iError, ®exp, acError, sizeof(acError) - 1); - error("%s", acError); - } - - iMatch = !regexec(®exp, pMtd->szImageFileName, 0, NULL, 0); - regfree(®exp); - - if (iMatch) { - pMtd->eFileType = eType; - - logMsg(LOG_HARDWARE1, - " Detected Image Type for %s: %s", - pMtd->szImageFileName, axFileType[eType].szName); - - /* check whether it matches the partition */ - if ((pMtd->eFileTypeNeeded != pMtd->eFileType) && - (pMtd->eFileTypeNeeded != FTUnknown)) - error("File %s (Type %s) doesn't match partition type %s", - pMtd->szImageFileName, - axFileType[pMtd->eFileType].szName, - aszPartType[pMtd->ePartType]); - - if (FTJFFS2 == pMtd->eFileType) - pMtd->cIsJFFS2 = 1; - - break; - } - eType++; - } -} - -/*********************************************************************** - * !Function: MtdPartVerifyFile - * !Descr: verifies the file (checksum, JFFS2) - ***********************************************************************/ -static void MtdPartVerifyFile(mtdPartition_t * pMtd) -{ - unsigned char *pucBuffer = NULL; - uint32_t uiCRC32 = 0; - int iFd = -1; - int iBytesRead; - const size_t iBlockSize = pMtd->xInfo.erasesize; - - pucBuffer = (unsigned char *)malloc(iBlockSize); - if (NULL == pucBuffer) - systemError("malloc"); - - iFd = open(pMtd->szImageFileName, O_RDONLY); - if (-1 == iFd) - systemError("%s", pMtd->szImageFileName); - - do { - iBytesRead = read(iFd, pucBuffer, iBlockSize); - if (!iBytesRead) - break; - else if (-1 == iBytesRead) - systemError("%s", pMtd->szImageFileName); - - if (pMtd->cIsJFFS2) - MtdPartVerifyJFFS2Block(pMtd, pucBuffer, iBytesRead); - - uiCRC32 = crc32(uiCRC32, pucBuffer, iBytesRead); - } while (1); - - CLOSE(iFd); - - FREE(pucBuffer); - - if (!pMtd->cChecksumSet) { - SET_CRC32(pMtd, uiCRC32); - pMtd->cChecksumCalculated = 1; - } else - MtdPartCompareCRC32(pMtd, uiCRC32); -} - -/*********************************************************************** - * !Function: MtdPartVerifyJFFS2Block - * !Descr: verifies whether the JFFS2 block is correct. On NOR clean markers - * need to be on the correct position, on NAND there mustn't be. - ***********************************************************************/ -static void MtdPartVerifyJFFS2Block(mtdPartition_t * pMtd, unsigned char *pucData, size_t iSize) -{ - char cCleanMarkerPresent = 0; - int iOffs; - /* only magic and node, length field of xCleanMarker may vary */ - static const size_t NODE_SIZE = 4; - - if (pMtd->cAlreadyPrintedVerifyWarning) - /* do it only once */ - return; - - if (iSize >= 4) - cCleanMarkerPresent = (MemCmp(pucData, &pMtd->xCleanMarker, NODE_SIZE) == -1); - - if (pMtd->cIsNAND) { - const jint16_t MAGIC = cpu_to_je16(JFFS2_MAGIC_BITMASK); - - if (cCleanMarkerPresent) { - logMsg(LOG_ERR, - WARNING - "CleanMarkers present in image for NAND. JFFS2 will complain but function."); - pMtd->cAlreadyPrintedVerifyWarning = 1; - } - - /* MAGIC is < sizeof( xCleanMarker ) */ - if (MemCmp(pucData, &MAGIC, sizeof(MAGIC)) != -1) - error("No JFFS2 Header at erase block begin"); - } else { - /* NOR etc. */ - if (!cCleanMarkerPresent) - error - ("No CleanMarkers present in image for NOR. JFFS2 won't like that. Possibly wrong erase block size of jffs2 or NAND image"); - - /* there shouldn't be any other clean marker in the block. - Check 2^n offsets. */ - for (iOffs = 16; iOffs < iSize - NODE_SIZE; iOffs *= 2) { - if (MemCmp(pucData + iOffs, &pMtd->xCleanMarker, NODE_SIZE) == -1) - error - ("Clean Markers present in the block at offset 0x%08x. Possibly wrong erase block size of jffs2", - iOffs); - } - } -} - -/*********************************************************************** - * !Function: MtdPartGetThrottle - ***********************************************************************/ -static int MtdPartGetThrottle(const mtdPartition_t * pMtd, uint64_t ullSize) -{ - /* Eclipse has a nicer output with an update every second. Therefore it - * is not throttled. */ - return 1; -} - -/*********************************************************************** - * !Function: PrintProgress - * !Descr: Prints message only when progress has changed - ***********************************************************************/ -static void PrintProgress(int iPercentage, int iThrottle, const char *szFmt, ...) -{ - static int iLastPercentage = -1; - int iThrottled = iPercentage / iThrottle; - - if (cSilent) - /* nothing to print */ - return; - - if (iThrottled != iLastPercentage) { - va_list args; - - iLastPercentage = iThrottled; - - va_start(args, szFmt); - vprintf(szFmt, args); - printf("% 3i%% \r", iPercentage); - va_end(args); - - if (cProgressInNewLine) - PRINTF("\n"); - fflush(stdout); - } -} - -/*********************************************************************** - * !Function: VerifyTmpDir - * !Descr: checks whether the temporary directory can be used - ***********************************************************************/ -static void VerifyTmpDir(void) -{ - struct statfs xStat; - - CLEAR(xStat); - - if (statfs(szTmpDir, &xStat)) - systemError("statfs"); - - switch (xStat.f_type) { - case JFFS2_SUPER_MAGIC: - /* flash image temporary on flash fs??? */ - error("Makes no sense to store flash image temporarily on JFFS2"); - break; /* not reached */ - case NFS_SUPER_MAGIC: - error("Makes no sense to store flash image temporarily on NFS"); - break; /* not reached */ - default: - /* Accept all other ones. If they are read-only, it is detected before - * erasing flash */ - break; - } -} - -/*********************************************************************** - * !Function: CalcCRC32OfFile - * !Descr: calculates the CRC32 of the file. - ***********************************************************************/ -static uint32_t CalcCRC32OfFile(const char *szFileName) -{ - char acBuffer[IO_BLOCK_SIZE]; - int iFd = -1; - uint32_t uiCRC32 = 0; - - iFd = open(szFileName, O_RDONLY); - if (-1 == iFd) - systemError("%s", szFileName); - - do { - int iBytesRead = read(iFd, acBuffer, IO_BLOCK_SIZE); - - if (!iBytesRead) - break; - else if (iBytesRead < 0) - systemError("%s", szFileName); - - uiCRC32 = crc32(uiCRC32, acBuffer, iBytesRead); - } while (1); - - CLOSE(iFd); - - return uiCRC32; -} - -/*********************************************************************** - * !Function: GetRootDevice - * !Descr: determines the rootdevice from kernel command line root= - ***********************************************************************/ -static const char *GetRootDevice(void) -{ - int iFd = -1; - int iRead; - /* arm command line is at max 1024 Bytes */ - char szCmdLine[1024]; - static char szRootDev[32] = ""; - const char *szRootStart = NULL; - - if (*szRootDev) - return szRootDev; - - iFd = open("/proc/cmdline", O_RDONLY); - if (-1 == iFd) - systemError("/proc/cmdline"); - - iRead = read(iFd, szCmdLine, sizeof(szCmdLine) - 2); - if (-1 == iRead) - systemError("read"); - szCmdLine[iRead + 1] = 0; - - CLOSE(iFd); - - szRootStart = strstr(szCmdLine, "root="); - if (NULL != szRootStart) { - const char *szDev = szRootStart + 5; /* strlen( root=) */ - const char *szDevEnd = szDev; - int iLen; - - szDevEnd = strchr(szDev, ' '); - iLen = ((NULL == szDevEnd) ? strlen(szDev) : (szDevEnd - szDev)); - - strncpy(szRootDev, szDev, MIN(sizeof(szRootDev), iLen)); - } - - return szRootDev; -} diff --git a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros.bb b/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros.bb deleted file mode 100644 index b81036507..000000000 --- a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros.bb +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (C) 2013 Digi International. - -SUMMARY = "Atheros's wireless driver" -LICENSE = "ISC" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/ISC;md5=f3b90e78ea0cffb20bf5cca7947a896d" - -inherit module - -SRCREV_external = "" -SRCREV_internal = "50dafb5890180cf33fdb42919c3e6f591d0cd2ea" -SRCREV = "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${SRCREV_internal}', '${SRCREV_external}', d)}" - -SRC_URI_external = "${DIGI_GITHUB_GIT}/atheros.git;protocol=git;nobranch=1" -SRC_URI_internal = "${DIGI_GIT}linux-modules/atheros.git;protocol=git;nobranch=1" -SRC_URI = "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${SRC_URI_internal}', '${SRC_URI_external}', d)}" -SRC_URI += " \ - file://atheros-pre-up \ - file://Makefile \ - file://0001-atheros-convert-NLA_PUT-macros.patch \ - file://0002-atheros-update-renamed-struct-members.patch \ -" - -S = "${WORKDIR}/git" - -EXTRA_OEMAKE += "DEL_PLATFORM=${MACHINE} KLIB_BUILD=${STAGING_KERNEL_DIR}" - -do_configure_prepend() { - cp ${WORKDIR}/Makefile ${S}/ -} - -do_install_append() { - install -d ${D}${sysconfdir}/network/if-pre-up.d - install -m 0755 ${WORKDIR}/atheros-pre-up ${D}${sysconfdir}/network/if-pre-up.d/atheros - install -d ${D}${sysconfdir}/modprobe.d - cat >> ${D}${sysconfdir}/modprobe.d/atheros.conf <<-_EOF_ - install ath6kl_sdio true - options ath6kl_sdio ath6kl_p2p=1 softmac_enable=1 - _EOF_ -} - -FILES_${PN} += " \ - ${sysconfdir}/modprobe.d/ \ - ${sysconfdir}/network/ \ -" - -# 'modprobe' from kmod package is needed to load atheros driver. The one -# from busybox does not support '--ignore-install' option. -RDEPENDS_${PN} = "kmod" - -COMPATIBLE_MACHINE = "(ccardimx28)" diff --git a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0001-atheros-convert-NLA_PUT-macros.patch b/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0001-atheros-convert-NLA_PUT-macros.patch deleted file mode 100644 index 331f62c78..000000000 --- a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0001-atheros-convert-NLA_PUT-macros.patch +++ /dev/null @@ -1,1761 +0,0 @@ -From: Javier Viguera -Date: Fri, 13 Sep 2013 10:54:16 +0200 -Subject: [PATCH] atheros: convert NLA_PUT macros - -sed -i -e '/NLA_PUT_[A-Z0-9]\+.*;$/{s,\(\t*\)\(NLA_PUT_[A-Z0-9]\+\)\([^;]\+\);,\1if (\L\2\E\3)\n\1\tgoto nla_put_failure;,g}' compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c compat-wireless/net/wireless/nl80211.c - -sed -i -e '/NLA_PUT_[A-Z0-9]\+.*[^;]$/{N;s,\(\t*\)\(NLA_PUT_[A-Z0-9]\+\)\([^;]\+\);,\1if (\L\2\E\3)\n\1\tgoto nla_put_failure;,g}' compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c compat-wireless/net/wireless/nl80211.c - -sed -i -e '/NLA_PUT.*;$/{s,\(\t*\)\(NLA_PUT\)\([^;]\+\);,\1if (\L\2\E\3)\n\1\tgoto nla_put_failure;,g}' compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c compat-wireless/net/wireless/nl80211.c - -sed -i -e '/NLA_PUT.*[^;]$/{N;s,\(\t*\)\(NLA_PUT\)\([^;]\+\);,\1if (\L\2\E\3)\n\1\tgoto nla_put_failure;,g}' compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c compat-wireless/net/wireless/nl80211.c - -sed -i -e '/NLA_PUT.*[^;]$/{N;N;s,\(\t*\)\(NLA_PUT\)\([^;]\+\);,\1if (\L\2\E\3)\n\1\tgoto nla_put_failure;,g}' compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c compat-wireless/net/wireless/nl80211.c - -And some minor manual fixes after running above commands. - -Signed-off-by: Javier Viguera ---- - .../drivers/net/wireless/ath/ath6kl/testmode.c | 6 +- - .../drivers/net/wireless/ath/ath6kl/wmiconfig.c | 6 +- - compat-wireless/net/wireless/nl80211.c | 1058 ++++++++++++-------- - 3 files changed, 676 insertions(+), 394 deletions(-) - -diff --git a/compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c b/compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c -index 942537cf81b5..c0ce573efb01 100644 ---- a/compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c -+++ b/compat-wireless/drivers/net/wireless/ath/ath6kl/testmode.c -@@ -59,8 +59,10 @@ void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len) - ath6kl_warn("failed to allocate testmode rx skb!\n"); - return; - } -- NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD); -- NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf); -+ if (nla_put_u32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD)) -+ goto nla_put_failure; -+ if (nla_put(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf)) -+ goto nla_put_failure; - cfg80211_testmode_event(skb, GFP_KERNEL); - return; - -diff --git a/compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c b/compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c -index bb60ed23a967..450f915b9f96 100644 ---- a/compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c -+++ b/compat-wireless/drivers/net/wireless/ath/ath6kl/wmiconfig.c -@@ -64,8 +64,10 @@ void ath6kl_tm_rx_wmi_event(struct ath6kl *ar, void *buf, size_t buf_len) - ath6kl_warn("failed to allocate testmode rx skb!\n"); - return; - } -- NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_WMI_CMD); -- NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf); -+ if (nla_put_u32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_WMI_CMD)) -+ goto nla_put_failure; -+ if (nla_put(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf)) -+ goto nla_put_failure; - cfg80211_testmode_event(skb, GFP_KERNEL); - return; - -diff --git a/compat-wireless/net/wireless/nl80211.c b/compat-wireless/net/wireless/nl80211.c -index 66d35f2ca879..c219a2ca027f 100644 ---- a/compat-wireless/net/wireless/nl80211.c -+++ b/compat-wireless/net/wireless/nl80211.c -@@ -363,20 +363,26 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, - static int nl80211_msg_put_channel(struct sk_buff *msg, - struct ieee80211_channel *chan) - { -- NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ, -- chan->center_freq); -+ if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ, -+ chan->center_freq)) -+ goto nla_put_failure; - - if (chan->flags & IEEE80211_CHAN_DISABLED) -- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED); -+ if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) -+ goto nla_put_failure; - if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) -- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN); -+ if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN)) -+ goto nla_put_failure; - if (chan->flags & IEEE80211_CHAN_NO_IBSS) -- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS); -+ if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) -+ goto nla_put_failure; - if (chan->flags & IEEE80211_CHAN_RADAR) -- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR); -+ if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) -+ goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, -- DBM_TO_MBM(chan->max_power)); -+ if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, -+ DBM_TO_MBM(chan->max_power))) -+ goto nla_put_failure; - - return 0; - -@@ -630,7 +636,8 @@ static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes) - i = 0; - while (ifmodes) { - if (ifmodes & 1) -- NLA_PUT_FLAG(msg, i); -+ if (nla_put_flag(msg, i)) -+ goto nla_put_failure; - ifmodes >>= 1; - i++; - } -@@ -673,8 +680,9 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy, - nl_limit = nla_nest_start(msg, j + 1); - if (!nl_limit) - goto nla_put_failure; -- NLA_PUT_U32(msg, NL80211_IFACE_LIMIT_MAX, -- c->limits[j].max); -+ if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX, -+ c->limits[j].max)) -+ goto nla_put_failure; - if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES, - c->limits[j].types)) - goto nla_put_failure; -@@ -684,12 +692,15 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy, - nla_nest_end(msg, nl_limits); - - if (c->beacon_int_infra_match) -- NLA_PUT_FLAG(msg, -- NL80211_IFACE_COMB_STA_AP_BI_MATCH); -- NLA_PUT_U32(msg, NL80211_IFACE_COMB_NUM_CHANNELS, -- c->num_different_channels); -- NLA_PUT_U32(msg, NL80211_IFACE_COMB_MAXNUM, -- c->max_interfaces); -+ if (nla_put_flag(msg, -+ NL80211_IFACE_COMB_STA_AP_BI_MATCH)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS, -+ c->num_different_channels)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, -+ c->max_interfaces)) -+ goto nla_put_failure; - - nla_nest_end(msg, nl_combi); - } -@@ -720,64 +731,89 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - if (!hdr) - return -1; - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); -- NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); -- -- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, -- cfg80211_rdev_list_generation); -- -- NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, -- dev->wiphy.retry_short); -- NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, -- dev->wiphy.retry_long); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, -- dev->wiphy.frag_threshold); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, -- dev->wiphy.rts_threshold); -- NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, -- dev->wiphy.coverage_class); -- NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, -- dev->wiphy.max_scan_ssids); -- NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, -- dev->wiphy.max_sched_scan_ssids); -- NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, -- dev->wiphy.max_scan_ie_len); -- NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, -- dev->wiphy.max_sched_scan_ie_len); -- NLA_PUT_U8(msg, NL80211_ATTR_MAX_MATCH_SETS, -- dev->wiphy.max_match_sets); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy))) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(msg, NL80211_ATTR_GENERATION, -+ cfg80211_rdev_list_generation)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, -+ dev->wiphy.retry_short)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, -+ dev->wiphy.retry_long)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, -+ dev->wiphy.frag_threshold)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, -+ dev->wiphy.rts_threshold)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, -+ dev->wiphy.coverage_class)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, -+ dev->wiphy.max_scan_ssids)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, -+ dev->wiphy.max_sched_scan_ssids)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, -+ dev->wiphy.max_scan_ie_len)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, -+ dev->wiphy.max_sched_scan_ie_len)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS, -+ dev->wiphy.max_match_sets)) -+ goto nla_put_failure; - - if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) -- NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); -+ if (nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN)) -+ goto nla_put_failure; - if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) -- NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); -+ if (nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH)) -+ goto nla_put_failure; - if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) -- NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD); -+ if (nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD)) -+ goto nla_put_failure; - if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) -- NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT); -+ if (nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT)) -+ goto nla_put_failure; - if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) -- NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT); -+ if (nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT)) -+ goto nla_put_failure; - if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) -- NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP); -+ if (nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) -+ goto nla_put_failure; - -- NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, -+ if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, - sizeof(u32) * dev->wiphy.n_cipher_suites, -- dev->wiphy.cipher_suites); -+ dev->wiphy.cipher_suites)) -+ goto nla_put_failure; - -- NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, -- dev->wiphy.max_num_pmkids); -+ if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, -+ dev->wiphy.max_num_pmkids)) -+ goto nla_put_failure; - - if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) -- NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); -+ if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE)) -+ goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, -- dev->wiphy.available_antennas_tx); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, -- dev->wiphy.available_antennas_rx); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, -+ dev->wiphy.available_antennas_tx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, -+ dev->wiphy.available_antennas_rx)) -+ goto nla_put_failure; - - if (dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) -- NLA_PUT_U32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, -- dev->wiphy.probe_resp_offload); -+ if (nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, -+ dev->wiphy.probe_resp_offload)) -+ goto nla_put_failure; - - if ((dev->wiphy.available_antennas_tx || - dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { -@@ -785,8 +821,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - int res; - res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); - if (!res) { -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant)) -+ goto nla_put_failure; - } - } - -@@ -808,15 +846,19 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - - /* add HT info */ - if (dev->wiphy.bands[band]->ht_cap.ht_supported) { -- NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET, -+ if (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET, - sizeof(dev->wiphy.bands[band]->ht_cap.mcs), -- &dev->wiphy.bands[band]->ht_cap.mcs); -- NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA, -- dev->wiphy.bands[band]->ht_cap.cap); -- NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR, -- dev->wiphy.bands[band]->ht_cap.ampdu_factor); -- NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY, -- dev->wiphy.bands[band]->ht_cap.ampdu_density); -+ &dev->wiphy.bands[band]->ht_cap.mcs)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA, -+ dev->wiphy.bands[band]->ht_cap.cap)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR, -+ dev->wiphy.bands[band]->ht_cap.ampdu_factor)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY, -+ dev->wiphy.bands[band]->ht_cap.ampdu_density)) -+ goto nla_put_failure; - } - - /* add frequencies */ -@@ -850,11 +892,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - goto nla_put_failure; - - rate = &dev->wiphy.bands[band]->bitrates[i]; -- NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE, -- rate->bitrate); -+ if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE, -+ rate->bitrate)) -+ goto nla_put_failure; - if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) -- NLA_PUT_FLAG(msg, -- NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE); -+ if (nla_put_flag(msg, -+ NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE)) -+ goto nla_put_failure; - - nla_nest_end(msg, nl_rate); - } -@@ -874,7 +918,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - do { \ - if (dev->ops->op) { \ - i++; \ -- NLA_PUT_U32(msg, i, NL80211_CMD_ ## n); \ -+ if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \ -+ goto nla_put_failure; \ - } \ - } while (0) - -@@ -901,7 +946,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL); - if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { - i++; -- NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); -+ if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) -+ goto nla_put_failure; - } - CMD(set_channel, SET_CHANNEL); - CMD(set_wds_peer, SET_WDS_PEER); -@@ -914,29 +960,34 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - CMD(probe_client, PROBE_CLIENT); - if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { - i++; -- NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS); -+ if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) -+ goto nla_put_failure; - } - - #undef CMD - - if (dev->ops->connect || dev->ops->auth) { - i++; -- NLA_PUT_U32(msg, i, NL80211_CMD_CONNECT); -+ if (nla_put_u32(msg, i, NL80211_CMD_CONNECT)) -+ goto nla_put_failure; - } - - if (dev->ops->disconnect || dev->ops->deauth) { - i++; -- NLA_PUT_U32(msg, i, NL80211_CMD_DISCONNECT); -+ if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT)) -+ goto nla_put_failure; - } - - nla_nest_end(msg, nl_cmds); - - if (dev->ops->remain_on_channel) -- NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, -- dev->wiphy.max_remain_on_channel_duration); -+ if (nla_put_u32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, -+ dev->wiphy.max_remain_on_channel_duration)) -+ goto nla_put_failure; - - if (dev->ops->mgmt_tx_cancel_wait) -- NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); -+ if (nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) -+ goto nla_put_failure; - - if (mgmt_stypes) { - u16 stypes; -@@ -955,8 +1006,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - stypes = mgmt_stypes[ift].tx; - while (stypes) { - if (stypes & 1) -- NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, -- (i << 4) | IEEE80211_FTYPE_MGMT); -+ if (nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, -+ (i << 4) | IEEE80211_FTYPE_MGMT)) -+ goto nla_put_failure; - stypes >>= 1; - i++; - } -@@ -977,8 +1029,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - stypes = mgmt_stypes[ift].rx; - while (stypes) { - if (stypes & 1) -- NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, -- (i << 4) | IEEE80211_FTYPE_MGMT); -+ if (nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, -+ (i << 4) | IEEE80211_FTYPE_MGMT)) -+ goto nla_put_failure; - stypes >>= 1; - i++; - } -@@ -996,21 +1049,29 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - goto nla_put_failure; - - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)) -+ goto nla_put_failure; - if (dev->wiphy.wowlan.n_patterns) { - struct nl80211_wowlan_pattern_support pat = { - .max_patterns = dev->wiphy.wowlan.n_patterns, -@@ -1019,8 +1080,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - .max_pattern_len = - dev->wiphy.wowlan.pattern_max_len, - }; -- NLA_PUT(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, -- sizeof(pat), &pat); -+ if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, -+ sizeof(pat), &pat)) -+ goto nla_put_failure; - } - - nla_nest_end(msg, nl_wowlan); -@@ -1034,10 +1096,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, - goto nla_put_failure; - - if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) -- NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME, -- dev->wiphy.ap_sme_capa); -+ if (nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME, -+ dev->wiphy.ap_sme_capa)) -+ goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features); -+ if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features)) -+ goto nla_put_failure; - - return genlmsg_end(msg, hdr); - -@@ -1480,14 +1544,19 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, - if (!hdr) - return -1; - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); -- NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype)) -+ goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, -+ if (nla_put_u32(msg, NL80211_ATTR_GENERATION, - rdev->devlist_generation ^ -- (cfg80211_rdev_list_generation << 2)); -+ (cfg80211_rdev_list_generation << 2))) -+ goto nla_put_failure; - - return genlmsg_end(msg, hdr); - -@@ -1769,34 +1838,41 @@ static void get_key_callback(void *c, struct key_params *params) - struct get_key_cookie *cookie = c; - - if (params->key) -- NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA, -- params->key_len, params->key); -+ if (nla_put(cookie->msg, NL80211_ATTR_KEY_DATA, -+ params->key_len, params->key)) -+ goto nla_put_failure; - - if (params->seq) -- NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ, -- params->seq_len, params->seq); -+ if (nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ, -+ params->seq_len, params->seq)) -+ goto nla_put_failure; - - if (params->cipher) -- NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER, -- params->cipher); -+ if (nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER, -+ params->cipher)) -+ goto nla_put_failure; - - key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY); - if (!key) - goto nla_put_failure; - - if (params->key) -- NLA_PUT(cookie->msg, NL80211_KEY_DATA, -- params->key_len, params->key); -+ if (nla_put(cookie->msg, NL80211_KEY_DATA, -+ params->key_len, params->key)) -+ goto nla_put_failure; - - if (params->seq) -- NLA_PUT(cookie->msg, NL80211_KEY_SEQ, -- params->seq_len, params->seq); -+ if (nla_put(cookie->msg, NL80211_KEY_SEQ, -+ params->seq_len, params->seq)) -+ goto nla_put_failure; - - if (params->cipher) -- NLA_PUT_U32(cookie->msg, NL80211_KEY_CIPHER, -- params->cipher); -+ if (nla_put_u32(cookie->msg, NL80211_KEY_CIPHER, -+ params->cipher)) -+ goto nla_put_failure; - -- NLA_PUT_U8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx); -+ if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx)) -+ goto nla_put_failure; - - nla_nest_end(cookie->msg, key); - -@@ -1854,10 +1930,13 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) - cookie.msg = msg; - cookie.idx = key_idx; - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx)) -+ goto nla_put_failure; - if (mac_addr) -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) -+ goto nla_put_failure; - - if (pairwise && mac_addr && - !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) -@@ -2373,14 +2452,18 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, - /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ - bitrate = cfg80211_calculate_bitrate(info); - if (bitrate > 0) -- NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate); -+ if (nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate)) -+ goto nla_put_failure; - - if (info->flags & RATE_INFO_FLAGS_MCS) -- NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, info->mcs); -+ if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) -+ goto nla_put_failure; - if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) -- NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH); -+ if (nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) -+ goto nla_put_failure; - if (info->flags & RATE_INFO_FLAGS_SHORT_GI) -- NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI); -+ if (nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) -+ goto nla_put_failure; - - nla_nest_end(msg, rate); - return true; -@@ -2400,41 +2483,53 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, - if (!hdr) - return -1; - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) -+ goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, sinfo->generation); -+ if (nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation)) -+ goto nla_put_failure; - - sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); - if (!sinfoattr) - goto nla_put_failure; - if (sinfo->filled & STATION_INFO_CONNECTED_TIME) -- NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME, -- sinfo->connected_time); -+ if (nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME, -+ sinfo->connected_time)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_INACTIVE_TIME) -- NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, -- sinfo->inactive_time); -+ if (nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME, -+ sinfo->inactive_time)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_RX_BYTES) -- NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES, -- sinfo->rx_bytes); -+ if (nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, -+ sinfo->rx_bytes)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_TX_BYTES) -- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES, -- sinfo->tx_bytes); -+ if (nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, -+ sinfo->tx_bytes)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_LLID) -- NLA_PUT_U16(msg, NL80211_STA_INFO_LLID, -- sinfo->llid); -+ if (nla_put_u16(msg, NL80211_STA_INFO_LLID, -+ sinfo->llid)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_PLID) -- NLA_PUT_U16(msg, NL80211_STA_INFO_PLID, -- sinfo->plid); -+ if (nla_put_u16(msg, NL80211_STA_INFO_PLID, -+ sinfo->plid)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_PLINK_STATE) -- NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE, -- sinfo->plink_state); -+ if (nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE, -+ sinfo->plink_state)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_SIGNAL) -- NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL, -- sinfo->signal); -+ if (nla_put_u8(msg, NL80211_STA_INFO_SIGNAL, -+ sinfo->signal)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_SIGNAL_AVG) -- NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, -- sinfo->signal_avg); -+ if (nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG, -+ sinfo->signal_avg)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_TX_BITRATE) { - if (!nl80211_put_sta_rate(msg, &sinfo->txrate, - NL80211_STA_INFO_TX_BITRATE)) -@@ -2446,45 +2541,56 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, - goto nla_put_failure; - } - if (sinfo->filled & STATION_INFO_RX_PACKETS) -- NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS, -- sinfo->rx_packets); -+ if (nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS, -+ sinfo->rx_packets)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_TX_PACKETS) -- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS, -- sinfo->tx_packets); -+ if (nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS, -+ sinfo->tx_packets)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_TX_RETRIES) -- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_RETRIES, -- sinfo->tx_retries); -+ if (nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES, -+ sinfo->tx_retries)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_TX_FAILED) -- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED, -- sinfo->tx_failed); -+ if (nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, -+ sinfo->tx_failed)) -+ goto nla_put_failure; - if (sinfo->filled & STATION_INFO_BSS_PARAM) { - bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); - if (!bss_param) - goto nla_put_failure; - - if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) -- NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_CTS_PROT); -+ if (nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) -+ goto nla_put_failure; - if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) -- NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE); -+ if (nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) -+ goto nla_put_failure; - if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) -- NLA_PUT_FLAG(msg, -- NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME); -- NLA_PUT_U8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, -- sinfo->bss_param.dtim_period); -- NLA_PUT_U16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, -- sinfo->bss_param.beacon_interval); -+ if (nla_put_flag(msg, -+ NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, -+ sinfo->bss_param.dtim_period)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, -+ sinfo->bss_param.beacon_interval)) -+ goto nla_put_failure; - - nla_nest_end(msg, bss_param); - } - if (sinfo->filled & STATION_INFO_STA_FLAGS) -- NLA_PUT(msg, NL80211_STA_INFO_STA_FLAGS, -+ if (nla_put(msg, NL80211_STA_INFO_STA_FLAGS, - sizeof(struct nl80211_sta_flag_update), -- &sinfo->sta_flags); -+ &sinfo->sta_flags)) -+ goto nla_put_failure; - nla_nest_end(msg, sinfoattr); - - if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES) -- NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, -- sinfo->assoc_req_ies); -+ if (nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, -+ sinfo->assoc_req_ies)) -+ goto nla_put_failure; - - return genlmsg_end(msg, hdr); - -@@ -2872,36 +2978,47 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, - if (!hdr) - return -1; - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst); -- NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop)) -+ goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, pinfo->generation); -+ if (nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation)) -+ goto nla_put_failure; - - pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO); - if (!pinfoattr) - goto nla_put_failure; - if (pinfo->filled & MPATH_INFO_FRAME_QLEN) -- NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN, -- pinfo->frame_qlen); -+ if (nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN, -+ pinfo->frame_qlen)) -+ goto nla_put_failure; - if (pinfo->filled & MPATH_INFO_SN) -- NLA_PUT_U32(msg, NL80211_MPATH_INFO_SN, -- pinfo->sn); -+ if (nla_put_u32(msg, NL80211_MPATH_INFO_SN, -+ pinfo->sn)) -+ goto nla_put_failure; - if (pinfo->filled & MPATH_INFO_METRIC) -- NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC, -- pinfo->metric); -+ if (nla_put_u32(msg, NL80211_MPATH_INFO_METRIC, -+ pinfo->metric)) -+ goto nla_put_failure; - if (pinfo->filled & MPATH_INFO_EXPTIME) -- NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME, -- pinfo->exptime); -+ if (nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME, -+ pinfo->exptime)) -+ goto nla_put_failure; - if (pinfo->filled & MPATH_INFO_FLAGS) -- NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS, -- pinfo->flags); -+ if (nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS, -+ pinfo->flags)) -+ goto nla_put_failure; - if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) -- NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, -- pinfo->discovery_timeout); -+ if (nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, -+ pinfo->discovery_timeout)) -+ goto nla_put_failure; - if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) -- NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES, -- pinfo->discovery_retries); -+ if (nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES, -+ pinfo->discovery_retries)) -+ goto nla_put_failure; - - nla_nest_end(msg, pinfoattr); - -@@ -3227,41 +3344,59 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, - pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG); - if (!pinfoattr) - goto nla_put_failure; -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT_U16(msg, NL80211_MESHCONF_RETRY_TIMEOUT, -- cur_params.dot11MeshRetryTimeout); -- NLA_PUT_U16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT, -- cur_params.dot11MeshConfirmTimeout); -- NLA_PUT_U16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT, -- cur_params.dot11MeshHoldingTimeout); -- NLA_PUT_U16(msg, NL80211_MESHCONF_MAX_PEER_LINKS, -- cur_params.dot11MeshMaxPeerLinks); -- NLA_PUT_U8(msg, NL80211_MESHCONF_MAX_RETRIES, -- cur_params.dot11MeshMaxRetries); -- NLA_PUT_U8(msg, NL80211_MESHCONF_TTL, -- cur_params.dot11MeshTTL); -- NLA_PUT_U8(msg, NL80211_MESHCONF_ELEMENT_TTL, -- cur_params.element_ttl); -- NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, -- cur_params.auto_open_plinks); -- NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, -- cur_params.dot11MeshHWMPmaxPREQretries); -- NLA_PUT_U32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME, -- cur_params.path_refresh_time); -- NLA_PUT_U16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, -- cur_params.min_discovery_timeout); -- NLA_PUT_U32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, -- cur_params.dot11MeshHWMPactivePathTimeout); -- NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, -- cur_params.dot11MeshHWMPpreqMinInterval); -- NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, -- cur_params.dot11MeshHWMPnetDiameterTraversalTime); -- NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, -- cur_params.dot11MeshHWMPRootMode); -- NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL, -- cur_params.dot11MeshHWMPRannInterval); -- NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, -- cur_params.dot11MeshGateAnnouncementProtocol); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT, -+ cur_params.dot11MeshRetryTimeout)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT, -+ cur_params.dot11MeshConfirmTimeout)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT, -+ cur_params.dot11MeshHoldingTimeout)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS, -+ cur_params.dot11MeshMaxPeerLinks)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES, -+ cur_params.dot11MeshMaxRetries)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_MESHCONF_TTL, -+ cur_params.dot11MeshTTL)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL, -+ cur_params.element_ttl)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, -+ cur_params.auto_open_plinks)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, -+ cur_params.dot11MeshHWMPmaxPREQretries)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME, -+ cur_params.path_refresh_time)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, -+ cur_params.min_discovery_timeout)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, -+ cur_params.dot11MeshHWMPactivePathTimeout)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, -+ cur_params.dot11MeshHWMPpreqMinInterval)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, -+ cur_params.dot11MeshHWMPnetDiameterTraversalTime)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, -+ cur_params.dot11MeshHWMPRootMode)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL, -+ cur_params.dot11MeshHWMPRannInterval)) -+ goto nla_put_failure; -+ if (nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, -+ cur_params.dot11MeshGateAnnouncementProtocol)) -+ goto nla_put_failure; - nla_nest_end(msg, pinfoattr); - genlmsg_end(msg, hdr); - return genlmsg_reply(msg, info); -@@ -3482,8 +3617,9 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) - if (!hdr) - goto put_failure; - -- NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, -- cfg80211_regdomain->alpha2); -+ if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, -+ cfg80211_regdomain->alpha2)) -+ goto nla_put_failure; - - nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); - if (!nl_reg_rules) -@@ -3503,18 +3639,24 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) - if (!nl_reg_rule) - goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS, -- reg_rule->flags); -- NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START, -- freq_range->start_freq_khz); -- NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END, -- freq_range->end_freq_khz); -- NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW, -- freq_range->max_bandwidth_khz); -- NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, -- power_rule->max_antenna_gain); -- NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP, -- power_rule->max_eirp); -+ if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS, -+ reg_rule->flags)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START, -+ freq_range->start_freq_khz)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END, -+ freq_range->end_freq_khz)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW, -+ freq_range->max_bandwidth_khz)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, -+ power_rule->max_antenna_gain)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP, -+ power_rule->max_eirp)) -+ goto nla_put_failure; - - nla_nest_end(msg, nl_reg_rule); - } -@@ -4081,37 +4223,49 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, - - genl_dump_check_consistent(cb, hdr, &nl80211_fam); - -- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex)) -+ goto nla_put_failure; - - bss = nla_nest_start(msg, NL80211_ATTR_BSS); - if (!bss) - goto nla_put_failure; - if (!is_zero_ether_addr(res->bssid)) -- NLA_PUT(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid); -+ if (nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)) -+ goto nla_put_failure; - if (res->information_elements && res->len_information_elements) -- NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS, -+ if (nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, - res->len_information_elements, -- res->information_elements); -+ res->information_elements)) -+ goto nla_put_failure; - if (res->beacon_ies && res->len_beacon_ies && - res->beacon_ies != res->information_elements) -- NLA_PUT(msg, NL80211_BSS_BEACON_IES, -- res->len_beacon_ies, res->beacon_ies); -+ if (nla_put(msg, NL80211_BSS_BEACON_IES, -+ res->len_beacon_ies, res->beacon_ies)) -+ goto nla_put_failure; - if (res->tsf) -- NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf); -+ if (nla_put_u64(msg, NL80211_BSS_TSF, res->tsf)) -+ goto nla_put_failure; - if (res->beacon_interval) -- NLA_PUT_U16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval); -- NLA_PUT_U16(msg, NL80211_BSS_CAPABILITY, res->capability); -- NLA_PUT_U32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq); -- NLA_PUT_U32(msg, NL80211_BSS_SEEN_MS_AGO, -- jiffies_to_msecs(jiffies - intbss->ts)); -+ if (nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO, -+ jiffies_to_msecs(jiffies - intbss->ts))) -+ goto nla_put_failure; - - switch (rdev->wiphy.signal_type) { - case CFG80211_SIGNAL_TYPE_MBM: -- NLA_PUT_U32(msg, NL80211_BSS_SIGNAL_MBM, res->signal); -+ if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal)) -+ goto nla_put_failure; - break; - case CFG80211_SIGNAL_TYPE_UNSPEC: -- NLA_PUT_U8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal); -+ if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal)) -+ goto nla_put_failure; - break; - default: - break; -@@ -4121,20 +4275,23 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_STATION: - if (intbss == wdev->current_bss) -- NLA_PUT_U32(msg, NL80211_BSS_STATUS, -- NL80211_BSS_STATUS_ASSOCIATED); -+ if (nla_put_u32(msg, NL80211_BSS_STATUS, -+ NL80211_BSS_STATUS_ASSOCIATED)) -+ goto nla_put_failure; - else for (i = 0; i < MAX_AUTH_BSSES; i++) { - if (intbss != wdev->auth_bsses[i]) - continue; -- NLA_PUT_U32(msg, NL80211_BSS_STATUS, -- NL80211_BSS_STATUS_AUTHENTICATED); -+ if (nla_put_u32(msg, NL80211_BSS_STATUS, -+ NL80211_BSS_STATUS_AUTHENTICATED)) -+ goto nla_put_failure; - break; - } - break; - case NL80211_IFTYPE_ADHOC: - if (intbss == wdev->current_bss) -- NLA_PUT_U32(msg, NL80211_BSS_STATUS, -- NL80211_BSS_STATUS_IBSS_JOINED); -+ if (nla_put_u32(msg, NL80211_BSS_STATUS, -+ NL80211_BSS_STATUS_IBSS_JOINED)) -+ goto nla_put_failure; - break; - default: - break; -@@ -4205,34 +4362,43 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, - if (!hdr) - return -ENOMEM; - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; - - infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO); - if (!infoattr) - goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_SURVEY_INFO_FREQUENCY, -- survey->channel->center_freq); -+ if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, -+ survey->channel->center_freq)) -+ goto nla_put_failure; - if (survey->filled & SURVEY_INFO_NOISE_DBM) -- NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE, -- survey->noise); -+ if (nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, -+ survey->noise)) -+ goto nla_put_failure; - if (survey->filled & SURVEY_INFO_IN_USE) -- NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); -+ if (nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE)) -+ goto nla_put_failure; - if (survey->filled & SURVEY_INFO_CHANNEL_TIME) -- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, -- survey->channel_time); -+ if (nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, -+ survey->channel_time)) -+ goto nla_put_failure; - if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) -- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, -- survey->channel_time_busy); -+ if (nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, -+ survey->channel_time_busy)) -+ goto nla_put_failure; - if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) -- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, -- survey->channel_time_ext_busy); -+ if (nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, -+ survey->channel_time_ext_busy)) -+ goto nla_put_failure; - if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) -- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, -- survey->channel_time_rx); -+ if (nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, -+ survey->channel_time_rx)) -+ goto nla_put_failure; - if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) -- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, -- survey->channel_time_tx); -+ if (nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, -+ survey->channel_time_tx)) -+ goto nla_put_failure; - - nla_nest_end(msg, infoattr); - -@@ -4900,7 +5066,8 @@ __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, - return NULL; - } - -- NLA_PUT_U32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -+ if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; - data = nla_nest_start(skb, NL80211_ATTR_TESTDATA); - - ((void **)skb->cb)[0] = rdev; -@@ -5274,7 +5441,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, - if (err) - goto free_msg; - -- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); -+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -5558,7 +5726,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) - goto free_msg; - - if (msg) { -- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); -+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - return genlmsg_reply(msg, info); -@@ -5663,7 +5832,8 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) - else - ps_state = NL80211_PS_DISABLED; - -- NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); -+ if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - return genlmsg_reply(msg, info); -@@ -5841,19 +6011,26 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) - goto nla_put_failure; - - if (rdev->wowlan->any) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) -+ goto nla_put_failure; - if (rdev->wowlan->disconnect) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) -+ goto nla_put_failure; - if (rdev->wowlan->magic_pkt) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) -+ goto nla_put_failure; - if (rdev->wowlan->gtk_rekey_failure) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) -+ goto nla_put_failure; - if (rdev->wowlan->eap_identity_req) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) -+ goto nla_put_failure; - if (rdev->wowlan->four_way_handshake) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) -+ goto nla_put_failure; - if (rdev->wowlan->rfkill_release) -- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); -+ if (nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)) -+ goto nla_put_failure; - if (rdev->wowlan->n_patterns) { - struct nlattr *nl_pats, *nl_pat; - int i, pat_len; -@@ -5868,12 +6045,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) - if (!nl_pat) - goto nla_put_failure; - pat_len = rdev->wowlan->patterns[i].pattern_len; -- NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_MASK, -+ if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK, - DIV_ROUND_UP(pat_len, 8), -- rdev->wowlan->patterns[i].mask); -- NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_PATTERN, -+ rdev->wowlan->patterns[i].mask)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN, - pat_len, -- rdev->wowlan->patterns[i].pattern); -+ rdev->wowlan->patterns[i].pattern)) -+ goto nla_put_failure; - nla_nest_end(msg, nl_pat); - } - nla_nest_end(msg, nl_pats); -@@ -6146,7 +6325,8 @@ static int nl80211_probe_client(struct sk_buff *skb, - if (err) - goto free_msg; - -- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); -+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -6843,18 +7023,21 @@ static int nl80211_add_scan_req(struct sk_buff *msg, - if (!nest) - goto nla_put_failure; - for (i = 0; i < req->n_ssids; i++) -- NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid); -+ if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid)) -+ goto nla_put_failure; - nla_nest_end(msg, nest); - - nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); - if (!nest) - goto nla_put_failure; - for (i = 0; i < req->n_channels; i++) -- NLA_PUT_U32(msg, i, req->channels[i]->center_freq); -+ if (nla_put_u32(msg, i, req->channels[i]->center_freq)) -+ goto nla_put_failure; - nla_nest_end(msg, nest); - - if (req->ie) -- NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie); -+ if (nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) -+ goto nla_put_failure; - - return 0; - nla_put_failure: -@@ -6873,8 +7056,10 @@ static int nl80211_send_scan_msg(struct sk_buff *msg, - if (!hdr) - return -1; - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; - - /* ignore errors and send incomplete event anyway */ - nl80211_add_scan_req(msg, rdev); -@@ -6898,8 +7083,10 @@ nl80211_send_sched_scan_msg(struct sk_buff *msg, - if (!hdr) - return -1; - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; - - return genlmsg_end(msg, hdr); - -@@ -7022,26 +7209,33 @@ void nl80211_send_reg_change_event(struct regulatory_request *request) - } - - /* Userspace can always count this one always being set */ -- NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator); -+ if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator)) -+ goto nla_put_failure; - - if (request->alpha2[0] == '0' && request->alpha2[1] == '0') -- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE, -- NL80211_REGDOM_TYPE_WORLD); -+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, -+ NL80211_REGDOM_TYPE_WORLD)) -+ goto nla_put_failure; - else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') -- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE, -- NL80211_REGDOM_TYPE_CUSTOM_WORLD); -+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, -+ NL80211_REGDOM_TYPE_CUSTOM_WORLD)) -+ goto nla_put_failure; - else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') || - request->intersect) -- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE, -- NL80211_REGDOM_TYPE_INTERSECTION); -+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, -+ NL80211_REGDOM_TYPE_INTERSECTION)) -+ goto nla_put_failure; - else { -- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE, -- NL80211_REGDOM_TYPE_COUNTRY); -- NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2); -+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, -+ NL80211_REGDOM_TYPE_COUNTRY)) -+ goto nla_put_failure; -+ if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2)) -+ goto nla_put_failure; - } - - if (wiphy_idx_valid(request->wiphy_idx)) -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7075,9 +7269,12 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_FRAME, len, buf)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7155,10 +7352,14 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7206,15 +7407,21 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; - if (bssid) -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); -- NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status); -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) -+ goto nla_put_failure; -+ if (nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status)) -+ goto nla_put_failure; - if (req_ie) -- NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie); -+ if (nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) -+ goto nla_put_failure; - if (resp_ie) -- NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); -+ if (nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7246,13 +7453,18 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) -+ goto nla_put_failure; - if (req_ie) -- NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie); -+ if (nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) -+ goto nla_put_failure; - if (resp_ie) -- NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); -+ if (nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7283,14 +7495,19 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; - if (from_ap && reason) -- NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason); -+ if (nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) -+ goto nla_put_failure; - if (from_ap) -- NLA_PUT_FLAG(msg, NL80211_ATTR_DISCONNECTED_BY_AP); -+ if (nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) -+ goto nla_put_failure; - if (ie) -- NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie); -+ if (nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7321,9 +7538,12 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7354,11 +7574,15 @@ void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr)) -+ goto nla_put_failure; - if (ie_len && ie) -- NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); -+ if (nla_put(msg, NL80211_ATTR_IE, ie_len , ie)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7389,15 +7613,21 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; - if (addr) -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); -- NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type); -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type)) -+ goto nla_put_failure; - if (key_id != -1) -- NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id); -+ if (nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) -+ goto nla_put_failure; - if (tsc) -- NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); -+ if (nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7432,7 +7662,8 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy, - * Since we are applying the beacon hint to a wiphy we know its - * wiphy_idx is valid - */ -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy))) -+ goto nla_put_failure; - - /* Before */ - nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE); -@@ -7484,14 +7715,20 @@ static void nl80211_send_remain_on_chan_event( - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type); -- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type)) -+ goto nla_put_failure; -+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) -+ goto nla_put_failure; - - if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL) -- NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration); -+ if (nla_put_u32(msg, NL80211_ATTR_DURATION, duration)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7561,8 +7798,10 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7632,9 +7871,12 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, - return true; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) -+ goto nla_put_failure; - - err = genlmsg_end(msg, hdr); - if (err < 0) { -@@ -7682,10 +7924,14 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, - return -ENOMEM; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); -- NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_FRAME, len, buf)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7715,12 +7961,17 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); -- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_FRAME, len, buf)) -+ goto nla_put_failure; -+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) -+ goto nla_put_failure; - if (ack) -- NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); -+ if (nla_put_flag(msg, NL80211_ATTR_ACK)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7752,15 +8003,18 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; - - pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); - if (!pinfoattr) - goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, -- rssi_event); -+ if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, -+ rssi_event)) -+ goto nla_put_failure; - - nla_nest_end(msg, pinfoattr); - -@@ -7793,16 +8047,20 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) -+ goto nla_put_failure; - - rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA); - if (!rekey_attr) - goto nla_put_failure; - -- NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR, -- NL80211_REPLAY_CTR_LEN, replay_ctr); -+ if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR, -+ NL80211_REPLAY_CTR_LEN, replay_ctr)) -+ goto nla_put_failure; - - nla_nest_end(msg, rekey_attr); - -@@ -7835,17 +8093,22 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; - - attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); - if (!attr) - goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index); -- NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid); -+ if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid)) -+ goto nla_put_failure; - if (preauth) -- NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH); -+ if (nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)) -+ goto nla_put_failure; - - nla_nest_end(msg, attr); - -@@ -7877,9 +8140,12 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type); -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - -@@ -7961,15 +8227,19 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) -+ goto nla_put_failure; - - pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); - if (!pinfoattr) - goto nla_put_failure; - -- NLA_PUT_U32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets); -+ if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets)) -+ goto nla_put_failure; - - nla_nest_end(msg, pinfoattr); - -@@ -8003,12 +8273,17 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); -- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); -- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) -+ goto nla_put_failure; -+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) -+ goto nla_put_failure; - if (acked) -- NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); -+ if (nla_put_flag(msg, NL80211_ATTR_ACK)) -+ goto nla_put_failure; - - err = genlmsg_end(msg, hdr); - if (err < 0) { -@@ -8048,10 +8323,13 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, - return; - } - -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) -+ goto nla_put_failure; - if (freq) -- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); -- NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) -+ goto nla_put_failure; -+ if (nla_put(msg, NL80211_ATTR_FRAME, len, frame)) -+ goto nla_put_failure; - - genlmsg_end(msg, hdr); - diff --git a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0002-atheros-update-renamed-struct-members.patch b/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0002-atheros-update-renamed-struct-members.patch deleted file mode 100644 index 767bca0cf..000000000 --- a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/0002-atheros-update-renamed-struct-members.patch +++ /dev/null @@ -1,235 +0,0 @@ -From: Javier Viguera -Date: Fri, 13 Sep 2013 11:12:04 +0200 -Subject: [PATCH] atheros: update renamed struct members - -struct genl_info: s/snd_pid/snd_portid -struct netlink_notify: s/pid/portid -struct netlink_skb_parms: s/pid/portid - -Signed-off-by: Javier Viguera ---- - compat-wireless/net/wireless/nl80211.c | 50 ++++++++++++++++---------------- - 1 file changed, 25 insertions(+), 25 deletions(-) - -diff --git a/compat-wireless/net/wireless/nl80211.c b/compat-wireless/net/wireless/nl80211.c -index c219a2ca027f..2cba63866a90 100644 ---- a/compat-wireless/net/wireless/nl80211.c -+++ b/compat-wireless/net/wireless/nl80211.c -@@ -1122,7 +1122,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) - continue; - if (++idx <= start) - continue; -- if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, -+ if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI, - dev) < 0) { - idx--; -@@ -1145,7 +1145,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) { -+ if (nl80211_send_wiphy(msg, info->snd_portid, info->snd_seq, 0, dev) < 0) { - nlmsg_free(msg); - return -ENOBUFS; - } -@@ -1590,7 +1590,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * - if_idx++; - continue; - } -- if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, -+ if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI, - rdev, wdev->netdev) < 0) { - mutex_unlock(&rdev->devlist_mtx); -@@ -1621,7 +1621,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, -+ if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, - dev, netdev) < 0) { - nlmsg_free(msg); - return -ENOBUFS; -@@ -1922,7 +1922,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_NEW_KEY); - if (IS_ERR(hdr)) - return PTR_ERR(hdr); -@@ -2628,7 +2628,7 @@ static int nl80211_dump_station(struct sk_buff *skb, - goto out_err; - - if (nl80211_send_station(skb, -- NETLINK_CB(cb->skb).pid, -+ NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI, - netdev, mac_addr, - &sinfo) < 0) -@@ -2674,7 +2674,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, -+ if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0, - dev, mac_addr, &sinfo) < 0) { - nlmsg_free(msg); - return -ENOBUFS; -@@ -3062,7 +3062,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, - if (err) - goto out_err; - -- if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid, -+ if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI, - netdev, dst, next_hop, - &pinfo) < 0) -@@ -3111,7 +3111,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0, -+ if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, - dev, dst, next_hop, &pinfo) < 0) { - nlmsg_free(msg); - return -ENOBUFS; -@@ -3337,7 +3337,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) - return -ENOMEM; -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_GET_MESH_CONFIG); - if (!hdr) - goto out; -@@ -3612,7 +3612,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) - goto out; - } - -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_GET_REG); - if (!hdr) - goto put_failure; -@@ -4216,7 +4216,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, - - ASSERT_WDEV_LOCK(wdev); - -- hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags, -+ hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags, - NL80211_CMD_NEW_SCAN_RESULTS); - if (!hdr) - return -1; -@@ -4451,7 +4451,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, - } - - if (nl80211_send_survey(skb, -- NETLINK_CB(cb->skb).pid, -+ NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI, - netdev, - &survey) < 0) -@@ -5010,7 +5010,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb, - } - - while (1) { -- void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid, -+ void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, NLM_F_MULTI, - NL80211_CMD_TESTMODE); - struct nlattr *tmdata; -@@ -5090,7 +5090,7 @@ struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy, - return NULL; - - return __cfg80211_testmode_alloc_skb(rdev, approxlen, -- rdev->testmode_info->snd_pid, -+ rdev->testmode_info->snd_portid, - rdev->testmode_info->snd_seq, - GFP_KERNEL); - } -@@ -5427,7 +5427,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, - if (!msg) - return -ENOMEM; - -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_REMAIN_ON_CHANNEL); - - if (IS_ERR(hdr)) { -@@ -5638,7 +5638,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) - if (!rdev->ops->mgmt_tx) - return -EOPNOTSUPP; - -- return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, -+ return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_portid, - frame_type, - nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), - nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); -@@ -5708,7 +5708,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_FRAME); - - if (IS_ERR(hdr)) { -@@ -5820,7 +5820,7 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_GET_POWER_SAVE); - if (!hdr) { - err = -ENOBUFS; -@@ -5998,7 +5998,7 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) - if (!msg) - return -ENOMEM; - -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_GET_WOWLAN); - if (!hdr) - goto nla_put_failure; -@@ -6281,7 +6281,7 @@ static int nl80211_register_unexpected_frame(struct sk_buff *skb, - if (wdev->ap_unexpected_nlpid) - return -EBUSY; - -- wdev->ap_unexpected_nlpid = info->snd_pid; -+ wdev->ap_unexpected_nlpid = info->snd_portid; - return 0; - } - -@@ -6311,7 +6311,7 @@ static int nl80211_probe_client(struct sk_buff *skb, - if (!msg) - return -ENOMEM; - -- hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, -+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, - NL80211_CMD_PROBE_CLIENT); - - if (IS_ERR(hdr)) { -@@ -6349,7 +6349,7 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) - if (rdev->ap_beacons_nlpid) - return -EBUSY; - -- rdev->ap_beacons_nlpid = info->snd_pid; -+ rdev->ap_beacons_nlpid = info->snd_portid; - - return 0; - } -@@ -8357,8 +8357,8 @@ static int nl80211_netlink_notify(struct notifier_block * nb, - - list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { - list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) -- cfg80211_mlme_unregister_socket(wdev, notify->pid); -- if (rdev->ap_beacons_nlpid == notify->pid) -+ cfg80211_mlme_unregister_socket(wdev, notify->portid); -+ if (rdev->ap_beacons_nlpid == notify->portid) - rdev->ap_beacons_nlpid = 0; - } - diff --git a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/Makefile b/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/Makefile deleted file mode 100644 index 260054a7a..000000000 --- a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -ATH_DRV_BASEDIR := compat-wireless - -ifneq ($(KERNELRELEASE),) - -ATH_DEFINES += \ - -DCOMPAT_BASE_TREE="\"$(shell cat $(src)/$(ATH_DRV_BASEDIR)/compat_base_tree)\"" \ - -DCOMPAT_BASE_TREE_VERSION="\"$(shell cat $(src)/$(ATH_DRV_BASEDIR)/compat_base_tree_version)\"" \ - -DCOMPAT_PROJECT="\"Compat-wireless\"" \ - -DCOMPAT_VERSION="\"$(shell cat $(src)/$(ATH_DRV_BASEDIR)/compat_version)\"" - -NOSTDINC_FLAGS := -I$(M)/$(ATH_DRV_BASEDIR)/include/ \ - -include $(M)/$(ATH_DRV_BASEDIR)/include/linux/compat-2.6.h \ - $(ATH_DEFINES) - -include $(src)/$(ATH_DRV_BASEDIR)/config.mk - -SHELL_EXPORT := PATH=$(src)/$(ATH_DRV_BASEDIR)/scripts:$${PATH} \ - COMPAT_CONFIG=$(src)/$(ATH_DRV_BASEDIR)/config.mk \ - CONFIG_CHECK=.$(COMPAT_CONFIG)_md5sum.txt \ - COMPAT_AUTOCONF=$(src)/$(ATH_DRV_BASEDIR)/include/linux/compat_autoconf.h - -dummy := $(shell $(SHELL_EXPORT) bash -c "cd $(src)/$(ATH_DRV_BASEDIR) && ./scripts/check_config.sh || true") - -obj-y := $(ATH_DRV_BASEDIR)/compat/ -obj-y += $(ATH_DRV_BASEDIR)/net/wireless/ -obj-y += $(ATH_DRV_BASEDIR)/drivers/net/wireless/ath/ath6kl/ - -else #ifneq ($(KERNELRELEASE),) - -SRC := $(shell pwd) - -all: - $(MAKE) -C $(KERNEL_SRC) M=$(SRC) - -modules_install: - $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install - # Fix installation directory of the modules. - find $(INSTALL_MOD_PATH)/lib/modules/$(KERNEL_VERSION)/extra/$(ATH_DRV_BASEDIR) -type f -name '*.ko' | \ - xargs -I modfile mv -f modfile $(INSTALL_MOD_PATH)/lib/modules/$(KERNEL_VERSION)/extra/ - rm -rf $(INSTALL_MOD_PATH)/lib/modules/*/extra/$(ATH_DRV_BASEDIR) - -endif #ifneq ($(KERNELRELEASE),) diff --git a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/atheros-pre-up b/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/atheros-pre-up deleted file mode 100644 index 78e776de3..000000000 --- a/meta-digi-arm/recipes-kernel/kernel-module-atheros/kernel-module-atheros/atheros-pre-up +++ /dev/null @@ -1,139 +0,0 @@ -#!/bin/sh -#=============================================================================== -# -# 10-atheros_pre-up -# -# Copyright (C) 2012 by Digi International Inc. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 as published by -# the Free Software Foundation. -# -# -# !Description: Load Atheros' wireless driver -# -#=============================================================================== - -set -e - -[ "${IFACE}" != "wlan0" ] && exit 0 - -FIRMWARE_DIR="/lib/firmware/ath6k/AR6003/hw2.1.1" - -ATH6KL_DBG_NONE=0x0 -ATH6KL_DBG_CREDIT=0x00000001 -ATH6KL_DBG_WLAN_TX=0x00000004 -ATH6KL_DBG_WLAN_RX=0x00000008 -ATH6KL_DBG_BMI=0x00000010 -ATH6KL_DBG_HTC=0x00000020 -ATH6KL_DBG_HIF=0x00000040 -ATH6KL_DBG_IRQ=0x00000080 -ATH6KL_DBG_WMI=0x00000400 -ATH6KL_DBG_TRC=0x00000800 -ATH6KL_DBG_SCATTER=0x00001000 -ATH6KL_DBG_WLAN_CFG=0x00002000 -ATH6KL_DBG_RAW_BYTES=0x00004000 -ATH6KL_DBG_AGGR=0x00008000 -ATH6KL_DBG_SDIO=0x00010000 -ATH6KL_DBG_SDIO_DUMP=0x00020000 -ATH6KL_DBG_BOOT=0x00040000 -ATH6KL_DBG_WMI_DUMP=0x00080000 -ATH6KL_DBG_SUSPEND=0x00100000 -ATH6KL_DBG_USB=0x00200000 -ATH6KL_DBG_RECOVERY=0x00400000 -ATH6KL_DBG_ANY=0xffffffff - -ATH6KL_DEBUG_MASK="${ATH6KL_DBG_NONE}" - -# -# Get the wlan MAC address from kernel command line. Use a default -# value if the address has not been set. -# -if [ -f "/proc/device-tree/wireless/mac-address" ]; then - MAC_ADDR="$(hexdump -ve '1/1 "%02X" ":"' /proc/device-tree/wireless/mac-address | sed 's/:$//g')" -else - MAC_ADDR="$(sed -ne 's,^.*ethaddr2=\([^[:blank:]]\+\)[:blank:]*.*,\1,g;T;p' /proc/cmdline)" -fi -if [ -z "${MAC_ADDR}" -o "${MAC_ADDR}" = "00:00:00:00:00:00" ]; then - MAC_ADDR="00:04:F3:4C:B1:D3" -fi - -# We need to write the WLAN MAC address to softmac in the ath6k firmware -# directory. However, we don't want to rewrite the file if it already exists -# and the address is the same because we don't want to wear out NAND flash. -# -# So create the file on the RAM DRIVE first and compare the two. Only update -# the copy on NAND if the address has changed. -# -mac1="$(echo ${MAC_ADDR} | cut -d':' -f1)" -mac2="$(echo ${MAC_ADDR} | cut -d':' -f2)" -mac3="$(echo ${MAC_ADDR} | cut -d':' -f3)" -mac4="$(echo ${MAC_ADDR} | cut -d':' -f4)" -mac5="$(echo ${MAC_ADDR} | cut -d':' -f5)" -mac6="$(echo ${MAC_ADDR} | cut -d':' -f6)" - -TMP_MACFILE="$(mktemp -t softmac.XXXXXX)" -printf "\x${mac1}\x${mac2}\x${mac3}\x${mac4}\x${mac5}\x${mac6}" > ${TMP_MACFILE} -if ! cmp -s ${TMP_MACFILE} ${FIRMWARE_DIR}/softmac; then - cp ${TMP_MACFILE} ${FIRMWARE_DIR}/softmac -fi -rm -f ${TMP_MACFILE} - -# Figure out which wireless region we are in. The US has rules for -# what channels can be used and at what power level. We use a different set of -# rules for the other regions in the world that we sell into. The mod_cert field -# in OTP will be set to 0x0 for the US. Once we know the region, make sure the -# appropriate calibration file is loaded. -# -MACHINE="$(cat /proc/device-tree/digi,machine,name 2>/dev/null || \ - cat /sys/kernel/machine/name)" -MOD_VARIANT="$(cat /proc/device-tree/digi,hwid,variant 2>/dev/null || \ - cat /sys/kernel/${MACHINE}/mod_variant)" -REGION_CODE="$(cat /proc/device-tree/digi,hwid,cert 2>/dev/null || \ - cat /sys/kernel/${MACHINE}/mod_cert)" - -# 'ccimx6sbc' variants 0x05, 0x07 and 0x0a do not have bluetooth -# and use a different calibration file -US_CODE="0x0" -case "${MACHINE}:${MOD_VARIANT}:${REGION_CODE}" in - ccimx6sbc:0x05:${US_CODE}|ccimx6sbc:0x07:${US_CODE}|ccimx6sbc:0x0a:${US_CODE}) - BDATA_SOURCE="Digi_6203_2_ANT-US.bin" - logger -t atheros "Setting US wireless region (no bluetooth)";; - ccimx6sbc:0x05:*|ccimx6sbc:0x07:*|ccimx6sbc:0x0a:*) - BDATA_SOURCE="Digi_6203_2_ANT-World.bin" - logger -t atheros "Setting non-US (world) wireless region (no bluetooth)";; - *:*:${US_CODE}) - BDATA_SOURCE="Digi_6203-6233-US.bin" - logger -t atheros "Setting US wireless region";; - *:*:*) - BDATA_SOURCE="Digi_6203-6233-World.bin" - logger -t atheros "Setting non-US (world) wireless region";; -esac - -# We don't want to rewrite NAND every time we boot so only -# change the link if it is wrong. -BDATA_LINK="${FIRMWARE_DIR}/bdata.bin" -if [ ! -e "${BDATA_LINK}" ] || ! cmp -s "${BDATA_LINK}" "${FIRMWARE_DIR}/${BDATA_SOURCE}"; then - ln -sf "${BDATA_SOURCE}" "${BDATA_LINK}" -fi - -# Load 'cfg80211' and let it settle down (needed by 'ath6kl_sdio') -modprobe -q cfg80211 && sleep 0.2 - -# ath6kl_sdio.ko -if ! grep -qs ath6kl_sdio /proc/modules; then - RETRIES="5" - while [ "${RETRIES}" -gt "0" ]; do - modprobe --ignore-install -q ath6kl_sdio debug_mask="${ATH6KL_DEBUG_MASK}" || true - [ -d "/sys/class/net/wlan0" ] && break - RETRIES="$((RETRIES - 1))" - rmmod ath6kl_sdio > /dev/null - echo "Retrying to load wireless" - sleep 2 - done - [ "${RETRIES}" -eq "0" ] && echo "Loading ath6kl_sdio module: [FAILED]" -fi - -# Delay required for the interface 'wlan0' to settle down before trying to configure it. -sleep 0.5 diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-3.10/ccardimx28js/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-3.10/ccardimx28js/defconfig deleted file mode 100644 index 2699f0629..000000000 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-3.10/ccardimx28js/defconfig +++ /dev/null @@ -1,212 +0,0 @@ -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_UTS_NS is not set -# CONFIG_IPC_NS is not set -# CONFIG_PID_NS is not set -# CONFIG_NET_NS is not set -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_PERF_EVENTS=y -# CONFIG_COMPAT_BRK is not set -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODVERSIONS=y -CONFIG_BLK_DEV_INTEGRITY=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_ARCH_MULTI_V7 is not set -CONFIG_ARCH_MXS=y -# CONFIG_ARM_THUMB is not set -CONFIG_PREEMPT_VOLUNTARY=y -CONFIG_AEABI=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_FPE_NWFPE=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_SYN_COOKIES=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -CONFIG_BRIDGE=y -CONFIG_NET_SCHED=y -CONFIG_CAN=y -# CONFIG_CAN_GW is not set -CONFIG_CAN_FLEXCAN=y -CONFIG_BT=y -CONFIG_BT_RFCOMM=y -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=y -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=y -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_ATH3K=y -CONFIG_WIRELESS_EXT=y -CONFIG_RFKILL=y -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_FIRMWARE_IN_KERNEL is not set -# CONFIG_FW_LOADER_USER_HELPER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_SST25L=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_GPMI_NAND=y -CONFIG_MTD_UBI=y -CONFIG_PROC_DEVICETREE=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=16384 -CONFIG_SRAM=y -CONFIG_EEPROM_AT24=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -# CONFIG_NET_CADENCE is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_CIRRUS is not set -# CONFIG_NET_VENDOR_FARADAY is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_STMICRO is not set -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_SMSC_PHY=y -CONFIG_ICPLUS_PHY=y -CONFIG_REALTEK_PHY=y -CONFIG_MICREL_PHY=y -CONFIG_USB_USBNET=y -CONFIG_USB_NET_SMSC95XX=y -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_MXS_PSWITCH=y -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_MXS_AUART=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -# CONFIG_I2C_COMPAT is not set -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MXS=y -CONFIG_SPI=y -CONFIG_SPI_GPIO=y -CONFIG_SPI_MXS=y -CONFIG_SPI_SPIDEV=y -CONFIG_GPIO_SYSFS=y -CONFIG_W1=y -CONFIG_W1_MASTER_DS2482=y -CONFIG_W1_SLAVE_DS2431=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_STMP3XXX_RTC_WATCHDOG=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_FB=y -CONFIG_FB_MXS=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_PWM=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FONTS=y -CONFIG_LOGO=y -CONFIG_FB_LOGO_CENTERED=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_DYNAMIC_MINORS=y -# CONFIG_SND_DRIVERS is not set -# CONFIG_SND_ARM is not set -# CONFIG_SND_SPI is not set -# CONFIG_SND_USB is not set -CONFIG_SND_SOC=y -CONFIG_SND_MXS_SOC=y -CONFIG_SND_SOC_MXS_SGTL5000=y -CONFIG_USB=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_CHIPIDEA=y -CONFIG_USB_CHIPIDEA_UDC=y -CONFIG_USB_CHIPIDEA_HOST=y -CONFIG_USB_PHY=y -CONFIG_USB_MXS_PHY=y -CONFIG_USB_GADGET=y -CONFIG_USB_ETH=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_MMC=y -CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_MXS=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_STMP=y -CONFIG_DMADEVICES=y -CONFIG_MXS_DMA=y -CONFIG_STAGING=y -CONFIG_MXS_LRADC=y -CONFIG_IIO_SYSFS_TRIGGER=y -CONFIG_COMMON_CLK_DEBUG=y -CONFIG_IIO=y -CONFIG_PWM=y -CONFIG_PWM_MXS=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT3_FS=y -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_LZO=y -CONFIG_JFFS2_RUBIN=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_PRINTK_TIME=y -CONFIG_FRAME_WARN=2048 -CONFIG_UNUSED_SYMBOLS=y -CONFIG_DEBUG_KERNEL=y -# CONFIG_FTRACE is not set -# CONFIG_ARM_UNWIND is not set -# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_3.10.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_3.10.bb deleted file mode 100644 index 6d7e0ec69..000000000 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_3.10.bb +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (C) 2012 Digi International - -require recipes-kernel/linux/linux-dey.inc -require recipes-kernel/linux/linux-dtb.inc - -SRCBRANCH = "v3.10/dey-1.4/maint" -SRCREV = "${AUTOREV}" - -config_dts() { - for DTB in ${KERNEL_DEVICETREE}; do - if [ "${1}" = "enable" ]; then - sed -i -e "/${2}/{s,^///include,/include,g}" ${S}/arch/arm/boot/dts/${DTB%b}s - elif [ "${1}" = "disable" ]; then - sed -i -e "/${2}/{s,^/include,///include,g}" ${S}/arch/arm/boot/dts/${DTB%b}s - fi - done -} - -do_update_dts() { - if [ -n "${HAVE_WIFI}" ]; then - config_dts enable '_ssp2_mmc_wifi.dtsi' - else - config_dts disable '_ssp2_mmc_wifi.dtsi' - fi - if [ -n "${HAVE_SECOND_ETH}" ]; then - config_dts enable '_ethernet1.dtsi' - else - config_dts disable '_ethernet1.dtsi' - fi - if [ -n "${HAVE_BT}" ]; then - config_dts enable '_auart0_bluetooth.dtsi' - else - config_dts disable '_auart0_bluetooth.dtsi' - fi - if [ -n "${HAVE_1WIRE}" ]; then - config_dts enable '_onewire_i2c1.dtsi' - config_dts disable '_auart2_4wires.dtsi' - else - config_dts disable '_onewire_i2c1.dtsi' - fi - if [ -n "${HAVE_GUI}" ]; then - # Enable LCD - config_dts enable '_display_' - config_dts disable '_auart1_' - # Enable touch - config_dts enable '_lradc_touchscreen' - config_dts disable '_ssp1_' - config_dts disable '_auart1_4wires' - config_dts disable '_ethernet0_leds' - else - # spidev conflicts with touchscreen, thus enable it only - # when touch is disabled - if [ -n "${HAVE_EXAMPLE}" ]; then - config_dts enable 'ssp1_spi_gpio.dtsi' - config_dts enable 'ssp1_spi_gpio_spidev.dtsi' - fi - fi -} -addtask update_dts before do_install after do_sizecheck - -COMPATIBLE_MACHINE = "(ccardimx28)" diff --git a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0001-enable-libnl3.patch b/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0001-enable-libnl3.patch deleted file mode 100644 index 1cd5ac29c..000000000 --- a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0001-enable-libnl3.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Javier Viguera -Date: Thu, 31 Jan 2013 11:23:37 +0100 -Subject: [PATCH] enable-libnl3 - -Signed-off-by: Javier Viguera ---- - Makefile | 7 ++++++- - nl80211_utils.c | 4 ++-- - nl80211_utils.h | 2 +- - 3 files changed, 9 insertions(+), 4 deletions(-) - -diff --git a/Makefile b/Makefile -index 115ad33..6c21413 100644 ---- a/Makefile -+++ b/Makefile -@@ -56,17 +56,22 @@ LIBS= -ldbus-1 -lpthread -lrt -lbluetooth - - NL1FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-1 && echo Y) - NL2FOUND := $(shell $(PKG_CONFIG) --atleast-version=2 libnl-2.0 && echo Y) -+NL3FOUND := $(shell $(PKG_CONFIG) --atleast-version=3 libnl-3.0 && echo Y) - - ifeq ($(NL1FOUND),Y) -+CFLAGS += -DCONFIG_LIBNL1 - NLLIBNAME = libnl-1 - endif - - ifeq ($(NL2FOUND),Y) --CFLAGS += -DCONFIG_LIBNL20 - LIBS += -lnl-genl - NLLIBNAME = libnl-2.0 - endif - -+ifeq ($(NL3FOUND),Y) -+NLLIBNAME = libnl-3.0 -+endif -+ - #ifeq ($(NLLIBNAME),) - #$(error Cannot find development files for any supported version of libnl) - #endif -diff --git a/nl80211_utils.c b/nl80211_utils.c -index 4689044..2957f2e 100644 ---- a/nl80211_utils.c -+++ b/nl80211_utils.c -@@ -9,7 +9,7 @@ - #include - #include "nl80211_utils.h" - --#ifndef CONFIG_LIBNL20 -+#ifdef CONFIG_LIBNL1 - /* libnl 2.0 compatibility code */ - - static inline int __genl_ctrl_alloc_cache(struct nl_sock *h, struct nl_cache **cache) -@@ -24,7 +24,7 @@ static inline int __genl_ctrl_alloc_cache(struct nl_sock *h, struct nl_cache **c - #define nl_socket_alloc nl_handle_alloc - #define nl_socket_free nl_handle_destroy - --#endif /* CONFIG_LIBNL20 */ -+#endif /* CONFIG_LIBNL1 */ - - int iw_debug = 0; - -diff --git a/nl80211_utils.h b/nl80211_utils.h -index 6a0dbd7..6bbeb2c 100644 ---- a/nl80211_utils.h -+++ b/nl80211_utils.h -@@ -11,7 +11,7 @@ - #include - #include - --#ifndef CONFIG_LIBNL20 -+#ifdef CONFIG_LIBNL1 - #define nl_sock nl_handle - #endif - diff --git a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0002-cross-compile.patch b/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0002-cross-compile.patch deleted file mode 100644 index 98b1a3aac..000000000 --- a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0002-cross-compile.patch +++ /dev/null @@ -1,85 +0,0 @@ -From: Javier Viguera -Date: Tue, 16 Apr 2013 18:46:31 +0200 -Subject: [PATCH] cross-compile - -Signed-off-by: Javier Viguera ---- - Makefile | 43 +++++++++++++++++++++++++++---------------- - 1 file changed, 27 insertions(+), 16 deletions(-) - -diff --git a/Makefile b/Makefile -index 6c21413..91659dd 100644 ---- a/Makefile -+++ b/Makefile -@@ -25,13 +25,13 @@ SBINDIR ?= $(PREFIX)/sbin - MANDIR ?= $(PREFIX)/share/man - - PKG_CONFIG ?= pkg-config --ifdef V210 --CC= $(ATH_CROSS_COMPILE_TYPE)gcc --LD= $(ATH_CROSS_COMPILE_TYPE)ld --else --CC= $(ATH_CROSSS_COMPILE_TYPE)gcc --LD= $(ATH_CROSSS_COMPILE_TYPE)ld --endif -+# ifdef V210 -+# CC= $(ATH_CROSS_COMPILE_TYPE)gcc -+# LD= $(ATH_CROSS_COMPILE_TYPE)ld -+# else -+# CC= $(ATH_CROSSS_COMPILE_TYPE)gcc -+# LD= $(ATH_CROSSS_COMPILE_TYPE)ld -+# endif - SOURCES=abtfilt_main.c \ - abtfilt_wlan.c \ - abtfilt_core.c \ -@@ -40,19 +40,19 @@ SOURCES=abtfilt_main.c \ - nl80211_utils.c\ - btfilter_core.c - --INCLUDES= -Iinclude \ -+override INCLUDES += -Iinclude \ - -Ios/linux/include \ -- -Icommon/include \ -- -I$(V210_DIR)/usr/include/dbus-1.0/ \ -- -I$(V210_DIR)/usr/lib/dbus-1.0/include \ -- -I$(V210_DIR)/usr/local/include/dbus-1.0 \ -- -I$(V210_DIR)/usr/local/lib/dbus-1.0/include \ -- -I$(V210_DIR)/usr/include/bluetooth \ -- -I$(V210_DIR)/usr/local/include/bluetooth \ -+ -Icommon/include -+# -I$(V210_DIR)/usr/include/dbus-1.0/ \ -+# -I$(V210_DIR)/usr/lib/dbus-1.0/include \ -+# -I$(V210_DIR)/usr/local/include/dbus-1.0 \ -+# -I$(V210_DIR)/usr/local/lib/dbus-1.0/include \ -+# -I$(V210_DIR)/usr/include/bluetooth \ -+# -I$(V210_DIR)/usr/local/include/bluetooth \ - - CFLAGS= -Wall -g -DABF_DEBUG - #LIBS= -ldbus-1 -lpthread -lbtfilt -lrt -lbluetooth --LIBS= -ldbus-1 -lpthread -lrt -lbluetooth -+# LIBS= -ldbus-1 -lpthread -lrt -lbluetooth - - NL1FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-1 && echo Y) - NL2FOUND := $(shell $(PKG_CONFIG) --atleast-version=2 libnl-2.0 && echo Y) -@@ -79,6 +79,13 @@ endif - LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME)) - CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME)) - -+# dbus -+LIBS += $(shell $(PKG_CONFIG) --libs --static dbus-1) -+CFLAGS += $(shell $(PKG_CONFIG) --cflags dbus-1) -+ -+# BlueZ -+LIBS += $(shell $(PKG_CONFIG) --libs bluez) -+CFLAGS += $(shell $(PKG_CONFIG) --cflags bluez) - - ifdef BOARD_HAS_ATH_WLAN_AR6004 - CFLAGS += -DMULTI_WLAN_CHAN_SUPPORT -@@ -124,3 +131,7 @@ all: $(OBJECTS) - - clean: - rm -f $(FILTERAPP) $(OBJECTS) -+ -+install: -+ mkdir -p $(DESTDIR)$(SBINDIR) -+ install -m 0755 $(FILTERAPP) $(DESTDIR)$(SBINDIR) diff --git a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0003-abtfilt_wan-Rewrite-the-netlink-listener.patch b/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0003-abtfilt_wan-Rewrite-the-netlink-listener.patch deleted file mode 100644 index 955fe6df7..000000000 --- a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0003-abtfilt_wan-Rewrite-the-netlink-listener.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 641f02fe3638d291a0ef53c076bda7e68e2f7d28 Mon Sep 17 00:00:00 2001 -From: Alex Gonzalez -Date: Tue, 26 Aug 2014 16:57:14 +0200 -Subject: [PATCH] abtfilt_wan: Rewrite the netlink listener. - -Not sure how old this code is but it is not working properly any more. - -Not only it incorrectly detects the netlink messages as corrupted, but it -also assumes an RTM_DELLINK will be issued for the link down event which -is not correct. - -I have updated the code trying to touch as little things as possible. - -Signed-off-by: Alex Gonzalez ---- - abtfilt_wlan.c | 87 +++++++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 56 insertions(+), 31 deletions(-) - -diff --git a/abtfilt_wlan.c b/abtfilt_wlan.c -index b1966cef7ef2..64dffde37f19 100644 ---- a/abtfilt_wlan.c -+++ b/abtfilt_wlan.c -@@ -232,6 +232,59 @@ Abf_WlanDispatchIO(ATHBT_FILTER_INFO *pInfo, unsigned long int req, - return A_OK; - } - -+static void -+print_link(struct ifinfomsg *ifi, int len, int up) -+{ -+ struct rtattr *attrib; -+ -+ for(attrib = IFLA_RTA(ifi); RTA_OK(attrib, len); -+ attrib = RTA_NEXT(attrib, len)) { -+ switch(attrib->rta_type) { -+ case IFLA_IFNAME: -+ A_DEBUG("[%d:%s] Link %s\n", ifi->ifi_index, -+ (char *)RTA_DATA(attrib), up ? "UP" : "DOWN"); -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+static void -+parse_message(ATH_BT_FILTER_INSTANCE *pInstance, int len, char *buf) -+{ -+ struct nlmsghdr *msg_ptr; -+ struct ifinfomsg *ifi; -+ int len1; -+ -+ for(msg_ptr = (struct nlmsghdr *)buf; NLMSG_OK(msg_ptr, len); -+ msg_ptr = NLMSG_NEXT(msg_ptr, len)) { -+ /* Finish reading */ -+ if(msg_ptr->nlmsg_type == NLMSG_DONE) -+ break; -+ -+ /* Message is some kind of error */ -+ if(msg_ptr->nlmsg_type == NLMSG_ERROR) { -+ A_ERR("Message is an error.\n"); -+ break; -+ } -+ -+ if(msg_ptr->nlmsg_type == RTM_NEWLINK) { -+ ifi = NLMSG_DATA(msg_ptr); -+ len1 = msg_ptr->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); -+ if(ifi->ifi_flags & IFF_RUNNING){ -+ print_link(ifi, len1, 1); -+ NewLinkEvent(pInstance, msg_ptr, len1); -+ } -+ else { -+ print_link(ifi, len1, 0); -+ DelLinkEvent(pInstance, msg_ptr, len1); -+ } -+ break; -+ } -+ } -+} -+ - /* Internal functions */ - static void * - WlanEventThread(void *arg) -@@ -322,41 +375,13 @@ WlanEventThread(void *arg) - } while (left == -1 && errno == EINTR); - - if (left < 0) { -- A_ERR("[%s] recvfrom(netlink)\n", __FUNCTION__); -+ A_ERR("[%s] recvfrom(netlink) error %d\n", __FUNCTION__, -+ left); - continue; - // break; - } - -- h = (struct nlmsghdr *) buf; -- while (left >= (int)sizeof(*h)) { -- int len, plen; -- -- len = h->nlmsg_len; -- plen = len - sizeof(*h); -- if (len > left || plen < 0) { -- A_ERR("[%s] malformed netlink message\n", __FUNCTION__); -- continue; -- } -- -- //A_DEBUG("RTM Message Type: %s\n", -- // ((h->nlmsg_type == RTM_NEWLINK) ? -- // "RTM_NEWLINK" : ((h->nlmsg_type == RTM_DELLINK) ? -- // "RTM_DELLINK" : "RTM_OTHER"))); -- switch (h->nlmsg_type) { -- case RTM_NEWLINK: -- NewLinkEvent(pInstance, h, plen); -- break; -- case RTM_DELLINK: -- DelLinkEvent(pInstance, h, plen); -- break; -- default: -- break; -- } -- -- len = NLMSG_ALIGN(len); -- left -= len; -- h = (struct nlmsghdr *) ((char *) h + len); -- } -+ parse_message(pInstance, left, buf); - } - } - diff --git a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0004-add-fgnu89-flag-for-gcc5.patch b/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0004-add-fgnu89-flag-for-gcc5.patch deleted file mode 100644 index ee131ad1b..000000000 --- a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/0004-add-fgnu89-flag-for-gcc5.patch +++ /dev/null @@ -1,29 +0,0 @@ -From d631ddd830cfacf610a562b52fc953b14dff7962 Mon Sep 17 00:00:00 2001 -From: Isaac Hermida -Date: Fri, 6 Nov 2015 17:46:33 +0100 -Subject: [PATCH] add -fgnu89-inline flag for gcc5 - -The problem is the change of the default C standard from gnu89 to gnu11 - which changes the semantics of 'inline'. The issue is described in the - Porting guide at https://gcc.gnu.org/gcc-5/porting_to.html. - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 91659ddb788c..1e2e1d6b0584 100644 ---- a/Makefile -+++ b/Makefile -@@ -50,7 +50,7 @@ override INCLUDES += -Iinclude \ - # -I$(V210_DIR)/usr/include/bluetooth \ - # -I$(V210_DIR)/usr/local/include/bluetooth \ - --CFLAGS= -Wall -g -DABF_DEBUG -+CFLAGS= -Wall -g -DABF_DEBUG -fgnu89-inline - #LIBS= -ldbus-1 -lpthread -lbtfilt -lrt -lbluetooth - # LIBS= -ldbus-1 -lpthread -lrt -lbluetooth - --- -1.9.1 - diff --git a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/btfilter-init b/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/btfilter-init deleted file mode 100755 index 530a125ce..000000000 --- a/meta-digi-dey/recipes-connectivity/btfilter/btfilter-v3.4p4-b3.4.0.158/btfilter-init +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -#=============================================================================== -# -# btfilter -# -# Copyright (C) 2015 by Digi International Inc. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 as published by -# the Free Software Foundation. -# -# -# !Description: Configure Bluetooth -# -#=============================================================================== - -set -e - -if [ "${1}" != "start" ]; then - exit 0 -fi - -SCRIPTNAME="$(basename "${0}")" - -# Check if this hardware does support Bluetooth -if [ -d "/proc/device-tree/bluetooth" ]; then - echo "Starting btfilter service." - if ! abtfilt -b -x -s -w wlan0 1>/dev/null; then - echo "${SCRIPTNAME}: FAILED (abtfilt)" - exit - fi -fi diff --git a/meta-digi-dey/recipes-connectivity/btfilter/btfilter_v3.4p4-b3.4.0.158.bb b/meta-digi-dey/recipes-connectivity/btfilter/btfilter_v3.4p4-b3.4.0.158.bb deleted file mode 100644 index a381020d2..000000000 --- a/meta-digi-dey/recipes-connectivity/btfilter/btfilter_v3.4p4-b3.4.0.158.bb +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2013 Digi International. - -SUMMARY = "Atheros BT/wlan coexistance daemon" -SECTION = "network" -LICENSE = "ISC" -LIC_FILES_CHKSUM = "file://Makefile;beginline=1;endline=14;md5=8f6614b37751445a5f6a9bdc69be26b3" - -inherit bluetooth -inherit update-rc.d - -DEPENDS = "${BLUEZ} dbus libnl" - -SRC_URI = " \ - ${DIGI_PKG_SRC}/${PN}-${PV}.tar.bz2 \ - file://0001-enable-libnl3.patch \ - file://0002-cross-compile.patch \ - file://0003-abtfilt_wan-Rewrite-the-netlink-listener.patch \ - file://0004-add-fgnu89-flag-for-gcc5.patch \ - file://btfilter-init \ -" - -SRC_URI[md5sum] = "06a26d3a368c33b508d660ea84d476ee" -SRC_URI[sha256sum] = "b1af73003b622189b66d51911d429d6d205ac9227ec8278c8572ca0c68c7d5f3" - -EXTRA_OEMAKE = "INCLUDES=-I${STAGING_INCDIR}/bluetooth" - -do_install() { - install -d ${D}${bindir} ${D}${sysconfdir}/init.d/ - install -m 0755 abtfilt ${D}${bindir} - install -m 0755 ${WORKDIR}/btfilter-init ${D}${sysconfdir}/init.d/btfilter -} - -INITSCRIPT_NAME = "btfilter" -INITSCRIPT_PARAMS = "start 11 5 ." From 8eb567e8ed45eb02d16f87c98a4aeb94e53d5ca3 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 29 Jun 2017 11:10:56 +0200 Subject: [PATCH 008/113] ccardimx28js removal: simplify firmware-atheros recipe https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- .../firmware-atheros/firmware-atheros.bb | 18 +-- .../{ccimx6 => }/Digi_6203-6233-US.bin | Bin .../{ccimx6 => }/Digi_6203_2_ANT-US.bin | Bin .../{ccimx6 => }/Digi_6203_2_ANT-World.bin | Bin .../{ccimx6 => }/PS_ASIC_class_1.pst | 0 .../ccardimx28/Digi_6203-6233-US.bin | Bin 2048 -> 0 bytes .../ccardimx28/PS_ASIC_class_1.pst | 126 ------------------ 7 files changed, 5 insertions(+), 139 deletions(-) rename meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/{ccimx6 => }/Digi_6203-6233-US.bin (100%) rename meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/{ccimx6 => }/Digi_6203_2_ANT-US.bin (100%) rename meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/{ccimx6 => }/Digi_6203_2_ANT-World.bin (100%) rename meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/{ccimx6 => }/PS_ASIC_class_1.pst (100%) delete mode 100644 meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccardimx28/Digi_6203-6233-US.bin delete mode 100644 meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccardimx28/PS_ASIC_class_1.pst diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb index c039dc191..4855009a6 100644 --- a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb +++ b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb @@ -8,6 +8,8 @@ LIC_FILES_CHKSUM = "file://${DIGI_EULA_FILE};md5=4c0991cfde5c8a92338cbfe0f4f9a5c FW_ATH6KL = " \ file://athtcmd_ram.bin \ file://athwlan.bin \ + file://Digi_6203_2_ANT-US.bin \ + file://Digi_6203_2_ANT-World.bin \ file://Digi_6203-6233-US.bin \ file://Digi_6203-6233-World.bin \ file://fw-4.bin \ @@ -15,11 +17,6 @@ FW_ATH6KL = " \ file://utf.bin \ " -FW_ATH6KL_append_ccimx6 = " \ - file://Digi_6203_2_ANT-US.bin \ - file://Digi_6203_2_ANT-World.bin \ -" - FW_AR3K = " \ file://PS_ASIC_class_1.pst \ file://PS_ASIC_class_2.pst \ @@ -49,6 +46,8 @@ do_install() { install -m 0644 \ athtcmd_ram.bin \ athwlan.bin \ + Digi_6203_2_ANT-US.bin \ + Digi_6203_2_ANT-World.bin \ Digi_6203-6233-US.bin \ Digi_6203-6233-World.bin \ fw-4.bin \ @@ -63,13 +62,6 @@ do_install() { ln -sf Digi_6203-6233-US.bin ${D}${base_libdir}/firmware/ath6k/AR6003/hw2.1.1/bdata.0x0.bin ln -sf Digi_6203-6233-World.bin ${D}${base_libdir}/firmware/ath6k/AR6003/hw2.1.1/bdata.0x1.bin ln -sf Digi_6203-6233-World.bin ${D}${base_libdir}/firmware/ath6k/AR6003/hw2.1.1/bdata.0x2.bin -} - -do_install_append_ccimx6() { - install -m 0644 \ - Digi_6203_2_ANT-US.bin \ - Digi_6203_2_ANT-World.bin \ - ${D}${base_libdir}/firmware/ath6k/AR6003/hw2.1.1/ ln -sf Digi_6203_2_ANT-US.bin ${D}${base_libdir}/firmware/ath6k/AR6003/hw2.1.1/bdata.ANT-0x0.bin ln -sf Digi_6203_2_ANT-World.bin ${D}${base_libdir}/firmware/ath6k/AR6003/hw2.1.1/bdata.ANT-0x1.bin ln -sf Digi_6203_2_ANT-World.bin ${D}${base_libdir}/firmware/ath6k/AR6003/hw2.1.1/bdata.ANT-0x2.bin @@ -82,4 +74,4 @@ FILES_${PN}-ar3k = "/lib/firmware/ar3k" FILES_${PN}-ath6kl = "/lib/firmware/ath6k" PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(ccardimx28|ccimx6$)" +COMPATIBLE_MACHINE = "(ccimx6$)" diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/Digi_6203-6233-US.bin b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/Digi_6203-6233-US.bin similarity index 100% rename from meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/Digi_6203-6233-US.bin rename to meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/Digi_6203-6233-US.bin diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/Digi_6203_2_ANT-US.bin b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/Digi_6203_2_ANT-US.bin similarity index 100% rename from meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/Digi_6203_2_ANT-US.bin rename to meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/Digi_6203_2_ANT-US.bin diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/Digi_6203_2_ANT-World.bin b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/Digi_6203_2_ANT-World.bin similarity index 100% rename from meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/Digi_6203_2_ANT-World.bin rename to meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/Digi_6203_2_ANT-World.bin diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/PS_ASIC_class_1.pst b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/PS_ASIC_class_1.pst similarity index 100% rename from meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccimx6/PS_ASIC_class_1.pst rename to meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/PS_ASIC_class_1.pst diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccardimx28/Digi_6203-6233-US.bin b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccardimx28/Digi_6203-6233-US.bin deleted file mode 100644 index 74e7f50fec9506d45bd328ec780f7ae2a445df9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmZSJU|?WV=TBf}aLM;*W?)cAW?(pGz`$J3+V}!OGBPrRJDHdm8@R+9m{^!68W`v@ ze%Q<*rK7|E1tKgA3<(Pu70~cI93Il4tgNsU#l8TD5k&=>5k3kEGGZAZVhe~k3nKo5)SwYSbqWe{GGZbT zFa}T)M5G7C0Ga?1*$ZO;jf04QO#>P0CkF&FQX(Q@Fh(4V(FbF!gE98Q7{_4@xH$zf zK(GTu09jH}ogiWjhyY7SNQj64g=Azv44^QCfk%o#KukhVNL1Xx&C$u#z|6wX$kZI< zTn3+-fSQb&o|*+UTWa>!oUK9U`_+Wiq}BA*%&S>fv%lteO+ig*&7zwBz~F;GLj0r?D5|7UP>b9HxhcKTnJqV?-PgS(r%hr6@W-?|jf z4?v!av#Ya%-KVczJqyd%3ydal)t+9Yf$%eVSeWe;yZqe`i0(fY0M F005(lRb&7F diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccardimx28/PS_ASIC_class_1.pst b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccardimx28/PS_ASIC_class_1.pst deleted file mode 100644 index 4ad2e1f52..000000000 --- a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/ccardimx28/PS_ASIC_class_1.pst +++ /dev/null @@ -1,126 +0,0 @@ - -// Radio table TAG -# -[H:S]012C -[H:S]00EE -[H:A]B1 B1 12 00 B8 08 FE FE 7D 00 17 00 00 20 02 00 - 0C 09 00 14 00 00 8C 08 00 00 00 40 80 08 78 00 - 00 01 84 08 AD AC 80 5F 88 08 20 3F 00 41 8C 08 - 00 00 00 40 94 08 54 25 64 92 98 08 C8 4E 2C 2E - 9C 08 C0 20 DA 2C C0 08 B6 0D 01 00 C4 08 6C DB - B6 6D C8 08 DB 36 D3 6D CC 08 60 DB B6 6D 00 09 - 50 00 92 04 04 09 20 49 00 80 08 09 E0 6F 5B E5 - 0C 09 00 14 00 00 10 09 81 03 30 F0 14 09 80 80 - 43 00 18 09 00 00 00 80 1C 09 00 00 00 00 20 09 - 02 00 00 00 88 0A 00 60 77 58 61 00 00 60 02 00 - 04 07 C4 C1 8B 00 1C 00 00 05 90 01 0C 07 00 0D - 00 00 30 00 D8 70 EF 4A 7C 00 B0 D2 5A B1 78 00 - DE 7A 58 00 5C 00 01 00 14 01 44 00 00 00 10 E4 - 84 00 3F F0 E7 04 C0 00 90 01 2C 00 C4 00 80 D6 - 82 03 DC 00 D8 40 06 00 88 00 52 6C 3D 0E -// Radio table TAG -# -[H:S]012D -[H:S]00F0 -[H:A]94 00 41 06 00 00 80 00 20 9C C8 00 90 00 DD DD - 97 06 54 00 E0 A6 09 00 10 07 3D A0 00 3D 14 07 - A0 80 01 00 18 07 17 55 D1 0C 1C 07 6D 23 00 00 - C0 07 65 A8 0C 0B E4 07 27 CA 54 00 C4 07 FF FF - FF 3F C8 07 FF FF E3 3F CC 07 FF FF FF 3F D0 07 - FF FF FF 3F D4 07 3F FE FF 3F D8 07 FF FF FF 3F - DC 07 FF FF FF 38 E0 07 FF FF FF 3F BC 07 D8 05 - 00 00 B8 07 42 00 0B 00 00 05 4A 1C 00 00 04 05 - 8A 1C 00 00 08 05 CA 1C 00 00 0C 05 0A 1D 00 00 - 10 05 4A 1D 00 00 14 05 1A 1C 00 00 18 05 5A 1C - 00 00 1C 05 9A 1C 00 00 20 05 DA 1C 00 00 24 05 - 1A 1D 00 00 28 05 5A 1D 00 00 2C 05 2A 1C 00 00 - 30 05 6A 1C 00 00 34 05 AA 1C 00 00 38 05 EA 1C - 00 00 3C 05 2A 1D 00 00 40 05 6A 1D 00 00 44 05 - 3A 1C 00 00 48 05 2B 1C 00 00 4C 05 6B 1C 00 00 - -// Radio table TAG -# -[H:S]012E -[H:S]00F0 -[H:A]50 05 AB 1C 00 00 54 05 EB 1C 00 00 58 05 2B 1D - 00 00 5C 05 5C 1D 00 00 60 05 2C 1C 00 00 64 05 - 6C 1C 00 00 68 05 AC 1C 00 00 6C 05 1D 1D 00 00 - 70 05 2D 1C 00 00 74 05 6D 1C 00 00 78 05 AD 1C - 00 00 7C 05 ED 1C 00 00 80 05 2D 1D 00 00 84 05 - 6D 1D 00 00 88 05 3D 1C 00 00 8C 05 7D 1C 00 00 - 90 05 AE 1C 00 00 94 05 EE 1C 00 00 98 05 2E 1D - 00 00 9C 05 6E 1D 00 00 A0 05 3E 1C 00 00 A4 05 - 7E 1C 00 00 A8 05 BE 1C 00 00 AC 05 2F 1C 00 00 - B0 05 6F 1C 00 00 B4 05 AF 1C 00 00 B8 05 EF 1C - 00 00 BC 05 2F 1D 00 00 C0 05 6F 1D 00 00 C4 05 - AF 1D 00 00 C8 05 BF 00 00 00 CC 05 FF 1C 00 00 - D0 05 3F 01 00 00 D4 05 7F 01 00 00 D8 05 BF 01 - 00 00 DC 05 FF 01 00 00 E0 05 3F 02 00 00 E4 05 - 7F 12 00 00 E8 05 BF 02 00 00 EC 05 FF 02 00 00 - -// Radio table TAG -# -[H:S]012F -[H:S]0044 -[H:A]F0 05 3F 03 00 00 F4 05 7F 03 00 00 F8 05 BF 03 - 00 00 FC 05 FF 03 00 00 04 00 00 00 02 00 10 00 - 01 CE C0 10 14 00 07 04 00 00 A0 04 00 E9 FF 03 - BC 04 FF 41 00 00 01 00 00 C0 02 00 B8 01 01 00 - 00 00 B2 B2 - -// System config TAG -# -[H:S]0013 -[H:S]00F0 -[H:A]C1 C1 20 02 BD 08 FE FE C9 00 00 CC B1 01 20 00 - FF CC 02 CC 04 00 B6 FB A9 90 00 21 00 E0 FF CC - 08 CC 1E 00 80 84 00 07 DB 05 93 11 FF CC 0E CC - 0B 00 E4 FF 61 47 00 00 4D FD 61 47 00 00 58 FD - E8 FF 41 27 04 00 6F FD 41 27 04 00 6C FD EC FF - A0 A7 00 00 2F FD A0 A7 00 00 6D FD F0 FF 60 27 - 01 00 50 FD 60 27 01 00 6F FD F4 FF A0 C7 04 00 - 3A FD A0 C7 04 00 89 FD F8 FF 80 C7 08 00 12 FD - 80 C7 08 00 58 FD FC FF 40 47 09 00 66 FD 40 47 - 09 00 0B FD 00 00 80 C7 0D 00 09 FD 80 C7 0D 00 - 09 FD 04 00 20 47 0E 40 58 FD 20 47 0E 40 58 FD - 08 00 60 47 13 40 58 FD 60 47 13 40 58 FD 0C 00 - 00 E7 13 40 58 FD 00 E7 13 40 58 FD FF CC 0F CC - 01 01 01 01 07 04 03 33 00 0A 00 04 00 00 60 6D - F0 00 66 01 00 00 00 00 00 00 FF CC 10 CC 22 81 - -// System config TAG -# -[H:S]0014 -[H:S]00AE -[H:A]A0 0F A0 00 32 00 02 08 0A 64 20 20 0A FF 20 20 - FF CC 11 CC 01 01 FF CC 12 CC 09 01 FF 03 00 FF - FF 03 FF CC 13 CC 02 19 B8 0B 17 0F E0 FD E0 FD - E0 FD E0 FD 58 FD 14 FD 58 FD 14 FD 54 25 11 A0 - 92 24 00 00 00 00 00 00 00 00 00 00 00 00 02 64 - 04 02 03 FF 04 03 FF CC 1A CC 0C 02 08 00 60 47 - 13 40 58 FD 0C 00 00 E7 13 40 58 FD FF CC 18 CC - 01 00 05 05 14 0A FF CC 17 CC 20 01 FF CC 16 CC - 07 00 C9 B0 B4 00 FF CC 14 CC 01 01 FF CC 15 CC - 01 00 08 00 FF CC 1D CC 01 00 00 00 00 00 FB 00 - 16 F5 08 00 24 24 07 00 1C 1C FF CC C2 C2 -// Coex Configuration -# -[H:S]0017 -[H:S]0026 -[H:A]D1 D1 20 00 02 01 02 09 0C 00 24 1F 12 00 00 01 - 00 01 00 00 01 01 01 01 01 00 00 00 01 00 01 01 - 01 01 01 00 D2 D2 - -//Audio - Audio main config -# -[H:S]0041 -[H:S]0004 -[H:A]01 00 00 00 - -//TLPM -//HOST TLPM 6W (GPIO14) Enable Active low No ack, Target TLPM 4W Enable Active low, No ack -# -[H:S]0023 -[H:S]0018 -[H:A]06 0E 06 0F 08 08 00 0E 05 00 05 00 2C 01 00 00 - E8 03 00 00 C8 00 00 00 \ No newline at end of file From 58480d6dff0cd66525425ae70775e711d32e19f6 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 29 Jun 2017 11:16:20 +0200 Subject: [PATCH 009/113] ccardimx28js removal: simplify alsa-state recipe https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- .../alsa-state/alsa-state.bbappend | 12 -- .../alsa-state/ccardimx28/asound.inline.state | 114 ----------- .../ccardimx28/asound.inline_play.state | 114 ----------- .../alsa-state/ccardimx28/asound.micro.state | 188 ------------------ .../ccardimx28/asound.micro_play.state | 114 ----------- .../alsa-state/ccardimx28/asound.play.state | 114 ----------- 6 files changed, 656 deletions(-) delete mode 100644 meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline.state delete mode 100644 meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline_play.state delete mode 100644 meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro.state delete mode 100644 meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro_play.state delete mode 100644 meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.play.state diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend index e21da25b4..5cc823267 100644 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend +++ b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend @@ -10,20 +10,8 @@ SRC_URI_append_ccimx6 = " \ file://asound.play.state \ " -SRC_URI_append_ccardimx28 = " \ - file://asound.inline_play.state \ - file://asound.inline.state \ - file://asound.micro_play.state \ - file://asound.micro.state \ - file://asound.play.state \ -" - SRC_URI_append_ccimx6ul = " file://asound.state" do_install_append_ccimx6() { ln -sf asound.micro_play.state ${D}${localstatedir}/lib/alsa/asound.state } - -do_install_append_ccardimx28() { - ln -sf asound.micro_play.state ${D}${localstatedir}/lib/alsa/asound.state -} diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline.state deleted file mode 100644 index 5a3fa2a42..000000000 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline.state +++ /dev/null @@ -1,114 +0,0 @@ -state.mxssgtl5000 { - control.1 { - iface MIXER - name 'PCM Playback Volume' - value.0 154 - value.1 154 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 192' - } - } - control.2 { - iface MIXER - name 'Capture Volume' - value.0 11 - value.1 11 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 15' - } - } - control.3 { - iface MIXER - name 'Capture Attenuate Switch (-6dB)' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 2' - dbmin -600 - dbmax 600 - dbvalue.0 -600 - } - } - control.4 { - iface MIXER - name 'Capture ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.5 { - iface MIXER - name 'Headphone Playback Volume' - value.0 115 - value.1 115 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -5150 - dbmax 1200 - dbvalue.0 600 - dbvalue.1 600 - } - } - control.6 { - iface MIXER - name 'Headphone Playback ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.7 { - iface MIXER - name 'Mic Volume' - value 2 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 3' - dbmin 0 - dbmax 4000 - dbvalue.0 3000 - } - } - control.8 { - iface MIXER - name 'Headphone Mux' - value LINE_IN - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 DAC - item.1 LINE_IN - } - } - control.9 { - iface MIXER - name 'Capture Mux' - value LINE_IN - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 MIC_IN - item.1 LINE_IN - } - } -} diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline_play.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline_play.state deleted file mode 100644 index 434eda5b0..000000000 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.inline_play.state +++ /dev/null @@ -1,114 +0,0 @@ -state.mxssgtl5000 { - control.1 { - iface MIXER - name 'PCM Playback Volume' - value.0 154 - value.1 154 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 192' - } - } - control.2 { - iface MIXER - name 'Capture Volume' - value.0 11 - value.1 11 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 15' - } - } - control.3 { - iface MIXER - name 'Capture Attenuate Switch (-6dB)' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 2' - dbmin -600 - dbmax 600 - dbvalue.0 -600 - } - } - control.4 { - iface MIXER - name 'Capture ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.5 { - iface MIXER - name 'Headphone Playback Volume' - value.0 115 - value.1 115 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -5150 - dbmax 1200 - dbvalue.0 600 - dbvalue.1 600 - } - } - control.6 { - iface MIXER - name 'Headphone Playback ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.7 { - iface MIXER - name 'Mic Volume' - value 2 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 3' - dbmin 0 - dbmax 4000 - dbvalue.0 3000 - } - } - control.8 { - iface MIXER - name 'Headphone Mux' - value DAC - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 DAC - item.1 LINE_IN - } - } - control.9 { - iface MIXER - name 'Capture Mux' - value LINE_IN - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 MIC_IN - item.1 LINE_IN - } - } -} diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro.state deleted file mode 100644 index 113b99bea..000000000 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro.state +++ /dev/null @@ -1,188 +0,0 @@ -state.ccardxmx28 { - control.1 { - comment.access 'read write' - comment.type ENUMERATED - comment.count 1 - comment.item.0 '0dB' - comment.item.1 '20dB' - comment.item.2 '30dB' - comment.item.3 '40dB' - iface MIXER - name 'MIC GAIN' - value '0dB' - } - control.2 { - comment.access 'read write' - comment.type INTEGER - comment.count 2 - comment.range '0 - 15' - iface MIXER - name 'Capture Volume' - value.0 15 - value.1 15 - } - control.3 { - comment.access 'read write' - comment.type ENUMERATED - comment.count 1 - comment.item.0 'No Change' - comment.item.1 'Reduced by 6dB' - iface MIXER - name 'Capture Vol Reduction' - value 'No Change' - } - control.4 { - comment.access 'read write' - comment.type INTEGER - comment.count 2 - comment.range '0 - 192' - iface MIXER - name 'Playback Volume' - value.0 132 - value.1 132 - } - control.5 { - comment.access 'read write' - comment.type INTEGER - comment.count 2 - comment.range '0 - 127' - iface MIXER - name 'Headphone Volume' - value.0 103 - value.1 103 - } - control.6 { - comment.access 'read write' - comment.type ENUMERATED - comment.count 1 - comment.item.0 DAC - comment.item.1 LINE_IN - iface MIXER - name 'DAC Mux' - value DAC - } - control.7 { - comment.access 'read write' - comment.type ENUMERATED - comment.count 1 - comment.item.0 MIC_IN - comment.item.1 LINE_IN - iface MIXER - name 'ADC Mux' - value MIC_IN - } -} -state.mxssgtl5000 { - control.1 { - iface MIXER - name 'PCM Playback Volume' - value.0 138 - value.1 138 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 192' - } - } - control.2 { - iface MIXER - name 'Capture Volume' - value.0 0 - value.1 0 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 15' - } - } - control.3 { - iface MIXER - name 'Capture Attenuate Switch (-6dB)' - value 2 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 2' - dbmin -600 - dbmax 600 - dbvalue.0 600 - } - } - control.4 { - iface MIXER - name 'Capture ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.5 { - iface MIXER - name 'Headphone Playback Volume' - value.0 103 - value.1 103 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -5150 - dbmax 1200 - dbvalue.0 0 - dbvalue.1 0 - } - } - control.6 { - iface MIXER - name 'Headphone Playback ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.7 { - iface MIXER - name 'Mic Volume' - value 1 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 3' - dbmin 0 - dbmax 4000 - dbvalue.0 2000 - } - } - control.8 { - iface MIXER - name 'Headphone Mux' - value LINE_IN - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 DAC - item.1 LINE_IN - } - } - control.9 { - iface MIXER - name 'Capture Mux' - value MIC_IN - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 MIC_IN - item.1 LINE_IN - } - } -} diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro_play.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro_play.state deleted file mode 100644 index 992cc8945..000000000 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.micro_play.state +++ /dev/null @@ -1,114 +0,0 @@ -state.mxssgtl5000 { - control.1 { - iface MIXER - name 'PCM Playback Volume' - value.0 138 - value.1 138 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 192' - } - } - control.2 { - iface MIXER - name 'Capture Volume' - value.0 0 - value.1 0 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 15' - } - } - control.3 { - iface MIXER - name 'Capture Attenuate Switch (-6dB)' - value 2 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 2' - dbmin -600 - dbmax 600 - dbvalue.0 600 - } - } - control.4 { - iface MIXER - name 'Capture ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.5 { - iface MIXER - name 'Headphone Playback Volume' - value.0 103 - value.1 103 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -5150 - dbmax 1200 - dbvalue.0 0 - dbvalue.1 0 - } - } - control.6 { - iface MIXER - name 'Headphone Playback ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.7 { - iface MIXER - name 'Mic Volume' - value 1 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 3' - dbmin 0 - dbmax 4000 - dbvalue.0 2000 - } - } - control.8 { - iface MIXER - name 'Headphone Mux' - value DAC - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 DAC - item.1 LINE_IN - } - } - control.9 { - iface MIXER - name 'Capture Mux' - value MIC_IN - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 MIC_IN - item.1 LINE_IN - } - } -} diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.play.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.play.state deleted file mode 100644 index 8a1bdb44e..000000000 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccardimx28/asound.play.state +++ /dev/null @@ -1,114 +0,0 @@ -state.mxssgtl5000 { - control.1 { - iface MIXER - name 'PCM Playback Volume' - value.0 142 - value.1 142 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 192' - } - } - control.2 { - iface MIXER - name 'Capture Volume' - value.0 11 - value.1 11 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 15' - } - } - control.3 { - iface MIXER - name 'Capture Attenuate Switch (-6dB)' - value 0 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 2' - dbmin -600 - dbmax 600 - dbvalue.0 -600 - } - } - control.4 { - iface MIXER - name 'Capture ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.5 { - iface MIXER - name 'Headphone Playback Volume' - value.0 115 - value.1 115 - comment { - access 'read write' - type INTEGER - count 2 - range '0 - 127' - dbmin -5150 - dbmax 1200 - dbvalue.0 600 - dbvalue.1 600 - } - } - control.6 { - iface MIXER - name 'Headphone Playback ZC Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.7 { - iface MIXER - name 'Mic Volume' - value 2 - comment { - access 'read write' - type INTEGER - count 1 - range '0 - 3' - dbmin 0 - dbmax 4000 - dbvalue.0 3000 - } - } - control.8 { - iface MIXER - name 'Headphone Mux' - value DAC - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 DAC - item.1 LINE_IN - } - } - control.9 { - iface MIXER - name 'Capture Mux' - value LINE_IN - comment { - access 'read write' - type ENUMERATED - count 1 - item.0 MIC_IN - item.1 LINE_IN - } - } -} From be58e0c849fc66fbe11588b3824f2bd50d53ea3c Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 2 Aug 2017 10:54:24 +0200 Subject: [PATCH 010/113] ccardimx28js removal: simplify dey-examples https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- .../recipes-digi/dey-examples/dey-examples-bt.bb | 4 ++-- .../dey-examples/dey-examples-btconfig.bb | 4 ++-- .../recipes-digi/dey-examples/dey-examples-can.bb | 4 ++-- .../recipes-digi/dey-examples/dey-examples-hdp.bb | 4 ++-- .../dey-examples/dey-examples-spidev.bb | 13 +------------ .../packagegroups/packagegroup-dey-examples.bb | 11 ++--------- 6 files changed, 11 insertions(+), 29 deletions(-) diff --git a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-bt.bb b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-bt.bb index ed1a49ad6..6b467525e 100644 --- a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-bt.bb +++ b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-bt.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013,2017 Digi International. +# Copyright (C) 2013-2017, Digi International Inc. SUMMARY = "DEY examples: application to transfer data over bluetooth" SECTION = "examples" @@ -22,4 +22,4 @@ do_install() { install -m 0755 bt_test ${D}${bindir} } -COMPATIBLE_MACHINE = "(ccardimx28|ccimx6$|ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" diff --git a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-btconfig.bb b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-btconfig.bb index f05173b94..f533b8237 100644 --- a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-btconfig.bb +++ b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-btconfig.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013,2017 Digi International. +# Copyright (C) 2013-2017, Digi International Inc. SUMMARY = "DEY examples: application to perform low level bluetooth" SECTION = "examples" @@ -22,4 +22,4 @@ do_install() { install -m 0755 btconfig ${D}${bindir} } -COMPATIBLE_MACHINE = "(ccardimx28|ccimx6$|ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" diff --git a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-can.bb b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-can.bb index a0cd3eecd..fa793a6c4 100644 --- a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-can.bb +++ b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-can.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013,2017 Digi International. +# Copyright (C) 2013-2017, Digi International Inc. SUMMARY = "DEY examples: CAN bus test application" SECTION = "examples" @@ -18,4 +18,4 @@ do_install() { install -m 0755 can_test ${D}${bindir} } -COMPATIBLE_MACHINE = "(ccardimx28|ccimx6$|ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" diff --git a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-hdp.bb b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-hdp.bb index e5642292f..ab52fd51d 100644 --- a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-hdp.bb +++ b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-hdp.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013 Digi International. +# Copyright (C) 2013-2017, Digi International Inc. SUMMARY = "DEY examples: bluetooth health profile test application" SECTION = "examples" @@ -16,4 +16,4 @@ do_install() { RDEPENDS_${PN} = "python3 python3-argparse python3-crypt python3-dbus python3-pygobject" -COMPATIBLE_MACHINE = "(ccardimx28|ccimx6$|ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" diff --git a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-spidev.bb b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-spidev.bb index 1f2ef985b..1acfd89ed 100644 --- a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-spidev.bb +++ b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-spidev.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013,2017 Digi International. +# Copyright (C) 2013-2017, Digi International Inc. SUMMARY = "DEY examples: SPI device driver test application" SECTION = "examples" @@ -9,17 +9,6 @@ SRC_URI = "file://spidev_test" S = "${WORKDIR}/spidev_test" -python do_warning_spidev() { - pass -} - -# Warn the user in case we cannot enable spidev in the device tree -python do_warning_spidev_ccardimx28() { - if d.getVar('HAVE_GUI', True): - bb.warn("SPIDEV conflicts with touchscreen so it was not enabled in the device tree") -} -addtask warning_spidev before do_compile - do_compile() { ${CC} -O2 -Wall ${LDFLAGS} spidev_test.c -o spidev_test } diff --git a/meta-digi-dey/recipes-digi/packagegroups/packagegroup-dey-examples.bb b/meta-digi-dey/recipes-digi/packagegroups/packagegroup-dey-examples.bb index 77bbc682b..e9c891015 100644 --- a/meta-digi-dey/recipes-digi/packagegroups/packagegroup-dey-examples.bb +++ b/meta-digi-dey/recipes-digi/packagegroups/packagegroup-dey-examples.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2017 Digi International. +# Copyright (C) 2013-2017, Digi International Inc. SUMMARY = "DEY examples packagegroup" @@ -16,13 +16,6 @@ RDEPENDS_${PN} = "\ dey-examples-watchdog \ " -RDEPENDS_${PN}_append_ccardimx28 = "\ - ${@bb.utils.contains("MACHINE_FEATURES", "bluetooth", "dey-examples-bt", "", d)} \ - ${@bb.utils.contains("MACHINE_FEATURES", "bluetooth", "dey-examples-btconfig", "", d)} \ - dey-examples-can \ - ${@bb.utils.contains("MACHINE_FEATURES", "bluetooth", "dey-examples-hdp", "", d)} \ -" - RDEPENDS_${PN}_append_ccimx6 = "\ awsiotsdk-demo \ ${@bb.utils.contains("MACHINE_FEATURES", "bluetooth", "dey-examples-bt", "", d)} \ @@ -46,4 +39,4 @@ RDEPENDS_${PN}_append_ccimx6ul = "\ dey-examples-tamper \ " -COMPATIBLE_MACHINE = "(ccardimx28|ccimx6$|ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" From bb72455cd8a642cea27e30ad1a2bae3bd04513bf Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 3 Aug 2017 19:19:05 +0200 Subject: [PATCH 011/113] ccardimx28js removal: remove platform reference from bluez4 bootscript https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- meta-digi-dey/recipes-connectivity/bluez/bluez4/bluez-init | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez4/bluez-init b/meta-digi-dey/recipes-connectivity/bluez/bluez4/bluez-init index 88d87dc5f..e2c4b9815 100755 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez4/bluez-init +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez4/bluez-init @@ -25,9 +25,7 @@ SCRIPTNAME="$(basename "${0}")" MACHINENAME="$(cat /proc/device-tree/digi,machine,name 2>/dev/null)" bt_init() { - if [ "${MACHINENAME}" = "ccardimx28" ]; then - BT_PWR_GPIO_NR="21" - elif [ "${MACHINENAME}" = "ccimx6sbc" ]; then + if [ "${MACHINENAME}" = "ccimx6sbc" ]; then BT_PWR_GPIO_NR="244" fi From 06d353c410eca1edb6e03c809689d0ae5991b11f Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 3 Aug 2017 19:45:38 +0200 Subject: [PATCH 012/113] meta-digi-arm: clean not used variables and machine features After the 'ccardimx28js' platform removal, these variables and machine features are not used anymore, so remove them. https://jira.digi.com/browse/DEL-4771 Signed-off-by: Javier Viguera --- meta-digi-arm/conf/machine/ccimx6ulsbc.conf | 2 -- meta-digi-arm/conf/machine/include/digi-defaults.inc | 3 --- 2 files changed, 5 deletions(-) diff --git a/meta-digi-arm/conf/machine/ccimx6ulsbc.conf b/meta-digi-arm/conf/machine/ccimx6ulsbc.conf index 33664cb87..2f99f4cf3 100644 --- a/meta-digi-arm/conf/machine/ccimx6ulsbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6ulsbc.conf @@ -28,8 +28,6 @@ KERNEL_DEVICETREE ?= " \ SERIAL_CONSOLES ?= "115200;ttymxc4" -MACHINE_FEATURES += "second-eth" - # Bluetooth tty BT_TTY ?= "ttymxc0" diff --git a/meta-digi-arm/conf/machine/include/digi-defaults.inc b/meta-digi-arm/conf/machine/include/digi-defaults.inc index fe6f69e66..29567ceff 100644 --- a/meta-digi-arm/conf/machine/include/digi-defaults.inc +++ b/meta-digi-arm/conf/machine/include/digi-defaults.inc @@ -16,11 +16,8 @@ PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg" # Help variables used in recipes HAVE_WIFI = "${@bb.utils.contains('MACHINE_FEATURES', 'wifi', '1', '', d)}" -HAVE_SECOND_ETH = "${@bb.utils.contains('MACHINE_FEATURES', 'second-eth', '1', '', d)}" HAVE_BT = "${@bb.utils.contains('MACHINE_FEATURES', 'bluetooth', '1', '', d)}" -HAVE_1WIRE = "${@bb.utils.contains('MACHINE_FEATURES', '1-wire', '1', '', d)}" HAVE_GUI = "${@bb.utils.contains('DISTRO_FEATURES', 'x11', '1', '', d)}" -HAVE_EXAMPLE = "${@bb.utils.contains('IMAGE_FEATURES', 'dey-examples', '1', '', d)}" # # Ethernet configuration used in recipes From 9c5774ed62b84d113b43c9be3e9a2013b3cc240e Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 3 Aug 2017 12:00:33 +0200 Subject: [PATCH 013/113] bridgeifupdown: fix script to create a bridge with a wireless interface The supplicant support for a bridge was not being managed, then the bridge was failing when the softap was configured with an encryption. With this change we launch a supplicant instance with the bridge support after checking that the /etc/network/interfaces contains the required parameters. https://jira.digi.com/browse/DEL-4454 Signed-off-by: Arturo Buzarra --- .../busybox/busybox-1.24.1/bridgeifupdown | 56 +++++++++++++++++-- .../ccimx6/interfaces.br0.example | 9 +++ .../{ => ccimx6ul}/interfaces.br0.example | 0 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6/interfaces.br0.example rename meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/{ => ccimx6ul}/interfaces.br0.example (100%) diff --git a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/bridgeifupdown b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/bridgeifupdown index 9191224f8..cbf5e3acb 100644 --- a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/bridgeifupdown +++ b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/bridgeifupdown @@ -1,4 +1,43 @@ #!/bin/sh + +VERBOSITY=0 + +start_stop_wpa_supplicant() { + BRIDGE_WPA_IFACE="${1}" + WPA_SUP_BIN="/usr/sbin/wpa_supplicant" + WPA_SUP_PNAME="wpa_supplicant" + WPA_SUP_PIDFILE="/var/run/wpa_supplicant.${BRIDGE_WPA_IFACE}.pid" + WPA_SUP_OPTIONS="-B -P ${WPA_SUP_PIDFILE} -i ${BRIDGE_WPA_IFACE}" + + if [ -z "${IF_BRIDGE_WPA_DRIVER}" ]; then + echo "${WPA_SUP_PNAME}: missing bridge_wpa_driver property for bridge interface ${IFACE}" + exit 1 + fi + + case "${MODE}" in + start) + if [ "${VERBOSITY}" = "1" ]; then + echo "${WPA_SUP_PNAME}: ${WPA_SUP_BIN} ${WPA_SUP_OPTIONS} -c ${IF_BRIDGE_WPA_CONF} -D ${IF_BRIDGE_WPA_DRIVER}" + fi + + start-stop-daemon --start --quiet \ + --name ${WPA_SUP_PNAME} --startas ${WPA_SUP_BIN} --pidfile ${WPA_SUP_PIDFILE} \ + -- ${WPA_SUP_OPTIONS} -c ${IF_BRIDGE_WPA_CONF} -D ${IF_BRIDGE_WPA_DRIVER} -b ${IFACE} + + # Wait for wireless to be ready + sleep 0.5 + ;; + stop) + if [ "${VERBOSITY}" = "1" ]; then + echo "${WPA_SUP_PNAME}: terminating ${WPA_SUP_PNAME} daemon" + fi + + start-stop-daemon --stop --quiet \ + --name ${WPA_SUP_PNAME} --pidfile ${WPA_SUP_PIDFILE} + ;; + esac +} + # Execute only if the interface has a bridge_ports property (this characterizes bridge interfaces) case "$IF_BRIDGE_PORTS" in "") @@ -16,16 +55,19 @@ if [ "$MODE" = "start" ] && [ ! -d /sys/class/net/$IFACE ]; then # Create the bridge interface using brctl brctl addbr $IFACE || exit 1 - # Wait for wlan0 to be ready - sleep 0.5 - # For all the interfaces in bridge ports, attach to the bridge and remove ip for port in $INTERFACES; do + if [ -d "/sys/class/net/${port}/wireless" ] && [ -n "${IF_BRIDGE_WPA_CONF}" ]; then + # Launch wpa_supplicant with bridge support + start_stop_wpa_supplicant ${port} + fi + + # Turn up the interface and include in the bridge brctl addif $IFACE $port && ifconfig $port 0.0.0.0 up done # Setup the bridge (only options supported by busybox) - [ -n "$IF_BRIDEG_AGEING" ] && brctl setageing $IFACE $IF_BRIDGE_AGEING + [ -n "$IF_BRIDGE_AGEING" ] && brctl setageing $IFACE $IF_BRIDGE_AGEING [ -n "$IF_BRIDGE_BRIDGEPRIO" ] && brctl setbridgeprio $IFACE $IF_BRIDGE_BRIDGEPRIO [ -n "$IF_BRIDGE_FD" ] && brctl setfd $IFACE $IF_BRIDGE_FD [ -n "$IF_BRIDGE_HELLO" ] && brctl sethello $IFACE $IF_BRIDGE_HELLO @@ -43,10 +85,14 @@ elif [ "$MODE" = "stop" ]; then # Remove port interfaces from the bridge for port in $INTERFACES; do + if [ -d "/sys/class/net/${port}/wireless" ] && [ -n "${IF_BRIDGE_WPA_CONF}" ]; then + # Stop the wpa_supplicant instance for the bridge + start_stop_wpa_supplicant ${port} + fi + ifconfig $port down && brctl delif $IFACE $port done # Destroy the interface brctl delbr $IFACE fi - diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6/interfaces.br0.example b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6/interfaces.br0.example new file mode 100644 index 000000000..6244da561 --- /dev/null +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6/interfaces.br0.example @@ -0,0 +1,9 @@ + +## Example bridge between eth0 and wlan0 +#auto br0 +#iface br0 inet static +# bridge_ports eth0 wlan0 +# address 192.168.42.50 +# netmask 255.255.255.0 +# bridge_wpa_driver nl80211 +# bridge_wpa_conf /etc/wpa_supplicant.conf diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/interfaces.br0.example b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/interfaces.br0.example similarity index 100% rename from meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/interfaces.br0.example rename to meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/interfaces.br0.example From bbe77432559401700aa3ebc8f52e8f9e16027a1b Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Tue, 8 Aug 2017 13:06:50 +0200 Subject: [PATCH 014/113] mca_tool: update checksums for build 1.10 Signed-off-by: Hector Palacios --- .../recipes-digi/mca/{mca-tool_1.9.bb => mca-tool_1.10.bb} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename meta-digi-arm/recipes-digi/mca/{mca-tool_1.9.bb => mca-tool_1.10.bb} (70%) diff --git a/meta-digi-arm/recipes-digi/mca/mca-tool_1.9.bb b/meta-digi-arm/recipes-digi/mca/mca-tool_1.10.bb similarity index 70% rename from meta-digi-arm/recipes-digi/mca/mca-tool_1.9.bb rename to meta-digi-arm/recipes-digi/mca/mca-tool_1.10.bb index f0371a72b..206e0abe2 100644 --- a/meta-digi-arm/recipes-digi/mca/mca-tool_1.9.bb +++ b/meta-digi-arm/recipes-digi/mca/mca-tool_1.10.bb @@ -7,8 +7,8 @@ LICENSE = "CLOSED" PKGNAME = "mca_tool" SRC_URI = "${DIGI_PKG_SRC}/${PKGNAME}-${PV}.tar.gz" -SRC_URI[md5sum] = "3d954ceb361efa8325c9fae280c95775" -SRC_URI[sha256sum] = "874f02bc1ad7d1768879cff563888666c70691b12404a986af2e5743b3e3e628" +SRC_URI[md5sum] = "e739879489b2d0f0ab2fa61f60af80f6" +SRC_URI[sha256sum] = "af2eb7abebfbabe228c574b887d166d2ef5ad5b3a9308ccd07778d0ccbed1e8b" S = "${WORKDIR}/${PKGNAME}-${PV}" From e623c365ff553df5b2b172d85b548f28f1c2f9a1 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 9 Aug 2017 18:31:12 +0200 Subject: [PATCH 015/113] qt: add support for Qt Quick 2D Renderer in the CC6UL This is an alternative software based renderer for QtQuick2 applications for hardware that doesn't have a GPU. This is the case of the CC6UL. It does not have a GPU, so the only way to run QML applications is using this software renderer. https://jira.digi.com/browse/DEL-3912 Signed-off-by: Javier Viguera --- .../recipes-graphics/packagegroups/packagegroup-dey-qt.bb | 1 + meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/qt5.sh | 3 +++ 2 files changed, 4 insertions(+) diff --git a/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb b/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb index 2e975d56c..fc792f1ad 100644 --- a/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb +++ b/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb @@ -11,6 +11,7 @@ MACHINE_QT5_EXTRA_INSTALL_ccimx6 ?= "qtwebengine-examples" QT5_PKS = "qtserialport" QT5_PKS_append_ccimx6 = " qtdeclarative-tools" +QT5_PKS_append_ccimx6ul = " qtdeclarative-render2d-plugins" QT5_EXAMPLES = "qtbase-examples" QT5_EXAMPLES_append_ccimx6 = " \ diff --git a/meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/qt5.sh b/meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/qt5.sh index e64709644..68dcf6f85 100644 --- a/meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/qt5.sh +++ b/meta-digi-dey/recipes-qt/qt5/qtbase/ccimx6ul/qt5.sh @@ -1,2 +1,5 @@ # Use LINUXFB platform plugin for images without X11 [ -f "/etc/init.d/xserver-nodm" ] || export QT_QPA_PLATFORM="linuxfb" + +# Use Qt Quick 2D Renderer +export QMLSCENE_DEVICE="softwarecontext" From 48ff14dc78c67df11e454645b32abc39625d531f Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 9 Aug 2017 18:31:44 +0200 Subject: [PATCH 016/113] qtsmarthome: fix missing runtime dependence The demo application uses 'svg' images, so at runtime it depends on 'qtsvg-plugins' package. Also add a patch to fix a runtime warning: Both point size and pixel size set. Using pixel size https://jira.digi.com/browse/DEL-3912 Signed-off-by: Javier Viguera --- ...0001-qtsmarthome-fix-runtime-warning.patch | 24 +++++++++++++++++++ .../examples/qtsmarthome_1.0.bbappend | 7 ++++++ 2 files changed, 31 insertions(+) create mode 100644 meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/0001-qtsmarthome-fix-runtime-warning.patch create mode 100644 meta-digi-dey/recipes-qt/examples/qtsmarthome_1.0.bbappend diff --git a/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/0001-qtsmarthome-fix-runtime-warning.patch b/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/0001-qtsmarthome-fix-runtime-warning.patch new file mode 100644 index 000000000..4ed074e69 --- /dev/null +++ b/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/0001-qtsmarthome-fix-runtime-warning.patch @@ -0,0 +1,24 @@ +From: Javier Viguera +Date: Tue, 8 Aug 2017 18:17:46 +0200 +Subject: [PATCH] qtsmarthome: fix runtime warning + +Both point size and pixel size set. Using pixel size. + +Signed-off-by: Javier Viguera +--- + components/qml/components/timepicker/PickerPathView.qml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/components/qml/components/timepicker/PickerPathView.qml b/components/qml/components/timepicker/PickerPathView.qml +index 7038331e3aae..1987d72e32b9 100644 +--- a/components/qml/components/timepicker/PickerPathView.qml ++++ b/components/qml/components/timepicker/PickerPathView.qml +@@ -74,7 +74,7 @@ PathView { + verticalAlignment: Text.AlignVCenter + text: modelData + Component.onCompleted: { +- font.pointSize = font.pointSize * 0.8 ++ font.pixelSize = font.pixelSize * 0.8 + } + } + diff --git a/meta-digi-dey/recipes-qt/examples/qtsmarthome_1.0.bbappend b/meta-digi-dey/recipes-qt/examples/qtsmarthome_1.0.bbappend new file mode 100644 index 000000000..b6f12c13a --- /dev/null +++ b/meta-digi-dey/recipes-qt/examples/qtsmarthome_1.0.bbappend @@ -0,0 +1,7 @@ +# Copyright (C) 2017, Digi International Inc. + +FILESEXTRAPATHS_prepend := "${THISDIR}/${BP}:" + +SRC_URI += "file://0001-qtsmarthome-fix-runtime-warning.patch" + +RDEPENDS_${PN} += "qtsvg-plugins" From 64010754d07bd7c392436987963a83013496d3f6 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 9 Aug 2017 18:32:17 +0200 Subject: [PATCH 017/113] qtsmarthome: move desktop launcher from qt5-demo-extrafiles recipe Instead of having a recipe to add launchers for a bunch of applications (most of them are not available anymore) move the qtsmarthome launcher to the recipe that installs the package. https://jira.digi.com/browse/DEL-3912 Signed-off-by: Javier Viguera --- .../qt5-demo-extrafiles.bbappend | 3 +++ .../qtsmarthome-1.0/qtsmarthome.desktop | 9 +++++++++ .../examples/qtsmarthome-1.0/qtsmarthome.png | Bin 0 -> 19986 bytes .../examples/qtsmarthome_1.0.bbappend | 12 +++++++++++- 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/qtsmarthome.desktop create mode 100644 meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/qtsmarthome.png diff --git a/meta-digi-dey/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend b/meta-digi-dey/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend index 508a98fdc..481ffc15d 100644 --- a/meta-digi-dey/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend +++ b/meta-digi-dey/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend @@ -15,6 +15,9 @@ do_install_append () { install -m 0644 ${WORKDIR}/qmlvideo.desktop ${D}${datadir}/applications/ install -m 0644 ${WORKDIR}/qmlvideo.png ${D}${datadir}/pixmaps/ + # Remove the desktop launchers that have been moved along with its package + rm -f ${D}${datadir}/applications/qtsmarthome.desktop ${D}${datadir}/pixmaps/qtsmarthome.png + # Remove the desktop launchers of the demo/example applications we do not provide. rm -f ${D}${datadir}/applications/hellogl_es2.desktop ${D}${datadir}/pixmaps/hellogl_es2.png rm -f ${D}${datadir}/applications/qt5basket.desktop ${D}${datadir}/pixmaps/qt5basket.png diff --git a/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/qtsmarthome.desktop b/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/qtsmarthome.desktop new file mode 100644 index 000000000..fef8057a8 --- /dev/null +++ b/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/qtsmarthome.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Qt5 Smart Home +Exec=/bin/sh -c "cd /usr/share/qtsmarthome-1.0/; ./smarthome" +Icon=qtsmarthome +Terminal=false +Type=Application +X-MB-SingleInstance=true +Comment=Qt5 Smart Home +StartupNotify=false diff --git a/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/qtsmarthome.png b/meta-digi-dey/recipes-qt/examples/qtsmarthome-1.0/qtsmarthome.png new file mode 100644 index 0000000000000000000000000000000000000000..d364da8ca348d1200e1880c848ce247eeb575213 GIT binary patch literal 19986 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 Date: Wed, 9 Aug 2017 18:32:49 +0200 Subject: [PATCH 018/113] packagegroup-dey-qt: rework default installed packages This only affects the CC6UL, where by default now 'qtsmarthome' is installed instead of 'qtbase-examples'. This serves two purposes: * Remove the 'qtbase-examples' package from the CC6UL to save space. * Use 'qtsmarthome' as a demo of a QML application running on the CC6UL using Qt Quick 2D Renderer. https://jira.digi.com/browse/DEL-3912 Signed-off-by: Javier Viguera --- .../recipes-graphics/packagegroups/packagegroup-dey-qt.bb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb b/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb index fc792f1ad..209438c87 100644 --- a/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb +++ b/meta-digi-dey/recipes-graphics/packagegroups/packagegroup-dey-qt.bb @@ -13,21 +13,21 @@ QT5_PKS = "qtserialport" QT5_PKS_append_ccimx6 = " qtdeclarative-tools" QT5_PKS_append_ccimx6ul = " qtdeclarative-render2d-plugins" -QT5_EXAMPLES = "qtbase-examples" +QT5_EXAMPLES = "" QT5_EXAMPLES_append_ccimx6 = " \ qt3d-examples \ + qtbase-examples \ qtconnectivity-examples \ qtdeclarative-examples \ qtmultimedia-examples \ qtsvg-examples \ " -QT5_DEMOS = "" +QT5_DEMOS = "qtsmarthome" QT5_DEMOS_append_ccimx6 = " \ cinematicexperience \ qt5-demo-extrafiles \ qt5everywheredemo \ - qtsmarthome \ " RDEPENDS_${PN} += " \ From d7889c28dbe39bbc873503af566ffd8c7cf4f7a2 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Mon, 28 Aug 2017 13:56:38 +0200 Subject: [PATCH 019/113] DIGI_EULA: Update Digi EULA file. Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-4859 (cherry picked from commit 86000bb0bb013c52547dd4ff2290c4eb5fde2dcc) --- meta-digi-arm/DIGI_EULA | 25 ++++++++----------- .../firmware-atheros/firmware-atheros.bb | 2 +- .../firmware-qualcomm/firmware-qualcomm.bb | 2 +- meta-digi-dey/DIGI_EULA | 25 ++++++++----------- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/meta-digi-arm/DIGI_EULA b/meta-digi-arm/DIGI_EULA index 6b71da0ad..746d55223 100644 --- a/meta-digi-arm/DIGI_EULA +++ b/meta-digi-arm/DIGI_EULA @@ -1,13 +1,12 @@ END-USER LICENSE AGREEMENT - DIGI DEVELOPMENT KIT - (PN 90002118) This end-user license agreement is a legal agreement between you (either an individual or a single entity) and Digi International, Inc. ("Digi") for use of Digi Technology. This license applies to the -product with which it was shipped, which may be a Development Kit or a -unit of Digi Hardware. By using Digi product, you are consenting to be -bound by and are becoming a party to this end-user license agreement. +product with which it was provided, which may be a Development Kit, +Digi Software, or a unit of Digi Hardware. By using the product, +you are consenting to be bound by and are becoming a party to this +end-user license agreement. DEFINITIONS @@ -42,6 +41,13 @@ may only be used in conjunction with Digi Hardware. Copies of Digi Software may not be redistributed on a standalone basis or as part of any product not incorporating Digi Hardware. +DEVELOPMENT KITS + +Development Kits may include Digi Hardware. ALL DIGI HARDWARE PROVIDED IN +DEVELOPMENT KITS IS INTENDED FOR PRODUCT EVALUATION, DEVELOPMENT, AND +PROTOTYPING PURPOSES ONLY, AND MAY NOT BE USED IN OR IS WARRANTED FOR +PRODUCTION ENVIRONMENTS. + THIRD-PARTY COMPONENTS A Development Kit may contain third-party components. THE LICENSE TO USE @@ -79,12 +85,3 @@ and regulations concerning export and re-export of products, technology and documentation, including without limitation, the laws and regulations administered by the United States Department of Commerce and the United States Department of State. - -------------------------------------------------------------------------- - U-BOOT LICENSE NOTICE - -THE U-BOOT SOFTWARE THAT IS PROVIDED WITH DIGI SOFTWARE AND DIGI HARDWARE -IS COVERED BY THE GNU GENERAL PUBLIC LICENSE (VERSION 2 OR LATER) AS -PUBLISHED BY THE FREE SOFTWARE FOUNDATION. - -Please visit http://www.denx.de for current U-Boot license information. diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb index 4855009a6..8c03f9df7 100644 --- a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb +++ b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb @@ -3,7 +3,7 @@ SUMMARY = "Firmware files for Digi's platforms, such as Atheros bluetooth." SECTION = "base" LICENSE = "Proprietary" -LIC_FILES_CHKSUM = "file://${DIGI_EULA_FILE};md5=4c0991cfde5c8a92338cbfe0f4f9a5c6" +LIC_FILES_CHKSUM = "file://${DIGI_EULA_FILE};md5=8c0ad592dd48ace3d25eed5bbb26ba78" FW_ATH6KL = " \ file://athtcmd_ram.bin \ diff --git a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb index 5522fd5fe..b12bc2b14 100644 --- a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb +++ b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb @@ -3,7 +3,7 @@ SUMMARY = "Qualcomm firmware files for Digi's platforms." SECTION = "base" LICENSE = "Proprietary" -LIC_FILES_CHKSUM = "file://${DIGI_EULA_FILE};md5=4c0991cfde5c8a92338cbfe0f4f9a5c6" +LIC_FILES_CHKSUM = "file://${DIGI_EULA_FILE};md5=8c0ad592dd48ace3d25eed5bbb26ba78" FW_QCA6564-BT = " \ file://qca/nvm_tlv_3.0.bin \ diff --git a/meta-digi-dey/DIGI_EULA b/meta-digi-dey/DIGI_EULA index 6b71da0ad..746d55223 100644 --- a/meta-digi-dey/DIGI_EULA +++ b/meta-digi-dey/DIGI_EULA @@ -1,13 +1,12 @@ END-USER LICENSE AGREEMENT - DIGI DEVELOPMENT KIT - (PN 90002118) This end-user license agreement is a legal agreement between you (either an individual or a single entity) and Digi International, Inc. ("Digi") for use of Digi Technology. This license applies to the -product with which it was shipped, which may be a Development Kit or a -unit of Digi Hardware. By using Digi product, you are consenting to be -bound by and are becoming a party to this end-user license agreement. +product with which it was provided, which may be a Development Kit, +Digi Software, or a unit of Digi Hardware. By using the product, +you are consenting to be bound by and are becoming a party to this +end-user license agreement. DEFINITIONS @@ -42,6 +41,13 @@ may only be used in conjunction with Digi Hardware. Copies of Digi Software may not be redistributed on a standalone basis or as part of any product not incorporating Digi Hardware. +DEVELOPMENT KITS + +Development Kits may include Digi Hardware. ALL DIGI HARDWARE PROVIDED IN +DEVELOPMENT KITS IS INTENDED FOR PRODUCT EVALUATION, DEVELOPMENT, AND +PROTOTYPING PURPOSES ONLY, AND MAY NOT BE USED IN OR IS WARRANTED FOR +PRODUCTION ENVIRONMENTS. + THIRD-PARTY COMPONENTS A Development Kit may contain third-party components. THE LICENSE TO USE @@ -79,12 +85,3 @@ and regulations concerning export and re-export of products, technology and documentation, including without limitation, the laws and regulations administered by the United States Department of Commerce and the United States Department of State. - -------------------------------------------------------------------------- - U-BOOT LICENSE NOTICE - -THE U-BOOT SOFTWARE THAT IS PROVIDED WITH DIGI SOFTWARE AND DIGI HARDWARE -IS COVERED BY THE GNU GENERAL PUBLIC LICENSE (VERSION 2 OR LATER) AS -PUBLISHED BY THE FREE SOFTWARE FOUNDATION. - -Please visit http://www.denx.de for current U-Boot license information. From 608b001036081ea01301ed517dea60cf674c48a4 Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Mon, 28 Aug 2017 17:26:17 +0200 Subject: [PATCH 020/113] imx6ul: ubifs: increase max leb count for linux The current value only allows partitions of up to 8 MiB, which is not enough for the 0x04 variant (which uses a linux partition of 24 MiB by default). This new value allows for up to 32 MiB (assuming 128 KiB erase block size). Also add comments explaining the -c value and maximum partition sizes supported. https://jira.digi.com/browse/DEL-4971 Signed-off-by: Jose Diaz de Grenu --- meta-digi-arm/conf/machine/include/ccimx6ul.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meta-digi-arm/conf/machine/include/ccimx6ul.inc b/meta-digi-arm/conf/machine/include/ccimx6ul.inc index 6c1d679fd..302bf54d9 100644 --- a/meta-digi-arm/conf/machine/include/ccimx6ul.inc +++ b/meta-digi-arm/conf/machine/include/ccimx6ul.inc @@ -39,7 +39,9 @@ MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1', 'firmware-qual KERNEL_IMAGETYPE = "zImage" # mkfs.ubifs parameters for boot partition (the one holding kernel and device tree files) -MKUBIFS_BOOT_ARGS ?= "-m 2048 -e 126976 -c 127" +# Max LEB count (-c 255) calculated for a partition of up to 32 MiB considering 128 KiB erase-block size. +MKUBIFS_BOOT_ARGS ?= "-m 2048 -e 126976 -c 255" # mkfs.ubifs parameters for rootfs partition +# Max LEB count (-c 8191) calculated for a partition of up to 1 GiB considering 128 KiB erase-block size. MKUBIFS_ARGS ?= "-m 2048 -e 126976 -c 8191" From d7c8fa4b9a8485150443bc9af21256579d8ac722 Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Tue, 29 Aug 2017 10:45:24 +0200 Subject: [PATCH 021/113] init-ifupdown: fix interfaces order The bridge example uses the wireless interface and it assumes that it is initialized, so it must be placed after it. https://jira.digi.com/browse/DEL-4823 Signed-off-by: Jose Diaz de Grenu --- .../recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend index 60cd13e5d..388399008 100644 --- a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend @@ -30,7 +30,6 @@ do_install_append() { sed -i -e 's,##WLAN_P2P_INTERFACE##,${WLAN_P2P_INTERFACE},g' ${D}${sysconfdir}/network/interfaces fi fi - cat ${WORKDIR}/interfaces.br0.example >> ${D}${sysconfdir}/network/interfaces # Remove config entries if corresponding variable is not defined [ -z "${P2P0_STATIC_DNS}" ] && sed -i -e "/##P2P0_STATIC_DNS##/d" ${D}${sysconfdir}/network/interfaces @@ -46,6 +45,10 @@ do_install_append() { sed -i -e "s,##WPA_DRIVER##,${WPA_DRIVER},g" ${D}${sysconfdir}/network/interfaces } +do_install_append_ccimx6sbc() { + cat ${WORKDIR}/interfaces.br0.example >> ${D}${sysconfdir}/network/interfaces +} + do_install_append_ccimx6ul() { install -d ${D}${base_bindir} install -m 0755 ${WORKDIR}/virtwlans.sh ${D}${base_bindir} @@ -64,6 +67,8 @@ do_install_append_ccimx6ul() { sed -i -e "s,##WLAN1_STATIC_NETMASK##,${WLAN1_STATIC_NETMASK},g" ${D}${sysconfdir}/network/interfaces sed -i -e "s,##WLAN1_STATIC_GATEWAY##,${WLAN1_STATIC_GATEWAY},g" ${D}${sysconfdir}/network/interfaces sed -i -e "s,##WLAN1_STATIC_DNS##,${WLAN1_STATIC_DNS},g" ${D}${sysconfdir}/network/interfaces + + cat ${WORKDIR}/interfaces.br0.example >> ${D}${sysconfdir}/network/interfaces } # Disable wireless interfaces on first boot for non-wireless variants From e6beba4cb0ecd51ef405910e51586598b651e6ca Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Tue, 29 Aug 2017 10:48:32 +0200 Subject: [PATCH 022/113] init-ifupdown: use wlan1 for the bridging example wlan1 is the interface used for SoftAP, so use that one instead. This also matches with the 'Network bridging' chapter of the documentation. https://jira.digi.com/browse/DEL-4823 Signed-off-by: Jose Diaz de Grenu --- .../init-ifupdown-1.0/ccimx6ul/interfaces.br0.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/interfaces.br0.example b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/interfaces.br0.example index 8340c5611..60e05fe52 100644 --- a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/interfaces.br0.example +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/interfaces.br0.example @@ -1,7 +1,7 @@ -## Example bridge between eth0 and wlan0 +## Example bridge between eth0 and wlan1 #auto br0 #iface br0 inet static -# bridge_ports eth0 wlan0 +# bridge_ports eth0 wlan1 # address 192.168.42.50 # netmask 255.255.255.0 From 270f8904948e9cfa6db63148c806876fffecea20 Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Mon, 28 Aug 2017 17:21:08 +0200 Subject: [PATCH 023/113] recovery-initramfs-init: remove parted dependency Turns out that the busybox' fdisk applet is also able to parse the GPT partition tables. This saves around 0.5 MiB of space. https://jira.digi.com/browse/DEL-4565 Signed-off-by: Jose Diaz de Grenu --- .../recipes-core/images/dey-image-recovery-initramfs.bb | 1 - .../recovery/recovery-initramfs/automount_block.sh | 4 ++-- .../recovery/recovery-initramfs/recovery-initramfs-init | 4 ++-- .../recipes-digi/swu-images/files/ccimx6/preinstall_swu.sh | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/meta-digi-dey/recipes-core/images/dey-image-recovery-initramfs.bb b/meta-digi-dey/recipes-core/images/dey-image-recovery-initramfs.bb index bd484673d..1d5ad31a2 100644 --- a/meta-digi-dey/recipes-core/images/dey-image-recovery-initramfs.bb +++ b/meta-digi-dey/recipes-core/images/dey-image-recovery-initramfs.bb @@ -5,7 +5,6 @@ LICENSE = "MIT" PACKAGE_INSTALL = " \ busybox \ - parted \ psplash \ recovery-initramfs \ swupdate \ diff --git a/meta-digi-dey/recipes-core/recovery/recovery-initramfs/automount_block.sh b/meta-digi-dey/recipes-core/recovery/recovery-initramfs/automount_block.sh index 1d3466b4b..e437f0b6d 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-initramfs/automount_block.sh +++ b/meta-digi-dey/recipes-core/recovery/recovery-initramfs/automount_block.sh @@ -23,12 +23,12 @@ PARTITION="$(echo "${MDEV}" | sed -n -e '/^mmc/{s,^[^p]\+p\([0-9]\+\)$,\1,g;T;p} # This will detect if the block device has a update partition is_update_device() { - parted -s "/dev/${DEVICE}" print | grep -qs update + fdisk -l "/dev/${DEVICE}" | grep -qs update } # This will verify that the requested partition is the update partition is_update_partition() { - parted -s "/dev/${DEVICE}" print | sed -ne "s,^[^0-9]*\([0-9]\+\).*\.*,\1,g;T;p" | grep -qs "${PARTITION}" + fdisk -l "/dev/${DEVICE}" | sed -ne "s,^[^0-9]*\([0-9]\+\).*\.*,\1,g;T;p" | grep -qs "${PARTITION}" } if is_update_device; then diff --git a/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init b/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init index 5f70a0e3d..7e7e2dd8b 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init +++ b/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init @@ -230,7 +230,7 @@ format_ubi_volume() { #------------------------------------------------------------------------------ format_emmc_block() { # Find partition block number. - local partition_block="/dev/mmcblk0p$(parted -s /dev/mmcblk0 print | sed -ne "s,^[^0-9]*\([0-9]\+\).*\<${1}\>.*,\1,g;T;p")" + local partition_block="/dev/mmcblk0p$(fdisk -l /dev/mmcblk0 | sed -ne "s,^[^0-9]*\([0-9]\+\).*\<${1}\>.*,\1,g;T;p")" if [ -b "${partition_block}" ]; then # Umount in case partition is mounted, ignore errors. if grep -qs "${partition_block}" /proc/mounts; then @@ -458,7 +458,7 @@ if [ -n "${encryption_key_bool}" ]; then # Format partition. if [ "$(is_nand)" = "no" ]; then psplash_message "Formatting rootfs partition..." - rootfs_block="/dev/mmcblk0p$(parted -s /dev/mmcblk0 print | sed -ne "s,^[^0-9]*\([0-9]\+\).*\.*,\1,g;T;p")" + rootfs_block="/dev/mmcblk0p$(fdisk -l /dev/mmcblk0 | sed -ne "s,^[^0-9]*\([0-9]\+\).*\.*,\1,g;T;p")" trustfence-tool --format ${rootfs_block} cryptroot fi psplash_progress "100" diff --git a/meta-digi-dey/recipes-digi/swu-images/files/ccimx6/preinstall_swu.sh b/meta-digi-dey/recipes-digi/swu-images/files/ccimx6/preinstall_swu.sh index 07bca0909..8723cfc11 100644 --- a/meta-digi-dey/recipes-digi/swu-images/files/ccimx6/preinstall_swu.sh +++ b/meta-digi-dey/recipes-digi/swu-images/files/ccimx6/preinstall_swu.sh @@ -72,7 +72,7 @@ if [ -b /dev/mapper/cryptroot ]; then exit 0 fi -rootfs_block="/dev/mmcblk0p$(parted -s /dev/mmcblk0 print | sed -ne "s,^[^0-9]*\([0-9]\+\).*\.*,\1,g;T;p")" +rootfs_block="/dev/mmcblk0p$(fdisk -l /dev/mmcblk0 | sed -ne "s,^[^0-9]*\([0-9]\+\).*\.*,\1,g;T;p")" # Open LUKS encrypted device trustfence-tool ${rootfs_block} cryptroot From 2f732624fe376575b814f48a99ba142195f1e78c Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Wed, 30 Aug 2017 12:33:46 +0200 Subject: [PATCH 024/113] wpa-supplicant: add p2p configuration file for cc6 https://jira.digi.com/browse/DEL-4559 Signed-off-by: Jose Diaz de Grenu --- .../wpa-supplicant/ccimx6/wpa_supplicant_p2p.conf | 6 ++++++ .../wpa-supplicant/wpa-supplicant_%.bbappend | 8 +++++--- 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6/wpa_supplicant_p2p.conf diff --git a/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6/wpa_supplicant_p2p.conf b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6/wpa_supplicant_p2p.conf new file mode 100644 index 000000000..c1146257f --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6/wpa_supplicant_p2p.conf @@ -0,0 +1,6 @@ +ctrl_interface=/var/run/wpa_supplicant +ctrl_interface_group=0 +device_name=ccimx6-p2p +device_type=10-0050F204-5 +config_methods=virtual_push_button keypad display pin +persistent_reconnect=1 diff --git a/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend index bee53d088..7a80ba361 100644 --- a/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend @@ -4,10 +4,12 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" PACKAGECONFIG ?= "openssl" -SRC_URI += "file://0001-wpa_supplicant-enable-control-socket-interface-when-.patch" -SRC_URI_append_ccimx6ul = " file://wpa_supplicant_p2p.conf" +SRC_URI += " \ + file://0001-wpa_supplicant-enable-control-socket-interface-when-.patch \ + file://wpa_supplicant_p2p.conf \ +" -do_install_append_ccimx6ul() { +do_install_append() { install -m 600 ${WORKDIR}/wpa_supplicant_p2p.conf ${D}${sysconfdir}/wpa_supplicant_p2p.conf } From e7adc7fe414b07d85394ec3c1ec7b76f44975587 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Mon, 4 Sep 2017 11:04:41 +0200 Subject: [PATCH 025/113] modemmanager: remove unnecessary dbus-glib dependence ModemManager moved to Glib2 GDBus since some stable releases. Signed-off-by: Javier Viguera --- .../recipes-connectivity/modemmanager/modemmanager_git.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_git.bb b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_git.bb index 623a8db0a..d83e76b6d 100644 --- a/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_git.bb +++ b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_git.bb @@ -8,7 +8,7 @@ LIC_FILES_CHKSUM = " \ file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c \ " -DEPENDS = "dbus-glib glib-2.0 intltool-native libgudev" +DEPENDS = "glib-2.0 intltool-native libgudev" PV = "1.7.0+git${SRCPV}" From 3f8c5bea0650dd78f41f9f3553b5945ad3758c35 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Mon, 4 Sep 2017 12:24:09 +0200 Subject: [PATCH 026/113] libsoc: add generic recipe to build from GIT Also configure DEY to build the GIT version of libsoc. https://jira.digi.com/browse/DEL-4816 Signed-off-by: Javier Viguera --- meta-digi-dey/conf/distro/dey.conf | 3 ++ .../recipes-support/libsoc/libsoc_git.bb | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc_git.bb diff --git a/meta-digi-dey/conf/distro/dey.conf b/meta-digi-dey/conf/distro/dey.conf index 39b6132d7..3bedfb74b 100644 --- a/meta-digi-dey/conf/distro/dey.conf +++ b/meta-digi-dey/conf/distro/dey.conf @@ -57,6 +57,9 @@ PREFERRED_VERSION_linux-yocto_qemumips ?= "4.8%" PREFERRED_VERSION_linux-yocto_qemumips64 ?= "4.8%" PREFERRED_VERSION_linux-yocto_qemuppc ?= "4.8%" +# Use git recipe for libsoc +PREFERRED_VERSION_libsoc = "git" + SDK_NAME = "${DISTRO}-${TCLIBC}-${SDK_ARCH}-${IMAGE_BASENAME}-${TUNE_PKGARCH}" SDKPATH = "/opt/${DISTRO}/${SDK_VERSION}" diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc_git.bb b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bb new file mode 100644 index 000000000..e3c4da70d --- /dev/null +++ b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bb @@ -0,0 +1,38 @@ +# Copyright (C) 2017 Digi International Inc. + +SUMMARY = "Library for interfacing with common SoC peripherals" +DESCRIPTION = "libsoc is a C library to interface with common peripherals (gpio, i2c, spi, pwm) \ + found in SoC (System on Chips) through generic Linux Kernel interfaces." + +HOMEPAGE = "https://github.com/jackmitch/libsoc" + +LICENSE = "LGPLv2.1" +LIC_FILES_CHKSUM = "file://LICENCE;md5=e0bfebea12a718922225ba987b2126a5" + +inherit autotools pkgconfig python-dir + +SRCBRANCH ?= "master" +SRCREV = "${AUTOREV}" +SRC_URI = "git://github.com/jackmitch/libsoc.git" + +S = "${WORKDIR}/git" + +BOARD ??= "devboard" + +PACKAGECONFIG ?= "" + +PACKAGECONFIG[disabledebug] = "--disable-debug,," +PACKAGECONFIG[allboardconfigs] = "--with-board-configs,," +PACKAGECONFIG[enableboardconfig] = "--enable-board=${BOARD},," +PACKAGECONFIG[python] = "--enable-python=${PYTHON_PN},,${PYTHON_PN}" + +PACKAGES =+ "${@bb.utils.contains('PACKAGECONFIG', 'python', \ + '${PYTHON_PN}-libsoc-staticdev ${PYTHON_PN}-libsoc', '', d)}" + +RDEPENDS_${PN} = "libgcc" +RDEPENDS_${PYTHON_PN}-libsoc = "${PN} ${PYTHON_PN}-ctypes" + +FILES_${PYTHON_PN}-libsoc-staticdev += "${PYTHON_SITEPACKAGES_DIR}/*/*.a" +FILES_${PYTHON_PN}-libsoc += "${PYTHON_SITEPACKAGES_DIR}" + +DEFAULT_PREFERENCE = "-1" From 1daf4d91d4f3c87f1e89fb57950506990b84c127 Mon Sep 17 00:00:00 2001 From: David Escalona Date: Mon, 4 Sep 2017 12:26:36 +0200 Subject: [PATCH 027/113] libsoc: extend libsoc recipe with configuration params and custom board files https://jira.digi.com/browse/DEL-4816 Signed-off-by: David Escalona Signed-off-by: Javier Viguera --- .../libsoc/libsoc-git/ccimx6sbc/board.conf | 47 +++++++++++++++++++ .../libsoc/libsoc-git/ccimx6ulsbc/board.conf | 40 ++++++++++++++++ .../libsoc-git/ccimx6ulstarter/board.conf | 40 ++++++++++++++++ .../libsoc/libsoc_git.bbappend | 20 ++++++++ 4 files changed, 147 insertions(+) create mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf create mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf create mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf create mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf new file mode 100644 index 000000000..03c72acbd --- /dev/null +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf @@ -0,0 +1,47 @@ +[board] +model = Digi International ConnectCore 6 Single Board Computer. + +[GPIO] + +# USER LED (RED) - GPIO02_IO02 +USER_LED = 34 + +# USER LED (ORANGE) - GPIO02_IO03 +USER_LED_2 = 35 + +# USER LED (GREEN) - GPIO02_IO04 +USER_LED_3 = 36 + +# USER BUTTON - GPIO02_IO05 +USER_BUTTON = 37 + +[I2C] + +# I2C-3 on I2C board connector. +DEFAULT_I2C_BUS = 2 + +[SPI] + +# SPI-1 on SPI board connector. +DEFAULT_SPI_BUS = 0 + +DEFAULT_SPI_SS = 0 + +[PWM] + +# PWM1 on LCD board connector (pin 10). +DEFAULT_PWM_CHIP = 0 + +DEFAULT_PWM_SIGNAL = 0 + +[ADC] + +# HWMON Driver +DEFAULT_ADC_DRIVER = 1 + +# IIO Device 0 +DEFAULT_DEVICE_INDEX = 0 + +# PMIC_ADCIN1 on GPIO board connector (Pin 1) +DEFAULT_ADC_LINE = 1 + diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf new file mode 100644 index 000000000..8e873fa80 --- /dev/null +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf @@ -0,0 +1,40 @@ +[board] +model = Digi International ConnectCore 6UL SBC. + +[GPIO] + +# USER LED - I/O Expander IO23 +USER_LED = 488 + +# USER BUTTON - MCA_IO1 +USER_BUTTON = 505 + +[I2C] + +# I2C-1 on I2C board connector. +DEFAULT_I2C_BUS = 0 + +[SPI] + +# SPI-1 on SPI board connector. +DEFAULT_SPI_BUS = 0 + +DEFAULT_SPI_SS = 0 + +[PWM] + +# PWM4 on GPIO board connector (pin 11). +DEFAULT_PWM_CHIP = 0 + +DEFAULT_PWM_SIGNAL = 0 + +[ADC] + +# IIO Driver +DEFAULT_ADC_DRIVER = 0 + +# IIO Device 0 +DEFAULT_DEVICE_INDEX = 0 + +# ADC1_IN2 on GPIO board connector (pin 13) +DEFAULT_ADC_LINE = 2 diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf new file mode 100644 index 000000000..527c60589 --- /dev/null +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf @@ -0,0 +1,40 @@ +[board] +model = Digi International ConnectCore 6UL Starter Board. + +[GPIO] + +# USER LED - GPIO03_IO11 +USER_LED = 75 + +# USER BUTTON - GPIO03_IO03 +USER_BUTTON = 67 + +[I2C] + +# I2C-2 on Expansion connector. +DEFAULT_I2C_BUS = 1 + +[SPI] + +# SPI-3 on Expansion connector. +DEFAULT_SPI_BUS = 2 + +DEFAULT_SPI_SS = 0 + +[PWM] + +# PWM1 on Expansion connector (pin 27). +DEFAULT_PWM_CHIP = 0 + +DEFAULT_PWM_SIGNAL = 0 + +[ADC] + +# IIO Driver +DEFAULT_ADC_DRIVER = 0 + +# IIO Device 1 +DEFAULT_DEVICE_INDEX = 1 + +# ADC1_IN4 on Expansion connector (pin 7). +DEFAULT_ADC_LINE = 4 diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend new file mode 100644 index 000000000..959c174d3 --- /dev/null +++ b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend @@ -0,0 +1,20 @@ +# Copyright (C) 2017 Digi International Inc. + +FILESEXTRAPATHS_prepend := "${THISDIR}/${BP}:" + +LIBSOC_URI_STASH = "${DIGI_MTK_GIT}dey/libsoc.git;protocol=ssh" +LIBSOC_URI_GITHUB = "git://github.com/jackmitch/libsoc.git;protocol=git" +LIBSOC_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${LIBSOC_URI_STASH}', '${LIBSOC_URI_GITHUB}', d)}" + +SRC_URI = " \ + ${LIBSOC_URI};branch=${SRCBRANCH} \ + file://board.conf \ +" + +PACKAGECONFIG = "enableboardconfig python" + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/board.conf ${S}/contrib/board_files/${BOARD}.conf +} + +PACKAGE_ARCH = "${MACHINE_ARCH}" From 7ef80dd7ad979dde838f436d226dcf5fb97a5164 Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Fri, 1 Sep 2017 11:36:13 +0200 Subject: [PATCH 028/113] hostapd: generate unique SSID for SoftAP If two or more targets are in the same environment, all of them will broadcast the same SSID, which may be a problem when a client wants to connect to a specific device. Use the last bytes of the non-virtual wireless MAC for the name of the SSID, a random value with no hexadecimal characters is used if the MAC is not available. Also drop 'wpa2aes' from the SSID. https://jira.digi.com/browse/DEL-4129 Signed-off-by: Jose Diaz de Grenu --- .../hostapd/ccimx6ul/hostapd_wlan1.conf | 2 +- .../hostapd/hostapd/hostapd_wlan0.conf | 2 +- .../hostapd/hostapd_%.bbappend | 25 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/meta-digi-dey/recipes-connectivity/hostapd/hostapd/ccimx6ul/hostapd_wlan1.conf b/meta-digi-dey/recipes-connectivity/hostapd/hostapd/ccimx6ul/hostapd_wlan1.conf index 3d2e87d0d..a5ee3b926 100644 --- a/meta-digi-dey/recipes-connectivity/hostapd/hostapd/ccimx6ul/hostapd_wlan1.conf +++ b/meta-digi-dey/recipes-connectivity/hostapd/hostapd/ccimx6ul/hostapd_wlan1.conf @@ -4,7 +4,7 @@ interface=wlan1 driver=nl80211 # WPA2-AES encryption -ssid=ap-wlan1-wpa2aes_a +ssid=ap-wlan1-##MAC## auth_algs=1 wpa=2 wpa_key_mgmt=WPA-PSK diff --git a/meta-digi-dey/recipes-connectivity/hostapd/hostapd/hostapd_wlan0.conf b/meta-digi-dey/recipes-connectivity/hostapd/hostapd/hostapd_wlan0.conf index 570643ccd..73aaa58c4 100644 --- a/meta-digi-dey/recipes-connectivity/hostapd/hostapd/hostapd_wlan0.conf +++ b/meta-digi-dey/recipes-connectivity/hostapd/hostapd/hostapd_wlan0.conf @@ -4,7 +4,7 @@ interface=wlan0 driver=nl80211 # WPA2-AES encryption -ssid=ap-wlan0-wpa2aes_a +ssid=ap-wlan0-##MAC## auth_algs=1 wpa=2 wpa_key_mgmt=WPA-PSK diff --git a/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend b/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend index 4134c7993..76f7b529a 100644 --- a/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend @@ -17,5 +17,30 @@ do_install_append_ccimx6ul() { install -m 0644 ${WORKDIR}/hostapd_wlan1.conf ${D}${sysconfdir} } +pkg_postinst_${PN}() { + # Append the last two bytes of the wlan0 MAC address to the SSID of the + # hostAP configuration files + # (execute on first boot) + if [ -n "$D" ]; then + exit 1 + fi + + # Get the last two bytes of the wlan0 MAC address + MAC="$(cut -d ':' -f5,6 /sys/class/net/wlan0/address | tr -d ':')" + + # If wlan0 is not available, use a random value with no hexadecimal characters + if [ -z "${MAC}" ]; then + MAC="$(cat /dev/urandom | tr -dc 'G-Z' | fold -w 4 | head -n 1)" + fi + + find "${sysconfdir}" -type f -name 'hostapd_wlan?.conf' -exec \ + sed -i -e "s,##MAC##,${MAC},g" {} \; + + # Create the symlinks in the different runlevels + if type update-rc.d >/dev/null 2>/dev/null; then + update-rc.d ${INITSCRIPT_NAME} ${INITSCRIPT_PARAMS} + fi +} + # Do not autostart hostapd daemon, it will conflict with wpa-supplicant. INITSCRIPT_PARAMS = "remove" From ef462702076dc454d312988bdd8b19f13a453ec4 Mon Sep 17 00:00:00 2001 From: Tatiana Leon Date: Thu, 31 Aug 2017 17:48:50 +0200 Subject: [PATCH 029/113] libdigiapix: add Digi APIX library recipe This library will provide a common API to access Digi hardware interfaces and/or other features. https://jira.digi.com/browse/DEL-4979 Signed-off-by: Tatiana Leon --- .../libdigiapix/libdigiapix_git.bb | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb new file mode 100644 index 000000000..e10d4ef6a --- /dev/null +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb @@ -0,0 +1,32 @@ +# Copyright (C) 2017 Digi International Inc. + +SUMMARY = "Digi APIX library" +DESCRIPTION = "C library to access and manage your ConnectCore platform interfaces in an easy manner" +SECTION = "libs" +LICENSE = "ISC" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/ISC;md5=f3b90e78ea0cffb20bf5cca7947a896d" + +DEPENDS = "libsoc" + +SRCBRANCH ?= "master" +SRCREV = "${AUTOREV}" + +LIBDIGIAPIX_URI_STASH = "${DIGI_MTK_GIT}dey/libdigiapix.git;protocol=ssh" +LIBDIGIAPIX_URI_GITHUB = "git://github.com/digi-embedded/libdigiapix.git;protocol=git" + +LIBDIGIAPIX_GIT_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${LIBDIGIAPIX_URI_STASH}', '${LIBDIGIAPIX_URI_GITHUB}', d)}" + +SRC_URI = "${LIBDIGIAPIX_GIT_URI};branch=${SRCBRANCH}" + +S = "${WORKDIR}/git" + +inherit pkgconfig + +do_install() { + oe_runmake 'DESTDIR=${D}' install + + # Create a link to 'libsoc.conf' file that is installed by libsoc recipe + install -d ${D}${sysconfdir}/ + ln -sf libsoc.conf ${D}${sysconfdir}/${BPN}.conf +} + From 1f7920f7deb3cbff999410c1671f588bd9db1768 Mon Sep 17 00:00:00 2001 From: Tatiana Leon Date: Mon, 4 Sep 2017 18:26:09 +0200 Subject: [PATCH 030/113] meta-digi-dey: add libdigiapix package This is the Digi APIX library. Signed-off-by: Tatiana Leon --- .../recipes-core/packagegroups/packagegroup-dey-core.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-dey/recipes-core/packagegroups/packagegroup-dey-core.bb b/meta-digi-dey/recipes-core/packagegroups/packagegroup-dey-core.bb index 2a4613cc1..ff26058ea 100644 --- a/meta-digi-dey/recipes-core/packagegroups/packagegroup-dey-core.bb +++ b/meta-digi-dey/recipes-core/packagegroups/packagegroup-dey-core.bb @@ -37,6 +37,7 @@ RDEPENDS_${PN} = "\ ${@bb.utils.contains("MACHINE_FEATURES", "rtc", "busybox-hwclock", "", d)} \ ${@bb.utils.contains("MACHINE_FEATURES", "touchscreen", "${VIRTUAL-RUNTIME_touchscreen}", "",d)} \ init-ifupdown \ + libdigiapix \ modutils-initscripts \ netbase \ networkmanager \ From c3459a0fdcb619e171a5dd852fad9fe370de5444 Mon Sep 17 00:00:00 2001 From: David Escalona Date: Thu, 7 Sep 2017 17:30:32 +0200 Subject: [PATCH 031/113] libsoc: update board configuration files to fix pwm definitions Signed-off-by: David Escalona --- .../recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf | 4 +--- .../recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf | 4 +--- .../libsoc/libsoc-git/ccimx6ulstarter/board.conf | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf index 03c72acbd..fa12d3878 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf @@ -30,9 +30,7 @@ DEFAULT_SPI_SS = 0 [PWM] # PWM1 on LCD board connector (pin 10). -DEFAULT_PWM_CHIP = 0 - -DEFAULT_PWM_SIGNAL = 0 +DEFAULT_PWM = 0,0 [ADC] diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf index 8e873fa80..aafdcd85d 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf @@ -24,9 +24,7 @@ DEFAULT_SPI_SS = 0 [PWM] # PWM4 on GPIO board connector (pin 11). -DEFAULT_PWM_CHIP = 0 - -DEFAULT_PWM_SIGNAL = 0 +DEFAULT_PWM = 0,0 [ADC] diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf index 527c60589..bb710cd8e 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf @@ -24,9 +24,7 @@ DEFAULT_SPI_SS = 0 [PWM] # PWM1 on Expansion connector (pin 27). -DEFAULT_PWM_CHIP = 0 - -DEFAULT_PWM_SIGNAL = 0 +DEFAULT_PWM = 0,0 [ADC] From 4320f0574f67ca8708a098a87fa706df737ad3d5 Mon Sep 17 00:00:00 2001 From: David Escalona Date: Fri, 15 Sep 2017 09:44:51 +0200 Subject: [PATCH 032/113] libsoc: update board configuration files to fix SPI definitions Signed-off-by: David Escalona --- .../recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf | 4 +--- .../recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf | 4 +--- .../libsoc/libsoc-git/ccimx6ulstarter/board.conf | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf index fa12d3878..c9559ae0f 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf @@ -23,9 +23,7 @@ DEFAULT_I2C_BUS = 2 [SPI] # SPI-1 on SPI board connector. -DEFAULT_SPI_BUS = 0 - -DEFAULT_SPI_SS = 0 +DEFAULT_SPI = 0,0 [PWM] diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf index aafdcd85d..06e16cfba 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf @@ -17,9 +17,7 @@ DEFAULT_I2C_BUS = 0 [SPI] # SPI-1 on SPI board connector. -DEFAULT_SPI_BUS = 0 - -DEFAULT_SPI_SS = 0 +DEFAULT_SPI = 0,0 [PWM] diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf index bb710cd8e..c26d171ad 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf +++ b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf @@ -17,9 +17,7 @@ DEFAULT_I2C_BUS = 1 [SPI] # SPI-3 on Expansion connector. -DEFAULT_SPI_BUS = 2 - -DEFAULT_SPI_SS = 0 +DEFAULT_SPI = 2,0 [PWM] From f64a59ba25004e3c9da8a9d2ad8b09c935eae693 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 14 Sep 2017 13:55:51 +0200 Subject: [PATCH 033/113] curl: enable 'ares' build time option This is required to use '--dns-interface' runtime parameter to instruct 'curl' to use a specific interface for DNS resolution. We need this in the context of the network failover support, where NetworkManager does the connectivity check, by trying to connect to a configured URL through the different interfaces available, and for this check it uses 'libcurl' underneath. If you try to use this functionality without this build time option enabled, you get: curl: (4) A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision. https://jira.digi.com/browse/DEL-4787 Signed-off-by: Javier Viguera --- meta-digi-dey/recipes-support/curl/curl_7.50.1.bbappend | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 meta-digi-dey/recipes-support/curl/curl_7.50.1.bbappend diff --git a/meta-digi-dey/recipes-support/curl/curl_7.50.1.bbappend b/meta-digi-dey/recipes-support/curl/curl_7.50.1.bbappend new file mode 100644 index 000000000..29bf61f82 --- /dev/null +++ b/meta-digi-dey/recipes-support/curl/curl_7.50.1.bbappend @@ -0,0 +1,6 @@ +# Copyright (C) 2017 Digi International Inc. + +# 'ares' and 'threaded-resolver' are mutually exclusive +PACKAGECONFIG_append_class-target = " ares" +PACKAGECONFIG[ares] = "--enable-ares,--disable-ares,c-ares" +PACKAGECONFIG[threaded-resolver] = "--enable-threaded-resolver,--disable-threaded-resolver," From c9b02d628812cadf02a8f1245ebe3fa405e4a26b Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 14 Sep 2017 14:01:24 +0200 Subject: [PATCH 034/113] networkmanager: connectivity check: set interface for DNS resolution Use the same interface that it's being checked for the DNS resolution. This makes connectivity check work in an scenario where the primary interface has lost connectivity (for example ethernet) but you still have connectivity through a secondary interface (e.g. wireless). What happens in that case is that even though you have correct connectivity in the secondary interface the check fails because it does not use that secondary interface to resolve the name of the test URL. The result is that the connectivity check assumes that this secondary interface is also failing and it penalizes the metrics in the routing table. This commit uses libcurl's CURLOPT_DNS_INTERFACE to set the DNS interface. Notice that this requires 'libcurl' to be compiled with '--enable-ares'. https://jira.digi.com/browse/DEL-4787 Signed-off-by: Javier Viguera --- ...figure-network-interface-for-DNS-res.patch | 38 +++++++++++++++++++ .../networkmanager/networkmanager_%.bbappend | 1 + 2 files changed, 39 insertions(+) create mode 100644 meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch new file mode 100644 index 000000000..e18331c9a --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch @@ -0,0 +1,38 @@ +From: Javier Viguera +Date: Thu, 14 Sep 2017 13:29:52 +0200 +Subject: [PATCH] connectivity: configure network interface for DNS resolution + +Use the same interface that it's being checked for the DNS resolution. + +This makes connectivity check work in an scenario where the primary +interface has lost connectivity (for example ethernet) but you still +have connectivity through a secondary interface (e.g. wireless). + +What happens in that case is that even though you have correct +connectivity in the secondary interface the check fails because it does +not use that secondary interface to resolve the name of the test URL. +The result is that the connectivity check assumes that this secondary +interface is also failing and it penalizes the metrics in the routing +table. + +This commit uses libcurl's CURLOPT_DNS_INTERFACE to set the DNS +interface. Notice that this requires 'libcurl' to be compiled with +'--enable-ares'. + +Signed-off-by: Javier Viguera +--- + src/nm-connectivity.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c +index 6f16b28e56ca..c12f145c2ad8 100644 +--- a/src/nm-connectivity.c ++++ b/src/nm-connectivity.c +@@ -365,6 +365,7 @@ nm_connectivity_check_async (NMConnectivity *self, + curl_easy_setopt (ehandle, CURLOPT_PRIVATE, cb_data); + curl_easy_setopt (ehandle, CURLOPT_HTTPHEADER, cb_data->request_headers); + curl_easy_setopt (ehandle, CURLOPT_INTERFACE, cb_data->ifspec); ++ curl_easy_setopt (ehandle, CURLOPT_DNS_INTERFACE, iface); + curl_multi_add_handle (priv->curl_mhandle, ehandle); + + cb_data->timeout_id = g_timeout_add_seconds (30, timeout_cb, cb_data); diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend index f744aa2d4..887fe5d0d 100644 --- a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend @@ -12,6 +12,7 @@ SRC_URI += " \ file://nm.eth1.static \ file://nm.wlan0.dhcp \ file://nm.wlan0.static \ + file://0001-connectivity-configure-network-interface-for-DNS-res.patch \ " # 'polkit' depends on 'consolekit', and this requires 'x11' distro feature. So From c9e81ed4eca0360e13fb3f3bd4a390310f2477c4 Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Mon, 25 Sep 2017 15:20:01 +0200 Subject: [PATCH 035/113] mca_tool: update checksums for build 1.11 Signed-off-by: Hector Palacios --- .../recipes-digi/mca/{mca-tool_1.10.bb => mca-tool_1.11.bb} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename meta-digi-arm/recipes-digi/mca/{mca-tool_1.10.bb => mca-tool_1.11.bb} (70%) diff --git a/meta-digi-arm/recipes-digi/mca/mca-tool_1.10.bb b/meta-digi-arm/recipes-digi/mca/mca-tool_1.11.bb similarity index 70% rename from meta-digi-arm/recipes-digi/mca/mca-tool_1.10.bb rename to meta-digi-arm/recipes-digi/mca/mca-tool_1.11.bb index 206e0abe2..a377aa142 100644 --- a/meta-digi-arm/recipes-digi/mca/mca-tool_1.10.bb +++ b/meta-digi-arm/recipes-digi/mca/mca-tool_1.11.bb @@ -7,8 +7,8 @@ LICENSE = "CLOSED" PKGNAME = "mca_tool" SRC_URI = "${DIGI_PKG_SRC}/${PKGNAME}-${PV}.tar.gz" -SRC_URI[md5sum] = "e739879489b2d0f0ab2fa61f60af80f6" -SRC_URI[sha256sum] = "af2eb7abebfbabe228c574b887d166d2ef5ad5b3a9308ccd07778d0ccbed1e8b" +SRC_URI[md5sum] = "7a2c1119914cfc59c2b8463dba155d03" +SRC_URI[sha256sum] = "71a9002851520947aca443b536327b08a5f413e71a9d6ba79d00e32180220b71" S = "${WORKDIR}/${PKGNAME}-${PV}" From 673f2553bda268f56fa0b37c5bc7f6b4433a69aa Mon Sep 17 00:00:00 2001 From: Alex Gonzalez Date: Fri, 22 Sep 2017 14:43:53 +0200 Subject: [PATCH 036/113] README: Add installation instructions Signed-off-by: Alex Gonzalez --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f25ff89c..9f3737b44 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This document provides information about Digi Embedded Yocto, Digi International's professional embedded Yocto development environment. -Digi Embedded Yocto 2.2 is based on the 2.2 (Morty) Yocto release. +Digi Embedded Yocto 2.2 is based on the Yocto Project(TM) 2.2 (Morty) release. For a full list of supported features and interfaces please refer to the online documentation. @@ -49,6 +49,13 @@ Software for the following hardware platforms is in production support: Previous versions of Digi Embedded Yocto include support for additional Digi hardware. +# Installation + +Digi Embedded Yocto is composed of a set of different Yocto layers that work in +parallel. The layers are specified on a [manifest](https://github.com/digi-embedded/dey-manifest/blob/morty/default.xml) file. + +To install, please follow the instructions at the dey-manifest [README](https://github.com/digi-embedded/dey-manifest) + # Documentation Documentation is available online on the Digi documentation site: From ad5e9aa66a75b0a7c29e655b2771def8c07f7a24 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 26 Sep 2017 09:30:19 +0200 Subject: [PATCH 037/113] meta-digi-arm: firmware-qualcomm: Update QCA binary Update to tag r110059.1 from https://chipmaster2.qti.qualcomm.com/home2/git/digi-international-inc/qca6564-le-1-0-3_qca_device.git https://jira.digi.com/browse/DEL-4993 Signed-off-by: Arturo Buzarra --- .../qca/rampatch_tlv_3.0.tlv | Bin 54000 -> 54000 bytes .../qca/rampatch_tlv_3.2.tlv | Bin 52684 -> 54228 bytes .../firmware-qualcomm/qwlan30.bin | Bin 508216 -> 509256 bytes .../firmware-qualcomm/utf30.bin | Bin 267522 -> 267115 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/qca/rampatch_tlv_3.0.tlv b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/qca/rampatch_tlv_3.0.tlv index ee1149488f03f3cff6743841e9cd2a3477bee161..7b9c5bb648957964bfb737b2920e9781e289403e 100644 GIT binary patch delta 301 zcmV+|0n+~Pr33J#1F+1{6hU=oATc%|GB7bW05CN=GdMamHE_DA8}@YJhRG9M4JHQk@)_gm}%YUJo5pTtva0GB7bV05Lf_FgH3iHah*sY-dP5VS=!7nYK|di(rBbH=9HDyUOYGXhn_%T+B%Da4rwilYRqcQ+*t0_Wsr zy2D2{5(UZ6(9BW<2{n)TM>@w08K^gF(}k6hd~5-zr_i`25!Y^biTgGmAp~?nGs5|B+0!%o!tY5xGg7Jt zdx1zq^!XkL@cKu5#V`mE3%11VOqd5;k+8@i#Wkx^I9=O4X&;ZcM+V#8=XD{SYq^TZ diff --git a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/qca/rampatch_tlv_3.2.tlv b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/qca/rampatch_tlv_3.2.tlv index ec01e674086ecde2e240f65173086a6febcf69f7..def7cc30a2af7eba36e4c5856856ba71d1a7de19 100644 GIT binary patch delta 13479 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 diff --git a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/qwlan30.bin b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/qwlan30.bin index caefbe0e2170546a8d9404a7b37b43257c419e26..47a5db5c624b68ba033b56fa48fc036c7dad85f2 100644 GIT binary patch delta 45245 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

s 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 delta 43831 zcmZ6T3qVvw`~RPrT`t0^3oI8EbU_voQCCGpC0Pg!4HFd&FV$+Sp^~Cul3}|NuThdA z2RqzZ$W2rz6l<|_RKT)IcG;(UKv%N zIco5dhZZEzz*9hhdk2p(?q3^4?Wdxs0d5y?ekzJW%`&1PNTnodb%y&0QExnv?(-

!SMlnl~9(jSGCjKpTp3$k~^_V1%8 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 Xns;icErUhB|FP@5#gBKfhob%;MA``u diff --git a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/utf30.bin b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm/utf30.bin index 301dbe9ec83f03969777f740c21435ada7275775..94fcd018b6dead53893818dbe19874e4e2ae8350 100644 GIT binary patch delta 153215 zcmb@ue_T{m8b5w!=H8hL3^3qDM*+S39u;*|R8-VE3>hXCDkc^;2W1p>^o)u|h0P40 zqJxE8EPhoCNm1zy$t^40khPYIEp*-1-L;}tcHLboD!1HSYrgM`w(aNh`uzFz)qBo! zp7ZND&w0*so^$V|$`?)lc+S)%Ydk%Z3GovmlKkgvB=>`CLiD1a<@}6kaF>mk(g<;( zAm>dR>GLzmNCuF-1Y7~c-8SMywX2}71J;*pq~L;$Tm$`Yz>U1g-AEXqZmot?_!<5M z8)-n17e%edY#!o0VIy6@X~65Yk&{SkfjXe4#75e{GsYhwHC;A>f0{n#`w~=Gd`5A|X zkXc4DkOR4Qq8>1~74mOuB!%Z~B)`%|sxiL`%qI^x1_&RGB89O>NFK(i>9!FU(pHX; zTF}Sdz+{mp)sW?Nj1Rg2e9HzKDFseB@4*DY=tIF#q?eH10KDixM1@Z9S^?ffNIsOm z7|4YX!5{%5iQ_{XDeAY85~S6Sio`8Dbm=L6hUwOjHVEw9fU$u>Cm}_^$q+(b0k(wr zYh#tcF+{pt+loBp5jiK@24BX^an~`x&Um25shmp8MiEB%bc0N#xrOs{8ypSfpPgK9taA=~F? zP2@+2pn+H<=!F(A_oDBU(LDJi`o13xnVvoes+JHx6ZawVR+nG?GdpvFpUIf>Bf2DH zP(y;>`kBqa;4w_qi`w22zdTDn1!`WePmRNR3Ycow9+8|hH<3=H4S?ebY()8}KB-vz zy^UnGHIfn@7SPp5$^a914xnvPHpxQkY@h}$a*@^{ZTl1^jJ;X%9O{9-{1LP}Ihzb1 z%_7;P2>o>pVvAmcrOFmVn#cM(8)-z#!e<(Z7cE|cvU~2Zk)%4a#*sB{A$qF-PAa3`t|A0b!les*s;VX&Q#e}bjV^)rcDby?h>W3PP%2eugf zfxb4zMsB{*NCtsxFt0O>MEEllf}%`RGo@q56es|61VFqRte8e%kjl$Aqo=MK+Jx*m zC~QMIjQ+^5NO~a1^VnoT_%)DiKrV(H)MS%kVCdIxeA1AFs@iNq5&<&&^~p&#@htDJpLy!Du7#-XW5Lh1ultQW)HfY~q*=6Uodb;{0rK5i~*B(P`Pl z3oq+NuWgxd=jWzpll~2`Dc~A#17J2ny?_8%fDAwc@_+)sA)7*DJ*}XQ0$soZ+cH7!zd4wdB1i#_&_-K+&lE_SqpMMv&8335+i#Q8QzjDGeYH;k!&>t|z@;y?gQK=9LG(2P_7w1n}qhv!>BT7e&e{|ROy z6@gqJ9~gj4!+?;7U6&_M51+Z(&lD}oCRQ-4`B++1Y6RMVPM`~LL3cUN;UIb*&Kswx z7xh9%W7!%Z10Voa;1ufi05~dqX8DcqEVG{}^?b@;MONt}h$ep~(E>uAUyg`~(+ta# zBeF(gGehmcMK>PDx%2p^o?uWUX21MsMA<^9VfY5oa%V}_GE4*E+YNF9XOAHV*<2vs z&twHvr7XHxh^zxB1>8WnU$#b0i58wj7M5`m$i);E`DGdztA_{8%J<84kz>v7d$Wlf z61eZn#(0PXZW>Gv8;B^Mjf|Z*fLS3TAp^}AtO@D^3c#y|3ai7RfrW%zhgRG&YntO3 zUJD;Fya+9Nf&-W|alin8!4|ZJ;gsKv{Rq?mbwC@?h3K&u&46K4I|Wt`&<9kk%T_1N ztVb^(+YlcNfPD!d<8hMunKD0PM6gxu6-l~-=t(*Z*(>*&(#N6KC`3s>4NwaV`t{9R z1z9I^Q47b4n1hfH_k+HULR&}kAlXU`Ew7EbXW9S^-5rXM0%&c8yzn8ya>xtX5a%ZN zkGMkp`hyW}aBj#SN2M*l-Ucs)c1Js#i1mdgauhIuzJ@gO#U?_2)Zl2-k~$nDZK<%E zP1sDSN#t@8`i2Kz2|9l>Y!H0cRA^aV6+JWS#492@LXb z6X`+6gU6dlR#y{=LwZHQK;WM|)`SkuMW<;T^0jDtj<>ssG``Y=a5segPqY)7rzN2Ib`i2xpNxAlS(oLLLM3974gJqml$3(wT8YmBy0f-`A6qJx$~i zz`fQ)Zk%l*1M;h*rezGgjS+s;MDlUCX7r-8uZeW&2=))reEn_{xr#LfD+{FYy(W?Y z49aGH!p!6?*qFf4Qa^jtT@Jh64-+eO-zySv0wG;cU6G%Cs>nb-N1JaJApnv$^GO~H z+E`wwCoXWW{i%uE`~<4_7w?Qayh5nN%iq1}VZ?+EQndL6pXQ1!>S@7uNP-Av`f?^KcWXo**N}B;*+Q zoj{fgy9d&hpzRfu=YI`}zkv#`Lpqe#eG3VIa+D3Cj~;|+Zqywv@U!)~NOH_ z6)pb**|;n9WxxW}C^;an0oB_f6zfTr)|IZzct?&BU6}Oian>@84Kw zb2F(nG!q8>U(_~}bBWDla02MmW>SLu%G8B~Pt7VJ(Wwi_D1`V65fd#!P6Xf$V2f=N zG0dc9atRm)_{kV1btMk>NOBbP^(h!)S~KZET{kSxjWih4k+^&6adN@YU>ZUA*e-eE zn3+Y6=@2HfnYiaRlZ^SzR6kUU^0V-g5-et|idrvg! zNedwZ5UlQ9nTYSn5cp=$jegAVbq=H+=$n7k&o&m^^s_Z{$*{*SKVVLX?<{C0u6vqE z;VMjH4RrrNGg*;3g|uPq2jo`s1kFYHv^mXFZW+hq1XgHj~y(Sm!Oxq}J6;&Y<2~K+?8savicAQ|(MoG{c~8 z0#@+d2BLvqX0|nx8(^8$;|d<$LYqn1_GVJIqnV^Xh&7Ze#>VP%(ID#~`Khtvlf4h4 z5NHG34`EECxI`L7kyJbawIMww4~~tUmQ{hCfKwR!I=DBp0ZgPEG){vYB>AcwK!F~| z=;U#B&q>rz_BE46;N(G(Fv~>ZrKn^VNzR%E!f(Q*zO;d4Wx?RVugio|(0@K+MXpDW zML8QJu_8H@h{G{XgiHFQXBg!f+p#&_2)2>t96+1|-X-8NFbHI#-@Kg-9wP2U{E1Ab zt%2mXiKG-LLw*=5?*i=xF4i`axI>tIWiu%S2%`DZ`(WnP(8PRffhw#VzyXaw-5f;1 zXyZVe;9rBm!J1~054vapVgRHBFsI2R?{VyjYuMlyA8#g^I9T$aEi4S|3X#MZq&PE6 z>tOXL<7A|AOKg%xl;4USGrskSW^(07GwBCT0y)671_<&bw(Sx5dh9$;-}~7l9XlW& zbBy6ap{%N4={JPr2!x10wNE718_~Q89-$fY1C9abfbxGNPanNehF*w zlKfeGEDi!=G>OTJBCGNuNeTEl$1pEo;5giug8T{S0=Np4qn~6qyg)Z}2Y9DrS3ZrW za{1t4D%B`&14Pg@NLzn_^+$OR)PU?Da0U0(T9}!oO-EwhXoel;ABL-(7S2hGIz z8z`l*1gn9 z$n&V%g*@QKJ#02k@mE_(9RRl?Uc{au7qE`M!+N5M$NNev9>ca0D>AM=ne?EawqLfA zo-?iF(g2L(Lo5a+bPDKECk8kmN6>@Vwp}Dv=w|@DL7?VEI2Dvp$hCGbjO3%t4R`?& z^QlAH1`MMvS*94uiZWr#98z($Up}7@=jr?s;#`BR260G#g*Cj6eeo?0fKHLr z0i++!8>oirT=&Yviopnu%hD>DnE%*7uD&P}L1vPtc|?eq1Ce6% zS`rNylL;xnYzavr4Cq48`Bk{t;W0}C&J|wDmcUoTIfjv| zMOYRLV@ky2+cd|9>+%USpE~I(eF>3-x;5nF8x3nk&$h5u#(eKau_g z(Je>t!F@p(q#3_a!-g*i3tA6Ycj18os^HbVoOknSM^P?Te< zpUE9S_B_}Zh_^FZ(=!+h=0j(qNp_{BkAhs$C|`~87|6wwD8KwlTCR4?LivZZgk@Ms z-R#+OW@~592014?+n%k>#`7G;UQ{F%X^V;d^`47Uw) zr|7&Bx@aW4U*2L#$QI#JSRB756i1=B8alW!9>-Z?E6H8ZO5#ADi*F?vajm3wTr2AQ zoz&D|(K>AC>LcPPk}p^u*1C)2yCS6#kDZ+YV3UxC?$CR#4r|u+d@+MoY1QWS_uyf9FR-WCrvUQZYAkJ(VikU?ZK}r7G6k)W)+$-rV5>qNMZi&f~m^_Iol;jCh$9T|GeHMn(kc|+ zXa{)-_!fxJNcx}q*dj6J98A{*9MMRLKJjkJ;4@2tFSiv$CWw4kK4H|dLbachQj*W1 zHYo*B`WFy!T0-JcIc~N3^D=&T1K7#HT3{arOqPs-Bn#8VOhIYkhzf4WV1{x(gxc#F z>}ys^+*>XsCQ3Oul8^Iol3X%vrbjYaB+l$bC9gpW&GhOdCPE6eoYS2%^y~T!5?ixX zFBvKrDO8ZSQpqILK%N?jF-ehTtkv-I*hjCaj~ap3z>xGl(|~Tka8Y;Ba7lN`a9MZR zAmMQ}88F~|6Nb5ntj}^xcg%2FcUm&AJ}BEL$?;afgVi=mT&0P$K@(k4bms8$!>?U` z9{qBhh`EX^42R>Y+pD{aG)1ge>(y6ltMy);*PzPVsq2(j%!|W}D&10MRiv#4H&`HNYwxI@MR50Ma@R>c&Lz3p39T8OfRO8zN=zzo+&&Jnei{ z8dpx9g*dNZg&{?$6joU(ahYTWs>Mmsq9l|{CadZay-839bgqu-Ba*y&x-eH71>-S5 zV_cymh?3QpE3x$scU7VsD+N`SOA!rLNw1e)>6)IP(Ma-z88h*# zpE(`BnKLKiciqg%_u`)2mA^~;H0CVe%2SV}!8dPyF!;NlueSb_(NlA#59o9z$xO0qX&0=jFPDy{?>Sar$m=zKi5C$N_fE4x^HsfPhHG6F~9=@TA1Hr%GYI zB~nw_7a_sS1}2Rk;$^kt>;eW0DcE)KNrF0OM{Uok%m0 zHUh5gEu-@Q6=h?ATtOERfvRvR$u@ySGSOIU=XO@+k%Hd=;I)wLLkl$IWV>f zW99-C$e#xKfr?s87ia^n1Kc6V0l0vI#}KLmUBD^81-z6=(!HfoniPJq83i zfm6Um;5uNEp?4q;C<0tS7jOeGHb8Ko9O!%yQR-fJ0_^sKR>^o|zQlw}KCyjKX#i6_ z0z8TN^Nk>Y(*S9PzFM%PfD5?zG?o+)+b|>=)qpn)aIMe>-~~Abu~^P#*`z4ns6qmyT@e04ltHUdSSJNVL}mx3k1hk%QA@(q!1jJTB5^2 zB*<57X5c71QiymMAJe;Lu5NQR{VN}&OPFN@D z^SO0s^~7S6n!I5Zz!I!zk*VgN*(|D6@}cQWv~qx7s`A%jrPZ`DuY9DL*^6pEOAYEF z?k07p*9brYp%bYp#i^10(jkmbAd=zfj6O7}a($h`{Y-V#Z^l$AX} zVqZ^B$A?TDnL;87L#AT9(bMo^J(O4__Ov{AL9G1lqO=@|9lO&hg&KFPUsk+xiz@qc zXm)z>dO~&-mpSd*%2Y+OF*{4?jlnUYJ1{SS3_lIOC3;J2y$(USa*Mg*9+9u)m#>!90Q) z_;v{cZ?zY@B=%Xcq_||g#2!euZ`g<)He&kdr+B?OC$fIWdMU)Wqr|y>2lUAL*1(*I zbNAN&_KTS4z_j8L6vbja*Go(ahL@O$Bfp4{jZP^n`4$Yx61xR*Oh?5T(9GV4mS8Cn z_p$pH!g`;|j&p)EO;Z2CTJDh8kV&B%HtpD1CT!hVvP;;yY3EKVglP3h6mQtDX}x5~7s@EiRsBd4jsE*B zs`}05rTK&?E*ZUhqqz^XSBx_>GDlr3m*a5fL20Cyr_l1}+Yc zBJvh_Ri})rP|O8NL}d{wDUf8=ETTa%yW16_L{*L>2DDHs$N1(cY~>8aP?@9fLW*Lj z-lp)eircM>u2w5()k=(Xt6xS5s}>E4y!4JZjUt!caS26?BIhhlyG78&6G9Y2)kNP2 z`^lf!y+09O{6v`Vyxqe76S3{iG|#O;@)g|H{;Lt_1-dmHn66CNC+HNzK2EXjBZ_IS z0}vF`K463vZ_#SmJ_jHwnIrYgilw?-F;y2T<|_9{T{H3m^4vbRg8Pd4RA0R&H_Ci2 zAFhP$6%}DWYVXff~-9v_d7y6vo9l6untt+zJDcD^#Arta#W` zb>z?^g|N@`Thmp4x&2v+(W*>+Vzv?;t;M)yjvb1=vH&*iP#Y}WsO0A>@$q5G%1Vn; z?#ol_}@9LhVY_!gm1HUG!TZ*hG~sys1DSQsW(o2;4$ zS8GMp5)&*KD(1{U93TM6fCWegtN@0pb1D;|c+1P%3%bd-Zs?MKN$8N<0jmI38J1>gm$ff}F|r~?{+MxYgF z1C9cnz%if;I0>8rP6Iu_IiL^d2L=?6fx8Ie5^xz91g-#Afos4pa2>b-+*G)FP6G|A zl5l_#FabPZ)+qYDmhqsHfl0_!7pCLapD_jbsaR^O%8M&h45s_QDFPk~8+`tZ?4A>2n0}lhL5RU?0pc1GC_5n4(L7*0R45$O@fd=3Spb`Ekw-rPi za8#XtCx~M}7jP0d1)K(YfO9|}&<_j%7lBK_Wnd7v0$c^I0mHy`;0ACLATY^l5d;Sq z0TaLjW-Tn48wV;*9bZ+N04U7;8M_tz<7G-^#Q{M{t|CgvL}kvC#9eJu*cXe08k-V+ zi0?Uq+;ee6Ruf}awW1dkBUM9?T|1R9Wr-3d?p7lv#i%%yFki01@&6NXDC}azD3;N( zV%JF2;ZZ{4;4;+6LkWvjSY#^WMxu^8cI==#l+bc8tT^Nq9nZ2&!}=RK|a)T*M(t*ou*X_ZR(d z#{E;qgU)N1b;Tu0cxCK}xHV?Q5T}Ivl!H$~m0h=r;PQUX6#O6cO4TAGB&n(Ri8^5V z-+m7yt8#?i?)O0Et(@o9pa=34W2IGL_Z7IeC?R{7D8_wmRTWFN5hr8}KUG-Lts-}qaJMx&8vT?vKm!*K{fCn~A-b}MGT-FifHwI7fB)+|!gIv{5% zMob>0J}%>Da@Nn}?4QXwKa&a*sf7I05dGdF4L<0ia_ori(50%o|2v11d1My<&%*zo z%c{zuWV5QXkrf&tF@JU4{%`ir+`9b#R;VlanZ&lZ-Rv+9l%Gf(G(V9U*b8O1IzEg& z_!GNGG3<|R!&sH z;uQ9Frr>`wrT?3$7|B%GM;ghd|IM}L+{$@w6}A@sABC>}%{@i_j~tFrUxih*8ty3z zR(kp^G7BVPJ(Zgea^@|v1Z2i763UO8H9|g(NF#3cEz$$$6*uP=tr}eBEixD6+*@Q3 z+=1$Zuy9Yi!M;U4!~9GlSow*Y{xd25Ocwl1mfj}K%BYbx*#EZ(LETR5{xXGqjNE2f zZl~$DQ|s+C<93>PJI%VCinr68+i5Pkgc($t^KLWpZ>I&f(?VsG>VGQDMYkD_+bJTj z5q|0I)O9;`qsLilgR}?bHjM{qH4Q3Bhc_U@zy7l^~vdHEx1pcsC1y@%zj0>I?5Vf(R``aK5laqrqPjDcpto+Jd+mC4st2C&Fsh zDEi-(Ay?3S^GPhrqyT0zQLpq(kwYZCDez{saEbA=pSRN8_v3oA_fLuW558=p9<+L z5NZnkstOpGiVuTlLYNFloQcnB0SCa%MQ1?cJbb1*A3};v_@f`>ZRiik&&D^;5TX`o zP7XdWz60M{--%Cmb1}&!O{DZL2;^Cc3cyXkoYzG105@<0uq=b5cS95RAkA;WWzus& zr|6F*E8OokBB;VGl6&1HLFaP;#8b(NQ9u}1)n z!7tp`M1(rDlQDrO@m2YgxXi$X?X_avtIHkm_C@*X6#*x#FC!OJUMYAvg^Iyb1B+}i z{wb_bcz=3f2JhuW=J_6%+(sAb)5D+pC zRrs(HcB&v%F??7wS~2|A1wZ>iNd&UV2*OXrA=vyNeIb5u%{B~(3AlrPkcq40 zhq>_MA7S2?@eWXD^6ET-i(oTL0W}*5-;}`BNxK%vCC1CxrH_4D< zXmz}*7%mhZ#!tmg+)k74#}br4=hYSSaCdP-3)Q8`IE794?2+_6i`8t#3OO{V%sQ3}I1 zz66J2iAMW^nr0=mihcz0FPPqUNYV5iW!x)yS4z=ig~H@D{6i$er5>ANcwz#+hQg;i zH&A4#%Wot%gLtvINzLd&kqILlGVJ5R1Qvel!!b%oze^dr%ezDsC*<=)AyiZ;_Vq%A z-3%G@z9NOKn~S&XdAADu=?Z&+8)ri;BH$8bF&NxR<3Zt8<|&-A`vfKIqauX~RhTi>dlBeZ6xMCT?OYDOe;m|mxgXC* zOs15SWc-(um>?u2s1LFjlVZ4^F@!4mcSplv7r>Z0;kQmP!fO=~uc2&s zB?GkCT0G=5h(RDX4=-1i;+@I^c&CD=^yv;X1mZx~tZE@gLEi*ja5vKBc#nm;b--yL z2j%(2cn<>%;zOy1HF&3UANVWrj_2+ch4t|_QIu5z7I5_*ymi7STh~f4e)=Yig;!1| z@#^U$-r=a9d-A|#&{@yoJr8gbh2XHodHF_Ng(G6_<(x|^w)S%_b<%g-KN-BU%T}w9#VS;7(m}*%ozCAEQCJqgN>9xR~unN4(Jj5 zE89?p1~-86b)bu}20$L__W{Fe@Y&Z+d`=Bs55Qm$g!EQ7SgY_g7@8GI=w>Zu1l$1K z3iJaW3x3Xld1X8L1g>Cw>-|UpQxRkUE*G`JyCb50dXbjZ>R1iK>I|V;E>sf|s?#dm zuoaKNn$$;n>5Ad=rFg!zt^^;l6)W814x+He>Lf z!Z;ni;HtwZY5}Knatm3B1F{WPT7PpD`Nq(}Fe*=5cYhXT zB8|QHq0CI-qn-&^bmuwd(!_!ISP8v~eZqIg7w!DNI%42D0d2KRfQYmYqhDWIU z&bo>6@VW_*$Fx3iHf2Ke6kn4B^n6`iSzA+A=wf|5`mEJZ`6gvJj; z;C}|ug36`q?dagx`UmhER`Ns$i8~N^V48E7$}g168igvm(d@z6M~-VDGg}o;<*!RN zd%)9Cwi;bl<@83+uF+Q7K^pAgD2M4$p+3IfCzOl2zl+o*lZ`kVX%r|z!)x^*3 z+~8H)=l1`~bZN!~yGfn4Jqk@JyD!c@sx!OY&bM{i+U+smjRwZltf;idQFe1YWj*@w z;7qtt|BXGFvhEaQpcQ@E)ymK90%bQQAd?6rUD|QMZU$p4GUI^Q&h}orwcT#%woj+* z)`^w%b1LmKC~KTV+0vOvCvR9XTv-e#gd1_;qg_y^(Uhsm8gLmh7h0gB&U5dCF`Z@=?6U?D!~X9CwC&VfAtS zke4xr#Tlu|ePS#h7{wbyW^6WPZ;r0tJSt%3J6@)Som79oVT?6aq}&Le7{?navuH|a zrKKzo%Ts+-G?l;Dn1B%@OJ{p%sLv>L3jv-_d5cSI)724bsLPFqcq#gVol!X~awB%vr|q?KJ$<&`pBJ`0F@whJbJZu#s<)d} zJGB3I9V%h4F`oVGio`i9>_UE_ZH4{6i}p=oCXLxY{`17SpW7{%{)~wj0}G^|Y>d2+ zIPZcz9n4u%z?ce5>rI@GH3e%nmQ;_$)X!{B%xbr1sH|DY&IabxCt~;_l_eqj0I;?) zH8H!=E*fEozDyf9*?@gTqJ4$E#K?g;4_i;afy$dVO@h7oCf@P6{T|qO z3-&uN7~?M3uT!~ulOvO|HTUEjUESEeQQhyOMby1CGztb9tIg)-TAb;*kM`7gF6a)N+{@+0=&)=FJ`dUi+I?w2Xam%T^ zed|_K_;hQ2BGntuFwVcg1#s+;OqQ;S&DoIifsv)5v*KE5XhsH=mv2jmrTQi3-dNG* zH8NQnDW5kB_Ch|Pv3VT_seEYLT6Ffsww04!YdBLpmtT=!et+?b-)UC7oxTsgU|EfC z^u`}vuu*;XzAu9`vT9e#MJjKhacERSw|XddIMW!`+n!iV_~qki=#iQ1iFtfwYBpG~ zx{ul4FlThfwV%!BQ@*46*88a;v&~JTGP5YF62{C0e8)Fb$XrNcGE=@n-k9g3`Z*SW zhD=<d&T)e&OV7(<;P@oEsvj#(P~I>%6U6lI@w*!j6yY7nOLywELw>mKc)`Xj4nYYfLVG^C*r zI!ijPQFV|^4OP>PVaD3_^IB}f_V=&}OxW@qJ`BZvJg;qk-_rfQ)p;XGjd3Da{(!Nz zn=+>C?)NE^g_`<^_V-(sKi&`9j><~SN|jR!tMHk(FS z7l8hRa@G^e_~{&{Ebds)p-8I-8_8rZ**8-Cj7)b)Yu~UBKR84a5X!O z8umK#p*<{5$`?Ow7#BtLm22v=Nqx4aK3iK!xxgB#PagXFj~nL2fWTtJ^=6Z9%3GXQ zX}Bee%4>Ee+Gs@UJjy=1f`(OE+j}kQux8%b$5NwjMt!y}v5lcztC@1?CaO>Gc$+4r zQ$yiUFO5!T>6pTl9x9*SId48SG!_wlMq6-B^eE%iv{Mmhw3U-e0xKvppEA>JEBQud z!`LvsJU{3~b-JG+XnoMc;il*-e~X2QQbw*ZFiTgi8~1#7qf{_yG)WgLZ++x1#> zwDE6guZLsHl`Wc04KI|dd&&q?@(~|_-Ej?*DO)EUUdb2V$2W%brh5BduS}s~zQ_&f z=HuEE_w!W#p==er(^k06%A!99$r&x;l?SL?vddNgJGWl`_ZeNl!B?ha8`CMXN=II7 zXixRjZ`c$2V*3V_WGTtO=oa$ zjw+$@zjs;SBa(Kj{%+6i$@qO?cRG%km*Z?y{?qQ+0u8Axqg+iP;;Q!d;@Z5|=QM`3 zow%ZIxJYvEJZR;?(b#aW*r2IRypQnH;o%R#&))aoeTZR>Ze4ckM}F(UG3fpG56%yv zdIc+4Iflxy<*E5tF-hC1GirCsq1iEH@+u+ODhSu9;bn*+1h(;Q?WPBJgq+c({1(T? z=-!uuJ?E@F0_mPadfqfy-xQqZZInCc==hCxN@y_-{UKjcBLPd#)u&fw{@sXYA9Dx7(h_@8Ikw!@2frtjceuVziEOnSo@ z29;BNXe<&GQ1*CgR$}~cWzq)-d8qu*!_^24o-lg(8NH77L^Aq5(w(RoIx0s!GGl@B zN!z`55##8^gc$Y58Rs`aYuk0P>v~5X36$~1|8zWK3+&=g)bJ@FcEbiMoln~W5Ar7t z@Iz0@-bbc*hMH|>*ucZQv)Q)1j)$Jk9_G7KJ_PqY>+tKh6tp2mv2I)IgbamAn(lGRmw?`Y2FE*|joI z&37l!u(gM6g}wxo-Ych9jMq6Ir}DCjSsu!i3QoUm#<56sy%G}wkMhylH~u9XRF=+=-pn`|^*0 zXQ05T-IHro;j3-EZJIzEeA>v>mihWJ~iQQ2WsZ_-}pm_?A;Ryo2lC~&O<}O z{ectDBY8h?q7zB`S<{IZXjlY);zb$~5jf8G9@d*ll-d4?dh41RuP$ubR8lKd##TMx1{gh4W;)kg|=>%|q8j?1l{C#j=;l1FTL`~;L z>S2<4&zjJME4-&ChlYzzwbS0SJY{UZP%HW-y-LG<2IqR4F)nbN8b*v|9mZcm!>ZD! zxAUX3wW^*^QPz@lgfh}vo3R!rrz@!*@z(>k_+hLI4NEaOC0p;y-_x*Ele38G_vVdm z*HLD<^g32---hl)C$#Ro&sK3d@CJY4O{%Z9@4_OctU)7h;55~zmQW@d&U7!=!ndwC zdxj7ElIo}ZiZb?lA>^X7Z&BkI(-2%?hO>(5+jtsM$5EN}Bx#583?a-k;+%C3p; zSYkW;HXk_0i!We~rJ;G8cY|<7pOR~fO@w#ZkoXw-D=0?vKJgvCJGHtu0B<4;-CQF-p)moJ*c7jiuN9ikg`yo=8Zux;xl~q8{YBTsNU2XJT(&D zG`agtgCD~N={#HDH~bi9(peb6=w7(_WK?VW*n~P5*WFJIlTtF#K^zTv%uU(eBDm)~ zsy|ei(7-Pr-~;D*tkea~Xk${?#{*f|sMR@j`PeBlZ78x)!@gy8+2Wg~jv2PVyZpMB z31y>e9LP_%y_z&FZ~+mU-XBTXxlXGsaDj%-c22Ve-b1{FYqN7I6z0}wahS=h?*W}N zjmjH*Gm&fd&B3JhW}N>W?>LDAzQ&$1!B$7evM~ME!3AM@=;tsw{}F%o_k7?IpYR9l zp9uzPsBy>HF1$>7+dP3kQpS9$n;H&IA7?xJCq8hQ8fvxOlMA7=j5|cW8QX@pZ*7adjntmCw}>-ywEGi`Ec}zK3?&9%MOHLD^{izI?(B?1EG|ONUj!Y zOkSVuKqLaTe30IM9tb({5kK0fhc53z^-DXu&OqhUB5jDg?XN&AoVZei4U(`v5q&|B za9dyyD~ryMG1Ab;e57GEnGGd~l6-eh*PI?|k)j=wOudJJI4(JNuIF_$THblJZYz zBE)$e^A7><+Y#QkVs;xrEq6v+rL38O|1D5Wly|1rIze2c?UBosBpaR&bY1paiJ{lSl2aiVecXa=e3H0zOL*hGH()~xa`+YCA+!gUW zWgjb6Ps~RyOxg1X-_YmcXT!YhYyRvv{PaUq|M*lP@CbaIY49H&L3~rl|E1h9C>G27 ztBK<%GtURzogc>L7xI_MsD&CGpNN5Pao&=YPsD4pK*Ig8zEqr_!q8=e{S~Jv7iAjy zlemw=5%qoGTPXB?gpkfZipD$|79}|UAYPso_$Pn%I@R;}=rrY$sAtL9((m}dKWRve z0AJGak!brBfB1WTyB*DK3F4ckx;KRlF zJu!ZGb}{+-2LIW=_`tu>>thctiRw;$Y>j3Z8p7QB#IxUFj+k)dW0*J9v5e8Nqt zkA76ZdH#-wR?B~&hGe*zl($9OkNox^T&N@PANVR&d2ry9s6Ne|3>xu}qtb%sM3;7A zhoGb0R38ml)6qjir>So0E&1>J#!V*FxWRdbhHr451~pyv9{=GlBvEG5*_&9HN1?!> z*J-#b<#j4g-9Hv{f3}dydHWG`u+MIt-t)F5pp6mxO;+eAzgzq+QM)(|$26;p=}w#8 z^Nxmwj_<;}QVn#acFEM4Y|woP81D^ z?RZIqSDVpxBl~4+?W_SBk=5}6YTz*yj1_rLSk}<<=$Vk|`WPEr+(X!{zQr9KsPsn~ zvH%w$pZzHI`;5TNY()pcI*8FY8v5{10Ck?C%z_XIX&t0t52v)D{N94=)5BtHc$l?k zhB_~}ojpTOsZ-kb5uPd7!%=$%4X?E05^BG`SZ9ljnI1t6cAO1%?B6|2sPoR-G}P`^ zr|nC4626z1Vr-jp;Zfo*j+ieZ~~5kI+#oE+2ynUCn~-$=v~S z4D2$+FBTu-UrhqDq&qMcZH5lW`3EMLhxUs$?7k#C)wwg-8VJGR+x42@+$ZlpFdJu) z*%*$$Rf%X%7?tuqmHQ8*;>7uOs;)$=ubB9J|Wy$n0c zEI;pdkCf(~7vTsqml+&#&vPOAzf9B_%?G~j{My|>xyZ3ipPl-wHzE49gQnP56nf$iWn)x* zq~OlB?|vHDoNqhC7mtsjQO(Pe6R`Oma5N8y%Voqyi&GK;m8!la5!bNpHVs~^E=YMd zh|A_=%7k_F;V0G@XIwD!YpNfOH09U9gb8?%yFZVztFU7`)`--&0)(>=wuyaxG*caI zT+HM{Fmi!zR9?zE#*TX<|YUbt}?U1BAG36BdbxI`*V=2Rvh`A*N#? zwyG_S>hF&aSkRftxd4w(a#G_16IH*NC8F6GZO42V`UiorF{gY(^U%OIDJC!(OXHiA zj;MK(Gn0nggR?O$WsZ18ixwTTRf+VU;s&__&qVzW8nHKrhCETRgR)OlJY4l;wE675 z2l(^*`Lrw^Zs~~%IK_vC(r^$`!}0R-Q(~}>aM~@W`X_ZMlxr5IiM_{zfp;Kr50-DL zx($0NSBoGudW!gJ8c&TXtwx^dBCd@O;^j&3P%Kmo;j_rusVL7eIW6MZU-5xyFyGNz zD06q32pdiK4!0ZqlXE9SEfE5ody3j0E{27un}@I~_uWYi^%>d49CiY(8f;}! zF9OWeu>PLSRj);x&+p^Y7L54}^Z6wzBzC~_&NK4+Jow|@Hga}UOduLQqEb+O$WXkf zp5txA884!)4UTJJEHzaw92zGY$E9o_M%Q+%*qt!>?zDs@hv7(4@F4q;E7gQIK9ziT za)QwXX2%%uEKF;Dnra15!)WnUSVh+&0UqZupmAJEj7L1K#S5dMH1e@l4Iuk`U+A2v zLCaxkcyft3=KrJWJ>Z%;!#>a?WRV<@ksL-qa{^(A0~CZH3PeB@7qsH8L=BEwU$I)X zwS^ojMxj;`E1hM#5_YjAtgkvwfl87ljjFQxUf( z$$|+_$&He%t}#mcbC{O=d0cbES_PN?tk%tK|KjNqj4L(2llz z%b6VuqxY`Glp}DU7y9|D*fx4IiR8eR=$GAZWp)PjeeUS%#M?@o` zV{nWLZ4vK~**^f5pm|Jso?kNwRh5WVcz(gHW}T+|F^>;&{+wA#!*bX<8{_Fput9EW z2QyDZL1q*tfk}d@JrB^RtqTkmFr7Kvkd~k?Kj9kgsOa&C-p}j`#@Y;wo=1c;?`0DI z*44zf5o>zS(taDC`0rT;AzZ2dE|bU}Z|<3Sw>-0KAB2j(9sS(40gX0(``=kkJQ?p~ z_B~QydJaqi@7)ElweB07J&>W{bR6f`nNUrz0I~nlEUdYKOei@Rbnbi>8h1Oh>t6-& zE4h`~%OW6_yo{)})a9HJ>iQ1b)IEVN?slAa2(r{~Pv2HsrtOo%YU_)O= z{~)4<#@3>NQqJkIihJ|b%*Y2svIAa${+a||&nHBl&v5GBmSkT9a%ixR4JXbRB znof+O@!YOg6wv0}BR+4dN$e$}`WYW#QSm_V32;DCe{crx`r06Y_)8+b8DT(a5aPR4 z1*8L9d+X4PFz|;)@4^bYfZo439|-50{2s2eP`bD?iRk?K%z6B>e-(yusCC9NN&w%5 zWb5$gm!OvdX_c}Yqj!~H^Bl-KHbsfY$M#1P=^LByuq^NVzJv2Afu#7#DD+O(enGZ08wt2L~-27*or}Tl?Sq8qgpci8@wF4?hBn}tNtxe zXnFJ88)QhRu{pDAC=u!ld$2BM5pm+t%)W8Tu1OdP_(Kw#GP@xE5)Em1?D8mJOxs@c zG-UP-D!Qrwq#w!b(t#mDZbGCja%OfV5E-X5Wgg1xOILP{C$dmrpP2_UyE2sa2>`XW zx3v61L^ghA-^6m|!fN6h0<+3S{&|A#@L_9Kn072pTsQu3TiNhXJ~z9mtOhU=-_{8&rz<$Dom`)G~_A^ z^B@4e!kt);(BI0Pdoxd9Qr}rV8SD1TE_FiDrz&#|tfjki>emMIX{SMQNX^gm0!%-obD7(Wdw~tKuC?LYjR%TSSf} z3S;sxOxg;5fqh{wH8F{&=qpe@oTj9#ajykKd&qe028_tW)+d$b<;2SDjfBG@zAf1d zjv3d$H}4^$?vgfsgS6;Li8P%gcK@38UNsB5kBiSP+HtcCIg#CmG43Vv-9bjo-llG*c>4c|Kx z1zY~21X&4NiS?(wqsocM3p{inKU<;5I;7U#fCIsOsG1s?l&>VB>$%G;J|V0o`wB*3 z5(M_#js=@3a0%67C9Bc5PFGTwsiEKb zT#It6L>Gcxm%zv$#oJ4iK>dXb2@(4*QMN7xr087EYgpepLusrKX)}rSo!Yz@B0V*v z9bRVKu}*Z$k5?zyGFa^!`G69*f`zUpc@7_$Bac|sbKAqDyUCDDt_4@^A0l3B!`5DYEJMubO>?k7EEp_8%M6`e8$Gl2F>(;J1 z&QW^5F0zQoz6zKFhF%t-q{bU}duvLS4)`4;TO)Xi?B(d*1`HVT~h%gY`-9Sbvy{mc}YsSQlR|7T@za zCeN+>fk?K);Z-$4X|dITs#TL=FaBHq0&aSKpBkhY8r(?KJeF8Bq7C)p1dE)*BYnbR`=qVkco- z|6EPPf4+p?i{&?TMD$+h!hYwC{z=j9Nm|#W7{?^QWn1=dk`Uj%RF6E<`q%y^e4OG; zYvF-N$e{9jj*BjjPiAowFLjS(fZ+`gVa&tll%_Ie?0X5ZX>mjv)8pi47VqPyD(ISx z%Gh>=eUmaa-QQ&!b8-)G(AEQ^3y4TMkax=4u03k0Z1c85XR15_?4oiUTW4!z9fDxRXWIPYH~-d6bl$q;L}PBNY+Gk%`+-=*=^T z;G3$a@P_PlSed8o&lBs-*Tb|#d{svza?Zn2_iXh%=#9Jo0UgVnuL6Z&|IM-+)hs#}?lf)${XBnXN9H zja}xL^owQEudwSxRVu7O+Z!O!_iVoh!eZZakcZBNy5C>@xS8keIZ`sTnDX6`M6AJ% zQKL!GliHVY3B*q!%Z#%SC0kg}-w|kGQduTxhoPRKLMh++vU<~wBx41_UmV4l)|%oa z%T6(il!MXXj*mrylPE+D4gOyc&Oo$kU{ZkNV#VX|p+JmD5dMPuqa*t#DIUiUfpz^C zE98zI=AIP#I2z@DLr&@zSf=v0C=_^}f29BW@PXU1XMy8mI1;V72S);vhL+6WUbzOZnQ0=|8-5)hsB`k`@kO|m*b-^D1;hEv$&OtOh*Gddc}zD&~Sis1wYHy!vGmXLSYG)vYy3H(c6)`CYc8xqYS= zl|_ZT$!+|MgodEY{F{8|4r|Hb^_a)kCb61g3L`AthY6{Nd`j=KDm^}YW}TumxR=%J zrRIZ9y9d1(=p0RZ^(G>@Hv3zzL*ow@hl_Y}y|gWT z4j%bNQHSudNEbe3_`LL+oUD)X_Au1F&kqpmt|OyBL%(cp=Cj%_(2>o}J{^2ET2GGm z9ZBYbam0G+L#nImMX1=EuLUH?KE^x~c z<*&8zcf%r`w)VVw*1PJ&gKAId-(V_DQA3EdaYfcUM5u#f#?wcveNChI#By{3R#k0! z&(9YO^=0^>fSMg9Vx4i634)yF74j5@r5yF_Q&Ovm)pV4DxsDyp!sorC8XXB5d1D_U zFo-Y@g1mT@uucQ1sA+go)ztVTf&hR!hX0t}rdOSA*Sn*Ys$Tap47Ey3tog@cU=1}c zv-5P>Qwryq@QVGg!_~yP_1K$OD%;C)sFAHtD=$mh#@jAiJ4@9^p)To~qoMMQe}(vs zZvgR*udA_bwyrHzgW5Klvx|2LT|x3e0l(!PU@1K7w&sOs=Rh+so*^R-T&y$9`7V^m z;}KyIKk~AK$XE!FFphcSJ=Am}jp&ccakvA{eA+f1-l|k;N8WoRz$7336UblQc%R!I zVcWvJPyCLzErEzK;hk@N13i)>8f1wI80M17!+=f#ngtlRRs+nb%9T$$S_Q8mbn2~< z!DI+C==7d{k59=Oebfn^@lYKuzZHkLvhaNyH~Z`mQa%=&kfVE{YH8p~;TU|c8mklT z5K%s?P54|R5rv9~G*mQVEH&l1MqdZwe^U2}#^dTH6+ER16wHvnOmC9KL@%U- zz-X=Sy&drsm}7`TnU$67KKJN1nCreK1y(RsekmvKzLye0zrnRX5V>lqA}hy+c~}+B zd9_|nuE^P~KewrSfH2V+-PiCrzxxUi|Fo78#QVVDE2(}CQ()D#G=f+E^mN5EYi|cd z{ZaFs{aR~#S2s$8M-b~@EgR5`verU;zTesebbU`Qv95D*MEJTZRZm2#D1d9;-bIB~#*v8ru4gm{&M`(Q0^SUMi8eLr*H(_}an=U2RHNpupY^uuZLklK_Q6iqJ6`cxQEvMl+OHW8RG(Lws%i z{ze4miEI=Vj@E*zv`!rn4TPSBdd=A_TN8@Yy%` zm!yG)7>>iO0djCnnB;kr2a1#`RG%m>N_P4y}a5oe;kyQ${5vU>h2u&%a(46;u$ z&}hm8akdlbfS=gCoGNSKT`Vm*6O6@hTO zag}^t8*EhBQAgWYPV?IC-xiE@POQJ4oR1F7YTJy@i)|?a=T}yKJ16&twz5YdaX?Wrlk38G3L9=I%ct!L1>t36Sm{n*;s z&P8b7YL62WQEKG}#Oi-4atNVzm2LT}<(5!>j}Z6*QuvHw`jzoM)4=&pharGwq$5V* zKz(+EJL>t6xFC8i!ds;&aN9N|+idTwo5pucEdzQzOEu zUY^w!+*@V3sx(81Fue)FdzJb?8TY1r}2$S5H-uKNS8%eL{znW0C^^Z}=lRi*(THD?WKua#Xrv^-PKBO(E>no-Cc;78z{rx=v`l9;TkeL0^ zbVE>;i-MB6Q_wI5U5=2O^TFC~t|fk7zL@>B670x2y)zVGz?V^`*~*3>HZB0C$0HUz zUtU+Ij?!B$X} z9gNAPf&R6x1Yts0d4$@xhS5Hsfw0Uqh*sFQ#<)3yV@lbcO^=VkHMnn$XXE2-<3?*n zS2Frn)-@F3nazuiXaE+u*I+(}z2|NsB+;!IO3B;xMwVFL?i#fKa1PYSSCT(aQa%l1 zvflv%Feihebz{I8aI3r_h{*P>)Isa;H8pRkc}fZRPqhw%4)OHyf18E3e0bfDh&9a}xe{3B+#i&j_=yjWhjDJYv<17uDO#N}UW8qD+z-kg zS@o9q;T?j8@LOc7;o>H^a zNQRgW36t(CnV*yhthJtXM-;(+EVS?B@MGuP46GoFwt|gX0zGszcI*!UTOB8&-?g4% zA{^E_sB~jj82&S0>9bpY1OTX=one0fjG+|V`7T~H3y&S~KF3b#*U<=Sd_SiArJ=5a zcOBX{j1x0#h>rVB>6wsW8?IiWeFMi!4y!#G867elHfCf{eqFCCZ6_R?yKIM9W2N>P z89YES%@Sui5o@*SIBz@Yh@fmoSnbQ&7iDO?Mg(t?SmObJsCgG^##AS(Wwm$?tu*Fj z*yeOn<#PM)N^NciJWY?3&YX-6vHcIF7T+TKpGxPX44iF^R%$0@6y_`4q7W)C_QxUS zgGAK6IApr41i({nNb6rp``=2((>&wXT3piEB`l8cEu5t+euoFgiL`$t$9mYPIeG&R zbYTBSXaYV_79_5PH7QB0d~8IV6bbJo?`9%(yOIoQBA1 zgc;Sic1qx#*|HiRdiQHY+O)7f343-SZFAZhU@irvH)e17v$3$z&{)>&leEsN{a^@Q zRXy#*K3OZ4(TiKA?+)MQ-n`tY0|zZ*goh5=e|sTFbgQ+;UrY8hG_9&m3&jnGd6bZ3i0* zTBWojILNaow(VfVj>ZM%!}Z5;W~A)c^{WTnvMBfTQ0GqT!)`62t5_)lkA3O3AWDBS zO=LOZJ*neIK1c#>E}avrvGH6{GMJ1PjyEC%oXu(r!nLsP(gY`UK9oN4fn7|yH3CO? zkQ1~&mPk6I&6=1VAId^RGZBG`Ryd2WC@fJjs-XQi7UoA-&T(UiBo1eZ(s!z-5Rb$0 z@0SsIh;b$nBZ9Z-`~@^&{jUN7WJH!6H!hAhg*9PA6xXVWtZ^m%)@ zz!L)a&2%v&(4&Z@1a}Yi1<=&YKaO8RMp5I%$nk%>133$pio7Pf5ZvNYl zW!Zjd5k9?_^q6LUZHa)+YC{5R+@+GRADUvZ_S=@@do6yPC1=TF12xp29NXAtX$mqW9#CBvUwJm8fqQPt(E>Mi*J z9CVZq`}jZ9DetFg zyWvwdcMQJS+_9c@#7aI44cC^9cjTra#*ZD9i#Zj8aK+;rel>z#>>mb$Kz%deE`Nqt zJ3b66cXHU^RXi`JKQ|Y6mqQ!WpPR=4U%8V#E63aJ;#B@X?i3Cl%LV!(E`ZCtutS6? zblXaxkw?b+c$V^wOZf3nzjhT7-}4zn>IgNgRNk@#u3EVyW=d`>_7`QLLJXh=$D*!^Vp z?f;%-&At-B5sUzTK4@9LXj!4&NyXer}DUIn)<&dg$bHL(UVs{8|Y5{ z^Jf1HOc(S2{Sa#0qS=m^09SX`#U?17ed^g*GcQE*hGcbi)?l@~yU?YL!d^>DO-sxA zi>J9>Xf-%+A@`g$);3~2EK;aRtC)!e#;6aCs@IPv{WDBG~Rw)91V zCQS2lF%)1CebI}E=-~nkCO(FU#k__XkYk>dBgZ^k_#YAf_${7l3ZZ-WgQA7~F^Yli zS?IvroxLQ8o!>?Qk3rUHN@)__j(@I>yzI=mmbI%0OIn&*cYtfj;L`*LfC z5=!mRMq*b2Q7K}FIkNLkdan!+ae;>CPpAS0pOS*k(-jc1JT-S{>u7W&@d}~>7~IVu zp#)bvbEOHvk!z`^J;TR$?;~PsT%njQ(jMv6a?0D5-=Vcyuk;U@fNV0B`ZJ~zUw zbmT_Xfw%0OG*nfuGPAit3&vwxNba!Rb(qHJT#+T0kNE@AAwY~2u||BX!sW;yv}Sx9 z21?2riM>(y8=XJK?8(X}{;_E=b^dq#+6Y@dDRWgk^}wHuM|+O}Dk-hGdsMh09~rk82o!C7#+LbpD-= z*Yx0Anp>{}Q*9V@>(e`XB-w8Lc+a1}DL)A-hnGYcc^B7Y4d}D6s2!TX0ll7E-TFz! z-*N5{&gBg1bFs1=nxH{_9=F8xlM$gSjO4nI&+4b33l2>%s|O!4Eh}*T49;d+GR>mL zvNO%c;t|iZhtRg!6?!d?Rs=aTiVmUnA(qPQS>-N$AugI;aBAVx z#&6Oc`ql6fW;}zAV8w`0Bt{eA1pS*(!wjqm+=58bKuNsFd7Wpx#?zF>?1#B=L(zdOg?It}>_l>M3=))&FR@0=~OIi4D$QLH8HHrx@zvE(md5dSLwPFJc|`c}Rfs zlXTX`)7ZS~;gc#5ernD8oW=Vue7=$))X|Jq+-C#YYI7y<+>R@qr&)*dM$7T+lcz*R zxAlpu8u&uC7CVT(1y4Oe@|%lKcb`v!B3}#Acfb;UXMbIX1rz6qQOavt#4nC4F+@C zI$QhhBVfr}XCJ%DH-1B`-(4?+tIo7j;<@F`dIyR7eQ7indfieem35fXx>7BSv26xo zUHruef8tNB!worwlIQ)6*4BS94}P7&FH+FLxElb>t#fWHhmbT&%8*_5!Hq3oE-wq< zXo15d3?7U|eq$hYDy>1g;F0`Pu{@abqj*+4>M5iTfJvC;+7&n=cP@WqkD{xNYw@k4 zFCBN5KC-9NuJ;2xMuaTMjYgnUn?pUzxUUG~<1e*yDYqA`ef$;YL|V-D%_Fo+pqXvo zoM<#~U&$WO#rDl<#>Zb7p2gf=mUgk#b8~~7_--%SMEtiG9U)fZmmEg2X zAl!X^u=p1*qE?7>db3a4A!oL?_j}lV4=FjEqu(G?R0TfkL#&^EsTDZqTmSxY=42v0 zu^JcwqWhT3GB!%zrb!ah7f&}F>xHX9l%U||HK_1xeJF2?K~!XrEHOx_eX#oZ z?SY=Lk4nRH>{E!<@>M*1IIQ_u=VBt;Dn4+P55UEG`73}@)__|JVA3Ui=gnw3@{XVq zzAs^D8V_!F!fk!+{ViD_j^>@n5#&w4QLXOZd$P)#UWcuP2uCA!asyRA?WrJ&PyjfgnnNiA|l17@5c)2feo&ARPZTL^D#+M5W@%pyJy!K*JHoaI>9jD`d;!EHuiw0!I&f2hROj zJnB23O;F<<-obN!7mvP+enb)LrrVtEP&xK8UQu}nx3}63brwJW4Q@3O;rds-u5-T@ zzwkA>mjuAS%IiKiP`qUTyNj^9-CKO5URhp`?r4|opDHN9}D93XSpDDprV-eahpv@uDi#W{MWY0B- z>VkTwQ~_#U;I?gP5KwaPzIK39U^m-K;{*j7%=j^3zgH8LX_`sjv4|_!7D_P%&g#go zhasExi&X%AzfOl1Fj2OKnGApt`%(^zhdLV>y*-*_9>K_WE+ z?C$$!IDq=k=bC+L3YFC>fWD<7ET$otL8|k`M~%U(Cb$aF|4&bM2<`J}R&$DoZXz6E zq$fNF1{b>!kK`#Da9JR3BO*PkIgRUDi|7Vfn;Zdom{NPP=V$M9S?@j~KmTmu)3kjJ zO-XAAk9OG`tUEmu5m|C_KHLM4@T@jva1xa8Z5lnXe(8w@J2TxM0gmu1!n`x&+V8v_ z#HzeA5h%>QWd7Biw`&wvuKe0RNzk*i-`>#Kv%x*dr)v#ex6d+3Xx@i+Sf9T$JQ)2; zMh1L`z_0;v;RShB#l(8@&J-+n{|mucQtAZ$*$$X%P^rD%3yXmE`|aY5@U?cdD{#p z06aI{9SS3zRip{%t&-mNiS?7a#*wg_{Shl6HVOM)q8t1!3(T_CS;|r=p?;inH@x%b z&Od+o9p!?*;IlmdWlO&sR!(F)mOt(J_`8JKs zqS3f6B~`B^(jz0rKvVi2$olnwmuO1Z;9FMCQ@DpShl3L+aqj^l&js)|pPoytq&SyK zmF}`gm6N&$l5>%J6~kez)YHbl5OcWJUe2u@z1xR<`)^86krR-3j@7;v(IM*tY9Cw|Me8h=0@pTzXO{|h?%cDiCx zpy>@o((4NJfQTXyj+%ww-ObP!%ea6E1>zfxn{rgHGB>MB&_m`D`9y z7LCv8a11lm^}3>sJ9;lny8#)lZNa!xyI$9IOKGp-iil_;Id|W)I(s$kDo1?!I-M&< zV1I@7l!2@$m9Y$R*fZSLu+{WZy$0yx8=wI2uvfNL^l` zv)@s)zD65Y=-h94?RSaz$-@xH%XRj>bPT(ipJ0fcuI6og3AE{n93LH^l!h{ zskTb)F`#=^y-=4Y%AwcfHJ6oNzbyt1*{f^sTr;)50 zy|qJNd{Q@n_Kpf?tViwvyOMY%JUEWg4K~UL8LqUH??w-0raZW2b^TF7`XAmj#GcWf z8M>=u?@sFVJGKk-ou{2n@Izef5#~z}RHQ#Qjg89$P`q(oD{CuhyloNs z+ii5M)bACUSz6G_#zCL^>RC=9^knGpem0H=*YI7GGx>0h{UE*N(^lxaOWOXzq&w5C z-`}5=1@7XU?AaT}Wwdhy-g-^Z_7_LP$-17_tG7)~n!=-95(OJK^d16JhsdcZw*A)K zv!RK@I^A!5{-@zF1{-Y#&on>6>@TE-Ya6|WBRB&4VUZb`&SmR>qt?x^Uit|cR$`^Y z_MWXiz>?#Sl1Bo!&D;4wC!oY>eXl6GDEjv6pexUi!GxAhZ@`0JoqyC2(bvAJTQ>u) ze3gC8Zf`&bR^udEsMXmUp$YMD-|O(bsBp{^rE^O_sBkleQuF|>yB~1NI4?>((%>DAi^z1up0OdIrwea1BGB42t?O;t6$3yuq>pO^t?QQve;X+fzwWg+(LIJf3PPFP z`5f1Xw{T$#Zt2Tb;PrG*S>Nj*^%wEv+&(-cL4|Yu0YSRTDlb~(;KrQ?4$Q_`^B$_7 zK&Z|hWQ{|G&GOd)>UO;CZEd053ciz1f=$!h42AbQ5zw+V3{wHoukzy>glZXEhvg#I zXh!QRiasJjB95t0LNumAk4hF)?XfugcPrw@r-P9ADEf; zAM2>Wp|A|L6}U&WtVQ&%{=#h{`eTFjsX-bdWZN?w1lb?2fSZs=4OW28)>*y*sVOYY8w)lhW?P&w~g-i6P_43!OaM` ziOMI`wsD@jX+24pE?Eu=6D{%FNi(cdl(o_(8-j$3<7zm{`yDp=DyV-Sy2t;}m4;X@uH8u3D{)PC> z>0Rv}(MN*kS3c{V?vFW4Mkoy`0wWZ{lnfRnG8a+lEjj8bc4sbvON;aEm@hXI$l22$ z{SpZg%L4AI3w;L?b4o)ER^YQ_C_7c#MvG@ae>I`Fn03gnBQXo67u`4f+`U)aBRDzv zyyfk$z|^8syx$e3E<-HJ&UiekYB5BM+Icz+S{wdt`I93yC13kCJ$YFeWKGwHy)#x@Te}p6R8n6?Kw>M+$Is*XSJmDJS1V;XTAjsW@bhYLqfOD z&>ka0@!6DyfiO$k3fZ_}4Sk?Hr!1_e@2ZKC-Sfd2y&)Jh2WXx0rSkQRJlM9w+E7!G zqxKB3=Kco9m~>mxsJu&%h=&w58oW1qzhaZ5&`z&AKMi0l&n&e>*IBs5ZcTG&L(v=T z+v+gdNK-~@3~$mL2rH^9sOvo4>EiC{@Zo}Z z?b~RRlSn0_OP8>54Cv}NuG))f1SngYj(Xk`HV4G;-kHdK7Bow+OHGIDKnvNpiI&n*+^>znQFnA53LlD0 zLralpJgy6ZdhU`~9=fbq(mf65krs-WxcN{y*!kc9EG}2=Hg~edP~#5kiQmVenY)4; zk+E3?Z_+LaOjX%2%m7%85MkA*48;RG2U92FJx?H=N@C(R*5cCA8ba-P!UM9aBH%~h zdE5$oiTGBn%O$~ko?!mFV`dWZ+cWEV;>Tqr&fJWZZBk2l~wLs12US6 z6+Rxg%3SAaj)KbGL>C%vgNWMf2;zw`-uV~U1Q;+Du$yDU$SJRaL&Pj2ve6{elwC@~ zicQ%@l3>bSLWY^LOVX|u_WKF&oC6a`aMi4*(s~STN^l^91XWG)EKCD$`uyMOQ&;=? zZ~FI-97|E|=>k-V5pp>Tpa?%IY=GuJJWO{1s`>+ENJN#z=n^#ue4pyVds7Fvj|cZV z2aMtUG{5sA5zeK;t{_niS0K&EyxFJ%AyIyKo?ENJJc6@kyYPqeiK;72yDbQuG;acj zmZpNWRF*lk5k!taJCKo!NTVZ(FaG4v@hB2lzBASVQbQgVvgQ#~5j6~$)OZJ69MI-* zz&C1n2^ji(w-(ye&Q;4x@IGpIhxjt^$Q=__Tb3Ju!7xNN6&wCLXDvrU9nyzz;(hHW)-LO4~Yu#8&y@zAE1i0h)rbM|zmCS~`9sts}znRUvF#DiJvXZ`s%141Zh{U-6Tii%vyxf85YYkxM4HsJaWcOyk&T^A`R_(h<<8j$Hg%mMQYSwa zs&0TM%6jH6F1fZ2;Y;18z4X`jVEmpUlEBK7UTj??5`Qtc`29F=XAcOUg_^(~o`qQ) z=NKNx#s%AK>xs1GNp9^|6&={g1tPXXzlB+1`uh2ZAK0k%*y@oH(Urt)bk{mXgRHvW z6&}NmSc6m`QN0fm7%obtu_IO^Gs(K>?@T_zGXF-4#Oxc2gjrxFya24Z5#WV|Rz>zJ z3fjjHOPD>pIa}&-kYGNT9^WM2v@3AvSq|woG5(hf5mBGegf`U4Hiarq;ptKpMn8igOtY+hoWEW}{ zJB+=UE+QY&2eyJV8p|jCj+J=-z=&;hnopWfQB)8mtXArC1w~k2_@ysYj`~=%L^}n~ zsHXLrJi!ueFT6oT+P*O#!+{t7Z1o0Q%tk${&lf@fH><7ezpD{$|MLp#;J=e8t`@B@ z0bdDlj^}#gF|ov(32@zX``Ok>NX}=YCQ^%t#J$!Rlr+URVE z!uRNS1WY^M4@XR&yiRD~DH?s*m~32usXw;)971Ee+_e3Dx(8JYJ9~F~I>Q@*4w*h6 z5=}S8?mWiMQ-LGKzmON?`Kp%U^JDp>7O4QJU@1)BsH&&pUZi68U&E}pY%f#OEFVMj zj6WuEOeuFvdFfQW!`SD-@|RjJL_c?wNJ6UWTah|wqp4ArkEQO9{T-{vS}vryp)QVv zu!(j|skm6*BLoAf^J5b>y5a+fZ;!eQrTSWXXsSB<0aZIeYzD1Xs7~ z66$t^w)Wyv-Fg|RcC8=MZE`Bym7t__ggRYz;5@0FDd5lJl(Xx;)a{Sx{^6*Dj_OX5 zmrJ{@&=^_c{?rC&xY{<^mR_s~_aP1f@zkd_aGrSzm5PJvQrkr8)9Pj}iV1^R?81oPyZ}r3D+?S_{UW3>H*g_Yzuk^KmB0$LK*g z%8z{laH8;2QajOy47eW)7fg>6wKu z@^KmNx<-7n54g5;QP{ z5>g!CILG=ehI`khBrp&0 zb)Yls*%@CzgLtxk-4R|@cEFO|i}(&Dg1-|%jdwSeZ+SeFrkj~@x7chVcvzNbi zJsYcA8_j)aH{(&*L;(sd9srqxmIeWf6ux=3_ zufa=NZ$M7Jv>q{htA8Nk(<=%wRLJPL32el4V|jtS^-B`wYnr*GH{hM!E*0-VPT(wz zAhLWVTMJ3;10g?j1raUtJOg+y+0H9M)dgY6SI~ofL6i?r^NfwXMf_ggaGUsT&l>;% zvW()^oWL{r0Y|vdIO*0o8UCH`bG7qq{ec7aP8i?=$X*t+XHxs$2FBJBY)q~6<2kyd zHd4D*#8=NJl7{jnsd1)058YGa>IyyeZkxOWaiMcDv#3Uafdwt^4OpBC@^5kydC6V6 z?+%^S&4&h2@-2~;d^;5VVUe37(wGK9zDNEXVA0wM}Mo34Aw`|P*iKff}OKn#)ffM)@nt%qMS*V&I z3}|twvxIoqRQ!GmALy1i8H`|g3#^qC?c`LXmu{n7-Ea4}pb*WYMCMRZ3yxnknqEh}cHRP&n zZRh%umi1`P!cV=L$ngHk*^D=_bC^3xXAWFV_-c)S4UoZYj8~v^(hYDp_*9R2Nv6P$`$`_{Y#cL z${kNR)lPF=mazV(X}%VX-;e`HnSV zjy0kEYeFn*=)v+eDxNBf3VJX;klNNsc%3CB>x#}VN0#R~xrGclh$0t!@4HFn& zND0h_5;t=`PE>M5ad^6%^6x35hNyc3Die67M|2%?`%n7eU$p%X`oTXo+cDd%d$zW) zifWr#TIYM$zd`nBh`i~+X;yy!K|Ra!&w7--dv|#&PnLzNRrR}TnB8^kTCWWP)jx}f z0tZHCx3shlj@IJ})#-irTUwbGGkfbhMs>fUqV?8oMrE!rF+05xX%GHjRNe;O>DMD5V7oL}Aj@oSw+_`P%_Q8BnzmS(YRCecI2}N~&_(V5;b>?Q&?wf(v zKfV6Bd%Dnpv%_R}yb{WH_nS{t@^}{9-W0XFDX_`ebi^`M1T3~85T;HW-z=plbKOlb zOofEms!~h$t>SCn&qJE%zInUGtO?Mp30$%!=-S!AHK=k+U910h$9)SzkZosnyi`A9 z$6FTLKlN)^+ld`dMflc#$lBiD@rK1#Ygwb99_{$jVso&zPuMj|u^FUS8Aqi1lWTot z{HTfG1Gf^fJPv9A7+!^1m6B*;)NwZGxgW3J^7C{76_gcq5cwc;#~kKRgE3K7byO!2 zXWfQVDW`Uoj31FtB(IGE2mFUnyCVQWaP=^~|5Fc>7XqZ|m@=*GMgB;i#1xxZP<_=A z!fWM+fEVqWXM8j+VPk`;3!y+L-Adj76L8fJ8K6*aI*BmYrQltC*h5|L!wYIAqQyP8@j~#v zCUrYyv;9KJwO@~G=xXchxqbB^?j2+T6E-G5P$V>Qfv~0*?jso#rGy3D*Sv9sD5GZQ z!D_OuNAZJc@nt##Dq$@22_e+0nZ?ld{13cC0nys?SU!kZIfsycF%HwWapRsl8t}i# z8jbbLp)odyx&*P1$0~UxW_3lyFL3H>YgdFpGy2?njnxjkIDhe567(-1CmZzr-+Monb5`UiWqd^}LIj<}!?KY3hW1DZr00&+o*c(A8H3FD0VchlnV>3l zGifNcj=9d!8^&r3$wh|LlHSh#oBV|P3El)VYseThj2|$h_Zub@S3fYkp`hkdVKFXd z`T&y#T!3;LM)e!CRK%_Ofdht!mNV9teO8NM+#r*7W?1dp{(L3y$QtBA)GY*6{VvtM zHE!K`0ra_?*gc=?nY7wl{`{%s<5Z=~>rT<q$;OpN&vuE9fbEAd_6V!|B;^{IUho7dLZNk1Qa_zyweG+sF+t*C!OT);d0 zmk@lhUf^I-dcUW9U5pmJR#jEBtall-3B5(13i>a{RcRcIt}5qtaR~|KM9N zWAGzI!A1)+mSvLrnN&=wsuX%ee1W;3-eMRFn(Q~E7E?cnBX|}jjql z>2$lG93#11CA;$%$DQ{R$!@<6-*z-&q=gxAvPsG^3EPhf#MitxP_6@ID6+X-O~hVg9o4jxQC zlIh1X(Y>22%qUP3eeJV#OnF#Q7nVdCC4O#SWSitbLXY;YsGk`#$Rw@0xym~*ljok! zQ#+yooaf4_vq*$1g;>NojGJU(C+vepaAzXInPi_+SL0?uh z`{w=T<*NQX!#N44AV|#;4J#j;n7DqU^%rP|A1%Y$+R_D%HokUx5T}Al4uvceK_{og zdT#CfyAmu$$A`zkcjqVk4wnG+Ou>Y&`{!OGP7jb<5VzV z3K7!x99^MiiK|P^#s#9%!Kwp#O6;(8;*hPA$m4zh+d~pXB9X??>%>J}>Lp#ZcY^rC zGNz7mJmC*7P``~gXzLk#!oPnFFh5?K_%2GQYMqmDdPpAfA>hb~9)c7F(cxTVxRgF*ntbWYU-a`xZcadtSxStNd8&p2ls9Mf=ziV$QwkXZ}_kchq+1FsVjqX3g& zaBw2X^TarkF8+G)6XPh_z7u!5W+g!(HWrP;{IP3MTMD0;Km;Gz;#~SAcMq z^UZ?u7|#m}dW1wZzY1QK{rJ0tzb|@xNcjALrvpgPf`O+4NzlT9rxhe*@Y=wE+y5DGs$s|wK=0;p;RW9(bC2EUn5wFW<$ zP_<_0V{l*?sT~{2AC9i>;%o-bqZAi|>|ixaeU!)!nC1ht%JUnM2O-i6gy#G;B~4N? zR^7}6-ov-v=EG6nFBtKFHXm4s#-CHh9Q77#bTh#PIp-CE%3EH{@(7jZVM@(4#qHlP z_@_~LYnHu6!TDToYH#@2ok}7q-?upsUfbRE#%=)`Ed`EMw_%-)S2#(5sjXGCwAP$2~7OlW;pK#K_$OCvp9`n*y>b`NyKpqfWL9tYbm7mUKn4k{w!tPc|Pr*i7W=>12=KDpi#|P&~Y*=z2gWO#-k;B)|K* zG<6Opy1lFTqS(#E(itQ5M0Dh7`p^hUP}DW+!LmT`Ua><#Bpt(RZ%4wm<;h}Rl~DUn z4il8VDM7f+j+8t;yf*@mxi(-ZKN60cs#&Ag5y|b zkoBS>To90xpg~R;sa#zPFAGywjf~V~0%(4_m5Rm{peI+xbO$Mq*f(aD{ zoNT^xHK~1N7(ae0k^U^__rLu&k(_;IMM^)Tp-1wYg)SxvZTSK}qY3x!k5Bb8@$@}D zehm%1G(!i_vTMIcyI z4>fJmky@hWquQB2yM&W3685719P}6P8f0?RoRkD;2Jr(-TyGUxM^RI6a=HoZrf*+6 z1&d+iAQO)`n*(nm+GTVr;!-nR3G3h}EJ~>ygWqB0*++(SRVn(a@lxJ3;M$mV_l#L7 zdBZvPl0Tb^`4MlMW6_A~%$w?OliDbT&!9TkRuMDQp{Z+pXo-L6$0@|Ga>ixhO-!|m zfpk_h!$LCMdfpHzMouDTF_HvtEeOa9fmWvK5V{#HH3c2r_JoFJu}DjaH^-(16Nx)Q_!9 z&*EOjQ`Qqr#+CDiHFme&<&d<%K7Hd8uy4hxLn`lceWM77`XQAOTLM7b0@c5IptvhK z?UpBh-o4k|+H%7^1q9zSMSW8&Tc7-O_kQ>xV_S7J~ z|K#S~lie30_{cdxz-t~ZWC4=q5?==DoVbvCG0*^kIkA|s|HKlc!-%$$@gdFn$}G3C zVx5$VZp~s-;`*)VTLq9=w+cX_*#08I*j4m6o&sHrz&?G43)Of(#x(gB2F0yH=P_>c z1?qdN(CE^`O<`^ocEjAuXr_K!3tR0|)}2uBbH2g)ci?f|nrXx(%`d^#%zp((Cs{(n zQrIK63Z$!S^NIR#$Oc1s=@JDExHZ$;glBqtE){+`$lHjM+ye2Tz5r2l(*PW(@GKR7 zJ+lBJdC03&cma(+Ow4PTdZ-K)P`PwDdaoJeA;1GtRBKkbm1D>dlX`^$Ko%93 z%cs7Vfw#u``L8^vGVWnl4k0KB=-09Ah6pD8+eM5&4tOIV|B&jNu8VviW=2*YpN0vf znX+yoi<$F5%D%-05D|rli-Trpj!V3Pz`T6ci@P4ufN$5V1UUBXno{cT46+@lbs)I? z?HWwbH&yKi?ygeYkUUwf;2o1aJ`EvTwL$x~KKx@>1jCgm8gNUka_)d^9XOOIIi~8# z#cQyd{m`~S>f(Yb=tpyvN^h0I&dlFjiYpLtJ?<=sESlrs3SE5#_x%ncX5=BL^J<-^h-I|!9Th2Hgqpcsd$d%eQ;8Nre4{@zV`aQb>?w`{=mL4%qW_GfJ!J$n@e{-xfH z__k}_MgWFC^GB2>3htZmbjQ9y12*TBaW9)N8*^p~bZ;sc@qB{m3(S&=u53U#aZHV~ z%ri{Ua_4Hj16uftsZ@OPO_gz#K0X^E7rylzDow6ElSRc>Lam6mtr(#|JZ0sFWuf^b(c%mTD3R0h*34*)vMpBZ%R4=&0bMVX_#`TlbLe5{R{O) zpDAgHz~D@tG88Af6wfZL0>YpgipsXu_jDcQke4`RqonA!)-WszRTJ+9D*}ik! z-X}19V8l?#JvE+?bFy9}=HZU0sAZ{) zmuEWVLwvz=|D6C);b`aEprK43sOC{YQo7z<*H76OnQUn3fQU6%>cjPA4?&+7eWqLv z{`)YH)Qfs0OpU!pk$SY9`hJ!J8@Tcl#ooyTnR@!2O;xc!I6qy;1O@gZ^=C0zzMqGvYf74_2Jx5I*+e*}P1lzLm{lFM~ zw^iZZ$(`64t@qf{F+WKZoD%czr2xWATw@5+Z0u`VspkHDhf0-3m7e;&$hqT#%k|x# z%H4Hv_>yr&oTG-Y_DO$lq`o95kopB-Cnre3HPPsV34)}*GhC0MK^D%1Wtmh!!%+5q zqEV^$9324S0l^(<75eVo3eSFU4zQd}D?|0&tiru76xXK>(RbG?+zkpUO$pL>?@_q# zq2`J-MaDUf@HvnPEjIZesyj~I22klT>i^2$|JXhpkFYsPCa$2t%lsI=W>E#h7oqsx@-L`l zxp`4V#JYNtdQMuqv%P4;6WH=R9v6m}dYmtYVY>GMrLv&<6Y_vC1i571MQb|1CuBMV`y#1C+vPdJFp2m?RM3p;pJXcT$ z-|0+4jh{$=1c4rW{ZkYS6U|jBTF_^IYS45DVamXP*BKpDumJucysbN5S5RRZ*m?Nl z-UHI!r=qmTURc7yH2b_b3V(F@}f+p};SXv1@Xi1BYr3$wu@G0DQXLxDE9 zV6X`HHyFp-!oH>_#Tcy5^#pmzY{4+H9&eY15&c-qdx237!&B8{0<;y1t$|?s4Hs)e zu&HixY1xARBXl05Wrv*Nt+NUmh;)3 z;Uvj_ZrXfFn^<)~W}M6Vzd$0Dn3uw$SHDA9>FADiKu6QNK=v^IvymP50#WjvhuAsT zYcdtFGaqNkzIO5a^(o_zL5B(dj*6&?kFJP2CVB?PXU&ManeQoJfgVsWH5=S0R{O2JCzFAotQp16-tuvS(i)Zw{WHc0}CT?VXpFBZOF%HlL}0f!=)F=6nhD(u^;$ z^U}#c5IK{*;5a1DPRseFk5e0dVcHj|$WW9f`WaYcI%(6Sq*>LKt_yt*!{&$!9z(T5 zZE+d4pm>U*iV9vhZucg#ua6)%@mQvhBr100NHSD}OGhPF);1CoUdeWiB#Bs9Ceu9j z`N)2%Rm>W60QY-?TQ7=A!}F z%_&YZxD-A1$Kb2j>$oJ14`;Zv!Qk#!o_#Y7IvxtMvR$tJ1lC!ER*(jnv_w{Rt86O5 zZ&$l!^w{2fj2mbl>(a^~+EL#z1r)ZSWmyZ`7j_?4sJdpy-~Vv z(-ro+F(iBR}9z29ET0~q1aXP_;bgH>)g26_Ddp?4TVj_Q~cDuOi zn}m)|xFx&|`Xe>2l(HFPi5?{B_V89k0;4e`78|Bf-;n&4lhpsMNwZr{!7p5hR)_w9 zOIpt0b!AH%Ue~vL3S*(=EM^Sa1p`GCOA#lR?uGy3#=GN^jItNTlJQyqdFxSR^mQhW zvmyY+OL_;uc@?#fFn*tkU#akEFPl7$Gs^`Dqc{!uU1}LfnOB)r@o~twTDdZs3YW)m zsR*0N?NkE?mEL(1H=CzhWk^^EopTFRs{i4+B71WBH>uS3?r2z`=Y5PcN?j65OWrn}mQS8U@yJ-V>hX6rRDPuZ*ENHFq;W$#n=-Z-)jZi4Cb zYo|j>KU28kq4g^pB8`_*3)Q+F_3&PIdGF_8y@n}k-<3`hK2=XCJnx%IdAz4z2%Z|I zz-yS)aykTO#}BzXx`6ZQ<@55HfF1)(4AWI*%dU{tQRrC;hq@ybz=&Zy6@Qu2I;!kC zhdh6lYCliQ{mifH7h-tMr2;J&j4h)lm5L7fm7WeMz@cM7x{_+$xM}K}mw^Mdrvm@v zaw@M)rVNzOz)w?A54scqkaT?bL%RIZOVmHJze=3GTc?>u~h8QSq5XKy?rLGm9wbY7P(S^n!{Gk$mFshO)p8E z$h^Bp)JNfgs<=`5h$_u0+|yyyp;4VGra_g9JnFP|3`!HIo%qow z`KWTZUts|~8G(R2D!jRJxcp+g)va=mKuGK<%UUioW*00`5aXyf>b#!0`jJNx0AERLTy`CT32Pzm>zbWRo33SEuF* z8PUpY=*Px9o_AF$s)CouA7hVXE6$)E&WXTWw*DMtmrNi-z_K)5j5Zdt^%F=kMr!l$ zCgG|J8QW)B)x&W`F7=cMNT&%TrJM#?a<#@(je43xJ;9}p?@>==B5_ZDc3a}^xy^Aw zVD5u{pV<^x=TRUE&IGUB>)#n>@!Q^zk}gddE$x8gzBLPx#%=v@@5}fP&(H^+C?>IU zL8|8HpQ-8uWa3;@XbYuSnRR`@l|ewz|E+RHxu{v0KB+b$ z_aX8g^q&q%%|h_U^!eDPAdfl$Cr5bFlvcKb`rhFo|7@7Ed^&g5RKs-nGVa7krN1rA z`mm1^7{V{5(_tNq!vts=2P(xGDi}8fA7pT617vL)!(GiJ8e|%CN~4~R>}pw!Y$7Ly zgyuC~6y6ImW#jp*^Je2rS;q1Bc-`Sg+}%xm#C=};VIK`IH?PM$9;pSaXBvs)dB*|> zTBjY0ACEklWADRzM9={4m3^lpnrJr?=t zv+ol1eom)fqRbc5F4KU6f-dgm3T2aXi4p|&`W0VLc4{t}4Gr22*zZs-c@w`pJuPM) zXLbwEzM1M!>r^h4F*23Yr)piB&kgZSp%JNu1F!)PTgTL30eZuLeQsJ)| z1~NvNWeCG%UsH7Nhia^zPF7+T!yvY?` zF<)}&LtMo*_Ma(ayz~p5v+Vg)NgLl`TaQ{7pR?2QNUZF#PP^eb^O~brx@wX1h|qb7 ztvg^pom9LzmPsP3<9f%y*ZVH!Eo7~-}@iZYmnZ2auE zfV*J&CxZ=|MrL3N1k||9g(!Du&EnStrDh?cV?*8^O~)hP$J0pOqEk9otN`{=`)S#! zV+&8ipZB)vA~YqQQ;_YP@5Y$EoXausPw2opBP7+}mt~OH_bZAG0gWRWCE$RqG~oNf z_kN6C73XsW%>oM0c~sm>_v-3P8x851mbxW&CW2j&k7-BQ#(XlDp~BMRE`yY6SNc&l zu%Mq=U|x8y8`mOFg5s#`7>t*cEi}Ts@K-7fkQz7ZENBt}u7c?yV~#^19!b5uwa%eN zH=?B|VDL{q6em=eSqIx2-lgcFf*TK$PBer1$+!r0g|1^0az}7!qROS(a$U!cKIr5t z3k&uuu;9yG2EId!aL%|m31T;z9$$?H285|5BW9BX088UAi@+gqSkOF)qEbXC+I-ih=4ykH%oO0`YL`(3-s3&Vu_1H^fQbr;Dvgg?6E>J1BRvF z#o*L)8ATg@>#sE_Hb=K%RH!e8BnCqQXy7{@8$YApC(fTih7be0aR!+bk2)Rl*sD7$ ztp@qlyHvc#SH#7P@4)zlIqL7whPn(vl=&rs%Yt|`gAC$yw>gQG%_IY5km!%c;*yvM z)Uv#5xkuS?GvT#^WHFOy{quB%=LJ(VuUJ7FKRT0e$&}Z%F)kG(b*|3d3tUybowM0; zb#53$qdkl(CbAG+L`9XCBwXfdj?Vr)kXV>GLyQx2ISda^_?NIKNX-4Q+H4&pVoxH9 z4Y*Z%Et?P+WzXb*)*_XM3ccu3>d5~Qe(3<9x`Ab7@R}rA2v4aoj7@uyXkrw)?cLv8yAiN( zIaG|Q1{h#Ef^}IcW2lbHO7({5G!7nR-*}O%M+CAiN?Iu!BRS%mGOUv80G%>l(&TRQ zk$xa^K4xXJNhls~>}>L8q+P3mEhqP-SrJ%5S+ABN1pY2Y6qESoJeNd~z@2x!JL&&mMjQ z?BKZst>;8owpJHZkbXutk{O@(?~>M$6B5%|)()e_(#g|1kDc z+&+-XPA|BfQdW&-%7s+eJ}^I@`r%XYY2LRfkdhw(e>fFUXh3Zesqq`m9}a9EsJ)p& zW$gpK*HbtTEr|M!$1jBU27R4^Uf3;<72dB>Face*uZ&-T4e>W!TEH9CvcsRK)kr)}S z5%jpWm;2wv=9ka2v*j_nF6fQ08ejt*;iQi z-V<0H>Y9C)6(C(==*BI8vjy2_`c0u@Uz*oH6{>VD?$#q;G9n+gDy0SV&J>xph1+iC zwtckC-1bp!o9F!~r9%e!J{jJTsOpV(oJUYbQ+ot;HS3&*vFZH~o0Udnl1=d*!e)i> zPzrP}%;)ak6z%8Q7vlN+5q~-a;5Ga?-~W~y4yM@8E6RGA5O|H%JX|^`R<0O5=YV~X zf{A)?4Mb~usS`K$Gf&4kp_$Mp+5<3Z3tER~V7L7#Iyj+GlyN7yVs!Y#X-|O{iinjv z9_&bW{75vY9mUCu_o?_*q+ww%P9?pE`kt_YJ%iw=tF-S@X1Q@6CW!~|^YT5Y|49Qq z%D+cb|K-klWTA~TVC-XBLCm4z)&drn=8+C`sM7#Z&F^2ZU(N4__tF;-AZ{)-5Wr8> zBFcWSfaK_n>jHah0!Ct0>zai2cNKefgC4NT55?vDTuUpg7o{Q*=)q}V_Pj96630xj ztOxyE^)gYw?%z_*x;VoLfaV|%2L%kKlIE$ZUIPTl$74VbY%eL$BB5pgwxF|*R{c{?8w%C9?2jrlhEjBJpfw^Bi5Yf2enSkEU7B5KQc9@sK z@M%!nXyZ%xzHRiM3hi_-GzZeqw$a)-G`PU|VoJvY4JfM~bxcj9CQpDIM_kK@->$D~l-&*yJ4+cKIzU3{|mM5DlSx#D7Res?yOxBLnu2l{x^=r+G^8o&&q?BHS& z3jFEJ0uc7%w0exxnFY=?M6TKboG8vS00S6+>U-kk6hzA~E_rl7TL2KIl462txx$Y| zHx)jD0mzfIg}iVU>9)xNSzcIY--mqq}&Z5&s{Y8c#UUwKGY-(Aq5z{3;W zXrZRCHevh?J@tK;F_0_+XIi5-PaCvkHG_1S*AUU2oF zZrUK&v`zLYtu904_C}7u#GYG3GJ+o@8|$C739T_Eb4a9 zP4>S1Y(9>vPF06$)La#rwqeVqtCnMl4%6OA_U?Fw=Q2$DU9z_ZfOgxkUbSk9=BZkp zdhXfWmw&Q;9w|YHylog_hi$`JIA_gA`+IV39Y$@K(eiAz$)$bUVZi;Ke!2QtoSoyb z1mc^g$(-94=`DYf%kEU|XYM}@N?>5ON6Ce1O%{0Pg6x6LpJ8~n4a)~5 zPUw6Hmv4~vVX`X*BRI_X<}+7J_k7Bnc|*GiJ|8j!&%EKi2X}9<@!tQpk9Q;X;oLpv z2Dp1hZ~wvk$K#5fKO{TUNK4lKklctnh;)9R+-T>rd*IX!boSyO_>dV`C@FX0@eR`A zHO_elUk=vZfyeh9d)Y{`u_R0%@WFq&d#^O&_IAkgce&7PWPgZMe82Q2GIHCC=3Ry~ zf1b^bDj`MOv!Ag|)A0m`OqFvz`+f-t!)&+A5YPb23^-ze@|^+ZYk}stw5_G`d$6F* z$HsIeqjwI-h9dLFAsS@e8ZNUBN=U2<*4qafu9#px6@E3|c_BHjG*>({CO=zsM9`{n zcCflvh?c8!ADXsIK7swV zN!yd57e0;Kuh5Brod*v1KN)pGz6U5pUdVlM4 z`zqTcC;6A04oMjrJ3D{vtNx|0$I_xntaR492@uizMA>&W?CL8Rf-#)SN!%4b0$O zumklHvDvN|=skPVKK8ApWHeUf<)s7-mc>=I1u+0Fq|SGeyRU|LeBQKQ1mnW5>PT6P z1&=&vXL66498ZLop}s^V>Xtnr*bVw$9BZsgroML0baB=uy9Xd>V;_bC8Q)IkP+s`Y zEdZRFeBQ$Iy$^92#9`{%9S9wpE-PXHxXEggaenjZ!P-&WWuqwFfNoi+N5H=;4dr!3 zRdfLkHrH;{a`m2)Ex5&=qr@X1y|(B07MNSKvziKXrAm*$=dMhN&uqYl>$0eCw6QAL z9i+6g2ntrQh1>zEYV*yghZ>H<3+_g6htHt0(a!P;9M&U1QFYv&3O{$ftXCkl_swK` zfD#RwL{$k)0%u`tN@lLy@yPHgve3)Mpa>jf^c%_D!Ag(KW=FWSDjx+DyeQK*(c`nJ zI|Ol@DpzQCC=FDvOIG)Va0T@IMsUNtmWqa#cmEr5wF^<@^2$}zH_f?*3gBA>VHCWp zlkIY>z%gaLD(noFsLT^Qx?7>dvRni5005WFl~kzq+1MS1f2+>E9*$Fh-lBe^J3`rx zvz|?i#3#$}Nm=(mT*kpU-GgX=+W2a+CrZW5A4%1*MD5t-W&!Ri#k&NEnZ)}Fo@8a? zVjtr2@$vZZd8eZ=LP*7IKh$oV!mWvx!Ag|p(;8XTGJ?vP?6_rQFjP=wMVYOUTd5W0 z6E`R_PO4nveYv9GW8P z<&%Y$D5S%}Ydt^K62--(O%aVz4~Mr2r?@R6@!R*LLf)k)OOzv<$CV*8zZWEy;^F{B zwh23B7KGSCn!v)dc04ay`bRYaIHpVE7TcqtPtoJGA+2U>M0SM6>Umyt^Or)LpplAb zTAa>m=h=pUnyRs*^Q*^3Jd1o#CutLcA~VNw3-pg9Ym^W0M1U_$rdCF%j(O)g%)5LE9$oc+MY_EL!f| z76BH_{YZ3_4Qupeq8t)D>9W-%g7mWWt4R{Z?80ieVz-lyM-8<97a=LGxS)d@<6 zh9|$o_u5e~p6A@|uWe0gngYF70<}kzoc|f19R#>j>J;&f zzEY!JN>yT$FC#Y02#rD0;IyKc@e^^+cUPN|0D5w#n9BOSP7>8X^Zt~gw;1LR2EFpp z8tR`_BtejH#C$3p(eaqFFTPF&L8Vo8p+-X$JH#5qe`V-{WTac`@c=13hb>9e}UUkaRpv1mT2ETx=LHjN_ z-03YaNcN*Tz9~)Va;IY+i!Mz&!Z+zTJ$yYo6V+Tx;zprAAj;tQnh&mG3)YgzU?ju@ zP+u;wtasjUCF*M`0bH*o>2Oi21T-iws_Y-?JFU3^8n!@6{R^b7V(?3*qYLPC%6_|+ zq~Ufe>q#zVzi~au;u|-xP3ws&NV|^V@XYTA zK1Q25U-LgpaP#X)WC5=C*ho`8Y?ms9yqnhg1W`HGw-YYxj^^| z<7c0#1R>31W3MW)8Ytj_N)x0+U*TDGaP3?8?72rdSJMQr}X z_eEtKzspMfO{){GMN0(8Fe1$;auEh77b{(=9f5p~Q_WmXk5v5Mr z=Q1r-TKC`EQi(@oYF$6(v42BFLsW_1Z(PG3KrU?Tn`BTqj1oNz8f(<-`mpZ3Au)3@ z(a0gj3i{a8ow%sp=v`DWA#q3ZGp>k1>;hHCXM0HNOZMqX=;3m2NRkN1 z?QhXkT6KROb}ReG8w7~ee0Za~7Lkaz?JKaK)G5PfrY;}QfL&2_c0@@-jnX706e_+& z5Oq$xJd}&h+j7p^DGyg9H3lY)9)iSoHKvRjSK`tHdyf9Q@HG5@d`M8iRQM9bC{GJ` z!!#6SZ}DoBu+z$kb~uDsn(Uz8@7yqrd2GFi0k4#E0I!%U{_l-NCjnDYG(mG>LYo#jNW=}T-`jk+0Y*Fer^cnyI>t8_z zf_u7!XQpgY1!`IRnFvtSoai}#zIW5@8@a)uq8sD>NNjn7TNx-Xj;OZ14A-&hw?zA{ zkbT%1JoJvozQGPFNw<#*biXF%0Cc0CkDj}R!r2d(I-e%G-$bF_))|mI66ce|p2NI^ zNXYu9K3nYNP%|d`%EyU4M|sQ{Oa!wb$zFjnW6np3*yTuwX)_nnjQmE87Sy04XkZf7 zY=}J60!n*;y;9jyh0m~K%Sh_KIRyB$nK1#sjXwt%vjWbZLDgDmyhp{08NRMsY1*Q+ zTa6ou0+At%AeNgwkv@+vR|0` zgQI?Cl0oQ+$!4M;gvS~xiBSk)v@MyvTuD-)sh(GoG`yu&k!-xJt0I#E`5gjYX93#0 zfW4oIBUO>(eB&;5%VvV;p72Uxo6iyOG8Od1+07)5zLeC9xW(l*3cx{r5 z1`vWdStfko@`(88B0SI4Bl5xfm6l$SAmdSc(byL5>!Zzezk}jkose_(IY^Bb@*3cH z(}*CAVrj%{9{@phc^1R`5LMOW)oiox3$3@?8dMGT*3#tTDwvP~nN8^7d0EK+>0y@nt z@1o#li1`ZN7=<=5D8si)Y5A-ZQsDLw>RB>yLbnghygpigKWW@{w)&4_x{7qd5h%WU)x(m z;}3oI*C6hvuJGwH#K$VszeS z2i20rY-KGe5u-jt&_$$?J+37xT#&4egn|Z8m4rKesuuT(6udrJ#Uq(Rl5^*_s#nCx z^LXt=Nvi=C^;=3V_TFF5Rle;9%H%N`QC(lXPv@kf(N7?bUhnYWzk8Fq#!_}e9Z7?e zT$S$X^EmjT7Rt8P_225Bbwq;`M_7@uP1zAvq&VUsJgl+Ea3~ployC0 zzL3ChO;;0f@P88U%SI}gWZO^UCZWDW<%QRSc=)ouupxLvp^W-|#C!~(N10zNSa@9J zJ+{6N>fHw*gsLGoKv}Ms%CuS8qg-;T7WnoKtefYBY73YyiLcI6>o*AEaZ+& zW^-g#98x*|gj0EaeWS*OX)+aA?q46`AvQbO6~yztonTY_ii?UX4B}-4iBe{{<1}-# zu`();tZ6x+RG(IwPATh7Ds}7!J4qmh=#!oOD^RhEsQFqeJ91b5Ofu~vc@T%6?;?D{ z_by?3-XVLj^NQU>nFBhGYlxN#^x6~H^q^s*Kp%4fn>|Bfu^D?E>EChKhy$BOj~ci7 zA&9%SpObP!sm{1KGvaoS0VzRUyZe#-hr3B6j_k*hlt831C}dVanAI?LTLWb$vi*~2 z2}?#u&{-2jhEN}evLCV}5=*lx)e#+5aY$<0k7RRc-Dk=kbx%h1BnBM{`%LLRudMgG&y4vjK-qU2`W^VL2BOBikI)!GDEn&z88R61 zF)6a<0zVKDSF<`*W0+KwE8;5G;EOZKAnorVT8ztJ2(lh^Iu>PsC&1ToO=bX z%%a;XiauNsC+PC@dOneddE-_*by&~B1DrfQbXaIrjeV3>~+p5u<^IE*iy*Q7- z^X9@(@YE+VfjJ=32E9+R6$s@mz3WozuLvm}zsY)8<1n&BeKG{c9@UPC_u}?=A_1yIThq>tblB|gEOI3%B2K%O z;rU%Hl>PJ|04Ab?sG*c9U26kH>~mEQW#jkvi-@`VNd$ac)4RnTU!uGg3WHce@F1)4 zE#O_-`iO|j=sVEfEI`8ex&0&x7x>eDG7^T?=bNIFD-bJI9li-3Kd!U>KyB@pTVVYw z&4RX=*`W!!*iLTS5++Glg3O`=BnCfTe}K%%2PZuf++v|QCOil6R-vCV=U88Rtw25p zR@25XCX(^9?W-)B^JnAK-teRopW@N)9_gAquRglDGqZk@XYzc9kH#97bP#}uqK2ic z+Q}iDqN?igbF8`lHy?zempn6lt2=P`P2o9iD)LiS-^L(2Nwfxgp7xjYnWJ48xP9Bq z(I3FzIhl?)o$2L)y>We++DlB9gAno!E6%Spl!;;Xu}hW)RT3_=v6^5Ux39bk}F zz7M0#^dK zie@s}U;7NeGh&>~P<(f5C~{N%s5qt?MvGujIQ~Xb89eyPdvBE9P!?Vz_Up>avp#&l z{`En>>7h8-FPerQB%^>N{7;~V^xs?^bR5$FMFyfa>wHX_B{l`Z);wnQ^R7LXPZ0ImfP#j1@YPtZ*GSjj5F@K7``tmprMUg|!l$8@ zdOH>RJ7$bA$G~*+@Nt(_9=Hw3jU;js?1@_`t3qgC)wg8dWV42QCN-DfV2P{e4n-V( z8WLE&&-zT?D4PHY{IDKK2fQZpVLe9v+kWb47TENY7EpFqBgsv3;_@E>?L_xAAWzy- zKtf3+!GR?q{)n@Lo3$90<1a%Yf#Uytk@Wzt0h4k-6N$ojeg9fSc1FgU6Z#ue^5bme zm}h0QuR&D^rt+$S&2J*|p}6iNV^cGKQnuU)wFunzP!+?hEyAaF%2JsKcbd{7=)?m* z1}~zviHyggzicAI24Nn36WN#sf+Cc(D=NrR??RN##QGqk4{Vm$LnI5>;bOy0;JY*=pBx{D`{VKXBj`usvjec-Bx+XEf-Yw?8B( z0WGfDv+TC;ir@%;;hi;YKBk9AQKSL?OHB8X&p?^}NTz@n((99xxlfrlwNY^Aw%e@D zM0JI#E4obZN_=wi(Dc|H$w0tf!l$ma_XK8qIK86J&5Zf`QO~p?xOZpSG2poVc)D}U zwrt%#rInwf(SQV4%kDc&Ldw4x8gap^;L6B^TUY7RQLZ797fL5=7*SErd-sF+d4gBxtYHbRsUG! z2yV1zLun@FrY;Gp*UaYE?rEPphy8>^l$c{BIL2EVcssX64*p7`+|P0X&g9zGtdfXW zE5EemCuJ8H*(*DIcqL&Bk};5P)TYXtfTvK*FVD#pES%+@n>}I|X5#D`Yr#`x7C$FH zn+r7`$**zgo+>ry>8Y^+#r5C0Bxa`!1M~|pON;LnD!RO4;A7pa&=M4@h_6P`fv`3~ z#>t)gaM$K2>1d|8Sq~HkO}nv{a|AqZyszz)3g4(4RE)S-)xna*xc08dzm(m7DqH?m z-u**q`dw-NRr%ytXx(p0E1;~V>1N6cxj*1!-_5}n|JR+SboVJ+DevxcrRiU#{U2rB zGj2C|)5}|v?^7-<=Hh(&FUmaTq{NI4nZBD>P|;%c>_2@YUFWlJ){MIZ6%#ZLX{z%T_cK1$^wf z6n1Yj8H06wvzfex5BAPyb6W`5=|W#XTW_?Gao9vCm_6G<#>P_N2xP#H=$+ml8$K*H zeTZc6tK~MdMV=_IP84!>$V9O5qFsPb*0J+kWCrL2{}*0=(|N5}=GY~cgA43u~ zoXuk-;sqM46=Vi~V__s2|-D5_UzBD9Pl7=z_z{(d#e~`=Wfz(Hj^J z-?U5NT0jxk>e=@{AzX!vzS->6Ply(F(DkT#a%O3x2$%%SU%_z_3(b~awE7<^S{5cl zCz2Wl1$RQ`pp;W4xNQDx?s4)3rcTw3Y&P-)DZxzHQ_5DKAj$9!s;-S>Pn{q-NTv^$ zvHv?kq7eEp?Ji>#t^KpInnSUESFy%cvWfd;p8w(m}U& zog^u~)b|Oxv+VI@ADrw51P7iX$$08hPZ1sL+UGOtN480}Y!G&aMs!^ay%GOHzzae74*xLM_W6cJ*nJh;!Lb6VRZ$h<^^Tgqr;epdI?uWwE@wc*=I;3`}!F&ZH)8W5LdBZlX>5MWXUXS z$>e2b32xY;#M>f>ferzpN(cNt%otyJ* zWG}Ez)2N@BjxRvhDP!-n^*in4(|)*g*ry~1#IQ2gHmj`O1#1{047 ztKF+=5Srr0;UhfyCq?b+7?Sl`ymeRsMoS5+er{^ z@!neYi*~XYms9n8x_loY z^vX!~wuf*!&^e6@?lwlSf#J#kNx)Segyq-ce-Q__+YhBYNA`x`u(fb%4A5eD&ruS1=T{GU|@%)Z6-p-`E? zo%RPrpaw8%Gs{o<`d=!Vca0O|0*-CsK&$jVt2z-%8lO4TDjD-2)|f<&8b8-E-h+iGy9hTX+d9C-6hDjo&+XH>ZVP88)8 zjvCQ^(MEkwWgo9Zie6Ri0F5R{6=l?nq7Q>Xdy|eeppr{u?yt358#{qundJaiF0;e-Ww;?zmFGq4otiV zh1Id{0TrH<&6ku&ka~RP0$B?Ykk(0(xcsU22DnNFYl_A;ND%)U0e^N3icn65zV0Ns zm@ww;)7Z{Vq6aJQz@np>qYeSf>>xbHen9&d$uJzfYWx+6D^AV~hFiTvF82}LX_Ni& z@!a~TTHBWhh_j0>_QyZ=UL?8D7Iljb4jbl(f!QciQ1j(4#qf&J zOiD%ISO!l3gxy6p0tMR=)_MW%W;61WmZ7T@yRVBhyH@#%A9v>0KKfwhD&<5aWNYkO^33-cmO9bE1dx z*?cL5UHCa!hjG2}InjcQabm5_At^7~Lp(!}(GhV8rgykpGKhv0_NpiM4hpJ$w5ZoG z#-%O-R>8)9L3EsAJ3kv4dWKo@csW8RqRqPmrutCy1N3)I7Fs7Gi03Q9nh=P^+xNHD zQMTp_f=Zdfqaabg*f`gF`1!vQ#;*px7TTY70f+tk3o-&%`IC_KzskuA=6*06f0blI z@Na&l+#L6p>oO$t8&^pf%=YU+aeqTJnyt&#(_HEoJ?hDpHMjW?MR9dhblC5yVQy~^ z+5V{G0w>zCJKmyVzv>$5Z};i3T}2gWhatD~RS3I<%T(f}sEqf+RZ^D#0Awg?WeWdS znnlGASG(LP&MFvRS=ex>Gp*uiNM~zi8VsC68rI%TG&xlC2Fjw(Y(6iL@B64%4KQ+? zJn$p%a_E4y8C0^?xT(+K&VaVvH4k>!8{%k3=J=KsA@#8B-`QaIB5hjTpY3?T4Yhk6_i^m5Ky&lM{$mFD!2d@W_p1vaL&j=v&Y zWe9m{2nOD)&5gSvbQz-II!29fM5SvdvY+=5J%-b}o)ul=Qvdv`nhV(>*N6@X$A1b$ zjL@Uew%iM42Dkb@HAL1x$dq0qZ(wfxe63%*s=p+K5Zb0*$x|*npzO>UB`%*|tddQq8myByaS0iKD1TqY{_`c*@ImxD!qdWEm$Ok{VWs0JUkqFof~oBr z@H9HK{_W20>r2Jg6OT$k|sOq$O2zgeN96BsB{|qnW_Vc?AWjSQU3*Blkw=XXHw!^OYR;9 zD1PK?G7XdLUJ%>&HR;a)?U;RA?EF>uRFHn_ZNv;A$1#-;3cC)O1ZeI6a-i^!QEcvY z63;mpH&YrZyYV^+7t^4v0cbwT?!Au6L|9_ii9+T5DfZ#yI<8kSx(1Y3hoC`Zkkvp1 zYfy~ScDkLip*Q+n^voM%{Aem_4939AFN%6>mJ0zT2>&@yh+9XKPK{r{p{YHNwBoz)IUIwiM)ndEXi`cITr;c<)jq7;u{DvSh z>FU+&p9UUhrXKOf4_#exsA-LMV>$3CG+NO??0#z@dKTo2xXVPv=w&6*RNNFA?*DP~ zDXtG(!HiJLJFvDwQRPP*1yrLc{mZM!X^(>1|6oNS`_fG^6l(o>9=r8se`4scy7aJ% zEhGF=C&a>pRr{Av;oWIPyMKkGR^|n`qr>hl2dyjJ&yx^z)4#oP=T-^Bi2jGGcz+?o zw?+kl#$)j-djJ;5R=*=YmNji~h)m~XSx=DUXX0`6rTuxS29Z5G%=@_nY+J@3qz^}N z5QwXu{pERhZr`WBgx(ZWnQ4al&>twlVXalGc5#>cj{kd~+ovXzWSBW~mhXJa`@J9SZFjs2&q^>W)q3I!FSYLg{vfo{`W&jdNG$I5Twhk|&L!2ftxy`>^GX_0DmyA*;U;ytL2e zn~(AjF1(1dj=4w;8Ekp-xG^1*t}y{cKV=6NwWQ!f)1fvSDnAKzs3ca8WoLm(9J%ST z$pKW0iMLg(~1E~ zaKGc`pHAT8E>S6H$2$eJO`pSG#K{IIfuQ3{FHzBBSjql5#kz-}#H9p0-v-#w9UiUU zB%tC?gYppbTVuhAe*jY}ZO+WrjjX!tVJh$)CFv^gnJvX$RZ+s)FYRvVR5XaEu)r9R6>;_c{`q+5Q$jHfU(CZ zL^IlI)V25OjHeKdcfsjcetbGy?}5DOS1KtSu`f^qD(+S~A~N-+$V_e`6y)!hDegw1 zQjOkLNlrY%3{B>(zY1tG8Q1B}ANZBZ=T*N^E8!8{KKEk;OMuuYD+UiUjCp&u#FZ_s z1_m6O!h&oWT>1-?g#`x86>qCC=&r@*?n$4ebNII3sKl|*_maDeM!QjWqlZTZZ`sdb z+V38LIjgI{cx(hzPz5A5IO%0vC{7aycQsr%jEcenpTdIRil6#!ygUz;->wMB`^vY@ zDD!Jm3df7>;}O3o!OPHw)S8T%on=+7+ECeQDHNJbd-qOZ6~TEkp63>5cPn}=W)ql^d|@ja5Y(Z z`zrpwD->#-&}FBh_^KXi941ED*_j?$Zf=TZy31yBV~gyeasagsOz-a3l{z-#1g6Z7 z$?zkE>T)J&O!L(*kbYBIOmSB<{!a`kZBPq;UNb=1$@VLE8V_#pD)27jzY@z$b{tvxip-X1eM(It%6!$XI^Ah}@ zv+`eNiXaSTlO!Lgo>@jn_iG~l+p82ajFo@2dQ##7?Wf{ZA;(VE%5uYfS?RsJ{PoSU z`QiIzmIr;b9(~xDBKTyt#|y$v=T(KTwqI*~T-(bKDNX<-^K z5!0Y!k_?0$O0k&_MKA zH?8hS5!T`aiE9Gz5pN4Gz7u3sQzlAiNri`~a~nt{u2UnCnpJw{6)^Qk8X!&bu2Wg- zplV0}CH?I_xctn-S5> zAq2ma$HiwPmLTs62sDwXc(~T(ppri`oROFVy=i6iXVKr(>%HNC#dlq&@j$fl?7mX` z1%r(B3Ub?{T`lU;2qnem=`8KomP@aX6x?s~bzN%FRn0n4yJ=YL--gy!v85Hia*r|T zk^&XgTUGV~bulBUBP%P`* zfSUAx*!+ZBdH54GH>c4D{I@9N)vNFZ!2|w7Zcy=1H6EZ|?(K4j+-hn7%AEJ20!!E8~r~^V9-I4r1p*zfbgyacWw$9m@lFu^DY;dXighIPxodULubf-e_{?h`) z@*htq>GzkJPrz54h6$2`rkqBE()!Zi6me>b1P_uM0L++NpqQ1orosCTHfrwKWa#O5 zjRT@#R}8R%wreS9;x@s8dJ;513JxTy7S)p|dQZkrPykzEfwVUx?TYKm##qFD0FPKF zCSMGix7D}ZPlN%*FfY&axH9XEQ%RljB1?gu8Sg+9Lr8?sZ9rwDfX1Oko73rMIbd4T$A(iowX@~t1Q50a) zG%FnvYf=eaN^3O{fTtqGATZG5#mhth`hpCRWvn!27wa8U(+3wV_tOOa599_xJ{`{T zV|nGD)N)Xw?N-zB`KgHT4h_>%w5*edhEnq<743;7ym+4#e+L`>{*>a20CBc^a9M#CUGz7Z35iDY5 z{4zSQR!N(xwa;j;rEjFNDA|QPlX~2vZIuqG5AYAXdWJNw)ui6Xbj7g$A4=Lol6ji_kDU|a2`HiS;&Z54l~Udb%~9zub5!Z^;kvh-W>HVEJqJDKjp@34JuA zy?ri*6pCu`?OX$>Gb9$PWGuV<6Gd)s|u=#|U- z#(yZ)I)MO3S_%?k-;8MZG*C56sCnQl}rnGAyNKv3ZVsAr~Ywl1ixI2jr;E3bu z^Xa4`d+ptJY6Fe?R7;W!{SEn<= z8UliY^4|h>k_b~(dnQRvP9NtdgHtvSN-OsvDk1zwX<$y(4}6>Dv;TV$`m_8;Dc^A`%=R`sR|L?#wf@vFKt@tu?rIF>3`HP z_=-7ZG6tT}8*zm)Bz^9jfh)9eIydHC+2bsHaL>RM(FQu>3#dXgtEhwXsx@Uaq!cTnx@sYCUDZKpwHFO;-vVV0&`^Zd3w}1639IY|4fAIqz ztuz;-UYZ-INAS1-egEzTI0>eI2`xLZ4Relh_Lt))3mU zXe(G8Btvf4Pd-0tc|aUZE2Ovk?wjc3YH@5G<=CRS`%F@8Ggu4h^_wLdJcFIKpU@2# zW7j<5vmR3YkuE_yD|E?=0snkErPE)n?oY zRCeao=8R2!+HKN68iRf~4sJkuTP7}ibJ=0zVV}bVhnJyDBperw6u!JY3i=OJXYNLd z3uh_4U~@0yFFvC5OvSQ3=s41)eKiRhn-y5PO6v)Tsq)5Iyy`KP0EM?KETSv#{&Qix zA$)DMfTn=15C~t`1hhBZ&nBjIw!~>*i(|#v>!&!@Ov#l@hGXPsteTU>Ai$Eu)NZ5u zSMPww7Fuv89QL|_)$g%d-RSC_IIa~pWEC@08j{+hhP7-9Up&!&?RW?i7=>yz>me=E z@FyM%WrrlELt*o~*%VF7Hf*VrgPV4-l9gaMNqHYn1}98sI`p8F-MAzG$CCYG%z>0@ zfU$HZ5Y^$@=fmCLv8gTl+_ya`OW?b~!_@iMR;A_u_LE@L0_);+8)2r<;~sG(f@kiP z))Ua9Dwp@XrXHsc<6nP5F<|25zFZ0Rs>;Pnh|#Kx@ZCu=$uwVKacw2@G|~uDUKb|w zbXMV}xlOEeqlo|V2{i*F&TYu#`#+`pC$h@dnr^n{y#ts3vS*K2@iJRXWpro6ruXUw zu-ezmtmL)YZPj*(_7pS?4(v3NT`CVjS%~y=g~nH1z~qG6ra>%7+NuQJ`jpCpyV@R? zw?<+60pYR>^4d_CAlxQ|tm{@`64kB3I?X;zHFyBs-{@28!7or?tG9KaP0m?jU);oE172M6 zwTNH#j6zj1$vZ*xw*!=Pkh4l>S@p2ls-qQ+o^|@{Z%-k~+BI??U=klcqoVsmKJ0+P z#eI<9`%@pvUD%UZ$=D`{K&U=V>HI&>sBkH^p$`EgG(M;N5GO0&KMHznM|Q)A;=svW zQNzNQyyU++8?N9i@YC9|(hv#|J^)0ez$@s&Y+3lDvvV1-8|zLuLvrHxJ`DI74wEzduva*0{S|M{GP{Vn-89p_2j%|9U(xx(}3DK%%LF*9v% zl{~6`H@13*%03Uy%1C}lA7z4Nux}yjJ*DCvEBj;`XdMe7{;g#Z{A+!b1q-q)hE;s^ zw)MahSo!S^6a=>JEU6cn+ji>&@*ipWvDg$*oI{tgTi5K=p?I_@G(a05L2kDb=Cj=+ z`b`+jmS@}bBp7f&MWL@v?EC<$s0Oe=uMgSn6G>1mCink}gy^0W@Ag7pAp`zxRsFxA zw6ga;Zm~6=X3Y2dYIf_Y-HwKtv>dVNnbs@_25yDm^mJ6Gh}6d2fH`2kmleWf+J20T zg|C64h&c_i;FtK+MO~@$u*aNx)4%OI0l?Yf#$Q{7@=u4|PPKmxhJS;_4bLjRzB8xN zeQyaX`6?k7N(Hwkf?q(9;fpX;eCq%8f(Gry#}*a^EEA;u4eiw;1Fq67?J6?1L9AMT zmiodAg8F;zB9qgh!*BL5UkL3<7&6~tUsUW=md@1v-4kp1PW+%mbecL=yEE%) zE^Ldbe<8@A=Qk4)gA0|v7s!7>NPqa+tRG7P{LreaF~=OJX|j&LLr7W>1cL~SW1L86 zfe3K^2F!9%6Ub=s!oTD};t`Utj->xUJ|Z6SqbzI0G1U2#TlW=vz{&4HCdRjfI*+Px z;pY81SJX1+$GYBwp>4b2=?D=3x*-6;iX%SJ)qjqz-aMWr6{z~f>%~OB?$b~V+j_A( zWT5ka4%4N#IkXy`RcEoYig1AacSwqZL6lra8!5LTn zaIQ5=G<7}X0*$>wkFzB}qDeUwXqCz`g!=Y`auZ@FBA4U2qmC87 zf#>`}?oK6Lj%zN*GfWeNdE-Z zo+|3a=24Xp*QApbN?;q+Kj;I?jnsNDiuaNdz5hF*7!el;3`T}86u)3WaURrJHuGbo z#Jp}}DB`{EtiB4&LfN=G^5mnK{YFUR(iLFKsJB70cDCrw9n!UfQY1{>`c2B&qpEW# zJR&W-DC7k0emnH4hiK|+{;Y4=8v?%u^rf+fSxKsigRXRGP^-Gjfn561??s??u)?lB z*FS)jhPSqdvf>4pIx{b$uBM?EYI$hMnRX8VdP7b?DBq7oHX~DV%xx;W>VbkSD%opd zdg57hWrn3Bw0(~VQ}7%sxnAgwIYxt#aHE=4ZuIEyNB;(_xLQ)YiS(`lw~35|g4S!( zgeDz$V`bcB2&=LK<3YQg8tUOb@Vx0WRsHKA#^iR+#CNp5=`)ld;k&jZgOZx&Sek8 zq1sfFKD0J{X63#SqL}-$`6@XH@tP7!*KXJWg@cu}t>%y6D{3M#wMn7`)F8VQe2{_! zz-np0HfDWD^P?3cJON5(`E)nQL@;>7e`_iHtrz#P^4v*XJ9)`YCZY(U2qZg_=SBXu z=(BeYiM6xa?xP4~=*-ZQUGtXswb+C^;+nAEX=1 zGMgtcKyEg8l2s*%ozBc}6Mq0X=c> z(nAKIGZEgow=m#-zX0%dX~z(#fJ+6u*`+lA$I)c7phtA2^EF=NZS;y0e#;Slb~3Ju zWc2WA(PhD_UNeY~@Fsz9=Ioud$IjCKy}@koE%hb_q?|`zEB#ftN*p9A!UaPrd3&y$o+5jFkGNwck z81z%fY)`2{^xvh`XoTQ{{4oT(dY$>f2x+JOU=)mD?I-HiV}`T)A!_Aae65P0-WSbH z2bvr01Cf*~1U1B3amD{GN$NX7q*Bqjjq27j_~xJgF3Iaphg9J9rO|wb4+$F#iF{jg z_vzNVcOb5Mt*Jfe_`ZIrSM90S(catfslQuOukHJlrak}kyg&zBK~m@YKE#0j-88?} zcuIj$QCPF?c0HWHHf5S#Bu zCc);F0)#6SHrN|IR|l$2-oYMVmERwv`sJ@IR+0`QgTLrU^f+mwzN4o-Mg^{c*6%cz zVh|-z6BAlJq{pdgkI_GD#@2PRylQcb_mw{kS6^l&L0reB*6#(gz>Bs$Scm8G;(pfL zNAvnrcOSmt+4nPOBIn~G(X8Z-zZzQUrUhunxt}o`%Ik8Vk{pVpXzi(#Rh-qVUw#rT zyEudYTuo-mvFH4xX+gv^KtqCI$J-~luuIQ5mw;MjH1fBH92?T~c;KV>+ z(KhEb-4sUkD#+(hq{yX{b<6&&JNv8V?53>%0cZ%=10>)3qePpXqVRYJG=xD0pLIfA z97IB`lMdwH9Xl-!93>heq|10{Nf`Dct0oTCZlG-E49k=dcb8AwF?`siG?<~9STE+Y zl2Zw%b!Wu307LHG^;4R-U*LePDyx+gCn044Ijger?|>Sc7eGSO(WYShGq}_{bK9gk zXzbGR`l1dYKUzrvId|eDPs`G9Lvi7S_&hKAx7+3zo+sU3>mSmK8S)m zC_k2SRo5FxAv$mk2y9Vzh#3j65^fxNQ41GWV>#s1mZ?y_YRl1{_;Osn`G300%8nFp z@dQw|si}oi@Wbo1Z@|?o4tWC$=DKf7%Fac%;fpywJVi(!sHF$s&k9893_p0`t+(Dr zaLNb%hl1s5mj#?>#}Fw2ip@t)kT@#6H$mu=S-5%IE{#o&t>#L0%>+%0qUyc2Y)uE< z8AE%WNAN7;xJTo5*1HsHzJGHsdIOn>Qf_(U6c)9i7%n*gAt9(;3sRxVc>W{&7K?CN z?G#(0&^KswSwMOK>~EPhG!7&HlBc5@Ew)6Ml-A#u@ki#;2c`g?$5xB;w1C|DolyrqMsh`3W}U0n2LD1&BE2m(*CTdJDdFz4Q_jyIqc zvcZKzP$e(MP7XTL1E&7r`Q{&j$9laKlVLpT_4O=PvAFp|H7<*)B~I+Bl@?q})%(cA zZPC=+(xQH6VRbzA=kS{vyJ=X{rz*#YQrRD#FBhasZLl^yQzOnJxJG2zB*8_ZrbkY&fV2rfs`oYCf+w8AvTDFjK>2$ zr3*y#1vpffUC`7HUM>^aBM~!S!Ad%E8jX!&TJKKFaHnN9NSdc;91gKIN@0Z~*fw*b zGG_|lD^_fBsKq*rKZomKv?E<- z%aD>&-u>F()F|wj+}!0R5{0z8arS_3h^lTfy+|#}v z^z|EL`AhZ=X~|`9C7yz&J203er9t)lhQZI`aPApeITevf zER(yw5kAM2VA0<>vjI}}eEM@393284OoTAwRjs&I`sN*?oKUISL0_Ws!+2`a;2Wj+b{VD}!QYYXBD? z3#CD!`bi8s0s0C5btuWjl5Etb{{JsX4go0m7KrXGfA8>=z&0z%hR$oa72?YI7j(6G3v|zxXA5th8&a^2&`A z6xiq*>v?r7{=z!4Kon^Ns|}=7JYNw(qA`|bOTO(}g^V|>n700!rcdFhF5pi_5L9mz zD@G$WeRS5}YuMf}qU!l1Zl*^e|iF5V@pJNK5yMCm9At;Kf4CFYv9ax`P~ zK;SYdk_hz`-H~J_He&0OfuHp4Cq2GQOF>6YcM84xZhFzu%Ra5GAYGMyIlj|yZkGo4 zd2vq>__%}C|KJ0&^UBvaWd-~RXDL26iVTG_%X%r3-yB6IVB#E=)EqiUq$5SeP{4nW zB16y#<(nt-#%S`gFCYjRU1<3UDDhXie9oR_d22L@iow%Q?6o7LV4ZKV^=bc=bjTV4J4Vu@_db0fP(+=Z&s$=M z0ruEVzuJ+wuphJdYx5N!4u(#Aqn#!t(rw|p#$)|61Nags2Xe7J|E{5nNrmknLYR4%r6t;POq5^H2{C z0oh*z;1@OqQ&Ag$DAtGp#FPU49s6c=Vj5rwRcjD7ko3-mE$8b_Rk>5?CRSgq#{8*P z*ZS@E5JUqj`$LU~amj(ggvN6-lz)E!2?t=w>X_}T%@!jR;Z?ot(2>ElfsRlAaa@7h zV*ttY2O??oR;Qyh#Sr0mNY2*9R`;nMVH`#eBm>~=^#i9L;$+q>{ovc+rWs+D4J1)m z+U17-OcBMteoh?&eW?DZ(aA8AJ~#9p0e%o)IQ5L>h!I~n1DSeMYn0E&Mc&Qiz_!0t z5yZIbMZJfBW+zyMI=3r?_N#e?Qh1{fJA zG$4M??h5UxclMdUvj1x$;3J0Wgs?1ASW++s-1=vcnX&Bd8Wyt3WC0}&D^3GCw>gX{d3;&i`(7V^X%NxA%1TppC-7Vw^SP;Dr|b;q z1@3bDTtNRUY(G^mT(>Ggzu65Xs{GgxcSseUr`}-{T@a)gU?uc zaT@Cz`!1^JZb$SPqIAkC2*|ME`mpiv;c?&2ut#ok=4iqfK(Zf2gvN}$mwRs&xJZhJ zi!BuBU5m#XJ-9BtW@q{et`Nqu>=KBkg*szHJ~Skx!2>*MKiRnj#RRu zKMr(z^$cMC__FGD+aRVnmT|^0=LRy3o~N({l~34E7~&kvG{-Z7x6x*7i)Wk(n5KV7 z-O-<5kRSV07_q&=FyIbiFDqNTq0ql=DBCYah4am204NV*y<)gTCXU|{M+TAlMSN=< z34&+v&jox>+zZc7So3HY*4?vfC6R4#$HLQ~)s3(M|0qRC`dfX81$6En(-I`~iKaTI zif4gxtmJ9yH?a^JJ!6<|Z)_1CLNm5r95kA#^~9&Uui}sEJkfdG9z8jlJTFXW>y0q@ zOo}7>38H2+^H4siPcUI0$@%qzi8pS=r6;1iJZGpG!_+DQ@8gS*H3 zMu*}$C{zUgwzJ|MSTH=ng58clKESj37aVoRRVoWiulGP{%wbRFb1D2%1$>k}NJ-dfa)qb#)qrk}Dh7;ssN`N^rF*@Hw`D_TC=OKNg6AeM_a-vkUJv^{8h!pHS_%G5DYk^oqDf414%3s% zpkEGqpMzQ<_iCFAdwd81n$ekpC1vfV?Bj9ch``6tKQ<*_7h;7Y4~BTT+9}Ap-asR8 zRG6&1kV#mZ&P~?Z@8s5S!t!{>oNd8je$Il~s*2&=7@n$gqxQ<&&_NRy6=hB=}ce6|_5R$Xq}e z#R>>fTw?bu%=z8ZRrR#dsnw|6PLUZH#_|(^z>`a>eDgkl$x||nj2g`>SkMTT-NCp* z+%%@eZj0{_;K^WmZ?Si{Y-vIi>~@fBnr~)m3+Wzw-siCK+$2rsR+x(A3t0Z)F!HA0 zJv}-6#IZitWwc`wVWq+;Yc|xAAV5Ne~gqms|6W-(vX>5=j;m z>pOne`1^@u9_DP7#~H8lDZksr4|7_-e*w9tLFXaF9#$j~Bf9e4Br*cxqc#wEi4~oF zCO^5u-l{!+&lO5gM)imIJ~K7n+sn*n(3yxw0Rlqyzm z(-?FKd|ef9c2LMJDXd#QJ@u3?Hs)%fM3Au%Ti|YRQnb8n4RN|1a531@T?j$J{w>|Z zBGTeEZF3ee!Y0;%wR?5OHca%9a~J`dv9x9`Wqw|233eCnzXZ#&^ zg}jiI{pfw)kt7kjQCWr78k&WyiCW@Zz*N^sgg{*Ztgg8u$sR;kl%vS7fvnVPo;`TK zta0aa%`cfVFkXph>YwmJOuQDhv1P%Aj`JPoKSQ&&ex zd*Lh}Gn(j&S?Pcl%I@hMrkkT>B-u`zcUD}>#U!KKlYn527uOl@9#tI%dtT&$FKvsu zJiP^o&7!cN?b;m=U2Q6yUVzh4-!dTwz`7Kmq6K1bEUwqJ`~N*Iw(W!RcQKJ~8%>4? zo5b#y1?CiMNFw~bW5_5zWehQZREE0}3T{rU{piD#^cm3Gr>Kl4P-ADIEqfM3EI0bm37jbNny63QPML!!ZV(k6Gl z#&B=4@^>w)=k`?~a-}^Dj(@C9(MRBSupZ0(Z@ic55@PPjBnBGS7YkWQmVjpeG8He! zL%=PNECl2GZ6k~M*OG}qXjp|ezxw$GR>9A@tFZ-GJD%hP(A*sUcrppc@4d+cFbc76 zOJG-H-`S%$Ivi+USY%&VU|%@bzOc|5I@$RS$cvWMFz2=~ZPiRy(fq?PPz)|k;NMCi zCX|{idmtC^KHOGJM>omfKqr%BlQ-41MTG3IMcQDtO)kI$Jmn8Ji}m|r{%i^vgcNjZ zcbuSpbjR63_SRKaqU39=i{x7ho+8$sN`_$HEZ<;A5gFfQ;T)@Jt7xPbmhe4rPesMYpPh`a_Gj8^|Oe)8*)}KEX z4Ume|$)fk284vqD+G%IK23GtHf#8lU0NR!Agdv-n8VdJcD(a-9lR!aO05~FmYVW2K zCKIi^f*}U|RN13gBT(10bXv%M@QzQYVx>z9bU?h~&oP%8)VLZRHn#xlKh=bcMGZQ_ zWz+$Eg%U!1?pTt#1f7!A3FuA5P)V&vGtU%9`b_h)MI&bs$prHQ8j~uN;HC+u>0Q#Q zVtpqx5)?1f+4P>r(2k$;yNm&d5{lZLr$$ZlGa2;)*Zcc|Bvm6HSPNl*`bx_~s4j=- zjI4JxPh}9Hf`=i4EH147D;TIMs5<@M9J0q`)Z(&e%#SPrj)m4#v0)Mn^5#*UhjFMv{R0|U&w!prh}rVWlr9r>_N@B6cS$Fv^(P4e?#BFQaN7~Bb1ws= zu~l?4xUB{I(uRSiDcDnbk+me7fR5iV4m z=diM#S9)0q$~6@ldanhSJUb8bXx(M}ZTZG5L?hhMLC#HD6!+>u*&7eD+5@PBo_{r6 z4lndZI}lT)-*}4a??aiv;G5wracYGISboL0L|9)S80hoHZR)s>vFhR?aDK;1Pq>yt z^38wuoxn=sAW*rNEEj@ty{?da+|s!T46fyy=Ax#ep}sq~-2sEE^!GfJ8}s=kxa1Ph zm#X@ogDnaV06^=ZcX9R=DWZa90j`hw=1XfPX(F_l(v^1oG_mzOHFY==4okQ6Z-J!B zBw^wBuycOXf2`zFy(B{-nmXLebe=M`BbhCNpaJ-Qfn-xUSeLWNNX!E3j|s<;O)7)w zr(t%f(ZSHck648x{g5yfxTpYAh|bxQPBZK)12t*GN-1Y{$0Wg?JW1_Q5QE@o8<{S<#`4??=e#y8)(kHdY3iGE0Az$BCd@*(s{6@aL2ZI3^6CLt#wm~gX zwJlMfTf&M*FFjsr`JCS{o|q!dpJI&TonK>0mUiU0gE3QX#7+d7^jqv-BTST5RtThf z*=KL@Ka3~lILM9&MTD=3P$08_M;k`6VlXSYytr0Tt3x^*-jYlT5i3zeo_LB-#$rAy z8yG1V|6wJ5w2tfXry+7T#x|B>p`qqjCEeo>T^?Vt(hu`NJ>@*XSU$wu2uu;RorD!p zwNuzfuFyaxe2X4R5iR?MStTnt$wa=Hv>{77ot0eghmJ$U63_9Lb_ONn1a&a&4h6lL zew&8NetI1hWZwD=BX%R1^^8ESJxWwi^gwz%J*E)>w0gcLoA|BkT@6imXACE@`-!-> zG<>3v;DnTg_BP+%Yf`t5yf~WFpY3CnuMQWYZXFDmgx;cGqvz0BbyV+00AYpDb_|7N zLD0Zta9Pw=QSr`0n76iAV}E~&GTkEuy0`kiRxh(%B;VSWyRPvO3xX-NAav$XD6n_`uYvQXwR-> zAD2Uk^I;5jGL{M;k3{cIB(ETBZxs#RBTDIkX>?`z&A}l8ACUF}EBPkl0@HSpxlDSO zKZ6Cr-PAOHs99gCYWmawPW9fB;F?QN4WBjW+)h?<8!F9B6$X#rJ(0vf@OMrmsPVn% znPn!N7m0viZqXQjWlTk^ye5KwiXWjVZ^(Mw;^B_gj{6fX8g9xg?3)sC>?GOOtn_Tp5xf)wlTAvQiL{(%{9``!<%Mue*ABmlm>ycV zbKx2COjh#vhPe4U)8*}Pb)YthvP{4eKx6c;INK+rgH^l@mz*$ne`hS?pRw}4(_vUp z2;OX7jUjtg2v6Q%ESU&fz3LP98&iea9339be=zMd)tiB`U#v`X6CW(~V_9#_pExQu zr{m}rj=XwPadaC;bbSggU6z_;HT{TDhbt+fT|w`}{xfhPZg7V&k9o$w{DX&J(C*HM z6rRM2(>-_O9j0+h;EC&hQ1nF3$p_T4Wcr zc$6H&*;dn+03g{HLFEdOEugKYFB<-2<*H!|R4&hatEtT$jXHknc?$r?sGf$rCzv(f z2U)rI)X@v@x5r)4Dt9z!zG1DFJ%lrv;h|cwifJ1bc)C0bt)^Sp&~6~eyD1TKKj#P| z=;kSh7$fpDbBHbqIO3pXzcKrEbo+DATx49A|{IYUX*c691$b>{)e$H{F^FCu9#5d=Vw7}jd zVTWk`k7;|r0D}h^+Z!2tT#7Bh63MG_iE*77N)UEb9+tzMpAB1HU~Q& zGbkhx8ti<6cMIMDmsEuWJD>gE+jFLQiMrPmOlP3UzpOKtI{TP>?4Cx{@M}JV0_}i8-nTV22A}64Hq!mkS`l!{un3r_76rJV4Vrm=N}f|s?25h)*OUyk5kcY_4B08 zqYQ|gP*9eGY|SWC7Ud0+6SGj2BiB5QGm-U%i{6-0A&+yx%%ffO$QgqrNPOEpn_P zck_If7FRFx)pI`jOqne+HPp9I3rL+c!YU4SJBo(Yj+{3lsg}&Bv+JPg`tnC(*nZr9 zbc0ODHd+Ma9?b6)$tlX6BDTqoQy3-}tOowm$z;+noGE0M;{J3ry|_I^>`p;Fg5wna z3XQmc0ks~>7jb_2II+&C)<=d^VvoLD!VjN9rlQ;a4&t{@AqyZ>`=*eD`GPQCn{lC! z9&U{e2EHd@%?Dtkn##;+`MYT^eq1eEG_hlRabPALUGaV2f02hKDvEWVv(h*rb6k3} z50f?F8n&7QJ7ba|KF^`kWL!dF>awdORn7sYEN7Sk)!`nyDln&Wb~c zoK_#F(Hs5sk*`$Zp7*i)=b8$d1N5M^cfqUsqXC5g%?F=qw^Cu)B)DIbK;F(@pGt&!YD=2dZ&kL?MrziYKeONPMbRaQAjuebY}P^+>y3f5EpG=gGGApF8D zIuQ-wu6Q&D>2Vv}47aIocp6qDfU^0CNct9R$2^+2&Dz75((hxh(#8{Ku-@&Mi___# z`lt8Kc(i`z<0>pf>V-jH|Kwh3;apc?5oqY4VDL=vy>TXl zwZEOqzlZA&0S3o8K<{ulY6U(H5DHEfyjuhHrlPeN`PRvUgt=fh`Nn{(_bXPOj}{-A z$={z&LQ#*bG#Xb6h||aU=#7K*k$}%f&LE&NmVCaJx|H1wZY5+0T`BxCa5&LF{2;6RqtQuJ_FmMkmD=GP!Bj#|5C9U6W; z0Z8GC*k?lJ|)7OJ~U*gd${x5CzVozv+N4^OhE$y{mDMxARS~mz@O}RxrJ(o9>2E{uD`3`xcPnj^Hl zAny-k&*ZwlevT{VJ&`^GsV+U?Fx5Ov-#hbZ(B0-l#48Yxd@BOKS5oE~c!XC3;FQWX z1f^JTiM-QKaS}b@8B%A2NCY>~JoV|mgfMkfSSWl<9R;WoKS9Py^6xt+T5@HkzOKDoH~W3kaJ%=CzSv;}RfQfX~L=IE9ck@U+>I=(LN1~VL>Go6^ z@+u_dLmEm`zgFp|eDpavu?%|V+#0rDSw&7~yX!nlpUma?IV6}^qWG3MBr!r5d0zy$ zCy3O8+heSuZ(z5vj&YmdA>_DpjN*qeptml!@B#TkbuJV?n9pbA3!XJO2Q_rx#JI6~ zxa4hqiJ181`M^`woBE?VP-+*e*iteU^R(=p{A1ei7ydHMMDhp`||aKI`{fNnnOz%$k}1O=)3BYN!RqrzR5 z#%1YeSpmRNlzy1WHxv-?8cTL&1zIBzG3|y;Vznof<=oX6xA`|{fbwS~VKYcZkSIn; zuLU$6!G-8Jbl&sVvi0teBY}wC8tUbUX&=!afji}G(^%lR2Vz$G3rFRThqwi-&p~Ou z1jz4p9E%4{(7R1Y^oBaMJs&z-8JT}Z;9V{#9cL0lre6m4~~{Eb3ESCE#~rSr-n5(DChAH*rF^l)$uQY0ohUq(uV zs`nm0p@^hnb$T8=?A3J<{NSHwosKjSvFBc`{VB~L((Lw-6q;*rryj2_Y=Ixx zfchb|l0M~gilXT&QW5gcant%Y0bukw4=xXoyLjU3xR>-$-Q|_wj~E$kHLqxLx8bxe zXWVy)t~x|b;A@p-d7e?yeoCASy*N$W41-O=Ei#y|@rJoXja~D%Rea)H5(ee-X>p%( zf4|%Ptfrc~eR0S8A~BdBe% zzUu>#D@Js`)8M%2U?n|966u`;6kl1z+b9ioc=S0Cl356o03*fVoT7)?b1(U$v%(tO zV1#B9Sw}gS2OxpM(jGL}Au4ouI9CMZf9fLyt=o9-Vq!{!>c0LnpQxjVqKkvJ{dM9& zU$GemWdIyQ*g8)iMV_2kA9@Ql_lg0P)XQ|q_zVIrett1QRw2KySnwf8(po>qMJzYL z;A;M>;&xwgsHf|LDiFMz|L8mMM_)0fem|Mce4|f#y{|ZZy8yjCrd|IzZcu+6bSSqn zenThyl0R8rkz-C>Cyd49mtaG)(v{1p>78E<79AfE1vT#-Qx(k)|*;cIo~sn_@P7ooku3}Y4b@AP%N?c+kkNRH4UxYFN1^E4d)9|J?E3T zI8n8LWQ1ZtIwMvdfL1)>A(uZ6#!O=0K=I(ys_8j zH4xVYaq5ipd#E$`tJ_(QvHMfh6?5$FW!2fPpMKw^uBn4!#r-K3%9Pkr4%QO4%WMs4 zY)D03YA9SI?T$d_VtxH$5!j|#{;!3IKC{x()A0|^{<4RIi-W-LI(ux)aDgSp8d?i- z2T7%JXAFLPDz?;NNOYLYA-y2my_rMI-`sU!Ub+tGYsq zdStqB-Vz)G8hI6f^2H=vV|h8qj%cJkQtL8}w3>#q5+Utu_F@8%iFnQf=lU&_wSb^N z&<5$8wsSg{X>9A4i2hE4g#H_ z#iZBdXy64`a+_wblE*Wm=r!1EhC@@ApCR-bYe<+-gK%&NR7wpdsaog(n*(JN+UDuU z!Ic+t!$sr-JCiWTRWDz3uVknEhd z0Spy*H`>~Zz-m3nROv24%Ptr;x`g*9GdJ0bwD?1-smfa94;O%Gb8b-pE1CXIDt<3L zAF}0s5tQ&5)mMwq6EkYMiU4z%@lJaY=Ie|t?jmf}Gpb!h!FU^6W5+EnzHWNgT4cm$ zKDWq(x7yUA5WryvIZVP0*DpqQ|FQ%F(Ojyx$AmW>Zff+5)a&aI#}BqI21(j(mH;{H zX+1#k*I5z_VIy5iOsGFnR<8mPhG|-aZ*eZ-+xob2JeV^lDKg0U;4Rf>&A*LMS%JHz8KSKV?QZfb%XX)^lMOOUX z2V!90Ugf2tZ=98IY+$Kb%VSZ&h1=4>&sq%8053jW_Jdc+{9Pa% z6PqBX%dSkY!)7s{&0w)Yqa(T?t%5I~tt>_Fm;Y0X`f z^wqTaX-v`UF=4#d%@>{X~#_E2E!tmgnGBl+i)+r zVXz?wT@(-@p+oKDQ*=>XbtY8xDXUVgM6G?`rG0_fx|!jM#JKcBuO(QH^F=F2GDf8Q zktg4{g75@XUB@+H@T4}k{hpdaaeC!)U zn}yX7xbN%2PeeIs>QR(&yZ%bLPgHsf*{N^vn1qLX#iq>1K7`)=I50at+ceJJ!^#~7 z%-_r?JO@Gq)=a2P^$q+MTn;7!XHQ{e2NFI)>@yMR!TF5&S|5jw@r_JGk*7C^P~U=D zNd^c`v(M#x{7Mpn$WRn3{XOABb@O|AWR0gFb?9w=;Yu=24b=DO6_ess$;skm_~f9- zeYuMN27iuy_wO0g#MhaqGZOfL9oUk&O-bg`$5?Q>>LzjW4%L;9DaT>MVN_MHL7m(D z){Gg`#RcF48RH837GkO8!@{sL@Z^kY+G{;7sb3p7O4;!lEWOq}t+Fro3@yb(nDO&@NG zxXll1wY5arib*Y)$+S*@4m-Y*v>q;%!Z%}me*z!AiVTZ{*)bI)k7!iEZoN&4^a5_ZdFFe|~*cvP?3$bLZZ3&wb8wo-<5D zk*Kh!K~Ynp#zw(0Grvdl5%#J7oDRD_($T=L@~6QRS#4|0!IW8A6V^DWVg!#s{sf_HuVOBv_qbhl;f;W0s)r{YUvH{?X>`VkL$?-Ge>mTg6 z&Uhn9;GuFFCC!A{*fed|OvdN=>~I9*1MCX!!Fn=^vIo$V$ogeaW1t~`8}b1GHOcF> zd_b+Q;a1zRuP+}^@a3b5pRfVs3ql)wVQft^lPaIC5DBzNg|ENnOA-BafgYNAl^>9J zEuu~lYh>t$79k@}QM2rHI5umsMF2D`GhRyK+CLx)^z*Y1NGY-3{XS2joDY-+I3lzyW)oj1yh1fEeZO#LzfERhWgJHuQ zdHs?zaG}P{^SGK~5`j~`9L;@OO!zX7gN;3)*bF0?kB?j#FW42v#SBk>n>%eJBXL~9 z5?+&VI7Ed2`o`pdAYMm&_}voX{376Ce7bB=1Ekn!1!3{lDE+{0?U1=t_5t}}Ke zFoDLhKK4Uuyhb9-uy%k>&zA9{rUT=}@S=NvJ4H3>m)}(HQb$be74Z%g!8Mf-zVyrQ zB}C@~vDpNq2v7j9RHbAS-nN#KxTyS3)w)h~@~>(PCXZO;77LwXpdKwt-C|OFL&%FX zfH?nV=PvF=Dbc^qh-aZEW_8vuhUxj7dSdG9&Y!NhJm+6dZwg_g>26m*Gu-}g!!|WV za7M=+wSB8PMt|7-gzE#e}ixsM0tAVf09LLcWRVkH2M1L`feO zhJC^l{va!fV z7=3p@YrWHA1k=5RKxEv=^eK6J{KjtUeKj?wZl7VgdIMY^<3wnU>WsNPNV^;iMx;F0NTocMr|8z)Zp`>97(FGV_&DUzH~ zv^`h2UMQ^p!1#P2`-s1*%jTesS-xTK2L4^R{=_!H1GrXYW6%eJ{u2yLU z(^6Gs=BWbX4otFZS}u8G4_Gj5BhmYGj#L-J3YPsFz!^7^zR=~`%rKmNBY7Y5;-K8x ztk51W&Y#G|nlN?2*ff!ycg}|BP(f^U}O_R92 zIEKs+%SUbnum2Q4V@c&m zXKtoch!KfLtYiDfo^rZUVWahOy-Job(T3X6o5&e%&}K54Td|qE%e8MNdOs9_z&v65 zsRvDma6mu>F>{|)kbc~`3NjFF{-o}~|DMK~J&A<@sl zVmzruB4Blk%({ip$Y4{D1Yf}F7O)ut>7UqP7&ZN6*%#u~uR1QsDIailktjAZ`#Z_1 z+Q?_=FkcTA2sVZcesHXM4tucp@_XTC>D0>V5?*bC`{F}V5Bo5>Tr_de@`j-JR|=<0 zkmrg6w!3x3?a&lgQTEAX{mE%5Cv!19oCblt1B^=Va6xB#Xv#_P#A*Gub>bV0_%+6B z%UicXQ*`qZ+JxEPD)irKd2=r^+(dgCiTxKK4k!BFtrvIp17YjDx8PyeuF=%nNSBP9 zCSP^X+vY8(tGA^ggHv!lOjUoS!vbfK{sQky)HQVnY-!^0pu3t^*gC%nZE1Z4dEX|P zKKISDa5#z3WQ~K> zPI&w%p!fzbfn}`$f}>#^vQ6 z`~=*64B=SFNK}%zp`G9(NjRlPEOd(nP7&i(EfonHZV2P}XLfgJOlrcnMDHet-4`{F zryKrtJXNgZ>XV&2VmsaN2 zLx_EUs0*mUx9h!?ZK06Nh--AgSo{`P%XL(dN%&NpnMBDM@3`3V_pBY3B9zWd4gm18 z*i2AYO=>KeL@TKgCgOIfOtsjOz3@jZBF<{=nXx~ZNmvfJA-6K)^lrz zFz`xS#~T8-Q0bl|z}A4BAOE337m8AsaaJ#-7Q3{n&@Aj;-w2Ph0$>ZQ4AlWZIF)C> zMS)Ld{}?~KSK_n+n9_a3&DcWvNf}wtcsP)yTSyW%FxS?cQ0w81mR=6v+O`mQhurfm zBpcAiqp)Y@vEl-KNTyv&&9N`y-rP#w!{MK{l32{GF+%uHC7-8q)HV{0w_n>v`j0SV zgYx#Ce7|T}QGC7BJ|lFY?uM+%r&?ZFCu}&H?7k{>w_3Qbh3d<8yGW3nWZ7wyE%pXx zgj~W;w~^pQsNEBVMEiC^KM~QtIk7P}N;ll-wu^ab` z#&O#1WIS!i2>sWob$;33r(ut-Nz^$e)WS&bE?_7ieH^=;!~*Bvltwph&S{m$wPJJq z%*#F{)Uk<2cC6@xP&XI~omr@1R(dWL#cH_g+sQbfGN#<%b$)2#3we6zY1!~rH?`L) zr<+eQl0F8;yHDo?E|nt#F|xhJg4JENCoLQ!#4{cgAX%D$2}pxjahjab;JGZ#J|z z09x=UtogzeCfGRJJ~Y&3=>-rKpTK4$gNDV-x&OVOHLRf(R5J^FJG2ro!kggKaQ@Z2 zOoXCjWaj|K?CRC{{z~xDfywuZKD3+-{sF2Tatu{x-kjl zN*k?>KcVJ5$uJU$mFMbYYb7UEMR~)^_^^m`A?Fgvukqz9$fQQBV`MGJRd!k|o`V-I z8zN`KKIAN3KTU&53m_YYH|ODj7JF`za2zBAJ(#L z5(vfUSYz*v9?=G;$i(Q4z5l|+_wEqA-xf?eMeE$*tQIY<@AbK&@{#=F@c@r#Ejm0T zzbm9eBrfO!IIheZ6-vX_VgsG;Qe&5PX`%hszYz+no6lA4AWL}2_Ht&!*Qjq3@=$U^ zjIFGOref_s|7}{i?jCS+b}S9(oQ2AsL<$&D+807BTd>wR`p~vq0O&l&F8|8k8@jp$ zsNFzPa!1wbDgTZvL6bkD{BR+tFS)4^i)9gO#pt-)R7&H?9T$-4TP ztvA(_?6i+NH`z_4P?60S!#%lUn@@(jbH}WzRl2RI&8J*v&w6N8<&9=l(;)TgWy=aF zsv)V68bkH3I-x$?ZwPBMQFN1deXpdix41uRZCJmh;WPyH6lc#mTjP$_RW!2J)Z&e< zO`AF<3}~!#Qv<+O6$tRGD0d{JOsjVHsw^&4*KFF{Y^qF{ zS(PwzTg)TMTaEpZxF0@J(Ekb*;?bp0Bc0Y%6n}9~I(n?=n0exW7H`3k{=M36synQy zw|;X`^!*#|Ndt^l(Et0vHgrW)7k4)sKUH-tTwuJd#yh+az4cR-IilLUcp)1JY-i&* zt5s!-j>JK{YpDTHqFuajg;G{A->DQGIU-!|i+WAW#tJ$5i4Kexvu^zK8ktQlEEvAhtV=Q1q%Er%yZlqt$d^vtD4T_t=Lj;l zX;;-LJ3<8RD#3k7YCUz&5*)rxJhKEbHE4$8w%Q$0-RSFHu&D8O)uCXUZtN{zPzH5l z8+{+p&?cZznK7maX0Xg6xve%~I}`{vOIm7G?v}OO?l%34X23CoS#wwc;UnI1OlpZ1$GR7QNnt0vCWstS9(9huX!M7m(GK`2VjK`&WNGjSf4Z zMvY#H#<}kz(BZg3>{b~`5t|W>DX`Ac-Q2ZcG0yAMjpu9mC3i$rcPx14%3PFUcqG1f zL!9(W32HLfa!2pl{7{0fYVz?2pjux=zqgi%jpz?i(ui;>RHHpH2ABd1^e;k+b{^7U9ON9u_*v)e`srmyv= zkH@r1u?6|oD+TS^TXW#xg_*R1=8dhk%>3^F^j0=po!=L%Y_>+z3>9o&15RsJG~Ko%$gMxt9z&y=)9K`5ET}FdVx_DKf$2So zQfsU=m#eXo{xF73y|)z?7dDtK7MHUylA9{n(^t?@Pe5msbH7?iB$!9W_SnV2#xAAV zC!lfm;aM>7eQiYTzc^&Pk~cvvTz1tGZi0=Z01ab5e!X)(ToBD;>p;iCAD| zTQlfi^`b+=rf9=UPObE3z5FUn+RCRhj*2LRGD|*-#i-GPc;m;;gjYJ8`_V=c;iNxM zg_tMz*F0{4ikSK{@@@tu#Vjgt!(ZK$e*9D5WK`ylT9C&vXb~UeRf$W_hKY!55i-?j z$5n+}G_&pFpg1(~+r)T&F^*XY;=Xn=R(e##{qeJ&e6g3Gkzl=j^xuH%%+}P(-RzE? z9kW!L$AXSPA>%aye&mSXf_ay259wQE82&dFs5>+hV4GP_beNGI{zpfJm{R~vZChsCDs%6k3-?+vY7W&oi>~ z5JUSoWnQr}Z1K_S`gw~11nd&uR4-5Ge%?c}0oHB|!1F2%ga&S>Z9s=mfC8v{uJgH^s-RuQP5wL-5H)gt?Q_DV+j^38OxZ3L{> z8P#(!`qGgBHi$lKnzcrS{E|*X$f(Do9z%ZT8?ik+gz-6)YP4Xs@-^h8#@56dRi_@n z%H!dT^iVFQyLiQ3LDeMuG@YA)`|>UbCPksV)Js3}8AHRSEyz+#6XbWoX|+G@=84hk zel`t(b`-4ClXUudFUr)_Yc_I+A->m@f(kkw&`Xtk^{L*eN<~-fry0aHatCkGOhJ!5neGOjaydw=LgO5W_NONt2Q%Riwn3b zNfUMo{>FVY1~rB(aJ@k{|17_DJ&I3ks!FHT$4!!Q&66qIoBK$V%KppW5$QyFv%3Y- z9EO4@Kioek(Cpd=o<}C_=`ZlyPJdk2RX2Z=i(FOEKWS^72_iL)SBp zs$Yk6&MrM8?Hk)gdYSa)Li^)qEjZP8Sy1gNvWV<|JTt4-Vp3LC{%W4S*3it~%5#{A z_OTP`^I}u=4LmPVj#OKVf(_4uaksWCth7#}oj()jxu>1af(<_hx24k%q_CWsG>6~(5{%_9^B4^J9g(3Zh-^e}* zwoa$t{5=0jaQs9%Wv{^5G8AKiie@95T{Cd`=NH?;&HMS#wPF9h$nZKtBVdBez9r#gGyxpm7kHVmmt&1JXK+_J~A~>1BM6(~SQm{oSHq z>ulOBk~l@cdv#z!qe33v*x!Nyafpo*X=KmJN{%jMydGup3?4v{?1fqJb&TYmOoh#C znRO10&)aYFV%g@fGMhz#7CSZpLpy@8d;7iC9dL8sq+N6A&L5vK(y_QO?B|?ee(o?z zALd_VXH5k9twZs{QSVq~Oan~8~J68tTpLK&k z%Z9y1b2p6ucUrI5;D~Vn$qVa46*MDUMTA8xr4n}!+Lb&Z=nUL64tN|G|Y~H`*8|x zFbu^^38m0aTahqrWeOlCBOFR2l}>|K<<%rI2d^+^3)tY5>=c2a9KnIlrsm#MFO+6W zzsk-QWJ?ccPZ6X93R(+UX*kPBKgu6xmWCs>Iu5=h$x7!AeU9{`iCp{VpaE^{#?A#N z*CWoGJCUw%>s12%6oFnP)K5jmcD9OS!>tr;_!qVcF1AZtFVtrVlGEvgEJ)p{H;3}3_}Rw!B6itCh(}!7dXv)Vy_Q&%ZW3rykIyc zR!J(B#xq6eM2|(_Nj-zT7S^54Np+Z>){(e5tvMLh_(?W0X@Z#l4InUEGdRbA9_y=q z)?b$Nva;jtQk>?i)p0?td32YelvR|mxq|%aXIQVF^@o#C*}Dng0($}Z2JDa20$Mkb zZqKJ(^Xaw%x+`{FLhM>LcC|US*cMypSz_;4Qrh+|-M*CGZ?18cXD4-~Vl{W4w?V;=_im zK24IB(YDsYCTz)Vv8VCb)th0@j`HjZr`WihhTULf*6C>8zi-dRWv=_$+N6R}IWbk= zBa5^p7`J*4z*5A{5m;dNjErAFSF_106vm?Ebawd4Sza~43G-LtPSXt_Kzy?VfPi2n z#^PzBS}3)}1~C4O(KQ_7)fjClY~5rm#39`J7~6GkvrlUL|LB5{5NGrNE2}VU4tDAV z)>U-e@nUDp7{ex5BxiJg>sm#AIcScnQH*pn0vIx5xKRkQ$C?y4mR+j%cxa?K*yhqY z)*`eQ=Xf7~lN{^tH`B2me{&ok;O{a=5kfeQVw!5Txr)@d&1GHjE4i<}fCpX3{rUwN zF&We1EF@GypY!TF%lC(vbp}=!o@=DJVc9laIO~c_U?l%*NUMxXtSpYIRM$1sRoZeR zDBl}mtU!bc0bJtsOEw!BZ#h%Ka7z!8P;8XmrX<|3Y52a=Rm8e-5?sp|*_`7IX(0at zL3oQY$*c`QR7ex*!QlgJvm4Q^v7*QBh#JdgnV52^~zN{ndr=TmPQbwQJ4&* z{AYjXx#A>@|I(ZsZc+mY9%g?lI0lgTBPVo1Bo_xT;`scz!K;Uc=v#!WOUqCLJ7MZ# z;dXCc_8~zkyo8#ayOMSka=RNy@>}X@nVE%Dpaa)1+zE^1-LPZJ;`e-4S5`LztOu5` z@d#}Dl^k6m&FT#pV7PxDEiR?oN@!qVq=w zTkk5=r`mR@EvWdeZ2J)5gS}|+FJngrGhD8dL`rZ5!f+osi3)c_`Y!%40?dYLxv%~| z?*kod_-#hIb(nN-H{;)_=Du^1v2fO;tMG5Naes)(3w7=J{CMk1y4GiSojE!bI&0|* z;mSlU!eox*z396jY2e!c?9xv{w+ zP#g3kvY>`*Jj+r`%O0`*c|J1(U#fV#xKbr>=BNCNlbW1JwyfoS|2D3((8hG znbA;Pdm+ajBHM5<_$xBtb$r{)tqX$e!fEPC)!DOW{2G00+Z&wCV4xtDTC%3m+UQ&N zIik564tBe9L&txLzw~$>>@}`)yY#3JBkuQPCHLW1J+ZB$Uy-Rewg2IsR-_yzun7na zBtQv|g`gcM4*j_g4wEr~3^st?l!%(Ss@7*&Nu?QF_3sap$fydiF~)Bb)S=QAg6{>l zuOq(TiLj?G0!x z!vcV%gR;PrRZUhx2GA25wQ&^LFjC<7h?~+#bdete_+ca6H@v&3R2d`4F$={x<15)% zZRJ)A_(~URENq%(Gf3Y%8_6i>vd#};1Tz`Me01vkqm0-5W41IT%|e8tk*E;ydwYOe zj!?4yQS!!XxF^-)FcP;QATGw&o@evtmgj7!Y&OZ$C#C!#+Vo*D-1hN}8kx^1>>lg z_YKaVMq>33#uSYy&UX|AL0W;0w>Jd2Kkvo_!vb{QcQ1dQgF!v|#nUT9?k~EnEsXcG zRi${}UXN;ZWiNre1?C?Javy{`UEt?935rn44y`NX7cKri8ZWF`_rQ7%Tau#fP;970 z_W+8HUrB>^k&OR^`ecElkbWZGqtI1ySB~{CDW4xBao})#G!Zdtgk54>Q2IMg1|n3; z-WeQJae(!9plrZ#(g#7-t2|=X6t|MTLTvp5C<&uD6AFzO_Z|V9Qk&l_HY_=(PL3Gh zH3T(G(|l{mNXo;<8gL_yPQaf}`6T7|Lhj0OGKa$0n4N;x#%-WDj`^CDQCsNTk7!2~ zT}zgmxr<*Dz5iC)@ge<^_ct0z)rZ@g5UnzDlbc}S81BO+5)DSP+U@s~RvOi`UnpbgNuw+k$?k^D`I#`&?; zvUj1!judW3Pi__KkOAyvM4ijf^5k8SOs|sN>uYep39Ga(vJl2P1p1VpEJJ^~W9SMX z`0Pdi`s`A8(Ih8ilxn(La$1a_42^2- zBLHA>cfTR1N+{Ven~fX{zWWK%PlHyjv&CpCW+R)YzYmhvV`9+}d*&~%p>tPqnJ0)o zdI#;k?yb+LtCl*KL?Lx^avhtt--WKA#1$r}1I6}7gmmqJan_yOt`j|Kf9&x@IHwrd zun9h77j|-`F6!(Ov^$jYh6pTVZ`K`f8z(}J`@u{Mxnyj+L~J-Ci{y(2gGdLGcCXVS zXgX(Lsw6=x3h9ZG{nBdaKMYA&q{AJkCg!W&3A4aObVkN|L2lpx*@YIvCad^j|7-u&-HF9^`btQu(S-he5yvxj@n>7o75$c+n_Rh009tz{7m7mW|;pz^*#brib9S z2gz^~BO`6mpoWc1mHyUEDOx(a*%%0i7vUVK8*X)@Z!1S6d$AQz*ww;{ZO+s`qGk#bu3e%{;mb5J`jeIlj z!bc5n`KlXB2%>uv-DEIQlZ~qzWff@T5PV&_uiJzX7p-Xd1R7U6+$0*RD1Tw7n30h3 zA(f7g=&(ZL2K5`|gBQzJa<|{38fVRZ9h44x5xkTmxvI5ZPj=F6D`~F>fv5c_-*zi^?prbtG%yUn2eUe; znb>3=9zZq>1#Gnj7A;kE#T(Pthw?`F1*r%p`6MWrN6salB+jChm`{Ub{GVa?p_c&Q zj`Z8lR|D|6fhDW=LtMqv1*c`;$v88FwX&3SakVTv4fyPReiB5I3R{B5JE6CxA}lf+ z-CDm6Nf`Rb6wTvxFd~YP2NSH7$)U)_)_-=_3Ij};e5g^*E8dQ=@`JZKwJy>pVSbd}ELo0*Dw6;jxVO zkaZP{8TTfZkwp<`{w^Q<2JU5eB>K4aEa>!I*miupdc+AElo(($2;B7%G$onHTpr9-*s_)9m6H z*D)^m6zRv8bKX3QqoKK|Pj*{!&_9kQINPgFi>tn-&GQD@TEPW7McxQEG^hl&X8=+n56V%ka6aoBSr?TaSEcI!Ubm>rL`tjqZUAY1F zFF5)%StB>ta4-lpEydcLzv@MXy`23t>Hmh|6TGeDHE^^~5!*M|Ks-2I<+#sNr;H$Ow7< zHr0M(lQ=HtFXaA1j=6?gdWH-P%&)?4De!*WQ^@I|KJhm0i!)?MdS``dzXR*+8@Alw zdQoSkN>C?v!pq&OZTOB|>T~K?pzqIX7hiR(9_oDx14`^@#<&+7%5gRo)GpYpda2<< zRor*rg7iPzLvPGHOO)6<`-3QTmdqph>$wYONw}!92$^DM$>5;;)%dQaNovcbyL3=Z zhAvlPkl}qU=^U8?fbC^3jyp#NVpCEg!4#{&eMfq&{U16z17t=1k1q?i?$$^bZ9G9Ie?wib7-0YX)&9Y)XIZ=| z`(}0L{a5=_ThE#=G5$YCK&uWT%#i&O_-}wit9IG51PB>C8V+Fm(Qq5~z~>5uh^?^f zsC+-cdLR9$+>kq=MA~0KNpz5XlqOqfYK~hMLZvnD+=5=RxiSGa!N>k2A}{$ZHtc64 zoYTiZlNzblC%?@tzrb@dB)`W|K45&YVej(ZfnT)KmC1%Jq4@QVB6;&M9R~3ka{y=# z(R{qKbrV3qZ-G|WM?9^D9(hHYKp$3+eF;s##2WcCBRM!tJ*{|JSSHszJ>(f;$&AnW z2|oELFBxekeMDV#l5QfbrCaBwsfV1`_arfbk=YgKzX^&7;uLWTrA!(;I4Nncc5DfI z@?VM+8%h|ji>YpI!S`gGznhNAss~?v|MEt4@^{>^@5zwR7TS1Uy>`VWw!Ez$kJUb3 zV$=CKEt32o&if*n(d!gVt-B$Ncz5gn)diWnFkSIgX*c~ahH#vD?`!Y zE9l5jxh+08)&X?#=fu+pB!(%T0+@OIzCe@QhJx@0=9ui>(^2yXw zJ*pyAZmzbiN0#=Nww{f|t2Pq3!2Uov{t^0u&f2Anchkw66~lUK$CV(_Kp8nDi48y{ z`1euD1v$ed5i7KMv~$~%+*aCnj;=aOThGw8Y=L=-fSoGHLqsf_k!s!aLcnG#q+hYp z!+Fy1iWL>FEtSFd_YeaZMyBAoWN&Y8Dsa_jL~8)d%AOg3p;`}ZI`6g#uw_@0xyv4u z@`7=z!%j_`|F^R00)1D60*vZMt3JU3Y8<%!h4gJQeJ> zH$)veZFLn$h~v7@j)mp&&I4TgPvEm^FZXc$-o4yo$g3`sH*i7imx(4Bf?ETkv0nBA zR0FerRMELdi47=1H%H}Rd$B`pxFWuq%x_RXQ^Ff4FnoZJ%eqFRIjYp;Q=4kS_U#Hu zg!Iz3R1n>yQ2im)$m&$K-@A)II{N4euvs{oI>t9m$@HFRyqkN45x+4@(=k_So;whC z>7ALW4i9Y_H*;EfydBBZkGxWyVSCL!;j@I`((XO#=MI%LTpM@!YusD+-1hHiO4;ul zAtg~Ar}*8)qR>UN7o{`e_kAFZmJ0SWui8+ZdRo{x>!_|4w94jVT+CGxj(*C#N`gZS zo0J}_px7v1ptT*swfBLj$G5x4dlX;cfkn|xsZ?{?4ip+2Xg zJKx3Y+FZkL-SKWN<7YCFrwz|RRhiE2(_<4?`w zi%)X85V9}1H`OXk$c?0et#0n_&w!HzT<_~-060IrMUbX20;RPS!{7q`P4JLxkJRPn z-n@<$y19+lN$h9@k#vzYI+It23y^`b2?F~_y!w0m4~+DI7`xFXAuOV9e@HEMZimPCZ@~v;clF{@Zt%(1ROp7Apqm?mQ6ttE><4mtuoN7V?=yIlm7))X zKAHlGEK3pr?v0XUp-los<2X2UPBjJ$yLI6b#=cCRtRXr1%@7fm)XbnHk$9`+1#ahG0XSEfzIQl2 zEj=~C@e>`}3Md8l07zghHuN9=LNow2KZ4-}BJ<@)o)H01Vgj;MtoTsBl-l9AWWXK2 zkdR17mL=Chl{sr{&s>&48uMh_*hH4``V>H1v!Wk`G_A5v6kM;HL>-QjVf1BsT^IN! zU&IM?muVAd^ZT_RZb0;;0ykMw13@=Y=ZaQ6mW!7*O}Mts#}+GZVWv9WbgP@49} z(EXE-7C*(!{cD1WR0l?Q2`g}DkmDK+zruBuZo5Kz^1RR3_6Hty+T3yWa1fWM_w6&V z(X=h$?%pI}5SC`0lmQxqWq+pTKgNx!_If~I7Zz(xF8)D=QXY@Hx9+9&RTm4H~9&|@WN&o8B-Jp>p99hoOiA%MN&)Eryfr%s`Tbc+2)p#X|ttGqCn?w`N z8YF@=!Ujs~#l9vsTRMF!?!z}rCK1$D9J}f>>8xL)o~E2kV!SiNcT)X_b+pb?r|R8F z(*L^mA}m*OWt~?!5^hSGq^WwUcOr5nI>;Dg50`97Qmw%9)VQ3R-qDj)w625Cw~!h? z4&W?!+6y@DiEP}pRx`ZHeMQ`bjvg`GhaE(dgCGW_^i8Fti`im<3Zyt=$)9-9}W0?VTF5G3Z=$wzCxpN6}1WNxfpqKA2 zJH$(<8otCTQew$4%2dUyB{H~C0+#ka-49U8HLjBcjex(i>O6YPXdVtda-1j?TsvZT z*8O03J(+zd|F7=rb@d{o`=vJG-<5Y7-@o`n^R?rQJPAbZ&Yo5NL?=ndePxZyIR85& z2%L$sQ?FynT>_0+i@~nFA*>C}w{%AeF_j$QKLD&kf`29+VyW8D&V7vRV~nn?R41Kx zusQqWn4D<=*wg{JZB60}gzWk|VrvJsX#z{bp zR(*#|1NP|@C)%#8*kaaS#u&Mpo_G0h%&6qM+@QOp-$X|8*_3)2!sQ9yhI{m<)YC2x zIc3u$W^gsqslQq=(WVFX|4S^sD_f-RKsst+Z448G!B zG7-J`(T{lRNaMDsQ3)RPuciiUfygX~2OgFko#8FQk#+V|>7WTcPzH(Dvrq zbd(}Fne4j5)!!%KPzf^DCg7%1(yDuO6tbW83;T;q@^bGk<;4j&TIea0EiyO;oQyNi4s6-X@iD)@jKDrvVNW>tdaV5!cLW~&-<%_5&Q=>WWE===gq#SKf<072;%L^rDv49F*?}a|^ zUdEL_AcJ)RrMb8CwR^q#EuxITKGyP7yVA2-T>6$U&lW$|J?_Q>vQYRtH~t}cEe4%j z*~_VKsg)n`>DweaFS#MbjW$btU}ql6$K%1+1U0vkve^t*`;gG6n*L$o-LW1@(B%>S zra@TXhlcA4MD|s?U z0n5=y?WVYQM$&Upiy==}%&mGv0Au@ZM5@)cM`#b@8&A(|&=%@*b^V$&wF>lbhyv{4 zka~$*r@bN8>Ko9aOudC~@~2t5&h8qzAW)7X;r!LtgXnyoALf)OV2dTqTRo`YTO6yG z;8+usHR+{fk_=Wua){VnG_sYfDTfJcYj$cG3d zHx%N+B*@$cm-TFXj7c)d2T!@YKS&soHBkmKAy=f&6+;zonD9Ar?%dqom_fGtO;YP^lFeN#02}j%L{YUwxACi zflJ@Ks7V;5GfArcpskPS{c=8S%+{|DuFx@Cm9ikZ;Y&*t2H&UQ4<+ZtHvpuWvH`A3 z$_K%5svgFVgf+Oqex^0lTmFn64P%fdO2|X@^-j3kDStu?S<3!8!Stu|GsepYV-8G8 zgoZ9)QNZ{qt5f%UVz-QcNgYrm!vqe7>6|}`@!t$mIMtdfP|WPjMkGV_;R(qERK79V zgj}bYPly&2)v`~Zay!sAP7IJsDKSUPtPUxdHIFJckMqWE^hpmXh>O3Ap*M6ctoBfo z7=c`wQEW?5;%N^zzJal&z^^q9aNMC$bC>eLOEw09uCdAJE-{o0`t=2QVWmmTKk?!c z&I9B_*Li<9KUuI;j0GYFg?QptHkiD$t1YHsHe5?IJ?k|Xva&A~eLVWh6{WW6;)PQ6 zwCU5kbMMfyr3H-Frci7~Ko6POMFtFGsLHGUl*AnyvM2jBrA0gRl;(xG0r10Z=JwyO-nhsm5U@B zVqh#{ai1S0a&>cSrQG1!@*qiVl!7kZFY2~DNEK-ES= z3n#gW%e*~P4`=OAYEW*bayO=BlNi=Ed9@1LndxD1^>$$z_f5jf}%>Oi5TqdJo#_Kj*=R)=CMnxX}d$Wi!@J&=7qUqX{dWCf{i8j2a9}+Fr6s1 zS9W|kH}Y>1tV0#UxE~q6y{SJkzI#(=vV7qR)(2*V?Tl9K@m+q0``_PWQ15#*6=SBn zI$E{2?ltW9cS5j|JN`EbL1*t!e0aHrY(9Pzu>ceNgsPxPWO~Y9umrJJM2%xjAKtCsHKFwrhT6Ws@4WbyKgfmkz9yvI zmej(}FTFQd!Z$jP@mjqwtYUncbXJ(=@vJa#v)FU7T<&v38W^fWsd-!-X2s_gG2VMX zsjxjK!=f2q4YY^O&ANN6;*-X)Fjyc4At}z6jnX{6vRI{gc^)I8cI+)bh7-TwE5S?I zwh7$e7bF{g#Kso{kG z<*om$NFmD_lbtD|d-)yHyvO?q>XB$(`m&&vkyu3T5GksxJCX7&tqg3gYu+2`dpg86 zO>CPcIo5hcStEIGNYu21X;`64a(YWrdc&9$r#5d-72J6$q?8PI<{vT!dh8|tdU1aL zl9}*>H}->TYgz)wtn|-B-5vV8gyl){8%okRtq)RV zbYrKh219|7rEhou0n3GZl`5Fkq-mBWWKLjPx?%Z@t&bRgCkPNf{L7Prw*N;aphMFB zBWgV4|3?OTBk|IA8ot7CyZi(1Ap~MM+;z%+)b$WI;O47~h zDR;SZcz9e~&ii`4xofzG|B>N1UF1tL09i^e#$D{5D}Jwiud?rirSk=>J?EW=r{^K>v zO~z$~mf`}-OgU8T@Ll|p>J{mi{DeN$=vUQ6TmPg_9VMrZ38_B2{XrsjM5(Dhr;f{> zJf%;Kf#uolUvZC-?azjV`o5Qk7i`{^DK)eqCjG&y9!*B~E0Uawd7q?hhp~e$F^t^_ z1x2Hn6(jCT?`xD*!Pq5&4|dhDi}Ctgr)ZL38NK3gVr4q_U!^&@^-L2sWd?41H?k#Q zy$U;_*4x=lhGCSM!s8_xHcT-6Ik8GL2qMS0^P9H~78z79hr35gGz-0!XDSn*1BnFmaarh}yt9^=%Q<~5t5ymAw9j0vE zjWSN7%$8G^k0ye^a!gb&!sV^n9pVWUbX*r6furbq4E#rk?FCqU`Ad(@$lvpq^JD-d z^ZfezSfM%nJNJ!H6wc%4w-5${eL0cjBq7eR0vidjjfKK*2(nJSP9a0W=vX7*i*?An zzz38Qk&ZXOmtt5zrEzXy(vwdVP7>Pwy}~9G2rfZ0Apb_dvg7jNPTmtfI0E_mZB>fr zh>UspX;6yyxb{kX{>H~QWaj~zm~xx9$ajG1%AS4m!Tsl1I7Mc2VLKz4fzr3jj$`lm z#UwusWP9yH9bAM06ZCv+Tmuz@xb)&6(vG9H*BAq@3tRMH+TtM@{@ z45xaYxLiRCPi=n`dpG$?ynWH*?6E=$ck@;AVYyo* zI(9^h-A8Uqh^R590zkpHA$em7q(_e(X@t?>Kj9GxJ!1vh)&Tcduq3>U3QbjSjWtl? zkZW84nzmk=c%>#$U!G8tw?F%6${BJMzq~V?3D^>cJyu%|BgYSHOyVY<6h##Ya#2<$ z;y#*u;8<-K;%>fdP52D7Zm$LrrzbZ<9V*T9UJu1ry1RM_P^)0ptjq1%1HrS8DrCTLVvJdnS3e|v;{0<-#G2ksVvvSVwG?); zAz-dgOLsR=l_*uHFzKnbDDF0X#F%H$oR=7aAHzUPuP!l11O`Ru6%h&Yf)pUc#u*iW z!AnlgMA;v$26;zs@}zjD$mPFy2=|&n-EaiVt(cKxRxt z$O(osv2{Ho8REeC_GeTb3C;bEFY3e{!JEcGu=Jz3EiOi`IP?%FBwQFFf-d5gKbhO@lMQ@Glfa zF0IpGT@f1oky|72q}cvKjyge$QfM#o){j3(@`!>MHwpo{C|K^IL_J}+Hg3)@QC56&We;pQ5sZ2Z$1}* z1z_3NTRMNoH%pEN+wY;fu^RJF@8TRK)GeFb@kC)eyAbPj^ITW7#u*J?LVHK~@%iBB= zh1S$NL_#-vat;Od_a7_f88O7M6(9o{L4D9WXR~_<~Cn3)%4FSWTUl zS6Kpu+X^+>WLq>3w%{EE#%x&60{O%uo|Swwl<%W&vSNB_ke!#a;rFm}4e)h>-HEyg zwu}W3%?>y6`y(C3R>L^hi?U$U%t2S5PLB)IqHaz+TF?yuE*Q(hkR~Hzn<6lr>(>ac_}P#C;p`{4tFDbv{nAHO*9RMp`u9%Yw0{EA z$J2aR^JA(0J^Kkcl^kMxsc4j0{|voy&QhSQ1^S6270vuFzqeFx{VSC9 zomADOphf_T!dZ^X;Vjj^XE-Kr;;ZY}kIFgYc~MZ20jQKQoKcn3FGJC6e0kYd|G$Sr z|Mv+K2%)e#^~;iAejW0jGCE<P>$L;|M&C@IqKv% zglcM7TW5|GUCaf$w6uNl?NDXa#a`(5r&HB zw8&90509VX_saqGPF>+`9jI}nhT1=oTjP+O*STAc)tvF&!e~2p;b{^>1=@GYV<{8^ z*a1Zre|e3(ptr(hS7NQoujU823&ljYPSSR6m%9?6(AK#P!)G##rz>9L4ELax9#$>{ z$V~H>9}CTWN0s%7LX}6X1B)~ecF#P{m;K7Y+K7mjaWuBLlPl%0jyxwGiHY`)VIUK~ zgrxW(Jla1(|0{GTC?+jAvb-NJdRo!~>Ov(FC4*#(N5f(+z=C}{)xJs2>W^W3SKUMz zakw}YX{`P@jA8o-#@{s40MB!CMv>bx0riREkz^UR2}U}9gB(?gDCCxuG_P{T^oTf? z!Q>fnb7iQ?B`tg19riiIPV!4|c69n6ta-EwY1blH-_qi@i}^|rQ?Nvp9C-)p^v6jF z8m#0k8K^wudtONU0h3A7-3-Ngia^`IE^h8ckqkk`b2*Fz()!9_iH!HKzFjE=jAGbe zyqtxXV;FA3MUfsmu>BW#Z$QdE@=|RQ@Y&2mH1_$hn8qCl8Ljw#G<|to6W8~4l1V1p zutQjfC6E9CWzi}sE}&9CT%d|e-B5{&+EHu2ZdlE*7%8?A+YVUTLMjp!t4SAeYbC7+ z3a!T4qLr#t6x^!mW>w7ljK9zO2V{~=X71eO+;g7uoO3J+1RQ2BdFdhe_B9ALEW?%9 z76J-ke2J0f7Nx%B`lbr)NG)cLI1bco`BFZY+T4!2IF41l+K*V3Hq5~zuf42*=3t~? zz?PhztHz={Jy$dLk7|+AU%n(i;Tejbsm?#;cNSegwrb>I;N z$|=-(57( zdWTz~CKvbYk?Sd$K9od%W$D2!&%y&4GokiIfu5IFCxXyZ9T&1u4{js@XB|N!!h70X z&nHL}YxfX3J@gGZe^e7Dxn3Karky>8A*20^P`U%b(k0!CIGqE{7BmxilYk={I@dDf z$V!NuMC}NXemPv;jCe_*K32j;9fT^WIR~+fjF+aMD9F?%xlN(h#)a}l97@MAl8F}H zi#QG_HF7YbQ>Lq)!Ymy>l5RuTx}DM&j{CzxI23wicmBu!QVX2f`aYt^y|CwptuOLF z`G+A_lU)#vPh^aLNz1s@KOmG^#z9fztCqHm8-W^ZXmQIpB=Y^ggJJ*w;FUj^XnZk* z&tB95mmvGsDs-lQk&KNzkNFRb!y-a$n{0iX2#?q@A5)`#6mJ=7MtIey(v&i*A;qhH zG!8T=Pz_Ka6}2mIhGsY@m^h(fm>0CU(X?h50Na%?q{c8xV?63ObqX<$L)_SyGcf(8 zGO~LUxI32!%~k>Q&I>8#I@s-lF<%E$azy^A5_qaX@hw2B6|bq)87TQRPVIS0)Emc( zzvr8(QovUrs}uIBz3fqfyc~fI83%$j7^Z2O z@aT^;(DtGAm99U4jV5gzO;tAdVojBNyIhIRs}_SGPTpLCr%q$I-+v-vMgw}pJRX1=N0o#$cwN&ARq8Y{IZf(J6C(*TS@K^V9v{6s@iL(q zM1^A8n1*XY%`e7zjI?t46#SYxN5!JhmpKig{%6b(!PL+R@UvVd;Af!>35+yzA|uaC zY<`P6mw5W`#I7`IqwK@ z(`2}^Elm!2CS%+dX5gB0lhb5WJ7r0$6z<8C9XQa!JXm|S0L==pVNiPM?;Y>z3A(N3$NKZp-njr!1s@*>mkv>=e zgc}oNh)NS+nWhjZ<-)c9OiYkx(LL^hhToy%seU1n)1iuOdOqz;_`;vV8Odbuz9#qn z_7IS;IQSgIOfbYkA7Pz@eMHm!kP$DHgfN1CPb{m-p^vL6EYW$e1vyXaG^qow~$Q_@s6)jIrswJ9lwuv(-_HW zpm3}CNcUVEcjCAo$9XtDkK;QyehtU%IPS&qbR2_cz4~_?&%pgx16^O;gE#p&{vO9S zaEw$GtL-@c4ac)^d>Y5tgF|NH_*)#Kv`okx9G}85$_|CRj$`PRtAD}qTpS~CZuMmx z&%<#uj(@`Od>o_N;cDa(30Z*SFL9i90dKIEKsAx!DagPc6t66x?e2?VT0lvlb)5_~ zViCZ;!+74J^XTqrXK=I_pB#F~NSnuT(knz150kbFxWp?2zkW+DuMsz=saB9J*YW1J zWtBN>^a-pDl|*Fb3$_R#pf0ZyHyrkyG$B}jW1rVd{QUB|ZD+g^zkuR)d5z|fXZ`gc z#LMs>Gm`1p+g1BO(F#DpOTPT>R=fovoy;iHZqL`#=N-1LvWzm@DG zs6mb?%byTVkEN7v$G6a};yXrG6X{v-vy@zxABDBn21H|Gde%}#@kwGcBmbCSYp9s^Q3k+?c#8xd2M^(fFl4tcYD*aE z@Qdlo0@BoRRrbTKZEDZcc34)QL{^slfNme6%5T~Bb;Q0Vs)&Em?Ed=^SbCzA%5s&1KzV9V63fSOde-P0mAE0$gh>Js%FJ_=&I zs2O*y_#bAgp$z;j@_ni1ogE?=Lv>pN7imM56Sz>G=Dpd7*=b$|?*LiS=cZQgh$pZU zAT}fV3utd&%wnW<>-Gxj2lH@6AK;n2Xd{A>40^QRjUkrDKtmG|tg!59~_opgwdlV7A9)#`3D67LgBhy%! zFg$j5c=)<#&=w_S%PxVimWXCtjS6&Q!tnxBr!1H;XiKi@usiSD0IN6#5PWMq_ewYM zD&UZ^E~F3mBIbBd($OGQI+Sdna|Z$wXRlDdgNufjQ=YP%TeTZg~@0Q2+21nw?;#GphUAAFau;95v`NjgOi zH?P8p4;!(FCjj}H;0MvB?=l&;DF4DS z4`<>duv78p6BVFIeaP`7! zv&5{73_f6<6p6|qd=KQ_+tReHZQ{`zBiZA_zp1mjSfB? z?juN};|0LFKLqWeemUJ6!Q>0WWfu1*ci$U`7dZi=HjZKr=dDY?L^^E_g!3??Z z4aR#RQeY$UuYOSt<6XZ9`8qrq=+&304Ta)A8Bz`*$`4Ld+J1(7Hq5%321sJB=R^PM z*Fc%I*NPncJ_a^sOa=N;FHj#o9gc)Xor}jgiiCh*_^8(7)9cql zdozz~7;yFx`v+TyW?jd5C-z-KRZRE^Pk<)2^W%=`fS*9%M5S4DH)MDwZYf`Rosy&X zYJ{i5(P;;=HZzj@?jeDkZMyYMn%mYxq;6eD{0qQIGTJw81Kxa;;>M)r&Meqs4t*ToHt z-%9e9>+wcLwXEA!wFxi3xR4`6wd{iHVliIMxgKxbg4gd{Rd3_vlnaSMRLj10UEGG3 zBd*5=yzF;Xv3U8+Wi7!=t&4vsN1Y(e<(rG*@5s#r245*72K-eL1JFdG)O*jw#};An z!y7Q}FYyUQW;4n#yo@^$ZV~og^oV%R&nQAT75F{D+_B#YPmK17^+qQ)%S_{1M*2Y# zPBupfOm)It07yHTfH|5DFwKlhTFUs|vKK(L(BKZm)K2Vr7ob6ven+%>oFXokLl~jJ zV>Iq_*5j1;=6381a5#Fmq9Dii)l9(jmCr-m@Ea&v(|f-I#$jZX(;GtVINHGgR@5c?k_Tc`!MNHH~ zYSdTKr#}{=LUr8`&z7Cw;TV9Hvaef&4Tt$(yo-4w_?+(+Ybkw9cnT87yYP?)L;g~X zTTVDdAlr_FW$Z19=`BN(TT)VpOmQ2P?~pyl$8#|sGW*~j?j=$uzDMush9C%k)E)kK zuiuexAQ2=btKk=G*y~|H3I{g*l(_ISk1A+D<;&1UqR{Mtb!|dPacJ;{CxF9eF!EhMB$uUn!=`DTx@ ztmwsle6;)at>X|I^KwED@9Sq29UCYf3bCTrd(5BBqtIctX*xy~V7LZ&Te?hK_#Am+ z3z6HN-G|G8u!_#?DG*%z08aX1?Ads@|Dg!rqc4OQYCa3z4iCML99THXdhB3i#zaPu z`XLjPswrobsi+7b+nS2B8WPq=@2$d9Yy@f_8dFL?!tr$YY%(D4T>%2NPEZeb4_S)S z!de(f8slkPT*uGp!ne_{_#_+bTpL6r8OMl8hEx|L@l_1Rcxu?ge>5vYkRqq-2(uf# zk+u;spW+9hc!#k5qze7NzIVNc$&ARUcSnN@6;gR0Pc@rL=R6#yffh_Ar z1?^NY-sNxf0|0x)i+{wOC6#R~41}jcdKk$HTZGVgMR)_BA1YBD5HQLrfM7epLn}Ls z&fe*ZC-wI#T;*Z@oKNIgjS)w(RN2mHumc)a06S?zkRIZTV1FBgwseG1Bo+v))rew) zO~Xc+U;fhxI(jgV>IFxR^Bu4h>#JY`(lakd2Oe$E>+lw+G7R1T*u5p=Z zuM)oacqT&yZ@-0tH1s1}9zt=eBgPh9Rl_fC6Q4R2f4B=}5o)kwmrMZefZ_uRV;qD+ z;e1RhLDENzXX#W(*{>E}3!;d0Kd~C*PRW&#uiC`PGsN_x(c+8&o?Tp33s49>FL`e@ z@Ph4thNgH`_E=FnUh>|?BL_U|EN?NAzqbAlwho{Dejn6H+llg~_IJc)f9~2iMbS zeH)H1xnTCH`z##IE&LlN9s;?-Q2Z&b99CaP_r`dj?mVgn#qjg3?#N$|o5Rp(gntz9 z=@)@*ym6NZ-da!Z_ccxMWG8stc;LAZ66d$wSHz3isp$T%s4$BgH*lBPCtp2u9L7H%UvY;ggY-J@n1J7L+1k{p7#O0q8+Vs;2^=f1ZsN;aR1>@Y9FX48_h2t3MVh6cEdkEp$L z;10fXAB4nPz1~k=MTsf-o z1V}U;9ms5QH<-I|pBTQJk?3PIC{*_>1y=Ud7*TEmU7L=)cx1X}=yEnzoNfvELvy!9oz}&I zwh|uAaMlNe3b`f6Ci@7t%{*PPc>O*_;*8VN)Z_6z!(D$s1Oe*Fk6K*b&&Zw%AX*ZU z^{6bdI{TEO@(NNJiHreo8_7$atbtec=xW^gmBd|t8KvOW%CKS$hvPahoFK`|%HI)l zSr3V1@L<^!uV~$@=*B9HVJ5@P{{tIs;c55a2{^YL8h&Xp6J!(=;oz@XOh7m~uwr@x z9V1FVyj86plC+O*QiF3NT^``S+|NjuMFB?HIG~Y_V>aPoc57qUeA@uyc|Jw&6I8o4 zPn40?NDKUsv5)dgjvC98I){WOFByxLcTY1J1`s1KmQRDtvdM6Z3~l7T5fduPLbvRv z`81-v$L@1C#Dt&!0lMWNt!ci`OXu~!Kk;Auw`sb#zKK&xhzVOir=7lJkFUfwfpqwa zt%vCSLc}jy?`PaXmUc$0w)yg%0-6zkrYVV+!mWoG>F}1r44L%#ee8%OuFQx=+9FD> z4`HtgS=mQbWQeLwY}PGnJeENz(~i(+=eX>}Yz$DWa&=x^X|t#xE5Q7#(5M}G!W75- zC?Uf5XQ+T=`CZV+{U;%YLMW7$P!>t{ahq~mYG<$-8o<%y4r~xVQv6dJc-P!JDL|Rc zBEih#!KcKXu!VdV9$+CG4t$2SZW5u6i3y>5RB7$>w3s zwQF5d%0}?E8FBW)w_5P?O>eR>6A*tWxg>&=JVFv-TRTZy3wyQr5Q97~q@i|!NT9?k zfm>5*MtXmxmB!@U3k1-R4bazc7#P!~X$Z(*WcQifd@b4SX{ticZ(^qdHe2!+(vGul%Qb^S0tiO z*vNIr*HZ$Vu_|Q1ulCJ<#w#mJSRJZZ*p0@4IMz92+`UTT<;iU8Df4!2_9${*4Gs)lK@qI&5&VRWUVP6_*8ip5=3ZrCy7s!e8 zscK2mfZzUp9&j`qn>6?kl5?ukruub?jNdyzMM(w?k#T!>{vna|6b<4dw$1IlkdLItO4L&+MBpqWXx_IV zm$KUR*xie2k)eJPL;3gudO6LwY2yLQV2XHk0_yUCH&xpL@1zf5J{NTZaERV&M-v#N zcPhm#%#l8}NZ*$4XjaW${GMi%+owC~9EZH#*9&zK` z#6_o3cu`^Kb;mAtZXEYaK@2BB_n#JVhD%WrIW*(70YYiRZbq>ID%J)@nT92U3=Z49 z-?-Sw)hh{qcZ6TjkD9Yn+rw*GZl2-JD2eE;tuz(Z>EX-{?s7A_TSl`n-&vkI2Bk8x zcLB7PTwKjaihXZ3(#`Iv9p<>X;T_KvU?VlIV&`;c)3E!#S zd%-G#Oo|ZIlY#v90eBNAD$JRU6wO9A3*3WC2Q$j0P+Fq00*rhnsH8@21x17boA_op zBUWC8wpP+gb2Sv91sq==6F;x&EWNGb^uB;0d-j-C&NC}F+M_l!ew@rmUI?2BtX;Em zlX=nxMzLrEs3D2?z@glL1Y>rP3Dm#T9-$xM1hBR?mSgpN6%S?Z+fkH%K_f@I5yKR1 zv@L!Jn4LX8aC6;=uvCD>acv|8xijbxftU`88dUwZ;Y+_qHISx$HE#oxAX)ei{wiR^ z!T>5Qpz6VhdiC*2QQR&E}Gql>gn&&hq9g94V ze4Up6j;N(Gn34RH!QJ)116gS{8pzjA-tac;$tQG3?*|o)Pm8~@7G7(k*m{nhW341 zV);su&V({3h$CZbguS=!G4k6h8|h53dh3!;lb6^rD%Ua_=?zl#()#43=JchXUr${rrYyI8B5=xRBoFvX6dQaG8Hp&bLj zr%5Es#|B~KFcMU78-?xJehpsf-fGe5gS%_b*<$TUD!&l|)3DhsPcqKR%EgxjXXrL^ivkTXQ3Ljlb(OJQ#1&ChV;0>EiafV` z=Iv4L`+}9!6eqQYn#UU>qTF_x)ga4UO$HT=Lgt7alu$O2pi`J;rROQwsKJcP+g|_I z?1=pZEGW+0LoXspc!mr2CdNcs`Md^f%m_$HAFU)?^_IA$k*;b5UvTCzaoTx08=QHA zH{lBytMpiCwh)C4R{s(XZ&ZY}gI@UX&AWFRzPX2xCt2ywA@A{_m@-4f97gu*bVgbm zl=vNA6uXlyJaG?jLWw^Feu;k-I!lguYLYL~&-SZ7!#(mQ0+&ES_J?4d&621Ko6-vp zB^Q1UT?Fy7Whr%x^5aY_%$P7L4m$q3IgRwi0Y8iQ^UD|7#}^+CFb_~5Ti$9n=mZtmQ)S+;m(yk zN>&vhGa){n8JsdTreeRi22oyHrLc-=5iWfGKYr=lvZ&U~}shX{zs03Q{Ua zyHq@HG~f+0UoAVMa! z!TQ<=66!|4mm6Dez^tNgA#@H9A6*W1wc+3R`kVe~1AeAR0p#v7KaeATqL&yvPOx5}9fO89l-)DJ&VB*u5^vVs%_C$shFrX2c)s^@M$$V5 zz||<6*hNzAIJwtw53b>o+F97|DDkXCiJ7}qev&mn1-``QSrz^P|8HpZ2mTuqP~t4p zR);`6sGa*K)j|>eokv>8kiz17)xuq+Z|<6~I5D$i+_-hK{PJIUh9(}L22uw!ZiQte z>|e9an~i~V*mu*pBr$BBC3x|5ZKH(@AP#rayJo>f5tn-uOK${wi+XC!@de2}`c zqvs8+I?PWAGYxL`fbR#aX!SZPGwk{$>= zRKS5wZU<;vdU|F@Hp@Fn-66uZ=fcBisGg)j^#k-W9c^GFLo5UdgF^?Yatzm+qE!dr zX&LcGa7Q*Wvc(o+=^kM$;5V&zn^yfupL~(=7|q|x!f${g6)>_O(Bpj zN_|O`o{p({XF?-)GLVRc{%1{Xvq;eKNMf}YoTYteIezqy&Kn*NHn^FNmXfieE@Yrzi~@L!`DDs!GG$<|sBYCIpK=67!BB zPe5rh1SCfxoz30kNC3b`A}|AB&{}_`yTtIQb_*SDIStYGs>O3^O!95k8GhQpKy7Ta zeuVlEaq$`*Zr{bmg;1NXb}-VNi7hA56XU&t&%qzz)eUue)M@)JMqVEd!5RT!Em>68 zf%+`Nv(j$*=Vyx1&Qj`Qg++35W6^QDa+^(Aa(0xoOVRQh7Z?o84InHvNOe$h;aE87 zFDQPeI*3(=9;xxH!PZtL)B6NkB3% zQk)nuG+a+(LgT9$36#-NBLdm_gNaxf6j)4cis6Dn2-*j?`zsb- zcV{w@2s#)t6dAm-LU=;DcqHtqk=q#snwf%CovsE|wKP47!bpK@K+)Cbi|?Oq_q5y4tBDE8z6f+)3VJ`^|ajQPR@;T!cyqS>(=im)ru)-~* zgpmZno(a0nxCKGf8G@aMw|4!&!p3$t(2#-6B1gRdCx7mOYK_L0Z9K;pr)v{guhVTE zz4z}jvh8zI+cL$-N0T{$YN&`xMi43y!0+nM5IfS~Y4#Sd+QBexglih66vB3Y1(!^BM>{&+n6d|LMuT9~nYA2P)R3FLpv0=@J*!Utw^6FAP zS;*{8aq}v8ffgf3lP@-AfrHl9k_~jC=m0jVWehpTru4sdBFV}_jF-^pnz3hiK@yo{ zzDk%e^WO+1vat;tJoPtVVr@#E6x!P5YTkk-r!K+isXw`FsI|Sqc77oL-h<|y&pB~bKiIW9ikDeT(!3pOxh(;P-wF=4Gpkat;_Cz&>qn|V}` zo+V%b)EHU#45Ai6ZHTV@nUclft7R$~?GBf;$QSeWt5mFy7|9GeJNT½R~}!o_--tDR&bz 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 delta 153513 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%0A;JwRs8~6UGY;zI1f84s&eULoKvt6ZK+gu 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ÄQ;O)y=}99>pO<-Na*+{`4#wlY2zA(Jeg2M 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 blaPmR+PadH>4+IM#1pUAix~nM^m_jfGt0$} From f68af9bda61ff80a2f8f74f28480d18ed61fc288 Mon Sep 17 00:00:00 2001 From: fgilmar Date: Tue, 26 Sep 2017 16:21:06 +0200 Subject: [PATCH 038/113] README: add supported digi APIX Signed-off-by: fgilmar --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f3737b44..972657536 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,11 @@ Documentation is available online on the Digi documentation site: ## 2.2-r3 -* TBC +* Added Digi APIX C library to access and manage ConnectCore platforms interfaces: + * GPIO + * SPI + * I2C + * PWM ## 2.2-r2 From 9aa7c620aab2a4e5aea0ead97a4ea009e4829cbd Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Tue, 26 Sep 2017 18:52:59 +0200 Subject: [PATCH 039/113] Revert "networkmanager: connectivity check: set interface for DNS resolution" The implemented patch fails when NetworkManager uses a local DNS cache underneath (like 'dnsmasq'). To access the local DNS cache it needs to use the loopback interface and hardcoding the physical interfaces make the connectivity check fail. This reverts commit c9b02d628812cadf02a8f1245ebe3fa405e4a26b. Signed-off-by: Javier Viguera --- ...figure-network-interface-for-DNS-res.patch | 38 ------------------- .../networkmanager/networkmanager_%.bbappend | 1 - 2 files changed, 39 deletions(-) delete mode 100644 meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch deleted file mode 100644 index e18331c9a..000000000 --- a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-connectivity-configure-network-interface-for-DNS-res.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Javier Viguera -Date: Thu, 14 Sep 2017 13:29:52 +0200 -Subject: [PATCH] connectivity: configure network interface for DNS resolution - -Use the same interface that it's being checked for the DNS resolution. - -This makes connectivity check work in an scenario where the primary -interface has lost connectivity (for example ethernet) but you still -have connectivity through a secondary interface (e.g. wireless). - -What happens in that case is that even though you have correct -connectivity in the secondary interface the check fails because it does -not use that secondary interface to resolve the name of the test URL. -The result is that the connectivity check assumes that this secondary -interface is also failing and it penalizes the metrics in the routing -table. - -This commit uses libcurl's CURLOPT_DNS_INTERFACE to set the DNS -interface. Notice that this requires 'libcurl' to be compiled with -'--enable-ares'. - -Signed-off-by: Javier Viguera ---- - src/nm-connectivity.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c -index 6f16b28e56ca..c12f145c2ad8 100644 ---- a/src/nm-connectivity.c -+++ b/src/nm-connectivity.c -@@ -365,6 +365,7 @@ nm_connectivity_check_async (NMConnectivity *self, - curl_easy_setopt (ehandle, CURLOPT_PRIVATE, cb_data); - curl_easy_setopt (ehandle, CURLOPT_HTTPHEADER, cb_data->request_headers); - curl_easy_setopt (ehandle, CURLOPT_INTERFACE, cb_data->ifspec); -+ curl_easy_setopt (ehandle, CURLOPT_DNS_INTERFACE, iface); - curl_multi_add_handle (priv->curl_mhandle, ehandle); - - cb_data->timeout_id = g_timeout_add_seconds (30, timeout_cb, cb_data); diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend index 887fe5d0d..f744aa2d4 100644 --- a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend @@ -12,7 +12,6 @@ SRC_URI += " \ file://nm.eth1.static \ file://nm.wlan0.dhcp \ file://nm.wlan0.static \ - file://0001-connectivity-configure-network-interface-for-DNS-res.patch \ " # 'polkit' depends on 'consolekit', and this requires 'x11' distro feature. So From 84b38d75b1c25938c7489496b8fb576f394f91f9 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Tue, 26 Sep 2017 18:53:31 +0200 Subject: [PATCH 040/113] networkmanager: enable the use of 'dnsmasq' server This is needed in the context of network failover, so when one physical interface is lost, you can still resolve the connectivity-check URL using the local DNS cache. https://jira.digi.com/browse/DEL-4787 Signed-off-by: Javier Viguera --- .../networkmanager/networkmanager/NetworkManager.conf | 1 + .../networkmanager/networkmanager_%.bbappend | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/NetworkManager.conf b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/NetworkManager.conf index 10810a323..ad683c98e 100644 --- a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/NetworkManager.conf +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/NetworkManager.conf @@ -1,6 +1,7 @@ [main] plugins=ifupdown,keyfile no-auto-default=type:ethernet +dns=dnsmasq rc-manager=file [ifupdown] diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend index f744aa2d4..b2bf4f7f7 100644 --- a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend @@ -22,7 +22,7 @@ EXTRA_OECONF += "--enable-polkit=disabled" PACKAGECONFIG_remove = "consolekit" # Adjust other compile time options to save space -PACKAGECONFIG_remove = "dnsmasq netconfig nss" +PACKAGECONFIG_remove = "netconfig nss" PACKAGECONFIG_append = " concheck gnutls modemmanager ppp" # From bfdd5e5bfe7746c2819826f6afaff0003cf03e17 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Tue, 26 Sep 2017 18:54:04 +0200 Subject: [PATCH 041/113] dnsmasq: configure package to be used by NetworkManager NM launches 'dnsmasq' using DBus, so enable DBus support at compile time. Also remove the symlinks in the different runlevels, so it's not launched by the included bootscript. https://jira.digi.com/browse/DEL-4787 Signed-off-by: Javier Viguera --- meta-digi-dey/recipes-support/dnsmasq/dnsmasq_%.bbappend | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 meta-digi-dey/recipes-support/dnsmasq/dnsmasq_%.bbappend diff --git a/meta-digi-dey/recipes-support/dnsmasq/dnsmasq_%.bbappend b/meta-digi-dey/recipes-support/dnsmasq/dnsmasq_%.bbappend new file mode 100644 index 000000000..10804155e --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/dnsmasq_%.bbappend @@ -0,0 +1,8 @@ +# Copyright (C) 2017, Digi International Inc. + +# Enable DBUS support so it can be used from NetworkManager +PACKAGECONFIG_append = " dbus" + +# NetworkManager will launch 'dnsmasq' using DBUS, so disable the creation +# of runlevel's symlinks. +INHIBIT_UPDATERCD_BBCLASS = "1" From 74b734f0953d3d054cae7a3efcb0f5a01febfce3 Mon Sep 17 00:00:00 2001 From: Francisco Gil Date: Fri, 29 Sep 2017 14:05:05 +0200 Subject: [PATCH 042/113] meta-digi-arm: firmware-atheros: update binary. CC6 PS_ASIC_class_1.pst MD5SUM be8766069eed652449682d9006dd6ecd https://jira.digi.com/browse/DEL-5057 Signed-off-by: Francisco Gil --- .../firmware-atheros/firmware-atheros/PS_ASIC_class_1.pst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/PS_ASIC_class_1.pst b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/PS_ASIC_class_1.pst index d749a0774..0155e02ee 100644 --- a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/PS_ASIC_class_1.pst +++ b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros/PS_ASIC_class_1.pst @@ -72,10 +72,10 @@ # [H:S]0013 [H:S]00F0 -[H:A]C1 C1 20 02 BD 08 FE FE C9 00 00 CC B1 01 20 00 +[H:A]C1 C1 20 02 BD 08 FE FE C2 00 00 CC B1 01 20 00 FF CC 02 CC 04 00 B6 FB A9 90 00 21 00 E0 FF CC 08 CC 1E 00 80 84 00 07 DB 05 93 11 FF CC 0E CC - 0B 00 E4 FF 61 47 00 00 4D FD 61 47 00 00 58 FD + 0A 00 E4 FF 61 47 00 00 4D FD 61 47 00 00 58 FD E8 FF 41 27 04 00 6F FD 41 27 04 00 6C FD EC FF A0 A7 00 00 2F FD A0 A7 00 00 6D FD F0 FF 60 27 01 00 50 FD 60 27 01 00 6F FD F4 FF A0 C7 04 00 @@ -83,8 +83,7 @@ 80 C7 08 00 58 FD FC FF 40 47 09 00 66 FD 40 47 09 00 0B FD 00 00 80 C7 0D 00 09 FD 80 C7 0D 00 09 FD 04 00 20 47 0E 40 58 FD 20 47 0E 40 58 FD - 08 00 40 47 12 40 58 FD 40 47 12 40 58 FD 0C 00 - 40 47 12 40 58 FD 40 47 12 40 58 FD FF CC 0F CC + 08 00 40 47 12 40 58 FD 40 47 12 40 58 FD FF CC 0F CC 01 01 01 01 07 04 03 33 00 0A 00 04 00 00 60 6D F0 00 66 01 00 00 00 00 00 00 FF CC 10 CC 22 81 From 7d2a07cf2ffc5e9a8882946367250efb861dd3a6 Mon Sep 17 00:00:00 2001 From: Tatiana Leon Date: Mon, 2 Oct 2017 20:29:23 +0200 Subject: [PATCH 043/113] dey-image: create an sdk/toolchain dey version file with params to identify it This commit creates a new file called 'dey-version-${REAL_MULTIMACH_TARGET_SYS}' (for example, 'dey-version-cortexa7hf-neon-dey-linux-gnueabi') at the same level as 'version-${REAL_MULTIMACH_TARGET_SYS}', 'site-config-${REAL_MULTIMACH_TARGET_SYS}', and 'environment-setup-${REAL_MULTIMACH_TARGET_SYS}' files. The file contains the following parameters: * Machine. The name of the platform the toolchain was built for (ccimx6sbc, ccimx6ulsbc, ccimx6ulstarter). * Version: A versioning system for the generated toolchains. Currently is the distro version followed by the timestamp on which the current build started. * Image: The name of the image that triggered the population of the SDK (core-image-base, dey-image-aws, dey-image-qt-${GRAPHICAL_BACKEND}) The purpose of the 'dey-version-*' file is to be parsed by Eclipse so toolchains can be autodetected. This file is packaged with the rest of SDK/toolchain resources ('version-*', 'site-config-*', and 'environment-setup-*' files, and 'sysroots' directory) when creating the SDK tarball and later the installation script. The 'dey-version-*' file could also be created in a 'meta-environment.bbappend' appending to the 'create_sdk_files()'. But from this recipe there is no access to the name of the image that triggers the creation of the SDK (core-image-base, dey-image-aws, dey-image-qt, etc.). Currently, we are redefining 'SDK_POSTPROCESS_COMMAND' (from 'poky/meta/classes/populate_sdk_base.bbclass') to insert the generation of the 'dey-version-*' file just before creating the SDK tarball. https://jira.digi.com/browse/DEL-5074 Signed-off-by: Tatiana Leon --- meta-digi-dey/classes/dey-image.bbclass | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/meta-digi-dey/classes/dey-image.bbclass b/meta-digi-dey/classes/dey-image.bbclass index 8d19292dd..cea4ffe8d 100644 --- a/meta-digi-dey/classes/dey-image.bbclass +++ b/meta-digi-dey/classes/dey-image.bbclass @@ -32,3 +32,27 @@ inherit ${@bb.utils.contains("IMAGE_FEATURES", "dey-qt", "populate_sdk_qt5", "", # DEY_IMAGE_INSTALLER ?= "0" inherit ${@base_conditional("DEY_IMAGE_INSTALLER", "1", "dey-image-installer", "", d)} + +# +# Create a dey-version file when populating the toolchain/SDK +# +# 'SDK_POSTPROCESS_COMMAND' variable is originally defined in populate_sdk_base +# class: poky/meta/classes/populate_sdk_base.bbclass +# It is redefined here to be able to tweak the resulting SDK before packaging, +# using the proper 'IMAGE_BASENAME' value. +# +SDK_PREPACKAGING_COMMAND ?= "toolchain_create_sdk_dey_version" +SDK_POSTPROCESS_COMMAND = " create_sdk_files; check_sdk_sysroots; ${SDK_PREPACKAGING_COMMAND}; tar_sdk; ${SDK_PACKAGING_COMMAND} " + +# This function creates a DEY version information file +fakeroot toolchain_create_sdk_dey_version() { + local deyversionfile="${SDK_OUTPUT}/${SDKPATH}/dey-version-${REAL_MULTIMACH_TARGET_SYS}" + + rm -f $deyversionfile + touch $deyversionfile + echo 'Machine: ${MACHINE}' >> $deyversionfile + echo 'Version: ${DISTRO_VERSION}-${DATETIME}' >> $deyversionfile + echo 'Image: ${IMAGE_BASENAME}' >> $deyversionfile +} +toolchain_create_sdk_dey_version[vardepsexclude] = "DATETIME" + From a5cfaa921d182cc862c10bcf4c58b0c01166cd2b Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Wed, 4 Oct 2017 15:48:16 +0200 Subject: [PATCH 044/113] cellular: Enable IPV6 support. This commit enables the IPV6 support that is necessary for the XBee Cellular LTE Cat1 modem. Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-4839 --- .../networkmanager/networkmanager/nm.cellular | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/nm.cellular b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/nm.cellular index b282aba1e..679945f3e 100644 --- a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/nm.cellular +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/nm.cellular @@ -14,4 +14,4 @@ lcp-echo-failure=3 lcp-echo-interval=5 [ipv6] -method=ignore +method=auto From 0e5ff61a7976738ed21423a1dc555d849c2cf03e Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Mon, 9 Oct 2017 17:48:17 +0200 Subject: [PATCH 045/113] cryptodev: fix compilation error for kernel v4.9 The patch is needed to match the API kernel changes. This fixes: zc.c:68:44: error: passing argument 7 of 'get_user_pages_remote' from incompatible pointer type [-Werror=incompatible-pointer-types] (unsigned long)addr, pgcount, write, 0, pg, NULL); ^~ In file included from zc.c:28:0: kernel-source/include/linux/mm.h:1276:6: note: expected 'struct vm_area_struct **' but argument is of type 'struct page **' long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, ^~~~~~~~~~~~~~~~~~~~~ zc.c:63:8: error: too many arguments to function 'get_user_pages_remote' ret = get_user_pages_remote( ^~~~~~~~~~~~~~~~~~~~~ In file included from zc.c:28:0: kernel-source/include/linux/mm.h:1276:6: note: declared here long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, ^~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors https://jira.digi.com/browse/DEL-5081 Signed-off-by: Jose Diaz de Grenu --- ...-another-change-in-the-user-page-API.patch | 32 +++++++++++++++++++ .../cryptodev/cryptodev-module_%.bbappend | 6 +++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module/0002-Adjust-to-another-change-in-the-user-page-API.patch diff --git a/meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module/0002-Adjust-to-another-change-in-the-user-page-API.patch b/meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module/0002-Adjust-to-another-change-in-the-user-page-API.patch new file mode 100644 index 000000000..73313f380 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module/0002-Adjust-to-another-change-in-the-user-page-API.patch @@ -0,0 +1,32 @@ +From: Michael Weiser +Date: Fri, 11 Nov 2016 18:09:32 +0100 +Subject: [PATCH] Adjust to another change in the user page API + +4.9.0 will replace the write and force flags of get_user_pages_remote() +with a gup_flags parameter[1]. Distinguish the two APIs based on kernel +version we're compiling for. + +[1] https://github.com/torvalds/linux/commit/9beae1ea89305a9667ceaab6d0bf46a045ad71e7 +--- + zc.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/zc.c b/zc.c +index a97b49f75327..e766ee3eabc7 100644 +--- a/zc.c ++++ b/zc.c +@@ -65,7 +65,13 @@ int __get_userbuf(uint8_t __user *addr, uint32_t len, int write, + ret = get_user_pages( + #endif + task, mm, +- (unsigned long)addr, pgcount, write, 0, pg, NULL); ++ (unsigned long)addr, pgcount, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) ++ write ? FOLL_WRITE : 0, ++#else ++ write, 0, ++#endif ++ pg, NULL); + up_read(&mm->mmap_sem); + if (ret != pgcount) + return -EINVAL; diff --git a/meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module_%.bbappend b/meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module_%.bbappend index 087f298e1..ce1d97772 100644 --- a/meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module_%.bbappend +++ b/meta-digi-arm/recipes-kernel/cryptodev/cryptodev-module_%.bbappend @@ -1,3 +1,7 @@ -# Copyright (C) 2016 Digi International. +# Copyright (C) 2016-2017 Digi International Inc. + +FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" + +SRC_URI_append = " file://0002-Adjust-to-another-change-in-the-user-page-API.patch" KERNEL_MODULE_AUTOLOAD = "cryptodev" From bba0c0d7958d0c34fca419a2d70fb1198dca5ad5 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Tue, 10 Oct 2017 10:03:59 +0200 Subject: [PATCH 046/113] libsoc: Remove platform board.conf files This commit removes the platform board.conf files from libsoc. Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-5096 --- .../libsoc/libsoc-git/ccimx6sbc/board.conf | 43 ------------------- .../libsoc/libsoc-git/ccimx6ulsbc/board.conf | 36 ---------------- .../libsoc-git/ccimx6ulstarter/board.conf | 36 ---------------- .../libsoc/libsoc_git.bbappend | 10 +---- 4 files changed, 1 insertion(+), 124 deletions(-) delete mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf delete mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf delete mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf deleted file mode 100644 index c9559ae0f..000000000 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6sbc/board.conf +++ /dev/null @@ -1,43 +0,0 @@ -[board] -model = Digi International ConnectCore 6 Single Board Computer. - -[GPIO] - -# USER LED (RED) - GPIO02_IO02 -USER_LED = 34 - -# USER LED (ORANGE) - GPIO02_IO03 -USER_LED_2 = 35 - -# USER LED (GREEN) - GPIO02_IO04 -USER_LED_3 = 36 - -# USER BUTTON - GPIO02_IO05 -USER_BUTTON = 37 - -[I2C] - -# I2C-3 on I2C board connector. -DEFAULT_I2C_BUS = 2 - -[SPI] - -# SPI-1 on SPI board connector. -DEFAULT_SPI = 0,0 - -[PWM] - -# PWM1 on LCD board connector (pin 10). -DEFAULT_PWM = 0,0 - -[ADC] - -# HWMON Driver -DEFAULT_ADC_DRIVER = 1 - -# IIO Device 0 -DEFAULT_DEVICE_INDEX = 0 - -# PMIC_ADCIN1 on GPIO board connector (Pin 1) -DEFAULT_ADC_LINE = 1 - diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf deleted file mode 100644 index 06e16cfba..000000000 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulsbc/board.conf +++ /dev/null @@ -1,36 +0,0 @@ -[board] -model = Digi International ConnectCore 6UL SBC. - -[GPIO] - -# USER LED - I/O Expander IO23 -USER_LED = 488 - -# USER BUTTON - MCA_IO1 -USER_BUTTON = 505 - -[I2C] - -# I2C-1 on I2C board connector. -DEFAULT_I2C_BUS = 0 - -[SPI] - -# SPI-1 on SPI board connector. -DEFAULT_SPI = 0,0 - -[PWM] - -# PWM4 on GPIO board connector (pin 11). -DEFAULT_PWM = 0,0 - -[ADC] - -# IIO Driver -DEFAULT_ADC_DRIVER = 0 - -# IIO Device 0 -DEFAULT_DEVICE_INDEX = 0 - -# ADC1_IN2 on GPIO board connector (pin 13) -DEFAULT_ADC_LINE = 2 diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf b/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf deleted file mode 100644 index c26d171ad..000000000 --- a/meta-digi-dey/recipes-support/libsoc/libsoc-git/ccimx6ulstarter/board.conf +++ /dev/null @@ -1,36 +0,0 @@ -[board] -model = Digi International ConnectCore 6UL Starter Board. - -[GPIO] - -# USER LED - GPIO03_IO11 -USER_LED = 75 - -# USER BUTTON - GPIO03_IO03 -USER_BUTTON = 67 - -[I2C] - -# I2C-2 on Expansion connector. -DEFAULT_I2C_BUS = 1 - -[SPI] - -# SPI-3 on Expansion connector. -DEFAULT_SPI = 2,0 - -[PWM] - -# PWM1 on Expansion connector (pin 27). -DEFAULT_PWM = 0,0 - -[ADC] - -# IIO Driver -DEFAULT_ADC_DRIVER = 0 - -# IIO Device 1 -DEFAULT_DEVICE_INDEX = 1 - -# ADC1_IN4 on Expansion connector (pin 7). -DEFAULT_ADC_LINE = 4 diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend index 959c174d3..04ef0b60d 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend +++ b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend @@ -1,20 +1,12 @@ # Copyright (C) 2017 Digi International Inc. -FILESEXTRAPATHS_prepend := "${THISDIR}/${BP}:" - LIBSOC_URI_STASH = "${DIGI_MTK_GIT}dey/libsoc.git;protocol=ssh" LIBSOC_URI_GITHUB = "git://github.com/jackmitch/libsoc.git;protocol=git" LIBSOC_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${LIBSOC_URI_STASH}', '${LIBSOC_URI_GITHUB}', d)}" SRC_URI = " \ ${LIBSOC_URI};branch=${SRCBRANCH} \ - file://board.conf \ " -PACKAGECONFIG = "enableboardconfig python" +PACKAGECONFIG = "python" -do_configure_prepend() { - install -m 0644 ${WORKDIR}/board.conf ${S}/contrib/board_files/${BOARD}.conf -} - -PACKAGE_ARCH = "${MACHINE_ARCH}" From b56c4ecc650c74c18da7694cec387a8d55ef41ca Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Tue, 10 Oct 2017 14:09:06 +0200 Subject: [PATCH 047/113] libdigiapix: Add platform board files This commit adds the some platform board files and removes the symbolic link to libsoc.conf Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-5096 --- .../libdigiapix-git/ccimx6sbc/board.conf | 43 +++++++++++++++++++ .../libdigiapix-git/ccimx6ulsbc/board.conf | 36 ++++++++++++++++ .../ccimx6ulstarter/board.conf | 36 ++++++++++++++++ .../libdigiapix/libdigiapix_git.bb | 9 ++-- 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf create mode 100644 meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf create mode 100644 meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf new file mode 100644 index 000000000..c9559ae0f --- /dev/null +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf @@ -0,0 +1,43 @@ +[board] +model = Digi International ConnectCore 6 Single Board Computer. + +[GPIO] + +# USER LED (RED) - GPIO02_IO02 +USER_LED = 34 + +# USER LED (ORANGE) - GPIO02_IO03 +USER_LED_2 = 35 + +# USER LED (GREEN) - GPIO02_IO04 +USER_LED_3 = 36 + +# USER BUTTON - GPIO02_IO05 +USER_BUTTON = 37 + +[I2C] + +# I2C-3 on I2C board connector. +DEFAULT_I2C_BUS = 2 + +[SPI] + +# SPI-1 on SPI board connector. +DEFAULT_SPI = 0,0 + +[PWM] + +# PWM1 on LCD board connector (pin 10). +DEFAULT_PWM = 0,0 + +[ADC] + +# HWMON Driver +DEFAULT_ADC_DRIVER = 1 + +# IIO Device 0 +DEFAULT_DEVICE_INDEX = 0 + +# PMIC_ADCIN1 on GPIO board connector (Pin 1) +DEFAULT_ADC_LINE = 1 + diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf new file mode 100644 index 000000000..06e16cfba --- /dev/null +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf @@ -0,0 +1,36 @@ +[board] +model = Digi International ConnectCore 6UL SBC. + +[GPIO] + +# USER LED - I/O Expander IO23 +USER_LED = 488 + +# USER BUTTON - MCA_IO1 +USER_BUTTON = 505 + +[I2C] + +# I2C-1 on I2C board connector. +DEFAULT_I2C_BUS = 0 + +[SPI] + +# SPI-1 on SPI board connector. +DEFAULT_SPI = 0,0 + +[PWM] + +# PWM4 on GPIO board connector (pin 11). +DEFAULT_PWM = 0,0 + +[ADC] + +# IIO Driver +DEFAULT_ADC_DRIVER = 0 + +# IIO Device 0 +DEFAULT_DEVICE_INDEX = 0 + +# ADC1_IN2 on GPIO board connector (pin 13) +DEFAULT_ADC_LINE = 2 diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf new file mode 100644 index 000000000..c26d171ad --- /dev/null +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf @@ -0,0 +1,36 @@ +[board] +model = Digi International ConnectCore 6UL Starter Board. + +[GPIO] + +# USER LED - GPIO03_IO11 +USER_LED = 75 + +# USER BUTTON - GPIO03_IO03 +USER_BUTTON = 67 + +[I2C] + +# I2C-2 on Expansion connector. +DEFAULT_I2C_BUS = 1 + +[SPI] + +# SPI-3 on Expansion connector. +DEFAULT_SPI = 2,0 + +[PWM] + +# PWM1 on Expansion connector (pin 27). +DEFAULT_PWM = 0,0 + +[ADC] + +# IIO Driver +DEFAULT_ADC_DRIVER = 0 + +# IIO Device 1 +DEFAULT_DEVICE_INDEX = 1 + +# ADC1_IN4 on Expansion connector (pin 7). +DEFAULT_ADC_LINE = 4 diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb index e10d4ef6a..35a5fa76e 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb @@ -16,7 +16,10 @@ LIBDIGIAPIX_URI_GITHUB = "git://github.com/digi-embedded/libdigiapix.git;protoco LIBDIGIAPIX_GIT_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${LIBDIGIAPIX_URI_STASH}', '${LIBDIGIAPIX_URI_GITHUB}', d)}" -SRC_URI = "${LIBDIGIAPIX_GIT_URI};branch=${SRCBRANCH}" +SRC_URI = " \ + ${LIBDIGIAPIX_GIT_URI};branch=${SRCBRANCH} \ + file://board.conf \ +" S = "${WORKDIR}/git" @@ -25,8 +28,8 @@ inherit pkgconfig do_install() { oe_runmake 'DESTDIR=${D}' install - # Create a link to 'libsoc.conf' file that is installed by libsoc recipe install -d ${D}${sysconfdir}/ - ln -sf libsoc.conf ${D}${sysconfdir}/${BPN}.conf + install -m 0644 ${WORKDIR}/board.conf ${D}${sysconfdir}/libdigiapix.conf } +PACKAGE_ARCH = "${MACHINE_ARCH}" From b06513e4027fc10d885531df62eea66820d71c08 Mon Sep 17 00:00:00 2001 From: Francisco Gil Martinez Date: Mon, 9 Oct 2017 10:49:34 +0200 Subject: [PATCH 048/113] libdigiapix: add Digi APIX examples recipe These examples show how to use the Digi APIX. https://jira.digi.com/browse/DEL-5097 Signed-off-by: Francisco Gil Martinez --- .../dey-examples/dey-examples-digiapix.bb | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 meta-digi-dey/recipes-digi/dey-examples/dey-examples-digiapix.bb diff --git a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-digiapix.bb b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-digiapix.bb new file mode 100644 index 000000000..32ae4e863 --- /dev/null +++ b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-digiapix.bb @@ -0,0 +1,34 @@ +# Copyright (C) 2017, Digi International Inc. + +SUMMARY = "DEY Digi APIX examples" +SECTION = "examples" +LICENSE = "ISC" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/ISC;md5=f3b90e78ea0cffb20bf5cca7947a896d" + +DEPENDS = "libdigiapix" + +SRCBRANCH = "master" +SRCREV = "${AUTOREV}" + +LIBDIGIAPIX_STASH = "${DIGI_MTK_GIT}dey/dey-examples.git;protocol=ssh" +LIBDIGIAPIX_GITHUB = "${DIGI_GITHUB_GIT}/dey-examples.git;protocol=git" + +LIBDIGIAPIX_GIT_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${LIBDIGIAPIX_STASH}', '${LIBDIGIAPIX_GITHUB}', d)}" + +SRC_URI = "${LIBDIGIAPIX_GIT_URI};branch=${SRCBRANCH}" + +S = "${WORKDIR}/git" + +inherit pkgconfig + +EXTRA_OEMAKE += "-f libdigiapix-examples.mk" + +do_compile() { + oe_runmake +} + +do_install() { + oe_runmake DESTDIR=${D} install +} + +COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" From d434043447a93e727cb75e537daae94b1e21b109 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Wed, 27 Sep 2017 10:56:51 +0200 Subject: [PATCH 049/113] bluez5: start bluetooth daemon with experimental flag The experimental flag is needed to run the GATT server application. https://jira.digi.com/browse/DEL-5023 Signed-off-by: Isaac Hermida --- meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend index 7e54c309c..57c32f083 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -43,6 +43,9 @@ do_install_append() { install -d ${D}${sysconfdir}/init.d/ install -m 0755 ${WORKDIR}/bluetooth-init ${D}${sysconfdir}/init.d/bluetooth-init install -m 0644 ${WORKDIR}/main.conf ${D}${sysconfdir}/bluetooth/ + if [ -n "${@bb.utils.contains('PACKAGECONFIG', 'experimental', 'experimental', '', d)}" ]; then + sed -i '/^SSD_OPTIONS/a SSD_OPTIONS="${SSD_OPTIONS} --experimental"' ${D}${INIT_D_DIR}/bluetooth + fi } PACKAGES =+ "${PN}-init" From 16a99ac65c63bb59398e86f0d5203cce14380681 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Wed, 27 Sep 2017 10:14:20 +0200 Subject: [PATCH 050/113] bluez5: update gatt server example to master version https://jira.digi.com/browse/DEL-5023 Signed-off-by: Isaac Hermida --- ...ver-update-example-to-master-version.patch | 124 ++++++++++++++++++ .../bluez/bluez5_5.41.bbappend | 1 + 2 files changed, 125 insertions(+) create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0027-example-gatt-server-update-example-to-master-version.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0027-example-gatt-server-update-example-to-master-version.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0027-example-gatt-server-update-example-to-master-version.patch new file mode 100644 index 000000000..081a65dbc --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0027-example-gatt-server-update-example-to-master-version.patch @@ -0,0 +1,124 @@ +From: Isaac Hermida +Date: Wed, 27 Sep 2017 10:00:15 +0200 +Subject: [PATCH] example-gatt-server: update example to master version + +Current test example was not registering correctly the services, so the BLEGATT +server was not working properly. +Update this example to current version in master (commit ed63d7e5a9f6). + +Note: In order to run it, the bluetoothd daemon needs to be started with the +experimental (-E) flag and needs to enable and advertise the BLE +functionallity (btmgmt le on/connectable on/advertisement on). + +https://jira.digi.com/browse/DEL-5023 + +Signed-off-by: Isaac Hermida +--- + test/example-gatt-server | 28 +++++++++++++++++++++------- + 1 file changed, 21 insertions(+), 7 deletions(-) + +diff --git a/test/example-gatt-server b/test/example-gatt-server +index 84905f3d0856..24aaff973b11 100755 +--- a/test/example-gatt-server ++++ b/test/example-gatt-server +@@ -42,6 +42,9 @@ class FailedException(dbus.exceptions.DBusException): + + + class Application(dbus.service.Object): ++ """ ++ org.bluez.GattApplication1 interface implementation ++ """ + def __init__(self, bus): + self.path = '/' + self.services = [] +@@ -74,6 +77,9 @@ class Application(dbus.service.Object): + + + class Service(dbus.service.Object): ++ """ ++ org.bluez.GattService1 interface implementation ++ """ + PATH_BASE = '/org/bluez/example/service' + + def __init__(self, bus, index, uuid, primary): +@@ -121,6 +127,9 @@ class Service(dbus.service.Object): + + + class Characteristic(dbus.service.Object): ++ """ ++ org.bluez.GattCharacteristic1 interface implementation ++ """ + def __init__(self, bus, index, uuid, flags, service): + self.path = service.path + '/char' + str(index) + self.bus = bus +@@ -195,6 +204,9 @@ class Characteristic(dbus.service.Object): + + + class Descriptor(dbus.service.Object): ++ """ ++ org.bluez.GattDescriptor1 interface implementation ++ """ + def __init__(self, bus, index, uuid, flags, characteristic): + self.path = characteristic.path + '/desc' + str(index) + self.bus = bus +@@ -222,7 +234,7 @@ class Descriptor(dbus.service.Object): + if interface != GATT_DESC_IFACE: + raise InvalidArgsException() + +- return self.get_properties()[GATT_CHRC_IFACE] ++ return self.get_properties()[GATT_DESC_IFACE] + + @dbus.service.method(GATT_DESC_IFACE, + in_signature='a{sv}', +@@ -426,7 +438,7 @@ class TestService(Service): + TEST_SVC_UUID = '12345678-1234-5678-1234-56789abcdef0' + + def __init__(self, bus, index): +- Service.__init__(self, bus, index, self.TEST_SVC_UUID, False) ++ Service.__init__(self, bus, index, self.TEST_SVC_UUID, True) + self.add_characteristic(TestCharacteristic(bus, 0, self)) + self.add_characteristic(TestEncryptCharacteristic(bus, 1, self)) + self.add_characteristic(TestSecureCharacteristic(bus, 2, self)) +@@ -523,11 +535,11 @@ class TestEncryptCharacteristic(Characteristic): + CharacteristicUserDescriptionDescriptor(bus, 3, self)) + + def ReadValue(self, options): +- print('TestCharacteristic Read: ' + repr(self.value)) ++ print('TestEncryptCharacteristic Read: ' + repr(self.value)) + return self.value + + def WriteValue(self, value, options): +- print('TestCharacteristic Write: ' + repr(value)) ++ print('TestEncryptCharacteristic Write: ' + repr(value)) + self.value = value + + class TestEncryptDescriptor(Descriptor): +@@ -564,16 +576,16 @@ class TestSecureCharacteristic(Characteristic): + ['secure-read', 'secure-write'], + service) + self.value = [] +- self.add_descriptor(TestEncryptDescriptor(bus, 2, self)) ++ self.add_descriptor(TestSecureDescriptor(bus, 2, self)) + self.add_descriptor( + CharacteristicUserDescriptionDescriptor(bus, 3, self)) + + def ReadValue(self, options): +- print('TestCharacteristic Read: ' + repr(self.value)) ++ print('TestSecureCharacteristic Read: ' + repr(self.value)) + return self.value + + def WriteValue(self, value, options): +- print('TestCharacteristic Write: ' + repr(value)) ++ print('TestSecureCharacteristic Write: ' + repr(value)) + self.value = value + + +@@ -636,6 +648,8 @@ def main(): + + mainloop = GObject.MainLoop() + ++ print('Registering GATT application...') ++ + service_manager.RegisterApplication(app.get_path(), {}, + reply_handler=register_app_cb, + error_handler=register_app_error_cb) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend index 57c32f083..45b7f10d3 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -8,6 +8,7 @@ SRC_URI += " \ file://0001-hcitool-do-not-show-unsupported-refresh-option.patch \ file://0002-hcitool-increase-the-shown-connection-limit-to-20.patch \ file://0025-port-test-discovery-to-python3.patch \ + file://0027-example-gatt-server-update-example-to-master-version.patch \ " SRC_URI_append_ccimx6ul = " \ From df7225abfe4d645bb143f20fe2ef7c55d481b3af Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 5 Oct 2017 08:59:23 +0200 Subject: [PATCH 051/113] pointercal-xinput: remove support for ccardimx28 Signed-off-by: Arturo Buzarra --- .../pointercal-xinput/ccardimx28/pointercal.xinput | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 meta-digi-dey/recipes-graphics/xinput-calibrator/pointercal-xinput/ccardimx28/pointercal.xinput diff --git a/meta-digi-dey/recipes-graphics/xinput-calibrator/pointercal-xinput/ccardimx28/pointercal.xinput b/meta-digi-dey/recipes-graphics/xinput-calibrator/pointercal-xinput/ccardimx28/pointercal.xinput deleted file mode 100644 index d6d9582ac..000000000 --- a/meta-digi-dey/recipes-graphics/xinput-calibrator/pointercal-xinput/ccardimx28/pointercal.xinput +++ /dev/null @@ -1,2 +0,0 @@ -xinput set-int-prop "mxs-lradc" "Evdev Axis Calibration" 32 4200 269 4020 250 -xinput set-int-prop "mxs-lradc" "Evdev Axes Swap" 8 1 From 62588b9f3d5c2384e9f187adf18a2a690648370c Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 10 Oct 2017 08:51:45 +0200 Subject: [PATCH 052/113] linux-dey: add recipe for version 4.9 At the moment it only suppports ccimx6ul. https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- .../linux/linux-dey-4.9/ccimx6ul/defconfig | 362 ++++++++++++++++++ .../recipes-kernel/linux/linux-dey_4.9.bb | 9 + 2 files changed, 371 insertions(+) create mode 100644 meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig create mode 100644 meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig new file mode 100644 index 000000000..58431835d --- /dev/null +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig @@ -0,0 +1,362 @@ +CONFIG_KERNEL_LZO=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZ4 is not set +CONFIG_EXPERT=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PERF_EVENTS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_ARCH_MXC=y +CONFIG_SOC_IMX6UL=y +# CONFIG_SWP_EMULATE is not set +CONFIG_ARM_ERRATA_764369=y +CONFIG_SMP=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_VMSPLIT_2G=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_CMA=y +CONFIG_SECCOMP=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_ARM_IMX6Q_CPUFREQ=y +CONFIG_CPU_IDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_PM_DEBUG=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +CONFIG_LLC2=y +CONFIG_CAN=y +CONFIG_CAN_FLEXCAN=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_IBS=y +CONFIG_CFG80211=y +CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_CFG80211_WEXT=y +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_REGULATOR=y +CONFIG_RFKILL_GPIO=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=0 +CONFIG_IMX_WEIM=y +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_GPMI_NAND=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_FASTMAP=y +CONFIG_MTD_UBI_BLOCK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_SMSC_PHY=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_ASYNC=y +CONFIG_USB_USBNET=y +# CONFIG_USB_NET_AX8817X is not set +# CONFIG_USB_NET_AX88179_178A is not set +CONFIG_USB_NET_CDC_EEM=y +CONFIG_USB_NET_CDC_MBIM=y +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_USB_NET_QMI_WWAN=y +CONFIG_USB_SIERRA_NET=y +CONFIG_HOSTAP=y +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_IMX=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_FUSION_7_10=y +CONFIG_TOUCHSCREEN_IMX6UL_TSC=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MCA_CC6UL_PWRKEY=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_FSL_OTP=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_IMX=y +CONFIG_I2C_IMX_LPI2C=y +CONFIG_SPI=y +CONFIG_SPI_GPIO=y +CONFIG_SPI_IMX=y +CONFIG_SPI_FSL_LPSPI=y +CONFIG_SPI_SPIDEV=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_MCA_CC6UL=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_POWER_SUPPLY=y +# CONFIG_MXC_MMA8451 is not set +CONFIG_THERMAL=y +CONFIG_CPU_THERMAL=y +CONFIG_IMX_THERMAL=y +CONFIG_DEVICE_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_MCA_CC6UL_WATCHDOG=y +CONFIG_IMX2_WDT=y +CONFIG_MFD_MCA_IOEXP=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_ANATOP=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_PFUZE100=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_MXC_OUTPUT=y +CONFIG_VIDEO_MXC_CAPTURE=y +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=y +# CONFIG_MXC_IPU_PRP_ENC is not set +CONFIG_VIDEO_MXC_PXP_V4L2=y +CONFIG_VIDEO_MXC_CSI_CAMERA=y +CONFIG_MXC_SUBDEV_CAMERA_OV5640=y +CONFIG_MXC_SUBDEV_CAMERA_OV5642=y +CONFIG_SOC_CAMERA=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_CODA=y +CONFIG_FB=y +# CONFIG_FB_MX3 is not set +CONFIG_FB_MXS=y +CONFIG_FB_MXC_SYNC_PANEL=y +CONFIG_FB_MXC_LDB=y +# CONFIG_FB_MXC_EDID is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_LOGO=y +CONFIG_FB_LOGO_CENTERED=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_FSL_ASRC=y +CONFIG_SND_IMX_SOC=y +CONFIG_SND_SOC_IMX_MAX98088=y +CONFIG_SND_SOC_IMX_SPDIF=y +CONFIG_SND_SOC_FSL_ASOC_CARD=y +CONFIG_USB=y +CONFIG_USB_OTG_WHITELIST=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MXC=y +CONFIG_USB_HCD_TEST_MODE=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_QUALCOMM=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +CONFIG_USB_SERIAL_OPTION=y +CONFIG_USB_EHSET_TEST_FIXTURE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MXS_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_FSL_USB2=y +CONFIG_USB_ETH=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_MXC_IPU=y +CONFIG_MXC_SIM=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_DRV_MCA_CC6UL=y +CONFIG_RTC_DRV_MXC=y +CONFIG_RTC_DRV_SNVS=y +CONFIG_DMADEVICES=y +CONFIG_IMX_SDMA=y +CONFIG_MXS_DMA=y +CONFIG_MXC_PXP_V2=y +CONFIG_MXC_PXP_V3=y +CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_IIO=y +CONFIG_MCA_CC6UL_ADC=y +CONFIG_VF610_ADC=y +CONFIG_TAMPER_MCA_CC6UL=y +CONFIG_PWM=y +CONFIG_PWM_IMX=y +# CONFIG_RESET_GPIO is not set +CONFIG_NVMEM_IMX_OCOTP=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_AUTOFS4_FS=y +CONFIG_OVERLAY_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_UBIFS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FTRACE is not set +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=y +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_RMD128=y +CONFIG_CRYPTO_RMD160=y +CONFIG_CRYPTO_RMD256=y +CONFIG_CRYPTO_RMD320=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_TGR192=y +CONFIG_CRYPTO_WP512=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_CAMELLIA=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_DEV_FSL_CAAM=y +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y +CONFIG_CRC_T10DIF=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_VIRTUALIZATION=y diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb new file mode 100644 index 000000000..d53b97ec2 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb @@ -0,0 +1,9 @@ +# Copyright (C) 2017 Digi International + +require recipes-kernel/linux/linux-dey.inc +require recipes-kernel/linux/linux-dtb.inc + +SRCBRANCH = "v4.9.11/master" +SRCREV = "${AUTOREV}" + +COMPATIBLE_MACHINE = "(ccimx6ul)" From 957e8623a5a985410b2657de0c8e3695711c737c Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 17 Oct 2017 12:10:46 +0200 Subject: [PATCH 053/113] sysinfo: fix IOEXP and MCA kernel nodes This commit modifies sysinfo tool to use the kernel symlinks for the devices instead of using the full node path and maintain compatibility with different kernel versions. Signed-off-by: Arturo Buzarra --- meta-digi-dey/recipes-digi/sysinfo/sysinfo/sysinfo | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/meta-digi-dey/recipes-digi/sysinfo/sysinfo/sysinfo b/meta-digi-dey/recipes-digi/sysinfo/sysinfo/sysinfo index 9d0695a87..f21c798e1 100755 --- a/meta-digi-dey/recipes-digi/sysinfo/sysinfo/sysinfo +++ b/meta-digi-dey/recipes-digi/sysinfo/sysinfo/sysinfo @@ -266,13 +266,13 @@ BOARD_SN="$(cat /proc/device-tree/digi,hwid,sn)" BOARD_VERSION="$(cat /proc/device-tree/digi,carrierboard,version)" BOARD_ID="$(cat /proc/device-tree/digi,carrierboard,id)" if grep -qs '\' /proc/device-tree/compatible; then - MCA_NODE="/sys/devices/platform/soc/2100000.aips-bus/21a0000.i2c/i2c-0/0-007e" + MCA_NODE="/sys/bus/i2c/devices/0-007e" MCA_HW_VERSION=$(cat ${MCA_NODE}/hw_version) || MCA_HW_VERSION="??" MCA_FW_VERSION=$(cat ${MCA_NODE}/fw_version) || MCA_FW_VERSION="??" MCA_VERSION="HW_VERSION=${MCA_HW_VERSION} FW_VERSION=${MCA_FW_VERSION}" fi -IOEXP_NODE="/sys/devices/platform/soc/2100000.aips-bus/21a0000.i2c/i2c-0/0-006e" +IOEXP_NODE="/sys/bus/i2c/devices/0-006e" if [ -d "$IOEXP_NODE" ]; then IOEXP_HW_VERSION=$(cat ${IOEXP_NODE}/hw_version 2>/dev/null) || IOEXP_HW_VERSION="??" IOEXP_FW_VERSION=$(cat ${IOEXP_NODE}/fw_version 2>/dev/null) || IOEXP_FW_VERSION="??" @@ -297,7 +297,7 @@ printf "\n\n" echo "|| Firmware | ${DISTRO}-${DEY_VERSION}-$(cat /etc/version)" echo "|| Kernel | $(uname -a)" echo "|| meta-digi | $(sed -ne '/^meta-digi-dey/s,.*= \(.*\)$,\1,g;T;p' /etc/build)" - [ -n "${MCA_VERSION}" ] && echo "|| Kinetis | ${MCA_VERSION}" + [ -n "${MCA_VERSION}" ] && echo "|| MCA | ${MCA_VERSION}" [ -n "${IOEXP_VERSION}" ] && echo "|| I/O Expander | ${IOEXP_VERSION}" printf "\n\n" ) | tee ${FILE} From 8e6ce42528cd8021cb7102d16b9435e5cd6a13db Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 3 Oct 2017 14:24:40 +0200 Subject: [PATCH 054/113] meta-digi-arm: add support for ccimx6qpsbc platform Add initial support for Digi's ConnectCore 6 QuadPlus SBC. The ccimx6qp platform has the QCA6564 chip instead of the other Atheros chips and included the Atmel ECC508A cryptographic chip. https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- meta-digi-arm/conf/machine/ccimx6qpsbc.conf | 38 +++ meta-digi-arm/conf/machine/ccimx6sbc.conf | 7 + meta-digi-arm/conf/machine/include/ccimx6.inc | 4 +- .../conf/machine/include/digi-defaults.inc | 3 +- sdk/build-github.sh | 3 +- sdk/build.sh | 1 + sdk/config/ccimx6qpsbc/bblayers.conf.sample | 22 ++ sdk/config/ccimx6qpsbc/conf-notes.txt | 18 ++ sdk/config/ccimx6qpsbc/local.conf.sample | 255 ++++++++++++++++++ 9 files changed, 346 insertions(+), 5 deletions(-) create mode 100644 meta-digi-arm/conf/machine/ccimx6qpsbc.conf create mode 100644 sdk/config/ccimx6qpsbc/bblayers.conf.sample create mode 100644 sdk/config/ccimx6qpsbc/conf-notes.txt create mode 100644 sdk/config/ccimx6qpsbc/local.conf.sample diff --git a/meta-digi-arm/conf/machine/ccimx6qpsbc.conf b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf new file mode 100644 index 000000000..440a20689 --- /dev/null +++ b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf @@ -0,0 +1,38 @@ +#@TYPE: Machine +#@NAME: ConnectCore 6 QuadPlus Single Board Computer. +#@DESCRIPTION: Machine configuration for Digi's ConnectCore 6 QuadPlus SBC. + +# Include the machine configuration for Digi's ConnectCore 6 module. +include conf/machine/include/ccimx6.inc + +# Wireless external module +WIRELESS_MODULE_append = " ${@base_conditional('HAVE_WIFI', '1', 'kernel-module-qualcomm', '', d)}" + +# Wireless p2p interface +WLAN_P2P_INTERFACE ?= "p2p0" + +MACHINE_EXTRA_RRECOMMENDS += "cryptoauthlib" + +# Firmware +MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1', 'firmware-qualcomm-qca6564-bt', '', d)}" +MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1', 'firmware-qualcomm-qca6564-wifi', '', d)}" + +# U-Boot configurations +# Last one is the default (the one the symlinks point at) +UBOOT_CONFIG ??= "ccimx6qpsbc2GB" +UBOOT_CONFIG[ccimx6qpsbc2GB] = "ccimx6qpsbc2GB_defconfig" + +KERNEL_DEVICETREE ?= " \ + imx6qp-ccimx6qpsbc-wb.dtb \ +" + +SERIAL_CONSOLES ?= "115200;ttymxc3" + +# Bluetooth tty +BT_TTY ?= "ttymxc1" + +# U-Boot script to be copied to the boot image +BOOT_SCRIPTS = "boot.scr:boot.scr" + +# Flash image types +IMAGE_FSTYPES ?= "boot.vfat ext4 sdcard tar.bz2 recovery.vfat" diff --git a/meta-digi-arm/conf/machine/ccimx6sbc.conf b/meta-digi-arm/conf/machine/ccimx6sbc.conf index 38d494206..1f1a96d93 100644 --- a/meta-digi-arm/conf/machine/ccimx6sbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6sbc.conf @@ -5,6 +5,13 @@ # Contains the ConnectCore 6 module. include conf/machine/include/ccimx6.inc +# To be removed (rng-tools) once kernel 3.14 is deprecated +MACHINE_EXTRA_RRECOMMENDS += "rng-tools" + +# Firmware +MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1' , 'firmware-atheros-ar3k', '', d)}" +MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1' , 'firmware-atheros-ath6kl', '', d)}" + # U-Boot configurations # Last one is the default (the one the symlinks point at) UBOOT_CONFIG ??= "ccimx6dlsbc512MB ccimx6dlsbc ccimx6qsbc2GB ccimx6qsbc512MB ccimx6qsbc" diff --git a/meta-digi-arm/conf/machine/include/ccimx6.inc b/meta-digi-arm/conf/machine/include/ccimx6.inc index b3477ba03..e638551ce 100644 --- a/meta-digi-arm/conf/machine/include/ccimx6.inc +++ b/meta-digi-arm/conf/machine/include/ccimx6.inc @@ -20,8 +20,6 @@ WIRELESS_MODULE ?= "" MACHINE_FIRMWARE ?= "" MACHINE_FIRMWARE_append_mx6q = " firmware-imx-vpu-imx6q" MACHINE_FIRMWARE_append_mx6dl = " firmware-imx-vpu-imx6d" -MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1' , 'firmware-atheros-ar3k', '', d)}" -MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1' , 'firmware-atheros-ath6kl', '', d)}" MACHINE_EXTRA_RDEPENDS += " \ e2fsprogs-mke2fs \ @@ -30,6 +28,6 @@ MACHINE_EXTRA_RDEPENDS += " \ u-boot-fw-utils \ " MACHINE_EXTRA_RRECOMMENDS += "${MACHINE_FIRMWARE} ${WIRELESS_MODULE}" -MACHINE_EXTRA_RRECOMMENDS += "imx-alsa-plugins cryptodev-module rng-tools" +MACHINE_EXTRA_RRECOMMENDS += "imx-alsa-plugins cryptodev-module" MACHINE_FEATURES += "accel-graphics accel-video wifi bluetooth" diff --git a/meta-digi-arm/conf/machine/include/digi-defaults.inc b/meta-digi-arm/conf/machine/include/digi-defaults.inc index 29567ceff..78d76a3ad 100644 --- a/meta-digi-arm/conf/machine/include/digi-defaults.inc +++ b/meta-digi-arm/conf/machine/include/digi-defaults.inc @@ -11,7 +11,8 @@ PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg" # Platform Linux U-Boot # ------------------------------------------------- # ccimx6 4.1, 3.14 2015.04 -# ccimx6ul 4.1 2015.04 +# ccimx6qp 4.9 2015.04 +# ccimx6ul 4.9, 4.1 2015.04 # # Help variables used in recipes diff --git a/sdk/build-github.sh b/sdk/build-github.sh index ec71e09a3..2c1af809e 100755 --- a/sdk/build-github.sh +++ b/sdk/build-github.sh @@ -22,7 +22,7 @@ set -e -AVAILABLE_PLATFORMS="ccimx6sbc ccimx6ulsbc ccimx6ulstarter" +AVAILABLE_PLATFORMS="ccimx6qpsbc ccimx6sbc ccimx6ulsbc ccimx6ulstarter" MANIFEST_URL="https://github.com/digi-embedded/dey-manifest.git" @@ -119,6 +119,7 @@ while read _pl _tgt; do [ -n "${DY_TARGET}" ] && _tgt="${DY_TARGET}" || true eval "${_pl}_tgt=\"${_tgt}\"" done<<-_EOF_ + ccimx6qpsbc dey-image-qt ccimx6sbc dey-image-qt ccimx6ulsbc dey-image-qt ccimx6ulstarter core-image-base diff --git a/sdk/build.sh b/sdk/build.sh index 82d45c1c3..e11e88c9a 100755 --- a/sdk/build.sh +++ b/sdk/build.sh @@ -169,6 +169,7 @@ while read _pl _var _tgt; do eval "${_pl}_var=\"${_var//,/ }\"" eval "${_pl}_tgt=\"${_tgt//,/ }\"" done<<-_EOF_ + ccimx6qpsbc DONTBUILDVARIANTS dey-image-qt,dey-image-aws ccimx6sbc DONTBUILDVARIANTS dey-image-qt,dey-image-aws ccimx6ulsbc DONTBUILDVARIANTS dey-image-qt,dey-image-aws ccimx6ulstarter DONTBUILDVARIANTS core-image-base,dey-image-aws diff --git a/sdk/config/ccimx6qpsbc/bblayers.conf.sample b/sdk/config/ccimx6qpsbc/bblayers.conf.sample new file mode 100644 index 000000000..bc2ef9645 --- /dev/null +++ b/sdk/config/ccimx6qpsbc/bblayers.conf.sample @@ -0,0 +1,22 @@ +# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf +# changes incompatibly +POKY_BBLAYERS_CONF_VERSION = "2" + +BBPATH = "${TOPDIR}" +BBFILES ?= "" + +BBLAYERS ?= " \ + ##OEROOT##/meta \ + ##OEROOT##/meta-poky \ + ##OEROOT##/meta-yocto-bsp \ + ##DIGIBASE##/meta-openembedded/meta-oe \ + ##DIGIBASE##/meta-openembedded/meta-python \ + ##DIGIBASE##/meta-openembedded/meta-networking \ + ##DIGIBASE##/meta-openembedded/meta-webserver \ + ##DIGIBASE##/meta-qt5 \ + ##DIGIBASE##/meta-swupdate \ + ##DIGIBASE##/meta-freescale \ + ##DIGIBASE##/meta-fsl-demos \ + ##DIGIBASE##/meta-digi/meta-digi-arm \ + ##DIGIBASE##/meta-digi/meta-digi-dey \ + " diff --git a/sdk/config/ccimx6qpsbc/conf-notes.txt b/sdk/config/ccimx6qpsbc/conf-notes.txt new file mode 100644 index 000000000..ed1cd5158 --- /dev/null +++ b/sdk/config/ccimx6qpsbc/conf-notes.txt @@ -0,0 +1,18 @@ +Digi Embedded Yocto provides the following image recipes: + + * dey-image-qt: graphical QT image + + By default the image is X11-based so it provides a full SATO theme + desktop environment. + + To compile the image for the framebuffer (instead of X11) add the + following line to the project's conf/local.conf: + + DISTRO_FEATURES_remove = "x11" + + * dey-image-aws: console-only image supporting Amazon Web Services IoT + + This image includes the AWS Greengrass Core and an AWS IoT platform + example application. For more information on AWS support in Digi + Embedded Yocto see the online documentation. + diff --git a/sdk/config/ccimx6qpsbc/local.conf.sample b/sdk/config/ccimx6qpsbc/local.conf.sample new file mode 100644 index 000000000..6b857638b --- /dev/null +++ b/sdk/config/ccimx6qpsbc/local.conf.sample @@ -0,0 +1,255 @@ +# +# This file is your local configuration file and is where all local user settings +# are placed. The comments in this file give some guide to the options a new user +# to the system might want to change but pretty much any configuration option can +# be set in this file. More adventurous users can look at local.conf.extended +# which contains other examples of configuration which can be placed in this file +# but new users likely won't need any of them initially. +# +# Lines starting with the '#' character are commented out and in some cases the +# default values are provided as comments to show people example syntax. Enabling +# the option is a question of removing the # character and making any change to the +# variable as required. + +# +# Machine Selection +# +# You need to select a specific machine to target the build with. There are a selection +# of emulated machines available which can boot and run in the QEMU emulator: +# +#MACHINE ?= "qemuarm" +#MACHINE ?= "qemuarm64" +#MACHINE ?= "qemumips" +#MACHINE ?= "qemumips64" +#MACHINE ?= "qemuppc" +#MACHINE ?= "qemux86" +#MACHINE ?= "qemux86-64" +# +# There are also the following hardware board target machines included for +# demonstration purposes: +# +#MACHINE ?= "beaglebone" +#MACHINE ?= "genericx86" +#MACHINE ?= "genericx86-64" +#MACHINE ?= "mpc8315e-rdb" +#MACHINE ?= "edgerouter" +# +# This sets the default machine to be qemux86 if no other machine is selected: +#MACHINE ??= "qemux86" + +MACHINE = "ccimx6qpsbc" + +# +# Use Digi's internal git repositories +# +#DIGI_INTERNAL_GIT ?= "1" + +# +# Where to place downloads +# +# During a first build the system will download many different source code tarballs +# from various upstream projects. This can take a while, particularly if your network +# connection is slow. These are all stored in DL_DIR. When wiping and rebuilding you +# can preserve this directory to speed up this part of subsequent builds. This directory +# is safe to share between multiple builds on the same machine too. +# +# The default is a downloads directory under TOPDIR which is the build directory. +# +#DL_DIR ?= "${TOPDIR}/downloads" + +# +# Where to place shared-state files +# +# BitBake has the capability to accelerate builds based on previously built output. +# This is done using "shared state" files which can be thought of as cache objects +# and this option determines where those files are placed. +# +# You can wipe out TMPDIR leaving this directory intact and the build would regenerate +# from these files if no changes were made to the configuration. If changes were made +# to the configuration, only shared state files where the state was still valid would +# be used (done using checksums). +# +# The default is a sstate-cache directory under TOPDIR. +# +#SSTATE_DIR ?= "${TOPDIR}/sstate-cache" + +# +# Where to place the build output +# +# This option specifies where the bulk of the building work should be done and +# where BitBake should place its temporary files and output. Keep in mind that +# this includes the extraction and compilation of many applications and the toolchain +# which can use Gigabytes of hard disk space. +# +# The default is a tmp directory under TOPDIR. +# +#TMPDIR = "${TOPDIR}/tmp" + +# +# Default policy config +# +# The distribution setting controls which policy settings are used as defaults. +# The default value is fine for general Yocto project use, at least initially. +# Ultimately when creating custom policy, people will likely end up subclassing +# these defaults. +# +DISTRO ?= "dey" +# As an example of a subclass there is a "bleeding" edge policy configuration +# where many versions are set to the absolute latest code from the upstream +# source control systems. This is just mentioned here as an example, its not +# useful to most new users. +# DISTRO ?= "poky-bleeding" + +# +# Package Management configuration +# +# This variable lists which packaging formats to enable. Multiple package backends +# can be enabled at once and the first item listed in the variable will be used +# to generate the root filesystems. +# Options are: +# - 'package_deb' for debian style deb files +# - 'package_ipk' for ipk files are used by opkg (a debian style embedded package manager) +# - 'package_rpm' for rpm style packages +# E.g.: PACKAGE_CLASSES ?= "package_rpm package_deb package_ipk" +# We default to rpm: +PACKAGE_CLASSES ?= "package_rpm" + +# +# SDK target architecture +# +# This variable specifies the architecture to build SDK items for and means +# you can build the SDK packages for architectures other than the machine you are +# running the build on (i.e. building i686 packages on an x86_64 host). +# Supported values are i686 and x86_64 +#SDKMACHINE ?= "i686" + +# +# Extra image configuration defaults +# +# The EXTRA_IMAGE_FEATURES variable allows extra packages to be added to the generated +# images. Some of these options are added to certain image types automatically. The +# variable can contain the following options: +# "dbg-pkgs" - add -dbg packages for all installed packages +# (adds symbol information for debugging/profiling) +# "dev-pkgs" - add -dev packages for all installed packages +# (useful if you want to develop against libs in the image) +# "ptest-pkgs" - add -ptest packages for all ptest-enabled packages +# (useful if you want to run the package test suites) +# "tools-sdk" - add development tools (gcc, make, pkgconfig etc.) +# "tools-debug" - add debugging tools (gdb, strace) +# "eclipse-debug" - add Eclipse remote debugging support +# "tools-profile" - add profiling tools (oprofile, lttng, valgrind) +# "tools-testapps" - add useful testing tools (ts_print, aplay, arecord etc.) +# "debug-tweaks" - make an image suitable for development +# e.g. ssh root access has a blank password +# There are other application targets that can be used here too, see +# meta/classes/image.bbclass and meta/classes/core-image.bbclass for more details. +# We default to enabling the debugging tweaks. +EXTRA_IMAGE_FEATURES ?= "debug-tweaks" + +# +# Additional image features +# +# The following is a list of additional classes to use when building images which +# enable extra features. Some available options which can be included in this variable +# are: +# - 'buildstats' collect build statistics +# - 'image-mklibs' to reduce shared library files size for an image +# - 'image-prelink' in order to prelink the filesystem image +# - 'image-swab' to perform host system intrusion detection +# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink +# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extended +USER_CLASSES ?= "buildstats image-mklibs image-prelink" + +# +# Runtime testing of images +# +# The build system can test booting virtual machine images under qemu (an emulator) +# after any root filesystems are created and run tests against those images. To +# enable this uncomment this line. See classes/testimage(-auto).bbclass for +# further details. +#TEST_IMAGE = "1" +# +# Interactive shell configuration +# +# Under certain circumstances the system may need input from you and to do this it +# can launch an interactive shell. It needs to do this since the build is +# multithreaded and needs to be able to handle the case where more than one parallel +# process may require the user's attention. The default is iterate over the available +# terminal types to find one that works. +# +# Examples of the occasions this may happen are when resolving patches which cannot +# be applied, to use the devshell or the kernel menuconfig +# +# Supported values are auto, gnome, xfce, rxvt, screen, konsole (KDE 3.x only), none +# Note: currently, Konsole support only works for KDE 3.x due to the way +# newer Konsole versions behave +#OE_TERMINAL = "auto" +# By default disable interactive patch resolution (tasks will just fail instead): +PATCHRESOLVE = "noop" + +# +# Disk Space Monitoring during the build +# +# Monitor the disk space during the build. If there is less that 1GB of space or less +# than 100K inodes in any key build location (TMPDIR, DL_DIR, SSTATE_DIR), gracefully +# shutdown the build. If there is less that 100MB or 1K inodes, perform a hard abort +# of the build. The reason for this is that running completely out of space can corrupt +# files and damages the build in ways which may not be easily recoverable. +# It's necesary to monitor /tmp, if there is no space left the build will fail +# with very exotic errors. +BB_DISKMON_DIRS = "\ + STOPTASKS,${TMPDIR},1G,100K \ + STOPTASKS,${DL_DIR},1G,100K \ + STOPTASKS,${SSTATE_DIR},1G,100K \ + STOPTASKS,/tmp,100M,100K \ + ABORT,${TMPDIR},100M,1K \ + ABORT,${DL_DIR},100M,1K \ + ABORT,${SSTATE_DIR},100M,1K \ + ABORT,/tmp,10M,1K" + +# +# Shared-state files from other locations +# +# As mentioned above, shared state files are prebuilt cache data objects which can +# used to accelerate build time. This variable can be used to configure the system +# to search other mirror locations for these objects before it builds the data itself. +# +# This can be a filesystem directory, or a remote url such as http or ftp. These +# would contain the sstate-cache results from previous builds (possibly from other +# machines). This variable works like fetcher MIRRORS/PREMIRRORS and points to the +# cache locations to check for the shared objects. +# NOTE: if the mirror uses the same structure as SSTATE_DIR, you need to add PATH +# at the end as shown in the examples below. This will be substituted with the +# correct path within the directory structure. +#SSTATE_MIRRORS ?= "\ +#file://.* http://someserver.tld/share/sstate/PATH;downloadfilename=PATH \n \ +#file://.* file:///some/local/dir/sstate/PATH" + + +# +# Qemu configuration +# +# By default qemu will build with a builtin VNC server where graphical output can be +# seen. The two lines below enable the SDL backend too. By default libsdl-native will +# be built, if you want to use your host's libSDL instead of the minimal libsdl built +# by libsdl-native then uncomment the ASSUME_PROVIDED line below. +PACKAGECONFIG_append_pn-qemu-native = " sdl" +PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl" +#ASSUME_PROVIDED += "libsdl-native" + + +# CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to +# track the version of this file when it was generated. This can safely be ignored if +# this doesn't mean anything to you. +CONF_VERSION = "1" + +# +# Enable local PR server +# +PRSERV_HOST = "localhost:0" + +# +# Some libraries and packages are covered by NXP EULA +# +#ACCEPT_FSL_EULA = "1" From 1a3f22c9e4589cbcbf2674dcb946d6681887ec6e Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 3 Oct 2017 16:36:27 +0200 Subject: [PATCH 055/113] u-boot-dey: add support for ccimx6qpsbc platform This commit includes ccimx6qpsbc platform in the recipe and adds U-Boot scripts for deploying and booting the system. https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- .../u-boot-dey-2015.04/ccimx6qpsbc/boot.txt | 35 ++++ .../ccimx6qpsbc/install_linux_fw_sd.txt | 162 ++++++++++++++++++ .../{ccimx6 => ccimx6sbc}/boot.txt | 0 .../install_linux_fw_sd.txt | 0 4 files changed, 197 insertions(+) create mode 100644 meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt create mode 100644 meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/install_linux_fw_sd.txt rename meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/{ccimx6 => ccimx6sbc}/boot.txt (100%) rename meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/{ccimx6 => ccimx6sbc}/install_linux_fw_sd.txt (100%) diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt new file mode 100644 index 000000000..e47f9fd88 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt @@ -0,0 +1,35 @@ +# +# U-Boot bootscript for EMMC/SD images created by Yocto. +# + +# +# Set device tree filename depending on the board ID (if defined) +# +if test -n "${board_id}"; then + setenv fdt_file uImage-${soc_family}-ccimx6qpsbc-id${board_id}.dtb +else + # + # Set device tree filename depending on the hardware variant + # + if test "${module_variant}" = "0x01"; then + setenv fdt_file uImage-${soc_family}-ccimx6qpsbc-wb.dtb + else + echo "------ Using default fdt_file" + fi +fi + +# Get the UUID of the configured boot partition. +part uuid mmc ${mmcbootdev}:${mmcpart} bootpart +# Check the boot source. +if test "${bootpart}" = "${part1_uuid}"; then + # We are booting from the eMMC using 'linux'. + true +elif test "${bootpart}" = "${part2_uuid}"; then + # We are booting from the eMMC using 'recovery'. + setenv boot_initrd true + setenv initrd_file uramdisk-recovery.img +else + # We are booting from the SD card. + setenv mmcroot /dev/mmcblk${mmcbootdev}p2 +fi +dboot linux mmc ${mmcbootdev}:${mmcpart} diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/install_linux_fw_sd.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/install_linux_fw_sd.txt new file mode 100644 index 000000000..76bebec7b --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/install_linux_fw_sd.txt @@ -0,0 +1,162 @@ +# +# U-Boot script for installing Linux images created by Yocto from the SD +# card into the eMMC +# + +echo "############################################################" +echo "# Linux firmware install from micro SD #" +echo "############################################################" +echo "" +echo " This process will erase your eMMC and will install a new" +echo " U-Boot and Linux firmware images on the eMMC." +echo "" +echo " Press CTRL+C now if you wish to abort or wait 10 seconds" +echo " to continue." + +sleep 10 +if test $? -eq 1; then + echo "Aborted by user."; + exit; +fi + +# Determine U-Boot file to program basing on module variant +if test -n "${module_variant}"; then + if test "${module_variant}" = "0x01"; then + setenv INSTALL_UBOOT_FILENAME u-boot-ccimx6qpsbc2GB.imx; + fi +fi +# Use 'test -n ...' because 'test -z ...' does not work well on old versions of +# u-boot when the checked value is empty. +if test -n "${INSTALL_UBOOT_FILENAME}"; then + true; +else + echo ""; + echo "[ERROR] Cannot determine U-Boot file for this module!"; + echo ""; + echo "1. Set variable 'INSTALL_UBOOT_FILENAME' depending on your ConnectCore 6 QuadPlus variant:"; + echo " - For a QuadPlus CPU with 2GB DDR3, run:"; + echo " => setenv INSTALL_UBOOT_FILENAME u-boot-ccimx6qpsbc2GB.imx"; + echo ""; + echo "2. Run the install script again."; + echo ""; + echo "Aborted"; + echo ""; + exit; +fi; + +setenv INSTALL_MMCDEV 1 +setenv INSTALL_LINUX_FILENAME dey-image-qt-##GRAPHICAL_BACKEND##-ccimx6qpsbc.boot.vfat +setenv INSTALL_RECOVERY_FILENAME dey-image-qt-##GRAPHICAL_BACKEND##-ccimx6qpsbc.recovery.vfat +setenv INSTALL_ROOTFS_FILENAME dey-image-qt-##GRAPHICAL_BACKEND##-ccimx6qpsbc.ext4 + +# Check for presence of firmware files on the SD card +for install_f in ${INSTALL_UBOOT_FILENAME} ${INSTALL_LINUX_FILENAME} ${INSTALL_RECOVERY_FILENAME} ${INSTALL_ROOTFS_FILENAME}; do + if test ! -e mmc ${INSTALL_MMCDEV}:1 ${install_f}; then + echo "ERROR: Could not find file ${install_f}"; + install_abort=1; + fi; +done +if test -n "${install_abort}"; then + echo "Aborted."; + exit; +fi + +# Skip user confirmation for U-Boot update +setenv forced_update 1 + +# Set bootdelay to zero so that firmware update is run immediately after +# the first reset. +setenv bootdelay 0 + +# Set target MMC device index to eMMC +setenv mmcdev 0 + +# Update U-Boot +echo "" +echo "" +echo ">> Installing U-Boot boot loader (target will reset)" +echo "" +echo "" +update uboot mmc ${INSTALL_MMCDEV} fat ${INSTALL_UBOOT_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update U-Boot boot loader!"; + echo ""; + echo "Aborted."; + exit; +fi + +# Set 'bootcmd' to the second part of the script that will +# - Reset environment to defaults +# - Save the environment +# - Partition the eMMC user data area for Linux +# - Update the 'linux' partition +# - Update the 'recovery' partition +# - Update the 'rootfs' partition +# - Configure recovery to wipe 'update' partition +# - Run 'recovery' and let the system boot after +setenv bootcmd " + env default -a; + saveenv; + echo \"\"; + echo \"\"; + echo \">> Creating Linux partition table on the eMMC\"; + echo \"\"; + echo \"\"; + run partition_mmc_linux; + if test \$? -eq 1; then + echo \"[ERROR] Failed to create Linux partition table!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing Linux kernel and device tree files\"; + echo \"\"; + echo \"\"; + update linux mmc ${INSTALL_MMCDEV} fat ${INSTALL_LINUX_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update linux partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing recovery\"; + echo \"\"; + echo \"\"; + update recovery mmc ${INSTALL_MMCDEV} fat ${INSTALL_RECOVERY_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update recovery partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing Linux root file system\"; + echo \"\"; + echo \"\"; + update rootfs mmc ${INSTALL_MMCDEV} fat ${INSTALL_ROOTFS_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update rootfs partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + setenv boot_recovery yes; + setenv recovery_command wipe_update; + saveenv; + echo \"\"; + echo \"\"; + echo \">> Firmware installation complete. Rebooting into recovery mode for final deployment.\"; + echo \"\"; + echo \"\"; + sleep 1; + reset; +" + +saveenv +reset diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6/boot.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6sbc/boot.txt similarity index 100% rename from meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6/boot.txt rename to meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6sbc/boot.txt diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6/install_linux_fw_sd.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6sbc/install_linux_fw_sd.txt similarity index 100% rename from meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6/install_linux_fw_sd.txt rename to meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6sbc/install_linux_fw_sd.txt From f1dd256c5b4c40775ec377e7d3d468d662fae047 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 3 Oct 2017 16:59:04 +0200 Subject: [PATCH 056/113] bluez5: add support for ccimx6qpsbc platform https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- ...d-bluetooth-support-for-QCA6174-chip.patch | 0 ...-bluetooth-low-power-mode-functional.patch | 0 ...ix-bug-in-firmware-parsing-mechanism.patch | 0 .../0006-bluetooth-Configure-BD-Address.patch | 0 ...-unused-functions-in-the-firmware-do.patch | 0 ...tooth-Enable-3Mbps-baud-rate-support.patch | 0 ...TTY-buffer-for-data-availability-bef.patch | 0 ...upport-for-TUFEELO-firmware-download.patch | 0 ...uetooth-Add-support-for-ROME-3.2-SOC.patch | 0 ...rrect-TTY-ioctl-calls-for-flow-contr.patch | 0 ...ooth-Add-support-for-multi-baud-rate.patch | 0 ...ttings-by-reading-configuration-file.patch | 0 ...0015-Add-support-for-Tufello-1.1-SOC.patch | 0 ...ART-CLK-ON-prior-to-firmware-downloa.patch | 0 ...ttings-by-reading-configuration-file.patch | 0 ...ter-derefrencing-in-AVRCP-Target-rol.patch | 0 ...bluetooth-Fix-flow-control-operation.patch | 0 ...M-specific-code-under-_PLATFORM_MDM_.patch | 0 ...Bluetooth-Fix-static-analysis-issues.patch | 0 ...espect-the-user-indication-for-noflo.patch | 0 ...If-the-user-supplies-a-bdaddr-use-it.patch | 0 .../0024-hciattach-Add-verbosity-option.patch | 0 .../bluez5-5.41/ccimx6qpsbc/bluetooth-init | 87 +++++++++++++++++++ .../bluez/bluez5-5.41/ccimx6qpsbc/main.conf | 12 +++ .../{ccimx6 => ccimx6sbc}/bluetooth-init | 0 .../{ccimx6 => ccimx6sbc}/main.conf | 0 .../bluez/bluez5_5.41.bbappend | 5 +- 27 files changed, 103 insertions(+), 1 deletion(-) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0006-bluetooth-Configure-BD-Address.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0013-bluetooth-Add-support-for-multi-baud-rate.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0014-Override-PCM-Settings-by-reading-configuration-file.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0015-Add-support-for-Tufello-1.1-SOC.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0017-Override-IBS-settings-by-reading-configuration-file.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0019-bluetooth-Fix-flow-control-operation.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0021-Bluetooth-Fix-static-analysis-issues.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6ul => }/0024-hciattach-Add-verbosity-option.patch (100%) create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/bluetooth-init create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/main.conf rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6 => ccimx6sbc}/bluetooth-init (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{ccimx6 => ccimx6sbc}/main.conf (100%) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0006-bluetooth-Configure-BD-Address.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-bluetooth-Configure-BD-Address.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0006-bluetooth-Configure-BD-Address.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-bluetooth-Configure-BD-Address.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0013-bluetooth-Add-support-for-multi-baud-rate.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-bluetooth-Add-support-for-multi-baud-rate.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0013-bluetooth-Add-support-for-multi-baud-rate.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-bluetooth-Add-support-for-multi-baud-rate.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0014-Override-PCM-Settings-by-reading-configuration-file.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-Override-PCM-Settings-by-reading-configuration-file.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0014-Override-PCM-Settings-by-reading-configuration-file.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-Override-PCM-Settings-by-reading-configuration-file.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0015-Add-support-for-Tufello-1.1-SOC.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-Add-support-for-Tufello-1.1-SOC.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0015-Add-support-for-Tufello-1.1-SOC.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-Add-support-for-Tufello-1.1-SOC.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0017-Override-IBS-settings-by-reading-configuration-file.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0017-Override-IBS-settings-by-reading-configuration-file.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0017-Override-IBS-settings-by-reading-configuration-file.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0017-Override-IBS-settings-by-reading-configuration-file.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0019-bluetooth-Fix-flow-control-operation.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0019-bluetooth-Fix-flow-control-operation.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0019-bluetooth-Fix-flow-control-operation.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0019-bluetooth-Fix-flow-control-operation.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0021-Bluetooth-Fix-static-analysis-issues.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0021-Bluetooth-Fix-static-analysis-issues.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0021-Bluetooth-Fix-static-analysis-issues.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0021-Bluetooth-Fix-static-analysis-issues.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0024-hciattach-Add-verbosity-option.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0024-hciattach-Add-verbosity-option.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/0024-hciattach-Add-verbosity-option.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0024-hciattach-Add-verbosity-option.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/bluetooth-init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/bluetooth-init new file mode 100644 index 000000000..1a9741841 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/bluetooth-init @@ -0,0 +1,87 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2012-2017 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: Initialize bluetooth hardware +# +#=============================================================================== + +# Bluetooth power GPIO +BT_EN_QCA_GPIO_NR="244" + +# set_gpio_value +set_gpio_value() { + local SG_GPIONR="${1}" + local SG_GPIOVAL="${2}" + local SG_GPIOPATH="/sys/class/gpio/gpio${SG_GPIONR}" + + [ -d "${SG_GPIOPATH}" ] || printf "%s" "${SG_GPIONR}" > /sys/class/gpio/export + printf out > "${SG_GPIOPATH}/direction" && sleep .2 + printf "${SG_GPIOVAL}" > "${SG_GPIOPATH}/value" && sleep .2 + [ -d "${SG_GPIOPATH}" ] && printf "%s" "${SG_GPIONR}" > /sys/class/gpio/unexport +} + +# powercycle_gpio +powercycle_gpio() { + set_gpio_value "${1}" 0 + set_gpio_value "${1}" 1 +} + +error() { + echo ${1} + exit 1 +} + +bluetooth_init() { + # Get MAC address from the device tree. Use a default value if it has not been set. + BT_MACADDR="$(hexdump -ve '1/1 "%02X" ":"' /proc/device-tree/bluetooth/mac-address 2>/dev/null | sed 's/:$//g')" + if [ -z "${BT_MACADDR}" ] || [ "${BT_MACADDR}" = "00:00:00:00:00:00" ]; then + BT_MACADDR="00:04:F3:FF:FF:BB" + fi + + # Start the Bluetooth driver and bring up the interface + HCIATTACH_LOG="/var/log/hciattach.log" + killproc hciattach + powercycle_gpio "${BT_EN_QCA_GPIO_NR}" + if ! hciattach ttyBt qca ${BT_RATE:-3000000} -t30 ${BT_FLOW:-flow} unused ${BT_MACADDR} >${HCIATTACH_LOG} 2>&1; then + BT_ERROR="FAIL (hciattach)" + fi +} + +# Source function library +. /etc/init.d/functions + +case "$1" in + start) + if [ -d "/proc/device-tree/bluetooth" ]; then + echo -n "Starting bluetooth hardware: " + bluetooth_init + echo "${BT_ERROR:-done.}" + fi + ;; + stop) + if [ -d "/sys/class/bluetooth/hci0" ]; then + echo -n "Stopping bluetooth hardware: " + killproc hciattach + # Power down bluetooth + set_gpio_value "${BT_EN_QCA_GPIO_NR}" 0 + echo "done." + fi + ;; + restart) + $0 stop + sleep 1 + $0 start + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 + ;; +esac diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/main.conf b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/main.conf new file mode 100644 index 000000000..332d38fad --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/main.conf @@ -0,0 +1,12 @@ +[General] + +# Default adapter name +# Defaults to 'BlueZ X.YZ' +Name = cc6qp + +[Policy] + +# AutoEnable defines option to enable all controllers when they are found. +# This includes adapters present on start as well as adapters that are plugged +# in later on. Defaults to 'false'. +AutoEnable=true diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6/bluetooth-init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/bluetooth-init similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6/bluetooth-init rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/bluetooth-init diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6/main.conf b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/main.conf similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6/main.conf rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/main.conf diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend index 45b7f10d3..188c4533f 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -11,7 +11,7 @@ SRC_URI += " \ file://0027-example-gatt-server-update-example-to-master-version.patch \ " -SRC_URI_append_ccimx6ul = " \ +QCA6564_COMMON_PATCHES = " \ file://0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch \ file://0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch \ file://0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch \ @@ -36,6 +36,9 @@ SRC_URI_append_ccimx6ul = " \ file://0024-hciattach-Add-verbosity-option.patch \ " +SRC_URI_append_ccimx6ul = " ${QCA6564_COMMON_PATCHES}" +SRC_URI_append_ccimx6qpsbc = " ${QCA6564_COMMON_PATCHES}" + inherit update-rc.d PACKAGECONFIG_append = " experimental" From 553337afc3326206450e03d3058d08ca5dd295d1 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 3 Oct 2017 17:15:15 +0200 Subject: [PATCH 057/113] init-ifupdown: add support for ccimx6qpsbc platform https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- .../ccimx6qpsbc/interfaces.br0.example | 7 +++++ .../ccimx6qpsbc/interfaces.wlan1.dhcp | 6 ++++ .../ccimx6qpsbc/interfaces.wlan1.static | 9 ++++++ .../ccimx6qpsbc/virtwlans.sh | 30 +++++++++++++++++++ .../interfaces.br0.example | 0 .../init-ifupdown/init-ifupdown_1.0.bbappend | 28 +++++++++++++++++ 6 files changed, 80 insertions(+) create mode 100644 meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.br0.example create mode 100644 meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.dhcp create mode 100644 meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.static create mode 100644 meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh rename meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/{ccimx6 => ccimx6sbc}/interfaces.br0.example (100%) diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.br0.example b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.br0.example new file mode 100644 index 000000000..60e05fe52 --- /dev/null +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.br0.example @@ -0,0 +1,7 @@ + +## Example bridge between eth0 and wlan1 +#auto br0 +#iface br0 inet static +# bridge_ports eth0 wlan1 +# address 192.168.42.50 +# netmask 255.255.255.0 diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.dhcp b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.dhcp new file mode 100644 index 000000000..245b973f0 --- /dev/null +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.dhcp @@ -0,0 +1,6 @@ + +auto wlan1 +iface wlan1 inet dhcp + udhcpc_opts -S -b >/dev/null & + post-up /etc/init.d/hostapd start + pre-down /etc/init.d/hostapd stop diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.static b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.static new file mode 100644 index 000000000..664542efe --- /dev/null +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/interfaces.wlan1.static @@ -0,0 +1,9 @@ + +auto wlan1 +iface wlan1 inet static + address ##WLAN1_STATIC_IP## + netmask ##WLAN1_STATIC_NETMASK## + gateway ##WLAN1_STATIC_GATEWAY## + dns-nameservers ##WLAN1_STATIC_DNS## + post-up /etc/init.d/hostapd start + pre-down /etc/init.d/hostapd stop diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh new file mode 100644 index 000000000..304c09fc5 --- /dev/null +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (c) 2017, Digi International Inc. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at http://mozilla.org/MPL/2.0/. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +# This will create a second wireless network device +if [ -s "/proc/device-tree/wireless/mac-address1" ] && + [ -s "/proc/device-tree/wireless/mac-address2" ] && + [ -s "/proc/device-tree/wireless/mac-address3" ]; then + : +else + echo "[WARN] Using default MAC addresses for virtual interfaces, please program them referring to the Digi U-Boot Documentation" +fi + +if [ ! -d "/sys/class/net/wlan1" ]; then + # This will create a second wireless network device + iw dev wlan0 interface add wlan1 type managed +fi diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6/interfaces.br0.example b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6sbc/interfaces.br0.example similarity index 100% rename from meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6/interfaces.br0.example rename to meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6sbc/interfaces.br0.example diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend index 388399008..97e1dccf4 100644 --- a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend @@ -11,6 +11,12 @@ SRC_URI_append = " \ file://resolv \ " +SRC_URI_append_ccimx6qpsbc = "\ + file://interfaces.wlan1.static \ + file://interfaces.wlan1.dhcp \ + file://virtwlans.sh \ +" + SRC_URI_append_ccimx6ul = "\ file://interfaces.wlan1.static \ file://interfaces.wlan1.dhcp \ @@ -49,6 +55,28 @@ do_install_append_ccimx6sbc() { cat ${WORKDIR}/interfaces.br0.example >> ${D}${sysconfdir}/network/interfaces } +do_install_append_ccimx6qpsbc() { + install -d ${D}${base_bindir} + install -m 0755 ${WORKDIR}/virtwlans.sh ${D}${base_bindir} + if [ -n "${HAVE_WIFI}" ]; then + cat ${WORKDIR}/interfaces.wlan1.${WLAN1_MODE} >> ${D}${sysconfdir}/network/interfaces + fi + + # Remove config entries if corresponding variable is not defined + [ -z "${WLAN1_STATIC_DNS}" ] && sed -i -e "/##WLAN1_STATIC_DNS##/d" ${D}${sysconfdir}/network/interfaces + [ -z "${WLAN1_STATIC_GATEWAY}" ] && sed -i -e "/##WLAN1_STATIC_GATEWAY##/d" ${D}${sysconfdir}/network/interfaces + [ -z "${WLAN1_STATIC_IP}" ] && sed -i -e "/##WLAN1_STATIC_IP##/d" ${D}${sysconfdir}/network/interfaces + [ -z "${WLAN1_STATIC_NETMASK}" ] && sed -i -e "/##WLAN1_STATIC_NETMASK##/d" ${D}${sysconfdir}/network/interfaces + + # Replace interface parameters + sed -i -e "s,##WLAN1_STATIC_IP##,${WLAN1_STATIC_IP},g" ${D}${sysconfdir}/network/interfaces + sed -i -e "s,##WLAN1_STATIC_NETMASK##,${WLAN1_STATIC_NETMASK},g" ${D}${sysconfdir}/network/interfaces + sed -i -e "s,##WLAN1_STATIC_GATEWAY##,${WLAN1_STATIC_GATEWAY},g" ${D}${sysconfdir}/network/interfaces + sed -i -e "s,##WLAN1_STATIC_DNS##,${WLAN1_STATIC_DNS},g" ${D}${sysconfdir}/network/interfaces + + cat ${WORKDIR}/interfaces.br0.example >> ${D}${sysconfdir}/network/interfaces +} + do_install_append_ccimx6ul() { install -d ${D}${base_bindir} install -m 0755 ${WORKDIR}/virtwlans.sh ${D}${base_bindir} From 3df334690fdd85737948a0faaf030971c6532fb7 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 3 Oct 2017 17:22:59 +0200 Subject: [PATCH 058/113] wpa-supplicant: add support for ccimx6qpsbc platform https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- .../ccimx6qpsbc/wpa_supplicant.conf-sane | 18 ++++++++++++++++++ .../ccimx6qpsbc/wpa_supplicant_p2p.conf | 8 ++++++++ .../wpa_supplicant_p2p.conf | 0 3 files changed, 26 insertions(+) create mode 100644 meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant.conf-sane create mode 100644 meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant_p2p.conf rename meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/{ccimx6 => ccimx6sbc}/wpa_supplicant_p2p.conf (100%) diff --git a/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant.conf-sane b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant.conf-sane new file mode 100644 index 000000000..c58546a06 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant.conf-sane @@ -0,0 +1,18 @@ +ctrl_interface=/var/run/wpa_supplicant +ctrl_interface_group=0 +fast_reauth=1 +update_config=1 + +ap_scan=1 + +# Static scheduled scan interval time in seconds +# +# The wpa-supplicant dynamically adjusts the scheduled scan time interval. On +# occassions, fixing the interval time is helpful, for example on DFS channels. +#sched_scan_interval=2 + +network={ + scan_ssid=1 + ssid="" + key_mgmt=NONE +} diff --git a/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant_p2p.conf b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant_p2p.conf new file mode 100644 index 000000000..c6d16f32d --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6qpsbc/wpa_supplicant_p2p.conf @@ -0,0 +1,8 @@ +ctrl_interface=/var/run/wpa_supplicant +update_config=1 +device_name=ccimx6qp-p2p +manufacturer=QCA +model_name=McK +device_type=1-0050F204-1 +config_methods=display keypad push_button +persistent_reconnect=1 diff --git a/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6/wpa_supplicant_p2p.conf b/meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6sbc/wpa_supplicant_p2p.conf similarity index 100% rename from meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6/wpa_supplicant_p2p.conf rename to meta-digi-dey/recipes-connectivity/wpa-supplicant/wpa-supplicant/ccimx6sbc/wpa_supplicant_p2p.conf From f1b47c1111b422091464833e2456db985af3e285 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 3 Oct 2017 17:25:39 +0200 Subject: [PATCH 059/113] busybox: add support for ccimx6qpsbc platform https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- .../busybox-1.24.1/ccimx6qpsbc/suspend | 109 ++++++++++++++++++ .../{ccimx6 => ccimx6sbc}/suspend | 0 2 files changed, 109 insertions(+) create mode 100755 meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend rename meta-digi-dey/recipes-core/busybox/busybox-1.24.1/{ccimx6 => ccimx6sbc}/suspend (100%) diff --git a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend new file mode 100755 index 000000000..50e3e59a3 --- /dev/null +++ b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend @@ -0,0 +1,109 @@ +#!/bin/sh +#=============================================================================== +# +# suspend +# +# Copyright (C) 2017 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: suspend system to RAM +# +#=============================================================================== + +scriptname="$(basename ${0})" +syspower="/sys/power/state" +lockfile="/var/lock/${scriptname}.lock" +lockfd="9" + +BT_INIT="/etc/init.d/bluetooth-init" +BT_DAEMON="/etc/init.d/bluetooth" + +usage() { + printf "\nSuspend system to RAM memory\n" + printf "\nUsage: ${scriptname} [OPTIONS]\n + -h Show this help + \n" +} + +suspend_interfaces() { + # Suspend wireless interfaces + if [ -d "/proc/device-tree/wireless" ]; then + for i in $(sed -ne 's,^\(wlan[0-9]\)=.*,\1,g;T;p' /var/run/ifstate | sort -r); do + ifdown "${i}" && RESUME_IFACES="${RESUME_IFACES:+${RESUME_IFACES} }${i}" + done + grep -qs '^wlan' /proc/modules && rmmod wlan + fi + + # Suspend bluetooth interface + if [ -d "/proc/device-tree/bluetooth" ]; then + hciconfig hci0 2>&1 | grep -qs UP && up_bt_on_resume="1" + ${BT_DAEMON} stop >/dev/null + ${BT_INIT} stop >/dev/null + fi +} + +resume_interfaces() { + # Resume wireless interfaces + if [ -d "/proc/device-tree/wireless" ]; then + # Trigger wireless module loading event, and wait until the interface exists + udevadm trigger --action=add --attr-match="modalias=sdio:c00v0271d050A" + timeout -t 5 sh -c "while [ ! -d /sys/class/net/wlan0 ]; do sleep .2; done" 2>/dev/null + + # Bring up the interfaces that were bring down on suspend + for i in $(echo ${RESUME_IFACES} | tr ' ' '\n' | sort); do + grep -qs "^${i}" /var/run/ifstate || ifup "${i}" + done + fi + + # Resume bluetooth interface + if [ -d "/proc/device-tree/bluetooth" ]; then + if [ -n "${up_bt_on_resume}" ]; then + ${BT_INIT} start >/dev/null + ${BT_DAEMON} start >/dev/null + fi + fi +} + +enter_critical_section() { + # Create lock file + eval "exec ${lockfd}>${lockfile}" + + # Acquire the lock in non blocking mode. Otherwise, additional calls + # to the script will be queued and the system will endlessly go in + # and out of suspend to ram + flock -n "${lockfd}" || exit 0 +} + +exit_critical_section() { + # Release the lock + flock -u "${lockfd}" +} + +while getopts "h" c; do + case "${c}" in + h) usage; exit;; + esac +done + +if [ -f "${syspower}" ]; then + # Avoid running multiple instances of this script in parallel + enter_critical_section + + # Pre-suspend actions + suspend_interfaces + + # Suspend the device + printf "mem" > ${syspower} + + # Post-resume actions + resume_interfaces + + exit_critical_section +else + printf "\n[ERROR] File ${syspower} not found\n\n" +fi diff --git a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6/suspend b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6sbc/suspend similarity index 100% rename from meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6/suspend rename to meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6sbc/suspend From f36e8a94a1d01c3acd8ca168714638a70f03c538 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Tue, 3 Oct 2017 17:28:10 +0200 Subject: [PATCH 060/113] hostapd: add support for ccimx6qpsbc platform https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- .../hostapd/hostapd/{ccimx6ul => }/hostapd_wlan1.conf | 0 .../recipes-connectivity/hostapd/hostapd_%.bbappend | 6 ++++++ 2 files changed, 6 insertions(+) rename meta-digi-dey/recipes-connectivity/hostapd/hostapd/{ccimx6ul => }/hostapd_wlan1.conf (100%) diff --git a/meta-digi-dey/recipes-connectivity/hostapd/hostapd/ccimx6ul/hostapd_wlan1.conf b/meta-digi-dey/recipes-connectivity/hostapd/hostapd/hostapd_wlan1.conf similarity index 100% rename from meta-digi-dey/recipes-connectivity/hostapd/hostapd/ccimx6ul/hostapd_wlan1.conf rename to meta-digi-dey/recipes-connectivity/hostapd/hostapd/hostapd_wlan1.conf diff --git a/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend b/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend index 76f7b529a..6f31b13df 100644 --- a/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/hostapd/hostapd_%.bbappend @@ -4,6 +4,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" SRC_URI_append = " file://hostapd_wlan0.conf" SRC_URI_append_ccimx6ul = " file://hostapd_wlan1.conf" +SRC_URI_append_ccimx6qpsbc = " file://hostapd_wlan1.conf" do_install_append() { # Remove the default hostapd.conf @@ -17,6 +18,11 @@ do_install_append_ccimx6ul() { install -m 0644 ${WORKDIR}/hostapd_wlan1.conf ${D}${sysconfdir} } +do_install_append_ccimx6qpsbc() { + # Install custom hostapd_IFACE.conf file + install -m 0644 ${WORKDIR}/hostapd_wlan1.conf ${D}${sysconfdir} +} + pkg_postinst_${PN}() { # Append the last two bytes of the wlan0 MAC address to the SSID of the # hostAP configuration files From 8c14ae877ff01ac6c899a6b142f381e8754b8932 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Wed, 4 Oct 2017 08:42:29 +0200 Subject: [PATCH 061/113] meta-digi recipes: adjust machine overrides for new platform This commit modifies different recipes to support the new platform ccimx6qpsbc and adapt it to maintain the support to ccimx6sbc. https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- .../firmware-atheros/firmware-atheros.bb | 4 +- .../firmware-qualcomm/firmware-qualcomm.bb | 4 +- .../u-boot/u-boot-fw-utils_%.bbappend | 2 +- .../kernel-module-qualcomm.bb | 2 +- .../recipes-kernel/linux/linux-dey_3.14.bb | 4 +- .../recipes-kernel/linux/linux-dey_4.1.bb | 2 +- .../packagegroup-dey-wireless.bb | 3 +- .../recovery/recovery-initramfs.bb | 4 +- .../trustfence/trustfence-initramfs.bb | 4 +- .../trustfence-initramfs-init | 0 .../dey-examples/dey-examples-cryptochip.bb | 2 +- .../libdigiapix-git/ccimx6qpsbc/board.conf | 43 +++++++++++++++++++ meta-digi-dey/recipes-digi/swu-images/swu.inc | 2 +- .../packagegroups/packagegroup-dey-audio.bb | 4 +- .../pulseaudio/pulseaudio_%.bbappend | 10 ++--- 15 files changed, 69 insertions(+), 21 deletions(-) rename meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/{ccimx6sbc => ccimx6}/trustfence-initramfs-init (100%) create mode 100644 meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb index 8c03f9df7..aba5c07cd 100644 --- a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb +++ b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013 Digi International. +# Copyright (C) 2013-2017 Digi International. SUMMARY = "Firmware files for Digi's platforms, such as Atheros bluetooth." SECTION = "base" @@ -74,4 +74,4 @@ FILES_${PN}-ar3k = "/lib/firmware/ar3k" FILES_${PN}-ath6kl = "/lib/firmware/ath6k" PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(ccimx6$)" +COMPATIBLE_MACHINE = "(ccimx6sbc)" diff --git a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb index b12bc2b14..049f3f41b 100644 --- a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb +++ b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2016 Digi International. +# Copyright (C) 2016,2017 Digi International. SUMMARY = "Qualcomm firmware files for Digi's platforms." SECTION = "base" @@ -55,4 +55,4 @@ FILES_${PN}-qca6564-bt = "/lib/firmware/qca" FILES_${PN}-qca6564-wifi = "/lib/firmware" PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6qpsbc|ccimx6ul)" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend index 547138192..5dc685e89 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend @@ -88,4 +88,4 @@ pkg_postinst_${PN}() { fi } -COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6sbc|ccimx6qpsbc|ccimx6ul)" diff --git a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb index e65ff29f5..37c80419d 100644 --- a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb +++ b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb @@ -56,4 +56,4 @@ FILES_${PN} += " \ ${base_libdir}/firmware/wlan/qcom_cfg.ini \ " -COMPATIBLE_MACHINE = "(ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6qpsbc|ccimx6ul)" diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_3.14.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_3.14.bb index 7f2aa8fc5..1692577bc 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_3.14.bb +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_3.14.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Digi International +# Copyright (C) 2015-2017 Digi International require recipes-kernel/linux/linux-dey.inc require recipes-kernel/linux/linux-dtb.inc @@ -8,4 +8,4 @@ inherit fsl-vivante-kernel-driver-handler SRCBRANCH = "v3.14/master" SRCREV = "${AUTOREV}" -COMPATIBLE_MACHINE = "(ccimx6$)" +COMPATIBLE_MACHINE = "(ccimx6sbc)" diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_4.1.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.1.bb index 8f891fed8..b7a681d46 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_4.1.bb +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.1.bb @@ -6,4 +6,4 @@ require recipes-kernel/linux/linux-dtb.inc SRCBRANCH = "v4.1.15/master" SRCREV = "${AUTOREV}" -COMPATIBLE_MACHINE = "(ccimx6$|ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6sbc|ccimx6ul)" diff --git a/meta-digi-dey/recipes-connectivity/packagegroups/packagegroup-dey-wireless.bb b/meta-digi-dey/recipes-connectivity/packagegroups/packagegroup-dey-wireless.bb index e4f27eb3e..f2d6bf9a7 100644 --- a/meta-digi-dey/recipes-connectivity/packagegroups/packagegroup-dey-wireless.bb +++ b/meta-digi-dey/recipes-connectivity/packagegroups/packagegroup-dey-wireless.bb @@ -1,5 +1,5 @@ # -# Copyright (C) 2012 Digi International. +# Copyright (C) 2012-2017 Digi International. # SUMMARY = "Wireless packagegroup for DEY image" @@ -16,3 +16,4 @@ RDEPENDS_${PN} = "\ " RDEPENDS_${PN}_append_ccimx6ul = " hostapd" +RDEPENDS_${PN}_append_ccimx6qpsbc = " hostapd" diff --git a/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb b/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb index fb88dba95..16103d2af 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb +++ b/meta-digi-dey/recipes-core/recovery/recovery-initramfs.bb @@ -53,7 +53,9 @@ PACKAGES = "${PN}" FILES_${PN} = "/" -RDEPENDS_${PN}_append_ccimx6 = " \ +RDEPENDS_${PN}_append_ccimx6sbc = " \ cryptsetup \ rng-tools \ " + +RDEPENDS_${PN}_append_ccimx6qpsbc = " cryptsetup" diff --git a/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb b/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb index 0d6d77ef4..5f9cb418c 100644 --- a/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb +++ b/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs.bb @@ -27,11 +27,13 @@ RDEPENDS_${PN} = " \ u-boot-fw-utils \ " -RDEPENDS_${PN}_append_ccimx6 = " \ +RDEPENDS_${PN}_append_ccimx6sbc = " \ cryptsetup \ rng-tools \ " +RDEPENDS_${PN}_append_ccimx6qpsbc = " cryptsetup" + RDEPENDS_${PN}_append_ccimx6ul = " \ mtd-utils-ubifs \ " diff --git a/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6sbc/trustfence-initramfs-init b/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6/trustfence-initramfs-init similarity index 100% rename from meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6sbc/trustfence-initramfs-init rename to meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6/trustfence-initramfs-init diff --git a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-cryptochip.bb b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-cryptochip.bb index e1700995b..0f71a4f42 100644 --- a/meta-digi-dey/recipes-digi/dey-examples/dey-examples-cryptochip.bb +++ b/meta-digi-dey/recipes-digi/dey-examples/dey-examples-cryptochip.bb @@ -24,5 +24,5 @@ do_install() { } PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6qpsbc|ccimx6ul)" diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf new file mode 100644 index 000000000..1e88b544e --- /dev/null +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf @@ -0,0 +1,43 @@ +[board] +model = Digi International ConnectCore 6 QuadPlus Single Board Computer. + +[GPIO] + +# USER LED (RED) - GPIO02_IO02 +USER_LED = 34 + +# USER LED (ORANGE) - GPIO02_IO03 +USER_LED_2 = 35 + +# USER LED (GREEN) - GPIO02_IO04 +USER_LED_3 = 36 + +# USER BUTTON - GPIO02_IO05 +USER_BUTTON = 37 + +[I2C] + +# I2C-3 on I2C board connector. +DEFAULT_I2C_BUS = 2 + +[SPI] + +# SPI-1 on SPI board connector. +DEFAULT_SPI = 0,0 + +[PWM] + +# PWM1 on LCD board connector (pin 10). +DEFAULT_PWM = 0,0 + +[ADC] + +# HWMON Driver +DEFAULT_ADC_DRIVER = 1 + +# IIO Device 0 +DEFAULT_DEVICE_INDEX = 0 + +# PMIC_ADCIN1 on GPIO board connector (Pin 1) +DEFAULT_ADC_LINE = 1 + diff --git a/meta-digi-dey/recipes-digi/swu-images/swu.inc b/meta-digi-dey/recipes-digi/swu-images/swu.inc index d88e78df2..e4024216f 100644 --- a/meta-digi-dey/recipes-digi/swu-images/swu.inc +++ b/meta-digi-dey/recipes-digi/swu-images/swu.inc @@ -32,7 +32,7 @@ ROOTFS_ENC_DEV_ccimx6ul = "${ROOTFS_DEV_NAME}" ROOTFS_DEV_NAME_FINAL = "${@oe.utils.ifelse(d.getVar('TRUSTFENCE_INITRAMFS_IMAGE', True), '${ROOTFS_ENC_DEV}', '${ROOTFS_DEV_NAME}')}" PREINST_SCRIPT_TEMPLATE = "scripts: ( { filename = \\"preinstall_swu.sh\\"; type = \\"preinstall\\"; sha256 = \\"@preinstall_swu.sh\\"; \\x7D );" PREINST_SCRIPT_DESC = "" -PREINST_SCRIPT_DESC_ccimx6sbc = "${@oe.utils.ifelse(d.getVar('TRUSTFENCE_INITRAMFS_IMAGE', True), '${PREINST_SCRIPT_TEMPLATE}', '')}" +PREINST_SCRIPT_DESC_ccimx6 = "${@oe.utils.ifelse(d.getVar('TRUSTFENCE_INITRAMFS_IMAGE', True), '${PREINST_SCRIPT_TEMPLATE}', '')}" PREINST_SCRIPT_DESC_ccimx6ul = "${@oe.utils.ifelse(d.getVar('TRUSTFENCE_INITRAMFS_IMAGE', True), '', '${PREINST_SCRIPT_TEMPLATE}')}" python () { diff --git a/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-audio.bb b/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-audio.bb index 1f5ece5d1..9ea584779 100644 --- a/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-audio.bb +++ b/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-audio.bb @@ -1,5 +1,5 @@ # -# Copyright (C) 2012 Digi International. +# Copyright (C) 2012-2017 Digi International. # SUMMARY = "Audio packagegroup for DEY image" @@ -21,4 +21,4 @@ RDEPENDS_${PN} = "\ ${ALSA_UTILS_PKGS} \ " -RDEPENDS_${PN}_append_ccimx6sbc = " card-detect" +RDEPENDS_${PN}_append_ccimx6 = " card-detect" diff --git a/meta-digi-dey/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend b/meta-digi-dey/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend index 1889c09a0..0b6d1ad0b 100644 --- a/meta-digi-dey/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend +++ b/meta-digi-dey/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend @@ -3,15 +3,15 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" SRC_URI_append_ccimx6ulsbc = " file://0001-pulseaudio-keep-headphones-volume-in-platforms-witho.patch" -SRC_URI_append_ccimx6sbc = " \ +SRC_URI_append_ccimx6 = " \ file://hdmi_hotplug.sh \ file://dey-audio-hdmi.conf \ file://dey-audio-sgtl5000.conf \ " -EXTRA_OECONF_append_ccimx6sbc = " --disable-memfd" +EXTRA_OECONF_append_ccimx6 = " --disable-memfd" -do_install_append_ccimx6sbc() { +do_install_append_ccimx6() { install -d ${D}${sysconfdir}/udev/scripts install -m 0755 ${WORKDIR}/hdmi_hotplug.sh ${D}${sysconfdir}/udev/scripts @@ -34,5 +34,5 @@ do_install_append_ccimx6sbc() { PACKAGE_ARCH = "${MACHINE_ARCH}" -# The card-detect binary is only necessary for the HDMI hotplug to work on the ccimx6sbc -RDEPENDS_${PN}_append_ccimx6sbc = " card-detect" +# The card-detect binary is only necessary for the HDMI hotplug to work on the ccimx6sbc/ccimx6qpsbc +RDEPENDS_${PN}_append_ccimx6 = " card-detect" From d305a5dcc8432537f7c59fa16f1738f409fa5c3e Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 5 Oct 2017 09:50:55 +0200 Subject: [PATCH 062/113] aws-iot-sdk: add support for ccimx6qpsbc platform https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- meta-digi-dey/recipes-digi/dey-examples/awsiotsdk-demo_git.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-dey/recipes-digi/dey-examples/awsiotsdk-demo_git.bb b/meta-digi-dey/recipes-digi/dey-examples/awsiotsdk-demo_git.bb index 26364cb58..41ccf688a 100644 --- a/meta-digi-dey/recipes-digi/dey-examples/awsiotsdk-demo_git.bb +++ b/meta-digi-dey/recipes-digi/dey-examples/awsiotsdk-demo_git.bb @@ -12,6 +12,7 @@ AWS_USER_LED ?= "" AWS_USER_LED_ccimx6ulstarter ?= "75" AWS_USER_LED_ccimx6ulsbc ?= "488" AWS_USER_LED_ccimx6sbc ?= "34" +AWS_USER_LED_ccimx6qpsbc ?= "34" SRCBRANCH = "master" SRCREV = "${AUTOREV}" From 5200bfc1b8dd07015715a44e09f2752c08df0835 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 5 Oct 2017 14:31:26 +0200 Subject: [PATCH 063/113] cryptoauthlib: add support for ccimx6qpsbc platform https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- meta-digi-dey/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meta-digi-dey/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb b/meta-digi-dey/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb index 9e2e7c12c..dcb283994 100644 --- a/meta-digi-dey/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb +++ b/meta-digi-dey/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb @@ -15,9 +15,11 @@ SRC_URI = "${GIT_URI};branch=${SRCBRANCH}" S = "${WORKDIR}/git/engine_atecc/cryptoauthlib" I2C_BUS = "" +I2C_BUS_ccimx6qpsbc = "1" I2C_BUS_ccimx6ul = "0" I2C_SPEED = "" +I2C_SPEED_ccimx6qpsbc = "100000" I2C_SPEED_ccimx6ul = "100000" CFLAGS += "-DATCA_HAL_I2C_BUS=${I2C_BUS} -DATCA_HAL_I2C_SPEED=${I2C_SPEED}" @@ -27,4 +29,4 @@ do_install() { } PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(ccimx6ul)" \ No newline at end of file +COMPATIBLE_MACHINE = "(ccimx6qpsbc|ccimx6ul)" From e37138ac85289069b1ade853c207d4702141e122 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Mon, 16 Oct 2017 19:02:59 +0200 Subject: [PATCH 064/113] linux-dey: add support for ccimx6qpsbc to kernel v4.9 This commit adds the defconfig for the platform ccimx6qpsbc to the kernel v4.9 and modifies the recipe. Signed-off-by: Arturo Buzarra --- .../linux/linux-dey-4.9/ccimx6qpsbc/defconfig | 331 ++++++++++++++++++ .../recipes-kernel/linux/linux-dey_4.9.bb | 2 +- 2 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig new file mode 100644 index 000000000..b4f0820a0 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig @@ -0,0 +1,331 @@ +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_KERNEL_LZO=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_BLK_CGROUP=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_ARCH_MXC=y +CONFIG_SOC_IMX6Q=y +CONFIG_SOC_VF610=y +CONFIG_ARM_ERRATA_814220=y +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_IMX6=y +CONFIG_SMP=y +CONFIG_HAVE_ARM_ARCH_TIMER=y +CONFIG_VMSPLIT_2G=y +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_CMA=y +CONFIG_SECCOMP=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_ARM_IMX6Q_CPUFREQ=y +CONFIG_CPU_IDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_PM_DEBUG=y +CONFIG_PM_TEST_SUSPEND=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_NETFILTER=y +CONFIG_BRIDGE=y +CONFIG_NET_SCHED=y +CONFIG_CAN=y +CONFIG_CAN_FLEXCAN=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_IBS=y +CONFIG_CFG80211=y +CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CFG80211_WEXT=y +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_PERCENTAGE=40 +CONFIG_CMA_SIZE_SEL_PERCENTAGE=y +CONFIG_IMX_WEIM=y +CONFIG_CONNECTOR=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_IMX=y +CONFIG_PATA_IMX=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y +CONFIG_NETDEVICES=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_MICREL_PHY=y +CONFIG_SMSC_PHY=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_ASYNC=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_CDC_EEM=y +CONFIG_USB_NET_CDC_MBIM=y +CONFIG_USB_NET_QMI_WWAN=y +CONFIG_USB_SIERRA_NET=y +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_DEBUG=y +CONFIG_ATH6KL_REGDOMAIN=y +CONFIG_HOSTAP=y +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_IMX=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_FUSION_7_10=y +CONFIG_TOUCHSCREEN_MC13783=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MMA8450=y +CONFIG_INPUT_DA9063_ONKEY=y +CONFIG_INPUT_ISL29023=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_FSL_OTP=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_IMX=y +CONFIG_I2C_IMX_LPI2C=y +CONFIG_SPI=y +CONFIG_SPI_IMX=y +CONFIG_SPI_FSL_LPSPI=y +CONFIG_SPI_SPIDEV=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_DA9063=y +CONFIG_POWER_SUPPLY=y +CONFIG_SENSORS_DA9063=y +CONFIG_SENSORS_MAG3110=y +CONFIG_THERMAL=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_CPU_THERMAL=y +CONFIG_IMX_THERMAL=y +CONFIG_DEVICE_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_IMX2_WDT=y +CONFIG_MFD_DA9052_I2C=y +CONFIG_MFD_DA9063=y +CONFIG_MFD_MC13XXX_SPI=y +CONFIG_MFD_MC13XXX_I2C=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_ANATOP=y +CONFIG_REGULATOR_DA9052=y +CONFIG_REGULATOR_DA9063=y +CONFIG_REGULATOR_MC13783=y +CONFIG_REGULATOR_MC13892=y +CONFIG_REGULATOR_PFUZE100=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +# CONFIG_USB_GSPCA is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_MXC_OUTPUT=y +CONFIG_VIDEO_MXC_CAPTURE=y +CONFIG_MXC_CAMERA_OV5642=y +CONFIG_MXC_CAMERA_OV5640_MIPI=y +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=y +CONFIG_VIDEO_MXC_IPU_OUTPUT=y +CONFIG_VIDEO_MXC_PXP_V4L2=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_OV2640=y +# CONFIG_VGA_ARB is not set +CONFIG_DRM=y +CONFIG_DRM_VIVANTE=y +CONFIG_FB_MXS=y +CONFIG_FB_MXC_SYNC_PANEL=y +CONFIG_FB_MXC_OVERLAY=y +CONFIG_FB_MXC_MIPI_DSI=y +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y +CONFIG_FB_MXC_LDB=y +CONFIG_FB_MXC_HDMI=y +CONFIG_FB_MXC_AD9389=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_L4F00242T03=y +CONFIG_LCD_PLATFORM=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +CONFIG_FB_LOGO_CENTERED=y +CONFIG_FB_LOGO_FORCE_SINGLE=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_PCI is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_IMX_SOC=y +CONFIG_SND_SOC_IMX_SGTL5000=y +CONFIG_SND_SOC_IMX_HDMI=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_QUALCOMM=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +CONFIG_USB_SERIAL_OPTION=y +CONFIG_USB_MXS_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_ETH=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_MXC_IPU=y +CONFIG_MXC_MIPI_CSI2=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_DA9063=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_DRV_DA9063=y +CONFIG_RTC_DRV_MC13XXX=y +CONFIG_RTC_DRV_MXC=y +CONFIG_RTC_DRV_SNVS=y +CONFIG_DMADEVICES=y +CONFIG_IMX_SDMA=y +CONFIG_MXS_DMA=y +CONFIG_MXC_PXP_V2=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON_USB_GPIO=y +CONFIG_PWM=y +CONFIG_PWM_IMX=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_OVERLAY_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_15=y +CONFIG_NLS_UTF8=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FTRACE is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_SECURITYFS=y +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_DEV_FSL_CAAM=y +CONFIG_FONTS=y +CONFIG_VIRTUALIZATION=y diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb index d53b97ec2..d7b9de9a0 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb @@ -6,4 +6,4 @@ require recipes-kernel/linux/linux-dtb.inc SRCBRANCH = "v4.9.11/master" SRCREV = "${AUTOREV}" -COMPATIBLE_MACHINE = "(ccimx6ul)" +COMPATIBLE_MACHINE = "(ccimx6qpsbc|ccimx6ul)" From 9e00f02456561aa4efc4da7cb998d891dd8777ff Mon Sep 17 00:00:00 2001 From: Sebastian Pastor Date: Mon, 16 Oct 2017 18:36:53 +0200 Subject: [PATCH 065/113] modemmanager: split udev rules for XBee Cellular The XBee Cellular modem is expected to be at ttymxc1 on CC6UL and at ttymxc4 on CC6. The changes are needed because in v4.9.11 kernel the /sys/devices entry for CC6UL and CC6 are the same for the TTYs, causing that on CC6UL ModemManager was also searching for modems on ttymxc4. Signed-off-by: Sebastian Pastor https://jira.digi.com/browse/DEL-5163 --- .../{ => ccimx6}/78-mm-digi-xbee-cellular.rules | 6 ++---- .../ccimx6ul/78-mm-digi-xbee-cellular.rules | 11 +++++++++++ .../modemmanager/modemmanager_%.bbappend | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) rename meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/{ => ccimx6}/78-mm-digi-xbee-cellular.rules (73%) create mode 100644 meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/ccimx6ul/78-mm-digi-xbee-cellular.rules diff --git a/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/78-mm-digi-xbee-cellular.rules b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/ccimx6/78-mm-digi-xbee-cellular.rules similarity index 73% rename from meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/78-mm-digi-xbee-cellular.rules rename to meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/ccimx6/78-mm-digi-xbee-cellular.rules index e3ddda0ec..9f999dd1c 100644 --- a/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/78-mm-digi-xbee-cellular.rules +++ b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/ccimx6/78-mm-digi-xbee-cellular.rules @@ -3,11 +3,9 @@ ACTION!="add|change|move", GOTO="mm_digi_xbee_cellular_modem_end" # By default, ModemManager expects a default baudrate of 57600bps. Different # baudrates may be used by setting the ID_MM_TTY_BAUDRATE udev tag. -# ConnectCore 6 SBC +# ModemManager documentation states that the best practice is to use the DEVPATH +# this way rather than other rules such as KERNEL, so be careful when modifying DEVPATH=="/devices/soc0/soc.0/2100000.aips-bus/21f4000.serial/tty/ttymxc4", ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_MM_PHYSDEV_UID}="Digi XBee Cellular" DEVPATH=="/devices/soc0/soc/2100000.aips-bus/21f4000.serial/tty/ttymxc4", ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_MM_PHYSDEV_UID}="Digi XBee Cellular" -# ConnectCore 6UL SBC Pro -DEVPATH=="/devices/platform/soc/2100000.aips-bus/21e8000.serial/tty/ttymxc1", ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_MM_PHYSDEV_UID}="Digi XBee Cellular" - LABEL="mm_digi_xbee_cellular_modem_end" diff --git a/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/ccimx6ul/78-mm-digi-xbee-cellular.rules b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/ccimx6ul/78-mm-digi-xbee-cellular.rules new file mode 100644 index 000000000..31fbcc68e --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager/ccimx6ul/78-mm-digi-xbee-cellular.rules @@ -0,0 +1,11 @@ +ACTION!="add|change|move", GOTO="mm_digi_xbee_cellular_modem_end" + +# By default, ModemManager expects a default baudrate of 57600bps. Different +# baudrates may be used by setting the ID_MM_TTY_BAUDRATE udev tag. + +# ModemManager documentation states that the best practice is to use the DEVPATH +# this way rather than other rules such as KERNEL, so be careful when modifying +DEVPATH=="/devices/platform/soc/2100000.aips-bus/21e8000.serial/tty/ttymxc1", ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_MM_PHYSDEV_UID}="Digi XBee Cellular" +DEVPATH=="/devices/soc0/soc/2100000.aips-bus/21e8000.serial/tty/ttymxc1", ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_MM_PHYSDEV_UID}="Digi XBee Cellular" + +LABEL="mm_digi_xbee_cellular_modem_end" diff --git a/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_%.bbappend b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_%.bbappend index b1d763aea..1fe0adcf9 100644 --- a/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/modemmanager/modemmanager_%.bbappend @@ -16,3 +16,5 @@ do_install_append() { install -d ${D}${nonarch_base_libdir}/udev/rules.d install -m 0644 ${WORKDIR}/78-mm-digi-xbee-cellular.rules ${D}${nonarch_base_libdir}/udev/rules.d/ } + +PACKAGE_ARCH = "${MACHINE_ARCH}" From 3a5a92f5427e79632e71728c8015f6577d70ced4 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 19 Oct 2017 08:47:28 +0200 Subject: [PATCH 066/113] kernel-module-imx-gpu-viv: update to recipe v6.2.2.p0 This commit adds the recipe to update the Vivante GPU driver to the latest version and refresh patches. https://jira.digi.com/browse/DEL-5082 Signed-off-by: Arturo Buzarra --- meta-digi-arm/conf/machine/ccimx6sbc.conf | 2 + ...mmended-values-for-minimum-GPU-frequ.patch | 0 ...Use-busfreq-imx6.h-up-to-3.15-kernel.patch | 0 ...-gpu-Get-GPU-reserved-memory-from-DT.patch | 0 ...mmended-values-for-minimum-GPU-frequ.patch | 71 +++++++++++++++++++ ...Use-busfreq-imx6.h-up-to-3.15-kernel.patch | 26 +++++++ ...-gpu-Get-GPU-reserved-memory-from-DT.patch | 38 ++++++++++ .../kernel-module-imx-gpu-viv_%.bbappend | 9 --- ...dule-imx-gpu-viv_5.0.11.p8.6+fslc.bbappend | 11 +++ ...kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bb | 18 +++++ ...-module-imx-gpu-viv_6.2.2.p0+fslc.bbappend | 11 +++ 11 files changed, 177 insertions(+), 9 deletions(-) rename meta-digi-arm/recipes-kernel/kernel-modules/{kernel-module-imx-gpu-viv => kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc}/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch (100%) rename meta-digi-arm/recipes-kernel/kernel-modules/{kernel-module-imx-gpu-viv => kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc}/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch (100%) rename meta-digi-arm/recipes-kernel/kernel-modules/{kernel-module-imx-gpu-viv => kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc}/0003-gpu-Get-GPU-reserved-memory-from-DT.patch (100%) create mode 100644 meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch create mode 100644 meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch create mode 100644 meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0003-gpu-Get-GPU-reserved-memory-from-DT.patch delete mode 100644 meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_%.bbappend create mode 100644 meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_5.0.11.p8.6+fslc.bbappend create mode 100644 meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bb create mode 100644 meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bbappend diff --git a/meta-digi-arm/conf/machine/ccimx6sbc.conf b/meta-digi-arm/conf/machine/ccimx6sbc.conf index 1f1a96d93..f7ee17754 100644 --- a/meta-digi-arm/conf/machine/ccimx6sbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6sbc.conf @@ -12,6 +12,8 @@ MACHINE_EXTRA_RRECOMMENDS += "rng-tools" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1' , 'firmware-atheros-ar3k', '', d)}" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1' , 'firmware-atheros-ath6kl', '', d)}" +PREFERRED_VERSION_kernel-module-imx-gpu-viv ?= "5.0.11.p8.6+fslc%" + # U-Boot configurations # Last one is the default (the one the symlinks point at) UBOOT_CONFIG ??= "ccimx6dlsbc512MB ccimx6dlsbc ccimx6qsbc2GB ccimx6qsbc512MB ccimx6qsbc" diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch similarity index 100% rename from meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch rename to meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch similarity index 100% rename from meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch rename to meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv/0003-gpu-Get-GPU-reserved-memory-from-DT.patch b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc/0003-gpu-Get-GPU-reserved-memory-from-DT.patch similarity index 100% rename from meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv/0003-gpu-Get-GPU-reserved-memory-from-DT.patch rename to meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-5.0.11.p8.6+fslc/0003-gpu-Get-GPU-reserved-memory-from-DT.patch diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch new file mode 100644 index 000000000..bd664fb07 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch @@ -0,0 +1,71 @@ +From: Javier Viguera +Date: Tue, 10 Nov 2015 17:45:37 +0100 +Subject: [PATCH] mxc: gpu: use recommended values for minimum GPU frequency + divisor + +Freescale recommends the following default minimum GPU frequency divisors +depending on the CPU family: + - 3 for Dual/Quad + - 8 for DualLite/Solo + +Adapted for the external Vivante GPU driver from commit a790ad3 in linux +git repository. + +Signed-off-by: Javier Viguera +--- + .../hal/os/linux/kernel/gc_hal_kernel_driver.c | 14 +++++++++++++- + .../platform/freescale/gc_hal_kernel_platform_imx6.c | 2 +- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/gc_hal_kernel_driver.c b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/gc_hal_kernel_driver.c +index 816aae0..15a8753 100644 +--- a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/gc_hal_kernel_driver.c ++++ b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/gc_hal_kernel_driver.c +@@ -54,6 +54,7 @@ + + + #include ++#include + #include + #include + +@@ -199,7 +200,7 @@ static uint type = 0; + module_param(type, uint, 0664); + MODULE_PARM_DESC(type, "0 - Char Driver (Default), 1 - Misc Driver"); + +-static int gpu3DMinClock = 1; ++static int gpu3DMinClock = 0; + + static int contiguousRequested = 0; + +@@ -1138,6 +1139,17 @@ static int __devinit gpu_probe(struct platform_device *pdev) + } + } + else { ++ /* If undefined, set Freescale recommended value. Else use the min freq. */ ++ if (gpu3DMinClock == 0) { ++ if (of_machine_is_compatible("fsl,imx6dl")) ++ gpu3DMinClock = 8; ++ else if (of_machine_is_compatible("fsl,imx6q") || ++ of_machine_is_compatible("fsl,imx6qp")) ++ gpu3DMinClock = 3; ++ else ++ gpu3DMinClock = 1; ++ } ++ + ret = drv_init(); + if (!ret) { + platform_set_drvdata(pdev, galDevice); +diff --git a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c +index 89706ec..65a54e2 100644 +--- a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c ++++ b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c +@@ -123,7 +123,7 @@ extern int unregister_thermal_notifier(struct notifier_block *nb); + #define gcdFSL_CONTIGUOUS_SIZE (4 << 20) + #endif + +-static int initgpu3DMinClock = 1; ++static int initgpu3DMinClock = 0; + module_param(initgpu3DMinClock, int, 0644); + + struct platform_device *pdevice; diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch new file mode 100644 index 000000000..4273613a2 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch @@ -0,0 +1,26 @@ +From: Hector Palacios +Date: Tue, 1 Dec 2015 11:36:24 +0100 +Subject: [PATCH] Use busfreq-imx6.h up to 3.15 kernel + +For CC6 we're using Freescale 3.14.28 BSP. Even though we apply stability +patches that move the kernel version beyond 3.14.29 we still want to use +the GPU vivante external module build with the original BSP. + +Signed-off-by: Hector Palacios +--- + .../os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c +index 0eae8262c2ce..f166680affa2 100644 +--- a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c ++++ b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c +@@ -81,7 +81,7 @@ + #include + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) + #include +-#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 29) ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) + #include + #include + #else diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0003-gpu-Get-GPU-reserved-memory-from-DT.patch b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0003-gpu-Get-GPU-reserved-memory-from-DT.patch new file mode 100644 index 000000000..4615d9d93 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv-6.2.2.p0+fslc/0003-gpu-Get-GPU-reserved-memory-from-DT.patch @@ -0,0 +1,38 @@ +From: Mike Engel +Date: Tue, 11 Apr 2017 11:13:23 +0200 +Subject: [PATCH] gpu: Get GPU reserved memory from DT. + +This commit adds support to specify the GPU reserved memory in +the DT. + +Signed-off-by: Mike Engel + +https://jira.digi.com/browse/DEL-3868 +--- + .../linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c +index dc7c976..fd2dbd3 100644 +--- a/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c ++++ b/kernel-module-imx-gpu-viv-src/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c +@@ -568,7 +568,7 @@ gckPLATFORM_AdjustParam( + Args->registerMemSizeVG = res->end - res->start + 1; + } + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "contiguous_mem"); + if (res) + { +@@ -577,8 +577,6 @@ gckPLATFORM_AdjustParam( + if( Args->contiguousSize == ~0U ) + Args->contiguousSize = res->end - res->start + 1; + } +-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +- Args->contiguousBase = 0; + #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + prop = of_get_property(dn, "contiguousbase", NULL); + if(prop) + + diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_%.bbappend b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_%.bbappend deleted file mode 100644 index a6c6597d8..000000000 --- a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_%.bbappend +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (C) 2015-2017 Digi International - -FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" - -SRC_URI += " \ - file://0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch \ - file://0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch \ - file://0003-gpu-Get-GPU-reserved-memory-from-DT.patch \ -" diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_5.0.11.p8.6+fslc.bbappend b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_5.0.11.p8.6+fslc.bbappend new file mode 100644 index 000000000..a0c759e21 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_5.0.11.p8.6+fslc.bbappend @@ -0,0 +1,11 @@ +# Copyright (C) 2015-2017 Digi International + +VER_DIR = "${@d.getVar('PV', True).split('+git')[0]}" + +FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}-${VER_DIR}:" + +SRC_URI += " \ + file://0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch \ + file://0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch \ + file://0003-gpu-Get-GPU-reserved-memory-from-DT.patch \ +" diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bb b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bb new file mode 100644 index 000000000..158d147a0 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bb @@ -0,0 +1,18 @@ +# Copyright (C) 2017 Digi International + +SUMMARY = "Kernel loadable module for Vivante GPU" +DESCRIPTION = "This package uses an exact copy of the GPU kernel driver source code of \ +the same version as base and include fixes and improvements developed by FSL Community" +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e" + +PV .= "+git${SRCPV}" + +SRCREV = "3b9e057f29853fd29364aa666328a92b807007d7" +SRC_URI = "git://github.com/Freescale/kernel-module-imx-gpu-viv.git;protocol=https" + +S = "${WORKDIR}/git" + +inherit module + +KERNEL_MODULE_AUTOLOAD = "galcore" diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bbappend b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bbappend new file mode 100644 index 000000000..bbf63d7d9 --- /dev/null +++ b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-imx-gpu-viv_6.2.2.p0+fslc.bbappend @@ -0,0 +1,11 @@ +# Copyright (C) 2017 Digi International + +VER_DIR = "${@d.getVar('PV', True).split('+git')[0]}" + +FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}-${VER_DIR}:" + +SRC_URI += " \ + file://0001-mxc-gpu-use-recommended-values-for-minimum-GPU-frequ.patch \ + file://0002-Use-busfreq-imx6.h-up-to-3.15-kernel.patch \ + file://0003-gpu-Get-GPU-reserved-memory-from-DT.patch \ +" From bb1171749929f6ccb58b80b428025e7f6241cd21 Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Fri, 20 Oct 2017 16:55:29 +0200 Subject: [PATCH 067/113] linux-dey-4.9: ccimx6qpsbc: sync defconfig https://jira.digi.com/browse/DEL-5176 https://jira.digi.com/browse/DEL-5219 Signed-off-by: Jose Diaz de Grenu --- .../recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig index b4f0820a0..218a3d511 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig @@ -319,7 +319,6 @@ CONFIG_DEBUG_FS=y # CONFIG_FTRACE is not set # CONFIG_ARM_UNWIND is not set CONFIG_SECURITYFS=y -# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_DEFLATE=y From 4b986b197ce978272250364208d02d9cfae440d5 Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Tue, 24 Oct 2017 11:41:22 +0200 Subject: [PATCH 068/113] ccimx6ul: sync defconfig Signed-off-by: Hector Palacios --- .../recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig index 58431835d..7b00f81ee 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig @@ -174,6 +174,7 @@ CONFIG_INPUT_MCA_CC6UL_PWRKEY=y # CONFIG_DEVKMEM is not set CONFIG_SERIAL_IMX=y CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_MCA_CC6UL=y CONFIG_FSL_OTP=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y From 37e4a2f9c3c567b2c5636f4896fa26407793677e Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Tue, 24 Oct 2017 17:44:48 +0200 Subject: [PATCH 069/113] ccimx6qpsbc: added device tree for board ID=160 ARM: dts: added CC6PLUS id160 device tree ID160 corresponds to ConnectCore 6 QuadPlus SBC with: - i.MX6QP, 1 GHz - 4 GB eMMC - 2 GB DDR3 - Microcontroller Assist (MKL14Z32VFT4) - 802.11a/b/g/n/ac - Bluetooth 4.2 - Gigabit Ethernet - CryptoAuth Signed-off-by: Hector Palacios --- meta-digi-arm/conf/machine/ccimx6qpsbc.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-arm/conf/machine/ccimx6qpsbc.conf b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf index 440a20689..55c298d6e 100644 --- a/meta-digi-arm/conf/machine/ccimx6qpsbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf @@ -23,6 +23,7 @@ UBOOT_CONFIG ??= "ccimx6qpsbc2GB" UBOOT_CONFIG[ccimx6qpsbc2GB] = "ccimx6qpsbc2GB_defconfig" KERNEL_DEVICETREE ?= " \ + imx6qp-ccimx6qpsbc-id160.dtb \ imx6qp-ccimx6qpsbc-wb.dtb \ " From 295bad2bbf4cafff7083124ceaaaa329755b1a73 Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Wed, 25 Oct 2017 19:28:28 +0200 Subject: [PATCH 070/113] ccimx6qpsbc: added device tree for CC6PLUS non-wireless variant Signed-off-by: Hector Palacios https://jira.digi.com/browse/DEL-5229 --- meta-digi-arm/conf/machine/ccimx6qpsbc.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-arm/conf/machine/ccimx6qpsbc.conf b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf index 55c298d6e..6d729fe22 100644 --- a/meta-digi-arm/conf/machine/ccimx6qpsbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf @@ -23,6 +23,7 @@ UBOOT_CONFIG ??= "ccimx6qpsbc2GB" UBOOT_CONFIG[ccimx6qpsbc2GB] = "ccimx6qpsbc2GB_defconfig" KERNEL_DEVICETREE ?= " \ + imx6qp-ccimx6qpsbc.dtb \ imx6qp-ccimx6qpsbc-id160.dtb \ imx6qp-ccimx6qpsbc-wb.dtb \ " From a8eaa47b85610de93eec9824b60f348200e0afd4 Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Mon, 30 Oct 2017 17:02:33 +0100 Subject: [PATCH 071/113] meta-digi: update support email address Signed-off-by: Jose Diaz de Grenu --- meta-digi-arm/README | 2 +- meta-digi-dey/README | 2 +- meta-digi-dey/conf/distro/dey.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/meta-digi-arm/README b/meta-digi-arm/README index a59b51cb4..f1c951904 100644 --- a/meta-digi-arm/README +++ b/meta-digi-arm/README @@ -29,4 +29,4 @@ Support ------- This layer is provided 'as is' with no guarantee. However, some support -may be available from support@digi.com +may be available from tech.support@digi.com diff --git a/meta-digi-dey/README b/meta-digi-dey/README index 75c63473c..fa258ad44 100644 --- a/meta-digi-dey/README +++ b/meta-digi-dey/README @@ -29,4 +29,4 @@ Support ------- This layer is provided 'as is' with no guarantee. However, some support -may be available from support@digi.com +may be available from tech.support@digi.com diff --git a/meta-digi-dey/conf/distro/dey.conf b/meta-digi-dey/conf/distro/dey.conf index 3bedfb74b..8a2f1e3b1 100644 --- a/meta-digi-dey/conf/distro/dey.conf +++ b/meta-digi-dey/conf/distro/dey.conf @@ -5,7 +5,7 @@ DISTRO_CODENAME = "morty" SDK_VENDOR = "-deysdk" SDK_VERSION := "${@'${DISTRO_VERSION}'}" -MAINTAINER = "Digi Support " +MAINTAINER = "Digi Support " TARGET_VENDOR = "-dey" From e6f9137f7cab44869be6019fef6e88559d065b8c Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 09:42:48 +0200 Subject: [PATCH 072/113] imx-gpu-viv: Upgrade GPU driver to 6.2.2.p0 This commit adds the recipe to update the GPU driver to the latest version. https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- meta-digi-arm/conf/machine/ccimx6sbc.conf | 1 + .../imx-gpu-viv/imx-gpu-viv-v6.inc | 327 ++++++++++++++++++ .../imx-gpu-viv_6.2.2.p0-aarch32.bb | 16 + 3 files changed, 344 insertions(+) create mode 100644 meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv-v6.inc create mode 100644 meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.2.2.p0-aarch32.bb diff --git a/meta-digi-arm/conf/machine/ccimx6sbc.conf b/meta-digi-arm/conf/machine/ccimx6sbc.conf index f7ee17754..e4ca8c338 100644 --- a/meta-digi-arm/conf/machine/ccimx6sbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6sbc.conf @@ -12,6 +12,7 @@ MACHINE_EXTRA_RRECOMMENDS += "rng-tools" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1' , 'firmware-atheros-ar3k', '', d)}" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1' , 'firmware-atheros-ath6kl', '', d)}" +PREFERRED_VERSION_imx-gpu-viv ?= "5.0.11.p8.6-hfp" PREFERRED_VERSION_kernel-module-imx-gpu-viv ?= "5.0.11.p8.6+fslc%" # U-Boot configurations diff --git a/meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv-v6.inc b/meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv-v6.inc new file mode 100644 index 000000000..d7716601d --- /dev/null +++ b/meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv-v6.inc @@ -0,0 +1,327 @@ +# Copyright (C) 2012-2016 Freescale Semiconductor +# Copyright (C) 2012-2016 O.S. Systems Software LTDA. +# Released under the MIT license (see COPYING.MIT for the terms) + +DESCRIPTION = "GPU driver and apps for imx" +SECTION = "libs" +LICENSE = "Proprietary" +LIC_FILES_CHKSUM = "file://COPYING;md5=08fd295cce89b0a9c74b9b83ed74f671" + +DEPENDS += " \ + ${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'wayland', \ + bb.utils.contains('DISTRO_FEATURES', 'x11', 'virtual/libx11 libxdamage libxext libxfixes', \ + '', d), d)} \ +" +DEPENDS += "libdrm" + +# imx-gpu-viv does not provide everything it needs to for virtual/libgl +# on x11 backend or on Wayland backend with XWayland support. +# We depend on mesa to fill in what is missing. +DEPENDS += "${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'mesa', '', d)}" + +EXTRA_PROVIDES = "" +EXTRA_PROVIDES_append_imxgpu3d = " virtual/libgl virtual/libgles1 virtual/libgles2" +EXTRA_PROVIDES_append_mx6q = " virtual/opencl-icd opencl-headers" +EXTRA_PROVIDES_append_mx8 = " virtual/opencl-icd opencl-headers virtual/libopenvx" +PROVIDES += "imx-gpu-viv virtual/wayland-egl virtual/libgal-x11 virtual/egl virtual/libopenvg ${EXTRA_PROVIDES}" + +RPROVIDES_${PN}_imxgpu3d += "imx-gpu-viv" + +PE = "1" + +inherit fsl-eula-unpack + +SRC_URI = "${FSL_MIRROR}/${PN}-${PV}.bin;fsl-eula=true" + +# Note : If you add a package here, to prevent a naming conflict see the python_anonymous() futher below +PACKAGES =+ "libclc-imx libclc-imx-dev \ + libgl-imx libgl-imx-dev \ + libgles-imx libgles-imx-dev \ + libgles2-imx libgles2-imx-dev \ + libgles3-imx-dev \ + libglslc-imx libglslc-imx-dev \ + libopencl-imx libopencl-imx-dev \ + libopenvg-imx libopenvg-imx-dev \ + libvdk-imx libvdk-imx-dev \ + libegl-imx libegl-imx-dev \ + libgal-imx libgal-imx-dev \ + libvivante-dri-imx \ + libvsc-imx \ + libgbm-imx libgbm-imx-dev \ + libwayland-viv-imx libwayland-viv-imx-dev \ + libgc-wayland-protocol-imx libgc-wayland-protocol-imx-dev \ + libwayland-egl-imx-dev \ + imx-gpu-viv-tools \ + imx-gpu-viv-demos \ + libvulkan-imx libvulkan-imx-dev \ + libopenvx-imx libopenvx-imx-dev \ +" +python __anonymous () { + has_vivante_kernel_driver_support = (d.getVar('MACHINE_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT', True) or '0') + if has_vivante_kernel_driver_support != '1': + raise bb.parse.SkipPackage('The kernel of machine needs to have Vivante kernel driver support for this recipe to be used.') +} + +USE_X11 = "${@bb.utils.contains("DISTRO_FEATURES", "x11", "yes", "no", d)}" +USE_WL = "${@bb.utils.contains("DISTRO_FEATURES", "wayland", "yes", "no", d)}" + +# Inhibit warnings about files being stripped. +INHIBIT_PACKAGE_STRIP = "1" +INHIBIT_PACKAGE_DEBUG_SPLIT = "1" + +# FIXME: The provided binary doesn't provide soname. If in future BSP +# release the libraries are fixed, we can drop this hack. +REALSOLIBS := "${SOLIBS}" +SOLIBS = "${SOLIBSDEV}" + +# For the packages that make up the OpenGL interfaces, inject variables so that +# they don't get Debian-renamed (which would remove the -imx suffix). +# +# FIXME: All binaries lack GNU_HASH in elf binary but as we don't have +# the source we cannot fix it. Disable the insane check for now. +python __anonymous() { + packages = d.getVar('PACKAGES', True).split() + for p in packages: + d.appendVar("INSANE_SKIP_%s" % p, " ldflags") + + for p in (("libegl", "libegl1"), ("libgl", "libgl1"), + ("libgles1", "libglesv1-cm1"), ("libgles2", "libglesv2-2"), + ("libgles3",) , ("libvulkan",)): + fullp = p[0] + "-imx" + pkgs = " ".join(p) + d.setVar("DEBIAN_NOAUTONAME_" + fullp, "1") + d.appendVar("RREPLACES_" + fullp, pkgs) + d.appendVar("RPROVIDES_" + fullp, pkgs) + d.appendVar("RCONFLICTS_" + fullp, pkgs) + + # For -dev, the first element is both the Debian and original name + fullp += "-dev" + pkgs = p[0] + "-dev" + d.setVar("DEBIAN_NOAUTONAME_" + fullp, "1") + d.appendVar("RREPLACES_" + fullp, pkgs) + d.appendVar("RPROVIDES_" + fullp, pkgs) + d.appendVar("RCONFLICTS_" + fullp, pkgs) +} + +IS_MX6SL = "0" +IS_MX6SL_mx6sl = "1" + +IS_MX8 = "0" +IS_MX8_mx8 = "1" + +do_install () { + install -d ${D}${libdir} + install -d ${D}${includedir} + install -d ${D}${bindir} + + cp -P ${S}/gpu-core/usr/lib/*.so* ${D}${libdir} + cp -r ${S}/gpu-core/usr/include/* ${D}${includedir} + cp -r ${S}/gpu-demos/opt ${D} + cp -r ${S}/gpu-tools/gmem-info/usr/bin/* ${D}${bindir} + + + install -d ${D}${libdir}/pkgconfig + + # The preference order, based in DISTRO_FEATURES, is Wayland (with or without X11), X11 and fb + if [ "${USE_WL}" = "yes" ]; then + + backend=wl + + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/egl_wayland.pc ${D}${libdir}/pkgconfig/egl.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/glesv1_cm.pc ${D}${libdir}/pkgconfig/glesv1_cm.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/glesv2.pc ${D}${libdir}/pkgconfig/glesv2.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/vg.pc ${D}${libdir}/pkgconfig/vg.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/gc_wayland_protocol.pc ${D}${libdir}/pkgconfig/gc_wayland_protocol.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/wayland-egl.pc ${D}${libdir}/pkgconfig/wayland-egl.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/wayland-viv.pc ${D}${libdir}/pkgconfig/wayland-viv.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/gbm.pc ${D}${libdir}/pkgconfig/gbm.pc + + if [ "${USE_X11}" = "yes" ]; then + + cp -r ${S}/gpu-core/usr/lib/dri ${D}${libdir} + + fi + + elif [ "${USE_X11}" = "yes" ]; then + + cp -r ${S}/gpu-core/usr/lib/dri ${D}${libdir} + + backend=x11 + + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/gl_x11.pc ${D}${libdir}/pkgconfig/gl.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/egl_x11.pc ${D}${libdir}/pkgconfig/egl.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/glesv1_cm_x11.pc ${D}${libdir}/pkgconfig/glesv1_cm.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/glesv2_x11.pc ${D}${libdir}/pkgconfig/glesv2.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/vg_x11.pc ${D}${libdir}/pkgconfig/vg.pc + + else + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/glesv1_cm.pc ${D}${libdir}/pkgconfig/glesv1_cm.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/glesv2.pc ${D}${libdir}/pkgconfig/glesv2.pc + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/vg.pc ${D}${libdir}/pkgconfig/vg.pc + + # Regular framebuffer + install -m 0644 ${S}/gpu-core/usr/lib/pkgconfig/egl_linuxfb.pc ${D}${libdir}/pkgconfig/egl.pc + + backend=fb + + fi + + # Install Vendor ICDs for OpenCL's installable client driver loader (ICDs Loader) + install -d ${D}${sysconfdir}/OpenCL/vendors/ + install -m 0644 ${S}/gpu-core/etc/Vivante.icd ${D}${sysconfdir}/OpenCL/vendors/Vivante.icd + + # We'll only have one backend here so we rename it to generic name + # and avoid rework in other packages, when possible + mv ${D}${libdir}/libGL.so.1.2 ${D}${libdir}/libGL.so.1.2.0 + ln -sf libGL.so.1.2.0 ${D}${libdir}/libGL.so.1.2 + ln -sf libGL.so.1.2.0 ${D}${libdir}/libGL.so.1 + ln -sf libGL.so.1.2.0 ${D}${libdir}/libGL.so + mv ${D}${libdir}/libEGL-${backend}.so ${D}${libdir}/libEGL.so.1.0 + ln -sf libEGL.so.1.0 ${D}${libdir}/libEGL.so.1 + ln -sf libEGL.so.1.0 ${D}${libdir}/libEGL.so + mv ${D}${libdir}/libGAL-${backend}.so ${D}${libdir}/libGAL.so + mv ${D}${libdir}/libVDK-${backend}.so ${D}${libdir}/libVDK.so + + # update libglesv2 as backend dependent + rm -rf ${D}${libdir}/libGLESv2* + cp ${S}/gpu-core/usr/lib/libGLESv2-${backend}.so ${D}${libdir}/libGLESv2.so.2.0.0 + ln -sf libGLESv2.so.2.0.0 ${D}${libdir}/libGLESv2.so.2 + ln -sf libGLESv2.so.2.0.0 ${D}${libdir}/libGLESv2.so + + if [ "${IS_MX8}" = "1" ]; then + # Install the vulkan driver in a sub-folder. When installed in the same + # folder as the vulkan loader layer library, an incorrect linkage is + # created from libvulkan.so.1 to our library instead of the loader + # layer library. + install -d ${D}${libdir}/vulkan + mv ${D}${libdir}/libvulkan-${backend}.so ${D}${libdir}/vulkan/libvulkan_VSI.so + fi + + # skip packaging wayland libraries if no support is requested + if [ "${USE_WL}" = "no" ]; then + rm ${D}${libdir}/libgc_wayland_protocol.* + rm ${D}${libdir}/libwayland-viv.* + fi + + for i in wl x11 fb dri; do + find ${D}${libdir} -name "*-$i.so" -exec rm '{}' ';' + find ${D}${libdir} -name "*.$i.so" -exec rm '{}' ';' + done + + # FIXME: MX6SL does not have 3D support; hack it for now + if [ "${IS_MX6SL}" = "1" ]; then + rm -rf ${D}${libdir}/libCLC* ${D}${includedir}/CL \ + \ + ${D}${libdir}/libGL* ${D}${includedir}/GL* ${D}${libdir}/pkgconfig/gl.pc \ + \ + ${D}${libdir}/libGLES* ${D}${libdir}/pkgconfig/gles*.pc \ + \ + ${D}${libdir}/libOpenCL* ${D}${includedir}/CL \ + \ + ${D}${libdir}/libOpenVG.3d.so \ + \ + ${D}${libdir}/libVivanteOpenCL.so \ + \ + ${D}/opt/viv_samples/vdk \ + ${D}/opt/viv_samples/es20 ${D}/opt/viv_samples/cl11 + + ln -sf libOpenVG.2d.so ${D}${libdir}/libOpenVG.so + fi + + find ${D}${libdir} -type f -exec chmod 644 {} \; + find ${D}${includedir} -type f -exec chmod 644 {} \; + + chown -R root:root "${D}" +} + +ALLOW_EMPTY_${PN} = "1" + +# FIXME: Remove the following lines after adding libopenvx package +INSANE_SKIP_imx-gpu-viv-dev += "dev-elf" +INSANE_SKIP_libclc-imx += "dev-deps" + +FILES_libclc-imx = "${libdir}/libCLC${SOLIBS}" +FILES_libclc-imx-dev = "${includedir}/CL ${libdir}/libCLC${SOLIBSDEV}" + +# libEGL.so is used by some demo apps from Freescale +INSANE_SKIP_libegl-imx += "dev-so" +FILES_libegl-imx = "${libdir}/libEGL${REALSOLIBS} ${libdir}/libEGL${SOLIBSDEV} " +FILES_libegl-imx-dev = "${includedir}/EGL ${includedir}/KHR ${libdir}/pkgconfig/egl.pc" +RDEPENDS_libegl-imx += "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'libgc-wayland-protocol-imx libwayland-viv-imx libgc-wayland-protocol-imx', '', d)}" +RDEPENDS_libegl-imx-dev += "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'libwayland-egl-imx-dev', '', d)}" + +FILES_libgal-imx = "${libdir}/libGAL${SOLIBS} ${libdir}/libGAL_egl${SOLIBS}" +FILES_libgal-imx-dev = "${libdir}/libGAL${SOLIBSDEV} ${includedir}/HAL" +RDEPENDS_libgal-imx += "kernel-module-imx-gpu-viv" +RPROVIDES_libgal-imx += "libgal-imx" +INSANE_SKIP_libgal-imx += "build-deps" + +FILES_libvsc-imx = "${libdir}/libVSC${SOLIBS}" + +FILES_libgbm-imx = "${libdir}/libgbm${SOLIBS} ${libdir}/gbm_viv${SOLIBS}" +FILES_libgbm-imx-dev = "${libdir}/pkgconfig/gbm.pc ${includedir}/gbm.h ${libdir}/libgbm${SOLIBSDEV}" +RDEPENDS_libgbm-imx += "libdrm" + +FILES_libvulkan-imx = "${libdir}/vulkan/libvulkan_VSI${SOLIBS}" +FILES_libvulkan-imx-dev = "${includedir}/vulkan ${libdir}/vulkan/libvulkan_VSI${SOLIBSDEV}" +INSANE_SKIP_libvulkan-imx += "dev-deps dev-so" + +FILES_libopenvx-imx = "${libdir}/libOpenVX${SOLIBS} ${libdir}/libOpenVXC${SOLIBS} ${libdir}/libOpenVXU${SOLIBS}" +FILES_libopenvx-imx-dev = "${includedir}/VX ${libdir}/libopenVX${SOLIBSDEV}" + +FILES_libgl-imx = "${libdir}/libGL${REALSOLIBS}" +FILES_libgl-imx-dev = "${libdir}/libGL${SOLIBSDEV} ${includedir}/GL" +# Includes GL headers from mesa +RDEPENDS_libgl-imx-dev += "libgl-mesa-dev" + +# libEGL needs to open libGLESv1.so +INSANE_SKIP_libgles-imx += "dev-so" +FILES_libgles-imx = "${libdir}/libGLESv1*${REALSOLIBS} ${libdir}/libGLESv1*${SOLIBS} ${libdir}/libGLES_*${REALSOLIBS} ${libdir}/libGLES_*${SOLIBS}" +FILES_libgles-imx-dev = "${includedir}/GLES ${libdir}/libGLESv1*${SOLIBS} ${libdir}/libGLES_*${SOLIBSDEV} ${libdir}/pkgconfig/glesv1_cm.pc" + +# libEGL needs to open libGLESv2.so +INSANE_SKIP_libgles2-imx += "dev-so" +FILES_libgles2-imx = "${libdir}/libGLESv2${REALSOLIBS} ${libdir}/libGLESv2${SOLIBS}" +FILES_libgles2-imx-dev = "${includedir}/GLES2 ${libdir}/libGLESv2${SOLIBSDEV} ${libdir}/pkgconfig/glesv2.pc" +RDEPENDS_libgles2-imx = "libglslc-imx" + +FILES_libgles3-imx-dev = "${includedir}/GLES3" +# as long as there is no libgles3: ship libgles3-dev along with +# libgles2-dev - otherwise GLES3 headers have to be added manually +RDEPENDS_libgles2-imx-dev += "libgles3-imx-dev" + +FILES_libglslc-imx = "${libdir}/libGLSLC${SOLIBS}" +FILES_libglslc-imx-dev = "${includedir}/CL ${libdir}/libGLSLC${SOLIBSDEV}" + +FILES_libopencl-imx = "${libdir}/libOpenCL${SOLIBS} \ + ${libdir}/libVivanteOpenCL${SOLIBS} \ + ${sysconfdir}/OpenCL/vendors/Vivante.icd" +FILES_libopencl-imx-dev = "${includedir}/CL ${libdir}/libOpenCL${SOLIBSDEV}" +RDEPENDS_libopencl-imx= "libclc-imx" + +INSANE_SKIP_libopenvg-imx += "dev-so" +FILES_libopenvg-imx = "${libdir}/libOpenVG*${SOLIBS}" +FILES_libopenvg-imx-dev = "${includedir}/VG ${libdir}/libOpenVG*${SOLIBSDEV} ${libdir}/pkgconfig/vg.pc" +RDEPENDS_libopenvg-imx += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd-gpuconfig', '', d)}" + +FILES_libvdk-imx = "${libdir}/libVDK${SOLIBS}" +FILES_libvdk-imx-dev = "${includedir}/*vdk*.h ${libdir}/libVDK${SOLIBSDEV}" + +FILES_libvivante-dri-imx = "${libdir}/dri/vivante_dri.so" +RDEPENDS_libvivante-dri-imx = "libdrm" + +INSANE_SKIP_libwayland-viv-imx += "dev-so" +FILES_libwayland-viv-imx = "${libdir}/libwayland-viv${REALSOLIBS} ${libdir}/libwayland-viv${SOLIBS}" +FILES_libwayland-viv-imx-dev = "${includedir}/wayland-viv ${libdir})/libwayland-viv${SOLIBSDEV} ${libdir}/pkgconfig/wayland-viv.pc" +RPROVIDES_libwayland-viv-imx += "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'xf86-video-imxfb-vivante', '', d)}" + +INSANE_SKIP_libgc-wayland-protocol-imx += "dev-so" +FILES_libgc-wayland-protocol-imx = "${libdir}/libgc_wayland_protocol${REALSOLIBS} ${libdir}/libgc_wayland_protocol${SOLIBS}" +FILES_libgc-wayland-protocol-imx-dev = "${libdir}/libgc_wayland_protocol${SOLIBSDEV} ${libdir}/pkgconfig/gc_wayland_protocol.pc" + +FILES_libwayland-egl-imx-dev = "${libdir}/pkgconfig/wayland-egl.pc" + +FILES_imx-gpu-viv-tools = "${bindir}/gmem_info" + +FILES_imx-gpu-viv-demos = "/opt" +INSANE_SKIP_imx-gpu-viv-demos += "rpaths dev-deps" diff --git a/meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.2.2.p0-aarch32.bb b/meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.2.2.p0-aarch32.bb new file mode 100644 index 000000000..c48216ab5 --- /dev/null +++ b/meta-digi-dey/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.2.2.p0-aarch32.bb @@ -0,0 +1,16 @@ +# Copyright (C) 2013-2016 Freescale Semiconductor +# Copyright 2017 NXP +# Released under the MIT license (see COPYING.MIT for the terms) + +require recipes-graphics/imx-gpu-viv/imx-gpu-viv-v6.inc + +SRC_URI = "${FSL_MIRROR}/${PN}-${PV}.bin;fsl-eula=true" + +S="${WORKDIR}/${PN}-${PV}" + +SRC_URI[md5sum] = "7d43f73b8bc0c1c442587f819218a1d5" +SRC_URI[sha256sum] = "4f93a4412c93ca5959aa2437bfed2ecbaf983b5b272be5977f76a967de5db150" + +PACKAGE_FP_TYPE = "hardfp" + +COMPATIBLE_MACHINE = "(mx6q|mx6dl|mx6sx|mx6sl|mx7ulp)" From 1fec236192c1c7cdef2f2e2675273d61eedf6f71 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 09:54:01 +0200 Subject: [PATCH 073/113] xf86-video-imxfb-vivante: Upgrade to 6.2.2.p0 https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- meta-digi-arm/conf/machine/ccimx6sbc.conf | 1 + ...top-using-Git-to-write-local-version.patch | 87 +++++++++++++++++++ .../xf86-video-imxfb-vivante/rc.autohdmi | 42 +++++++++ .../xf86-video-imxfb-vivante_6.2.2.p0.bb | 24 +++++ 4 files changed, 154 insertions(+) create mode 100644 meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/Stop-using-Git-to-write-local-version.patch create mode 100644 meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/rc.autohdmi create mode 100644 meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante_6.2.2.p0.bb diff --git a/meta-digi-arm/conf/machine/ccimx6sbc.conf b/meta-digi-arm/conf/machine/ccimx6sbc.conf index e4ca8c338..0b257d8f5 100644 --- a/meta-digi-arm/conf/machine/ccimx6sbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6sbc.conf @@ -14,6 +14,7 @@ MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1' , 'firmware-ath PREFERRED_VERSION_imx-gpu-viv ?= "5.0.11.p8.6-hfp" PREFERRED_VERSION_kernel-module-imx-gpu-viv ?= "5.0.11.p8.6+fslc%" +PREFERRED_VERSION_xf86-video-imxfb-vivante ?= "5.0.11.p8.6" # U-Boot configurations # Last one is the default (the one the symlinks point at) diff --git a/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/Stop-using-Git-to-write-local-version.patch b/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/Stop-using-Git-to-write-local-version.patch new file mode 100644 index 000000000..f541e5c17 --- /dev/null +++ b/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/Stop-using-Git-to-write-local-version.patch @@ -0,0 +1,87 @@ +From 69a92f4576a1e789ba2fcf957164d2c4013020c5 Mon Sep 17 00:00:00 2001 +From: Otavio Salvador +Date: Wed, 2 Dec 2015 13:36:25 +0000 +Subject: [PATCH] Stop using Git to write local version +Organization: O.S. Systems Software LTDA. + +The standard version does not use a Git repository so we should not +use Git to identify the commit of the build as it can end getting the +version from a wrong repository and can be misleading. + +Upstream-Status: Pending + +Signed-off-by: Otavio Salvador +--- + EXA/src/makefile.tc | 6 +++--- + FslExt/src/makefile.tc | 6 +++--- + util/autohdmi/makefile.tc | 6 +++--- + util/pandisplay/makefile.tc | 6 +++--- + 4 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/EXA/src/makefile.tc b/EXA/src/makefile.tc +index 0b9a9e6..ec6e68d 100644 +--- a/EXA/src/makefile.tc ++++ b/EXA/src/makefile.tc +@@ -52,8 +52,8 @@ prefix ?= /usr + sysroot ?= / + + # get git commit number +-COMMITNR := `git log -n 1 --format=%H` +-DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` +-LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" ++#COMMITNR := `git log -n 1 --format=%H` ++#DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` ++#LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" + + +diff --git a/FslExt/src/makefile.tc b/FslExt/src/makefile.tc +index 0b9a9e6..ec6e68d 100644 +--- a/FslExt/src/makefile.tc ++++ b/FslExt/src/makefile.tc +@@ -52,8 +52,8 @@ prefix ?= /usr + sysroot ?= / + + # get git commit number +-COMMITNR := `git log -n 1 --format=%H` +-DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` +-LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" ++#COMMITNR := `git log -n 1 --format=%H` ++#DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` ++#LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" + + +diff --git a/util/autohdmi/makefile.tc b/util/autohdmi/makefile.tc +index c9de0a6..d0a468c 100644 +--- a/util/autohdmi/makefile.tc ++++ b/util/autohdmi/makefile.tc +@@ -64,8 +64,8 @@ prefix ?= /usr + sysroot ?= / + + # get git commit number +-COMMITNR := `git log -n 1 --format=%H` +-DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` +-LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" ++#COMMITNR := `git log -n 1 --format=%H` ++#DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` ++#LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" + + +diff --git a/util/pandisplay/makefile.tc b/util/pandisplay/makefile.tc +index 28732b9..bf54c20 100644 +--- a/util/pandisplay/makefile.tc ++++ b/util/pandisplay/makefile.tc +@@ -64,8 +64,8 @@ prefix ?= /usr + sysroot ?= / + + # get git commit number +-COMMITNR := `git log -n 1 --format=%H` +-DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` +-LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" ++#COMMITNR := `git log -n 1 --format=%H` ++#DIRTY := `git diff-index --quiet HEAD || echo '-dirty'` ++#LOCAL_CFLAGS += -DCOMMIT="${COMMITNR}${DIRTY}" + + +-- +2.1.4 + diff --git a/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/rc.autohdmi b/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/rc.autohdmi new file mode 100644 index 000000000..8c16a1d7f --- /dev/null +++ b/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante/rc.autohdmi @@ -0,0 +1,42 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: rc.autohdmi +# Required-Start: $all +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: +### END INIT INFO + +PATH=/sbin:/usr/sbin:/bin:/usr/bin + +# Source function library. +. /etc/init.d/functions + +case "$1" in + start) + echo -n "Starting autohdmi: " + export DISPLAY=:0 + autohdmi & + echo + exit 0 + ;; + reload|force-reload) + echo "Error: argument '$1' not supported" >&2 + exit 3 + ;; + stop) + echo -n "Shutting down autohdmi: " + killproc autohdmi + echo + ;; + restart) + echo -n "Restarting autohdmi: " + $0 stop + $0 start + echo + ;; + *) + echo "Usage: $0 start|stop" >&2 + exit 3 + ;; +esac diff --git a/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante_6.2.2.p0.bb b/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante_6.2.2.p0.bb new file mode 100644 index 000000000..3768064a3 --- /dev/null +++ b/meta-digi-dey/recipes-graphics/xorg-driver/xf86-video-imxfb-vivante_6.2.2.p0.bb @@ -0,0 +1,24 @@ +# Copyright (C) 2012-2016 Freescale Semiconductor +# Copyright (C) 2012-2014 O.S. Systems Software LTDA. +# Copyright 2017 NXP +# Released under the MIT license (see COPYING.MIT for the terms) + +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +require recipes-graphics/xorg-driver/xf86-video-imxfb-vivante.inc + +NXP_REPO_MIRROR ?= "nxp/" +SRCBRANCH = "${NXP_REPO_MIRROR}imx_4.9.11_1.0.0_ga" +S = "${WORKDIR}/git/" +XF86_VIDEO_IMX_VIVANTE_SRC ?= "git://source.codeaurora.org/external/imx/xf86-video-imx-vivante.git;protocol=https" +SRC_URI = "${XF86_VIDEO_IMX_VIVANTE_SRC};branch=${SRCBRANCH}" +SRC_URI +="file://rc.autohdmi" +SRCREV = "07ef065dfe09f1c05a1a188c371577faa3677a17" + +DEPENDS += "virtual/libg2d" + +RDEPENDS_${PN}_remove = "libvivante-dri-mx6" + +RDEPENDS_${PN}_append = " libvivante-dri-imx" + +COMPATIBLE_MACHINE = "(mx6|mx8|mx7ulp)" From 7096238b0889e3904c54f533716e6ab75adcf88c Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 10:07:23 +0200 Subject: [PATCH 074/113] mesa: remove parts provided by imx-gpu-viv v6 for ccimx6qpsbc This commit adds a platform dependency to remove the parts provided by the new GPU driver and maintain the compatibility for other platforms using previous versions. https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- .../recipes-graphics/mesa/mesa_%.bbappend | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/meta-digi-dey/recipes-graphics/mesa/mesa_%.bbappend b/meta-digi-dey/recipes-graphics/mesa/mesa_%.bbappend index d9020a0e6..a244fe9a4 100644 --- a/meta-digi-dey/recipes-graphics/mesa/mesa_%.bbappend +++ b/meta-digi-dey/recipes-graphics/mesa/mesa_%.bbappend @@ -4,3 +4,23 @@ # Add runtime dependency so that GLES3 headers don't need to be added manually # RDEPENDS_libgles2-mesa-dev += "libgles3-mesa-dev" + +# +# Add platform dependency to maintain compatibility +# with GPU driver previous to v6. +# +PROVIDES_remove_ccimx6qpsbc = "gbm" +PACKAGECONFIG_remove_ccimx6qpsbc = "gbm" + +BACKEND = \ + "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'wayland', \ + bb.utils.contains('DISTRO_FEATURES', 'x11', 'x11', \ + 'fb', d), d)}" + +do_install_append_ccimx6qpsbc () { + rm -f ${D}${includedir}/GL/glx.h \ + ${D}${includedir}/GL/glxext.h + if [ "${BACKEND}" = "x11" ]; then + rm -f ${D}${libdir}/pkgconfig/gl.pc + fi +} From 2d0da1cc5566cbc1319b9680f23bbd2f299fe420 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 10:17:50 +0200 Subject: [PATCH 075/113] imx-gpu-g2d: move imx-gpu-g2d out of imx-gpu-viv v6 This commit re-adds the imx-gpu-g2d recipe that was removed from the imx-gpu-viv v6 driver. https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- meta-digi-arm/conf/machine/ccimx6qpsbc.conf | 2 ++ .../imx-gpu-g2d/imx-gpu-g2d_6.2.2.p0.bb | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 meta-digi-dey/recipes-graphics/imx-gpu-g2d/imx-gpu-g2d_6.2.2.p0.bb diff --git a/meta-digi-arm/conf/machine/ccimx6qpsbc.conf b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf index 6d729fe22..810d92b89 100644 --- a/meta-digi-arm/conf/machine/ccimx6qpsbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6qpsbc.conf @@ -17,6 +17,8 @@ MACHINE_EXTRA_RRECOMMENDS += "cryptoauthlib" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1', 'firmware-qualcomm-qca6564-bt', '', d)}" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1', 'firmware-qualcomm-qca6564-wifi', '', d)}" +PREFERRED_PROVIDER_virtual/libg2d_mx6 = "imx-gpu-g2d" + # U-Boot configurations # Last one is the default (the one the symlinks point at) UBOOT_CONFIG ??= "ccimx6qpsbc2GB" diff --git a/meta-digi-dey/recipes-graphics/imx-gpu-g2d/imx-gpu-g2d_6.2.2.p0.bb b/meta-digi-dey/recipes-graphics/imx-gpu-g2d/imx-gpu-g2d_6.2.2.p0.bb new file mode 100644 index 000000000..8be05f93f --- /dev/null +++ b/meta-digi-dey/recipes-graphics/imx-gpu-g2d/imx-gpu-g2d_6.2.2.p0.bb @@ -0,0 +1,36 @@ +# Copyright (C) 2016 Freescale Semiconductor +# Copyright 2017 NXP +# Released under the MIT license (see COPYING.MIT for the terms) + +DESCRIPTION = "GPU G2D library and apps for imx6" +LICENSE = "Proprietary" +LIC_FILES_CHKSUM = "file://COPYING;md5=08fd295cce89b0a9c74b9b83ed74f671" + +PROVIDES += "virtual/libg2d" + +SRC_URI = "${FSL_MIRROR}/${PN}-${PV}.bin;fsl-eula=true" + +S="${WORKDIR}/${PN}-${PV}" + +inherit fsl-eula-unpack + +SRC_URI[md5sum] = "64720dda9b96fd7af5be7e2c654ab72a" +SRC_URI[sha256sum] = "070a95aa9942bd67e8ba4012962df74143bffb9998301ac097dab5e1437000d8" + +do_install () { + + install -d ${D}${libdir} + install -d ${D}${includedir} + + cp ${S}/g2d/usr/lib/*.so* ${D}${libdir} + cp -Pr ${S}/g2d/usr/include/* ${D}${includedir} + cp -r ${S}/gpu-demos/opt ${D} +} + +RDEPENDS_${PN} = "libgal-imx" + +FILES_${PN} = "${libdir}/libg2d* /opt" +FILES_${PN}-dev = "${includedir}" +INSANE_SKIP_${PN} = "ldflags" + +COMPATIBLE_MACHINE = "(mx6|mx7ulp)" From a4f33b85b42e83e91e70e5f449fedceff20ff1a7 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 11:49:15 +0200 Subject: [PATCH 076/113] imx-vpu: upgrade VPU library to v5.4.37 https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- .../recipes-bsp/imx-vpu/imx-vpu_5.4.37.bb | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 meta-digi-arm/recipes-bsp/imx-vpu/imx-vpu_5.4.37.bb diff --git a/meta-digi-arm/recipes-bsp/imx-vpu/imx-vpu_5.4.37.bb b/meta-digi-arm/recipes-bsp/imx-vpu/imx-vpu_5.4.37.bb new file mode 100644 index 000000000..05f77def3 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/imx-vpu/imx-vpu_5.4.37.bb @@ -0,0 +1,21 @@ +# Copyright (C) 2013-2016 Freescale Semiconductor +# Copyright 2017 NXP + +require recipes-bsp/imx-vpu/imx-vpu.inc +LIC_FILES_CHKSUM = "file://COPYING;md5=6b552f505eedab4a11ab538cf3db743a" + +PE = "1" + +SRC_URI[md5sum] = "2b8311cb6e5b5813253db706e807d962" +SRC_URI[sha256sum] = "ee265e88d17c7369bd9cb917e7cce035b8c7ee2ba4491645fdab9f382f54beb0" + +# imx-vpu can only support imx6q platform, in order to build out the vpu case in unit test, +# using a workaround to transfer "IMX6Q" on imx6ul & imx7d platform. +PLATFORM_mx6ul = "IMX6Q" +PLATFORM_mx7 = "IMX6Q" +PLATFORM_mx6sll = "IMX6Q" + +PROVIDES = "virtual/libvpu" +RPROVIDES_${PN} = "virtual/libvpu" + +COMPATIBLE_MACHINE = "(ccimx6qpsbc)" From b9440ff590df2eafef65e8b52fe230af6c1feb63 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 12:24:37 +0200 Subject: [PATCH 077/113] firmware-imx: upgrade VPU firmware to v6.0 https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- .../recipes-bsp/firmware-imx/firmware-imx_6.0.bb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 meta-digi-arm/recipes-bsp/firmware-imx/firmware-imx_6.0.bb diff --git a/meta-digi-arm/recipes-bsp/firmware-imx/firmware-imx_6.0.bb b/meta-digi-arm/recipes-bsp/firmware-imx/firmware-imx_6.0.bb new file mode 100644 index 000000000..5c2cfb949 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/firmware-imx/firmware-imx_6.0.bb @@ -0,0 +1,13 @@ +# Copyright (C) 2012-2016 Freescale Semiconductor +# Copyright 2017 NXP + +require recipes-bsp/firmware-imx/firmware-imx.inc +LIC_FILES_CHKSUM = "file://COPYING;md5=6b552f505eedab4a11ab538cf3db743a" + +SRC_URI[md5sum] = "088fb08b565748b537f6481b1ad6c9d7" +SRC_URI[sha256sum] = "9fa7c204a6ff8a30f2b5e8f9002d8c5736791e455dc137b952fa725dc0c3aeb8" + +#BRCM firmware git +SRCREV = "951c1363abe95dd75ab3e9447f640d7807240236" + +COMPATIBLE_MACHINE = "(ccimx6qpsbc)" From cb496e49bee6dd34b4769f90ce28f16bae037503 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 14:07:25 +0200 Subject: [PATCH 078/113] imx-codec: Upgrade to 4.2.1 version https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- .../recipes-multimedia/imx-codec/imx-codec_4.2.1.bb | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.2.1.bb diff --git a/meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.2.1.bb b/meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.2.1.bb new file mode 100644 index 000000000..6076ee964 --- /dev/null +++ b/meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.2.1.bb @@ -0,0 +1,11 @@ +# Copyright (C) 2013-2016 Freescale Semiconductor +# Copyright 2017 NXP +# Released under the MIT license (see COPYING.MIT for the terms) + +require recipes-multimedia/imx-codec/imx-codec.inc +LIC_FILES_CHKSUM = "file://COPYING;md5=6b552f505eedab4a11ab538cf3db743a" + +SRC_URI[md5sum] = "3db67e3f602e65fe0ac00ae4f9ea6109" +SRC_URI[sha256sum] = "20d3f9b4187fcd9e7007c94558a00bab1191513eee74b6f0d8c7b43f874e06ed" + +COMPATIBLE_MACHINE = "(ccimx6qpsbc)" From 55b59c9525af69504647261a835f18edd0411420 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 27 Oct 2017 14:19:11 +0200 Subject: [PATCH 079/113] imx-parser: Upgrade to 4.2.1 version https://jira.digi.com/browse/DEL-5234 Signed-off-by: Arturo Buzarra --- .../recipes-multimedia/imx-parser/imx-parser_4.2.1.bb | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.2.1.bb diff --git a/meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.2.1.bb b/meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.2.1.bb new file mode 100644 index 000000000..dcac23417 --- /dev/null +++ b/meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.2.1.bb @@ -0,0 +1,11 @@ +# Copyright (C) 2013-2016 Freescale Semiconductor +# Copyright 2017 NXP +# Released under the MIT license (see COPYING.MIT for the terms) + +include recipes-multimedia/imx-parser/imx-parser.inc +LIC_FILES_CHKSUM = "file://COPYING;md5=6b552f505eedab4a11ab538cf3db743a" + +SRC_URI[md5sum] = "6717799abce0dc5918db8d3fd0e39184" +SRC_URI[sha256sum] = "36d3ae7285f3a83a87abf680b8a52b3c07df869d2443de844fb5f0ff528ca862" + +COMPATIBLE_MACHINE = "(ccimx6qpsbc)" From 387381a586ee322525e393c1ddbbcb74279b4f16 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Fri, 3 Nov 2017 17:21:53 +0100 Subject: [PATCH 080/113] bluez: squash specific qualcomm code Create a multiple patch file with the original qualcomm code that adds support for the qca6564 chip (hcitattach_rome) Signed-off-by: Isaac Hermida --- .../0003-QCA_bluetooth_chip_support.patch | 4190 +++++++++++++++++ ...d-bluetooth-support-for-QCA6174-chip.patch | 2068 -------- ...-bluetooth-low-power-mode-functional.patch | 28 - ...spect-the-user-indication-for-noflo.patch} | 0 ...ix-bug-in-firmware-parsing-mechanism.patch | 51 - ...f-the-user-supplies-a-bdaddr-use-it.patch} | 0 .../0006-bluetooth-Configure-BD-Address.patch | 114 - ...0006-hciattach-Add-verbosity-option.patch} | 0 ...-unused-functions-in-the-firmware-do.patch | 73 - ...0007-port-test-discovery-to-python3.patch} | 0 ...tooth-Enable-3Mbps-baud-rate-support.patch | 150 - ...er-update-example-to-master-version.patch} | 0 ...TTY-buffer-for-data-availability-bef.patch | 189 - ...upport-for-TUFEELO-firmware-download.patch | 44 - ...uetooth-Add-support-for-ROME-3.2-SOC.patch | 236 - ...rrect-TTY-ioctl-calls-for-flow-contr.patch | 189 - ...ooth-Add-support-for-multi-baud-rate.patch | 256 - ...ttings-by-reading-configuration-file.patch | 144 - ...0015-Add-support-for-Tufello-1.1-SOC.patch | 169 - ...ART-CLK-ON-prior-to-firmware-downloa.patch | 74 - ...ttings-by-reading-configuration-file.patch | 127 - ...ter-derefrencing-in-AVRCP-Target-rol.patch | 79 - ...bluetooth-Fix-flow-control-operation.patch | 52 - ...M-specific-code-under-_PLATFORM_MDM_.patch | 65 - ...Bluetooth-Fix-static-analysis-issues.patch | 37 - .../bluez/bluez5_5.41.bbappend | 30 +- 26 files changed, 4196 insertions(+), 4169 deletions(-) create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-QCA_bluetooth_chip_support.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch => 0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch} (100%) delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch => 0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch} (100%) delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-bluetooth-Configure-BD-Address.patch rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0024-hciattach-Add-verbosity-option.patch => 0006-hciattach-Add-verbosity-option.patch} (100%) delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0025-port-test-discovery-to-python3.patch => 0007-port-test-discovery-to-python3.patch} (100%) delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0027-example-gatt-server-update-example-to-master-version.patch => 0008-example-gatt-server-update-example-to-master-version.patch} (100%) delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-bluetooth-Add-support-for-multi-baud-rate.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-Override-PCM-Settings-by-reading-configuration-file.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-Add-support-for-Tufello-1.1-SOC.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0017-Override-IBS-settings-by-reading-configuration-file.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0019-bluetooth-Fix-flow-control-operation.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch delete mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0021-Bluetooth-Fix-static-analysis-issues.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-QCA_bluetooth_chip_support.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-QCA_bluetooth_chip_support.patch new file mode 100644 index 000000000..1f6e178c4 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-QCA_bluetooth_chip_support.patch @@ -0,0 +1,4190 @@ +Add hciattach rome support for Qualcomm chip QCA6564 + +This is a multiple patch including all the specific qualcomm commits to add +support for its chip in bluez stack (hciattach rome). + +Signed-off-by: Isaac Hermida + +From e6d2fb7efcde66f9ab22a42bd6d7039a4f0c02cd Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Tue, 19 Aug 2014 20:23:01 +0530 +Subject: [PATCH 01/19] bluetooth : Add bluetooth support for QCA6174 chip. + +Register the QCA6174 initialization routine with hciattach for +downloading firmware patches to the bluetooth controller. +Add optional support 'f' to control installation of line +discipline driver. Invoke hciattach from command line and +download the firmware patches: + hciattach /dev/ttyHS0 qca 3000000 -t120 flow -f0 + +Change-Id: I87f2927d7096904071a02d73d3afef0dc34db414 +Signed-off-by: Rupesh Tatiya +--- + Makefile.tools | 3 +- + tools/hciattach.c | 25 +- + tools/hciattach.h | 8 +- + tools/hciattach_rome.c | 1578 ++++++++++++++++++++++++++++++++++++++++++++++++ + tools/hciattach_rome.h | 317 ++++++++++ + 5 files changed, 1926 insertions(+), 5 deletions(-) + create mode 100644 tools/hciattach_rome.c + create mode 100644 tools/hciattach_rome.h + +diff --git a/Makefile.tools b/Makefile.tools +index 0d5f1431e013..8f087c597490 100644 +--- a/Makefile.tools ++++ b/Makefile.tools +@@ -164,7 +164,8 @@ tools_hciattach_SOURCES = tools/hciattach.c tools/hciattach.h \ + tools/hciattach_ath3k.c \ + tools/hciattach_qualcomm.c \ + tools/hciattach_intel.c \ +- tools/hciattach_bcm43xx.c ++ tools/hciattach_bcm43xx.c \ ++ tools/hciattach_rome.c tools/hciattach_rome.h + tools_hciattach_LDADD = lib/libbluetooth-internal.la + + tools_hciconfig_SOURCES = tools/hciconfig.c tools/csr.h tools/csr.c +diff --git a/tools/hciattach.c b/tools/hciattach.c +index fad176c9b804..73811d4c4c2a 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -69,6 +69,8 @@ struct uart_t { + #define ENABLE_PM 1 + #define DISABLE_PM 0 + ++int line_disp = 1; ++ + static volatile sig_atomic_t __io_canceled = 0; + + static void sig_hup(int sig) +@@ -263,6 +265,12 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) + return ath3k_post(fd, u->pm); + } + ++static int qca(int fd, struct uart_t *u, struct termios *ti) ++{ ++ fprintf(stderr,"qca\n"); ++ return qca_soc_init(fd, u->bdaddr); ++} ++ + static int qualcomm(int fd, struct uart_t *u, struct termios *ti) + { + return qualcomm_init(fd, u->speed, ti, u->bdaddr); +@@ -1093,6 +1101,10 @@ struct uart_t uart[] = { + { "ath3k", 0x0000, 0x0000, HCI_UART_ATH3K, 115200, 115200, + FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm }, + ++ /* QCA ROME */ ++ { "qca", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, ++ FLOW_CTL, DISABLE_PM, NULL, qca, NULL }, ++ + /* QUALCOMM BTS */ + { "qualcomm", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, + FLOW_CTL, DISABLE_PM, NULL, qualcomm, NULL }, +@@ -1195,6 +1207,7 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw) + goto fail; + } + ++if (line_disp) { + /* Set TTY to N_HCI line discipline */ + i = N_HCI; + if (ioctl(fd, TIOCSETD, &i) < 0) { +@@ -1211,6 +1224,7 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw) + perror("Can't set device"); + goto fail; + } ++} + + if (u->post && u->post(fd, u, &ti) < 0) + goto fail; +@@ -1249,7 +1263,7 @@ int main(int argc, char *argv[]) + printpid = 0; + raw = 0; + +- while ((opt=getopt(argc, argv, "bnpt:s:lr")) != EOF) { ++ while ((opt=getopt(argc, argv, "bnpt:s:lrf:")) != EOF) { + switch(opt) { + case 'b': + send_break = 1; +@@ -1282,6 +1296,11 @@ int main(int argc, char *argv[]) + raw = 1; + break; + ++ case 'f': ++ line_disp = atoi(optarg); ++ fprintf(stderr, "Line_disp val : %d\n", line_disp); ++ break; ++ + default: + usage(); + exit(1); +@@ -1350,6 +1369,7 @@ int main(int argc, char *argv[]) + case 5: + u->bdaddr = argv[optind]; + break; ++ + } + } + +@@ -1426,12 +1446,15 @@ int main(int argc, char *argv[]) + break; + } + ++if (line_disp) { + /* Restore TTY line discipline */ ++ fprintf(stderr, "Restoring the Line Discipline driver\n"); + ld = N_TTY; + if (ioctl(n, TIOCSETD, &ld) < 0) { + perror("Can't restore line discipline"); + exit(1); + } ++} + + return 0; + } +diff --git a/tools/hciattach.h b/tools/hciattach.h +index 4279a3361749..0656a845223c 100644 +--- a/tools/hciattach.h ++++ b/tools/hciattach.h +@@ -39,9 +39,10 @@ + #define HCI_UART_H4DS 3 + #define HCI_UART_LL 4 + #define HCI_UART_ATH3K 5 +-#define HCI_UART_INTEL 6 +-#define HCI_UART_BCM 7 +-#define HCI_UART_QCA 8 ++#define HCI_UART_IBS 6 ++#define HCI_UART_INTEL 7 ++#define HCI_UART_BCM 8 ++#define HCI_UART_QCA 9 + + #define HCI_UART_RAW_DEVICE 0 + #define HCI_UART_RESET_ON_INIT 1 +@@ -63,6 +64,7 @@ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, + struct termios *ti); + int ath3k_post(int fd, int pm); + int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); ++int qca_soc_init(int fd, char *bdaddr); + int intel_init(int fd, int init_speed, int *speed, struct termios *ti); + int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti, + const char *bdaddr); +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +new file mode 100644 +index 000000000000..f31be43c09e4 +--- /dev/null ++++ b/tools/hciattach_rome.c +@@ -0,0 +1,1578 @@ ++/* ++ * ++ * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Not a Contribution. ++ * ++ * Copyright 2012 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); you ++ * may not use this file except in compliance with the License. You may ++ * obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * permissions and limitations under the License. ++ * ++ */ ++ ++/****************************************************************************** ++ * ++ * Filename: hciattach_rome.c ++ * ++ * Description: Contains controller-specific functions, like ++ * firmware patch download ++ * low power mode operations ++ * ++ ******************************************************************************/ ++ ++#define LOG_TAG "bt_vendor" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "hciattach_rome.h" ++#include "hciattach.h" ++ ++#ifdef __cplusplus ++} ++#endif ++ ++ ++/****************************************************************************** ++** Variables ++******************************************************************************/ ++FILE *file; ++unsigned char *phdr_buffer; ++unsigned char *pdata_buffer = NULL; ++patch_info rampatch_patch_info; ++int rome_ver = ROME_VER_UNKNOWN; ++unsigned char gTlv_type; ++char *rampatch_file_path; ++char *nvm_file_path; ++vnd_userial_cb_t vnd_userial; ++/****************************************************************************** ++** Extern variables ++******************************************************************************/ ++//extern unsigned char vnd_local_bd_addr[6]; ++ ++/***************************************************************************** ++** Functions ++*****************************************************************************/ ++ ++/******************************************************************************* ++** ++** Function userial_to_tcio_baud ++** ++** Description helper function converts USERIAL baud rates into TCIO ++** conforming baud rates ++** ++** Returns TRUE/FALSE ++** ++*******************************************************************************/ ++unsigned char userial_to_tcio_baud(unsigned char cfg_baud, unsigned int *baud) ++{ ++ if (cfg_baud == USERIAL_BAUD_115200) ++ *baud = B115200; ++ else if (cfg_baud == USERIAL_BAUD_4M) ++ *baud = B4000000; ++ else if (cfg_baud == USERIAL_BAUD_3M) ++ *baud = B3000000; ++ else if (cfg_baud == USERIAL_BAUD_2M) ++ *baud = B2000000; ++ else if (cfg_baud == USERIAL_BAUD_1M) ++ *baud = B1000000; ++ else if (cfg_baud == USERIAL_BAUD_921600) ++ *baud = B921600; ++ else if (cfg_baud == USERIAL_BAUD_460800) ++ *baud = B460800; ++ else if (cfg_baud == USERIAL_BAUD_230400) ++ *baud = B230400; ++ else if (cfg_baud == USERIAL_BAUD_57600) ++ *baud = B57600; ++ else if (cfg_baud == USERIAL_BAUD_19200) ++ *baud = B19200; ++ else if (cfg_baud == USERIAL_BAUD_9600) ++ *baud = B9600; ++ else if (cfg_baud == USERIAL_BAUD_1200) ++ *baud = B1200; ++ else if (cfg_baud == USERIAL_BAUD_600) ++ *baud = B600; ++ else ++ { ++ fprintf(stderr, "userial vendor open: unsupported baud idx %i\n", cfg_baud); ++ *baud = B115200; ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++ ++/******************************************************************************* ++** ++** Function userial_vendor_set_baud ++** ++** Description Set new baud rate ++** ++** Returns None ++** ++*******************************************************************************/ ++void userial_vendor_set_baud(unsigned char userial_baud) ++{ ++ unsigned int tcio_baud; ++ fprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); ++ ++ userial_to_tcio_baud(userial_baud, &tcio_baud); ++ ++ cfsetospeed(&vnd_userial.termios, tcio_baud); ++ cfsetispeed(&vnd_userial.termios, tcio_baud); ++ tcsetattr(vnd_userial.fd, TCSADRAIN, &vnd_userial.termios); /* don't change speed until last write done */ ++ ++} ++ ++ ++/******************************************************************************* ++** ++** Function userial_vendor_ioctl ++** ++** Description ioctl inteface ++** ++** Returns None ++** ++*******************************************************************************/ ++int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) ++{ ++ int err = -1; ++ struct termios ti; ++ ++ if (tcgetattr(fd, &ti) < 0) { ++ perror("Can't get port settings"); ++ return -1; ++ } ++ cfmakeraw(&ti); ++ ti.c_cflag |= CLOCAL; ++ ++ switch(op) ++ { ++#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) ++ case USERIAL_OP_ASSERT_BT_WAKE: ++ VNDUSERIALDBG("## userial_vendor_ioctl: Asserting BT_Wake ##"); ++ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL); ++ break; ++ ++ case USERIAL_OP_DEASSERT_BT_WAKE: ++ VNDUSERIALDBG("## userial_vendor_ioctl: De-asserting BT_Wake ##"); ++ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL); ++ break; ++ ++ case USERIAL_OP_GET_BT_WAKE_STATE: ++ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_GET_ST, p_data); ++ break; ++#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) ++ case USERIAL_OP_FLOW_ON: ++ fprintf(stderr, "## userial_vendor_ioctl: UART Flow On\n "); ++ ti.c_cflag |= CRTSCTS; ++ ++ if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { ++ perror("Can't set port settings"); ++ return -1; ++ } ++ ++ break; ++ ++ case USERIAL_OP_FLOW_OFF: ++ fprintf(stderr, "## userial_vendor_ioctl: UART Flow Off\n "); ++ ti.c_cflag &= ~CRTSCTS; ++ if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { ++ fprintf(stderr, "Can't set port settings"); ++ return -1; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return err; ++} ++ ++ ++int get_vs_hci_event(unsigned char *rsp) ++{ ++ int err = 0, soc_id =0; ++ unsigned char paramlen = 0; ++ ++ if( (rsp[EVENTCODE_OFFSET] == VSEVENT_CODE) || (rsp[EVENTCODE_OFFSET] == EVT_CMD_COMPLETE)) ++ fprintf(stderr, "%s: Received HCI-Vendor Specific event\n", __FUNCTION__); ++ else { ++ fprintf(stderr, "%s: Failed to receive HCI-Vendor Specific event\n", __FUNCTION__); ++ err = -EIO; ++ goto failed; ++ } ++ ++ fprintf(stderr, "%s: Parameter Length: 0x%x\n", __FUNCTION__, paramlen = rsp[EVT_PLEN]); ++ fprintf(stderr, "%s: Command response: 0x%x\n", __FUNCTION__, rsp[CMD_RSP_OFFSET]); ++ fprintf(stderr, "%s: Response type : 0x%x\n", __FUNCTION__, rsp[RSP_TYPE_OFFSET]); ++ ++ /* Check the status of the operation */ ++ switch ( rsp[CMD_RSP_OFFSET] ) ++ { ++ case EDL_CMD_REQ_RES_EVT: ++ fprintf(stderr, "%s: Command Request Response\n", __FUNCTION__); ++ switch(rsp[RSP_TYPE_OFFSET]) ++ { ++ case EDL_PATCH_VER_RES_EVT: ++ case EDL_APP_VER_RES_EVT: ++ fprintf(stderr, "\t Current Product ID\t\t: 0x%08x\n", ++ (unsigned int)(rsp[PATCH_PROD_ID_OFFSET +3] << 24 | ++ rsp[PATCH_PROD_ID_OFFSET+2] << 16 | ++ rsp[PATCH_PROD_ID_OFFSET+1] << 8 | ++ rsp[PATCH_PROD_ID_OFFSET] )); ++ ++ /* Patch Version indicates FW patch version */ ++ fprintf(stderr, "\t Current Patch Version\t\t: 0x%04x\n", ++ (unsigned short)(rsp[PATCH_PATCH_VER_OFFSET + 1] << 8 | ++ rsp[PATCH_PATCH_VER_OFFSET] )); ++ ++ /* ROM Build Version indicates ROM build version like 1.0/1.1/2.0 */ ++ fprintf(stderr, "\t Current ROM Build Version\t: 0x%04x\n", rome_ver = ++ (int)(rsp[PATCH_ROM_BUILD_VER_OFFSET + 1] << 8 | ++ rsp[PATCH_ROM_BUILD_VER_OFFSET] )); ++ ++ /* In case rome 1.0/1.1, there is no SOC ID version available */ ++ if (paramlen - 10) ++ { ++ fprintf(stderr, "\t Current SOC Version\t\t: 0x%08x\n", soc_id = ++ (unsigned int)(rsp[PATCH_SOC_VER_OFFSET +3] << 24 | ++ rsp[PATCH_SOC_VER_OFFSET+2] << 16 | ++ rsp[PATCH_SOC_VER_OFFSET+1] << 8 | ++ rsp[PATCH_SOC_VER_OFFSET] )); ++ } ++ ++ /* Rome Chipset Version can be decided by Patch version and SOC version, ++ Upper 2 bytes will be used for Patch version and Lower 2 bytes will be ++ used for SOC as combination for BT host driver */ ++ rome_ver = (rome_ver << 16) | (soc_id & 0x0000ffff); ++ break; ++ case EDL_TVL_DNLD_RES_EVT: ++ case EDL_CMD_EXE_STATUS_EVT: ++ switch (err = rsp[CMD_STATUS_OFFSET]) ++ { ++ case HCI_CMD_SUCCESS: ++ fprintf(stderr, "%s: Download Packet successfully!\n", __FUNCTION__); ++ break; ++ case PATCH_LEN_ERROR: ++ fprintf(stderr, "%s: Invalid patch length argument passed for EDL PATCH " ++ "SET REQ cmd\n", __FUNCTION__); ++ break; ++ case PATCH_VER_ERROR: ++ fprintf(stderr, "%s: Invalid patch version argument passed for EDL PATCH " ++ "SET REQ cmd\n", __FUNCTION__); ++ break; ++ case PATCH_CRC_ERROR: ++ fprintf(stderr, "%s: CRC check of patch failed!!!\n", __FUNCTION__); ++ break; ++ case PATCH_NOT_FOUND: ++ fprintf(stderr, "%s: Invalid patch data!!!\n", __FUNCTION__); ++ break; ++ case TLV_TYPE_ERROR: ++ fprintf(stderr, "%s: TLV Type Error !!!\n", __FUNCTION__); ++ break; ++ default: ++ fprintf(stderr, "%s: Undefined error (0x%x)", __FUNCTION__, err); ++ break; ++ } ++ break; ++ } ++ break; ++ ++ case NVM_ACCESS_CODE: ++ fprintf(stderr, "%s: NVM Access Code!!!\n", __FUNCTION__); ++ err = HCI_CMD_SUCCESS; ++ break; ++ case EDL_SET_BAUDRATE_RSP_EVT: ++ /* Rome 1.1 has bug with the response, so it should ignore it. */ ++ if (rsp[BAUDRATE_RSP_STATUS_OFFSET] != BAUDRATE_CHANGE_SUCCESS) ++ { ++ fprintf(stderr, "%s: Set Baudrate request failed - 0x%x\n", __FUNCTION__, ++ rsp[CMD_STATUS_OFFSET]); ++ err = -1; ++ } ++ break; ++ default: ++ fprintf(stderr, "%s: Not a valid status!!!\n", __FUNCTION__); ++ err = -1; ++ break; ++ } ++ ++failed: ++ return err; ++} ++ ++ ++/* ++ * Read an VS HCI event from the given file descriptor. ++ */ ++int read_vs_hci_event(int fd, unsigned char* buf, int size) ++{ ++ int remain, r; ++ int count = 0; ++ ++ if (size <= 0) { ++ fprintf(stderr, "Invalid size arguement!\n"); ++ return -1; ++ } ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); ++ ++ /* The first byte identifies the packet type. For HCI event packets, it ++ * should be 0x04, so we read until we get to the 0x04. */ ++ /* It will keep reading until find 0x04 byte */ ++ while (1) { ++ r = read(fd, buf, 1); ++ if (r <= 0) ++ return -1; ++ if (buf[0] == 0x04) ++ break; ++ } ++ count++; ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[0] - 0x%x\n", __FUNCTION__, buf[0]); ++ /* The next two bytes are the event code and parameter total length. */ ++ while (count < 3) { ++ r = read(fd, buf + count, 3 - count); ++ if ((r <= 0) || (buf[1] != 0xFF )) { ++ fprintf(stderr, "It is not VS event !!\n"); ++ return -1; ++ } ++ count += r; ++ } ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[1] - 0x%x\n", __FUNCTION__, buf[1]); ++ /* Now we read the parameters. */ ++ if (buf[2] < (size - 3)) ++ remain = buf[2]; ++ else ++ remain = size - 3; ++ ++ while ((count - 3) < remain) { ++ r = read(fd, buf + count, remain - (count - 3)); ++ if (r <= 0) ++ return -1; ++ count += r; ++ } ++ ++ /* Check if the set patch command is successful or not */ ++ if(get_vs_hci_event(buf) != HCI_CMD_SUCCESS) ++ return -1; ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, count - 0x%x\n", __FUNCTION__, count); ++ return count; ++} ++ ++ ++int hci_send_vs_cmd(int fd, unsigned char *cmd, unsigned char *rsp, int size) ++{ ++ int ret = 0; ++ ++ /* Send the HCI command packet to UART for transmission */ ++ ret = write(fd, cmd, size); ++ if (ret != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, ret); ++ goto failed; ++ } ++ ++ /* Check for response from the Controller */ ++ if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { ++ ret = -ETIMEDOUT; ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto failed; ++ } ++ ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++failed: ++ return ret; ++} ++ ++void frame_hci_cmd_pkt( ++ unsigned char *cmd, ++ int edl_cmd, unsigned int p_base_addr, ++ int segtNo, int size ++ ) ++{ ++ int offset = 0; ++ hci_command_hdr *cmd_hdr; ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, HCI_PATCH_CMD_OCF); ++ cmd_hdr->plen = size; ++ cmd[4] = edl_cmd; ++ ++ switch (edl_cmd) ++ { ++ case EDL_PATCH_SET_REQ_CMD: ++ /* Copy the patch header info as CMD params */ ++ memcpy(&cmd[5], phdr_buffer, PATCH_HDR_LEN); ++ fprintf(stderr, "%s: Sending EDL_PATCH_SET_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_DLD_REQ_CMD: ++ offset = ((segtNo - 1) * MAX_DATA_PER_SEGMENT); ++ p_base_addr += offset; ++ cmd_hdr->plen = (size + 6); ++ cmd[5] = (size + 4); ++ cmd[6] = EXTRACT_BYTE(p_base_addr, 0); ++ cmd[7] = EXTRACT_BYTE(p_base_addr, 1); ++ cmd[8] = EXTRACT_BYTE(p_base_addr, 2); ++ cmd[9] = EXTRACT_BYTE(p_base_addr, 3); ++ memcpy(&cmd[10], (pdata_buffer + offset), size); ++ ++ fprintf(stderr, "%s: Sending EDL_PATCH_DLD_REQ_CMD: size: %d bytes\n", ++ __FUNCTION__, size); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t" ++ "0x%x\t0x%x\t0x%x\t\n", segtNo, cmd[0], cmd[1], cmd[2], ++ cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]); ++ break; ++ case EDL_PATCH_ATCH_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_ATTACH_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_RST_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_RESET_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_VER_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_VER_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_TLV_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_TLV_REQ_CMD\n", __FUNCTION__); ++ /* Parameter Total Length */ ++ cmd[3] = size +2; ++ ++ /* TLV Segment Length */ ++ cmd[5] = size; ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]); ++ offset = (segtNo * MAX_SIZE_PER_TLV_SEGMENT); ++ memcpy(&cmd[6], (pdata_buffer + offset), size); ++ break; ++ default: ++ fprintf(stderr, "%s: Unknown EDL CMD !!!\n", __FUNCTION__); ++ } ++} ++ ++void rome_extract_patch_header_info(unsigned char *buf) ++{ ++ int index; ++ ++ /* Extract patch id */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_id |= ++ (LSH(buf[index + P_ID_OFFSET], (index * 8))); ++ ++ /* Extract (ROM and BUILD) version information */ ++ for (index = 0; index < 2; index++) ++ rampatch_patch_info.patch_ver.rom_version |= ++ (LSH(buf[index + P_ROME_VER_OFFSET], (index * 8))); ++ ++ for (index = 0; index < 2; index++) ++ rampatch_patch_info.patch_ver.build_version |= ++ (LSH(buf[index + P_BUILD_VER_OFFSET], (index * 8))); ++ ++ /* Extract patch base and entry addresses */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_base_addr |= ++ (LSH(buf[index + P_BASE_ADDR_OFFSET], (index * 8))); ++ ++ /* Patch BASE & ENTRY addresses are same */ ++ rampatch_patch_info.patch_entry_addr = rampatch_patch_info.patch_base_addr; ++ ++ /* Extract total length of the patch payload */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_length |= ++ (LSH(buf[index + P_LEN_OFFSET], (index * 8))); ++ ++ /* Extract the CRC checksum of the patch payload */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_crc |= ++ (LSH(buf[index + P_CRC_OFFSET], (index * 8))); ++ ++ /* Extract patch control value */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_ctrl |= ++ (LSH(buf[index + P_CONTROL_OFFSET], (index * 8))); ++ ++ fprintf(stderr, "PATCH_ID\t : 0x%x\n", rampatch_patch_info.patch_id); ++ fprintf(stderr, "ROM_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.rom_version); ++ fprintf(stderr, "BUILD_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.build_version); ++ fprintf(stderr, "PATCH_LENGTH\t : 0x%x\n", rampatch_patch_info.patch_length); ++ fprintf(stderr, "PATCH_CRC\t : 0x%x\n", rampatch_patch_info.patch_crc); ++ fprintf(stderr, "PATCH_CONTROL\t : 0x%x\n", rampatch_patch_info.patch_ctrl); ++ fprintf(stderr, "PATCH_BASE_ADDR\t : 0x%x\n", rampatch_patch_info.patch_base_addr); ++ ++} ++ ++int rome_edl_set_patch_request(int fd) ++{ ++ int size, err; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_SET_REQ_CMD, 0, ++ -1, PATCH_HDR_LEN + 1); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to set the patch info to the Controller!\n"); ++ goto error; ++ } ++ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: Successfully set patch info on the Controller\n", __FUNCTION__); ++error: ++ return err; ++} ++ ++int rome_edl_patch_download_request(int fd) ++{ ++ int no_of_patch_segment; ++ int index = 1, err = 0, size = 0; ++ unsigned int p_base_addr; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ no_of_patch_segment = (rampatch_patch_info.patch_length / ++ MAX_DATA_PER_SEGMENT); ++ fprintf(stderr, "%s: %d patch segments to be d'loaded from patch base addr: 0x%x\n", ++ __FUNCTION__, no_of_patch_segment, ++ rampatch_patch_info.patch_base_addr); ++ ++ /* Initialize the patch base address from the one read from bin file */ ++ p_base_addr = rampatch_patch_info.patch_base_addr; ++ ++ /* ++ * Depending upon size of the patch payload, download the patches in ++ * segments with a max. size of 239 bytes ++ */ ++ for (index = 1; index <= no_of_patch_segment; index++) { ++ ++ fprintf(stderr, "%s: Downloading patch segment: %d\n", __FUNCTION__, index); ++ ++ /* Frame the HCI CMD PKT to be sent to Controller*/ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_DLD_REQ_CMD, p_base_addr, ++ index, MAX_DATA_PER_SEGMENT); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Initialize the RSP packet everytime to 0 */ ++ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to send the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", ++ __FUNCTION__, index); ++ goto error; ++ } ++ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", ++ __FUNCTION__, index); ++ } ++ ++ /* Check if any pending patch data to be sent */ ++ size = (rampatch_patch_info.patch_length < MAX_DATA_PER_SEGMENT) ? ++ rampatch_patch_info.patch_length : ++ (rampatch_patch_info.patch_length % MAX_DATA_PER_SEGMENT); ++ ++ if (size) ++ { ++ /* Frame the HCI CMD PKT to be sent to Controller*/ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_DLD_REQ_CMD, p_base_addr, index, size); ++ ++ /* Initialize the RSP packet everytime to 0 */ ++ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to send the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", ++ __FUNCTION__, index); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", ++ __FUNCTION__, index); ++ } ++ ++error: ++ return err; ++} ++ ++static int rome_download_rampatch(int fd) ++{ ++ int c, size, index, ret = -1; ++ ++ fprintf(stderr, "%s:\n", __FUNCTION__); ++ ++ /* Get handle to the RAMPATCH binary file */ ++ fprintf(stderr, "%s: Getting handle to the RAMPATCH binary file from %s\n", __FUNCTION__, ROME_FW_PATH); ++ file = fopen(ROME_FW_PATH, "r"); ++ if (file == NULL) { ++ fprintf(stderr, "%s: Failed to get handle to the RAMPATCH bin file!\n", ++ __FUNCTION__); ++ return -ENFILE; ++ } ++ ++ /* Allocate memory for the patch headder info */ ++ fprintf(stderr, "%s: Allocating memory for the patch header\n", __FUNCTION__); ++ phdr_buffer = (unsigned char *) malloc(PATCH_HDR_LEN + 1); ++ if (phdr_buffer == NULL) { ++ fprintf(stderr, "%s: Failed to allocate memory for patch header\n", ++ __FUNCTION__); ++ goto phdr_alloc_failed; ++ } ++ for (index = 0; index < PATCH_HDR_LEN + 1; index++) ++ phdr_buffer[index] = 0x0; ++ ++ /* Read 28 bytes of patch header information */ ++ fprintf(stderr, "%s: Reading patch header info\n", __FUNCTION__); ++ index = 0; ++ do { ++ c = fgetc (file); ++ phdr_buffer[index++] = (unsigned char)c; ++ } while (index != PATCH_HDR_LEN); ++ ++ /* Save the patch header info into local structure */ ++ fprintf(stderr, "%s: Saving patch hdr. info\n", __FUNCTION__); ++ rome_extract_patch_header_info((unsigned char *)phdr_buffer); ++ ++ /* Set the patch header info onto the Controller */ ++ ret = rome_edl_set_patch_request(fd); ++ if (ret < 0) { ++ fprintf(stderr, "%s: Error setting the patchheader info!\n", __FUNCTION__); ++ goto pdata_alloc_failed; ++ } ++ ++ /* Allocate memory for the patch payload */ ++ fprintf(stderr, "%s: Allocating memory for patch payload\n", __FUNCTION__); ++ size = rampatch_patch_info.patch_length; ++ pdata_buffer = (unsigned char *) malloc(size+1); ++ if (pdata_buffer == NULL) { ++ fprintf(stderr, "%s: Failed to allocate memory for patch payload\n", ++ __FUNCTION__); ++ goto pdata_alloc_failed; ++ } ++ for (index = 0; index < size+1; index++) ++ pdata_buffer[index] = 0x0; ++ ++ /* Read the patch data from Rampatch binary image */ ++ fprintf(stderr, "%s: Reading patch payload from RAMPATCH file\n", __FUNCTION__); ++ index = 0; ++ do { ++ c = fgetc (file); ++ pdata_buffer[index++] = (unsigned char)c; ++ } while (c != EOF); ++ ++ /* Downloading patches in segments to controller */ ++ ret = rome_edl_patch_download_request(fd); ++ if (ret < 0) { ++ fprintf(stderr, "%s: Error downloading patch segments!\n", __FUNCTION__); ++ goto cleanup; ++ } ++cleanup: ++ free(pdata_buffer); ++pdata_alloc_failed: ++ free(phdr_buffer); ++phdr_alloc_failed: ++ fclose(file); ++ ++ return ret; ++} ++ ++int rome_attach_rampatch(int fd) ++{ ++ int size, err; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_ATCH_REQ_CMD, 0, ++ -1, EDL_PATCH_CMD_LEN); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to attach the patch segment(s)\n", __FUNCTION__); ++ goto error; ++ } ++error: ++ return err; ++} ++ ++int rome_rampatch_reset(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ struct timespec tm = { 0, 100*1000*1000 }; /* 100 ms */ ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_RST_REQ_CMD, 0, ++ -1, EDL_PATCH_CMD_LEN); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ ++ /* Send HCI Command packet to Controller */ ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* ++ * Controller doesn't sends any response for the patch reset ++ * command. HOST has to wait for 100ms before proceeding. ++ */ ++ nanosleep(&tm, NULL); ++ ++error: ++ return err; ++} ++ ++int rome_get_tlv_file(char *file_path) ++{ ++ FILE * pFile; ++ long fileSize; ++ int readSize, nvm_length, nvm_index, i; ++ unsigned short nvm_tag_len; ++ tlv_patch_info *ptlv_header; ++ tlv_nvm_hdr *nvm_ptr; ++ unsigned char data_buf[PRINT_BUF_SIZE]={0,}; ++ unsigned char *nvm_byte_ptr; ++ ++ fprintf(stderr, "File Open (%s)\n", file_path); ++ pFile = fopen ( file_path , "r" ); ++ if (pFile==NULL) {; ++ fprintf(stderr, "%s File Open Fail\n", file_path); ++ return -1; ++ } ++ ++ /* Get File Size */ ++ fseek (pFile , 0 , SEEK_END); ++ fileSize = ftell (pFile); ++ rewind (pFile); ++ ++ pdata_buffer = (unsigned char*) malloc (sizeof(char)*fileSize); ++ if (pdata_buffer == NULL) { ++ fprintf(stderr, "Allocated Memory failed\n"); ++ fclose (pFile); ++ return -1; ++ } ++ ++ /* Copy file into allocated buffer */ ++ readSize = fread (pdata_buffer,1,fileSize,pFile); ++ ++ /* File Close */ ++ fclose (pFile); ++ ++ if (readSize != fileSize) { ++ fprintf(stderr, "Read file size(%d) not matched with actual file size (%ld bytes)\n",readSize,fileSize); ++ return -1; ++ } ++ ++ ptlv_header = (tlv_patch_info *) pdata_buffer; ++ ++ /* To handle different event between rampatch and NVM */ ++ gTlv_type = ptlv_header->tlv_type; ++ ++ if(ptlv_header->tlv_type == TLV_TYPE_PATCH){ ++ fprintf(stderr, "====================================================\n"); ++ fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); ++ fprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | ++ (ptlv_header->tlv_length2 << 8) | ++ (ptlv_header->tlv_length3 << 16)); ++ fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv_data_len); ++ fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv_patch_data_len); ++ fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); ++ fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); ++ fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); ++ fprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); ++ fprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); ++ fprintf(stderr, "Patch Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.patch_ver); ++ fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved2); ++ fprintf(stderr, "Patch Entry Address\t\t : 0x%x\n", (ptlv_header->tlv.patch.patch_entry_addr)); ++ fprintf(stderr, "====================================================\n"); ++ ++ } else if(ptlv_header->tlv_type == TLV_TYPE_NVM) { ++ fprintf(stderr, "====================================================\n"); ++ fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); ++ fprintf(stderr, "Length\t\t\t : %d bytes\n", nvm_length = (ptlv_header->tlv_length1) | ++ (ptlv_header->tlv_length2 << 8) | ++ (ptlv_header->tlv_length3 << 16)); ++ ++ if(nvm_length <= 0) ++ return readSize; ++ ++ for(nvm_byte_ptr=(unsigned char *)(nvm_ptr = &(ptlv_header->tlv.nvm)), nvm_index=0; ++ nvm_index < nvm_length ; nvm_ptr = (tlv_nvm_hdr *) nvm_byte_ptr) ++ { ++ fprintf(stderr, "TAG ID\t\t\t : %d\n", nvm_ptr->tag_id); ++ fprintf(stderr, "TAG Length\t\t\t : %d\n", nvm_tag_len = nvm_ptr->tag_len); ++ fprintf(stderr, "TAG Pointer\t\t\t : %d\n", nvm_ptr->tag_ptr); ++ fprintf(stderr, "TAG Extended Flag\t\t : %d\n", nvm_ptr->tag_ex_flag); ++ ++ /* Increase nvm_index to NVM data */ ++ nvm_index+=sizeof(tlv_nvm_hdr); ++ nvm_byte_ptr+=sizeof(tlv_nvm_hdr); ++ ++ /* Write BD Address */ ++ if(nvm_ptr->tag_id == TAG_NUM_2){ ++ memcpy(nvm_byte_ptr, vnd_local_bd_addr, 6); ++ fprintf(stderr, "BD Address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", ++ *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), ++ *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); ++ } ++ ++ for(i =0;(itag_len && (i*3 + 2) tag_len; ++ nvm_byte_ptr +=nvm_ptr->tag_len; ++ } ++ ++ fprintf(stderr, "====================================================\n"); ++ ++ } else { ++ fprintf(stderr, "TLV Header type is unknown (%d) \n", ptlv_header->tlv_type); ++ } ++ ++ return readSize; ++} ++ ++int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc_evt) ++{ ++ int size=0, err = -1; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d\n", __FUNCTION__, index, seg_size); ++ ++ /* Frame the HCI CMD PKT to be sent to Controller*/ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_TLV_REQ_CMD, 0, index, seg_size); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Initialize the RSP packet everytime to 0 */ ++ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to send the patch payload to the Controller! 0x%x\n", err); ++ return err; ++ } ++ ++ if(wait_cc_evt) { ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", __FUNCTION__, index); ++ return err; ++ } ++ } ++ ++ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", __FUNCTION__, index); ++ return err; ++} ++ ++int rome_tlv_dnld_req(int fd, int tlv_size) ++{ ++ int total_segment, remain_size, i, err = -1; ++ unsigned char wait_cc_evt; ++ ++ total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; ++ remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\ ++ tlv_size: (tlv_size%MAX_SIZE_PER_TLV_SEGMENT); ++ ++ fprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", ++ __FUNCTION__,tlv_size, total_segment, remain_size); ++ ++ for(i=0;i= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) ++ && !remain_size && ((i+1) == total_segment))? FALSE: TRUE; ++ if((err = rome_tlv_dnld_segment(fd, i, MAX_SIZE_PER_TLV_SEGMENT, wait_cc_evt )) < 0) ++ goto error; ++ } ++ ++ /* In case remain data still remain, last rampatch segment command will not wait ++ for command complete event here */ ++ wait_cc_evt = ((rome_ver >= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) ++ && remain_size )? FALSE:TRUE; ++ ++ if(remain_size) err =rome_tlv_dnld_segment(fd, i, remain_size, wait_cc_evt); ++ ++error: ++ return err; ++} ++ ++int rome_download_tlv_file(int fd) ++{ ++ int tlv_size, err = -1; ++ ++ /* Rampatch TLV file Downloading */ ++ pdata_buffer = NULL; ++ ++ if((tlv_size = rome_get_tlv_file(rampatch_file_path)) < 0) ++ goto error; ++ ++ if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) ++ goto error; ++ ++ if (pdata_buffer != NULL){ ++ free (pdata_buffer); ++ pdata_buffer = NULL; ++ } ++ ++ /* NVM TLV file Downloading */ ++ if((tlv_size = rome_get_tlv_file(nvm_file_path)) < 0) ++ goto error; ++ ++ if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) ++ goto error; ++ ++error: ++ if (pdata_buffer != NULL) ++ free (pdata_buffer); ++ ++ return err; ++} ++ ++int rome_1_0_nvm_tag_dnld(int fd) ++{ ++ int i, size, err = 0; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++#if (NVM_VERSION >= ROME_1_0_100019) ++ unsigned char cmds[MAX_TAG_CMD][HCI_MAX_CMD_SIZE] = ++ { ++ /* Tag 2 */ /* BD Address */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 9, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 2, ++ /* Tag Len */ 6, ++ /* Tag Value */ 0x77,0x78,0x23,0x01,0x56,0x22 ++ }, ++ /* Tag 6 */ /* Bluetooth Support Features */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 6, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0xFF,0xFE,0x8B,0xFE,0xD8,0x3F,0x5B,0x8B ++ }, ++ /* Tag 17 */ /* HCI Transport Layer Setting */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 17, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0x82,0x01,0x0E,0x08,0x04,0x32,0x0A,0x00 ++ }, ++ /* Tag 35 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 58, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 35, ++ /* Tag Len */ 55, ++ /* Tag Value */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x58, 0x59, ++ 0x0E, 0x0E, 0x16, 0x16, 0x16, 0x1E, 0x26, 0x5F, 0x2F, 0x5F, ++ 0x0E, 0x0E, 0x16, 0x16, 0x16, 0x1E, 0x26, 0x5F, 0x2F, 0x5F, ++ 0x0C, 0x18, 0x14, 0x24, 0x40, 0x4C, 0x70, 0x80, 0x80, 0x80, ++ 0x0C, 0x18, 0x14, 0x24, 0x40, 0x4C, 0x70, 0x80, 0x80, 0x80, ++ 0x1B, 0x14, 0x01, 0x04, 0x48 ++ }, ++ /* Tag 36 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 15, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 36, ++ /* Tag Len */ 12, ++ /* Tag Value */ 0x0F,0x00,0x03,0x03,0x03,0x03,0x00,0x00,0x03,0x03,0x04,0x00 ++ }, ++ /* Tag 39 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 7, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 39, ++ /* Tag Len */ 4, ++ /* Tag Value */ 0x12,0x00,0x00,0x00 ++ }, ++ /* Tag 41 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 91, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 41, ++ /* Tag Len */ 88, ++ /* Tag Value */ 0x15, 0x00, 0x00, 0x00, 0xF6, 0x02, 0x00, 0x00, 0x76, 0x00, ++ 0x1E, 0x00, 0x29, 0x02, 0x1F, 0x00, 0x61, 0x00, 0x1A, 0x00, ++ 0x76, 0x00, 0x1E, 0x00, 0x7D, 0x00, 0x40, 0x00, 0x91, 0x00, ++ 0x06, 0x00, 0x92, 0x00, 0x03, 0x00, 0xA6, 0x01, 0x50, 0x00, ++ 0xAA, 0x01, 0x15, 0x00, 0xAB, 0x01, 0x0A, 0x00, 0xAC, 0x01, ++ 0x00, 0x00, 0xB0, 0x01, 0xC5, 0x00, 0xB3, 0x01, 0x03, 0x00, ++ 0xB4, 0x01, 0x13, 0x00, 0xB5, 0x01, 0x0C, 0x00, 0xC5, 0x01, ++ 0x0D, 0x00, 0xC6, 0x01, 0x10, 0x00, 0xCA, 0x01, 0x2B, 0x00, ++ 0xCB, 0x01, 0x5F, 0x00, 0xCC, 0x01, 0x48, 0x00 ++ }, ++ /* Tag 42 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 63, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 42, ++ /* Tag Len */ 60, ++ /* Tag Value */ 0xD7, 0xC0, 0x00, 0x00, 0x8F, 0x5C, 0x02, 0x00, 0x80, 0x47, ++ 0x60, 0x0C, 0x70, 0x4C, 0x00, 0x00, 0x00, 0x01, 0x1F, 0x01, ++ 0x42, 0x01, 0x69, 0x01, 0x95, 0x01, 0xC7, 0x01, 0xFE, 0x01, ++ 0x3D, 0x02, 0x83, 0x02, 0xD1, 0x02, 0x29, 0x03, 0x00, 0x0A, ++ 0x10, 0x00, 0x1F, 0x00, 0x3F, 0x00, 0x7F, 0x00, 0xFD, 0x00, ++ 0xF9, 0x01, 0xF1, 0x03, 0xDE, 0x07, 0x00, 0x00, 0x9A, 0x01 ++ }, ++ /* Tag 84 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 153, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 84, ++ /* Tag Len */ 150, ++ /* Tag Value */ 0x7C, 0x6A, 0x59, 0x47, 0x19, 0x36, 0x35, 0x25, 0x25, 0x28, ++ 0x2C, 0x2B, 0x2B, 0x28, 0x2C, 0x28, 0x29, 0x28, 0x29, 0x28, ++ 0x29, 0x29, 0x2C, 0x29, 0x2C, 0x29, 0x2C, 0x28, 0x29, 0x28, ++ 0x29, 0x28, 0x29, 0x2A, 0x00, 0x00, 0x2C, 0x2A, 0x2C, 0x18, ++ 0x98, 0x98, 0x98, 0x98, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, ++ 0x1E, 0x13, 0x1E, 0x1E, 0x1E, 0x1E, 0x13, 0x13, 0x11, 0x13, ++ 0x1E, 0x1E, 0x13, 0x12, 0x12, 0x12, 0x11, 0x12, 0x1F, 0x12, ++ 0x12, 0x12, 0x10, 0x0C, 0x18, 0x0D, 0x01, 0x01, 0x01, 0x01, ++ 0x01, 0x01, 0x01, 0x0C, 0x01, 0x01, 0x01, 0x01, 0x0D, 0x0D, ++ 0x0E, 0x0D, 0x01, 0x01, 0x0D, 0x0D, 0x0D, 0x0D, 0x0F, 0x0D, ++ 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x05, 0x10, 0x03, 0x00, ++ 0x7E, 0x7B, 0x7B, 0x72, 0x71, 0x50, 0x50, 0x50, 0x00, 0x40, ++ 0x60, 0x60, 0x30, 0x08, 0x02, 0x0F, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x08, 0x16, 0x16, 0x08, 0x08, 0x00, ++ 0x00, 0x00, 0x1E, 0x34, 0x2B, 0x1B, 0x23, 0x2B, 0x15, 0x0D ++ }, ++ /* Tag 85 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 119, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 85, ++ /* Tag Len */ 116, ++ /* Tag Value */ 0x03, 0x00, 0x38, 0x00, 0x45, 0x77, 0x00, 0xE8, 0x00, 0x59, ++ 0x01, 0xCA, 0x01, 0x3B, 0x02, 0xAC, 0x02, 0x1D, 0x03, 0x8E, ++ 0x03, 0x00, 0x89, 0x01, 0x0E, 0x02, 0x5C, 0x02, 0xD7, 0x02, ++ 0xF8, 0x08, 0x01, 0x00, 0x1F, 0x00, 0x0A, 0x02, 0x55, 0x02, ++ 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xD7, 0x00, 0x00, ++ 0x00, 0x1E, 0xDE, 0x00, 0x00, 0x00, 0x14, 0x0F, 0x0A, 0x0F, ++ 0x0A, 0x0C, 0x0C, 0x0C, 0x0C, 0x04, 0x04, 0x04, 0x0C, 0x0C, ++ 0x0C, 0x0C, 0x06, 0x06, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, ++ 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, ++ 0x06, 0x0F, 0x14, 0x05, 0x47, 0xCF, 0x77, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xAC, 0x7C, 0xFF, 0x40, 0x00, 0x00, 0x00, ++ 0x12, 0x04, 0x04, 0x01, 0x04, 0x03 ++ }, ++ {TAG_END} ++ }; ++#elif (NVM_VERSION == ROME_1_0_6002) ++ unsigned char cmds[MAX_TAG_CMD][HCI_MAX_CMD_SIZE] = ++ { ++ /* Tag 2 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 9, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 2, ++ /* Tag Len */ 6, ++ /* Tag Value */ 0x77,0x78,0x23,0x01,0x56,0x22 /* BD Address */ ++ }, ++ /* Tag 6 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 6, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0xFF,0xFE,0x8B,0xFE,0xD8,0x3F,0x5B,0x8B ++ }, ++ /* Tag 17 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 17, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0x82,0x01,0x0E,0x08,0x04,0x32,0x0A,0x00 ++ }, ++ /* Tag 36 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 15, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 36, ++ /* Tag Len */ 12, ++ /* Tag Value */ 0x0F,0x00,0x03,0x03,0x03,0x03,0x00,0x00,0x03,0x03,0x04,0x00 ++ }, ++ ++ /* Tag 39 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 7, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 39, ++ /* Tag Len */ 4, ++ /* Tag Value */ 0x12,0x00,0x00,0x00 ++ }, ++ ++ /* Tag 41 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 199, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 41, ++ /* Tag Len */ 196, ++ /* Tag Value */ 0x30,0x00,0x00,0x00,0xD5,0x00,0x0E,0x00,0xD6,0x00,0x0E,0x00, ++ 0xD7,0x00,0x16,0x00,0xD8,0x00,0x16,0x00,0xD9,0x00,0x16,0x00, ++ 0xDA,0x00,0x1E,0x00,0xDB,0x00,0x26,0x00,0xDC,0x00,0x5F,0x00, ++ 0xDD,0x00,0x2F,0x00,0xDE,0x00,0x5F,0x00,0xE0,0x00,0x0E,0x00, ++ 0xE1,0x00,0x0E,0x00,0xE2,0x00,0x16,0x00,0xE3,0x00,0x16,0x00, ++ 0xE4,0x00,0x16,0x00,0xE5,0x00,0x1E,0x00,0xE6,0x00,0x26,0x00, ++ 0xE7,0x00,0x5F,0x00,0xE8,0x00,0x2F,0x00,0xE9,0x00,0x5F,0x00, ++ 0xEC,0x00,0x0C,0x00,0xED,0x00,0x08,0x00,0xEE,0x00,0x14,0x00, ++ 0xEF,0x00,0x24,0x00,0xF0,0x00,0x40,0x00,0xF1,0x00,0x4C,0x00, ++ 0xF2,0x00,0x70,0x00,0xF3,0x00,0x80,0x00,0xF4,0x00,0x80,0x00, ++ 0xF5,0x00,0x80,0x00,0xF8,0x00,0x0C,0x00,0xF9,0x00,0x18,0x00, ++ 0xFA,0x00,0x14,0x00,0xFB,0x00,0x24,0x00,0xFC,0x00,0x40,0x00, ++ 0xFD,0x00,0x4C,0x00,0xFE,0x00,0x70,0x00,0xFF,0x00,0x80,0x00, ++ 0x00,0x01,0x80,0x00,0x01,0x01,0x80,0x00,0x04,0x01,0x1B,0x00, ++ 0x05,0x01,0x14,0x00,0x06,0x01,0x01,0x00,0x07,0x01,0x04,0x00, ++ 0x08,0x01,0x00,0x00,0x09,0x01,0x00,0x00,0x0A,0x01,0x03,0x00, ++ 0x0B,0x01,0x03,0x00 ++ }, ++ ++ /* Tag 44 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 44, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 44, ++ /* Tag Len */ 41, ++ /* Tag Value */ 0x6F,0x0A,0x00,0x00,0x00,0x00,0x00,0x50,0xFF,0x10,0x02,0x02, ++ 0x01,0x00,0x14,0x01,0x06,0x28,0xA0,0x62,0x03,0x64,0x01,0x01, ++ 0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0xFF,0x10,0x02,0x01, ++ 0x00,0x14,0x01,0x02,0x03 ++ }, ++ {TAG_END} ++ }; ++#endif ++ ++ fprintf(stderr, "%s: Start sending NVM Tags (ver: 0x%x)\n", __FUNCTION__, (unsigned int) NVM_VERSION); ++ ++ for (i=0; (i < MAX_TAG_CMD) && (cmds[i][0] != TAG_END); i++) ++ { ++ /* Write BD Address */ ++ if(cmds[i][TAG_NUM_OFFSET] == TAG_NUM_2){ ++ memcpy(&cmds[i][TAG_BDADDR_OFFSET], vnd_local_bd_addr, 6); ++ fprintf(stderr, "BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", ++ cmds[i][TAG_BDADDR_OFFSET ], cmds[i][TAG_BDADDR_OFFSET + 1], ++ cmds[i][TAG_BDADDR_OFFSET + 2], cmds[i][TAG_BDADDR_OFFSET + 3], ++ cmds[i][TAG_BDADDR_OFFSET + 4], cmds[i][TAG_BDADDR_OFFSET + 5]); ++ } ++ size = cmds[i][3] + HCI_COMMAND_HDR_SIZE + 1; ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)&cmds[i][0], rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event - This is extra routine for ROME 1.0. From ROM 2.0, it should be removed. */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to get patch version(s)\n", __FUNCTION__); ++ goto error; ++ } ++ } ++ ++error: ++ return err; ++} ++ ++ ++ ++int rome_patch_ver_req(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_VER_REQ_CMD, 0, ++ -1, EDL_PATCH_CMD_LEN); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event - This is extra routine for ROME 1.0. From ROM 2.0, it should be removed. */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to get patch version(s)\n", __FUNCTION__); ++ goto error; ++ } ++error: ++ return err; ++ ++} ++ ++int rome_disable_sleep(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ hci_command_hdr *cmd_hdr; ++ int flags; ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, NVM_ACCESS_CODE); ++ cmd_hdr->plen = VSC_DISABLE_IBS_LEN; ++ cmd[4] = 0x01; ++ cmd[5] = 0x1B; ++ cmd[6] = 0x01; ++ cmd[7] = 0x00; ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_DISABLE_IBS_LEN); ++ /* Send the HCI command packet to UART for transmission */ ++ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]) ; ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* Check for response from the Controller */ ++ if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++ ++ /* Wait for command complete event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s\n", __FUNCTION__); ++error: ++ return err; ++ ++} ++ ++int rome_set_baudrate_req(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ hci_command_hdr *cmd_hdr; ++ int flags; ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); ++ cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; ++ cmd[4] = BAUDRATE_115200; ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); ++ /* Send the HCI command packet to UART for transmission */ ++ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* Check for response from the Controller */ ++ if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++ ++ /* Wait for command complete event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s\n", __FUNCTION__); ++error: ++ return err; ++ ++} ++ ++ ++int rome_hci_reset_req(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ hci_command_hdr *cmd_hdr; ++ int flags; ++ ++ fprintf(stderr, "%s: HCI RESET \n", __FUNCTION__); ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = HCI_RESET; ++ cmd_hdr->plen = 0; ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); ++ ++ /* Send the HCI command packet to UART for transmission */ ++ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* Wait for command complete event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ ++error: ++ return err; ++ ++} ++ ++ ++int qca_soc_init(int fd, char *bdaddr) ++{ ++ int err = -1; ++ int size; ++ ++ fprintf(stderr, " %s \n", __FUNCTION__); ++ vnd_userial.fd = fd; ++ /* Get Rome version information */ ++ if((err = rome_patch_ver_req(fd)) <0){ ++ fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Rome Version (0x%08x)\n", __FUNCTION__, rome_ver); ++ ++ switch (rome_ver){ ++ case ROME_VER_1_0: ++ { ++ /* Set and Download the RAMPATCH */ ++ fprintf(stderr, "%s: Setting Patch Header & Downloading Patches\n", __FUNCTION__); ++ err = rome_download_rampatch(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: DOWNLOAD RAMPATCH failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: DOWNLOAD RAMPTACH complete\n", __FUNCTION__); ++ ++ /* Attach the RAMPATCH */ ++ fprintf(stderr, "%s: Attaching the patches\n", __FUNCTION__); ++ err = rome_attach_rampatch(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: ATTACH RAMPATCH failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: ATTACH RAMPTACH complete\n", __FUNCTION__); ++ ++ /* Send Reset */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ err = rome_rampatch_reset(fd); ++ if ( err < 0 ) { ++ fprintf(stderr, "Failed to RESET after RAMPATCH upgrade!\n"); ++ goto error; ++ } ++ ++ /* NVM download */ ++ fprintf(stderr, "%s: Downloading NVM\n", __FUNCTION__); ++ err = rome_1_0_nvm_tag_dnld(fd); ++ if ( err <0 ) { ++ fprintf(stderr, "Downloading NVM Failed !!\n"); ++ goto error; ++ } ++ ++ /* Change baud rate 115.2 kbps to 3Mbps*/ ++ err = rome_hci_reset_req(fd); ++ if ( err <0 ) { ++ fprintf(stderr, "HCI Reset Failed !!\n"); ++ goto error; ++ } ++ ++ fprintf(stderr, "HCI Reset is done\n"); ++ } ++ break; ++ case ROME_VER_1_1: ++ rampatch_file_path = ROME_RAMPATCH_TLV_PATH; ++ nvm_file_path = ROME_NVM_TLV_PATH; ++ goto download; ++ case ROME_VER_1_3: ++ rampatch_file_path = ROME_RAMPATCH_TLV_1_0_3_PATH; ++ nvm_file_path = ROME_NVM_TLV_1_0_3_PATH; ++ goto download; ++ case ROME_VER_2_1: ++ rampatch_file_path = ROME_RAMPATCH_TLV_2_0_1_PATH; ++ nvm_file_path = ROME_NVM_TLV_2_0_1_PATH; ++ goto download; ++ case ROME_VER_3_0: ++ case TUFELLO_VER_1_0: ++ rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; ++ nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; ++ ++download: ++ /* Donwload TLV files (rampatch, NVM) */ ++ err = rome_download_tlv_file(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); ++ ++ /* Change baud rate back to user requested */ ++ fprintf(stderr, "Changing baud rate back from 3M --> 115K\n"); ++ err = rome_set_baudrate_req(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); ++ ++ fprintf(stderr, "%s: Disabling In Band Sleep functionality\n", __FUNCTION__); ++ err = rome_disable_sleep(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: Failed to disable IBS!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: IBS disabled successfully \n", __FUNCTION__); ++ ++ /* Perform HCI reset here*/ ++ err = rome_hci_reset_req(fd); ++ if ( err <0 ) { ++ fprintf(stderr, "HCI Reset Failed !!!\n"); ++ goto error; ++ } ++ fprintf(stderr, "HCI Reset is done\n"); ++ ++ break; ++ case ROME_VER_UNKNOWN: ++ default: ++ fprintf(stderr, "%s: Detected unknown ROME version\n", __FUNCTION__); ++ err = -1; ++ break; ++ } ++ ++error: ++ return err; ++} +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +new file mode 100644 +index 000000000000..aa59965643ec +--- /dev/null ++++ b/tools/hciattach_rome.h +@@ -0,0 +1,317 @@ ++/* ++ * Copyright 2012 The Android Open Source Project ++ * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Not a Contribution. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++#ifndef HW_ROME_H ++#define HW_ROME_H ++ ++/****************************************************************************** ++** Constants & Macros ++******************************************************************************/ ++#define HCI_MAX_CMD_SIZE 260 ++#define HCI_MAX_EVENT_SIZE 260 ++#define PRINT_BUF_SIZE ((HCI_MAX_CMD_SIZE * 3) + 2) ++/* HCI Command/Event Opcode */ ++#define HCI_RESET 0x0C03 ++#define EVT_CMD_COMPLETE 0x0E ++/* HCI Packet types */ ++#define HCI_COMMAND_PKT 0x01 ++#define HCI_ACLDATA_PKT 0x02 ++#define HCI_SCODATA_PKT 0x03 ++#define HCI_EVENT_PKT 0x04 ++#define HCI_VENDOR_PKT 0xff ++#define cmd_opcode_pack(ogf, ocf) (unsigned short)((ocf & 0x03ff)|(ogf << 10)) ++unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++typedef enum { ++ USERIAL_OP_FLOW_ON, ++ USERIAL_OP_FLOW_OFF, ++ USERIAL_OP_NOP, ++} userial_vendor_ioctl_op_t; ++ ++ ++/* vendor serial control block */ ++typedef struct ++{ ++ int fd; /* fd to Bluetooth device */ ++ struct termios termios; /* serial terminal of BT port */ ++ char port_name[256]; ++} vnd_userial_cb_t; ++ ++/**** baud rates ****/ ++#define USERIAL_BAUD_300 0 ++#define USERIAL_BAUD_600 1 ++#define USERIAL_BAUD_1200 2 ++#define USERIAL_BAUD_2400 3 ++#define USERIAL_BAUD_9600 4 ++#define USERIAL_BAUD_19200 5 ++#define USERIAL_BAUD_57600 6 ++#define USERIAL_BAUD_115200 7 ++#define USERIAL_BAUD_230400 8 ++#define USERIAL_BAUD_460800 9 ++#define USERIAL_BAUD_921600 10 ++#define USERIAL_BAUD_1M 11 ++#define USERIAL_BAUD_1_5M 12 ++#define USERIAL_BAUD_2M 13 ++#define USERIAL_BAUD_3M 14 ++#define USERIAL_BAUD_4M 15 ++#define USERIAL_BAUD_AUTO 16 ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE (!FALSE) ++#endif ++ ++#define HCI_CHG_BAUD_CMD_OCF 0x0C ++#define HCI_VENDOR_CMD_OGF 0x3F ++#define WRITE_BDADDR_CMD_LEN 14 ++#define WRITE_BAUD_CMD_LEN 6 ++#define MAX_CMD_LEN WRITE_BDADDR_CMD_LEN ++#define GET_VERSION_OCF 0x1E ++ ++#define PS_HDR_LEN 4 ++#define HCI_VENDOR_CMD_OGF 0x3F ++#define HCI_PS_CMD_OCF 0x0B ++ ++#define HCI_COMMAND_HDR_SIZE 3 ++#define EVT_CMD_COMPLETE_SIZE 3 ++#define EVT_CMD_STATUS 0x0F ++#define EVT_CMD_STATUS_SIZE 4 ++#define HCI_EVENT_HDR_SIZE 2 ++#define HCI_EV_SUCCESS 0x00 ++/* HCI Socket options */ ++#define HCI_DATA_DIR 1 ++#define HCI_FILTER 2 ++#define HCI_TIME_STAMP 3 ++ ++#define P_ID_OFFSET (0) ++#define HCI_CMD_IND (1) ++#define EVENTCODE_OFFSET (1) ++#define EVT_PLEN (2) ++#define PLEN (3) ++#define CMD_RSP_OFFSET (3) ++#define RSP_TYPE_OFFSET (4) ++#define BAUDRATE_RSP_STATUS_OFFSET (4) ++#define CMD_STATUS_OFFSET (5) ++#define P_ROME_VER_OFFSET (4) ++#define P_BUILD_VER_OFFSET (6) ++#define P_BASE_ADDR_OFFSET (8) ++#define P_ENTRY_ADDR_OFFSET (12) ++#define P_LEN_OFFSET (16) ++#define P_CRC_OFFSET (20) ++#define P_CONTROL_OFFSET (24) ++#define PATCH_HDR_LEN (28) ++#define MAX_DATA_PER_SEGMENT (239) ++#define VSEVENT_CODE (0xFF) ++#define HC_VS_MAX_CMD_EVENT (0xFF) ++#define PATCH_PROD_ID_OFFSET (5) ++#define PATCH_PATCH_VER_OFFSET (9) ++#define PATCH_ROM_BUILD_VER_OFFSET (11) ++#define PATCH_SOC_VER_OFFSET (13) ++#define MAX_SIZE_PER_TLV_SEGMENT (243) ++ ++/* VS Opcode */ ++#define HCI_PATCH_CMD_OCF (0) ++#define EDL_SET_BAUDRATE_CMD_OCF (0x48) ++ ++/* VS Commands */ ++#define VSC_SET_BAUDRATE_REQ_LEN (1) ++#define EDL_PATCH_CMD_LEN (1) ++#define EDL_PATCH_CMD_REQ_LEN (1) ++#define EDL_PATCH_DLD_REQ_CMD (0x01) ++#define EDL_PATCH_RST_REQ_CMD (0x05) ++#define EDL_PATCH_SET_REQ_CMD (0x16) ++#define EDL_PATCH_ATCH_REQ_CMD (0x17) ++#define EDL_PATCH_VER_REQ_CMD (0x19) ++#define EDL_PATCH_TLV_REQ_CMD (0x1E) ++#define VSC_DISABLE_IBS_LEN (0x04) ++ ++/* VS Event */ ++#define EDL_CMD_REQ_RES_EVT (0x00) ++#define EDL_CMD_EXE_STATUS_EVT (0x00) ++#define EDL_SET_BAUDRATE_RSP_EVT (0x92) ++#define EDL_PATCH_VER_RES_EVT (0x19) ++#define EDL_TVL_DNLD_RES_EVT (0x04) ++#define EDL_APP_VER_RES_EVT (0x02) ++ ++ ++/* Status Codes of HCI CMD execution*/ ++#define HCI_CMD_SUCCESS (0x0) ++#define PATCH_LEN_ERROR (0x1) ++#define PATCH_VER_ERROR (0x2) ++#define PATCH_CRC_ERROR (0x3) ++#define PATCH_NOT_FOUND (0x4) ++#define TLV_TYPE_ERROR (0x10) ++#define NVM_ACCESS_CODE (0x0B) ++#define BAUDRATE_CHANGE_SUCCESS (1) ++ ++/* TLV_TYPE */ ++#define TLV_TYPE_PATCH (1) ++#define TLV_TYPE_NVM (2) ++ ++/* NVM */ ++#define MAX_TAG_CMD 30 ++#define TAG_END 0xFF ++#define NVM_ACCESS_SET 0x01 ++#define TAG_NUM_OFFSET 5 ++#define TAG_NUM_2 2 ++#define TAG_BDADDR_OFFSET 7 ++ ++/* NVM Tags specifically used for ROME 1.0 */ ++#define ROME_1_0_100022_1 0x101000221 ++#define ROME_1_0_100019 0x101000190 ++#define ROME_1_0_6002 0x100600200 ++ ++/* Default NVM Version setting for ROME 1.0 */ ++#define NVM_VERSION ROME_1_0_100022_1 ++ ++ ++#define LSH(val, n) ((unsigned int)(val) << (n)) ++#define EXTRACT_BYTE(val, pos) (char) (((val) >> (8 * (pos))) & 0xFF) ++#define CALC_SEG_SIZE(len, max) ((plen) % (max))?((plen/max)+1) : ((plen) / (max)) ++ ++#define ROME_FW_PATH "/lib/firmware/rampatch.img" ++#define ROME_RAMPATCH_TLV_PATH "/lib/firmware/rampatch_tlv.img" ++#define ROME_NVM_TLV_PATH "/lib/firmware/nvm_tlv.bin" ++#define ROME_RAMPATCH_TLV_1_0_3_PATH "/lib/firmware/rampatch_tlv_1.3.tlv" ++#define ROME_NVM_TLV_1_0_3_PATH "/lib/firmware/nvm_tlv_1.3.bin" ++#define ROME_RAMPATCH_TLV_2_0_1_PATH "/lib/firmware/rampatch_tlv_2.1.tlv" ++#define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" ++#define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" ++#define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" ++ ++ ++/****************************************************************************** ++** Local type definitions ++******************************************************************************/ ++ ++typedef struct { ++ unsigned char ncmd; ++ unsigned short opcode; ++} __attribute__ ((packed)) evt_cmd_complete; ++ ++typedef struct { ++ unsigned char status; ++ unsigned char ncmd; ++ unsigned short opcode; ++} __attribute__ ((packed)) evt_cmd_status; ++ ++typedef struct { ++ unsigned short opcode; ++ unsigned char plen; ++} __attribute__ ((packed)) hci_command_hdr; ++ ++typedef struct { ++ unsigned char evt; ++ unsigned char plen; ++} __attribute__ ((packed)) hci_event_hdr; ++typedef struct { ++ unsigned short rom_version; ++ unsigned short build_version; ++} __attribute__ ((packed)) patch_version; ++ ++typedef struct { ++ unsigned int patch_id; ++ patch_version patch_ver; ++ unsigned int patch_base_addr; ++ unsigned int patch_entry_addr; ++ unsigned short patch_length; ++ int patch_crc; ++ unsigned short patch_ctrl; ++} __attribute__ ((packed)) patch_info; ++ ++typedef struct { ++ unsigned char sign_ver; ++ unsigned char sign_algorithm; ++ unsigned short reserved1; ++ unsigned short prod_id; ++ unsigned short build_ver; ++ unsigned short patch_ver; ++ unsigned short reserved2; ++ unsigned int patch_entry_addr; ++} __attribute__ ((packed)) tlv_patch_hdr; ++ ++typedef struct { ++ unsigned short tag_id; ++ unsigned short tag_len; ++ unsigned int tag_ptr; ++ unsigned int tag_ex_flag; ++} __attribute__ ((packed)) tlv_nvm_hdr; ++ ++typedef struct { ++ unsigned char tlv_type; ++ unsigned char tlv_length1; ++ unsigned char tlv_length2; ++ unsigned char tlv_length3; ++ unsigned int tlv_data_len; ++ unsigned int tlv_patch_data_len; ++ ++ union{ ++ tlv_patch_hdr patch; ++ tlv_nvm_hdr nvm; ++ }tlv; ++} __attribute__ ((packed)) tlv_patch_info; ++ ++enum{ ++ BAUDRATE_115200 = 0x00, ++ BAUDRATE_57600 = 0x01, ++ BAUDRATE_38400 = 0x02, ++ BAUDRATE_19200 = 0x03, ++ BAUDRATE_9600 = 0x04, ++ BAUDRATE_230400 = 0x05, ++ BAUDRATE_250000 = 0x06, ++ BAUDRATE_460800 = 0x07, ++ BAUDRATE_500000 = 0x08, ++ BAUDRATE_720000 = 0x09, ++ BAUDRATE_921600 = 0x0A, ++ BAUDRATE_1000000 = 0x0B, ++ BAUDRATE_1250000 = 0x0C, ++ BAUDRATE_2000000 = 0x0D, ++ BAUDRATE_3000000 = 0x0E, ++ BAUDRATE_4000000 = 0x0F, ++ BAUDRATE_1600000 = 0x10, ++ BAUDRATE_3200000 = 0x11, ++ BAUDRATE_3500000 = 0x12, ++ BAUDRATE_AUTO = 0xFE, ++ BAUDRATE_Reserved = 0xFF ++}; ++ ++enum{ ++ ROME_PATCH_VER_0100 = 0x0100, ++ ROME_PATCH_VER_0101 = 0x0101, ++ ROME_PATCH_VER_0200 = 0x0200, ++ ROME_PATCH_VER_0300 = 0x0300 ++ }; ++ ++enum{ ++ ROME_SOC_ID_00 = 0x00000000, ++ ROME_SOC_ID_11 = 0x00000011, ++ ROME_SOC_ID_13 = 0x00000013, ++ ROME_SOC_ID_22 = 0x00000022, ++}; ++ ++enum{ ++ ROME_VER_UNKNOWN = 0, ++ ROME_VER_1_0 = ((ROME_PATCH_VER_0100 << 16 ) | ROME_SOC_ID_00 ), ++ ROME_VER_1_1 = ((ROME_PATCH_VER_0101 << 16 ) | ROME_SOC_ID_00 ), ++ ROME_VER_1_3 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_00 ), ++ ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), ++ ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), ++ TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) ++}; ++#endif /* HW_ROME_H */ + +From 333676e63694e137558e7a685d2fa1a50c499436 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Thu, 11 Sep 2014 19:20:02 +0530 +Subject: [PATCH 02/19] bluetooth: Enable bluetooth low power mode + functionality + +During periods of inactivity the bluetooth controller and the +application processor will indicate each other to enter into +low power mode and signal each other when they have data to be +exchanged, thereby saving considerable amount of power. + +Change-Id: I9e0d579ac8a9d61a2ebde78b031f4101cb6bc443 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index 73811d4c4c2a..e3a915061440 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -1102,7 +1102,7 @@ struct uart_t uart[] = { + FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm }, + + /* QCA ROME */ +- { "qca", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, ++ { "qca", 0x0000, 0x0000, HCI_UART_IBS, 115200, 115200, + FLOW_CTL, DISABLE_PM, NULL, qca, NULL }, + + /* QUALCOMM BTS */ + +From 0518592a10bff2ac0b99e4081bd01154f2eeacb6 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Thu, 11 Sep 2014 18:57:45 +0530 +Subject: [PATCH 03/19] bluetooth: Fix bug in firmware parsing mechanism + +Reorganize the RAMPATCH members to be present as part of the +RAMPATCH header structre instead of the main firmware structure + +Change-Id: If523e1bb20edcd52b7c6f623c07af492e6305bd0 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 4 ++-- + tools/hciattach_rome.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index f31be43c09e4..122a0f4b89bc 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -851,8 +851,8 @@ int rome_get_tlv_file(char *file_path) + fprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | + (ptlv_header->tlv_length2 << 8) | + (ptlv_header->tlv_length3 << 16)); +- fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv_data_len); +- fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv_patch_data_len); ++ fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv.patch.tlv_data_len); ++ fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); + fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); + fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); + fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index aa59965643ec..07127f30a70a 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -236,6 +236,8 @@ typedef struct { + } __attribute__ ((packed)) patch_info; + + typedef struct { ++ unsigned int tlv_data_len; ++ unsigned int tlv_patch_data_len; + unsigned char sign_ver; + unsigned char sign_algorithm; + unsigned short reserved1; +@@ -258,8 +260,6 @@ typedef struct { + unsigned char tlv_length1; + unsigned char tlv_length2; + unsigned char tlv_length3; +- unsigned int tlv_data_len; +- unsigned int tlv_patch_data_len; + + union{ + tlv_patch_hdr patch; + +From 78f1ab9c20956f4e6f009d7bc2b94fe1d4474a08 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Sep 2014 15:11:02 +0530 +Subject: [PATCH 04/19] bluetooth: Configure BD Address + +Read the BD Address programmed by user from persist location. +If there is no user programmed BD address then use the default +BD address present in the firmware file. + +Change-Id: Id702d1476bae765dfd23f88542bfd5a8a1f26056 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--- + tools/hciattach_rome.h | 7 +++++++ + 2 files changed, 60 insertions(+), 3 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 122a0f4b89bc..947e1abb96c4 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -809,6 +809,7 @@ int rome_get_tlv_file(char *file_path) + tlv_nvm_hdr *nvm_ptr; + unsigned char data_buf[PRINT_BUF_SIZE]={0,}; + unsigned char *nvm_byte_ptr; ++ unsigned char bdaddr[6]; + + fprintf(stderr, "File Open (%s)\n", file_path); + pFile = fopen ( file_path , "r" ); +@@ -886,9 +887,10 @@ int rome_get_tlv_file(char *file_path) + nvm_byte_ptr+=sizeof(tlv_nvm_hdr); + + /* Write BD Address */ +- if(nvm_ptr->tag_id == TAG_NUM_2){ +- memcpy(nvm_byte_ptr, vnd_local_bd_addr, 6); +- fprintf(stderr, "BD Address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", ++ if(nvm_ptr->tag_id == TAG_NUM_2 && read_bd_address(&bdaddr) == 0) { ++ memcpy(nvm_byte_ptr, bdaddr, 6); ++ fprintf(stderr, "Overriding default BD ADDR with user" ++ " programmed BD Address: %02x:%02x:%02x:%02x:%02x:%02x\n", + *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), + *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); + } +@@ -1451,6 +1453,54 @@ error: + + } + ++int read_bd_address(unsigned char *bdaddr) ++{ ++ int fd = -1; ++ int readPtr = 0; ++ unsigned char data[BD_ADDR_LEN]; ++ ++ /* Open the persist file for reading device address*/ ++ fd = open("/etc/bluetooth/.bt_nv.bin", O_RDONLY); ++ if(fd < 0) ++ { ++ fprintf(stderr, "%s: Open failed: Programming default BD ADDR\n", __func__); ++ return -1; ++ } ++ ++ /* Read the NVM Header : fp will be advanced by readPtr number of bytes */ ++ readPtr = read(fd, data, PERSIST_HEADER_LEN); ++ if (readPtr > 0) ++ fprintf(stderr, "%s: Persist header data: %02x \t %02x \t %02x\n", __func__, ++ data[NVITEM], data[RDWR_PROT], data[NVITEM_SIZE]); ++ else { ++ fprintf(stderr, "%s: Read from persist memory failed : Programming default" ++ " BD ADDR\n"); ++ close(fd); ++ return -1; ++ } ++ ++ /* Check for BD ADDR length before programming */ ++ if(data[NVITEM_SIZE] != BD_ADDR_LEN) { ++ fprintf(stderr, "Invalid BD ADDR: Programming default BD ADDR!\n"); ++ close(fd); ++ return -1; ++ } ++ ++ /* Read the BD ADDR info */ ++ readPtr = read(fd, data, BD_ADDR_LEN); ++ if (readPtr > 0) ++ fprintf(stderr, "BD-ADDR: ==> %02x:%02x:%02x:%02x:%02x:%02x\n", data[0], ++ data[1], data[2], data[3], data[4], data[5]); ++ else { ++ fprintf(stderr, "%s: Read from persist memory failed : Programming default" ++ " BD ADDR\n"); ++ close(fd); ++ return -1; ++ } ++ memcpy(bdaddr, data, BD_ADDR_LEN); ++ close(fd); ++ return 0; ++} + + int qca_soc_init(int fd, char *bdaddr) + { +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 07127f30a70a..a4abe9f73080 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -34,6 +34,13 @@ + #define HCI_EVENT_PKT 0x04 + #define HCI_VENDOR_PKT 0xff + #define cmd_opcode_pack(ogf, ocf) (unsigned short)((ocf & 0x03ff)|(ogf << 10)) ++ ++#define NVITEM 0 ++#define RDWR_PROT 1 ++#define NVITEM_SIZE 2 ++#define PERSIST_HEADER_LEN 3 ++#define BD_ADDR_LEN 6 ++ + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + USERIAL_OP_FLOW_ON, + +From 7f148243e9d36427734de874f291911e1f3d60d0 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Sep 2014 14:33:24 +0530 +Subject: [PATCH 05/19] bluetooth: Remove unused functions in the firmware + download process + +rome_disable_sleep() function is not used anywhere in the code and +hence remove it. + +Change-Id: Iec1f9b1478850af3023ff297493693283a5338d7 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 48 ------------------------------------------------ + 1 file changed, 48 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 947e1abb96c4..4fcbdf2ab82a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1317,54 +1317,6 @@ error: + + } + +-int rome_disable_sleep(int fd) +-{ +- int size, err = 0; +- unsigned char cmd[HCI_MAX_CMD_SIZE]; +- unsigned char rsp[HCI_MAX_EVENT_SIZE]; +- hci_command_hdr *cmd_hdr; +- int flags; +- +- memset(cmd, 0x0, HCI_MAX_CMD_SIZE); +- +- cmd_hdr = (void *) (cmd + 1); +- cmd[0] = HCI_COMMAND_PKT; +- cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, NVM_ACCESS_CODE); +- cmd_hdr->plen = VSC_DISABLE_IBS_LEN; +- cmd[4] = 0x01; +- cmd[5] = 0x1B; +- cmd[6] = 0x01; +- cmd[7] = 0x00; +- +- /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_DISABLE_IBS_LEN); +- /* Send the HCI command packet to UART for transmission */ +- fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]) ; +- err = write(fd, cmd, size); +- if (err != size) { +- fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); +- goto error; +- } +- +- /* Check for response from the Controller */ +- if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { +- fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +- goto error; +- } +- +- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); +- +- /* Wait for command complete event */ +- err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); +- if ( err < 0) { +- fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); +- goto error; +- } +- fprintf(stderr, "%s\n", __FUNCTION__); +-error: +- return err; +- +-} + + int rome_set_baudrate_req(int fd) + { + +From 175fe3690522afc91f38933f821e4b00bd1a12c8 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Sep 2014 14:31:18 +0530 +Subject: [PATCH 06/19] bluetooth: Enable 3Mbps baud rate support + +Allow APPS PROC and BT Controller to operate at 3Mbps baud rate +for faster exchange of commands, events and data between the two + +Change-Id: I55651633027ea60a762b11abea84fe1abd6574a9 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 63 ++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 48 insertions(+), 15 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 4fcbdf2ab82a..d0e2935b9997 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -166,6 +166,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) + } + cfmakeraw(&ti); + ti.c_cflag |= CLOCAL; ++ ti.c_cflag |= CREAD; + + switch(op) + { +@@ -332,6 +333,8 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + { + int remain, r; + int count = 0; ++ fd_set infids; ++ struct timeval timeout; + + if (size <= 0) { + fprintf(stderr, "Invalid size arguement!\n"); +@@ -340,6 +343,16 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + + fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); + ++ FD_ZERO (&infids); ++ FD_SET (fd, &infids); ++ timeout.tv_sec = 3; ++ timeout.tv_usec = 0; /* half second is a long time at 115.2 Kbps */ ++ ++ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) ++ fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); ++ else ++ fprintf(stderr, "%s: Data available in TTY Serial buffer\n", __FUNCTION__); ++ + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + /* It will keep reading until find 0x04 byte */ +@@ -1332,10 +1345,16 @@ int rome_set_baudrate_req(int fd) + cmd[0] = HCI_COMMAND_PKT; + cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); + cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; +- cmd[4] = BAUDRATE_115200; ++ cmd[4] = BAUDRATE_3000000; + + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); ++ /* Flow off during baudrate change */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); ++ goto error; ++ } + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; + err = write(fd, cmd, size); +@@ -1343,7 +1362,15 @@ int rome_set_baudrate_req(int fd) + fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); + goto error; + } ++ /* Change Local UART baudrate to high speed UART */ ++ userial_vendor_set_baud(USERIAL_BAUD_3M); + ++ /* Flow on after changing local uart baudrate */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); ++ return err; ++ } + /* Check for response from the Controller */ + if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { + fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +@@ -1385,6 +1412,12 @@ int rome_hci_reset_req(int fd) + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); + ++ /* Flow off during baudrate change */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); ++ goto error; ++ } + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); + err = write(fd, cmd, size); +@@ -1393,6 +1426,15 @@ int rome_hci_reset_req(int fd) + goto error; + } + ++ /* Change Local UART baudrate to high speed UART */ ++ userial_vendor_set_baud(USERIAL_BAUD_3M); ++ ++ /* Flow on after changing local uart baudrate */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); ++ return err; ++ } + /* Wait for command complete event */ + err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); + if ( err < 0) { +@@ -1534,16 +1576,7 @@ int qca_soc_init(int fd, char *bdaddr) + nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; + + download: +- /* Donwload TLV files (rampatch, NVM) */ +- err = rome_download_tlv_file(fd); +- if (err < 0) { +- fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); +- goto error; +- } +- fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); +- +- /* Change baud rate back to user requested */ +- fprintf(stderr, "Changing baud rate back from 3M --> 115K\n"); ++ /* Change baud rate 115.2 kbps to 3Mbps*/ + err = rome_set_baudrate_req(fd); + if (err < 0) { + fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); +@@ -1551,13 +1584,13 @@ download: + } + fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); + +- fprintf(stderr, "%s: Disabling In Band Sleep functionality\n", __FUNCTION__); +- err = rome_disable_sleep(fd); ++ /* Donwload TLV files (rampatch, NVM) */ ++ err = rome_download_tlv_file(fd); + if (err < 0) { +- fprintf(stderr, "%s: Failed to disable IBS!\n", __FUNCTION__); ++ fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); + goto error; + } +- fprintf(stderr, "%s: IBS disabled successfully \n", __FUNCTION__); ++ fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); + + /* Perform HCI reset here*/ + err = rome_hci_reset_req(fd); + +From 1911a9d5799d110a7d010e154b44e43c65e838ff Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Tue, 30 Sep 2014 12:13:00 +0530 +Subject: [PATCH 07/19] bluetooth: Check TTY buffer for data availability + before reading + +When operating at higher baud rates check the TTY buffer for +availability of data before proceeding to read. Call select() with +a 3 sec timeout value to check for the availablitiy of data. +select() will return once data is available in the TTY buffers +and will allow read() to fetch the data. If data is not available +in the TTY buffer until the timeout valueexpires, do not proceed +to read the data from the TTY buffers as there is none. + +Occasionally corrupt data is received on UART lines while we wait +for vendor specific event from Controller. Expected vendor specific +events are received after the corrupt data. But we do not retry +and exit and this causes firmware download failures. So, retry once +if we did not get HCI event. + +Change-Id: I3b672a7762403690f8b934ca216492f16285e8da +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach.c | 20 ++++++++++++- + tools/hciattach_rome.c | 77 +++++++++++++++++++++++++++++++++++++++----------- + tools/hciattach_rome.h | 3 ++ + 3 files changed, 83 insertions(+), 17 deletions(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index e3a915061440..c3cf10843303 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -109,16 +109,34 @@ int read_hci_event(int fd, unsigned char* buf, int size) + { + int remain, r; + int count = 0; ++ fd_set infids; ++ struct timeval timeout; + + if (size <= 0) + return -1; + ++ FD_ZERO (&infids); ++ FD_SET (fd, &infids); ++ timeout.tv_sec = 3; ++ timeout.tv_usec = 0; ++ ++ /* Check whether data is available in TTY buffer before calling read() */ ++ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) { ++ fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); ++ return -1; ++ } ++ else ++ fprintf(stderr, "%s: Data(HCI-CMD-COMP-EVENT) available in TTY Serial buffer\n", __FUNCTION__); ++ + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + while (1) { + r = read(fd, buf, 1); +- if (r <= 0) ++ if (r <= 0) { ++ fprintf(stderr, "%s: read() failed with return value: %d\n", ++ __FUNCTION__, r); + return -1; ++ } + if (buf[0] == 0x04) + break; + } +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index d0e2935b9997..d2687b1ef01a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -326,42 +326,87 @@ failed: + } + + ++int wait_for_data(int fd, int maxTimeOut) ++{ ++ fd_set infids; ++ struct timeval timeout; ++ ++ if (maxTimeOut <= 0) { ++ fprintf(stderr, "%s: Invalid timeout value specified", __func__); ++ return -EINVAL; ++ } ++ ++ FD_ZERO (&infids); ++ FD_SET (fd, &infids); ++ timeout.tv_sec = maxTimeOut; ++ timeout.tv_usec = 0; ++ ++ /* Check whether data is available in TTY buffer before calling read() */ ++ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) { ++ fprintf(stderr, "%s: Timing out on select for %d secs.\n", __FUNCTION__, maxTimeOut); ++ return -1; ++ } ++ else ++ fprintf(stderr, "%s: HCI-VS-EVENT available in TTY Serial buffer\n", ++ __FUNCTION__); ++ ++ return 1; ++} ++ + /* + * Read an VS HCI event from the given file descriptor. + */ + int read_vs_hci_event(int fd, unsigned char* buf, int size) + { +- int remain, r; ++ int remain, r, retry = 0; + int count = 0; +- fd_set infids; +- struct timeval timeout; + + if (size <= 0) { + fprintf(stderr, "Invalid size arguement!\n"); + return -1; + } + +- fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); +- +- FD_ZERO (&infids); +- FD_SET (fd, &infids); +- timeout.tv_sec = 3; +- timeout.tv_usec = 0; /* half second is a long time at 115.2 Kbps */ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", ++ __FUNCTION__); + +- if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) +- fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); +- else +- fprintf(stderr, "%s: Data available in TTY Serial buffer\n", __FUNCTION__); ++ /* Check whether data is available in TTY buffer before calling read() */ ++ if (wait_for_data(fd, SELECT_TIMEOUT) < 1) ++ return -1; + + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + /* It will keep reading until find 0x04 byte */ + while (1) { ++ /* Read UART Buffer for HCI-DATA */ + r = read(fd, buf, 1); +- if (r <= 0) +- return -1; +- if (buf[0] == 0x04) ++ if (r <= 0) { ++ fprintf(stderr, "%s: read() failed. error: %d\n", ++ __FUNCTION__, r); ++ return -1; ++ } ++ ++ /* Check if received data is HCI-DATA or not. ++ * If not HCI-DATA, then retry reading the UART Buffer once. ++ * Sometimes there could be corruption on the UART lines and to ++ * avoid that retry once reading the UART Buffer for HCI-DATA. ++ */ ++ if (buf[0] == 0x04) { /* Recvd. HCI DATA */ ++ retry = 0; + break; ++ } ++ else if (retry < MAX_RETRY_CNT){ /* Retry mechanism */ ++ retry++; ++ fprintf(stderr, "%s: Not an HCI-VS-Event! buf[0]: %d", ++ __FUNCTION__, buf[0]); ++ if (wait_for_data(fd, SELECT_TIMEOUT) < 1) ++ return -1; ++ else /* Data available in UART Buffer: Continue to read */ ++ continue; ++ } ++ else { /* RETRY failed : Exiting with failure */ ++ fprintf(stderr, "%s: RETRY failed!", __FUNCTION__); ++ return -1; ++ } + } + count++; + +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index a4abe9f73080..3efb71995c45 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -179,6 +179,9 @@ typedef struct + #define TAG_NUM_2 2 + #define TAG_BDADDR_OFFSET 7 + ++#define MAX_RETRY_CNT 1 ++#define SELECT_TIMEOUT 3 ++ + /* NVM Tags specifically used for ROME 1.0 */ + #define ROME_1_0_100022_1 0x101000221 + #define ROME_1_0_100019 0x101000190 + +From 9d81b1dd643966ba6f2ffb3f7658a24cfcb37df4 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Wed, 20 Aug 2014 12:13:19 +0530 +Subject: [PATCH 08/19] bluetooth : Add support for TUFEELO firmware download + +Add TUFELLO chip version to allow firmware download. + +Change-Id: Ie3760fa64e8345bf9a84b2f047fde0ac1003b393 +--- + tools/hciattach_rome.c | 5 ++++- + tools/hciattach_rome.h | 3 ++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index d2687b1ef01a..84dfc97b5140 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1616,9 +1616,12 @@ int qca_soc_init(int fd, char *bdaddr) + nvm_file_path = ROME_NVM_TLV_2_0_1_PATH; + goto download; + case ROME_VER_3_0: +- case TUFELLO_VER_1_0: + rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; + nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; ++ goto download; ++ case TUFELLO_VER_1_0: ++ rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; ++ nvm_file_path = TF_NVM_TLV_1_0_0_PATH; + + download: + /* Change baud rate 115.2 kbps to 3Mbps*/ +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 3efb71995c45..9d18c576fcae 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -204,7 +204,8 @@ typedef struct + #define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" + #define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" + #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" +- ++#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" ++#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" + + /****************************************************************************** + ** Local type definitions + +From ac12a2a733ad6cc6eed8ccdd3462d1fe1969fc54 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Dec 2014 14:52:16 +0530 +Subject: [PATCH 09/19] bluetooth: Add support for ROME 3.2 SOC. + +Add firmware download support for ROME 3.2 version. As part +of this, the Bluetooth on time is optimized based on event +handling while downloading rampatch files.From ROME 3.2 onwards, +the VS and command complete events will be sent depending the flag +indication present in the header. HOST can wait for VS and command +complete events only if specified in the header info. This greatly +reduces the time spent by HOST in waiting for 2 events from the +Controller before downloading each segment of the RAMPATCH file + +Change-Id: I9c4227a7a529455f4d120b2c9d065f3ec6b439e9 +--- + tools/hciattach_rome.c | 104 ++++++++++++++++++++++++++++++++++++++++++------- + tools/hciattach_rome.h | 16 +++++++- + 2 files changed, 103 insertions(+), 17 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 84dfc97b5140..c6d528f118e1 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -62,9 +62,11 @@ unsigned char *pdata_buffer = NULL; + patch_info rampatch_patch_info; + int rome_ver = ROME_VER_UNKNOWN; + unsigned char gTlv_type; ++unsigned char gtlv_dwndcfg; + char *rampatch_file_path; + char *nvm_file_path; + vnd_userial_cb_t vnd_userial; ++unsigned char wait_vsc_evt = TRUE; + /****************************************************************************** + ** Extern variables + ******************************************************************************/ +@@ -455,14 +457,16 @@ int hci_send_vs_cmd(int fd, unsigned char *cmd, unsigned char *rsp, int size) + goto failed; + } + +- /* Check for response from the Controller */ +- if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { +- ret = -ETIMEDOUT; +- fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +- goto failed; ++ if (wait_vsc_evt) { ++ /* Check for response from the Controller */ ++ if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { ++ ret = -ETIMEDOUT; ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto failed; ++ } ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); + } + +- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); + failed: + return ret; + } +@@ -903,6 +907,7 @@ int rome_get_tlv_file(char *file_path) + + /* To handle different event between rampatch and NVM */ + gTlv_type = ptlv_header->tlv_type; ++ gtlv_dwndcfg = ptlv_header->tlv.patch.dwnd_cfg; + + if(ptlv_header->tlv_type == TLV_TYPE_PATCH){ + fprintf(stderr, "====================================================\n"); +@@ -914,6 +919,7 @@ int rome_get_tlv_file(char *file_path) + fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); + fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); + fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); ++ fprintf(stderr, "Event Handling\t\t\t : 0x%x", ptlv_header->tlv.patch.dwnd_cfg); + fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); + fprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); + fprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); +@@ -1023,19 +1029,83 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + fprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", + __FUNCTION__,tlv_size, total_segment, remain_size); + +- for(i=0;i= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) +- && !remain_size && ((i+1) == total_segment))? FALSE: TRUE; ++ if (gTlv_type == TLV_TYPE_PATCH) { ++ /* Prior to Rome version 3.2(including inital few rampatch release of ++ * Rome 3.2), the event handling mechanism is ROME_SKIP_EVT_NONE. After ++ * few release of rampatch for Rome 3.2, the mechamism is changed to ++ * ROME_SKIP_EVT_VSE_CC. Rest of the mechanism is not used for now ++ */ ++ switch(gtlv_dwndcfg) ++ { ++ case ROME_SKIP_EVT_NONE: ++ wait_vsc_evt = TRUE; ++ wait_cc_evt = TRUE; ++ fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_NONE", __func__); ++ break; ++ case ROME_SKIP_EVT_VSE_CC: ++ wait_vsc_evt = FALSE; ++ wait_cc_evt = FALSE; ++ fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_VSE_CC", __func__); ++ break; ++ /* Not handled for now */ ++ case ROME_SKIP_EVT_VSE: ++ case ROME_SKIP_EVT_CC: ++ default: ++ fprintf(stderr, "%s: Unsupported Event handling: %d", __func__, gtlv_dwndcfg); ++ break; ++ } ++ } else { ++ wait_vsc_evt = TRUE; ++ wait_cc_evt = TRUE; ++ } ++ ++ for(i = 0; i < total_segment; i++) { ++ if((i+1) == total_segment) { ++ if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && ++ (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is from 1.1 to 3.1 ++ * 1. No CCE for the last command segment but all other segment ++ * 2. All the command segments get VSE including the last one ++ */ ++ wait_cc_evt = !remain_size ? FALSE: TRUE; ++ } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is 3.2 ++ * 1. None of the command segments receive CCE ++ * 2. No command segments receive VSE except the last one ++ * 3. If gtlv_dwndcfg is ROME_SKIP_EVT_NONE then the logic is ++ * same as Rome 2.1, 2.2, 3.0 ++ */ ++ if (gtlv_dwndcfg == ROME_SKIP_EVT_NONE) { ++ wait_cc_evt = !remain_size ? FALSE: TRUE; ++ } else if (gtlv_dwndcfg == ROME_SKIP_EVT_VSE_CC) { ++ wait_vsc_evt = !remain_size ? TRUE: FALSE; ++ } ++ } ++ } ++ + if((err = rome_tlv_dnld_segment(fd, i, MAX_SIZE_PER_TLV_SEGMENT, wait_cc_evt )) < 0) + goto error; + } + +- /* In case remain data still remain, last rampatch segment command will not wait +- for command complete event here */ +- wait_cc_evt = ((rome_ver >= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) +- && remain_size )? FALSE:TRUE; ++ if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is from 1.1 to 3.1 ++ * 1. No CCE for the last command segment but all other segment ++ * 2. All the command segments get VSE including the last one ++ */ ++ wait_cc_evt = remain_size ? FALSE: TRUE; ++ } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is 3.2 ++ * 1. None of the command segments receive CCE ++ * 2. No command segments receive VSE except the last one ++ * 3. If gtlv_dwndcfg is ROME_SKIP_EVT_NONE then the logic is ++ * same as Rome 2.1, 2.2, 3.0 ++ */ ++ if (gtlv_dwndcfg == ROME_SKIP_EVT_NONE) { ++ wait_cc_evt = remain_size ? FALSE: TRUE; ++ } else if (gtlv_dwndcfg == ROME_SKIP_EVT_VSE_CC) { ++ wait_vsc_evt = remain_size ? TRUE: FALSE; ++ } ++ } + + if(remain_size) err =rome_tlv_dnld_segment(fd, i, remain_size, wait_cc_evt); + +@@ -1619,6 +1689,10 @@ int qca_soc_init(int fd, char *bdaddr) + rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; + nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; + goto download; ++ case ROME_VER_3_2: ++ rampatch_file_path = ROME_RAMPATCH_TLV_3_0_2_PATH; ++ nvm_file_path = ROME_NVM_TLV_3_0_2_PATH; ++ goto download; + case TUFELLO_VER_1_0: + rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; + nvm_file_path = TF_NVM_TLV_1_0_0_PATH; +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 9d18c576fcae..77e85e7e7b19 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -204,9 +204,17 @@ typedef struct + #define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" + #define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" + #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" ++#define ROME_RAMPATCH_TLV_3_0_2_PATH "/lib/firmware/qca/rampatch_tlv_3.2.tlv" ++#define ROME_NVM_TLV_3_0_2_PATH "/lib/firmware/qca/nvm_tlv_3.2.bin" + #define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" + #define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" + ++/* This header value in rampatch file decides event handling mechanism in the HOST */ ++#define ROME_SKIP_EVT_NONE 0x00 ++#define ROME_SKIP_EVT_VSE 0x01 ++#define ROME_SKIP_EVT_CC 0x02 ++#define ROME_SKIP_EVT_VSE_CC 0x03 ++ + /****************************************************************************** + ** Local type definitions + ******************************************************************************/ +@@ -251,7 +259,8 @@ typedef struct { + unsigned int tlv_patch_data_len; + unsigned char sign_ver; + unsigned char sign_algorithm; +- unsigned short reserved1; ++ unsigned char dwnd_cfg; ++ unsigned char reserved1; + unsigned short prod_id; + unsigned short build_ver; + unsigned short patch_ver; +@@ -306,7 +315,8 @@ enum{ + ROME_PATCH_VER_0100 = 0x0100, + ROME_PATCH_VER_0101 = 0x0101, + ROME_PATCH_VER_0200 = 0x0200, +- ROME_PATCH_VER_0300 = 0x0300 ++ ROME_PATCH_VER_0300 = 0x0300, ++ ROME_PATCH_VER_0302 = 0x0302 + }; + + enum{ +@@ -314,6 +324,7 @@ enum{ + ROME_SOC_ID_11 = 0x00000011, + ROME_SOC_ID_13 = 0x00000013, + ROME_SOC_ID_22 = 0x00000022, ++ ROME_SOC_ID_44 = 0x00000044 + }; + + enum{ +@@ -323,6 +334,7 @@ enum{ + ROME_VER_1_3 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_00 ), + ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), + ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), ++ ROME_VER_3_2 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_44 ), + TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) + }; + #endif /* HW_ROME_H */ + +From f7cc3b22522cfc66a7c4126630c6222f22be17f6 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Thu, 4 Dec 2014 17:23:58 +0530 +Subject: [PATCH 10/19] bluetooth: Use correct TTY ioctl calls for flow control + operations + +BT firmware download application is using incorrect APIs for +performing flow off and flow on operations. As a result, the local +UART Controller is detecting breaks errors on the UART HW lines. + +Appliaction should use TIOCMGET and TIOCMSET ioctl()'s for flow +control operations instead of the tcsetattr() call. Also, the +application should set the value of "number of bits per character" +value to 8 and not as 5. + +Due to incorrect APIs used for flow control operation and wrong +value configured for CSIZE parameter, the local UART Controller +detected break errors on the UART HW lines. This caused the +firmware download operation to fail and resulted in BT ON failure. + +Change-Id: Id0ac1276609eceb528163860cc87267aaa50fede +--- + tools/hciattach_rome.c | 67 +++++++++++++++++++++++++++++++++----------------- + tools/hciattach_rome.h | 6 +++-- + 2 files changed, 49 insertions(+), 24 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index c6d528f118e1..1e689273b851 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright 2012 The Android Open Source Project +@@ -31,6 +31,7 @@ + + #define LOG_TAG "bt_vendor" + #include ++#include + #include + #include + #include +@@ -139,6 +140,16 @@ void userial_vendor_set_baud(unsigned char userial_baud) + unsigned int tcio_baud; + fprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); + ++ if (tcgetattr(vnd_userial.fd, &vnd_userial.termios) < 0) { ++ perror("Can't get port settings"); ++ return; ++ } ++ cfmakeraw(&vnd_userial.termios); ++ vnd_userial.termios.c_cflag |= CLOCAL; ++ vnd_userial.termios.c_cflag |= CREAD; ++ vnd_userial.termios.c_cflag |= CS8; ++ tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); ++ + userial_to_tcio_baud(userial_baud, &tcio_baud); + + cfsetospeed(&vnd_userial.termios, tcio_baud); +@@ -169,6 +180,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) + cfmakeraw(&ti); + ti.c_cflag |= CLOCAL; + ti.c_cflag |= CREAD; ++ ti.c_cflag |= CS8; + + switch(op) + { +@@ -1445,6 +1457,29 @@ error: + + } + ++static void flow_control(int fd, int opt) ++{ ++ struct termios c_opt; ++ ++ ioctl(fd, TIOCMGET, &c_opt); ++ c_opt.c_cc[VTIME] = 0; /* inter-character timer unused */ ++ c_opt.c_cc[VMIN] = 0; /* blocking read until 8 chars received */ ++ c_opt.c_cflag &= ~CSIZE; ++ c_opt.c_cflag |= (CS8 | CLOCAL | CREAD); ++ if (MSM_ENABLE_FLOW_CTRL) ++ c_opt.c_cflag |= CRTSCTS; ++ else if (MSM_DISABLE_FLOW_CTRL) ++ c_opt.c_cflag |= ~CRTSCTS; ++ else { ++ fprintf(stderr, "%s: Incorrect option passed for TIOCMSET\n", __func__); ++ return; ++ } ++ c_opt.c_iflag = IGNPAR; ++ c_opt.c_oflag = 0; ++ c_opt.c_lflag = 0; ++ ioctl(fd, TIOCMSET, &c_opt); ++} ++ + + int rome_set_baudrate_req(int fd) + { +@@ -1464,12 +1499,10 @@ int rome_set_baudrate_req(int fd) + + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); ++ + /* Flow off during baudrate change */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); +- goto error; +- } ++ flow_control(fd, MSM_DISABLE_FLOW_CTRL); ++ + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; + err = write(fd, cmd, size); +@@ -1481,11 +1514,8 @@ int rome_set_baudrate_req(int fd) + userial_vendor_set_baud(USERIAL_BAUD_3M); + + /* Flow on after changing local uart baudrate */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); +- return err; +- } ++ flow_control(fd, MSM_ENABLE_FLOW_CTRL); ++ + /* Check for response from the Controller */ + if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { + fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +@@ -1528,11 +1558,8 @@ int rome_hci_reset_req(int fd) + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); + + /* Flow off during baudrate change */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); +- goto error; +- } ++ flow_control(fd, MSM_DISABLE_FLOW_CTRL); ++ + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); + err = write(fd, cmd, size); +@@ -1545,11 +1572,8 @@ int rome_hci_reset_req(int fd) + userial_vendor_set_baud(USERIAL_BAUD_3M); + + /* Flow on after changing local uart baudrate */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); +- return err; +- } ++ flow_control(fd, MSM_ENABLE_FLOW_CTRL); ++ + /* Wait for command complete event */ + err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); + if ( err < 0) { +@@ -1616,7 +1640,6 @@ int qca_soc_init(int fd, char *bdaddr) + int err = -1; + int size; + +- fprintf(stderr, " %s \n", __FUNCTION__); + vnd_userial.fd = fd; + /* Get Rome version information */ + if((err = rome_patch_ver_req(fd)) <0){ +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 77e85e7e7b19..ef3647e6a69b 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -1,7 +1,7 @@ + /* +- * Copyright 2012 The Android Open Source Project +- * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Not a Contribution. ++ * Copyright 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. +@@ -40,6 +40,8 @@ + #define NVITEM_SIZE 2 + #define PERSIST_HEADER_LEN 3 + #define BD_ADDR_LEN 6 ++#define MSM_ENABLE_FLOW_CTRL 16 ++#define MSM_DISABLE_FLOW_CTRL 17 + + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + +From bd7d1fce8de4639445563442a8448468d671fad2 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Tue, 20 Jan 2015 12:43:20 +0530 +Subject: [PATCH 11/19] bluetooth: Add support for multi baud rate + +Currently BT operates only at 3M baud rate. Provide option +to configure the pre-defined baud rate values as supported by the +target platform. + +Change-Id: I4bbaf7db01ffb983c38dca7c4a4a56f579c678a8 +--- + tools/hciattach.c | 2 +- + tools/hciattach.h | 2 +- + tools/hciattach_rome.c | 109 ++++++++++++++++++++++++++++++++++++++++++------- + tools/hciattach_rome.h | 23 +++++++++++ + 4 files changed, 119 insertions(+), 17 deletions(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index c3cf10843303..dda639cabca3 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -286,7 +286,7 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) + static int qca(int fd, struct uart_t *u, struct termios *ti) + { + fprintf(stderr,"qca\n"); +- return qca_soc_init(fd, u->bdaddr); ++ return qca_soc_init(fd, u->speed, u->bdaddr); + } + + static int qualcomm(int fd, struct uart_t *u, struct termios *ti) +diff --git a/tools/hciattach.h b/tools/hciattach.h +index 0656a845223c..49e59321fcac 100644 +--- a/tools/hciattach.h ++++ b/tools/hciattach.h +@@ -64,7 +64,7 @@ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, + struct termios *ti); + int ath3k_post(int fd, int pm); + int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); +-int qca_soc_init(int fd, char *bdaddr); ++int qca_soc_init(int fd, int speed, char *bdaddr); + int intel_init(int fd, int init_speed, int *speed, struct termios *ti); + int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti, + const char *bdaddr); +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 1e689273b851..37974290ae0a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1481,7 +1481,7 @@ static void flow_control(int fd, int opt) + } + + +-int rome_set_baudrate_req(int fd) ++int rome_set_baudrate_req(int fd, int local_baud_rate, int controller_baud_rate) + { + int size, err = 0; + unsigned char cmd[HCI_MAX_CMD_SIZE]; +@@ -1495,7 +1495,7 @@ int rome_set_baudrate_req(int fd) + cmd[0] = HCI_COMMAND_PKT; + cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); + cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; +- cmd[4] = BAUDRATE_3000000; ++ cmd[4] = controller_baud_rate; + + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); +@@ -1511,7 +1511,7 @@ int rome_set_baudrate_req(int fd) + goto error; + } + /* Change Local UART baudrate to high speed UART */ +- userial_vendor_set_baud(USERIAL_BAUD_3M); ++ userial_vendor_set_baud(local_baud_rate); + + /* Flow on after changing local uart baudrate */ + flow_control(fd, MSM_ENABLE_FLOW_CTRL); +@@ -1537,7 +1537,7 @@ error: + } + + +-int rome_hci_reset_req(int fd) ++int rome_hci_reset_req(int fd, char baud) + { + int size, err = 0; + unsigned char cmd[HCI_MAX_CMD_SIZE]; +@@ -1569,7 +1569,7 @@ int rome_hci_reset_req(int fd) + } + + /* Change Local UART baudrate to high speed UART */ +- userial_vendor_set_baud(USERIAL_BAUD_3M); ++ userial_vendor_set_baud(baud); + + /* Flow on after changing local uart baudrate */ + flow_control(fd, MSM_ENABLE_FLOW_CTRL); +@@ -1635,10 +1635,69 @@ int read_bd_address(unsigned char *bdaddr) + return 0; + } + +-int qca_soc_init(int fd, char *bdaddr) ++int isSpeedValid(int speed, int *local_baud_rate, int *controller_baud_rate) ++{ ++ switch(speed) { ++ case 9600: ++ *local_baud_rate = USERIAL_BAUD_9600; ++ *controller_baud_rate = BAUDRATE_9600; ++ break; ++ case 19200: ++ *local_baud_rate = USERIAL_BAUD_19200; ++ *controller_baud_rate = BAUDRATE_19200; ++ break; ++ case 57600: ++ *local_baud_rate = USERIAL_BAUD_57600; ++ *controller_baud_rate = BAUDRATE_57600; ++ break; ++ case 115200: ++ *local_baud_rate = USERIAL_BAUD_115200; ++ *controller_baud_rate = BAUDRATE_115200; ++ break; ++ case 230400: ++ *local_baud_rate = USERIAL_BAUD_230400; ++ *controller_baud_rate = BAUDRATE_230400; ++ break; ++ case 460800: ++ *local_baud_rate = USERIAL_BAUD_460800; ++ *controller_baud_rate = BAUDRATE_460800; ++ break; ++ case 921600: ++ *local_baud_rate = USERIAL_BAUD_921600; ++ *controller_baud_rate = BAUDRATE_921600; ++ break; ++ case 1000000: ++ *local_baud_rate = USERIAL_BAUD_1M; ++ *controller_baud_rate = BAUDRATE_1000000; ++ break; ++ case 2000000: ++ *local_baud_rate = USERIAL_BAUD_2M; ++ *controller_baud_rate = BAUDRATE_2000000; ++ break; ++ case 3000000: ++ *local_baud_rate = USERIAL_BAUD_3M; ++ *controller_baud_rate = BAUDRATE_3000000; ++ break; ++ case 4000000: ++ *local_baud_rate = USERIAL_BAUD_4M; ++ *controller_baud_rate = BAUDRATE_4000000; ++ break; ++ case 300: ++ case 600: ++ case 1200: ++ case 2400: ++ default: ++ fprintf(stderr, "Invalid baud rate passed!\n"); ++ *local_baud_rate = *controller_baud_rate = -1; ++ break; ++ } ++ return -1; ++} ++ ++int qca_soc_init(int fd, int speed, char *bdaddr) + { + int err = -1; +- int size; ++ int size, local_baud_rate = 0, controller_baud_rate = 0; + + vnd_userial.fd = fd; + /* Get Rome version information */ +@@ -1687,7 +1746,7 @@ int qca_soc_init(int fd, char *bdaddr) + } + + /* Change baud rate 115.2 kbps to 3Mbps*/ +- err = rome_hci_reset_req(fd); ++ err = rome_hci_reset_req(fd, local_baud_rate); + if ( err <0 ) { + fprintf(stderr, "HCI Reset Failed !!\n"); + goto error; +@@ -1721,13 +1780,23 @@ int qca_soc_init(int fd, char *bdaddr) + nvm_file_path = TF_NVM_TLV_1_0_0_PATH; + + download: +- /* Change baud rate 115.2 kbps to 3Mbps*/ +- err = rome_set_baudrate_req(fd); +- if (err < 0) { +- fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); +- goto error; ++ /* Check if user requested for 115200 kbps */ ++ if (speed == 115200) { ++ local_baud_rate = USERIAL_BAUD_115200; ++ controller_baud_rate = BAUDRATE_115200; + } +- fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); ++ else { ++ /* Change only if baud rate requested is valid or not */ ++ isSpeedValid(speed, &local_baud_rate, &controller_baud_rate); ++ if (local_baud_rate < 0 || controller_baud_rate < 0) ++ goto error; ++ ++ err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); ++ if (err < 0) { ++ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); ++ goto error; ++ } ++ } + + /* Donwload TLV files (rampatch, NVM) */ + err = rome_download_tlv_file(fd); +@@ -1737,8 +1806,18 @@ download: + } + fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); + ++ /* ++ * Overriding the baud rate value in NVM file with the user ++ * requested baud rate, since default baud rate in NVM file is 3M. ++ */ ++ err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); ++ if (err < 0) { ++ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); ++ goto error; ++ } ++ + /* Perform HCI reset here*/ +- err = rome_hci_reset_req(fd); ++ err = rome_hci_reset_req(fd, local_baud_rate); + if ( err <0 ) { + fprintf(stderr, "HCI Reset Failed !!!\n"); + goto error; +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index ef3647e6a69b..1500ddd3a79f 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -78,6 +78,29 @@ typedef struct + #define USERIAL_BAUD_4M 15 + #define USERIAL_BAUD_AUTO 16 + ++/* Vendor specific baud rate values */ ++#define UART_Baud_Rate_Baud_9600 4 ++#define UART_Baud_Rate_Baud_19200 3 ++#define UART_Baud_Rate_Baud_57600 1 ++#define UART_Baud_Rate_Baud_115200 0 ++#define UART_Baud_Rate_Baud_230400 5 ++#define UART_Baud_Rate_Baud_460800 7 ++#define UART_Baud_Rate_Baud_921600 10 ++#define UART_Baud_Rate_Baud_1000000 11 ++#define UART_Baud_Rate_Baud_2000000 13 ++#define UART_Baud_Rate_Baud_3000000 14 ++#define UART_Baud_Rate_Baud_4000000 15 ++ ++#define UART_Baud_Rate_Baud_250000 6 ++#define UART_Baud_Rate_Baud_500000 8 ++#define UART_Baud_Rate_Baud_720000 9 ++#define UART_Baud_Rate_Baud_125000 12 ++#define UART_Baud_Rate_Baud_1600000 16 ++#define UART_Baud_Rate_Baud_3200000 17 ++#define UART_Baud_Rate_Baud_3500000 18 ++ ++ ++ + #ifndef FALSE + #define FALSE 0 + #endif + +From 7dc9c5e316aa9a22899259ce296136b2e257735d Mon Sep 17 00:00:00 2001 +From: Kamal Negi +Date: Tue, 30 Dec 2014 19:15:08 +0530 +Subject: [PATCH 12/19] Override PCM Settings by reading configuration file + +Configure the PCM role as master or slave depending upon +the platform's support. This configuration is provided +in the config file which is read during the firmware +download process and the default PCM configuration is +overwritten with this value. + +Change-Id: If0eae58b4cd32d75b3bcb669bc73dca67652473c +Signed-off-by: Kamal Negi +--- + tools/hciattach_rome.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++--- + tools/hciattach_rome.h | 8 ++++++ + 2 files changed, 71 insertions(+), 4 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 37974290ae0a..99866e23e99e 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright 2012 The Android Open Source Project +@@ -873,6 +873,44 @@ error: + return err; + } + ++int get_value_from_config(char *file_path,char *param) ++{ ++ FILE *pfile = NULL; ++ char *line = NULL; ++ char *pch = NULL; ++ char param_str[20]; ++ int bytes_read = 0, position; ++ int ret = -1; ++ ++ if (!file_path || !param) { ++ fprintf(stderr,"Invalid arguments\n"); ++ return -EINVAL; ++ } ++ ++ pfile = fopen(file_path, "r" ); ++ if (!pfile) { ++ fprintf(stderr, "Failed to open %s\n", file_path); ++ return ret; ++ } ++ ++ while (getline(&line, &bytes_read, pfile) > 0 ) { ++ if (line[0] != '#' && line[0] != '\n') { ++ pch = memchr(line, '=', strlen(line)); ++ if (pch != NULL) { ++ position = pch - line; ++ strncpy(param_str, line, position); ++ if (strncmp(param_str, param, position) == 0) { ++ ret = atoi(pch + 1); ++ break; ++ } ++ } ++ } ++ } ++ free(line); ++ fclose(pfile); ++ return ret; ++} ++ + int rome_get_tlv_file(char *file_path) + { + FILE * pFile; +@@ -884,7 +922,7 @@ int rome_get_tlv_file(char *file_path) + unsigned char data_buf[PRINT_BUF_SIZE]={0,}; + unsigned char *nvm_byte_ptr; + unsigned char bdaddr[6]; +- ++ unsigned short pcm_value; + fprintf(stderr, "File Open (%s)\n", file_path); + pFile = fopen ( file_path , "r" ); + if (pFile==NULL) {; +@@ -970,9 +1008,30 @@ int rome_get_tlv_file(char *file_path) + *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), + *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); + } ++ /* Read from file and check what PCM Configuration is required: ++ * Master = 0 /Slave = 1 */ ++ /* Override PCM configuration */ ++ if (nvm_ptr->tag_id == TAG_NUM_44) { ++ if ((pcm_value = ++ get_value_from_config(PCM_CONFIG_FILE_PATH, "PCM")) >= 0) { ++ ++ if (pcm_value == PCM_SLAVE) { ++ nvm_byte_ptr[PCM_MS_OFFSET_1] |= ++ (1 << PCM_ROLE_BIT_OFFSET); ++ nvm_byte_ptr[PCM_MS_OFFSET_2] |= ++ (1 << PCM_ROLE_BIT_OFFSET); ++ } else if (pcm_value == PCM_MASTER) { ++ nvm_byte_ptr[PCM_MS_OFFSET_1] &= ++ (~(1 << PCM_ROLE_BIT_OFFSET)); ++ nvm_byte_ptr[PCM_MS_OFFSET_2] &= ++ (~(1 << PCM_ROLE_BIT_OFFSET)); ++ } ++ } ++ } + +- for(i =0;(itag_len && (i*3 + 2) tag_len && (i*3 + 2) < PRINT_BUF_SIZE);i++) ++ snprintf((char *) data_buf, PRINT_BUF_SIZE, "%s%.02x ", ++ (char *)data_buf, *(nvm_byte_ptr + i)); + + fprintf(stderr, "TAG Data\t\t\t : %s\n", data_buf); + +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 1500ddd3a79f..f591c10e4f2b 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -202,8 +202,15 @@ typedef struct + #define NVM_ACCESS_SET 0x01 + #define TAG_NUM_OFFSET 5 + #define TAG_NUM_2 2 ++#define TAG_NUM_44 44 + #define TAG_BDADDR_OFFSET 7 + ++#define PCM_MS_OFFSET_1 9 ++#define PCM_MS_OFFSET_2 33 ++ ++#define PCM_SLAVE 1 ++#define PCM_MASTER 0 ++#define PCM_ROLE_BIT_OFFSET 4 + #define MAX_RETRY_CNT 1 + #define SELECT_TIMEOUT 3 + +@@ -240,6 +247,7 @@ typedef struct + #define ROME_SKIP_EVT_CC 0x02 + #define ROME_SKIP_EVT_VSE_CC 0x03 + ++#define PCM_CONFIG_FILE_PATH "/etc/bluetooth/pcm.conf" + /****************************************************************************** + ** Local type definitions + ******************************************************************************/ + +From 9eb8220969598d63be3b918b49b6258387629bf3 Mon Sep 17 00:00:00 2001 +From: Rupesh Tatiya +Date: Thu, 29 Jan 2015 15:36:27 +0530 +Subject: [PATCH 13/19] Add support for Tufello 1.1 SOC + +Enable mechanism to download firmware for Tufello 1.1 SOC. +Also, use correct firmware file path for Tufello 1.0. + +Change-Id: I915e48023e45de9e2550336a3de9a07f2b788189 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 29 ++++++++++++++++++----------- + tools/hciattach_rome.h | 10 +++++++--- + 2 files changed, 25 insertions(+), 14 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 99866e23e99e..fee36f904e04 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -621,7 +621,7 @@ int rome_edl_set_patch_request(int fd) + -1, PATCH_HDR_LEN + 1); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Send HCI Command packet to Controller */ + err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); +@@ -670,7 +670,7 @@ int rome_edl_patch_download_request(int fd) + index, MAX_DATA_PER_SEGMENT); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Initialize the RSP packet everytime to 0 */ + memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); +@@ -707,7 +707,7 @@ int rome_edl_patch_download_request(int fd) + memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Send HCI Command packet to Controller */ + err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); +@@ -824,7 +824,7 @@ int rome_attach_rampatch(int fd) + -1, EDL_PATCH_CMD_LEN); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Send HCI Command packet to Controller */ + err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); +@@ -854,7 +854,7 @@ int rome_rampatch_reset(int fd) + -1, EDL_PATCH_CMD_LEN); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); + + /* Send HCI Command packet to Controller */ + err = write(fd, cmd, size); +@@ -1058,7 +1058,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc + unsigned char cmd[HCI_MAX_CMD_SIZE]; + unsigned char rsp[HCI_MAX_EVENT_SIZE]; + +- fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d\n", __FUNCTION__, index, seg_size); ++ fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d wait_cc_evt = 0x%x\n", __FUNCTION__, index, seg_size, wait_cc_evt); + + /* Frame the HCI CMD PKT to be sent to Controller*/ + frame_hci_cmd_pkt(cmd, EDL_PATCH_TLV_REQ_CMD, 0, index, seg_size); +@@ -1092,6 +1092,7 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + { + int total_segment, remain_size, i, err = -1; + unsigned char wait_cc_evt; ++ unsigned int rom = rome_ver >> 16; + + total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; + remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\ +@@ -1132,14 +1133,15 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + + for(i = 0; i < total_segment; i++) { + if((i+1) == total_segment) { +- if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && ++ if ((rom >= ROME_PATCH_VER_0100) && (rom < ROME_PATCH_VER_0302) && + (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is from 1.1 to 3.1 + * 1. No CCE for the last command segment but all other segment + * 2. All the command segments get VSE including the last one + */ + wait_cc_evt = !remain_size ? FALSE: TRUE; +- } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ } else if ((rom == ROME_PATCH_VER_0302) && ++ (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is 3.2 + * 1. None of the command segments receive CCE + * 2. No command segments receive VSE except the last one +@@ -1158,13 +1160,14 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + goto error; + } + +- if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ if ((rom >= ROME_PATCH_VER_0100) && (rom < ROME_PATCH_VER_0302) && ++ (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is from 1.1 to 3.1 + * 1. No CCE for the last command segment but all other segment + * 2. All the command segments get VSE including the last one + */ + wait_cc_evt = remain_size ? FALSE: TRUE; +- } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ } else if ((rom == ROME_PATCH_VER_0302) && (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is 3.2 + * 1. None of the command segments receive CCE + * 2. No command segments receive VSE except the last one +@@ -1837,6 +1840,10 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + case TUFELLO_VER_1_0: + rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; + nvm_file_path = TF_NVM_TLV_1_0_0_PATH; ++ goto download; ++ case TUFELLO_VER_1_1: ++ rampatch_file_path = TF_RAMPATCH_TLV_1_0_1_PATH; ++ nvm_file_path = TF_NVM_TLV_1_0_1_PATH; + + download: + /* Check if user requested for 115200 kbps */ +@@ -1881,7 +1888,7 @@ download: + fprintf(stderr, "HCI Reset Failed !!!\n"); + goto error; + } +- fprintf(stderr, "HCI Reset is done\n"); ++ fprintf(stderr, "HCI Reset is done\n"); + + break; + case ROME_VER_UNKNOWN: +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index f591c10e4f2b..95d5f1e8a5c2 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -238,8 +238,10 @@ typedef struct + #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" + #define ROME_RAMPATCH_TLV_3_0_2_PATH "/lib/firmware/qca/rampatch_tlv_3.2.tlv" + #define ROME_NVM_TLV_3_0_2_PATH "/lib/firmware/qca/nvm_tlv_3.2.bin" +-#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" +-#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" ++#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/qca/rampatch_tlv_tf_1.0.tlv" ++#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/qca/nvm_tlv_tf_1.0.bin" ++#define TF_RAMPATCH_TLV_1_0_1_PATH "/lib/firmware/qca/rampatch_tlv_tf_1.1.tlv" ++#define TF_NVM_TLV_1_0_1_PATH "/lib/firmware/qca/nvm_tlv_tf_1.1.bin" + + /* This header value in rampatch file decides event handling mechanism in the HOST */ + #define ROME_SKIP_EVT_NONE 0x00 +@@ -357,6 +359,7 @@ enum{ + ROME_SOC_ID_11 = 0x00000011, + ROME_SOC_ID_13 = 0x00000013, + ROME_SOC_ID_22 = 0x00000022, ++ ROME_SOC_ID_23 = 0x00000023, + ROME_SOC_ID_44 = 0x00000044 + }; + +@@ -368,6 +371,7 @@ enum{ + ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), + ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), + ROME_VER_3_2 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_44 ), +- TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) ++ TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ), ++ TUFELLO_VER_1_1 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_23 ) + }; + #endif /* HW_ROME_H */ + +From f55d710cf43d008e42ce06ead49dc0dfbf97d3a1 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Wed, 4 Feb 2015 12:29:07 +0530 +Subject: [PATCH 14/19] bluetooth: Vote UART CLK ON prior to firmware download + process + +Before starting the firmware download process, vote UART CLK ON +to avoid triggering the dynamic suspend of UART driver. Post +firmware download and in error scenarios vote UART CLK OFF. + +As per design, the UART driver enters into dynamic suspend if +there are no activity on the UART lines for 100ms. Depending upon +the rampatch size, the BT Controller takes time to apply the +downloaded rampatch segments and in sending the vendor specific +event. If the BT Controller takes > 100ms time in sending the +vendor specific event, the UART driver enters into suspend state. + +As a result, UART driver fails to process the last vendor specific +event sent by the BT Controller. The VSE sent by BT Controller +wakes up the UART driver, but the data is not processed causing +firmware download failures. + +Hence, vote UART CLK ON prior to firmware download process and +vote UART CLK OFF post firmware download proess and in error +scenarios. + +Change-Id: I447ded33ad1cfaa020b491effce368fbfe41f894 +--- + tools/hciattach_rome.c | 13 +++++++++++++ + tools/hciattach_rome.h | 2 ++ + 2 files changed, 15 insertions(+) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index fee36f904e04..574ceac6c750 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1762,6 +1762,14 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + int size, local_baud_rate = 0, controller_baud_rate = 0; + + vnd_userial.fd = fd; ++ ++ /* Vote for UART CLK prior to FW download */ ++ err = ioctl(fd, USERIAL_OP_CLK_ON); ++ if (err < 0) { ++ fprintf(stderr, "%s: Failed to vote UART CLK ON\n", __func__); ++ return -1; ++ } ++ + /* Get Rome version information */ + if((err = rome_patch_ver_req(fd)) <0){ + fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); +@@ -1899,5 +1907,10 @@ download: + } + + error: ++ /* Vote UART CLK OFF post to FW download */ ++ err = ioctl(fd, USERIAL_OP_CLK_OFF); ++ if (err < 0) ++ fprintf(stderr, "%s: Failed to vote UART CLK OFF!!!\n", __func__); ++ + return err; + } +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 95d5f1e8a5c2..20264f9978d9 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -42,6 +42,8 @@ + #define BD_ADDR_LEN 6 + #define MSM_ENABLE_FLOW_CTRL 16 + #define MSM_DISABLE_FLOW_CTRL 17 ++#define USERIAL_OP_CLK_ON 0x5441 ++#define USERIAL_OP_CLK_OFF 0x5442 + + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + +From b09f8b12c937ec58df0581b2d95493e036c86432 Mon Sep 17 00:00:00 2001 +From: Kamal Negi +Date: Thu, 30 Apr 2015 15:53:06 +0530 +Subject: [PATCH 15/19] Override IBS settings by reading configuration file + +Configure the IBS value in Firmware by reading the +configuration file.This configuration value is +provided in the config file which is read during +the firmware download process and the default +configuration value is overwritten with this value. + +Change-Id: I47992a573b3137ac9bfb80538727981f56b328c4 +Signed-off-by: Kamal Negi +--- + tools/hciattach_rome.c | 42 +++++++++++++++++++++++++++++------------- + tools/hciattach_rome.h | 24 ++++++++++++++++-------- + 2 files changed, 45 insertions(+), 21 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 574ceac6c750..6a3f33867c12 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -922,7 +922,8 @@ int rome_get_tlv_file(char *file_path) + unsigned char data_buf[PRINT_BUF_SIZE]={0,}; + unsigned char *nvm_byte_ptr; + unsigned char bdaddr[6]; +- unsigned short pcm_value; ++ unsigned short pcm_value, ibs_value; ++ + fprintf(stderr, "File Open (%s)\n", file_path); + pFile = fopen ( file_path , "r" ); + if (pFile==NULL) {; +@@ -1008,23 +1009,38 @@ int rome_get_tlv_file(char *file_path) + *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), + *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); + } ++ ++ if (nvm_ptr->tag_id == TAG_NUM_17) { ++ if ((ibs_value = ++ get_value_from_config(FW_CONFIG_FILE_PATH, "IBS")) >= 0) { ++ if (ibs_value == FWCONF_IBS_DISABLE) { ++ nvm_byte_ptr[FWCONF_IBS_VAL_OFFSET] &= ++ (~(FWCONF_IBS_ENABLE << ++ FWCONF_IBS_VAL_BIT)); ++ } else if (ibs_value == FWCONF_IBS_ENABLE) { ++ nvm_byte_ptr[FWCONF_IBS_VAL_OFFSET] |= ++ (FWCONF_IBS_ENABLE << ++ FWCONF_IBS_VAL_BIT); ++ } ++ } ++ } + /* Read from file and check what PCM Configuration is required: + * Master = 0 /Slave = 1 */ + /* Override PCM configuration */ + if (nvm_ptr->tag_id == TAG_NUM_44) { + if ((pcm_value = +- get_value_from_config(PCM_CONFIG_FILE_PATH, "PCM")) >= 0) { +- +- if (pcm_value == PCM_SLAVE) { +- nvm_byte_ptr[PCM_MS_OFFSET_1] |= +- (1 << PCM_ROLE_BIT_OFFSET); +- nvm_byte_ptr[PCM_MS_OFFSET_2] |= +- (1 << PCM_ROLE_BIT_OFFSET); +- } else if (pcm_value == PCM_MASTER) { +- nvm_byte_ptr[PCM_MS_OFFSET_1] &= +- (~(1 << PCM_ROLE_BIT_OFFSET)); +- nvm_byte_ptr[PCM_MS_OFFSET_2] &= +- (~(1 << PCM_ROLE_BIT_OFFSET)); ++ get_value_from_config(FW_CONFIG_FILE_PATH, "PCM")) >= 0) { ++ ++ if (pcm_value == FWCONF_PCM_SLAVE) { ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_1] |= ++ (1 << FWCONF_PCM_ROLE_BIT_OFFSET); ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_2] |= ++ (1 << FWCONF_PCM_ROLE_BIT_OFFSET); ++ } else if (pcm_value == FWCONF_PCM_MASTER) { ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_1] &= ++ (~(1 << FWCONF_PCM_ROLE_BIT_OFFSET)); ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_2] &= ++ (~(1 << FWCONF_PCM_ROLE_BIT_OFFSET)); + } + } + } +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 20264f9978d9..8eaeeed8bc96 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -203,16 +203,24 @@ typedef struct + #define TAG_END 0xFF + #define NVM_ACCESS_SET 0x01 + #define TAG_NUM_OFFSET 5 +-#define TAG_NUM_2 2 +-#define TAG_NUM_44 44 ++#define TAG_NUM_2 2 ++#define TAG_NUM_17 (17) ++#define TAG_NUM_44 44 + #define TAG_BDADDR_OFFSET 7 + +-#define PCM_MS_OFFSET_1 9 +-#define PCM_MS_OFFSET_2 33 ++/* FW PCM Configuration */ ++#define FWCONF_PCM_MS_OFFSET_1 9 ++#define FWCONF_PCM_MS_OFFSET_2 33 ++#define FWCONF_PCM_SLAVE 1 ++#define FWCONF_PCM_MASTER 0 ++#define FWCONF_PCM_ROLE_BIT_OFFSET 4 ++ ++/* FW IBS Configuration */ ++#define FWCONF_IBS_DISABLE (0) ++#define FWCONF_IBS_ENABLE (1) ++#define FWCONF_IBS_VAL_BIT (7) ++#define FWCONF_IBS_VAL_OFFSET (0) + +-#define PCM_SLAVE 1 +-#define PCM_MASTER 0 +-#define PCM_ROLE_BIT_OFFSET 4 + #define MAX_RETRY_CNT 1 + #define SELECT_TIMEOUT 3 + +@@ -251,7 +259,7 @@ typedef struct + #define ROME_SKIP_EVT_CC 0x02 + #define ROME_SKIP_EVT_VSE_CC 0x03 + +-#define PCM_CONFIG_FILE_PATH "/etc/bluetooth/pcm.conf" ++#define FW_CONFIG_FILE_PATH "/etc/bluetooth/firmware.conf" + /****************************************************************************** + ** Local type definitions + ******************************************************************************/ + +From b307659dc988054c1fef32c131417cfab2b74c3e Mon Sep 17 00:00:00 2001 +From: Dibyendu Roy +Date: Fri, 22 May 2015 18:57:05 +0530 +Subject: [PATCH 16/19] bluetooth: Fix flow control operation + +Flow off operation was not actually happening at the UART line level, +since the argument passed was not being used correctly. As a result, +sometimes command complete and VS event were sent by BT SOC even +before the local UART Controller could change its baud rate to the +newer one(3 Mbps). This led to VS event being processed +incorrectly which in turn causes baud rate change to fail. + +CRs-Fixed: 844730 +Change-Id: I06d8c4ed7807aa47dd5498642c7a23c9189a1cff +Signed-off-by: Dibyendu Roy +--- + tools/hciattach_rome.c | 6 +++--- + tools/hciattach_rome.h | 4 ++-- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 6a3f33867c12..0d7014f1d2f6 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1544,10 +1544,10 @@ static void flow_control(int fd, int opt) + c_opt.c_cc[VMIN] = 0; /* blocking read until 8 chars received */ + c_opt.c_cflag &= ~CSIZE; + c_opt.c_cflag |= (CS8 | CLOCAL | CREAD); +- if (MSM_ENABLE_FLOW_CTRL) ++ if (opt == MSM_ENABLE_FLOW_CTRL) + c_opt.c_cflag |= CRTSCTS; +- else if (MSM_DISABLE_FLOW_CTRL) +- c_opt.c_cflag |= ~CRTSCTS; ++ else if (opt == MSM_DISABLE_FLOW_CTRL) ++ c_opt.c_cflag &= ~CRTSCTS; + else { + fprintf(stderr, "%s: Incorrect option passed for TIOCMSET\n", __func__); + return; +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 8eaeeed8bc96..3fdaf208e522 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -40,8 +40,8 @@ + #define NVITEM_SIZE 2 + #define PERSIST_HEADER_LEN 3 + #define BD_ADDR_LEN 6 +-#define MSM_ENABLE_FLOW_CTRL 16 +-#define MSM_DISABLE_FLOW_CTRL 17 ++#define MSM_DISABLE_FLOW_CTRL 0 ++#define MSM_ENABLE_FLOW_CTRL 1 + #define USERIAL_OP_CLK_ON 0x5441 + #define USERIAL_OP_CLK_OFF 0x5442 + + +From bec6be1174e250c60b48b51933ab6f80a27a093e Mon Sep 17 00:00:00 2001 +From: Dibyendu Roy +Date: Thu, 11 Jun 2015 12:07:43 +0530 +Subject: [PATCH 17/19] Adding MDM specific code under _PLATFORM_MDM_ + +This patch is added to comment out the commit +84cc0e12983b5761c67789ef93fd6fb164c7314d in x86 as +dynamic suspend feature is not available in x86. However, +this code shall be active for MDM platform due to +dynamic suspend feature. + +Change-Id: I998f0521b4a5f9744412db40f2c2d3bff2ac3d11 +--- + tools/hciattach_rome.c | 5 ++++- + tools/hciattach_rome.h | 3 +++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 0d7014f1d2f6..1891de24e21a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1779,13 +1779,14 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + + vnd_userial.fd = fd; + ++#ifdef _PLATFORM_MDM_ + /* Vote for UART CLK prior to FW download */ + err = ioctl(fd, USERIAL_OP_CLK_ON); + if (err < 0) { + fprintf(stderr, "%s: Failed to vote UART CLK ON\n", __func__); + return -1; + } +- ++#endif + /* Get Rome version information */ + if((err = rome_patch_ver_req(fd)) <0){ + fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); +@@ -1923,10 +1924,12 @@ download: + } + + error: ++#ifdef _PLATFORM_MDM_ + /* Vote UART CLK OFF post to FW download */ + err = ioctl(fd, USERIAL_OP_CLK_OFF); + if (err < 0) + fprintf(stderr, "%s: Failed to vote UART CLK OFF!!!\n", __func__); ++#endif + + return err; + } +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 3fdaf208e522..89f7db3bef86 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -42,8 +42,11 @@ + #define BD_ADDR_LEN 6 + #define MSM_DISABLE_FLOW_CTRL 0 + #define MSM_ENABLE_FLOW_CTRL 1 ++ ++#ifdef _PLATFORM_MDM_ + #define USERIAL_OP_CLK_ON 0x5441 + #define USERIAL_OP_CLK_OFF 0x5442 ++#endif + + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + +From 5ab2a193c11eaa8a68a0e060a560a5bd2ee2459c Mon Sep 17 00:00:00 2001 +From: Dibyendu Roy +Date: Mon, 6 Jul 2015 13:30:53 +0530 +Subject: [PATCH 18/19] Bluetooth: Fix static analysis issues + +Change-Id: Ida91f012544c39a8aaa6e7db23f1d5b68d3bec08 +--- + tools/hciattach_rome.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 1891de24e21a..59bdc16e4e8f 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -933,7 +933,13 @@ int rome_get_tlv_file(char *file_path) + + /* Get File Size */ + fseek (pFile , 0 , SEEK_END); +- fileSize = ftell (pFile); ++ ++ if((fileSize = ftell(pFile)) < 0) { ++ fprintf(stderr, "%s: fail to get current file position\n", file_path); ++ fclose (pFile); ++ return -1; ++ } ++ + rewind (pFile); + + pdata_buffer = (unsigned char*) malloc (sizeof(char)*fileSize); +@@ -1107,7 +1113,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc + int rome_tlv_dnld_req(int fd, int tlv_size) + { + int total_segment, remain_size, i, err = -1; +- unsigned char wait_cc_evt; ++ unsigned char wait_cc_evt = FALSE; + unsigned int rom = rome_ver >> 16; + + total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; + +From ca52faad6e23bee353e3315f136efb43d1e9d143 Mon Sep 17 00:00:00 2001 +From: Kamal Negi +Date: Fri, 8 May 2015 15:01:02 +0530 +Subject: [PATCH 19/19] Handle NULL Pointer derefrencing in AVRCP Target role + +Check NULL pointer to AVRCP controller role initialized or not. +If remote device don't support the AVRCP target role, then HOST dont +initialize AVRCP controller role and directly dereference the controller +role and segfault happens. + +Change-Id: Ibbb9452f17a576c3a79a53ea72e0211982752144 +Signed-off-by: Kamal Negi +--- + profiles/audio/avrcp.c | 27 ++++++++++++++++++++++----- + 1 file changed, 22 insertions(+), 5 deletions(-) + +diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c +index c100149acf42..d8cb0ed96a1f 100644 +--- a/profiles/audio/avrcp.c ++++ b/profiles/audio/avrcp.c +@@ -2082,13 +2082,19 @@ static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, + void *user_data) + { + struct avrcp *session = user_data; +- struct avrcp_player *player = session->controller->player; +- struct media_player *mp = player->user_data; ++ struct avrcp_player *player; ++ struct media_player *mp; + struct avrcp_header *pdu = (void *) operands; + uint32_t duration; + uint32_t position; + uint8_t status; + ++ if (!session || !session->controller) ++ return FALSE; ++ ++ player = session->controller->player; ++ mp = player->user_data; ++ + if (pdu == NULL || code == AVC_CTYPE_REJECTED || + ntohs(pdu->params_len) != 9) + return FALSE; +@@ -2146,12 +2152,18 @@ static gboolean avrcp_player_value_rsp(struct avctp *conn, uint8_t code, + void *user_data) + { + struct avrcp *session = user_data; +- struct avrcp_player *player = session->controller->player; +- struct media_player *mp = player->user_data; ++ struct avrcp_player *player; ++ struct media_player *mp; + struct avrcp_header *pdu = (void *) operands; + uint8_t count; + int i; + ++ if (!session || !session->controller) ++ return FALSE; ++ ++ player = session->controller->player; ++ mp = player->user_data; ++ + if (pdu == NULL) { + media_player_set_setting(mp, "Error", "Timeout"); + return FALSE; +@@ -2303,10 +2315,15 @@ static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn, + void *user_data) + { + struct avrcp *session = user_data; +- struct avrcp_player *player = session->controller->player; ++ struct avrcp_player *player; + struct avrcp_header *pdu = (void *) operands; + uint8_t count; + ++ if (!session || !session->controller) ++ return FALSE; ++ ++ player = session->controller->player; ++ + if (code == AVC_CTYPE_REJECTED) + return FALSE; + diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch deleted file mode 100644 index 1537e2bbb..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch +++ /dev/null @@ -1,2068 +0,0 @@ -From: Anantha Krishnan -Date: Tue, 19 Aug 2014 20:23:01 +0530 -Subject: [PATCH] bluetooth : Add bluetooth support for QCA6174 chip. - -Register the QCA6174 initialization routine with hciattach for -downloading firmware patches to the bluetooth controller. -Add optional support 'f' to control installation of line -discipline driver. Invoke hciattach from command line and -download the firmware patches: - hciattach /dev/ttyHS0 qca 3000000 -t120 flow -f0 - -Change-Id: I87f2927d7096904071a02d73d3afef0dc34db414 -Signed-off-by: Rupesh Tatiya ---- - Makefile.tools | 3 +- - tools/hciattach.c | 25 +- - tools/hciattach.h | 8 +- - tools/hciattach_rome.c | 1578 ++++++++++++++++++++++++++++++++++++++++++++++++ - tools/hciattach_rome.h | 317 ++++++++++ - 5 files changed, 1926 insertions(+), 5 deletions(-) - create mode 100644 tools/hciattach_rome.c - create mode 100644 tools/hciattach_rome.h - -diff --git a/Makefile.tools b/Makefile.tools -index 0d5f1431e013..8f087c597490 100644 ---- a/Makefile.tools -+++ b/Makefile.tools -@@ -164,7 +164,8 @@ tools_hciattach_SOURCES = tools/hciattach.c tools/hciattach.h \ - tools/hciattach_ath3k.c \ - tools/hciattach_qualcomm.c \ - tools/hciattach_intel.c \ -- tools/hciattach_bcm43xx.c -+ tools/hciattach_bcm43xx.c \ -+ tools/hciattach_rome.c tools/hciattach_rome.h - tools_hciattach_LDADD = lib/libbluetooth-internal.la - - tools_hciconfig_SOURCES = tools/hciconfig.c tools/csr.h tools/csr.c -diff --git a/tools/hciattach.c b/tools/hciattach.c -index fad176c9b804..73811d4c4c2a 100644 ---- a/tools/hciattach.c -+++ b/tools/hciattach.c -@@ -69,6 +69,8 @@ struct uart_t { - #define ENABLE_PM 1 - #define DISABLE_PM 0 - -+int line_disp = 1; -+ - static volatile sig_atomic_t __io_canceled = 0; - - static void sig_hup(int sig) -@@ -263,6 +265,12 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) - return ath3k_post(fd, u->pm); - } - -+static int qca(int fd, struct uart_t *u, struct termios *ti) -+{ -+ fprintf(stderr,"qca\n"); -+ return qca_soc_init(fd, u->bdaddr); -+} -+ - static int qualcomm(int fd, struct uart_t *u, struct termios *ti) - { - return qualcomm_init(fd, u->speed, ti, u->bdaddr); -@@ -1093,6 +1101,10 @@ struct uart_t uart[] = { - { "ath3k", 0x0000, 0x0000, HCI_UART_ATH3K, 115200, 115200, - FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm }, - -+ /* QCA ROME */ -+ { "qca", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, -+ FLOW_CTL, DISABLE_PM, NULL, qca, NULL }, -+ - /* QUALCOMM BTS */ - { "qualcomm", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, - FLOW_CTL, DISABLE_PM, NULL, qualcomm, NULL }, -@@ -1195,6 +1207,7 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw) - goto fail; - } - -+if (line_disp) { - /* Set TTY to N_HCI line discipline */ - i = N_HCI; - if (ioctl(fd, TIOCSETD, &i) < 0) { -@@ -1211,6 +1224,7 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw) - perror("Can't set device"); - goto fail; - } -+} - - if (u->post && u->post(fd, u, &ti) < 0) - goto fail; -@@ -1249,7 +1263,7 @@ int main(int argc, char *argv[]) - printpid = 0; - raw = 0; - -- while ((opt=getopt(argc, argv, "bnpt:s:lr")) != EOF) { -+ while ((opt=getopt(argc, argv, "bnpt:s:lrf:")) != EOF) { - switch(opt) { - case 'b': - send_break = 1; -@@ -1282,6 +1296,11 @@ int main(int argc, char *argv[]) - raw = 1; - break; - -+ case 'f': -+ line_disp = atoi(optarg); -+ fprintf(stderr, "Line_disp val : %d\n", line_disp); -+ break; -+ - default: - usage(); - exit(1); -@@ -1350,6 +1369,7 @@ int main(int argc, char *argv[]) - case 5: - u->bdaddr = argv[optind]; - break; -+ - } - } - -@@ -1426,12 +1446,15 @@ int main(int argc, char *argv[]) - break; - } - -+if (line_disp) { - /* Restore TTY line discipline */ -+ fprintf(stderr, "Restoring the Line Discipline driver\n"); - ld = N_TTY; - if (ioctl(n, TIOCSETD, &ld) < 0) { - perror("Can't restore line discipline"); - exit(1); - } -+} - - return 0; - } -diff --git a/tools/hciattach.h b/tools/hciattach.h -index 4279a3361749..0656a845223c 100644 ---- a/tools/hciattach.h -+++ b/tools/hciattach.h -@@ -39,9 +39,10 @@ - #define HCI_UART_H4DS 3 - #define HCI_UART_LL 4 - #define HCI_UART_ATH3K 5 --#define HCI_UART_INTEL 6 --#define HCI_UART_BCM 7 --#define HCI_UART_QCA 8 -+#define HCI_UART_IBS 6 -+#define HCI_UART_INTEL 7 -+#define HCI_UART_BCM 8 -+#define HCI_UART_QCA 9 - - #define HCI_UART_RAW_DEVICE 0 - #define HCI_UART_RESET_ON_INIT 1 -@@ -63,6 +64,7 @@ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, - struct termios *ti); - int ath3k_post(int fd, int pm); - int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); -+int qca_soc_init(int fd, char *bdaddr); - int intel_init(int fd, int init_speed, int *speed, struct termios *ti); - int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti, - const char *bdaddr); -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -new file mode 100644 -index 000000000000..f31be43c09e4 ---- /dev/null -+++ b/tools/hciattach_rome.c -@@ -0,0 +1,1578 @@ -+/* -+ * -+ * Copyright (c) 2013, The Linux Foundation. All rights reserved. -+ * Not a Contribution. -+ * -+ * Copyright 2012 The Android Open Source Project -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); you -+ * may not use this file except in compliance with the License. You may -+ * obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -+ * implied. See the License for the specific language governing -+ * permissions and limitations under the License. -+ * -+ */ -+ -+/****************************************************************************** -+ * -+ * Filename: hciattach_rome.c -+ * -+ * Description: Contains controller-specific functions, like -+ * firmware patch download -+ * low power mode operations -+ * -+ ******************************************************************************/ -+ -+#define LOG_TAG "bt_vendor" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "hciattach_rome.h" -+#include "hciattach.h" -+ -+#ifdef __cplusplus -+} -+#endif -+ -+ -+/****************************************************************************** -+** Variables -+******************************************************************************/ -+FILE *file; -+unsigned char *phdr_buffer; -+unsigned char *pdata_buffer = NULL; -+patch_info rampatch_patch_info; -+int rome_ver = ROME_VER_UNKNOWN; -+unsigned char gTlv_type; -+char *rampatch_file_path; -+char *nvm_file_path; -+vnd_userial_cb_t vnd_userial; -+/****************************************************************************** -+** Extern variables -+******************************************************************************/ -+//extern unsigned char vnd_local_bd_addr[6]; -+ -+/***************************************************************************** -+** Functions -+*****************************************************************************/ -+ -+/******************************************************************************* -+** -+** Function userial_to_tcio_baud -+** -+** Description helper function converts USERIAL baud rates into TCIO -+** conforming baud rates -+** -+** Returns TRUE/FALSE -+** -+*******************************************************************************/ -+unsigned char userial_to_tcio_baud(unsigned char cfg_baud, unsigned int *baud) -+{ -+ if (cfg_baud == USERIAL_BAUD_115200) -+ *baud = B115200; -+ else if (cfg_baud == USERIAL_BAUD_4M) -+ *baud = B4000000; -+ else if (cfg_baud == USERIAL_BAUD_3M) -+ *baud = B3000000; -+ else if (cfg_baud == USERIAL_BAUD_2M) -+ *baud = B2000000; -+ else if (cfg_baud == USERIAL_BAUD_1M) -+ *baud = B1000000; -+ else if (cfg_baud == USERIAL_BAUD_921600) -+ *baud = B921600; -+ else if (cfg_baud == USERIAL_BAUD_460800) -+ *baud = B460800; -+ else if (cfg_baud == USERIAL_BAUD_230400) -+ *baud = B230400; -+ else if (cfg_baud == USERIAL_BAUD_57600) -+ *baud = B57600; -+ else if (cfg_baud == USERIAL_BAUD_19200) -+ *baud = B19200; -+ else if (cfg_baud == USERIAL_BAUD_9600) -+ *baud = B9600; -+ else if (cfg_baud == USERIAL_BAUD_1200) -+ *baud = B1200; -+ else if (cfg_baud == USERIAL_BAUD_600) -+ *baud = B600; -+ else -+ { -+ fprintf(stderr, "userial vendor open: unsupported baud idx %i\n", cfg_baud); -+ *baud = B115200; -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+ -+/******************************************************************************* -+** -+** Function userial_vendor_set_baud -+** -+** Description Set new baud rate -+** -+** Returns None -+** -+*******************************************************************************/ -+void userial_vendor_set_baud(unsigned char userial_baud) -+{ -+ unsigned int tcio_baud; -+ fprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); -+ -+ userial_to_tcio_baud(userial_baud, &tcio_baud); -+ -+ cfsetospeed(&vnd_userial.termios, tcio_baud); -+ cfsetispeed(&vnd_userial.termios, tcio_baud); -+ tcsetattr(vnd_userial.fd, TCSADRAIN, &vnd_userial.termios); /* don't change speed until last write done */ -+ -+} -+ -+ -+/******************************************************************************* -+** -+** Function userial_vendor_ioctl -+** -+** Description ioctl inteface -+** -+** Returns None -+** -+*******************************************************************************/ -+int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) -+{ -+ int err = -1; -+ struct termios ti; -+ -+ if (tcgetattr(fd, &ti) < 0) { -+ perror("Can't get port settings"); -+ return -1; -+ } -+ cfmakeraw(&ti); -+ ti.c_cflag |= CLOCAL; -+ -+ switch(op) -+ { -+#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) -+ case USERIAL_OP_ASSERT_BT_WAKE: -+ VNDUSERIALDBG("## userial_vendor_ioctl: Asserting BT_Wake ##"); -+ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL); -+ break; -+ -+ case USERIAL_OP_DEASSERT_BT_WAKE: -+ VNDUSERIALDBG("## userial_vendor_ioctl: De-asserting BT_Wake ##"); -+ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL); -+ break; -+ -+ case USERIAL_OP_GET_BT_WAKE_STATE: -+ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_GET_ST, p_data); -+ break; -+#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) -+ case USERIAL_OP_FLOW_ON: -+ fprintf(stderr, "## userial_vendor_ioctl: UART Flow On\n "); -+ ti.c_cflag |= CRTSCTS; -+ -+ if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { -+ perror("Can't set port settings"); -+ return -1; -+ } -+ -+ break; -+ -+ case USERIAL_OP_FLOW_OFF: -+ fprintf(stderr, "## userial_vendor_ioctl: UART Flow Off\n "); -+ ti.c_cflag &= ~CRTSCTS; -+ if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { -+ fprintf(stderr, "Can't set port settings"); -+ return -1; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ return err; -+} -+ -+ -+int get_vs_hci_event(unsigned char *rsp) -+{ -+ int err = 0, soc_id =0; -+ unsigned char paramlen = 0; -+ -+ if( (rsp[EVENTCODE_OFFSET] == VSEVENT_CODE) || (rsp[EVENTCODE_OFFSET] == EVT_CMD_COMPLETE)) -+ fprintf(stderr, "%s: Received HCI-Vendor Specific event\n", __FUNCTION__); -+ else { -+ fprintf(stderr, "%s: Failed to receive HCI-Vendor Specific event\n", __FUNCTION__); -+ err = -EIO; -+ goto failed; -+ } -+ -+ fprintf(stderr, "%s: Parameter Length: 0x%x\n", __FUNCTION__, paramlen = rsp[EVT_PLEN]); -+ fprintf(stderr, "%s: Command response: 0x%x\n", __FUNCTION__, rsp[CMD_RSP_OFFSET]); -+ fprintf(stderr, "%s: Response type : 0x%x\n", __FUNCTION__, rsp[RSP_TYPE_OFFSET]); -+ -+ /* Check the status of the operation */ -+ switch ( rsp[CMD_RSP_OFFSET] ) -+ { -+ case EDL_CMD_REQ_RES_EVT: -+ fprintf(stderr, "%s: Command Request Response\n", __FUNCTION__); -+ switch(rsp[RSP_TYPE_OFFSET]) -+ { -+ case EDL_PATCH_VER_RES_EVT: -+ case EDL_APP_VER_RES_EVT: -+ fprintf(stderr, "\t Current Product ID\t\t: 0x%08x\n", -+ (unsigned int)(rsp[PATCH_PROD_ID_OFFSET +3] << 24 | -+ rsp[PATCH_PROD_ID_OFFSET+2] << 16 | -+ rsp[PATCH_PROD_ID_OFFSET+1] << 8 | -+ rsp[PATCH_PROD_ID_OFFSET] )); -+ -+ /* Patch Version indicates FW patch version */ -+ fprintf(stderr, "\t Current Patch Version\t\t: 0x%04x\n", -+ (unsigned short)(rsp[PATCH_PATCH_VER_OFFSET + 1] << 8 | -+ rsp[PATCH_PATCH_VER_OFFSET] )); -+ -+ /* ROM Build Version indicates ROM build version like 1.0/1.1/2.0 */ -+ fprintf(stderr, "\t Current ROM Build Version\t: 0x%04x\n", rome_ver = -+ (int)(rsp[PATCH_ROM_BUILD_VER_OFFSET + 1] << 8 | -+ rsp[PATCH_ROM_BUILD_VER_OFFSET] )); -+ -+ /* In case rome 1.0/1.1, there is no SOC ID version available */ -+ if (paramlen - 10) -+ { -+ fprintf(stderr, "\t Current SOC Version\t\t: 0x%08x\n", soc_id = -+ (unsigned int)(rsp[PATCH_SOC_VER_OFFSET +3] << 24 | -+ rsp[PATCH_SOC_VER_OFFSET+2] << 16 | -+ rsp[PATCH_SOC_VER_OFFSET+1] << 8 | -+ rsp[PATCH_SOC_VER_OFFSET] )); -+ } -+ -+ /* Rome Chipset Version can be decided by Patch version and SOC version, -+ Upper 2 bytes will be used for Patch version and Lower 2 bytes will be -+ used for SOC as combination for BT host driver */ -+ rome_ver = (rome_ver << 16) | (soc_id & 0x0000ffff); -+ break; -+ case EDL_TVL_DNLD_RES_EVT: -+ case EDL_CMD_EXE_STATUS_EVT: -+ switch (err = rsp[CMD_STATUS_OFFSET]) -+ { -+ case HCI_CMD_SUCCESS: -+ fprintf(stderr, "%s: Download Packet successfully!\n", __FUNCTION__); -+ break; -+ case PATCH_LEN_ERROR: -+ fprintf(stderr, "%s: Invalid patch length argument passed for EDL PATCH " -+ "SET REQ cmd\n", __FUNCTION__); -+ break; -+ case PATCH_VER_ERROR: -+ fprintf(stderr, "%s: Invalid patch version argument passed for EDL PATCH " -+ "SET REQ cmd\n", __FUNCTION__); -+ break; -+ case PATCH_CRC_ERROR: -+ fprintf(stderr, "%s: CRC check of patch failed!!!\n", __FUNCTION__); -+ break; -+ case PATCH_NOT_FOUND: -+ fprintf(stderr, "%s: Invalid patch data!!!\n", __FUNCTION__); -+ break; -+ case TLV_TYPE_ERROR: -+ fprintf(stderr, "%s: TLV Type Error !!!\n", __FUNCTION__); -+ break; -+ default: -+ fprintf(stderr, "%s: Undefined error (0x%x)", __FUNCTION__, err); -+ break; -+ } -+ break; -+ } -+ break; -+ -+ case NVM_ACCESS_CODE: -+ fprintf(stderr, "%s: NVM Access Code!!!\n", __FUNCTION__); -+ err = HCI_CMD_SUCCESS; -+ break; -+ case EDL_SET_BAUDRATE_RSP_EVT: -+ /* Rome 1.1 has bug with the response, so it should ignore it. */ -+ if (rsp[BAUDRATE_RSP_STATUS_OFFSET] != BAUDRATE_CHANGE_SUCCESS) -+ { -+ fprintf(stderr, "%s: Set Baudrate request failed - 0x%x\n", __FUNCTION__, -+ rsp[CMD_STATUS_OFFSET]); -+ err = -1; -+ } -+ break; -+ default: -+ fprintf(stderr, "%s: Not a valid status!!!\n", __FUNCTION__); -+ err = -1; -+ break; -+ } -+ -+failed: -+ return err; -+} -+ -+ -+/* -+ * Read an VS HCI event from the given file descriptor. -+ */ -+int read_vs_hci_event(int fd, unsigned char* buf, int size) -+{ -+ int remain, r; -+ int count = 0; -+ -+ if (size <= 0) { -+ fprintf(stderr, "Invalid size arguement!\n"); -+ return -1; -+ } -+ -+ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); -+ -+ /* The first byte identifies the packet type. For HCI event packets, it -+ * should be 0x04, so we read until we get to the 0x04. */ -+ /* It will keep reading until find 0x04 byte */ -+ while (1) { -+ r = read(fd, buf, 1); -+ if (r <= 0) -+ return -1; -+ if (buf[0] == 0x04) -+ break; -+ } -+ count++; -+ -+ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[0] - 0x%x\n", __FUNCTION__, buf[0]); -+ /* The next two bytes are the event code and parameter total length. */ -+ while (count < 3) { -+ r = read(fd, buf + count, 3 - count); -+ if ((r <= 0) || (buf[1] != 0xFF )) { -+ fprintf(stderr, "It is not VS event !!\n"); -+ return -1; -+ } -+ count += r; -+ } -+ -+ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[1] - 0x%x\n", __FUNCTION__, buf[1]); -+ /* Now we read the parameters. */ -+ if (buf[2] < (size - 3)) -+ remain = buf[2]; -+ else -+ remain = size - 3; -+ -+ while ((count - 3) < remain) { -+ r = read(fd, buf + count, remain - (count - 3)); -+ if (r <= 0) -+ return -1; -+ count += r; -+ } -+ -+ /* Check if the set patch command is successful or not */ -+ if(get_vs_hci_event(buf) != HCI_CMD_SUCCESS) -+ return -1; -+ -+ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, count - 0x%x\n", __FUNCTION__, count); -+ return count; -+} -+ -+ -+int hci_send_vs_cmd(int fd, unsigned char *cmd, unsigned char *rsp, int size) -+{ -+ int ret = 0; -+ -+ /* Send the HCI command packet to UART for transmission */ -+ ret = write(fd, cmd, size); -+ if (ret != size) { -+ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, ret); -+ goto failed; -+ } -+ -+ /* Check for response from the Controller */ -+ if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { -+ ret = -ETIMEDOUT; -+ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -+ goto failed; -+ } -+ -+ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); -+failed: -+ return ret; -+} -+ -+void frame_hci_cmd_pkt( -+ unsigned char *cmd, -+ int edl_cmd, unsigned int p_base_addr, -+ int segtNo, int size -+ ) -+{ -+ int offset = 0; -+ hci_command_hdr *cmd_hdr; -+ -+ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); -+ -+ cmd_hdr = (void *) (cmd + 1); -+ -+ cmd[0] = HCI_COMMAND_PKT; -+ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, HCI_PATCH_CMD_OCF); -+ cmd_hdr->plen = size; -+ cmd[4] = edl_cmd; -+ -+ switch (edl_cmd) -+ { -+ case EDL_PATCH_SET_REQ_CMD: -+ /* Copy the patch header info as CMD params */ -+ memcpy(&cmd[5], phdr_buffer, PATCH_HDR_LEN); -+ fprintf(stderr, "%s: Sending EDL_PATCH_SET_REQ_CMD\n", __FUNCTION__); -+ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", -+ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); -+ break; -+ case EDL_PATCH_DLD_REQ_CMD: -+ offset = ((segtNo - 1) * MAX_DATA_PER_SEGMENT); -+ p_base_addr += offset; -+ cmd_hdr->plen = (size + 6); -+ cmd[5] = (size + 4); -+ cmd[6] = EXTRACT_BYTE(p_base_addr, 0); -+ cmd[7] = EXTRACT_BYTE(p_base_addr, 1); -+ cmd[8] = EXTRACT_BYTE(p_base_addr, 2); -+ cmd[9] = EXTRACT_BYTE(p_base_addr, 3); -+ memcpy(&cmd[10], (pdata_buffer + offset), size); -+ -+ fprintf(stderr, "%s: Sending EDL_PATCH_DLD_REQ_CMD: size: %d bytes\n", -+ __FUNCTION__, size); -+ fprintf(stderr, "HCI-CMD %d:\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t" -+ "0x%x\t0x%x\t0x%x\t\n", segtNo, cmd[0], cmd[1], cmd[2], -+ cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]); -+ break; -+ case EDL_PATCH_ATCH_REQ_CMD: -+ fprintf(stderr, "%s: Sending EDL_PATCH_ATTACH_REQ_CMD\n", __FUNCTION__); -+ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", -+ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); -+ break; -+ case EDL_PATCH_RST_REQ_CMD: -+ fprintf(stderr, "%s: Sending EDL_PATCH_RESET_REQ_CMD\n", __FUNCTION__); -+ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", -+ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); -+ break; -+ case EDL_PATCH_VER_REQ_CMD: -+ fprintf(stderr, "%s: Sending EDL_PATCH_VER_REQ_CMD\n", __FUNCTION__); -+ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", -+ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); -+ break; -+ case EDL_PATCH_TLV_REQ_CMD: -+ fprintf(stderr, "%s: Sending EDL_PATCH_TLV_REQ_CMD\n", __FUNCTION__); -+ /* Parameter Total Length */ -+ cmd[3] = size +2; -+ -+ /* TLV Segment Length */ -+ cmd[5] = size; -+ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", -+ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]); -+ offset = (segtNo * MAX_SIZE_PER_TLV_SEGMENT); -+ memcpy(&cmd[6], (pdata_buffer + offset), size); -+ break; -+ default: -+ fprintf(stderr, "%s: Unknown EDL CMD !!!\n", __FUNCTION__); -+ } -+} -+ -+void rome_extract_patch_header_info(unsigned char *buf) -+{ -+ int index; -+ -+ /* Extract patch id */ -+ for (index = 0; index < 4; index++) -+ rampatch_patch_info.patch_id |= -+ (LSH(buf[index + P_ID_OFFSET], (index * 8))); -+ -+ /* Extract (ROM and BUILD) version information */ -+ for (index = 0; index < 2; index++) -+ rampatch_patch_info.patch_ver.rom_version |= -+ (LSH(buf[index + P_ROME_VER_OFFSET], (index * 8))); -+ -+ for (index = 0; index < 2; index++) -+ rampatch_patch_info.patch_ver.build_version |= -+ (LSH(buf[index + P_BUILD_VER_OFFSET], (index * 8))); -+ -+ /* Extract patch base and entry addresses */ -+ for (index = 0; index < 4; index++) -+ rampatch_patch_info.patch_base_addr |= -+ (LSH(buf[index + P_BASE_ADDR_OFFSET], (index * 8))); -+ -+ /* Patch BASE & ENTRY addresses are same */ -+ rampatch_patch_info.patch_entry_addr = rampatch_patch_info.patch_base_addr; -+ -+ /* Extract total length of the patch payload */ -+ for (index = 0; index < 4; index++) -+ rampatch_patch_info.patch_length |= -+ (LSH(buf[index + P_LEN_OFFSET], (index * 8))); -+ -+ /* Extract the CRC checksum of the patch payload */ -+ for (index = 0; index < 4; index++) -+ rampatch_patch_info.patch_crc |= -+ (LSH(buf[index + P_CRC_OFFSET], (index * 8))); -+ -+ /* Extract patch control value */ -+ for (index = 0; index < 4; index++) -+ rampatch_patch_info.patch_ctrl |= -+ (LSH(buf[index + P_CONTROL_OFFSET], (index * 8))); -+ -+ fprintf(stderr, "PATCH_ID\t : 0x%x\n", rampatch_patch_info.patch_id); -+ fprintf(stderr, "ROM_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.rom_version); -+ fprintf(stderr, "BUILD_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.build_version); -+ fprintf(stderr, "PATCH_LENGTH\t : 0x%x\n", rampatch_patch_info.patch_length); -+ fprintf(stderr, "PATCH_CRC\t : 0x%x\n", rampatch_patch_info.patch_crc); -+ fprintf(stderr, "PATCH_CONTROL\t : 0x%x\n", rampatch_patch_info.patch_ctrl); -+ fprintf(stderr, "PATCH_BASE_ADDR\t : 0x%x\n", rampatch_patch_info.patch_base_addr); -+ -+} -+ -+int rome_edl_set_patch_request(int fd) -+{ -+ int size, err; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ -+ /* Frame the HCI CMD to be sent to the Controller */ -+ frame_hci_cmd_pkt(cmd, EDL_PATCH_SET_REQ_CMD, 0, -+ -1, PATCH_HDR_LEN + 1); -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ -+ /* Send HCI Command packet to Controller */ -+ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -+ if ( err != size) { -+ fprintf(stderr, "Failed to set the patch info to the Controller!\n"); -+ goto error; -+ } -+ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s: Successfully set patch info on the Controller\n", __FUNCTION__); -+error: -+ return err; -+} -+ -+int rome_edl_patch_download_request(int fd) -+{ -+ int no_of_patch_segment; -+ int index = 1, err = 0, size = 0; -+ unsigned int p_base_addr; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ -+ no_of_patch_segment = (rampatch_patch_info.patch_length / -+ MAX_DATA_PER_SEGMENT); -+ fprintf(stderr, "%s: %d patch segments to be d'loaded from patch base addr: 0x%x\n", -+ __FUNCTION__, no_of_patch_segment, -+ rampatch_patch_info.patch_base_addr); -+ -+ /* Initialize the patch base address from the one read from bin file */ -+ p_base_addr = rampatch_patch_info.patch_base_addr; -+ -+ /* -+ * Depending upon size of the patch payload, download the patches in -+ * segments with a max. size of 239 bytes -+ */ -+ for (index = 1; index <= no_of_patch_segment; index++) { -+ -+ fprintf(stderr, "%s: Downloading patch segment: %d\n", __FUNCTION__, index); -+ -+ /* Frame the HCI CMD PKT to be sent to Controller*/ -+ frame_hci_cmd_pkt(cmd, EDL_PATCH_DLD_REQ_CMD, p_base_addr, -+ index, MAX_DATA_PER_SEGMENT); -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ -+ /* Initialize the RSP packet everytime to 0 */ -+ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); -+ -+ /* Send HCI Command packet to Controller */ -+ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -+ if ( err != size) { -+ fprintf(stderr, "Failed to send the patch payload to the Controller!\n"); -+ goto error; -+ } -+ -+ /* Read Command Complete Event */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", -+ __FUNCTION__, index); -+ goto error; -+ } -+ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", -+ __FUNCTION__, index); -+ } -+ -+ /* Check if any pending patch data to be sent */ -+ size = (rampatch_patch_info.patch_length < MAX_DATA_PER_SEGMENT) ? -+ rampatch_patch_info.patch_length : -+ (rampatch_patch_info.patch_length % MAX_DATA_PER_SEGMENT); -+ -+ if (size) -+ { -+ /* Frame the HCI CMD PKT to be sent to Controller*/ -+ frame_hci_cmd_pkt(cmd, EDL_PATCH_DLD_REQ_CMD, p_base_addr, index, size); -+ -+ /* Initialize the RSP packet everytime to 0 */ -+ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ -+ /* Send HCI Command packet to Controller */ -+ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -+ if ( err != size) { -+ fprintf(stderr, "Failed to send the patch payload to the Controller!\n"); -+ goto error; -+ } -+ -+ /* Read Command Complete Event */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", -+ __FUNCTION__, index); -+ goto error; -+ } -+ -+ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", -+ __FUNCTION__, index); -+ } -+ -+error: -+ return err; -+} -+ -+static int rome_download_rampatch(int fd) -+{ -+ int c, size, index, ret = -1; -+ -+ fprintf(stderr, "%s:\n", __FUNCTION__); -+ -+ /* Get handle to the RAMPATCH binary file */ -+ fprintf(stderr, "%s: Getting handle to the RAMPATCH binary file from %s\n", __FUNCTION__, ROME_FW_PATH); -+ file = fopen(ROME_FW_PATH, "r"); -+ if (file == NULL) { -+ fprintf(stderr, "%s: Failed to get handle to the RAMPATCH bin file!\n", -+ __FUNCTION__); -+ return -ENFILE; -+ } -+ -+ /* Allocate memory for the patch headder info */ -+ fprintf(stderr, "%s: Allocating memory for the patch header\n", __FUNCTION__); -+ phdr_buffer = (unsigned char *) malloc(PATCH_HDR_LEN + 1); -+ if (phdr_buffer == NULL) { -+ fprintf(stderr, "%s: Failed to allocate memory for patch header\n", -+ __FUNCTION__); -+ goto phdr_alloc_failed; -+ } -+ for (index = 0; index < PATCH_HDR_LEN + 1; index++) -+ phdr_buffer[index] = 0x0; -+ -+ /* Read 28 bytes of patch header information */ -+ fprintf(stderr, "%s: Reading patch header info\n", __FUNCTION__); -+ index = 0; -+ do { -+ c = fgetc (file); -+ phdr_buffer[index++] = (unsigned char)c; -+ } while (index != PATCH_HDR_LEN); -+ -+ /* Save the patch header info into local structure */ -+ fprintf(stderr, "%s: Saving patch hdr. info\n", __FUNCTION__); -+ rome_extract_patch_header_info((unsigned char *)phdr_buffer); -+ -+ /* Set the patch header info onto the Controller */ -+ ret = rome_edl_set_patch_request(fd); -+ if (ret < 0) { -+ fprintf(stderr, "%s: Error setting the patchheader info!\n", __FUNCTION__); -+ goto pdata_alloc_failed; -+ } -+ -+ /* Allocate memory for the patch payload */ -+ fprintf(stderr, "%s: Allocating memory for patch payload\n", __FUNCTION__); -+ size = rampatch_patch_info.patch_length; -+ pdata_buffer = (unsigned char *) malloc(size+1); -+ if (pdata_buffer == NULL) { -+ fprintf(stderr, "%s: Failed to allocate memory for patch payload\n", -+ __FUNCTION__); -+ goto pdata_alloc_failed; -+ } -+ for (index = 0; index < size+1; index++) -+ pdata_buffer[index] = 0x0; -+ -+ /* Read the patch data from Rampatch binary image */ -+ fprintf(stderr, "%s: Reading patch payload from RAMPATCH file\n", __FUNCTION__); -+ index = 0; -+ do { -+ c = fgetc (file); -+ pdata_buffer[index++] = (unsigned char)c; -+ } while (c != EOF); -+ -+ /* Downloading patches in segments to controller */ -+ ret = rome_edl_patch_download_request(fd); -+ if (ret < 0) { -+ fprintf(stderr, "%s: Error downloading patch segments!\n", __FUNCTION__); -+ goto cleanup; -+ } -+cleanup: -+ free(pdata_buffer); -+pdata_alloc_failed: -+ free(phdr_buffer); -+phdr_alloc_failed: -+ fclose(file); -+ -+ return ret; -+} -+ -+int rome_attach_rampatch(int fd) -+{ -+ int size, err; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ -+ /* Frame the HCI CMD to be sent to the Controller */ -+ frame_hci_cmd_pkt(cmd, EDL_PATCH_ATCH_REQ_CMD, 0, -+ -1, EDL_PATCH_CMD_LEN); -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ -+ /* Send HCI Command packet to Controller */ -+ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -+ if ( err != size) { -+ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); -+ goto error; -+ } -+ -+ /* Read Command Complete Event */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to attach the patch segment(s)\n", __FUNCTION__); -+ goto error; -+ } -+error: -+ return err; -+} -+ -+int rome_rampatch_reset(int fd) -+{ -+ int size, err = 0; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ struct timespec tm = { 0, 100*1000*1000 }; /* 100 ms */ -+ -+ /* Frame the HCI CMD to be sent to the Controller */ -+ frame_hci_cmd_pkt(cmd, EDL_PATCH_RST_REQ_CMD, 0, -+ -1, EDL_PATCH_CMD_LEN); -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); -+ -+ /* Send HCI Command packet to Controller */ -+ err = write(fd, cmd, size); -+ if (err != size) { -+ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); -+ goto error; -+ } -+ -+ /* -+ * Controller doesn't sends any response for the patch reset -+ * command. HOST has to wait for 100ms before proceeding. -+ */ -+ nanosleep(&tm, NULL); -+ -+error: -+ return err; -+} -+ -+int rome_get_tlv_file(char *file_path) -+{ -+ FILE * pFile; -+ long fileSize; -+ int readSize, nvm_length, nvm_index, i; -+ unsigned short nvm_tag_len; -+ tlv_patch_info *ptlv_header; -+ tlv_nvm_hdr *nvm_ptr; -+ unsigned char data_buf[PRINT_BUF_SIZE]={0,}; -+ unsigned char *nvm_byte_ptr; -+ -+ fprintf(stderr, "File Open (%s)\n", file_path); -+ pFile = fopen ( file_path , "r" ); -+ if (pFile==NULL) {; -+ fprintf(stderr, "%s File Open Fail\n", file_path); -+ return -1; -+ } -+ -+ /* Get File Size */ -+ fseek (pFile , 0 , SEEK_END); -+ fileSize = ftell (pFile); -+ rewind (pFile); -+ -+ pdata_buffer = (unsigned char*) malloc (sizeof(char)*fileSize); -+ if (pdata_buffer == NULL) { -+ fprintf(stderr, "Allocated Memory failed\n"); -+ fclose (pFile); -+ return -1; -+ } -+ -+ /* Copy file into allocated buffer */ -+ readSize = fread (pdata_buffer,1,fileSize,pFile); -+ -+ /* File Close */ -+ fclose (pFile); -+ -+ if (readSize != fileSize) { -+ fprintf(stderr, "Read file size(%d) not matched with actual file size (%ld bytes)\n",readSize,fileSize); -+ return -1; -+ } -+ -+ ptlv_header = (tlv_patch_info *) pdata_buffer; -+ -+ /* To handle different event between rampatch and NVM */ -+ gTlv_type = ptlv_header->tlv_type; -+ -+ if(ptlv_header->tlv_type == TLV_TYPE_PATCH){ -+ fprintf(stderr, "====================================================\n"); -+ fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); -+ fprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | -+ (ptlv_header->tlv_length2 << 8) | -+ (ptlv_header->tlv_length3 << 16)); -+ fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv_data_len); -+ fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv_patch_data_len); -+ fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); -+ fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); -+ fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); -+ fprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); -+ fprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); -+ fprintf(stderr, "Patch Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.patch_ver); -+ fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved2); -+ fprintf(stderr, "Patch Entry Address\t\t : 0x%x\n", (ptlv_header->tlv.patch.patch_entry_addr)); -+ fprintf(stderr, "====================================================\n"); -+ -+ } else if(ptlv_header->tlv_type == TLV_TYPE_NVM) { -+ fprintf(stderr, "====================================================\n"); -+ fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); -+ fprintf(stderr, "Length\t\t\t : %d bytes\n", nvm_length = (ptlv_header->tlv_length1) | -+ (ptlv_header->tlv_length2 << 8) | -+ (ptlv_header->tlv_length3 << 16)); -+ -+ if(nvm_length <= 0) -+ return readSize; -+ -+ for(nvm_byte_ptr=(unsigned char *)(nvm_ptr = &(ptlv_header->tlv.nvm)), nvm_index=0; -+ nvm_index < nvm_length ; nvm_ptr = (tlv_nvm_hdr *) nvm_byte_ptr) -+ { -+ fprintf(stderr, "TAG ID\t\t\t : %d\n", nvm_ptr->tag_id); -+ fprintf(stderr, "TAG Length\t\t\t : %d\n", nvm_tag_len = nvm_ptr->tag_len); -+ fprintf(stderr, "TAG Pointer\t\t\t : %d\n", nvm_ptr->tag_ptr); -+ fprintf(stderr, "TAG Extended Flag\t\t : %d\n", nvm_ptr->tag_ex_flag); -+ -+ /* Increase nvm_index to NVM data */ -+ nvm_index+=sizeof(tlv_nvm_hdr); -+ nvm_byte_ptr+=sizeof(tlv_nvm_hdr); -+ -+ /* Write BD Address */ -+ if(nvm_ptr->tag_id == TAG_NUM_2){ -+ memcpy(nvm_byte_ptr, vnd_local_bd_addr, 6); -+ fprintf(stderr, "BD Address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", -+ *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), -+ *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); -+ } -+ -+ for(i =0;(itag_len && (i*3 + 2) tag_len; -+ nvm_byte_ptr +=nvm_ptr->tag_len; -+ } -+ -+ fprintf(stderr, "====================================================\n"); -+ -+ } else { -+ fprintf(stderr, "TLV Header type is unknown (%d) \n", ptlv_header->tlv_type); -+ } -+ -+ return readSize; -+} -+ -+int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc_evt) -+{ -+ int size=0, err = -1; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ -+ fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d\n", __FUNCTION__, index, seg_size); -+ -+ /* Frame the HCI CMD PKT to be sent to Controller*/ -+ frame_hci_cmd_pkt(cmd, EDL_PATCH_TLV_REQ_CMD, 0, index, seg_size); -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ -+ /* Initialize the RSP packet everytime to 0 */ -+ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); -+ -+ /* Send HCI Command packet to Controller */ -+ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -+ if ( err != size) { -+ fprintf(stderr, "Failed to send the patch payload to the Controller! 0x%x\n", err); -+ return err; -+ } -+ -+ if(wait_cc_evt) { -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", __FUNCTION__, index); -+ return err; -+ } -+ } -+ -+ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", __FUNCTION__, index); -+ return err; -+} -+ -+int rome_tlv_dnld_req(int fd, int tlv_size) -+{ -+ int total_segment, remain_size, i, err = -1; -+ unsigned char wait_cc_evt; -+ -+ total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; -+ remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\ -+ tlv_size: (tlv_size%MAX_SIZE_PER_TLV_SEGMENT); -+ -+ fprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", -+ __FUNCTION__,tlv_size, total_segment, remain_size); -+ -+ for(i=0;i= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) -+ && !remain_size && ((i+1) == total_segment))? FALSE: TRUE; -+ if((err = rome_tlv_dnld_segment(fd, i, MAX_SIZE_PER_TLV_SEGMENT, wait_cc_evt )) < 0) -+ goto error; -+ } -+ -+ /* In case remain data still remain, last rampatch segment command will not wait -+ for command complete event here */ -+ wait_cc_evt = ((rome_ver >= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) -+ && remain_size )? FALSE:TRUE; -+ -+ if(remain_size) err =rome_tlv_dnld_segment(fd, i, remain_size, wait_cc_evt); -+ -+error: -+ return err; -+} -+ -+int rome_download_tlv_file(int fd) -+{ -+ int tlv_size, err = -1; -+ -+ /* Rampatch TLV file Downloading */ -+ pdata_buffer = NULL; -+ -+ if((tlv_size = rome_get_tlv_file(rampatch_file_path)) < 0) -+ goto error; -+ -+ if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) -+ goto error; -+ -+ if (pdata_buffer != NULL){ -+ free (pdata_buffer); -+ pdata_buffer = NULL; -+ } -+ -+ /* NVM TLV file Downloading */ -+ if((tlv_size = rome_get_tlv_file(nvm_file_path)) < 0) -+ goto error; -+ -+ if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) -+ goto error; -+ -+error: -+ if (pdata_buffer != NULL) -+ free (pdata_buffer); -+ -+ return err; -+} -+ -+int rome_1_0_nvm_tag_dnld(int fd) -+{ -+ int i, size, err = 0; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ -+#if (NVM_VERSION >= ROME_1_0_100019) -+ unsigned char cmds[MAX_TAG_CMD][HCI_MAX_CMD_SIZE] = -+ { -+ /* Tag 2 */ /* BD Address */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 9, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 2, -+ /* Tag Len */ 6, -+ /* Tag Value */ 0x77,0x78,0x23,0x01,0x56,0x22 -+ }, -+ /* Tag 6 */ /* Bluetooth Support Features */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 11, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 6, -+ /* Tag Len */ 8, -+ /* Tag Value */ 0xFF,0xFE,0x8B,0xFE,0xD8,0x3F,0x5B,0x8B -+ }, -+ /* Tag 17 */ /* HCI Transport Layer Setting */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 11, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 17, -+ /* Tag Len */ 8, -+ /* Tag Value */ 0x82,0x01,0x0E,0x08,0x04,0x32,0x0A,0x00 -+ }, -+ /* Tag 35 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 58, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 35, -+ /* Tag Len */ 55, -+ /* Tag Value */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x58, 0x59, -+ 0x0E, 0x0E, 0x16, 0x16, 0x16, 0x1E, 0x26, 0x5F, 0x2F, 0x5F, -+ 0x0E, 0x0E, 0x16, 0x16, 0x16, 0x1E, 0x26, 0x5F, 0x2F, 0x5F, -+ 0x0C, 0x18, 0x14, 0x24, 0x40, 0x4C, 0x70, 0x80, 0x80, 0x80, -+ 0x0C, 0x18, 0x14, 0x24, 0x40, 0x4C, 0x70, 0x80, 0x80, 0x80, -+ 0x1B, 0x14, 0x01, 0x04, 0x48 -+ }, -+ /* Tag 36 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 15, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 36, -+ /* Tag Len */ 12, -+ /* Tag Value */ 0x0F,0x00,0x03,0x03,0x03,0x03,0x00,0x00,0x03,0x03,0x04,0x00 -+ }, -+ /* Tag 39 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 7, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 39, -+ /* Tag Len */ 4, -+ /* Tag Value */ 0x12,0x00,0x00,0x00 -+ }, -+ /* Tag 41 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 91, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 41, -+ /* Tag Len */ 88, -+ /* Tag Value */ 0x15, 0x00, 0x00, 0x00, 0xF6, 0x02, 0x00, 0x00, 0x76, 0x00, -+ 0x1E, 0x00, 0x29, 0x02, 0x1F, 0x00, 0x61, 0x00, 0x1A, 0x00, -+ 0x76, 0x00, 0x1E, 0x00, 0x7D, 0x00, 0x40, 0x00, 0x91, 0x00, -+ 0x06, 0x00, 0x92, 0x00, 0x03, 0x00, 0xA6, 0x01, 0x50, 0x00, -+ 0xAA, 0x01, 0x15, 0x00, 0xAB, 0x01, 0x0A, 0x00, 0xAC, 0x01, -+ 0x00, 0x00, 0xB0, 0x01, 0xC5, 0x00, 0xB3, 0x01, 0x03, 0x00, -+ 0xB4, 0x01, 0x13, 0x00, 0xB5, 0x01, 0x0C, 0x00, 0xC5, 0x01, -+ 0x0D, 0x00, 0xC6, 0x01, 0x10, 0x00, 0xCA, 0x01, 0x2B, 0x00, -+ 0xCB, 0x01, 0x5F, 0x00, 0xCC, 0x01, 0x48, 0x00 -+ }, -+ /* Tag 42 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 63, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 42, -+ /* Tag Len */ 60, -+ /* Tag Value */ 0xD7, 0xC0, 0x00, 0x00, 0x8F, 0x5C, 0x02, 0x00, 0x80, 0x47, -+ 0x60, 0x0C, 0x70, 0x4C, 0x00, 0x00, 0x00, 0x01, 0x1F, 0x01, -+ 0x42, 0x01, 0x69, 0x01, 0x95, 0x01, 0xC7, 0x01, 0xFE, 0x01, -+ 0x3D, 0x02, 0x83, 0x02, 0xD1, 0x02, 0x29, 0x03, 0x00, 0x0A, -+ 0x10, 0x00, 0x1F, 0x00, 0x3F, 0x00, 0x7F, 0x00, 0xFD, 0x00, -+ 0xF9, 0x01, 0xF1, 0x03, 0xDE, 0x07, 0x00, 0x00, 0x9A, 0x01 -+ }, -+ /* Tag 84 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 153, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 84, -+ /* Tag Len */ 150, -+ /* Tag Value */ 0x7C, 0x6A, 0x59, 0x47, 0x19, 0x36, 0x35, 0x25, 0x25, 0x28, -+ 0x2C, 0x2B, 0x2B, 0x28, 0x2C, 0x28, 0x29, 0x28, 0x29, 0x28, -+ 0x29, 0x29, 0x2C, 0x29, 0x2C, 0x29, 0x2C, 0x28, 0x29, 0x28, -+ 0x29, 0x28, 0x29, 0x2A, 0x00, 0x00, 0x2C, 0x2A, 0x2C, 0x18, -+ 0x98, 0x98, 0x98, 0x98, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, -+ 0x1E, 0x13, 0x1E, 0x1E, 0x1E, 0x1E, 0x13, 0x13, 0x11, 0x13, -+ 0x1E, 0x1E, 0x13, 0x12, 0x12, 0x12, 0x11, 0x12, 0x1F, 0x12, -+ 0x12, 0x12, 0x10, 0x0C, 0x18, 0x0D, 0x01, 0x01, 0x01, 0x01, -+ 0x01, 0x01, 0x01, 0x0C, 0x01, 0x01, 0x01, 0x01, 0x0D, 0x0D, -+ 0x0E, 0x0D, 0x01, 0x01, 0x0D, 0x0D, 0x0D, 0x0D, 0x0F, 0x0D, -+ 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x05, 0x10, 0x03, 0x00, -+ 0x7E, 0x7B, 0x7B, 0x72, 0x71, 0x50, 0x50, 0x50, 0x00, 0x40, -+ 0x60, 0x60, 0x30, 0x08, 0x02, 0x0F, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x16, 0x16, 0x08, 0x08, 0x00, -+ 0x00, 0x00, 0x1E, 0x34, 0x2B, 0x1B, 0x23, 0x2B, 0x15, 0x0D -+ }, -+ /* Tag 85 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 119, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 85, -+ /* Tag Len */ 116, -+ /* Tag Value */ 0x03, 0x00, 0x38, 0x00, 0x45, 0x77, 0x00, 0xE8, 0x00, 0x59, -+ 0x01, 0xCA, 0x01, 0x3B, 0x02, 0xAC, 0x02, 0x1D, 0x03, 0x8E, -+ 0x03, 0x00, 0x89, 0x01, 0x0E, 0x02, 0x5C, 0x02, 0xD7, 0x02, -+ 0xF8, 0x08, 0x01, 0x00, 0x1F, 0x00, 0x0A, 0x02, 0x55, 0x02, -+ 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xD7, 0x00, 0x00, -+ 0x00, 0x1E, 0xDE, 0x00, 0x00, 0x00, 0x14, 0x0F, 0x0A, 0x0F, -+ 0x0A, 0x0C, 0x0C, 0x0C, 0x0C, 0x04, 0x04, 0x04, 0x0C, 0x0C, -+ 0x0C, 0x0C, 0x06, 0x06, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, -+ 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, -+ 0x06, 0x0F, 0x14, 0x05, 0x47, 0xCF, 0x77, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0xAC, 0x7C, 0xFF, 0x40, 0x00, 0x00, 0x00, -+ 0x12, 0x04, 0x04, 0x01, 0x04, 0x03 -+ }, -+ {TAG_END} -+ }; -+#elif (NVM_VERSION == ROME_1_0_6002) -+ unsigned char cmds[MAX_TAG_CMD][HCI_MAX_CMD_SIZE] = -+ { -+ /* Tag 2 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 9, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 2, -+ /* Tag Len */ 6, -+ /* Tag Value */ 0x77,0x78,0x23,0x01,0x56,0x22 /* BD Address */ -+ }, -+ /* Tag 6 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 11, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 6, -+ /* Tag Len */ 8, -+ /* Tag Value */ 0xFF,0xFE,0x8B,0xFE,0xD8,0x3F,0x5B,0x8B -+ }, -+ /* Tag 17 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 11, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 17, -+ /* Tag Len */ 8, -+ /* Tag Value */ 0x82,0x01,0x0E,0x08,0x04,0x32,0x0A,0x00 -+ }, -+ /* Tag 36 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 15, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 36, -+ /* Tag Len */ 12, -+ /* Tag Value */ 0x0F,0x00,0x03,0x03,0x03,0x03,0x00,0x00,0x03,0x03,0x04,0x00 -+ }, -+ -+ /* Tag 39 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 7, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 39, -+ /* Tag Len */ 4, -+ /* Tag Value */ 0x12,0x00,0x00,0x00 -+ }, -+ -+ /* Tag 41 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 199, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 41, -+ /* Tag Len */ 196, -+ /* Tag Value */ 0x30,0x00,0x00,0x00,0xD5,0x00,0x0E,0x00,0xD6,0x00,0x0E,0x00, -+ 0xD7,0x00,0x16,0x00,0xD8,0x00,0x16,0x00,0xD9,0x00,0x16,0x00, -+ 0xDA,0x00,0x1E,0x00,0xDB,0x00,0x26,0x00,0xDC,0x00,0x5F,0x00, -+ 0xDD,0x00,0x2F,0x00,0xDE,0x00,0x5F,0x00,0xE0,0x00,0x0E,0x00, -+ 0xE1,0x00,0x0E,0x00,0xE2,0x00,0x16,0x00,0xE3,0x00,0x16,0x00, -+ 0xE4,0x00,0x16,0x00,0xE5,0x00,0x1E,0x00,0xE6,0x00,0x26,0x00, -+ 0xE7,0x00,0x5F,0x00,0xE8,0x00,0x2F,0x00,0xE9,0x00,0x5F,0x00, -+ 0xEC,0x00,0x0C,0x00,0xED,0x00,0x08,0x00,0xEE,0x00,0x14,0x00, -+ 0xEF,0x00,0x24,0x00,0xF0,0x00,0x40,0x00,0xF1,0x00,0x4C,0x00, -+ 0xF2,0x00,0x70,0x00,0xF3,0x00,0x80,0x00,0xF4,0x00,0x80,0x00, -+ 0xF5,0x00,0x80,0x00,0xF8,0x00,0x0C,0x00,0xF9,0x00,0x18,0x00, -+ 0xFA,0x00,0x14,0x00,0xFB,0x00,0x24,0x00,0xFC,0x00,0x40,0x00, -+ 0xFD,0x00,0x4C,0x00,0xFE,0x00,0x70,0x00,0xFF,0x00,0x80,0x00, -+ 0x00,0x01,0x80,0x00,0x01,0x01,0x80,0x00,0x04,0x01,0x1B,0x00, -+ 0x05,0x01,0x14,0x00,0x06,0x01,0x01,0x00,0x07,0x01,0x04,0x00, -+ 0x08,0x01,0x00,0x00,0x09,0x01,0x00,0x00,0x0A,0x01,0x03,0x00, -+ 0x0B,0x01,0x03,0x00 -+ }, -+ -+ /* Tag 44 */ -+ { /* Packet Type */HCI_COMMAND_PKT, -+ /* Opcode */ 0x0b,0xfc, -+ /* Total Len */ 44, -+ /* NVM CMD */ NVM_ACCESS_SET, -+ /* Tag Num */ 44, -+ /* Tag Len */ 41, -+ /* Tag Value */ 0x6F,0x0A,0x00,0x00,0x00,0x00,0x00,0x50,0xFF,0x10,0x02,0x02, -+ 0x01,0x00,0x14,0x01,0x06,0x28,0xA0,0x62,0x03,0x64,0x01,0x01, -+ 0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0xFF,0x10,0x02,0x01, -+ 0x00,0x14,0x01,0x02,0x03 -+ }, -+ {TAG_END} -+ }; -+#endif -+ -+ fprintf(stderr, "%s: Start sending NVM Tags (ver: 0x%x)\n", __FUNCTION__, (unsigned int) NVM_VERSION); -+ -+ for (i=0; (i < MAX_TAG_CMD) && (cmds[i][0] != TAG_END); i++) -+ { -+ /* Write BD Address */ -+ if(cmds[i][TAG_NUM_OFFSET] == TAG_NUM_2){ -+ memcpy(&cmds[i][TAG_BDADDR_OFFSET], vnd_local_bd_addr, 6); -+ fprintf(stderr, "BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", -+ cmds[i][TAG_BDADDR_OFFSET ], cmds[i][TAG_BDADDR_OFFSET + 1], -+ cmds[i][TAG_BDADDR_OFFSET + 2], cmds[i][TAG_BDADDR_OFFSET + 3], -+ cmds[i][TAG_BDADDR_OFFSET + 4], cmds[i][TAG_BDADDR_OFFSET + 5]); -+ } -+ size = cmds[i][3] + HCI_COMMAND_HDR_SIZE + 1; -+ /* Send HCI Command packet to Controller */ -+ err = hci_send_vs_cmd(fd, (unsigned char *)&cmds[i][0], rsp, size); -+ if ( err != size) { -+ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); -+ goto error; -+ } -+ -+ /* Read Command Complete Event - This is extra routine for ROME 1.0. From ROM 2.0, it should be removed. */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to get patch version(s)\n", __FUNCTION__); -+ goto error; -+ } -+ } -+ -+error: -+ return err; -+} -+ -+ -+ -+int rome_patch_ver_req(int fd) -+{ -+ int size, err = 0; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ -+ /* Frame the HCI CMD to be sent to the Controller */ -+ frame_hci_cmd_pkt(cmd, EDL_PATCH_VER_REQ_CMD, 0, -+ -1, EDL_PATCH_CMD_LEN); -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); -+ -+ /* Send HCI Command packet to Controller */ -+ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -+ if ( err != size) { -+ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); -+ goto error; -+ } -+ -+ /* Read Command Complete Event - This is extra routine for ROME 1.0. From ROM 2.0, it should be removed. */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to get patch version(s)\n", __FUNCTION__); -+ goto error; -+ } -+error: -+ return err; -+ -+} -+ -+int rome_disable_sleep(int fd) -+{ -+ int size, err = 0; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ hci_command_hdr *cmd_hdr; -+ int flags; -+ -+ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); -+ -+ cmd_hdr = (void *) (cmd + 1); -+ cmd[0] = HCI_COMMAND_PKT; -+ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, NVM_ACCESS_CODE); -+ cmd_hdr->plen = VSC_DISABLE_IBS_LEN; -+ cmd[4] = 0x01; -+ cmd[5] = 0x1B; -+ cmd[6] = 0x01; -+ cmd[7] = 0x00; -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_DISABLE_IBS_LEN); -+ /* Send the HCI command packet to UART for transmission */ -+ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]) ; -+ err = write(fd, cmd, size); -+ if (err != size) { -+ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); -+ goto error; -+ } -+ -+ /* Check for response from the Controller */ -+ if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { -+ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -+ goto error; -+ } -+ -+ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); -+ -+ /* Wait for command complete event */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s\n", __FUNCTION__); -+error: -+ return err; -+ -+} -+ -+int rome_set_baudrate_req(int fd) -+{ -+ int size, err = 0; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ hci_command_hdr *cmd_hdr; -+ int flags; -+ -+ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); -+ -+ cmd_hdr = (void *) (cmd + 1); -+ cmd[0] = HCI_COMMAND_PKT; -+ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); -+ cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; -+ cmd[4] = BAUDRATE_115200; -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); -+ /* Send the HCI command packet to UART for transmission */ -+ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; -+ err = write(fd, cmd, size); -+ if (err != size) { -+ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); -+ goto error; -+ } -+ -+ /* Check for response from the Controller */ -+ if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { -+ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -+ goto error; -+ } -+ -+ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); -+ -+ /* Wait for command complete event */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s\n", __FUNCTION__); -+error: -+ return err; -+ -+} -+ -+ -+int rome_hci_reset_req(int fd) -+{ -+ int size, err = 0; -+ unsigned char cmd[HCI_MAX_CMD_SIZE]; -+ unsigned char rsp[HCI_MAX_EVENT_SIZE]; -+ hci_command_hdr *cmd_hdr; -+ int flags; -+ -+ fprintf(stderr, "%s: HCI RESET \n", __FUNCTION__); -+ -+ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); -+ -+ cmd_hdr = (void *) (cmd + 1); -+ cmd[0] = HCI_COMMAND_PKT; -+ cmd_hdr->opcode = HCI_RESET; -+ cmd_hdr->plen = 0; -+ -+ /* Total length of the packet to be sent to the Controller */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); -+ -+ /* Send the HCI command packet to UART for transmission */ -+ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); -+ err = write(fd, cmd, size); -+ if (err != size) { -+ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); -+ goto error; -+ } -+ -+ /* Wait for command complete event */ -+ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -+ if ( err < 0) { -+ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); -+ goto error; -+ } -+ -+error: -+ return err; -+ -+} -+ -+ -+int qca_soc_init(int fd, char *bdaddr) -+{ -+ int err = -1; -+ int size; -+ -+ fprintf(stderr, " %s \n", __FUNCTION__); -+ vnd_userial.fd = fd; -+ /* Get Rome version information */ -+ if((err = rome_patch_ver_req(fd)) <0){ -+ fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); -+ goto error; -+ } -+ -+ fprintf(stderr, "%s: Rome Version (0x%08x)\n", __FUNCTION__, rome_ver); -+ -+ switch (rome_ver){ -+ case ROME_VER_1_0: -+ { -+ /* Set and Download the RAMPATCH */ -+ fprintf(stderr, "%s: Setting Patch Header & Downloading Patches\n", __FUNCTION__); -+ err = rome_download_rampatch(fd); -+ if (err < 0) { -+ fprintf(stderr, "%s: DOWNLOAD RAMPATCH failed!\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s: DOWNLOAD RAMPTACH complete\n", __FUNCTION__); -+ -+ /* Attach the RAMPATCH */ -+ fprintf(stderr, "%s: Attaching the patches\n", __FUNCTION__); -+ err = rome_attach_rampatch(fd); -+ if (err < 0) { -+ fprintf(stderr, "%s: ATTACH RAMPATCH failed!\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s: ATTACH RAMPTACH complete\n", __FUNCTION__); -+ -+ /* Send Reset */ -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); -+ err = rome_rampatch_reset(fd); -+ if ( err < 0 ) { -+ fprintf(stderr, "Failed to RESET after RAMPATCH upgrade!\n"); -+ goto error; -+ } -+ -+ /* NVM download */ -+ fprintf(stderr, "%s: Downloading NVM\n", __FUNCTION__); -+ err = rome_1_0_nvm_tag_dnld(fd); -+ if ( err <0 ) { -+ fprintf(stderr, "Downloading NVM Failed !!\n"); -+ goto error; -+ } -+ -+ /* Change baud rate 115.2 kbps to 3Mbps*/ -+ err = rome_hci_reset_req(fd); -+ if ( err <0 ) { -+ fprintf(stderr, "HCI Reset Failed !!\n"); -+ goto error; -+ } -+ -+ fprintf(stderr, "HCI Reset is done\n"); -+ } -+ break; -+ case ROME_VER_1_1: -+ rampatch_file_path = ROME_RAMPATCH_TLV_PATH; -+ nvm_file_path = ROME_NVM_TLV_PATH; -+ goto download; -+ case ROME_VER_1_3: -+ rampatch_file_path = ROME_RAMPATCH_TLV_1_0_3_PATH; -+ nvm_file_path = ROME_NVM_TLV_1_0_3_PATH; -+ goto download; -+ case ROME_VER_2_1: -+ rampatch_file_path = ROME_RAMPATCH_TLV_2_0_1_PATH; -+ nvm_file_path = ROME_NVM_TLV_2_0_1_PATH; -+ goto download; -+ case ROME_VER_3_0: -+ case TUFELLO_VER_1_0: -+ rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; -+ nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; -+ -+download: -+ /* Donwload TLV files (rampatch, NVM) */ -+ err = rome_download_tlv_file(fd); -+ if (err < 0) { -+ fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); -+ -+ /* Change baud rate back to user requested */ -+ fprintf(stderr, "Changing baud rate back from 3M --> 115K\n"); -+ err = rome_set_baudrate_req(fd); -+ if (err < 0) { -+ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); -+ -+ fprintf(stderr, "%s: Disabling In Band Sleep functionality\n", __FUNCTION__); -+ err = rome_disable_sleep(fd); -+ if (err < 0) { -+ fprintf(stderr, "%s: Failed to disable IBS!\n", __FUNCTION__); -+ goto error; -+ } -+ fprintf(stderr, "%s: IBS disabled successfully \n", __FUNCTION__); -+ -+ /* Perform HCI reset here*/ -+ err = rome_hci_reset_req(fd); -+ if ( err <0 ) { -+ fprintf(stderr, "HCI Reset Failed !!!\n"); -+ goto error; -+ } -+ fprintf(stderr, "HCI Reset is done\n"); -+ -+ break; -+ case ROME_VER_UNKNOWN: -+ default: -+ fprintf(stderr, "%s: Detected unknown ROME version\n", __FUNCTION__); -+ err = -1; -+ break; -+ } -+ -+error: -+ return err; -+} -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -new file mode 100644 -index 000000000000..aa59965643ec ---- /dev/null -+++ b/tools/hciattach_rome.h -@@ -0,0 +1,317 @@ -+/* -+ * Copyright 2012 The Android Open Source Project -+ * Copyright (c) 2013, The Linux Foundation. All rights reserved. -+ * Not a Contribution. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+#ifndef HW_ROME_H -+#define HW_ROME_H -+ -+/****************************************************************************** -+** Constants & Macros -+******************************************************************************/ -+#define HCI_MAX_CMD_SIZE 260 -+#define HCI_MAX_EVENT_SIZE 260 -+#define PRINT_BUF_SIZE ((HCI_MAX_CMD_SIZE * 3) + 2) -+/* HCI Command/Event Opcode */ -+#define HCI_RESET 0x0C03 -+#define EVT_CMD_COMPLETE 0x0E -+/* HCI Packet types */ -+#define HCI_COMMAND_PKT 0x01 -+#define HCI_ACLDATA_PKT 0x02 -+#define HCI_SCODATA_PKT 0x03 -+#define HCI_EVENT_PKT 0x04 -+#define HCI_VENDOR_PKT 0xff -+#define cmd_opcode_pack(ogf, ocf) (unsigned short)((ocf & 0x03ff)|(ogf << 10)) -+unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -+typedef enum { -+ USERIAL_OP_FLOW_ON, -+ USERIAL_OP_FLOW_OFF, -+ USERIAL_OP_NOP, -+} userial_vendor_ioctl_op_t; -+ -+ -+/* vendor serial control block */ -+typedef struct -+{ -+ int fd; /* fd to Bluetooth device */ -+ struct termios termios; /* serial terminal of BT port */ -+ char port_name[256]; -+} vnd_userial_cb_t; -+ -+/**** baud rates ****/ -+#define USERIAL_BAUD_300 0 -+#define USERIAL_BAUD_600 1 -+#define USERIAL_BAUD_1200 2 -+#define USERIAL_BAUD_2400 3 -+#define USERIAL_BAUD_9600 4 -+#define USERIAL_BAUD_19200 5 -+#define USERIAL_BAUD_57600 6 -+#define USERIAL_BAUD_115200 7 -+#define USERIAL_BAUD_230400 8 -+#define USERIAL_BAUD_460800 9 -+#define USERIAL_BAUD_921600 10 -+#define USERIAL_BAUD_1M 11 -+#define USERIAL_BAUD_1_5M 12 -+#define USERIAL_BAUD_2M 13 -+#define USERIAL_BAUD_3M 14 -+#define USERIAL_BAUD_4M 15 -+#define USERIAL_BAUD_AUTO 16 -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef TRUE -+#define TRUE (!FALSE) -+#endif -+ -+#define HCI_CHG_BAUD_CMD_OCF 0x0C -+#define HCI_VENDOR_CMD_OGF 0x3F -+#define WRITE_BDADDR_CMD_LEN 14 -+#define WRITE_BAUD_CMD_LEN 6 -+#define MAX_CMD_LEN WRITE_BDADDR_CMD_LEN -+#define GET_VERSION_OCF 0x1E -+ -+#define PS_HDR_LEN 4 -+#define HCI_VENDOR_CMD_OGF 0x3F -+#define HCI_PS_CMD_OCF 0x0B -+ -+#define HCI_COMMAND_HDR_SIZE 3 -+#define EVT_CMD_COMPLETE_SIZE 3 -+#define EVT_CMD_STATUS 0x0F -+#define EVT_CMD_STATUS_SIZE 4 -+#define HCI_EVENT_HDR_SIZE 2 -+#define HCI_EV_SUCCESS 0x00 -+/* HCI Socket options */ -+#define HCI_DATA_DIR 1 -+#define HCI_FILTER 2 -+#define HCI_TIME_STAMP 3 -+ -+#define P_ID_OFFSET (0) -+#define HCI_CMD_IND (1) -+#define EVENTCODE_OFFSET (1) -+#define EVT_PLEN (2) -+#define PLEN (3) -+#define CMD_RSP_OFFSET (3) -+#define RSP_TYPE_OFFSET (4) -+#define BAUDRATE_RSP_STATUS_OFFSET (4) -+#define CMD_STATUS_OFFSET (5) -+#define P_ROME_VER_OFFSET (4) -+#define P_BUILD_VER_OFFSET (6) -+#define P_BASE_ADDR_OFFSET (8) -+#define P_ENTRY_ADDR_OFFSET (12) -+#define P_LEN_OFFSET (16) -+#define P_CRC_OFFSET (20) -+#define P_CONTROL_OFFSET (24) -+#define PATCH_HDR_LEN (28) -+#define MAX_DATA_PER_SEGMENT (239) -+#define VSEVENT_CODE (0xFF) -+#define HC_VS_MAX_CMD_EVENT (0xFF) -+#define PATCH_PROD_ID_OFFSET (5) -+#define PATCH_PATCH_VER_OFFSET (9) -+#define PATCH_ROM_BUILD_VER_OFFSET (11) -+#define PATCH_SOC_VER_OFFSET (13) -+#define MAX_SIZE_PER_TLV_SEGMENT (243) -+ -+/* VS Opcode */ -+#define HCI_PATCH_CMD_OCF (0) -+#define EDL_SET_BAUDRATE_CMD_OCF (0x48) -+ -+/* VS Commands */ -+#define VSC_SET_BAUDRATE_REQ_LEN (1) -+#define EDL_PATCH_CMD_LEN (1) -+#define EDL_PATCH_CMD_REQ_LEN (1) -+#define EDL_PATCH_DLD_REQ_CMD (0x01) -+#define EDL_PATCH_RST_REQ_CMD (0x05) -+#define EDL_PATCH_SET_REQ_CMD (0x16) -+#define EDL_PATCH_ATCH_REQ_CMD (0x17) -+#define EDL_PATCH_VER_REQ_CMD (0x19) -+#define EDL_PATCH_TLV_REQ_CMD (0x1E) -+#define VSC_DISABLE_IBS_LEN (0x04) -+ -+/* VS Event */ -+#define EDL_CMD_REQ_RES_EVT (0x00) -+#define EDL_CMD_EXE_STATUS_EVT (0x00) -+#define EDL_SET_BAUDRATE_RSP_EVT (0x92) -+#define EDL_PATCH_VER_RES_EVT (0x19) -+#define EDL_TVL_DNLD_RES_EVT (0x04) -+#define EDL_APP_VER_RES_EVT (0x02) -+ -+ -+/* Status Codes of HCI CMD execution*/ -+#define HCI_CMD_SUCCESS (0x0) -+#define PATCH_LEN_ERROR (0x1) -+#define PATCH_VER_ERROR (0x2) -+#define PATCH_CRC_ERROR (0x3) -+#define PATCH_NOT_FOUND (0x4) -+#define TLV_TYPE_ERROR (0x10) -+#define NVM_ACCESS_CODE (0x0B) -+#define BAUDRATE_CHANGE_SUCCESS (1) -+ -+/* TLV_TYPE */ -+#define TLV_TYPE_PATCH (1) -+#define TLV_TYPE_NVM (2) -+ -+/* NVM */ -+#define MAX_TAG_CMD 30 -+#define TAG_END 0xFF -+#define NVM_ACCESS_SET 0x01 -+#define TAG_NUM_OFFSET 5 -+#define TAG_NUM_2 2 -+#define TAG_BDADDR_OFFSET 7 -+ -+/* NVM Tags specifically used for ROME 1.0 */ -+#define ROME_1_0_100022_1 0x101000221 -+#define ROME_1_0_100019 0x101000190 -+#define ROME_1_0_6002 0x100600200 -+ -+/* Default NVM Version setting for ROME 1.0 */ -+#define NVM_VERSION ROME_1_0_100022_1 -+ -+ -+#define LSH(val, n) ((unsigned int)(val) << (n)) -+#define EXTRACT_BYTE(val, pos) (char) (((val) >> (8 * (pos))) & 0xFF) -+#define CALC_SEG_SIZE(len, max) ((plen) % (max))?((plen/max)+1) : ((plen) / (max)) -+ -+#define ROME_FW_PATH "/lib/firmware/rampatch.img" -+#define ROME_RAMPATCH_TLV_PATH "/lib/firmware/rampatch_tlv.img" -+#define ROME_NVM_TLV_PATH "/lib/firmware/nvm_tlv.bin" -+#define ROME_RAMPATCH_TLV_1_0_3_PATH "/lib/firmware/rampatch_tlv_1.3.tlv" -+#define ROME_NVM_TLV_1_0_3_PATH "/lib/firmware/nvm_tlv_1.3.bin" -+#define ROME_RAMPATCH_TLV_2_0_1_PATH "/lib/firmware/rampatch_tlv_2.1.tlv" -+#define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" -+#define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" -+#define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" -+ -+ -+/****************************************************************************** -+** Local type definitions -+******************************************************************************/ -+ -+typedef struct { -+ unsigned char ncmd; -+ unsigned short opcode; -+} __attribute__ ((packed)) evt_cmd_complete; -+ -+typedef struct { -+ unsigned char status; -+ unsigned char ncmd; -+ unsigned short opcode; -+} __attribute__ ((packed)) evt_cmd_status; -+ -+typedef struct { -+ unsigned short opcode; -+ unsigned char plen; -+} __attribute__ ((packed)) hci_command_hdr; -+ -+typedef struct { -+ unsigned char evt; -+ unsigned char plen; -+} __attribute__ ((packed)) hci_event_hdr; -+typedef struct { -+ unsigned short rom_version; -+ unsigned short build_version; -+} __attribute__ ((packed)) patch_version; -+ -+typedef struct { -+ unsigned int patch_id; -+ patch_version patch_ver; -+ unsigned int patch_base_addr; -+ unsigned int patch_entry_addr; -+ unsigned short patch_length; -+ int patch_crc; -+ unsigned short patch_ctrl; -+} __attribute__ ((packed)) patch_info; -+ -+typedef struct { -+ unsigned char sign_ver; -+ unsigned char sign_algorithm; -+ unsigned short reserved1; -+ unsigned short prod_id; -+ unsigned short build_ver; -+ unsigned short patch_ver; -+ unsigned short reserved2; -+ unsigned int patch_entry_addr; -+} __attribute__ ((packed)) tlv_patch_hdr; -+ -+typedef struct { -+ unsigned short tag_id; -+ unsigned short tag_len; -+ unsigned int tag_ptr; -+ unsigned int tag_ex_flag; -+} __attribute__ ((packed)) tlv_nvm_hdr; -+ -+typedef struct { -+ unsigned char tlv_type; -+ unsigned char tlv_length1; -+ unsigned char tlv_length2; -+ unsigned char tlv_length3; -+ unsigned int tlv_data_len; -+ unsigned int tlv_patch_data_len; -+ -+ union{ -+ tlv_patch_hdr patch; -+ tlv_nvm_hdr nvm; -+ }tlv; -+} __attribute__ ((packed)) tlv_patch_info; -+ -+enum{ -+ BAUDRATE_115200 = 0x00, -+ BAUDRATE_57600 = 0x01, -+ BAUDRATE_38400 = 0x02, -+ BAUDRATE_19200 = 0x03, -+ BAUDRATE_9600 = 0x04, -+ BAUDRATE_230400 = 0x05, -+ BAUDRATE_250000 = 0x06, -+ BAUDRATE_460800 = 0x07, -+ BAUDRATE_500000 = 0x08, -+ BAUDRATE_720000 = 0x09, -+ BAUDRATE_921600 = 0x0A, -+ BAUDRATE_1000000 = 0x0B, -+ BAUDRATE_1250000 = 0x0C, -+ BAUDRATE_2000000 = 0x0D, -+ BAUDRATE_3000000 = 0x0E, -+ BAUDRATE_4000000 = 0x0F, -+ BAUDRATE_1600000 = 0x10, -+ BAUDRATE_3200000 = 0x11, -+ BAUDRATE_3500000 = 0x12, -+ BAUDRATE_AUTO = 0xFE, -+ BAUDRATE_Reserved = 0xFF -+}; -+ -+enum{ -+ ROME_PATCH_VER_0100 = 0x0100, -+ ROME_PATCH_VER_0101 = 0x0101, -+ ROME_PATCH_VER_0200 = 0x0200, -+ ROME_PATCH_VER_0300 = 0x0300 -+ }; -+ -+enum{ -+ ROME_SOC_ID_00 = 0x00000000, -+ ROME_SOC_ID_11 = 0x00000011, -+ ROME_SOC_ID_13 = 0x00000013, -+ ROME_SOC_ID_22 = 0x00000022, -+}; -+ -+enum{ -+ ROME_VER_UNKNOWN = 0, -+ ROME_VER_1_0 = ((ROME_PATCH_VER_0100 << 16 ) | ROME_SOC_ID_00 ), -+ ROME_VER_1_1 = ((ROME_PATCH_VER_0101 << 16 ) | ROME_SOC_ID_00 ), -+ ROME_VER_1_3 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_00 ), -+ ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), -+ ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), -+ TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) -+}; -+#endif /* HW_ROME_H */ diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch deleted file mode 100644 index 8ba83ae56..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Anantha Krishnan -Date: Thu, 11 Sep 2014 19:20:02 +0530 -Subject: [PATCH] bluetooth: Enable bluetooth low power mode functionality - -During periods of inactivity the bluetooth controller and the -application processor will indicate each other to enter into -low power mode and signal each other when they have data to be -exchanged, thereby saving considerable amount of power. - -Change-Id: I9e0d579ac8a9d61a2ebde78b031f4101cb6bc443 -Signed-off-by: Rupesh Tatiya ---- - tools/hciattach.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tools/hciattach.c b/tools/hciattach.c -index 73811d4c4c2a..e3a915061440 100644 ---- a/tools/hciattach.c -+++ b/tools/hciattach.c -@@ -1102,7 +1102,7 @@ struct uart_t uart[] = { - FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm }, - - /* QCA ROME */ -- { "qca", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, -+ { "qca", 0x0000, 0x0000, HCI_UART_IBS, 115200, 115200, - FLOW_CTL, DISABLE_PM, NULL, qca, NULL }, - - /* QUALCOMM BTS */ diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch deleted file mode 100644 index 21b57dde3..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Anantha Krishnan -Date: Thu, 11 Sep 2014 18:57:45 +0530 -Subject: [PATCH] bluetooth: Fix bug in firmware parsing mechanism - -Reorganize the RAMPATCH members to be present as part of the -RAMPATCH header structre instead of the main firmware structure - -Change-Id: If523e1bb20edcd52b7c6f623c07af492e6305bd0 -Signed-off-by: Rupesh Tatiya ---- - tools/hciattach_rome.c | 4 ++-- - tools/hciattach_rome.h | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index f31be43c09e4..122a0f4b89bc 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -851,8 +851,8 @@ int rome_get_tlv_file(char *file_path) - fprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | - (ptlv_header->tlv_length2 << 8) | - (ptlv_header->tlv_length3 << 16)); -- fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv_data_len); -- fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv_patch_data_len); -+ fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv.patch.tlv_data_len); -+ fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); - fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); - fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); - fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index aa59965643ec..07127f30a70a 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -236,6 +236,8 @@ typedef struct { - } __attribute__ ((packed)) patch_info; - - typedef struct { -+ unsigned int tlv_data_len; -+ unsigned int tlv_patch_data_len; - unsigned char sign_ver; - unsigned char sign_algorithm; - unsigned short reserved1; -@@ -258,8 +260,6 @@ typedef struct { - unsigned char tlv_length1; - unsigned char tlv_length2; - unsigned char tlv_length3; -- unsigned int tlv_data_len; -- unsigned int tlv_patch_data_len; - - union{ - tlv_patch_hdr patch; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-bluetooth-Configure-BD-Address.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-bluetooth-Configure-BD-Address.patch deleted file mode 100644 index d39d8d0a0..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-bluetooth-Configure-BD-Address.patch +++ /dev/null @@ -1,114 +0,0 @@ -From: Anantha Krishnan -Date: Mon, 8 Sep 2014 15:11:02 +0530 -Subject: [PATCH] bluetooth: Configure BD Address - -Read the BD Address programmed by user from persist location. -If there is no user programmed BD address then use the default -BD address present in the firmware file. - -Change-Id: Id702d1476bae765dfd23f88542bfd5a8a1f26056 -Signed-off-by: Rupesh Tatiya ---- - tools/hciattach_rome.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--- - tools/hciattach_rome.h | 7 +++++++ - 2 files changed, 60 insertions(+), 3 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 122a0f4b89bc..947e1abb96c4 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -809,6 +809,7 @@ int rome_get_tlv_file(char *file_path) - tlv_nvm_hdr *nvm_ptr; - unsigned char data_buf[PRINT_BUF_SIZE]={0,}; - unsigned char *nvm_byte_ptr; -+ unsigned char bdaddr[6]; - - fprintf(stderr, "File Open (%s)\n", file_path); - pFile = fopen ( file_path , "r" ); -@@ -886,9 +887,10 @@ int rome_get_tlv_file(char *file_path) - nvm_byte_ptr+=sizeof(tlv_nvm_hdr); - - /* Write BD Address */ -- if(nvm_ptr->tag_id == TAG_NUM_2){ -- memcpy(nvm_byte_ptr, vnd_local_bd_addr, 6); -- fprintf(stderr, "BD Address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", -+ if(nvm_ptr->tag_id == TAG_NUM_2 && read_bd_address(&bdaddr) == 0) { -+ memcpy(nvm_byte_ptr, bdaddr, 6); -+ fprintf(stderr, "Overriding default BD ADDR with user" -+ " programmed BD Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), - *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); - } -@@ -1451,6 +1453,54 @@ error: - - } - -+int read_bd_address(unsigned char *bdaddr) -+{ -+ int fd = -1; -+ int readPtr = 0; -+ unsigned char data[BD_ADDR_LEN]; -+ -+ /* Open the persist file for reading device address*/ -+ fd = open("/etc/bluetooth/.bt_nv.bin", O_RDONLY); -+ if(fd < 0) -+ { -+ fprintf(stderr, "%s: Open failed: Programming default BD ADDR\n", __func__); -+ return -1; -+ } -+ -+ /* Read the NVM Header : fp will be advanced by readPtr number of bytes */ -+ readPtr = read(fd, data, PERSIST_HEADER_LEN); -+ if (readPtr > 0) -+ fprintf(stderr, "%s: Persist header data: %02x \t %02x \t %02x\n", __func__, -+ data[NVITEM], data[RDWR_PROT], data[NVITEM_SIZE]); -+ else { -+ fprintf(stderr, "%s: Read from persist memory failed : Programming default" -+ " BD ADDR\n"); -+ close(fd); -+ return -1; -+ } -+ -+ /* Check for BD ADDR length before programming */ -+ if(data[NVITEM_SIZE] != BD_ADDR_LEN) { -+ fprintf(stderr, "Invalid BD ADDR: Programming default BD ADDR!\n"); -+ close(fd); -+ return -1; -+ } -+ -+ /* Read the BD ADDR info */ -+ readPtr = read(fd, data, BD_ADDR_LEN); -+ if (readPtr > 0) -+ fprintf(stderr, "BD-ADDR: ==> %02x:%02x:%02x:%02x:%02x:%02x\n", data[0], -+ data[1], data[2], data[3], data[4], data[5]); -+ else { -+ fprintf(stderr, "%s: Read from persist memory failed : Programming default" -+ " BD ADDR\n"); -+ close(fd); -+ return -1; -+ } -+ memcpy(bdaddr, data, BD_ADDR_LEN); -+ close(fd); -+ return 0; -+} - - int qca_soc_init(int fd, char *bdaddr) - { -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 07127f30a70a..a4abe9f73080 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -34,6 +34,13 @@ - #define HCI_EVENT_PKT 0x04 - #define HCI_VENDOR_PKT 0xff - #define cmd_opcode_pack(ogf, ocf) (unsigned short)((ocf & 0x03ff)|(ogf << 10)) -+ -+#define NVITEM 0 -+#define RDWR_PROT 1 -+#define NVITEM_SIZE 2 -+#define PERSIST_HEADER_LEN 3 -+#define BD_ADDR_LEN 6 -+ - unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - typedef enum { - USERIAL_OP_FLOW_ON, diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0024-hciattach-Add-verbosity-option.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach-Add-verbosity-option.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0024-hciattach-Add-verbosity-option.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach-Add-verbosity-option.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch deleted file mode 100644 index 604efb2e4..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Anantha Krishnan -Date: Mon, 8 Sep 2014 14:33:24 +0530 -Subject: [PATCH] bluetooth: Remove unused functions in the firmware download - process - -rome_disable_sleep() function is not used anywhere in the code and -hence remove it. - -Change-Id: Iec1f9b1478850af3023ff297493693283a5338d7 -Signed-off-by: Rupesh Tatiya ---- - tools/hciattach_rome.c | 48 ------------------------------------------------ - 1 file changed, 48 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 947e1abb96c4..4fcbdf2ab82a 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1317,54 +1317,6 @@ error: - - } - --int rome_disable_sleep(int fd) --{ -- int size, err = 0; -- unsigned char cmd[HCI_MAX_CMD_SIZE]; -- unsigned char rsp[HCI_MAX_EVENT_SIZE]; -- hci_command_hdr *cmd_hdr; -- int flags; -- -- memset(cmd, 0x0, HCI_MAX_CMD_SIZE); -- -- cmd_hdr = (void *) (cmd + 1); -- cmd[0] = HCI_COMMAND_PKT; -- cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, NVM_ACCESS_CODE); -- cmd_hdr->plen = VSC_DISABLE_IBS_LEN; -- cmd[4] = 0x01; -- cmd[5] = 0x1B; -- cmd[6] = 0x01; -- cmd[7] = 0x00; -- -- /* Total length of the packet to be sent to the Controller */ -- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_DISABLE_IBS_LEN); -- /* Send the HCI command packet to UART for transmission */ -- fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]) ; -- err = write(fd, cmd, size); -- if (err != size) { -- fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); -- goto error; -- } -- -- /* Check for response from the Controller */ -- if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { -- fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -- goto error; -- } -- -- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); -- -- /* Wait for command complete event */ -- err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); -- if ( err < 0) { -- fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); -- goto error; -- } -- fprintf(stderr, "%s\n", __FUNCTION__); --error: -- return err; -- --} - - int rome_set_baudrate_req(int fd) - { diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0025-port-test-discovery-to-python3.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-port-test-discovery-to-python3.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0025-port-test-discovery-to-python3.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-port-test-discovery-to-python3.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch deleted file mode 100644 index a4f15ead0..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-bluetooth-Enable-3Mbps-baud-rate-support.patch +++ /dev/null @@ -1,150 +0,0 @@ -From: Anantha Krishnan -Date: Mon, 8 Sep 2014 14:31:18 +0530 -Subject: [PATCH] bluetooth: Enable 3Mbps baud rate support - -Allow APPS PROC and BT Controller to operate at 3Mbps baud rate -for faster exchange of commands, events and data between the two - -Change-Id: I55651633027ea60a762b11abea84fe1abd6574a9 -Signed-off-by: Rupesh Tatiya ---- - tools/hciattach_rome.c | 63 ++++++++++++++++++++++++++++++++++++++------------ - 1 file changed, 48 insertions(+), 15 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 4fcbdf2ab82a..d0e2935b9997 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -166,6 +166,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) - } - cfmakeraw(&ti); - ti.c_cflag |= CLOCAL; -+ ti.c_cflag |= CREAD; - - switch(op) - { -@@ -332,6 +333,8 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) - { - int remain, r; - int count = 0; -+ fd_set infids; -+ struct timeval timeout; - - if (size <= 0) { - fprintf(stderr, "Invalid size arguement!\n"); -@@ -340,6 +343,16 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) - - fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); - -+ FD_ZERO (&infids); -+ FD_SET (fd, &infids); -+ timeout.tv_sec = 3; -+ timeout.tv_usec = 0; /* half second is a long time at 115.2 Kbps */ -+ -+ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) -+ fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); -+ else -+ fprintf(stderr, "%s: Data available in TTY Serial buffer\n", __FUNCTION__); -+ - /* The first byte identifies the packet type. For HCI event packets, it - * should be 0x04, so we read until we get to the 0x04. */ - /* It will keep reading until find 0x04 byte */ -@@ -1332,10 +1345,16 @@ int rome_set_baudrate_req(int fd) - cmd[0] = HCI_COMMAND_PKT; - cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); - cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; -- cmd[4] = BAUDRATE_115200; -+ cmd[4] = BAUDRATE_3000000; - - /* Total length of the packet to be sent to the Controller */ - size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); -+ /* Flow off during baudrate change */ -+ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) -+ { -+ fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); -+ goto error; -+ } - /* Send the HCI command packet to UART for transmission */ - fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; - err = write(fd, cmd, size); -@@ -1343,7 +1362,15 @@ int rome_set_baudrate_req(int fd) - fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); - goto error; - } -+ /* Change Local UART baudrate to high speed UART */ -+ userial_vendor_set_baud(USERIAL_BAUD_3M); - -+ /* Flow on after changing local uart baudrate */ -+ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) -+ { -+ fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); -+ return err; -+ } - /* Check for response from the Controller */ - if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { - fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -@@ -1385,6 +1412,12 @@ int rome_hci_reset_req(int fd) - /* Total length of the packet to be sent to the Controller */ - size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); - -+ /* Flow off during baudrate change */ -+ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) -+ { -+ fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); -+ goto error; -+ } - /* Send the HCI command packet to UART for transmission */ - fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); - err = write(fd, cmd, size); -@@ -1393,6 +1426,15 @@ int rome_hci_reset_req(int fd) - goto error; - } - -+ /* Change Local UART baudrate to high speed UART */ -+ userial_vendor_set_baud(USERIAL_BAUD_3M); -+ -+ /* Flow on after changing local uart baudrate */ -+ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) -+ { -+ fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); -+ return err; -+ } - /* Wait for command complete event */ - err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); - if ( err < 0) { -@@ -1534,16 +1576,7 @@ int qca_soc_init(int fd, char *bdaddr) - nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; - - download: -- /* Donwload TLV files (rampatch, NVM) */ -- err = rome_download_tlv_file(fd); -- if (err < 0) { -- fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); -- goto error; -- } -- fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); -- -- /* Change baud rate back to user requested */ -- fprintf(stderr, "Changing baud rate back from 3M --> 115K\n"); -+ /* Change baud rate 115.2 kbps to 3Mbps*/ - err = rome_set_baudrate_req(fd); - if (err < 0) { - fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); -@@ -1551,13 +1584,13 @@ download: - } - fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); - -- fprintf(stderr, "%s: Disabling In Band Sleep functionality\n", __FUNCTION__); -- err = rome_disable_sleep(fd); -+ /* Donwload TLV files (rampatch, NVM) */ -+ err = rome_download_tlv_file(fd); - if (err < 0) { -- fprintf(stderr, "%s: Failed to disable IBS!\n", __FUNCTION__); -+ fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); - goto error; - } -- fprintf(stderr, "%s: IBS disabled successfully \n", __FUNCTION__); -+ fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); - - /* Perform HCI reset here*/ - err = rome_hci_reset_req(fd); diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0027-example-gatt-server-update-example-to-master-version.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-example-gatt-server-update-example-to-master-version.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0027-example-gatt-server-update-example-to-master-version.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-example-gatt-server-update-example-to-master-version.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch deleted file mode 100644 index 6e276d517..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch +++ /dev/null @@ -1,189 +0,0 @@ -From: Anantha Krishnan -Date: Tue, 30 Sep 2014 12:13:00 +0530 -Subject: [PATCH] bluetooth: Check TTY buffer for data availability before - reading - -When operating at higher baud rates check the TTY buffer for -availability of data before proceeding to read. Call select() with -a 3 sec timeout value to check for the availablitiy of data. -select() will return once data is available in the TTY buffers -and will allow read() to fetch the data. If data is not available -in the TTY buffer until the timeout valueexpires, do not proceed -to read the data from the TTY buffers as there is none. - -Occasionally corrupt data is received on UART lines while we wait -for vendor specific event from Controller. Expected vendor specific -events are received after the corrupt data. But we do not retry -and exit and this causes firmware download failures. So, retry once -if we did not get HCI event. - -Change-Id: I3b672a7762403690f8b934ca216492f16285e8da -Signed-off-by: Rupesh Tatiya ---- - tools/hciattach.c | 20 ++++++++++++- - tools/hciattach_rome.c | 77 +++++++++++++++++++++++++++++++++++++++----------- - tools/hciattach_rome.h | 3 ++ - 3 files changed, 83 insertions(+), 17 deletions(-) - -diff --git a/tools/hciattach.c b/tools/hciattach.c -index e3a915061440..c3cf10843303 100644 ---- a/tools/hciattach.c -+++ b/tools/hciattach.c -@@ -109,16 +109,34 @@ int read_hci_event(int fd, unsigned char* buf, int size) - { - int remain, r; - int count = 0; -+ fd_set infids; -+ struct timeval timeout; - - if (size <= 0) - return -1; - -+ FD_ZERO (&infids); -+ FD_SET (fd, &infids); -+ timeout.tv_sec = 3; -+ timeout.tv_usec = 0; -+ -+ /* Check whether data is available in TTY buffer before calling read() */ -+ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) { -+ fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); -+ return -1; -+ } -+ else -+ fprintf(stderr, "%s: Data(HCI-CMD-COMP-EVENT) available in TTY Serial buffer\n", __FUNCTION__); -+ - /* The first byte identifies the packet type. For HCI event packets, it - * should be 0x04, so we read until we get to the 0x04. */ - while (1) { - r = read(fd, buf, 1); -- if (r <= 0) -+ if (r <= 0) { -+ fprintf(stderr, "%s: read() failed with return value: %d\n", -+ __FUNCTION__, r); - return -1; -+ } - if (buf[0] == 0x04) - break; - } -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index d0e2935b9997..d2687b1ef01a 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -326,42 +326,87 @@ failed: - } - - -+int wait_for_data(int fd, int maxTimeOut) -+{ -+ fd_set infids; -+ struct timeval timeout; -+ -+ if (maxTimeOut <= 0) { -+ fprintf(stderr, "%s: Invalid timeout value specified", __func__); -+ return -EINVAL; -+ } -+ -+ FD_ZERO (&infids); -+ FD_SET (fd, &infids); -+ timeout.tv_sec = maxTimeOut; -+ timeout.tv_usec = 0; -+ -+ /* Check whether data is available in TTY buffer before calling read() */ -+ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) { -+ fprintf(stderr, "%s: Timing out on select for %d secs.\n", __FUNCTION__, maxTimeOut); -+ return -1; -+ } -+ else -+ fprintf(stderr, "%s: HCI-VS-EVENT available in TTY Serial buffer\n", -+ __FUNCTION__); -+ -+ return 1; -+} -+ - /* - * Read an VS HCI event from the given file descriptor. - */ - int read_vs_hci_event(int fd, unsigned char* buf, int size) - { -- int remain, r; -+ int remain, r, retry = 0; - int count = 0; -- fd_set infids; -- struct timeval timeout; - - if (size <= 0) { - fprintf(stderr, "Invalid size arguement!\n"); - return -1; - } - -- fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); -- -- FD_ZERO (&infids); -- FD_SET (fd, &infids); -- timeout.tv_sec = 3; -- timeout.tv_usec = 0; /* half second is a long time at 115.2 Kbps */ -+ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", -+ __FUNCTION__); - -- if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) -- fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); -- else -- fprintf(stderr, "%s: Data available in TTY Serial buffer\n", __FUNCTION__); -+ /* Check whether data is available in TTY buffer before calling read() */ -+ if (wait_for_data(fd, SELECT_TIMEOUT) < 1) -+ return -1; - - /* The first byte identifies the packet type. For HCI event packets, it - * should be 0x04, so we read until we get to the 0x04. */ - /* It will keep reading until find 0x04 byte */ - while (1) { -+ /* Read UART Buffer for HCI-DATA */ - r = read(fd, buf, 1); -- if (r <= 0) -- return -1; -- if (buf[0] == 0x04) -+ if (r <= 0) { -+ fprintf(stderr, "%s: read() failed. error: %d\n", -+ __FUNCTION__, r); -+ return -1; -+ } -+ -+ /* Check if received data is HCI-DATA or not. -+ * If not HCI-DATA, then retry reading the UART Buffer once. -+ * Sometimes there could be corruption on the UART lines and to -+ * avoid that retry once reading the UART Buffer for HCI-DATA. -+ */ -+ if (buf[0] == 0x04) { /* Recvd. HCI DATA */ -+ retry = 0; - break; -+ } -+ else if (retry < MAX_RETRY_CNT){ /* Retry mechanism */ -+ retry++; -+ fprintf(stderr, "%s: Not an HCI-VS-Event! buf[0]: %d", -+ __FUNCTION__, buf[0]); -+ if (wait_for_data(fd, SELECT_TIMEOUT) < 1) -+ return -1; -+ else /* Data available in UART Buffer: Continue to read */ -+ continue; -+ } -+ else { /* RETRY failed : Exiting with failure */ -+ fprintf(stderr, "%s: RETRY failed!", __FUNCTION__); -+ return -1; -+ } - } - count++; - -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index a4abe9f73080..3efb71995c45 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -179,6 +179,9 @@ typedef struct - #define TAG_NUM_2 2 - #define TAG_BDADDR_OFFSET 7 - -+#define MAX_RETRY_CNT 1 -+#define SELECT_TIMEOUT 3 -+ - /* NVM Tags specifically used for ROME 1.0 */ - #define ROME_1_0_100022_1 0x101000221 - #define ROME_1_0_100019 0x101000190 diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch deleted file mode 100644 index e8f2f8dcc..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Anantha Krishnan -Date: Wed, 20 Aug 2014 12:13:19 +0530 -Subject: [PATCH] bluetooth : Add support for TUFEELO firmware download - -Add TUFELLO chip version to allow firmware download. - -Change-Id: Ie3760fa64e8345bf9a84b2f047fde0ac1003b393 ---- - tools/hciattach_rome.c | 5 ++++- - tools/hciattach_rome.h | 3 ++- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index d2687b1ef01a..84dfc97b5140 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1616,9 +1616,12 @@ int qca_soc_init(int fd, char *bdaddr) - nvm_file_path = ROME_NVM_TLV_2_0_1_PATH; - goto download; - case ROME_VER_3_0: -- case TUFELLO_VER_1_0: - rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; - nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; -+ goto download; -+ case TUFELLO_VER_1_0: -+ rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; -+ nvm_file_path = TF_NVM_TLV_1_0_0_PATH; - - download: - /* Change baud rate 115.2 kbps to 3Mbps*/ -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 3efb71995c45..9d18c576fcae 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -204,7 +204,8 @@ typedef struct - #define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" - #define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" - #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" -- -+#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" -+#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" - - /****************************************************************************** - ** Local type definitions diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch deleted file mode 100644 index 5cc72bde2..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch +++ /dev/null @@ -1,236 +0,0 @@ -From: Anantha Krishnan -Date: Mon, 8 Dec 2014 14:52:16 +0530 -Subject: [PATCH] bluetooth: Add support for ROME 3.2 SOC. - -Add firmware download support for ROME 3.2 version. As part -of this, the Bluetooth on time is optimized based on event -handling while downloading rampatch files.From ROME 3.2 onwards, -the VS and command complete events will be sent depending the flag -indication present in the header. HOST can wait for VS and command -complete events only if specified in the header info. This greatly -reduces the time spent by HOST in waiting for 2 events from the -Controller before downloading each segment of the RAMPATCH file - -Change-Id: I9c4227a7a529455f4d120b2c9d065f3ec6b439e9 ---- - tools/hciattach_rome.c | 104 ++++++++++++++++++++++++++++++++++++++++++------- - tools/hciattach_rome.h | 16 +++++++- - 2 files changed, 103 insertions(+), 17 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 84dfc97b5140..c6d528f118e1 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -62,9 +62,11 @@ unsigned char *pdata_buffer = NULL; - patch_info rampatch_patch_info; - int rome_ver = ROME_VER_UNKNOWN; - unsigned char gTlv_type; -+unsigned char gtlv_dwndcfg; - char *rampatch_file_path; - char *nvm_file_path; - vnd_userial_cb_t vnd_userial; -+unsigned char wait_vsc_evt = TRUE; - /****************************************************************************** - ** Extern variables - ******************************************************************************/ -@@ -455,14 +457,16 @@ int hci_send_vs_cmd(int fd, unsigned char *cmd, unsigned char *rsp, int size) - goto failed; - } - -- /* Check for response from the Controller */ -- if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { -- ret = -ETIMEDOUT; -- fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -- goto failed; -+ if (wait_vsc_evt) { -+ /* Check for response from the Controller */ -+ if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { -+ ret = -ETIMEDOUT; -+ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -+ goto failed; -+ } -+ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); - } - -- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); - failed: - return ret; - } -@@ -903,6 +907,7 @@ int rome_get_tlv_file(char *file_path) - - /* To handle different event between rampatch and NVM */ - gTlv_type = ptlv_header->tlv_type; -+ gtlv_dwndcfg = ptlv_header->tlv.patch.dwnd_cfg; - - if(ptlv_header->tlv_type == TLV_TYPE_PATCH){ - fprintf(stderr, "====================================================\n"); -@@ -914,6 +919,7 @@ int rome_get_tlv_file(char *file_path) - fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); - fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); - fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); -+ fprintf(stderr, "Event Handling\t\t\t : 0x%x", ptlv_header->tlv.patch.dwnd_cfg); - fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); - fprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); - fprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); -@@ -1023,19 +1029,83 @@ int rome_tlv_dnld_req(int fd, int tlv_size) - fprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", - __FUNCTION__,tlv_size, total_segment, remain_size); - -- for(i=0;i= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) -- && !remain_size && ((i+1) == total_segment))? FALSE: TRUE; -+ if (gTlv_type == TLV_TYPE_PATCH) { -+ /* Prior to Rome version 3.2(including inital few rampatch release of -+ * Rome 3.2), the event handling mechanism is ROME_SKIP_EVT_NONE. After -+ * few release of rampatch for Rome 3.2, the mechamism is changed to -+ * ROME_SKIP_EVT_VSE_CC. Rest of the mechanism is not used for now -+ */ -+ switch(gtlv_dwndcfg) -+ { -+ case ROME_SKIP_EVT_NONE: -+ wait_vsc_evt = TRUE; -+ wait_cc_evt = TRUE; -+ fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_NONE", __func__); -+ break; -+ case ROME_SKIP_EVT_VSE_CC: -+ wait_vsc_evt = FALSE; -+ wait_cc_evt = FALSE; -+ fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_VSE_CC", __func__); -+ break; -+ /* Not handled for now */ -+ case ROME_SKIP_EVT_VSE: -+ case ROME_SKIP_EVT_CC: -+ default: -+ fprintf(stderr, "%s: Unsupported Event handling: %d", __func__, gtlv_dwndcfg); -+ break; -+ } -+ } else { -+ wait_vsc_evt = TRUE; -+ wait_cc_evt = TRUE; -+ } -+ -+ for(i = 0; i < total_segment; i++) { -+ if((i+1) == total_segment) { -+ if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && -+ (gTlv_type == TLV_TYPE_PATCH)) { -+ /* If the Rome version is from 1.1 to 3.1 -+ * 1. No CCE for the last command segment but all other segment -+ * 2. All the command segments get VSE including the last one -+ */ -+ wait_cc_evt = !remain_size ? FALSE: TRUE; -+ } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { -+ /* If the Rome version is 3.2 -+ * 1. None of the command segments receive CCE -+ * 2. No command segments receive VSE except the last one -+ * 3. If gtlv_dwndcfg is ROME_SKIP_EVT_NONE then the logic is -+ * same as Rome 2.1, 2.2, 3.0 -+ */ -+ if (gtlv_dwndcfg == ROME_SKIP_EVT_NONE) { -+ wait_cc_evt = !remain_size ? FALSE: TRUE; -+ } else if (gtlv_dwndcfg == ROME_SKIP_EVT_VSE_CC) { -+ wait_vsc_evt = !remain_size ? TRUE: FALSE; -+ } -+ } -+ } -+ - if((err = rome_tlv_dnld_segment(fd, i, MAX_SIZE_PER_TLV_SEGMENT, wait_cc_evt )) < 0) - goto error; - } - -- /* In case remain data still remain, last rampatch segment command will not wait -- for command complete event here */ -- wait_cc_evt = ((rome_ver >= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) -- && remain_size )? FALSE:TRUE; -+ if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { -+ /* If the Rome version is from 1.1 to 3.1 -+ * 1. No CCE for the last command segment but all other segment -+ * 2. All the command segments get VSE including the last one -+ */ -+ wait_cc_evt = remain_size ? FALSE: TRUE; -+ } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { -+ /* If the Rome version is 3.2 -+ * 1. None of the command segments receive CCE -+ * 2. No command segments receive VSE except the last one -+ * 3. If gtlv_dwndcfg is ROME_SKIP_EVT_NONE then the logic is -+ * same as Rome 2.1, 2.2, 3.0 -+ */ -+ if (gtlv_dwndcfg == ROME_SKIP_EVT_NONE) { -+ wait_cc_evt = remain_size ? FALSE: TRUE; -+ } else if (gtlv_dwndcfg == ROME_SKIP_EVT_VSE_CC) { -+ wait_vsc_evt = remain_size ? TRUE: FALSE; -+ } -+ } - - if(remain_size) err =rome_tlv_dnld_segment(fd, i, remain_size, wait_cc_evt); - -@@ -1619,6 +1689,10 @@ int qca_soc_init(int fd, char *bdaddr) - rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; - nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; - goto download; -+ case ROME_VER_3_2: -+ rampatch_file_path = ROME_RAMPATCH_TLV_3_0_2_PATH; -+ nvm_file_path = ROME_NVM_TLV_3_0_2_PATH; -+ goto download; - case TUFELLO_VER_1_0: - rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; - nvm_file_path = TF_NVM_TLV_1_0_0_PATH; -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 9d18c576fcae..77e85e7e7b19 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -204,9 +204,17 @@ typedef struct - #define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" - #define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" - #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" -+#define ROME_RAMPATCH_TLV_3_0_2_PATH "/lib/firmware/qca/rampatch_tlv_3.2.tlv" -+#define ROME_NVM_TLV_3_0_2_PATH "/lib/firmware/qca/nvm_tlv_3.2.bin" - #define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" - #define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" - -+/* This header value in rampatch file decides event handling mechanism in the HOST */ -+#define ROME_SKIP_EVT_NONE 0x00 -+#define ROME_SKIP_EVT_VSE 0x01 -+#define ROME_SKIP_EVT_CC 0x02 -+#define ROME_SKIP_EVT_VSE_CC 0x03 -+ - /****************************************************************************** - ** Local type definitions - ******************************************************************************/ -@@ -251,7 +259,8 @@ typedef struct { - unsigned int tlv_patch_data_len; - unsigned char sign_ver; - unsigned char sign_algorithm; -- unsigned short reserved1; -+ unsigned char dwnd_cfg; -+ unsigned char reserved1; - unsigned short prod_id; - unsigned short build_ver; - unsigned short patch_ver; -@@ -306,7 +315,8 @@ enum{ - ROME_PATCH_VER_0100 = 0x0100, - ROME_PATCH_VER_0101 = 0x0101, - ROME_PATCH_VER_0200 = 0x0200, -- ROME_PATCH_VER_0300 = 0x0300 -+ ROME_PATCH_VER_0300 = 0x0300, -+ ROME_PATCH_VER_0302 = 0x0302 - }; - - enum{ -@@ -314,6 +324,7 @@ enum{ - ROME_SOC_ID_11 = 0x00000011, - ROME_SOC_ID_13 = 0x00000013, - ROME_SOC_ID_22 = 0x00000022, -+ ROME_SOC_ID_44 = 0x00000044 - }; - - enum{ -@@ -323,6 +334,7 @@ enum{ - ROME_VER_1_3 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_00 ), - ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), - ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), -+ ROME_VER_3_2 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_44 ), - TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) - }; - #endif /* HW_ROME_H */ diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch deleted file mode 100644 index b48e915e2..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch +++ /dev/null @@ -1,189 +0,0 @@ -From: Anantha Krishnan -Date: Thu, 4 Dec 2014 17:23:58 +0530 -Subject: [PATCH] bluetooth: Use correct TTY ioctl calls for flow control - operations - -BT firmware download application is using incorrect APIs for -performing flow off and flow on operations. As a result, the local -UART Controller is detecting breaks errors on the UART HW lines. - -Appliaction should use TIOCMGET and TIOCMSET ioctl()'s for flow -control operations instead of the tcsetattr() call. Also, the -application should set the value of "number of bits per character" -value to 8 and not as 5. - -Due to incorrect APIs used for flow control operation and wrong -value configured for CSIZE parameter, the local UART Controller -detected break errors on the UART HW lines. This caused the -firmware download operation to fail and resulted in BT ON failure. - -Change-Id: Id0ac1276609eceb528163860cc87267aaa50fede ---- - tools/hciattach_rome.c | 67 +++++++++++++++++++++++++++++++++----------------- - tools/hciattach_rome.h | 6 +++-- - 2 files changed, 49 insertions(+), 24 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index c6d528f118e1..1e689273b851 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1,6 +1,6 @@ - /* - * -- * Copyright (c) 2013, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. - * Not a Contribution. - * - * Copyright 2012 The Android Open Source Project -@@ -31,6 +31,7 @@ - - #define LOG_TAG "bt_vendor" - #include -+#include - #include - #include - #include -@@ -139,6 +140,16 @@ void userial_vendor_set_baud(unsigned char userial_baud) - unsigned int tcio_baud; - fprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); - -+ if (tcgetattr(vnd_userial.fd, &vnd_userial.termios) < 0) { -+ perror("Can't get port settings"); -+ return; -+ } -+ cfmakeraw(&vnd_userial.termios); -+ vnd_userial.termios.c_cflag |= CLOCAL; -+ vnd_userial.termios.c_cflag |= CREAD; -+ vnd_userial.termios.c_cflag |= CS8; -+ tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); -+ - userial_to_tcio_baud(userial_baud, &tcio_baud); - - cfsetospeed(&vnd_userial.termios, tcio_baud); -@@ -169,6 +180,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) - cfmakeraw(&ti); - ti.c_cflag |= CLOCAL; - ti.c_cflag |= CREAD; -+ ti.c_cflag |= CS8; - - switch(op) - { -@@ -1445,6 +1457,29 @@ error: - - } - -+static void flow_control(int fd, int opt) -+{ -+ struct termios c_opt; -+ -+ ioctl(fd, TIOCMGET, &c_opt); -+ c_opt.c_cc[VTIME] = 0; /* inter-character timer unused */ -+ c_opt.c_cc[VMIN] = 0; /* blocking read until 8 chars received */ -+ c_opt.c_cflag &= ~CSIZE; -+ c_opt.c_cflag |= (CS8 | CLOCAL | CREAD); -+ if (MSM_ENABLE_FLOW_CTRL) -+ c_opt.c_cflag |= CRTSCTS; -+ else if (MSM_DISABLE_FLOW_CTRL) -+ c_opt.c_cflag |= ~CRTSCTS; -+ else { -+ fprintf(stderr, "%s: Incorrect option passed for TIOCMSET\n", __func__); -+ return; -+ } -+ c_opt.c_iflag = IGNPAR; -+ c_opt.c_oflag = 0; -+ c_opt.c_lflag = 0; -+ ioctl(fd, TIOCMSET, &c_opt); -+} -+ - - int rome_set_baudrate_req(int fd) - { -@@ -1464,12 +1499,10 @@ int rome_set_baudrate_req(int fd) - - /* Total length of the packet to be sent to the Controller */ - size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); -+ - /* Flow off during baudrate change */ -- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) -- { -- fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); -- goto error; -- } -+ flow_control(fd, MSM_DISABLE_FLOW_CTRL); -+ - /* Send the HCI command packet to UART for transmission */ - fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; - err = write(fd, cmd, size); -@@ -1481,11 +1514,8 @@ int rome_set_baudrate_req(int fd) - userial_vendor_set_baud(USERIAL_BAUD_3M); - - /* Flow on after changing local uart baudrate */ -- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) -- { -- fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); -- return err; -- } -+ flow_control(fd, MSM_ENABLE_FLOW_CTRL); -+ - /* Check for response from the Controller */ - if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { - fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); -@@ -1528,11 +1558,8 @@ int rome_hci_reset_req(int fd) - size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); - - /* Flow off during baudrate change */ -- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) -- { -- fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); -- goto error; -- } -+ flow_control(fd, MSM_DISABLE_FLOW_CTRL); -+ - /* Send the HCI command packet to UART for transmission */ - fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); - err = write(fd, cmd, size); -@@ -1545,11 +1572,8 @@ int rome_hci_reset_req(int fd) - userial_vendor_set_baud(USERIAL_BAUD_3M); - - /* Flow on after changing local uart baudrate */ -- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) -- { -- fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); -- return err; -- } -+ flow_control(fd, MSM_ENABLE_FLOW_CTRL); -+ - /* Wait for command complete event */ - err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); - if ( err < 0) { -@@ -1616,7 +1640,6 @@ int qca_soc_init(int fd, char *bdaddr) - int err = -1; - int size; - -- fprintf(stderr, " %s \n", __FUNCTION__); - vnd_userial.fd = fd; - /* Get Rome version information */ - if((err = rome_patch_ver_req(fd)) <0){ -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 77e85e7e7b19..ef3647e6a69b 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -1,7 +1,7 @@ - /* -- * Copyright 2012 The Android Open Source Project -- * Copyright (c) 2013, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. - * Not a Contribution. -+ * Copyright 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. -@@ -40,6 +40,8 @@ - #define NVITEM_SIZE 2 - #define PERSIST_HEADER_LEN 3 - #define BD_ADDR_LEN 6 -+#define MSM_ENABLE_FLOW_CTRL 16 -+#define MSM_DISABLE_FLOW_CTRL 17 - - unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - typedef enum { diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-bluetooth-Add-support-for-multi-baud-rate.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-bluetooth-Add-support-for-multi-baud-rate.patch deleted file mode 100644 index 8b19376ba..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-bluetooth-Add-support-for-multi-baud-rate.patch +++ /dev/null @@ -1,256 +0,0 @@ -From: Anantha Krishnan -Date: Tue, 20 Jan 2015 12:43:20 +0530 -Subject: [PATCH] bluetooth: Add support for multi baud rate - -Currently BT operates only at 3M baud rate. Provide option -to configure the pre-defined baud rate values as supported by the -target platform. - -Change-Id: I4bbaf7db01ffb983c38dca7c4a4a56f579c678a8 ---- - tools/hciattach.c | 2 +- - tools/hciattach.h | 2 +- - tools/hciattach_rome.c | 109 ++++++++++++++++++++++++++++++++++++++++++------- - tools/hciattach_rome.h | 23 +++++++++++ - 4 files changed, 119 insertions(+), 17 deletions(-) - -diff --git a/tools/hciattach.c b/tools/hciattach.c -index c3cf10843303..dda639cabca3 100644 ---- a/tools/hciattach.c -+++ b/tools/hciattach.c -@@ -286,7 +286,7 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) - static int qca(int fd, struct uart_t *u, struct termios *ti) - { - fprintf(stderr,"qca\n"); -- return qca_soc_init(fd, u->bdaddr); -+ return qca_soc_init(fd, u->speed, u->bdaddr); - } - - static int qualcomm(int fd, struct uart_t *u, struct termios *ti) -diff --git a/tools/hciattach.h b/tools/hciattach.h -index 0656a845223c..49e59321fcac 100644 ---- a/tools/hciattach.h -+++ b/tools/hciattach.h -@@ -64,7 +64,7 @@ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, - struct termios *ti); - int ath3k_post(int fd, int pm); - int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); --int qca_soc_init(int fd, char *bdaddr); -+int qca_soc_init(int fd, int speed, char *bdaddr); - int intel_init(int fd, int init_speed, int *speed, struct termios *ti); - int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti, - const char *bdaddr); -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 1e689273b851..37974290ae0a 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1481,7 +1481,7 @@ static void flow_control(int fd, int opt) - } - - --int rome_set_baudrate_req(int fd) -+int rome_set_baudrate_req(int fd, int local_baud_rate, int controller_baud_rate) - { - int size, err = 0; - unsigned char cmd[HCI_MAX_CMD_SIZE]; -@@ -1495,7 +1495,7 @@ int rome_set_baudrate_req(int fd) - cmd[0] = HCI_COMMAND_PKT; - cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); - cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; -- cmd[4] = BAUDRATE_3000000; -+ cmd[4] = controller_baud_rate; - - /* Total length of the packet to be sent to the Controller */ - size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); -@@ -1511,7 +1511,7 @@ int rome_set_baudrate_req(int fd) - goto error; - } - /* Change Local UART baudrate to high speed UART */ -- userial_vendor_set_baud(USERIAL_BAUD_3M); -+ userial_vendor_set_baud(local_baud_rate); - - /* Flow on after changing local uart baudrate */ - flow_control(fd, MSM_ENABLE_FLOW_CTRL); -@@ -1537,7 +1537,7 @@ error: - } - - --int rome_hci_reset_req(int fd) -+int rome_hci_reset_req(int fd, char baud) - { - int size, err = 0; - unsigned char cmd[HCI_MAX_CMD_SIZE]; -@@ -1569,7 +1569,7 @@ int rome_hci_reset_req(int fd) - } - - /* Change Local UART baudrate to high speed UART */ -- userial_vendor_set_baud(USERIAL_BAUD_3M); -+ userial_vendor_set_baud(baud); - - /* Flow on after changing local uart baudrate */ - flow_control(fd, MSM_ENABLE_FLOW_CTRL); -@@ -1635,10 +1635,69 @@ int read_bd_address(unsigned char *bdaddr) - return 0; - } - --int qca_soc_init(int fd, char *bdaddr) -+int isSpeedValid(int speed, int *local_baud_rate, int *controller_baud_rate) -+{ -+ switch(speed) { -+ case 9600: -+ *local_baud_rate = USERIAL_BAUD_9600; -+ *controller_baud_rate = BAUDRATE_9600; -+ break; -+ case 19200: -+ *local_baud_rate = USERIAL_BAUD_19200; -+ *controller_baud_rate = BAUDRATE_19200; -+ break; -+ case 57600: -+ *local_baud_rate = USERIAL_BAUD_57600; -+ *controller_baud_rate = BAUDRATE_57600; -+ break; -+ case 115200: -+ *local_baud_rate = USERIAL_BAUD_115200; -+ *controller_baud_rate = BAUDRATE_115200; -+ break; -+ case 230400: -+ *local_baud_rate = USERIAL_BAUD_230400; -+ *controller_baud_rate = BAUDRATE_230400; -+ break; -+ case 460800: -+ *local_baud_rate = USERIAL_BAUD_460800; -+ *controller_baud_rate = BAUDRATE_460800; -+ break; -+ case 921600: -+ *local_baud_rate = USERIAL_BAUD_921600; -+ *controller_baud_rate = BAUDRATE_921600; -+ break; -+ case 1000000: -+ *local_baud_rate = USERIAL_BAUD_1M; -+ *controller_baud_rate = BAUDRATE_1000000; -+ break; -+ case 2000000: -+ *local_baud_rate = USERIAL_BAUD_2M; -+ *controller_baud_rate = BAUDRATE_2000000; -+ break; -+ case 3000000: -+ *local_baud_rate = USERIAL_BAUD_3M; -+ *controller_baud_rate = BAUDRATE_3000000; -+ break; -+ case 4000000: -+ *local_baud_rate = USERIAL_BAUD_4M; -+ *controller_baud_rate = BAUDRATE_4000000; -+ break; -+ case 300: -+ case 600: -+ case 1200: -+ case 2400: -+ default: -+ fprintf(stderr, "Invalid baud rate passed!\n"); -+ *local_baud_rate = *controller_baud_rate = -1; -+ break; -+ } -+ return -1; -+} -+ -+int qca_soc_init(int fd, int speed, char *bdaddr) - { - int err = -1; -- int size; -+ int size, local_baud_rate = 0, controller_baud_rate = 0; - - vnd_userial.fd = fd; - /* Get Rome version information */ -@@ -1687,7 +1746,7 @@ int qca_soc_init(int fd, char *bdaddr) - } - - /* Change baud rate 115.2 kbps to 3Mbps*/ -- err = rome_hci_reset_req(fd); -+ err = rome_hci_reset_req(fd, local_baud_rate); - if ( err <0 ) { - fprintf(stderr, "HCI Reset Failed !!\n"); - goto error; -@@ -1721,13 +1780,23 @@ int qca_soc_init(int fd, char *bdaddr) - nvm_file_path = TF_NVM_TLV_1_0_0_PATH; - - download: -- /* Change baud rate 115.2 kbps to 3Mbps*/ -- err = rome_set_baudrate_req(fd); -- if (err < 0) { -- fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); -- goto error; -+ /* Check if user requested for 115200 kbps */ -+ if (speed == 115200) { -+ local_baud_rate = USERIAL_BAUD_115200; -+ controller_baud_rate = BAUDRATE_115200; - } -- fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); -+ else { -+ /* Change only if baud rate requested is valid or not */ -+ isSpeedValid(speed, &local_baud_rate, &controller_baud_rate); -+ if (local_baud_rate < 0 || controller_baud_rate < 0) -+ goto error; -+ -+ err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); -+ if (err < 0) { -+ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); -+ goto error; -+ } -+ } - - /* Donwload TLV files (rampatch, NVM) */ - err = rome_download_tlv_file(fd); -@@ -1737,8 +1806,18 @@ download: - } - fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); - -+ /* -+ * Overriding the baud rate value in NVM file with the user -+ * requested baud rate, since default baud rate in NVM file is 3M. -+ */ -+ err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); -+ if (err < 0) { -+ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); -+ goto error; -+ } -+ - /* Perform HCI reset here*/ -- err = rome_hci_reset_req(fd); -+ err = rome_hci_reset_req(fd, local_baud_rate); - if ( err <0 ) { - fprintf(stderr, "HCI Reset Failed !!!\n"); - goto error; -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index ef3647e6a69b..1500ddd3a79f 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -78,6 +78,29 @@ typedef struct - #define USERIAL_BAUD_4M 15 - #define USERIAL_BAUD_AUTO 16 - -+/* Vendor specific baud rate values */ -+#define UART_Baud_Rate_Baud_9600 4 -+#define UART_Baud_Rate_Baud_19200 3 -+#define UART_Baud_Rate_Baud_57600 1 -+#define UART_Baud_Rate_Baud_115200 0 -+#define UART_Baud_Rate_Baud_230400 5 -+#define UART_Baud_Rate_Baud_460800 7 -+#define UART_Baud_Rate_Baud_921600 10 -+#define UART_Baud_Rate_Baud_1000000 11 -+#define UART_Baud_Rate_Baud_2000000 13 -+#define UART_Baud_Rate_Baud_3000000 14 -+#define UART_Baud_Rate_Baud_4000000 15 -+ -+#define UART_Baud_Rate_Baud_250000 6 -+#define UART_Baud_Rate_Baud_500000 8 -+#define UART_Baud_Rate_Baud_720000 9 -+#define UART_Baud_Rate_Baud_125000 12 -+#define UART_Baud_Rate_Baud_1600000 16 -+#define UART_Baud_Rate_Baud_3200000 17 -+#define UART_Baud_Rate_Baud_3500000 18 -+ -+ -+ - #ifndef FALSE - #define FALSE 0 - #endif diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-Override-PCM-Settings-by-reading-configuration-file.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-Override-PCM-Settings-by-reading-configuration-file.patch deleted file mode 100644 index c86dee8e7..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-Override-PCM-Settings-by-reading-configuration-file.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: Kamal Negi -Date: Tue, 30 Dec 2014 19:15:08 +0530 -Subject: [PATCH] Override PCM Settings by reading configuration file - -Configure the PCM role as master or slave depending upon -the platform's support. This configuration is provided -in the config file which is read during the firmware -download process and the default PCM configuration is -overwritten with this value. - -Change-Id: If0eae58b4cd32d75b3bcb669bc73dca67652473c -Signed-off-by: Kamal Negi ---- - tools/hciattach_rome.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++--- - tools/hciattach_rome.h | 8 ++++++ - 2 files changed, 71 insertions(+), 4 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 37974290ae0a..99866e23e99e 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1,6 +1,6 @@ - /* - * -- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. - * Not a Contribution. - * - * Copyright 2012 The Android Open Source Project -@@ -873,6 +873,44 @@ error: - return err; - } - -+int get_value_from_config(char *file_path,char *param) -+{ -+ FILE *pfile = NULL; -+ char *line = NULL; -+ char *pch = NULL; -+ char param_str[20]; -+ int bytes_read = 0, position; -+ int ret = -1; -+ -+ if (!file_path || !param) { -+ fprintf(stderr,"Invalid arguments\n"); -+ return -EINVAL; -+ } -+ -+ pfile = fopen(file_path, "r" ); -+ if (!pfile) { -+ fprintf(stderr, "Failed to open %s\n", file_path); -+ return ret; -+ } -+ -+ while (getline(&line, &bytes_read, pfile) > 0 ) { -+ if (line[0] != '#' && line[0] != '\n') { -+ pch = memchr(line, '=', strlen(line)); -+ if (pch != NULL) { -+ position = pch - line; -+ strncpy(param_str, line, position); -+ if (strncmp(param_str, param, position) == 0) { -+ ret = atoi(pch + 1); -+ break; -+ } -+ } -+ } -+ } -+ free(line); -+ fclose(pfile); -+ return ret; -+} -+ - int rome_get_tlv_file(char *file_path) - { - FILE * pFile; -@@ -884,7 +922,7 @@ int rome_get_tlv_file(char *file_path) - unsigned char data_buf[PRINT_BUF_SIZE]={0,}; - unsigned char *nvm_byte_ptr; - unsigned char bdaddr[6]; -- -+ unsigned short pcm_value; - fprintf(stderr, "File Open (%s)\n", file_path); - pFile = fopen ( file_path , "r" ); - if (pFile==NULL) {; -@@ -970,9 +1008,30 @@ int rome_get_tlv_file(char *file_path) - *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), - *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); - } -+ /* Read from file and check what PCM Configuration is required: -+ * Master = 0 /Slave = 1 */ -+ /* Override PCM configuration */ -+ if (nvm_ptr->tag_id == TAG_NUM_44) { -+ if ((pcm_value = -+ get_value_from_config(PCM_CONFIG_FILE_PATH, "PCM")) >= 0) { -+ -+ if (pcm_value == PCM_SLAVE) { -+ nvm_byte_ptr[PCM_MS_OFFSET_1] |= -+ (1 << PCM_ROLE_BIT_OFFSET); -+ nvm_byte_ptr[PCM_MS_OFFSET_2] |= -+ (1 << PCM_ROLE_BIT_OFFSET); -+ } else if (pcm_value == PCM_MASTER) { -+ nvm_byte_ptr[PCM_MS_OFFSET_1] &= -+ (~(1 << PCM_ROLE_BIT_OFFSET)); -+ nvm_byte_ptr[PCM_MS_OFFSET_2] &= -+ (~(1 << PCM_ROLE_BIT_OFFSET)); -+ } -+ } -+ } - -- for(i =0;(itag_len && (i*3 + 2) tag_len && (i*3 + 2) < PRINT_BUF_SIZE);i++) -+ snprintf((char *) data_buf, PRINT_BUF_SIZE, "%s%.02x ", -+ (char *)data_buf, *(nvm_byte_ptr + i)); - - fprintf(stderr, "TAG Data\t\t\t : %s\n", data_buf); - -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 1500ddd3a79f..f591c10e4f2b 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -202,8 +202,15 @@ typedef struct - #define NVM_ACCESS_SET 0x01 - #define TAG_NUM_OFFSET 5 - #define TAG_NUM_2 2 -+#define TAG_NUM_44 44 - #define TAG_BDADDR_OFFSET 7 - -+#define PCM_MS_OFFSET_1 9 -+#define PCM_MS_OFFSET_2 33 -+ -+#define PCM_SLAVE 1 -+#define PCM_MASTER 0 -+#define PCM_ROLE_BIT_OFFSET 4 - #define MAX_RETRY_CNT 1 - #define SELECT_TIMEOUT 3 - -@@ -240,6 +247,7 @@ typedef struct - #define ROME_SKIP_EVT_CC 0x02 - #define ROME_SKIP_EVT_VSE_CC 0x03 - -+#define PCM_CONFIG_FILE_PATH "/etc/bluetooth/pcm.conf" - /****************************************************************************** - ** Local type definitions - ******************************************************************************/ diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-Add-support-for-Tufello-1.1-SOC.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-Add-support-for-Tufello-1.1-SOC.patch deleted file mode 100644 index f47a9d47e..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-Add-support-for-Tufello-1.1-SOC.patch +++ /dev/null @@ -1,169 +0,0 @@ -From: Rupesh Tatiya -Date: Thu, 29 Jan 2015 15:36:27 +0530 -Subject: [PATCH] Add support for Tufello 1.1 SOC - -Enable mechanism to download firmware for Tufello 1.1 SOC. -Also, use correct firmware file path for Tufello 1.0. - -Change-Id: I915e48023e45de9e2550336a3de9a07f2b788189 -Signed-off-by: Rupesh Tatiya ---- - tools/hciattach_rome.c | 29 ++++++++++++++++++----------- - tools/hciattach_rome.h | 10 +++++++--- - 2 files changed, 25 insertions(+), 14 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 99866e23e99e..fee36f904e04 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -621,7 +621,7 @@ int rome_edl_set_patch_request(int fd) - -1, PATCH_HDR_LEN + 1); - - /* Total length of the packet to be sent to the Controller */ -- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); - - /* Send HCI Command packet to Controller */ - err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -@@ -670,7 +670,7 @@ int rome_edl_patch_download_request(int fd) - index, MAX_DATA_PER_SEGMENT); - - /* Total length of the packet to be sent to the Controller */ -- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); - - /* Initialize the RSP packet everytime to 0 */ - memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); -@@ -707,7 +707,7 @@ int rome_edl_patch_download_request(int fd) - memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); - - /* Total length of the packet to be sent to the Controller */ -- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); - - /* Send HCI Command packet to Controller */ - err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -@@ -824,7 +824,7 @@ int rome_attach_rampatch(int fd) - -1, EDL_PATCH_CMD_LEN); - - /* Total length of the packet to be sent to the Controller */ -- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); - - /* Send HCI Command packet to Controller */ - err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); -@@ -854,7 +854,7 @@ int rome_rampatch_reset(int fd) - -1, EDL_PATCH_CMD_LEN); - - /* Total length of the packet to be sent to the Controller */ -- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); -+ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); - - /* Send HCI Command packet to Controller */ - err = write(fd, cmd, size); -@@ -1058,7 +1058,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc - unsigned char cmd[HCI_MAX_CMD_SIZE]; - unsigned char rsp[HCI_MAX_EVENT_SIZE]; - -- fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d\n", __FUNCTION__, index, seg_size); -+ fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d wait_cc_evt = 0x%x\n", __FUNCTION__, index, seg_size, wait_cc_evt); - - /* Frame the HCI CMD PKT to be sent to Controller*/ - frame_hci_cmd_pkt(cmd, EDL_PATCH_TLV_REQ_CMD, 0, index, seg_size); -@@ -1092,6 +1092,7 @@ int rome_tlv_dnld_req(int fd, int tlv_size) - { - int total_segment, remain_size, i, err = -1; - unsigned char wait_cc_evt; -+ unsigned int rom = rome_ver >> 16; - - total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; - remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\ -@@ -1132,14 +1133,15 @@ int rome_tlv_dnld_req(int fd, int tlv_size) - - for(i = 0; i < total_segment; i++) { - if((i+1) == total_segment) { -- if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && -+ if ((rom >= ROME_PATCH_VER_0100) && (rom < ROME_PATCH_VER_0302) && - (gTlv_type == TLV_TYPE_PATCH)) { - /* If the Rome version is from 1.1 to 3.1 - * 1. No CCE for the last command segment but all other segment - * 2. All the command segments get VSE including the last one - */ - wait_cc_evt = !remain_size ? FALSE: TRUE; -- } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { -+ } else if ((rom == ROME_PATCH_VER_0302) && -+ (gTlv_type == TLV_TYPE_PATCH)) { - /* If the Rome version is 3.2 - * 1. None of the command segments receive CCE - * 2. No command segments receive VSE except the last one -@@ -1158,13 +1160,14 @@ int rome_tlv_dnld_req(int fd, int tlv_size) - goto error; - } - -- if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { -+ if ((rom >= ROME_PATCH_VER_0100) && (rom < ROME_PATCH_VER_0302) && -+ (gTlv_type == TLV_TYPE_PATCH)) { - /* If the Rome version is from 1.1 to 3.1 - * 1. No CCE for the last command segment but all other segment - * 2. All the command segments get VSE including the last one - */ - wait_cc_evt = remain_size ? FALSE: TRUE; -- } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { -+ } else if ((rom == ROME_PATCH_VER_0302) && (gTlv_type == TLV_TYPE_PATCH)) { - /* If the Rome version is 3.2 - * 1. None of the command segments receive CCE - * 2. No command segments receive VSE except the last one -@@ -1837,6 +1840,10 @@ int qca_soc_init(int fd, int speed, char *bdaddr) - case TUFELLO_VER_1_0: - rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; - nvm_file_path = TF_NVM_TLV_1_0_0_PATH; -+ goto download; -+ case TUFELLO_VER_1_1: -+ rampatch_file_path = TF_RAMPATCH_TLV_1_0_1_PATH; -+ nvm_file_path = TF_NVM_TLV_1_0_1_PATH; - - download: - /* Check if user requested for 115200 kbps */ -@@ -1881,7 +1888,7 @@ download: - fprintf(stderr, "HCI Reset Failed !!!\n"); - goto error; - } -- fprintf(stderr, "HCI Reset is done\n"); -+ fprintf(stderr, "HCI Reset is done\n"); - - break; - case ROME_VER_UNKNOWN: -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index f591c10e4f2b..95d5f1e8a5c2 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -238,8 +238,10 @@ typedef struct - #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" - #define ROME_RAMPATCH_TLV_3_0_2_PATH "/lib/firmware/qca/rampatch_tlv_3.2.tlv" - #define ROME_NVM_TLV_3_0_2_PATH "/lib/firmware/qca/nvm_tlv_3.2.bin" --#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" --#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" -+#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/qca/rampatch_tlv_tf_1.0.tlv" -+#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/qca/nvm_tlv_tf_1.0.bin" -+#define TF_RAMPATCH_TLV_1_0_1_PATH "/lib/firmware/qca/rampatch_tlv_tf_1.1.tlv" -+#define TF_NVM_TLV_1_0_1_PATH "/lib/firmware/qca/nvm_tlv_tf_1.1.bin" - - /* This header value in rampatch file decides event handling mechanism in the HOST */ - #define ROME_SKIP_EVT_NONE 0x00 -@@ -357,6 +359,7 @@ enum{ - ROME_SOC_ID_11 = 0x00000011, - ROME_SOC_ID_13 = 0x00000013, - ROME_SOC_ID_22 = 0x00000022, -+ ROME_SOC_ID_23 = 0x00000023, - ROME_SOC_ID_44 = 0x00000044 - }; - -@@ -368,6 +371,7 @@ enum{ - ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), - ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), - ROME_VER_3_2 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_44 ), -- TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) -+ TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ), -+ TUFELLO_VER_1_1 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_23 ) - }; - #endif /* HW_ROME_H */ diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch deleted file mode 100644 index ffb182062..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Anantha Krishnan -Date: Wed, 4 Feb 2015 12:29:07 +0530 -Subject: [PATCH] bluetooth: Vote UART CLK ON prior to firmware download - process - -Before starting the firmware download process, vote UART CLK ON -to avoid triggering the dynamic suspend of UART driver. Post -firmware download and in error scenarios vote UART CLK OFF. - -As per design, the UART driver enters into dynamic suspend if -there are no activity on the UART lines for 100ms. Depending upon -the rampatch size, the BT Controller takes time to apply the -downloaded rampatch segments and in sending the vendor specific -event. If the BT Controller takes > 100ms time in sending the -vendor specific event, the UART driver enters into suspend state. - -As a result, UART driver fails to process the last vendor specific -event sent by the BT Controller. The VSE sent by BT Controller -wakes up the UART driver, but the data is not processed causing -firmware download failures. - -Hence, vote UART CLK ON prior to firmware download process and -vote UART CLK OFF post firmware download proess and in error -scenarios. - -Change-Id: I447ded33ad1cfaa020b491effce368fbfe41f894 ---- - tools/hciattach_rome.c | 13 +++++++++++++ - tools/hciattach_rome.h | 2 ++ - 2 files changed, 15 insertions(+) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index fee36f904e04..574ceac6c750 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1762,6 +1762,14 @@ int qca_soc_init(int fd, int speed, char *bdaddr) - int size, local_baud_rate = 0, controller_baud_rate = 0; - - vnd_userial.fd = fd; -+ -+ /* Vote for UART CLK prior to FW download */ -+ err = ioctl(fd, USERIAL_OP_CLK_ON); -+ if (err < 0) { -+ fprintf(stderr, "%s: Failed to vote UART CLK ON\n", __func__); -+ return -1; -+ } -+ - /* Get Rome version information */ - if((err = rome_patch_ver_req(fd)) <0){ - fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); -@@ -1899,5 +1907,10 @@ download: - } - - error: -+ /* Vote UART CLK OFF post to FW download */ -+ err = ioctl(fd, USERIAL_OP_CLK_OFF); -+ if (err < 0) -+ fprintf(stderr, "%s: Failed to vote UART CLK OFF!!!\n", __func__); -+ - return err; - } -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 95d5f1e8a5c2..20264f9978d9 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -42,6 +42,8 @@ - #define BD_ADDR_LEN 6 - #define MSM_ENABLE_FLOW_CTRL 16 - #define MSM_DISABLE_FLOW_CTRL 17 -+#define USERIAL_OP_CLK_ON 0x5441 -+#define USERIAL_OP_CLK_OFF 0x5442 - - unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - typedef enum { diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0017-Override-IBS-settings-by-reading-configuration-file.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0017-Override-IBS-settings-by-reading-configuration-file.patch deleted file mode 100644 index 0a1e865ba..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0017-Override-IBS-settings-by-reading-configuration-file.patch +++ /dev/null @@ -1,127 +0,0 @@ -From: Kamal Negi -Date: Thu, 30 Apr 2015 15:53:06 +0530 -Subject: [PATCH] Override IBS settings by reading configuration file - -Configure the IBS value in Firmware by reading the -configuration file.This configuration value is -provided in the config file which is read during -the firmware download process and the default -configuration value is overwritten with this value. - -Change-Id: I47992a573b3137ac9bfb80538727981f56b328c4 -Signed-off-by: Kamal Negi ---- - tools/hciattach_rome.c | 42 +++++++++++++++++++++++++++++------------- - tools/hciattach_rome.h | 24 ++++++++++++++++-------- - 2 files changed, 45 insertions(+), 21 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 574ceac6c750..6a3f33867c12 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -922,7 +922,8 @@ int rome_get_tlv_file(char *file_path) - unsigned char data_buf[PRINT_BUF_SIZE]={0,}; - unsigned char *nvm_byte_ptr; - unsigned char bdaddr[6]; -- unsigned short pcm_value; -+ unsigned short pcm_value, ibs_value; -+ - fprintf(stderr, "File Open (%s)\n", file_path); - pFile = fopen ( file_path , "r" ); - if (pFile==NULL) {; -@@ -1008,23 +1009,38 @@ int rome_get_tlv_file(char *file_path) - *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), - *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); - } -+ -+ if (nvm_ptr->tag_id == TAG_NUM_17) { -+ if ((ibs_value = -+ get_value_from_config(FW_CONFIG_FILE_PATH, "IBS")) >= 0) { -+ if (ibs_value == FWCONF_IBS_DISABLE) { -+ nvm_byte_ptr[FWCONF_IBS_VAL_OFFSET] &= -+ (~(FWCONF_IBS_ENABLE << -+ FWCONF_IBS_VAL_BIT)); -+ } else if (ibs_value == FWCONF_IBS_ENABLE) { -+ nvm_byte_ptr[FWCONF_IBS_VAL_OFFSET] |= -+ (FWCONF_IBS_ENABLE << -+ FWCONF_IBS_VAL_BIT); -+ } -+ } -+ } - /* Read from file and check what PCM Configuration is required: - * Master = 0 /Slave = 1 */ - /* Override PCM configuration */ - if (nvm_ptr->tag_id == TAG_NUM_44) { - if ((pcm_value = -- get_value_from_config(PCM_CONFIG_FILE_PATH, "PCM")) >= 0) { -- -- if (pcm_value == PCM_SLAVE) { -- nvm_byte_ptr[PCM_MS_OFFSET_1] |= -- (1 << PCM_ROLE_BIT_OFFSET); -- nvm_byte_ptr[PCM_MS_OFFSET_2] |= -- (1 << PCM_ROLE_BIT_OFFSET); -- } else if (pcm_value == PCM_MASTER) { -- nvm_byte_ptr[PCM_MS_OFFSET_1] &= -- (~(1 << PCM_ROLE_BIT_OFFSET)); -- nvm_byte_ptr[PCM_MS_OFFSET_2] &= -- (~(1 << PCM_ROLE_BIT_OFFSET)); -+ get_value_from_config(FW_CONFIG_FILE_PATH, "PCM")) >= 0) { -+ -+ if (pcm_value == FWCONF_PCM_SLAVE) { -+ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_1] |= -+ (1 << FWCONF_PCM_ROLE_BIT_OFFSET); -+ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_2] |= -+ (1 << FWCONF_PCM_ROLE_BIT_OFFSET); -+ } else if (pcm_value == FWCONF_PCM_MASTER) { -+ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_1] &= -+ (~(1 << FWCONF_PCM_ROLE_BIT_OFFSET)); -+ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_2] &= -+ (~(1 << FWCONF_PCM_ROLE_BIT_OFFSET)); - } - } - } -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 20264f9978d9..8eaeeed8bc96 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -203,16 +203,24 @@ typedef struct - #define TAG_END 0xFF - #define NVM_ACCESS_SET 0x01 - #define TAG_NUM_OFFSET 5 --#define TAG_NUM_2 2 --#define TAG_NUM_44 44 -+#define TAG_NUM_2 2 -+#define TAG_NUM_17 (17) -+#define TAG_NUM_44 44 - #define TAG_BDADDR_OFFSET 7 - --#define PCM_MS_OFFSET_1 9 --#define PCM_MS_OFFSET_2 33 -+/* FW PCM Configuration */ -+#define FWCONF_PCM_MS_OFFSET_1 9 -+#define FWCONF_PCM_MS_OFFSET_2 33 -+#define FWCONF_PCM_SLAVE 1 -+#define FWCONF_PCM_MASTER 0 -+#define FWCONF_PCM_ROLE_BIT_OFFSET 4 -+ -+/* FW IBS Configuration */ -+#define FWCONF_IBS_DISABLE (0) -+#define FWCONF_IBS_ENABLE (1) -+#define FWCONF_IBS_VAL_BIT (7) -+#define FWCONF_IBS_VAL_OFFSET (0) - --#define PCM_SLAVE 1 --#define PCM_MASTER 0 --#define PCM_ROLE_BIT_OFFSET 4 - #define MAX_RETRY_CNT 1 - #define SELECT_TIMEOUT 3 - -@@ -251,7 +259,7 @@ typedef struct - #define ROME_SKIP_EVT_CC 0x02 - #define ROME_SKIP_EVT_VSE_CC 0x03 - --#define PCM_CONFIG_FILE_PATH "/etc/bluetooth/pcm.conf" -+#define FW_CONFIG_FILE_PATH "/etc/bluetooth/firmware.conf" - /****************************************************************************** - ** Local type definitions - ******************************************************************************/ diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch deleted file mode 100644 index 003364c2c..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: Kamal Negi -Date: Fri, 8 May 2015 15:01:02 +0530 -Subject: [PATCH] Handle NULL Pointer derefrencing in AVRCP Target role - -Check NULL pointer to AVRCP controller role initialized or not. -If remote device don't support the AVRCP target role, then HOST dont -initialize AVRCP controller role and directly dereference the controller -role and segfault happens. - -Change-Id: Ibbb9452f17a576c3a79a53ea72e0211982752144 -Signed-off-by: Kamal Negi ---- - profiles/audio/avrcp.c | 27 ++++++++++++++++++++++----- - 1 file changed, 22 insertions(+), 5 deletions(-) - -diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c -index c100149acf42..d8cb0ed96a1f 100644 ---- a/profiles/audio/avrcp.c -+++ b/profiles/audio/avrcp.c -@@ -2082,13 +2082,19 @@ static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, - void *user_data) - { - struct avrcp *session = user_data; -- struct avrcp_player *player = session->controller->player; -- struct media_player *mp = player->user_data; -+ struct avrcp_player *player; -+ struct media_player *mp; - struct avrcp_header *pdu = (void *) operands; - uint32_t duration; - uint32_t position; - uint8_t status; - -+ if (!session || !session->controller) -+ return FALSE; -+ -+ player = session->controller->player; -+ mp = player->user_data; -+ - if (pdu == NULL || code == AVC_CTYPE_REJECTED || - ntohs(pdu->params_len) != 9) - return FALSE; -@@ -2146,12 +2152,18 @@ static gboolean avrcp_player_value_rsp(struct avctp *conn, uint8_t code, - void *user_data) - { - struct avrcp *session = user_data; -- struct avrcp_player *player = session->controller->player; -- struct media_player *mp = player->user_data; -+ struct avrcp_player *player; -+ struct media_player *mp; - struct avrcp_header *pdu = (void *) operands; - uint8_t count; - int i; - -+ if (!session || !session->controller) -+ return FALSE; -+ -+ player = session->controller->player; -+ mp = player->user_data; -+ - if (pdu == NULL) { - media_player_set_setting(mp, "Error", "Timeout"); - return FALSE; -@@ -2303,10 +2315,15 @@ static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn, - void *user_data) - { - struct avrcp *session = user_data; -- struct avrcp_player *player = session->controller->player; -+ struct avrcp_player *player; - struct avrcp_header *pdu = (void *) operands; - uint8_t count; - -+ if (!session || !session->controller) -+ return FALSE; -+ -+ player = session->controller->player; -+ - if (code == AVC_CTYPE_REJECTED) - return FALSE; - diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0019-bluetooth-Fix-flow-control-operation.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0019-bluetooth-Fix-flow-control-operation.patch deleted file mode 100644 index ce05c2928..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0019-bluetooth-Fix-flow-control-operation.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Dibyendu Roy -Date: Fri, 22 May 2015 18:57:05 +0530 -Subject: [PATCH] bluetooth: Fix flow control operation - -Flow off operation was not actually happening at the UART line level, -since the argument passed was not being used correctly. As a result, -sometimes command complete and VS event were sent by BT SOC even -before the local UART Controller could change its baud rate to the -newer one(3 Mbps). This led to VS event being processed -incorrectly which in turn causes baud rate change to fail. - -CRs-Fixed: 844730 -Change-Id: I06d8c4ed7807aa47dd5498642c7a23c9189a1cff -Signed-off-by: Dibyendu Roy ---- - tools/hciattach_rome.c | 6 +++--- - tools/hciattach_rome.h | 4 ++-- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 6a3f33867c12..0d7014f1d2f6 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1544,10 +1544,10 @@ static void flow_control(int fd, int opt) - c_opt.c_cc[VMIN] = 0; /* blocking read until 8 chars received */ - c_opt.c_cflag &= ~CSIZE; - c_opt.c_cflag |= (CS8 | CLOCAL | CREAD); -- if (MSM_ENABLE_FLOW_CTRL) -+ if (opt == MSM_ENABLE_FLOW_CTRL) - c_opt.c_cflag |= CRTSCTS; -- else if (MSM_DISABLE_FLOW_CTRL) -- c_opt.c_cflag |= ~CRTSCTS; -+ else if (opt == MSM_DISABLE_FLOW_CTRL) -+ c_opt.c_cflag &= ~CRTSCTS; - else { - fprintf(stderr, "%s: Incorrect option passed for TIOCMSET\n", __func__); - return; -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 8eaeeed8bc96..3fdaf208e522 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -40,8 +40,8 @@ - #define NVITEM_SIZE 2 - #define PERSIST_HEADER_LEN 3 - #define BD_ADDR_LEN 6 --#define MSM_ENABLE_FLOW_CTRL 16 --#define MSM_DISABLE_FLOW_CTRL 17 -+#define MSM_DISABLE_FLOW_CTRL 0 -+#define MSM_ENABLE_FLOW_CTRL 1 - #define USERIAL_OP_CLK_ON 0x5441 - #define USERIAL_OP_CLK_OFF 0x5442 - diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch deleted file mode 100644 index c2987d399..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: Dibyendu Roy -Date: Thu, 11 Jun 2015 12:07:43 +0530 -Subject: [PATCH] Adding MDM specific code under _PLATFORM_MDM_ - -This patch is added to comment out the commit -84cc0e12983b5761c67789ef93fd6fb164c7314d in x86 as -dynamic suspend feature is not available in x86. However, -this code shall be active for MDM platform due to -dynamic suspend feature. - -Change-Id: I998f0521b4a5f9744412db40f2c2d3bff2ac3d11 ---- - tools/hciattach_rome.c | 5 ++++- - tools/hciattach_rome.h | 3 +++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 0d7014f1d2f6..1891de24e21a 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -1779,13 +1779,14 @@ int qca_soc_init(int fd, int speed, char *bdaddr) - - vnd_userial.fd = fd; - -+#ifdef _PLATFORM_MDM_ - /* Vote for UART CLK prior to FW download */ - err = ioctl(fd, USERIAL_OP_CLK_ON); - if (err < 0) { - fprintf(stderr, "%s: Failed to vote UART CLK ON\n", __func__); - return -1; - } -- -+#endif - /* Get Rome version information */ - if((err = rome_patch_ver_req(fd)) <0){ - fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); -@@ -1923,10 +1924,12 @@ download: - } - - error: -+#ifdef _PLATFORM_MDM_ - /* Vote UART CLK OFF post to FW download */ - err = ioctl(fd, USERIAL_OP_CLK_OFF); - if (err < 0) - fprintf(stderr, "%s: Failed to vote UART CLK OFF!!!\n", __func__); -+#endif - - return err; - } -diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h -index 3fdaf208e522..89f7db3bef86 100644 ---- a/tools/hciattach_rome.h -+++ b/tools/hciattach_rome.h -@@ -42,8 +42,11 @@ - #define BD_ADDR_LEN 6 - #define MSM_DISABLE_FLOW_CTRL 0 - #define MSM_ENABLE_FLOW_CTRL 1 -+ -+#ifdef _PLATFORM_MDM_ - #define USERIAL_OP_CLK_ON 0x5441 - #define USERIAL_OP_CLK_OFF 0x5442 -+#endif - - unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - typedef enum { diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0021-Bluetooth-Fix-static-analysis-issues.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0021-Bluetooth-Fix-static-analysis-issues.patch deleted file mode 100644 index 97a865291..000000000 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0021-Bluetooth-Fix-static-analysis-issues.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Dibyendu Roy -Date: Mon, 6 Jul 2015 13:30:53 +0530 -Subject: [PATCH] Bluetooth: Fix static analysis issues - -Change-Id: Ida91f012544c39a8aaa6e7db23f1d5b68d3bec08 ---- - tools/hciattach_rome.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c -index 1891de24e21a..59bdc16e4e8f 100644 ---- a/tools/hciattach_rome.c -+++ b/tools/hciattach_rome.c -@@ -933,7 +933,13 @@ int rome_get_tlv_file(char *file_path) - - /* Get File Size */ - fseek (pFile , 0 , SEEK_END); -- fileSize = ftell (pFile); -+ -+ if((fileSize = ftell(pFile)) < 0) { -+ fprintf(stderr, "%s: fail to get current file position\n", file_path); -+ fclose (pFile); -+ return -1; -+ } -+ - rewind (pFile); - - pdata_buffer = (unsigned char*) malloc (sizeof(char)*fileSize); -@@ -1107,7 +1113,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc - int rome_tlv_dnld_req(int fd, int tlv_size) - { - int total_segment, remain_size, i, err = -1; -- unsigned char wait_cc_evt; -+ unsigned char wait_cc_evt = FALSE; - unsigned int rom = rome_ver >> 16; - - total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend index 188c4533f..c99d87434 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -7,33 +7,15 @@ SRC_URI += " \ file://main.conf \ file://0001-hcitool-do-not-show-unsupported-refresh-option.patch \ file://0002-hcitool-increase-the-shown-connection-limit-to-20.patch \ - file://0025-port-test-discovery-to-python3.patch \ - file://0027-example-gatt-server-update-example-to-master-version.patch \ + file://0007-port-test-discovery-to-python3.patch \ + file://0008-example-gatt-server-update-example-to-master-version.patch \ " QCA6564_COMMON_PATCHES = " \ - file://0003-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch \ - file://0004-bluetooth-Enable-bluetooth-low-power-mode-functional.patch \ - file://0005-bluetooth-Fix-bug-in-firmware-parsing-mechanism.patch \ - file://0006-bluetooth-Configure-BD-Address.patch \ - file://0007-bluetooth-Remove-unused-functions-in-the-firmware-do.patch \ - file://0008-bluetooth-Enable-3Mbps-baud-rate-support.patch \ - file://0009-bluetooth-Check-TTY-buffer-for-data-availability-bef.patch \ - file://0010-bluetooth-Add-support-for-TUFEELO-firmware-download.patch \ - file://0011-bluetooth-Add-support-for-ROME-3.2-SOC.patch \ - file://0012-bluetooth-Use-correct-TTY-ioctl-calls-for-flow-contr.patch \ - file://0013-bluetooth-Add-support-for-multi-baud-rate.patch \ - file://0014-Override-PCM-Settings-by-reading-configuration-file.patch \ - file://0015-Add-support-for-Tufello-1.1-SOC.patch \ - file://0016-bluetooth-Vote-UART-CLK-ON-prior-to-firmware-downloa.patch \ - file://0017-Override-IBS-settings-by-reading-configuration-file.patch \ - file://0018-Handle-NULL-Pointer-derefrencing-in-AVRCP-Target-rol.patch \ - file://0019-bluetooth-Fix-flow-control-operation.patch \ - file://0020-Adding-MDM-specific-code-under-_PLATFORM_MDM_.patch \ - file://0021-Bluetooth-Fix-static-analysis-issues.patch \ - file://0022-hciattach_rome-Respect-the-user-indication-for-noflo.patch \ - file://0023-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch \ - file://0024-hciattach-Add-verbosity-option.patch \ + file://0003-QCA_bluetooth_chip_support.patch \ + file://0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch \ + file://0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch \ + file://0006-hciattach-Add-verbosity-option.patch \ " SRC_URI_append_ccimx6ul = " ${QCA6564_COMMON_PATCHES}" From e3e0230c6fafb9f17df19a236794ee7a5774cec1 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Fri, 3 Nov 2017 18:00:17 +0100 Subject: [PATCH 081/113] bluez: reorder commits For avoid compilation error due to platform specific patches, first apply the common patches and later apply platform specific patches. Signed-off-by: Isaac Hermida --- ...tch => 0003-port-test-discovery-to-python3.patch} | 0 ...tt-server-update-example-to-master-version.patch} | 0 ...t.patch => 0005-QCA_bluetooth_chip_support.patch} | 0 ...rome-Respect-the-user-indication-for-noflo.patch} | 0 ...ttach-If-the-user-supplies-a-bdaddr-use-it.patch} | 0 ...tch => 0008-hciattach-Add-verbosity-option.patch} | 0 .../recipes-connectivity/bluez/bluez5_5.41.bbappend | 12 ++++++------ 7 files changed, 6 insertions(+), 6 deletions(-) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0007-port-test-discovery-to-python3.patch => 0003-port-test-discovery-to-python3.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0008-example-gatt-server-update-example-to-master-version.patch => 0004-example-gatt-server-update-example-to-master-version.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0003-QCA_bluetooth_chip_support.patch => 0005-QCA_bluetooth_chip_support.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch => 0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch => 0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0006-hciattach-Add-verbosity-option.patch => 0008-hciattach-Add-verbosity-option.patch} (100%) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-port-test-discovery-to-python3.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-port-test-discovery-to-python3.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-port-test-discovery-to-python3.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-port-test-discovery-to-python3.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-example-gatt-server-update-example-to-master-version.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-example-gatt-server-update-example-to-master-version.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-example-gatt-server-update-example-to-master-version.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-example-gatt-server-update-example-to-master-version.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-QCA_bluetooth_chip_support.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-QCA_bluetooth_chip_support.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-QCA_bluetooth_chip_support.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-QCA_bluetooth_chip_support.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach-Add-verbosity-option.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-hciattach-Add-verbosity-option.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach-Add-verbosity-option.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-hciattach-Add-verbosity-option.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend index c99d87434..c75e99a53 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -7,15 +7,15 @@ SRC_URI += " \ file://main.conf \ file://0001-hcitool-do-not-show-unsupported-refresh-option.patch \ file://0002-hcitool-increase-the-shown-connection-limit-to-20.patch \ - file://0007-port-test-discovery-to-python3.patch \ - file://0008-example-gatt-server-update-example-to-master-version.patch \ + file://0003-port-test-discovery-to-python3.patch \ + file://0004-example-gatt-server-update-example-to-master-version.patch \ " QCA6564_COMMON_PATCHES = " \ - file://0003-QCA_bluetooth_chip_support.patch \ - file://0004-hciattach_rome-Respect-the-user-indication-for-noflo.patch \ - file://0005-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch \ - file://0006-hciattach-Add-verbosity-option.patch \ + file://0005-QCA_bluetooth_chip_support.patch \ + file://0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch \ + file://0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch \ + file://0008-hciattach-Add-verbosity-option.patch \ " SRC_URI_append_ccimx6ul = " ${QCA6564_COMMON_PATCHES}" From 9053e0c3182cecf1ea737ef9a7f60ff7f818cdc3 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Fri, 3 Nov 2017 18:21:50 +0100 Subject: [PATCH 082/113] bluez: Fix BR/EDR pairing for dual mode devices Subset of commits to fix the pairing for dual mode devices. Main commit that fixes is 2d3685252a21cda4b918ad1cc4dd0572bd5c6d3c, but some previous commits are required as well. """ For dual mode devices we need to pass address type used in pairing events to reply with correct one on agent reply. Otherwise reply for BR/EDR pairing of dual mode device would use address type (which is valid only for LE address) resulting in reply being ignored by kernel and eventually pairing timeout. """ https://jira.digi.com/browse/DEL-5226 Signed-off-by: Isaac Hermida --- ...DR-over-LE-if-it-set-in-advertisemen.patch | 47 +++++ ...Fix-not-connecting-services-properly.patch | 38 ++++ ...device-Fix-marking-auto-connect-flag.patch | 29 +++ ...refer-bonded-bearers-when-connecting.patch | 30 +++ ...ccept-and-.disconnect-instead-of-att.patch | 137 +++++++++++++ ...-bonding-while-failed-to-pair-device.patch | 99 +++++++++ ...BR-EDR-pairing-for-dual-mode-devices.patch | 189 ++++++++++++++++++ ... => 0012-QCA_bluetooth_chip_support.patch} | 0 ...spect-the-user-indication-for-noflo.patch} | 0 ...f-the-user-supplies-a-bdaddr-use-it.patch} | 0 ...0015-hciattach-Add-verbosity-option.patch} | 0 .../bluez/bluez5_5.41.bbappend | 15 +- 12 files changed, 580 insertions(+), 4 deletions(-) create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-core-device-Fix-not-connecting-services-properly.patch create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-core-device-Fix-marking-auto-connect-flag.patch create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-core-device-Prefer-bonded-bearers-when-connecting.patch create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-src-device-Free-bonding-while-failed-to-pair-device.patch create mode 100644 meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0005-QCA_bluetooth_chip_support.patch => 0012-QCA_bluetooth_chip_support.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch => 0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch => 0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch} (100%) rename meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/{0008-hciattach-Add-verbosity-option.patch => 0015-hciattach-Add-verbosity-option.patch} (100%) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch new file mode 100644 index 000000000..310dd5a1b --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch @@ -0,0 +1,47 @@ +From 2f78f64aee11dde478fd76f1e15bb1b977ba7099 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Wed, 10 Aug 2016 16:23:56 +0300 +Subject: [PATCH 1/7] core: Prefer BR/EDR over LE if it set in advertisement + flag + +This makes the code prefer BR/EDR if the last advertisement has it set +in the flags. +--- + src/adapter.c | 5 ++++- + src/device.c | 6 +++++- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/adapter.c b/src/adapter.c +index 37423985dfb4..ddabf2de5462 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -5488,8 +5488,11 @@ static void update_found_devices(struct btd_adapter *adapter, + * supports this we can make the non-zero check conditional. + */ + if (bdaddr_type != BDADDR_BREDR && eir_data.flags && +- !(eir_data.flags & EIR_BREDR_UNSUP)) ++ !(eir_data.flags & EIR_BREDR_UNSUP)) { + device_set_bredr_support(dev); ++ /* Update last seen for BR/EDR in case its flag is set */ ++ device_update_last_seen(dev, BDADDR_BREDR); ++ } + + if (eir_data.name != NULL && eir_data.name_complete) + device_store_cached_name(dev, eir_data.name); +diff --git a/src/device.c b/src/device.c +index 82704f8bb343..7f40af44cd01 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -1763,7 +1763,11 @@ static uint8_t select_conn_bearer(struct btd_device *dev) + if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME)) + return dev->bdaddr_type; + +- if (bredr_last < le_last) ++ /* ++ * Prefer BR/EDR if time is the same since it might be from an ++ * advertisement with BR/EDR flag set. ++ */ ++ if (bredr_last <= le_last) + return BDADDR_BREDR; + + return dev->bdaddr_type; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-core-device-Fix-not-connecting-services-properly.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-core-device-Fix-not-connecting-services-properly.patch new file mode 100644 index 000000000..11fa4e12f --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-core-device-Fix-not-connecting-services-properly.patch @@ -0,0 +1,38 @@ +From 727cf85d5c710193df9b386b2a87afccbbc766ff Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Fri, 12 Aug 2016 11:20:10 +0300 +Subject: [PATCH 2/7] core/device: Fix not connecting services properly + +Device.Connect shall check if the service discovery is pending or no +service have been connected yet before switching to LE otherwise these +services may never be connected. +--- + src/device.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/device.c b/src/device.c +index 7f40af44cd01..460a9980fc63 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -1779,9 +1779,18 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg, + struct btd_device *dev = user_data; + uint8_t bdaddr_type; + +- if (dev->bredr_state.connected) +- bdaddr_type = dev->bdaddr_type; +- else if (dev->le_state.connected && dev->bredr) ++ if (dev->bredr_state.connected) { ++ /* ++ * Check if services have been resolved and there is at list ++ * one connected before switching to connect LE. ++ */ ++ if (dev->bredr_state.svc_resolved && ++ find_service_with_state(dev->services, ++ BTD_SERVICE_STATE_CONNECTED)) ++ bdaddr_type = dev->bdaddr_type; ++ else ++ bdaddr_type = BDADDR_BREDR; ++ } else if (dev->le_state.connected && dev->bredr) + bdaddr_type = BDADDR_BREDR; + else + bdaddr_type = select_conn_bearer(dev); diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-core-device-Fix-marking-auto-connect-flag.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-core-device-Fix-marking-auto-connect-flag.patch new file mode 100644 index 000000000..39278978b --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-core-device-Fix-marking-auto-connect-flag.patch @@ -0,0 +1,29 @@ +From 7e6b4a0de4580af0cefa8b3d45677f2f9f103f65 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Mon, 22 Aug 2016 13:04:15 +0300 +Subject: [PATCH 3/7] core/device: Fix marking auto-connect flag + +Device auto-connect shall be set only if the profile is able to accept +incoming connections, this fixes the wrong behavior or connecting LE +with dual mode devices immediatelly after probing service as profiles +may have auto-connect flag for outgoing connection (usually BR/EDR only). +--- + src/device.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/device.c b/src/device.c +index 460a9980fc63..0b13a3190539 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -4084,7 +4084,10 @@ static struct btd_service *probe_service(struct btd_device *device, + return NULL; + } + +- if (profile->auto_connect) ++ /* Only set auto connect if profile has set the flag and can really ++ * accept connections. ++ */ ++ if (profile->auto_connect && profile->accept) + device_set_auto_connect(device, TRUE); + + return service; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-core-device-Prefer-bonded-bearers-when-connecting.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-core-device-Prefer-bonded-bearers-when-connecting.patch new file mode 100644 index 000000000..bf111f2f2 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-core-device-Prefer-bonded-bearers-when-connecting.patch @@ -0,0 +1,30 @@ +From 3a908f611b0ea84e3388215ae800d9bec05b10b6 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Tue, 23 Aug 2016 12:58:03 +0300 +Subject: [PATCH 4/7] core/device: Prefer bonded bearers when connecting + +When attempting to connect a dual-mode device prefer bonded bearer if +only one has been marked as bonded. This prevents connecting to a +different bearer after pairing is complete and cross transport pairing +is not supported. +--- + src/device.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/device.c b/src/device.c +index 0b13a3190539..ade74e58a3bf 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -1742,6 +1742,12 @@ static uint8_t select_conn_bearer(struct btd_device *dev) + time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME; + time_t current = time(NULL); + ++ /* Prefer bonded bearer in case only one is bonded */ ++ if (dev->bredr_state.bonded && !dev->le_state.bonded ) ++ return BDADDR_BREDR; ++ else if (!dev->bredr_state.bonded && dev->le_state.bonded) ++ return dev->bdaddr_type; ++ + if (dev->bredr_seen) { + bredr_last = current - dev->bredr_seen; + if (bredr_last > SEEN_TRESHHOLD) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch new file mode 100644 index 000000000..168932afc --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch @@ -0,0 +1,137 @@ +From ddaa8ad58cd798c218ed9cc2c798cdaac6ed4924 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Mon, 26 Sep 2016 16:44:03 +0300 +Subject: [PATCH 5/7] input/hog: Use .accept and .disconnect instead of attio + +This adds .accept and .disconnect callbacks instead of attio which +is deprecated. +--- + profiles/input/hog.c | 56 ++++++++++++++++++++++++++-------------------------- + src/device.c | 8 ++++++++ + src/device.h | 1 + + 3 files changed, 37 insertions(+), 28 deletions(-) + +diff --git a/profiles/input/hog.c b/profiles/input/hog.c +index a934c6238525..b25437917188 100644 +--- a/profiles/input/hog.c ++++ b/profiles/input/hog.c +@@ -69,24 +69,6 @@ struct hog_device { + static gboolean suspend_supported = FALSE; + static struct queue *devices = NULL; + +-static void attio_connected_cb(GAttrib *attrib, gpointer user_data) +-{ +- struct hog_device *dev = user_data; +- +- DBG("HoG connected"); +- +- bt_hog_attach(dev->hog, attrib); +-} +- +-static void attio_disconnected_cb(gpointer user_data) +-{ +- struct hog_device *dev = user_data; +- +- DBG("HoG disconnected"); +- +- bt_hog_detach(dev->hog); +-} +- + static struct hog_device *hog_device_new(struct btd_device *device, + struct gatt_primary *prim) + { +@@ -115,15 +97,6 @@ static struct hog_device *hog_device_new(struct btd_device *device, + + dev->device = btd_device_ref(device); + +- /* +- * TODO: Remove attio callback and use .accept once using +- * bt_gatt_client. +- */ +- dev->attioid = btd_device_add_attio_callback(device, +- attio_connected_cb, +- attio_disconnected_cb, +- dev); +- + if (!devices) + devices = queue_new(); + +@@ -142,7 +115,6 @@ static void hog_device_free(void *data) + devices = NULL; + } + +- btd_device_remove_attio_callback(dev->device, dev->attioid); + btd_device_unref(dev->device); + bt_hog_unref(dev->hog); + free(dev); +@@ -215,11 +187,39 @@ static void hog_remove(struct btd_service *service) + hog_device_free(dev); + } + ++static int hog_accept(struct btd_service *service) ++{ ++ struct hog_device *dev = btd_service_get_user_data(service); ++ struct btd_device *device = btd_service_get_device(service); ++ GAttrib *attrib = btd_device_get_attrib(device); ++ ++ /* TODO: Replace GAttrib with bt_gatt_client */ ++ bt_hog_attach(dev->hog, attrib); ++ ++ btd_service_connecting_complete(service, 0); ++ ++ return 0; ++} ++ ++static int hog_disconnect(struct btd_service *service) ++{ ++ struct hog_device *dev = btd_service_get_user_data(service); ++ ++ bt_hog_detach(dev->hog); ++ ++ btd_service_disconnecting_complete(service, 0); ++ ++ return 0; ++} ++ + static struct btd_profile hog_profile = { + .name = "input-hog", + .remote_uuid = HOG_UUID, + .device_probe = hog_probe, + .device_remove = hog_remove, ++ .accept = hog_accept, ++ .disconnect = hog_disconnect, ++ .auto_connect = true, + }; + + static int hog_init(void) +diff --git a/src/device.c b/src/device.c +index ade74e58a3bf..2a77a2e67232 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -5921,6 +5921,14 @@ struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device) + return device->client; + } + ++void *btd_device_get_attrib(struct btd_device *device) ++{ ++ if (!device) ++ return NULL; ++ ++ return device->attrib; ++} ++ + struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device) + { + if (!device) +diff --git a/src/device.h b/src/device.h +index db108278a12e..387f598fb2e5 100644 +--- a/src/device.h ++++ b/src/device.h +@@ -70,6 +70,7 @@ GSList *btd_device_get_primaries(struct btd_device *device); + struct gatt_db *btd_device_get_gatt_db(struct btd_device *device); + struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device); + struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device); ++void *btd_device_get_attrib(struct btd_device *device); + void btd_device_gatt_set_service_changed(struct btd_device *device, + uint16_t start, uint16_t end); + bool device_attach_att(struct btd_device *dev, GIOChannel *io); diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-src-device-Free-bonding-while-failed-to-pair-device.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-src-device-Free-bonding-while-failed-to-pair-device.patch new file mode 100644 index 000000000..3e11556d4 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-src-device-Free-bonding-while-failed-to-pair-device.patch @@ -0,0 +1,99 @@ +From c0202538bc31e25f37fc45681d07873c8a127ecb Mon Sep 17 00:00:00 2001 +From: Jiangbo Wu +Date: Sun, 2 Oct 2016 20:38:31 +0800 +Subject: [PATCH 6/7] src/device: Free bonding while failed to pair device + +device unable pair since another pairng is in progress, and need to +free bonding before it created for next pairing. +--- + src/device.c | 62 +++++++++++++++++++++++++++++++----------------------------- + 1 file changed, 32 insertions(+), 30 deletions(-) + +diff --git a/src/device.c b/src/device.c +index 2a77a2e67232..97d7c4e899f6 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -2330,6 +2330,35 @@ static void create_bond_req_exit(DBusConnection *conn, void *user_data) + } + } + ++static void bonding_request_free(struct bonding_req *bonding) ++{ ++ if (!bonding) ++ return; ++ ++ if (bonding->listener_id) ++ g_dbus_remove_watch(dbus_conn, bonding->listener_id); ++ ++ if (bonding->msg) ++ dbus_message_unref(bonding->msg); ++ ++ if (bonding->cb_iter) ++ g_free(bonding->cb_iter); ++ ++ if (bonding->agent) { ++ agent_cancel(bonding->agent); ++ agent_unref(bonding->agent); ++ bonding->agent = NULL; ++ } ++ ++ if (bonding->retry_timer) ++ g_source_remove(bonding->retry_timer); ++ ++ if (bonding->device) ++ bonding->device->bonding = NULL; ++ ++ g_free(bonding); ++} ++ + static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg, + void *data) + { +@@ -2400,8 +2429,10 @@ static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg, + BDADDR_BREDR, io_cap); + } + +- if (err < 0) ++ if (err < 0) { ++ bonding_request_free(device->bonding); + return btd_error_failed(msg, strerror(-err)); ++ } + + return NULL; + } +@@ -2442,35 +2473,6 @@ static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status) + } + } + +-static void bonding_request_free(struct bonding_req *bonding) +-{ +- if (!bonding) +- return; +- +- if (bonding->listener_id) +- g_dbus_remove_watch(dbus_conn, bonding->listener_id); +- +- if (bonding->msg) +- dbus_message_unref(bonding->msg); +- +- if (bonding->cb_iter) +- g_free(bonding->cb_iter); +- +- if (bonding->agent) { +- agent_cancel(bonding->agent); +- agent_unref(bonding->agent); +- bonding->agent = NULL; +- } +- +- if (bonding->retry_timer) +- g_source_remove(bonding->retry_timer); +- +- if (bonding->device) +- bonding->device->bonding = NULL; +- +- g_free(bonding); +-} +- + static void device_cancel_bonding(struct btd_device *device, uint8_t status) + { + struct bonding_req *bonding = device->bonding; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch new file mode 100644 index 000000000..f667587a9 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch @@ -0,0 +1,189 @@ +From 4fbef59d01931111c3181194ec4d38cbcb4da45a Mon Sep 17 00:00:00 2001 +From: Szymon Janc +Date: Fri, 21 Oct 2016 21:41:18 +0200 +Subject: [PATCH 7/7] core: Fix BR/EDR pairing for dual mode devices + +For dual mode devices we need to pass address type used in pairing +events to reply with correct one on agent reply. Otherwise reply for +BR/EDR pairing of dual mode device would use address type (which is +valid only for LE address) resulting in reply being ignored by kernel +and eventually pairing timeout. +--- + src/adapter.c | 7 ++++--- + src/device.c | 31 +++++++++++++++++-------------- + src/device.h | 10 +++++----- + 3 files changed, 26 insertions(+), 22 deletions(-) + +diff --git a/src/adapter.c b/src/adapter.c +index ddabf2de5462..5ebe3d7c8eec 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -6180,7 +6180,7 @@ static void user_confirm_request_callback(uint16_t index, uint16_t length, + return; + } + +- err = device_confirm_passkey(device, btohl(ev->value), ++ err = device_confirm_passkey(device, ev->addr.type, btohl(ev->value), + ev->confirm_hint); + if (err < 0) { + btd_error(adapter->dev_id, +@@ -6254,7 +6254,7 @@ static void user_passkey_request_callback(uint16_t index, uint16_t length, + return; + } + +- err = device_request_passkey(device); ++ err = device_request_passkey(device, ev->addr.type); + if (err < 0) { + btd_error(adapter->dev_id, + "device_request_passkey: %s", strerror(-err)); +@@ -6293,7 +6293,8 @@ static void user_passkey_notify_callback(uint16_t index, uint16_t length, + + DBG("passkey %06u entered %u", passkey, ev->entered); + +- err = device_notify_passkey(device, passkey, ev->entered); ++ err = device_notify_passkey(device, ev->addr.type, passkey, ++ ev->entered); + if (err < 0) + btd_error(adapter->dev_id, + "device_notify_passkey: %s", strerror(-err)); +diff --git a/src/device.c b/src/device.c +index 97d7c4e899f6..d6be3fcf82c2 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -127,6 +127,7 @@ struct authentication_req { + auth_type_t type; + struct agent *agent; + struct btd_device *device; ++ uint8_t addr_type; + uint32_t passkey; + char *pincode; + gboolean secure; +@@ -5644,7 +5645,7 @@ static void confirm_cb(struct agent *agent, DBusError *err, void *data) + return; + + btd_adapter_confirm_reply(device->adapter, &device->bdaddr, +- device->bdaddr_type, ++ auth->addr_type, + err ? FALSE : TRUE); + + agent_unref(device->authr->agent); +@@ -5665,7 +5666,7 @@ static void passkey_cb(struct agent *agent, DBusError *err, + passkey = INVALID_PASSKEY; + + btd_adapter_passkey_reply(device->adapter, &device->bdaddr, +- device->bdaddr_type, passkey); ++ auth->addr_type, passkey); + + agent_unref(device->authr->agent); + device->authr->agent = NULL; +@@ -5683,7 +5684,9 @@ static void display_pincode_cb(struct agent *agent, DBusError *err, void *data) + } + + static struct authentication_req *new_auth(struct btd_device *device, +- auth_type_t type, gboolean secure) ++ uint8_t addr_type, ++ auth_type_t type, ++ gboolean secure) + { + struct authentication_req *auth; + struct agent *agent; +@@ -5711,6 +5714,7 @@ static struct authentication_req *new_auth(struct btd_device *device, + auth->agent = agent; + auth->device = device; + auth->type = type; ++ auth->addr_type = addr_type; + auth->secure = secure; + device->authr = auth; + +@@ -5722,7 +5726,7 @@ int device_request_pincode(struct btd_device *device, gboolean secure) + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_PINCODE, secure); ++ auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure); + if (!auth) + return -EPERM; + +@@ -5736,12 +5740,12 @@ int device_request_pincode(struct btd_device *device, gboolean secure) + return err; + } + +-int device_request_passkey(struct btd_device *device) ++int device_request_passkey(struct btd_device *device, uint8_t type) + { + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_PASSKEY, FALSE); ++ auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE); + if (!auth) + return -EPERM; + +@@ -5755,14 +5759,13 @@ int device_request_passkey(struct btd_device *device) + return err; + } + +-int device_confirm_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t confirm_hint) +- ++int device_confirm_passkey(struct btd_device *device, uint8_t type, ++ int32_t passkey, uint8_t confirm_hint) + { + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_CONFIRM, FALSE); ++ auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE); + if (!auth) + return -EPERM; + +@@ -5783,8 +5786,8 @@ int device_confirm_passkey(struct btd_device *device, uint32_t passkey, + return err; + } + +-int device_notify_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t entered) ++int device_notify_passkey(struct btd_device *device, uint8_t type, ++ uint32_t passkey, uint8_t entered) + { + struct authentication_req *auth; + int err; +@@ -5794,7 +5797,7 @@ int device_notify_passkey(struct btd_device *device, uint32_t passkey, + if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY) + return -EPERM; + } else { +- auth = new_auth(device, AUTH_TYPE_NOTIFY_PASSKEY, FALSE); ++ auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE); + if (!auth) + return -EPERM; + } +@@ -5814,7 +5817,7 @@ int device_notify_pincode(struct btd_device *device, gboolean secure, + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_NOTIFY_PINCODE, secure); ++ auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure); + if (!auth) + return -EPERM; + +diff --git a/src/device.h b/src/device.h +index 387f598fb2e5..dd7c4f300be1 100644 +--- a/src/device.h ++++ b/src/device.h +@@ -110,11 +110,11 @@ int device_bonding_attempt_retry(struct btd_device *device); + long device_bonding_last_duration(struct btd_device *device); + void device_bonding_restart_timer(struct btd_device *device); + int device_request_pincode(struct btd_device *device, gboolean secure); +-int device_request_passkey(struct btd_device *device); +-int device_confirm_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t confirm_hint); +-int device_notify_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t entered); ++int device_request_passkey(struct btd_device *device, uint8_t type); ++int device_confirm_passkey(struct btd_device *device, uint8_t type, ++ int32_t passkey, uint8_t confirm_hint); ++int device_notify_passkey(struct btd_device *device, uint8_t type, ++ uint32_t passkey, uint8_t entered); + int device_notify_pincode(struct btd_device *device, gboolean secure, + const char *pincode); + void device_cancel_authentication(struct btd_device *device, gboolean aborted); diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-QCA_bluetooth_chip_support.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-QCA_bluetooth_chip_support.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-QCA_bluetooth_chip_support.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-QCA_bluetooth_chip_support.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-hciattach-Add-verbosity-option.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-hciattach-Add-verbosity-option.patch similarity index 100% rename from meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-hciattach-Add-verbosity-option.patch rename to meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-hciattach-Add-verbosity-option.patch diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend index c75e99a53..2c7439747 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -9,13 +9,20 @@ SRC_URI += " \ file://0002-hcitool-increase-the-shown-connection-limit-to-20.patch \ file://0003-port-test-discovery-to-python3.patch \ file://0004-example-gatt-server-update-example-to-master-version.patch \ + file://0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch \ + file://0006-core-device-Fix-not-connecting-services-properly.patch \ + file://0007-core-device-Fix-marking-auto-connect-flag.patch \ + file://0008-core-device-Prefer-bonded-bearers-when-connecting.patch \ + file://0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch \ + file://0010-src-device-Free-bonding-while-failed-to-pair-device.patch \ + file://0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch \ " QCA6564_COMMON_PATCHES = " \ - file://0005-QCA_bluetooth_chip_support.patch \ - file://0006-hciattach_rome-Respect-the-user-indication-for-noflo.patch \ - file://0007-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch \ - file://0008-hciattach-Add-verbosity-option.patch \ + file://0012-QCA_bluetooth_chip_support.patch \ + file://0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch \ + file://0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch \ + file://0015-hciattach-Add-verbosity-option.patch \ " SRC_URI_append_ccimx6ul = " ${QCA6564_COMMON_PATCHES}" From 23f36d558f90e3a4fdef10b6fb000475b65088c1 Mon Sep 17 00:00:00 2001 From: Sebastian Pastor Date: Tue, 7 Nov 2017 15:45:57 +0100 Subject: [PATCH 083/113] linux-dey-4.9: ccimx6qpsbc: sync defconfig Signed-off-by: Sebastian Pastor https://jira.digi.com/browse/DEL-5272 --- .../recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig index 218a3d511..fb44c7d19 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig @@ -274,6 +274,7 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_ESDHC_IMX=y CONFIG_MXC_IPU=y +CONFIG_MXC_IPU_V3_PRE=y CONFIG_MXC_MIPI_CSI2=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y From ab21a77bc9880b03094b496d4948f7e5c3f9a976 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Thu, 9 Nov 2017 16:19:17 +0100 Subject: [PATCH 084/113] networkmanager: trigger dispatcher on per-device connectivity loss This creates a new dispatcher action DEVICE_CONNECTIVITY_CHANGE, that gets triggered whenever one interface fails in the upstream connectivity check, regardless of the system having connectivity through a different interface. https://jira.digi.com/browse/DEL-5210 Signed-off-by: Javier Viguera --- ...rigger-dispatcher-on-per-device-conn.patch | 129 ++++++++++++++++++ .../networkmanager/networkmanager_%.bbappend | 1 + 2 files changed, 130 insertions(+) create mode 100644 meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-networkmanager-trigger-dispatcher-on-per-device-conn.patch diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-networkmanager-trigger-dispatcher-on-per-device-conn.patch b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-networkmanager-trigger-dispatcher-on-per-device-conn.patch new file mode 100644 index 000000000..dd383515a --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager/0001-networkmanager-trigger-dispatcher-on-per-device-conn.patch @@ -0,0 +1,129 @@ +From: Javier Viguera +Date: Thu, 9 Nov 2017 11:49:14 +0100 +Subject: [PATCH] networkmanager: trigger dispatcher on per-device connectivity + loss + +This creates a new dispatcher action DEVICE_CONNECTIVITY_CHANGE, that +gets triggered whenever one interface fails in the upstream connectivity +check, regardless of the system having connectivity through a different +interface. + +Signed-off-by: Javier Viguera +--- + shared/nm-dispatcher-api.h | 1 + + src/devices/nm-device.c | 3 +++ + src/nm-dispatcher.c | 40 +++++++++++++++++++++++++++++++++++++++- + src/nm-dispatcher.h | 9 ++++++++- + 4 files changed, 51 insertions(+), 2 deletions(-) + +diff --git a/shared/nm-dispatcher-api.h b/shared/nm-dispatcher-api.h +index b1f28e71d4c3..e83835b03057 100644 +--- a/shared/nm-dispatcher-api.h ++++ b/shared/nm-dispatcher-api.h +@@ -50,6 +50,7 @@ + #define NMD_ACTION_DHCP4_CHANGE "dhcp4-change" + #define NMD_ACTION_DHCP6_CHANGE "dhcp6-change" + #define NMD_ACTION_CONNECTIVITY_CHANGE "connectivity-change" ++#define NMD_ACTION_DEVICE_CONNECTIVITY_CHANGE "device-connectivity-change" + + typedef enum { + DISPATCH_RESULT_UNKNOWN = 0, +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index fbf315ed3bc8..503c4689b035 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -1824,6 +1824,9 @@ update_connectivity_state (NMDevice *self, NMConnectivityState state) + nm_connectivity_state_to_string (priv->connectivity_state), + nm_connectivity_state_to_string (state)); + #endif ++ if (priv->connectivity_state == NM_CONNECTIVITY_FULL) ++ nm_dispatcher_call_device_connectivity(state, self, NULL, NULL, NULL); ++ + priv->connectivity_state = state; + _notify (self, PROP_CONNECTIVITY); + +diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c +index 0d482e0cad9d..8e3f95c0b819 100644 +--- a/src/nm-dispatcher.c ++++ b/src/nm-dispatcher.c +@@ -453,7 +453,8 @@ static const char *action_table[] = { + [NM_DISPATCHER_ACTION_VPN_DOWN] = NMD_ACTION_VPN_DOWN, + [NM_DISPATCHER_ACTION_DHCP4_CHANGE] = NMD_ACTION_DHCP4_CHANGE, + [NM_DISPATCHER_ACTION_DHCP6_CHANGE] = NMD_ACTION_DHCP6_CHANGE, +- [NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE ++ [NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE, ++ [NM_DISPATCHER_ACTION_DEVICE_CONNECTIVITY_CHANGE] = NMD_ACTION_DEVICE_CONNECTIVITY_CHANGE + }; + + static const char * +@@ -903,6 +904,43 @@ nm_dispatcher_call_connectivity (NMConnectivityState connectivity_state, + callback, user_data, out_call_id); + } + ++/** ++ * nm_dispatcher_call_device_connectivity(): ++ * @connectivity_state: the #NMConnectivityState value ++ * @device: the #NMDevice the action applies to ++ * @callback: a caller-supplied callback to execute when done ++ * @user_data: caller-supplied pointer passed to @callback ++ * @out_call_id: on success, a call identifier which can be passed to ++ * nm_dispatcher_call_cancel() ++ * ++ * This method does not block the caller. ++ * ++ * Returns: %TRUE if the action was dispatched, %FALSE on failure ++ */ ++gboolean ++nm_dispatcher_call_device_connectivity(NMConnectivityState connectivity_state, ++ NMDevice *device, ++ NMDispatcherFunc callback, ++ gpointer user_data, guint *out_call_id) ++{ ++ NMActRequest *act_request; ++ ++ nm_assert(NM_IS_DEVICE(device)); ++ ++ act_request = nm_device_get_act_request(device); ++ if (!act_request) ++ return FALSE; ++ ++ nm_assert(NM_IN_SET(nm_active_connection_get_device(NM_ACTIVE_CONNECTION(act_request)), NULL, device)); ++ return _dispatcher_call(NM_DISPATCHER_ACTION_DEVICE_CONNECTIVITY_CHANGE, FALSE, device, ++ nm_act_request_get_settings_connection(act_request), ++ nm_act_request_get_applied_connection(act_request), ++ nm_active_connection_get_activation_type(NM_ACTIVE_CONNECTION(act_request)) == NM_ACTIVATION_TYPE_EXTERNAL, ++ connectivity_state, ++ NULL, NULL, NULL, NULL, ++ callback, user_data, out_call_id); ++} ++ + void + nm_dispatcher_call_cancel (guint call_id) + { +diff --git a/src/nm-dispatcher.h b/src/nm-dispatcher.h +index 4448e8173fa7..9902a77ba683 100644 +--- a/src/nm-dispatcher.h ++++ b/src/nm-dispatcher.h +@@ -36,7 +36,8 @@ typedef enum { + NM_DISPATCHER_ACTION_VPN_DOWN, + NM_DISPATCHER_ACTION_DHCP4_CHANGE, + NM_DISPATCHER_ACTION_DHCP6_CHANGE, +- NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE ++ NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, ++ NM_DISPATCHER_ACTION_DEVICE_CONNECTIVITY_CHANGE + } NMDispatcherAction; + + typedef void (*NMDispatcherFunc) (guint call_id, gpointer user_data); +@@ -82,6 +83,12 @@ gboolean nm_dispatcher_call_connectivity (NMConnectivityState state, + gpointer user_data, + guint *out_call_id); + ++gboolean nm_dispatcher_call_device_connectivity(NMConnectivityState ++ connectivity_state, ++ NMDevice *device, ++ NMDispatcherFunc callback, ++ gpointer user_data, ++ guint *out_call_id); + + void nm_dispatcher_call_cancel (guint call_id); + diff --git a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend index b2bf4f7f7..461cc0f5c 100644 --- a/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend +++ b/meta-digi-dey/recipes-connectivity/networkmanager/networkmanager_%.bbappend @@ -3,6 +3,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" SRC_URI += " \ + file://0001-networkmanager-trigger-dispatcher-on-per-device-conn.patch \ file://NetworkManager.conf \ file://networkmanager-init \ file://nm.cellular \ From 64c9227cfea3529add6711216c8a99d67bf5fa9f Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Mon, 13 Nov 2017 09:59:48 +0100 Subject: [PATCH 085/113] linux-dey: build from 'v4.9/dey-2.2/maint' branch Signed-off-by: Hector Palacios --- meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb index d7b9de9a0..4bd073c7e 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_4.9.bb @@ -3,7 +3,7 @@ require recipes-kernel/linux/linux-dey.inc require recipes-kernel/linux/linux-dtb.inc -SRCBRANCH = "v4.9.11/master" +SRCBRANCH = "v4.9/dey-2.2/maint" SRCREV = "${AUTOREV}" COMPATIBLE_MACHINE = "(ccimx6qpsbc|ccimx6ul)" From 74c10edc2b87e3df1cc2abe23b3438608f121cf5 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Mon, 13 Nov 2017 11:09:19 +0100 Subject: [PATCH 086/113] meta-digi: Add Eclipse debug support Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-5327 --- meta-digi-dey/recipes-core/images/core-image-base.bbappend | 1 + meta-digi-dey/recipes-core/images/dey-image-qt.bb | 1 + 2 files changed, 2 insertions(+) diff --git a/meta-digi-dey/recipes-core/images/core-image-base.bbappend b/meta-digi-dey/recipes-core/images/core-image-base.bbappend index 4263517ac..2e7b4d5de 100644 --- a/meta-digi-dey/recipes-core/images/core-image-base.bbappend +++ b/meta-digi-dey/recipes-core/images/core-image-base.bbappend @@ -4,6 +4,7 @@ IMAGE_FEATURES += " \ dey-network \ + eclipse-debug \ package-management \ ssh-server-dropbear \ ${@bb.utils.contains('MACHINE_FEATURES', 'accel-video', 'dey-gstreamer', '', d)} \ diff --git a/meta-digi-dey/recipes-core/images/dey-image-qt.bb b/meta-digi-dey/recipes-core/images/dey-image-qt.bb index 6cd4e2956..bb935e61d 100644 --- a/meta-digi-dey/recipes-core/images/dey-image-qt.bb +++ b/meta-digi-dey/recipes-core/images/dey-image-qt.bb @@ -17,6 +17,7 @@ IMAGE_INSTALL = " \ IMAGE_FEATURES += " \ dey-network \ dey-qt \ + eclipse-debug \ package-management \ ssh-server-dropbear \ ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'x11-base x11-sato', '', d)} \ From 2d0af46beeeff58dede06ea015bb88cb8202c5cf Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Wed, 15 Nov 2017 08:48:26 +0100 Subject: [PATCH 087/113] init-ifupdown: virtwlans: specify type of wlan1 virtwlans script creates an additional interface on startup for QCA6564 chip. The created interface purpose is for ap mode, so specify its type on creation. https://jira.digi.com/browse/DEL-5290 Signed-off-by: Isaac Hermida --- .../init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh | 2 +- .../init-ifupdown/init-ifupdown-1.0/ccimx6ul/virtwlans.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh index 304c09fc5..a3eb3dc7b 100644 --- a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6qpsbc/virtwlans.sh @@ -26,5 +26,5 @@ fi if [ ! -d "/sys/class/net/wlan1" ]; then # This will create a second wireless network device - iw dev wlan0 interface add wlan1 type managed + iw dev wlan0 interface add wlan1 type __ap fi diff --git a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/virtwlans.sh b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/virtwlans.sh index 304c09fc5..a3eb3dc7b 100644 --- a/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/virtwlans.sh +++ b/meta-digi-dey/recipes-core/init-ifupdown/init-ifupdown-1.0/ccimx6ul/virtwlans.sh @@ -26,5 +26,5 @@ fi if [ ! -d "/sys/class/net/wlan1" ]; then # This will create a second wireless network device - iw dev wlan0 interface add wlan1 type managed + iw dev wlan0 interface add wlan1 type __ap fi From 557bf97081e921c6ea18fa89f89bb56e20047576 Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Wed, 15 Nov 2017 17:58:50 +0100 Subject: [PATCH 088/113] ccimx6ul/ccimx6qp: synchronize kernel v4.9 defconfig https://jira.digi.com/browse/DEL-4748 Signed-off-by: Arturo Buzarra --- .../recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig | 2 +- .../recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig index fb44c7d19..ae8df27c7 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6qpsbc/defconfig @@ -174,7 +174,7 @@ CONFIG_I2C_IMX_LPI2C=y CONFIG_SPI=y CONFIG_SPI_IMX=y CONFIG_SPI_FSL_LPSPI=y -CONFIG_SPI_SPIDEV=y +CONFIG_SPI_SPIDEV=m CONFIG_GPIO_SYSFS=y CONFIG_GPIO_DA9063=y CONFIG_POWER_SUPPLY=y diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig index 7b00f81ee..22f448883 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.9/ccimx6ul/defconfig @@ -186,7 +186,7 @@ CONFIG_SPI=y CONFIG_SPI_GPIO=y CONFIG_SPI_IMX=y CONFIG_SPI_FSL_LPSPI=y -CONFIG_SPI_SPIDEV=y +CONFIG_SPI_SPIDEV=m CONFIG_GPIO_SYSFS=y CONFIG_GPIO_MCA_CC6UL=y CONFIG_POWER_RESET=y From bd51c63b2ad5c02f7dee0b9a6bcf7bfe6cf87062 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Thu, 16 Nov 2017 13:25:49 +0100 Subject: [PATCH 089/113] libdigiapix: Add digiapix group Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-5231 --- meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb index 35a5fa76e..88517db7d 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb @@ -23,7 +23,7 @@ SRC_URI = " \ S = "${WORKDIR}/git" -inherit pkgconfig +inherit pkgconfig useradd do_install() { oe_runmake 'DESTDIR=${D}' install @@ -32,4 +32,7 @@ do_install() { install -m 0644 ${WORKDIR}/board.conf ${D}${sysconfdir}/libdigiapix.conf } +USERADD_PACKAGES = "${PN}" +GROUPADD_PARAM_${PN} = "-r digiapix" + PACKAGE_ARCH = "${MACHINE_ARCH}" From faabf6ebbbfbec1c6d988312ad7970a1b917b98d Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Fri, 17 Nov 2017 14:04:28 +0100 Subject: [PATCH 090/113] udev-extraconf: add rule not to autoload spidev module Prevents loading the spidev module at boot time to avoid the undesired warning message from driver. https://jira.digi.com/browse/DEL-4748 Signed-off-by: Arturo Buzarra --- .../recipes-core/udev/udev-extraconf/81-spi-spidev.rules | 2 ++ meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 meta-digi-arm/recipes-core/udev/udev-extraconf/81-spi-spidev.rules diff --git a/meta-digi-arm/recipes-core/udev/udev-extraconf/81-spi-spidev.rules b/meta-digi-arm/recipes-core/udev/udev-extraconf/81-spi-spidev.rules new file mode 100644 index 000000000..4c1a31799 --- /dev/null +++ b/meta-digi-arm/recipes-core/udev/udev-extraconf/81-spi-spidev.rules @@ -0,0 +1,2 @@ +# Skip loading Spidev module +SUBSYSTEM=="spi", ACTION=="add", ENV{MODALIAS}=="spi:spidev", RUN="/bin/true" diff --git a/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend b/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend index 662156665..682247ec3 100644 --- a/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend +++ b/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend @@ -1,15 +1,17 @@ -# Copyright (C) 2013 Digi International. +# Copyright (C) 2013-2017 Digi International. FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" SRC_URI += " \ file://mount_bootparts.sh \ file://mount_partition.sh \ + file://81-spi-spidev.rules \ " do_install_append() { install -m 0755 ${WORKDIR}/mount_bootparts.sh ${D}${sysconfdir}/udev/scripts/ install -m 0755 ${WORKDIR}/mount_partition.sh ${D}${sysconfdir}/udev/scripts/ + install -m 0644 ${WORKDIR}/81-spi-spidev.rules ${D}${sysconfdir}/udev/rules.d/ # Bluetooth tty symlink if [ -n "${BT_TTY}" ]; then From 5d18ee67317013f30f73f31988704847d3760f12 Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Mon, 20 Nov 2017 12:51:13 +0100 Subject: [PATCH 091/113] ccimx6/ccimx6ul: default kernel image to zImage, except for CC6 U-Boot has been able to boot kernel zImage for a long time so make this the default kernel image. For the CC6 we still want to use uImage for compatibility reasons. Signed-off-by: Hector Palacios https://jira.digi.com/browse/DEL-5237 --- meta-digi-arm/conf/machine/ccimx6sbc.conf | 3 +++ meta-digi-arm/conf/machine/include/ccimx6ul.inc | 2 -- meta-digi-arm/conf/machine/include/imx-digi-base.inc | 2 +- .../u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/meta-digi-arm/conf/machine/ccimx6sbc.conf b/meta-digi-arm/conf/machine/ccimx6sbc.conf index 0b257d8f5..5dc0967ff 100644 --- a/meta-digi-arm/conf/machine/ccimx6sbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6sbc.conf @@ -25,6 +25,9 @@ UBOOT_CONFIG[ccimx6qsbc2GB] = "ccimx6qsbc2GB_defconfig" UBOOT_CONFIG[ccimx6qsbc512MB] = "ccimx6qsbc512MB_defconfig" UBOOT_CONFIG[ccimx6qsbc] = "ccimx6qsbc_defconfig" +# Use uImage for backwards compatibility +KERNEL_IMAGETYPE = "uImage" + KERNEL_DEVICETREE ?= " \ imx6dl-ccimx6sbc.dtb \ imx6dl-ccimx6sbc-w.dtb \ diff --git a/meta-digi-arm/conf/machine/include/ccimx6ul.inc b/meta-digi-arm/conf/machine/include/ccimx6ul.inc index 302bf54d9..30691e816 100644 --- a/meta-digi-arm/conf/machine/include/ccimx6ul.inc +++ b/meta-digi-arm/conf/machine/include/ccimx6ul.inc @@ -36,8 +36,6 @@ MACHINE_FEATURES += "wifi bluetooth" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_BT', '1', 'firmware-qualcomm-qca6564-bt', '', d)}" MACHINE_FIRMWARE_append = " ${@base_conditional('HAVE_WIFI', '1', 'firmware-qualcomm-qca6564-wifi', '', d)}" -KERNEL_IMAGETYPE = "zImage" - # mkfs.ubifs parameters for boot partition (the one holding kernel and device tree files) # Max LEB count (-c 255) calculated for a partition of up to 32 MiB considering 128 KiB erase-block size. MKUBIFS_BOOT_ARGS ?= "-m 2048 -e 126976 -c 255" diff --git a/meta-digi-arm/conf/machine/include/imx-digi-base.inc b/meta-digi-arm/conf/machine/include/imx-digi-base.inc index b5447c7de..bb8a6a5ec 100644 --- a/meta-digi-arm/conf/machine/include/imx-digi-base.inc +++ b/meta-digi-arm/conf/machine/include/imx-digi-base.inc @@ -88,7 +88,7 @@ PREFERRED_PROVIDER_virtual/libg2d_mx6ul = "" EXTRA_IMAGEDEPENDS = "u-boot" -KERNEL_IMAGETYPE = "uImage" +KERNEL_IMAGETYPE = "zImage" MACHINE_FEATURES = "usbgadget usbhost vfat alsa touchscreen" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt index e47f9fd88..52b84adef 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey-2015.04/ccimx6qpsbc/boot.txt @@ -6,13 +6,13 @@ # Set device tree filename depending on the board ID (if defined) # if test -n "${board_id}"; then - setenv fdt_file uImage-${soc_family}-ccimx6qpsbc-id${board_id}.dtb + setenv fdt_file zImage-${soc_family}-ccimx6qpsbc-id${board_id}.dtb else # # Set device tree filename depending on the hardware variant # if test "${module_variant}" = "0x01"; then - setenv fdt_file uImage-${soc_family}-ccimx6qpsbc-wb.dtb + setenv fdt_file zImage-${soc_family}-ccimx6qpsbc-wb.dtb else echo "------ Using default fdt_file" fi From d8d95f6348df85cc420f3819fe7aeb1d85024be5 Mon Sep 17 00:00:00 2001 From: Francisco Gil Date: Thu, 16 Nov 2017 13:59:35 +0100 Subject: [PATCH 092/113] apix: adc: Add default adc pins in all the platforms Signed-off-by: Francisco Gil --- .../libdigiapix-git/ccimx6qpsbc/board.conf | 11 ++--------- .../libdigiapix/libdigiapix-git/ccimx6sbc/board.conf | 11 ++--------- .../libdigiapix-git/ccimx6ulsbc/board.conf | 8 +------- .../libdigiapix-git/ccimx6ulstarter/board.conf | 8 +------- 4 files changed, 6 insertions(+), 32 deletions(-) diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf index 1e88b544e..31d0afd0b 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6qpsbc/board.conf @@ -32,12 +32,5 @@ DEFAULT_PWM = 0,0 [ADC] -# HWMON Driver -DEFAULT_ADC_DRIVER = 1 - -# IIO Device 0 -DEFAULT_DEVICE_INDEX = 0 - -# PMIC_ADCIN1 on GPIO board connector (Pin 1) -DEFAULT_ADC_LINE = 1 - +# ADC1 on GPIO connector (pin 1). +DEFAULT_ADC = 0,1 diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf index c9559ae0f..5d726f2e9 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6sbc/board.conf @@ -32,12 +32,5 @@ DEFAULT_PWM = 0,0 [ADC] -# HWMON Driver -DEFAULT_ADC_DRIVER = 1 - -# IIO Device 0 -DEFAULT_DEVICE_INDEX = 0 - -# PMIC_ADCIN1 on GPIO board connector (Pin 1) -DEFAULT_ADC_LINE = 1 - +# ADC1 on GPIO connector (pin 1). +DEFAULT_ADC = 0,1 diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf index 06e16cfba..f311343c6 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulsbc/board.conf @@ -26,11 +26,5 @@ DEFAULT_PWM = 0,0 [ADC] -# IIO Driver -DEFAULT_ADC_DRIVER = 0 - -# IIO Device 0 -DEFAULT_DEVICE_INDEX = 0 - # ADC1_IN2 on GPIO board connector (pin 13) -DEFAULT_ADC_LINE = 2 +DEFAULT_ADC = 0,2 diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf index c26d171ad..1e403afad 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf @@ -26,11 +26,5 @@ DEFAULT_PWM = 0,0 [ADC] -# IIO Driver -DEFAULT_ADC_DRIVER = 0 - -# IIO Device 1 -DEFAULT_DEVICE_INDEX = 1 - # ADC1_IN4 on Expansion connector (pin 7). -DEFAULT_ADC_LINE = 4 +DEFAULT_ADC = 0,4 From f94533e1370de22c48b38557fa364262c7692321 Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Wed, 22 Nov 2017 13:37:40 +0100 Subject: [PATCH 093/113] ccimx6ulsbc: add support for SBC Pro board ID=136 Signed-off-by: Hector Palacios https://jira.digi.com/browse/DUB-769 --- meta-digi-arm/conf/machine/ccimx6ulsbc.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/meta-digi-arm/conf/machine/ccimx6ulsbc.conf b/meta-digi-arm/conf/machine/ccimx6ulsbc.conf index 2f99f4cf3..db3ce2345 100644 --- a/meta-digi-arm/conf/machine/ccimx6ulsbc.conf +++ b/meta-digi-arm/conf/machine/ccimx6ulsbc.conf @@ -24,6 +24,7 @@ KERNEL_DEVICETREE ?= " \ imx6ul-ccimx6ulsbc.dtb \ imx6ul-ccimx6ulsbc-wb.dtb \ imx6ul-ccimx6ulsbc-id135.dtb \ + imx6ul-ccimx6ulsbc-id136.dtb \ " SERIAL_CONSOLES ?= "115200;ttymxc4" From c2245554519174d9fdc528af9028f359f56da503 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 22 Nov 2017 10:07:47 +0100 Subject: [PATCH 094/113] packagegroup-dey-gstreamer: define installed packages per machine This allows to specify a different set of gstreamer packages to be installed per machine. It's mainly used for the CC6UL to define a minimum set of packages that allows to play a WEBM video, and at the same time save some space as this platform does not have much storage. The space saved with this change for the CC6UL and the default QT image is about ~5MB. https://jira.digi.com/browse/DEL-4987 Signed-off-by: Javier Viguera --- .../packagegroup-dey-gstreamer.bb | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb b/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb index 85d4803f6..a51f3e079 100644 --- a/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb +++ b/meta-digi-dey/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb @@ -1,11 +1,34 @@ # -# Copyright (C) 2012 Digi International. +# Copyright (C) 2012-2017 Digi International Inc. # SUMMARY = "Gstreamer framework packagegroup for DEY image" PACKAGE_ARCH = "${MACHINE_ARCH}" inherit packagegroup +# Per machine gstreamer base packages +MACHINE_GSTREAMER_1_0_PKGS = " \ + gstreamer1.0-meta-audio \ + gstreamer1.0-meta-video \ + gstreamer1.0-plugins-base-meta \ + gstreamer1.0-plugins-good-meta \ +" +# Minimal set of gstreamer elements to play a local WEBM video +MACHINE_GSTREAMER_1_0_PKGS_ccimx6ul = " \ + gstreamer1.0-plugins-base-alsa \ + gstreamer1.0-plugins-base-audioconvert \ + gstreamer1.0-plugins-base-audioresample \ + gstreamer1.0-plugins-base-playback \ + gstreamer1.0-plugins-base-typefindfunctions \ + gstreamer1.0-plugins-base-videoconvert \ + gstreamer1.0-plugins-base-videoscale \ + gstreamer1.0-plugins-base-volume \ + gstreamer1.0-plugins-good-pulse \ + gstreamer1.0-plugins-good-video4linux2 \ + gstreamer1.0-plugins-good-videofilter \ + gstreamer1.0-plugins-good-vpx \ +" + MACHINE_GSTREAMER_1_0_EXTRA_INSTALL ?= "" MACHINE_GSTREAMER_1_0_EXTRA_INSTALL_ccimx6 ?= " \ gstreamer1.0-plugins-bad-meta \ @@ -14,10 +37,7 @@ MACHINE_GSTREAMER_1_0_EXTRA_INSTALL_ccimx6 ?= " \ " RDEPENDS_${PN} = " \ - gstreamer1.0-meta-audio \ - gstreamer1.0-meta-video \ - gstreamer1.0-plugins-base-meta \ - gstreamer1.0-plugins-good-meta \ + ${MACHINE_GSTREAMER_1_0_PKGS} \ ${MACHINE_GSTREAMER_1_0_EXTRA_INSTALL} \ ${MACHINE_GSTREAMER_1_0_PLUGIN} \ " From f5a28b98e71f6f89fa3d46ff6935b12be86a62bc Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 22 Nov 2017 10:08:19 +0100 Subject: [PATCH 095/113] tcf-agent: remove bash dependence tcf-agent falls back to '/bin/sh' if 'bash' is not available, so don't depend on bash at runtime. https://jira.digi.com/browse/DEL-4987 https://jira.digi.com/browse/DEL-5360 Signed-off-by: Javier Viguera --- .../recipes-devtools/tcf-agent/tcf-agent_git.bbappend | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend diff --git a/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend new file mode 100644 index 000000000..e948a4fc4 --- /dev/null +++ b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend @@ -0,0 +1,5 @@ +# Copyright (C) 2017 Digi International Inc. + +# tcf-agent falls back to '/bin/sh' if 'bash' is not available, so don't +# depend on bash at runtime. +RDEPENDS_${PN}_remove = "bash" From c8edc81ea07a1ec97d10771cdf5f3411745fa13e Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 22 Nov 2017 10:08:52 +0100 Subject: [PATCH 096/113] tcf-agent: update to '1.5_oxygen' version That's the version of Eclipse we are going to use for application development. Signed-off-by: Javier Viguera --- .../0001-Makefile.inc-fix-ranlib.patch | 25 ++++++++++++ .../0002-tcf-agent-obey-LDFLAGS.patch | 22 ++++++++++ ...alize_file_name-is-specific-to-glibc.patch | 40 +++++++++++++++++++ .../tcf-agent/tcf-agent_git.bbappend | 14 +++++++ 4 files changed, 101 insertions(+) create mode 100644 meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0001-Makefile.inc-fix-ranlib.patch create mode 100644 meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0002-tcf-agent-obey-LDFLAGS.patch create mode 100644 meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0003-canonicalize_file_name-is-specific-to-glibc.patch diff --git a/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0001-Makefile.inc-fix-ranlib.patch b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0001-Makefile.inc-fix-ranlib.patch new file mode 100644 index 000000000..bfacb21eb --- /dev/null +++ b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0001-Makefile.inc-fix-ranlib.patch @@ -0,0 +1,25 @@ +From: Javier Viguera +Date: Thu, 16 Nov 2017 17:57:07 +0100 +Subject: [PATCH 1/3] Makefile.inc: fix ranlib + +Upstream-Status: Inappropriate [poky-specific fix] + +Signed-off-by: Javier Viguera +--- + agent/Makefile.inc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/agent/Makefile.inc b/agent/Makefile.inc +index 8304cfecc14a..cdf8536dbf9b 100644 +--- a/agent/Makefile.inc ++++ b/agent/Makefile.inc +@@ -88,6 +88,9 @@ ifeq ($(OPSYS),GNU/Linux) + else + OPTS += -DUSE_uuid_generate=0 + endif ++ ifneq ($(RANLIB),) ++ RANLIB += $@ ++ endif + OPTS += -DENABLE_arch_$(shell uname -m) + endif + diff --git a/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0002-tcf-agent-obey-LDFLAGS.patch b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0002-tcf-agent-obey-LDFLAGS.patch new file mode 100644 index 000000000..b130bfa8e --- /dev/null +++ b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0002-tcf-agent-obey-LDFLAGS.patch @@ -0,0 +1,22 @@ +From: Abdur Rehman +Date: Wed, 26 Aug 2015 19:18:11 +0500 +Subject: [PATCH 2/3] tcf-agent: obey LDFLAGS + +Signed-off-by: Abdur Rehman +--- + agent/Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/agent/Makefile.inc b/agent/Makefile.inc +index cdf8536dbf9b..70f4710dcacd 100644 +--- a/agent/Makefile.inc ++++ b/agent/Makefile.inc +@@ -114,7 +114,7 @@ NO_LINK_F ?= -c + # Linker definition and flags + + LINK ?= $(CC) +-LINK_FLAGS ?= $(CFLAGS) ++LINK_FLAGS ?= $(LDFLAGS) $(CFLAGS) + LINK_OUT_F ?= $(OUT_OBJ_F) + + # Archiver definition and flags diff --git a/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0003-canonicalize_file_name-is-specific-to-glibc.patch b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0003-canonicalize_file_name-is-specific-to-glibc.patch new file mode 100644 index 000000000..1b94cdfd5 --- /dev/null +++ b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent/0003-canonicalize_file_name-is-specific-to-glibc.patch @@ -0,0 +1,40 @@ +From: Khem Raj +Date: Thu, 7 Jan 2016 22:37:48 +0000 +Subject: [PATCH 3/3] canonicalize_file_name is specific to glibc + +When on Linux and not using glibc then we need to define +canonicalize_file_name() API, therefore add a check for finding out if +its not glibc + +Signed-off-by: Khem Raj +--- + agent/tcf/framework/mdep.c | 2 +- + agent/tcf/framework/mdep.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/agent/tcf/framework/mdep.c b/agent/tcf/framework/mdep.c +index cf5771e5f016..ccdea09b8817 100644 +--- a/agent/tcf/framework/mdep.c ++++ b/agent/tcf/framework/mdep.c +@@ -1086,7 +1086,7 @@ char * canonicalize_file_name(const char * path) { + return strdup(res); + } + +-#elif defined(__UCLIBC__) ++#elif defined(__UCLIBC__) || !defined(__GLIBC__) + + char * canonicalize_file_name(const char * path) { + return realpath(path, NULL); +diff --git a/agent/tcf/framework/mdep.h b/agent/tcf/framework/mdep.h +index fec94d787224..52c41256cd92 100644 +--- a/agent/tcf/framework/mdep.h ++++ b/agent/tcf/framework/mdep.h +@@ -288,7 +288,7 @@ extern int loc_clock_gettime(int, struct timespec *); + + #define O_BINARY 0 + +-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__sun__) ++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__sun__) || !defined(__GLIBC__) + # define O_LARGEFILE 0 + extern char ** environ; + extern char * canonicalize_file_name(const char * path); diff --git a/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend index e948a4fc4..822d2337a 100644 --- a/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend +++ b/meta-digi-dey/recipes-devtools/tcf-agent/tcf-agent_git.bbappend @@ -1,5 +1,19 @@ # Copyright (C) 2017 Digi International Inc. +FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" + +SRCREV = "5ec928ddf62b0ad936efacf2b2d8fb87cca112ac" +PV = "1.5+git${SRCPV}" + +SRC_URI = " \ + git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent;branch=1.5_oxygen_bugfix \ + file://0001-Makefile.inc-fix-ranlib.patch;striplevel=2 \ + file://0002-tcf-agent-obey-LDFLAGS.patch;striplevel=2 \ + file://0003-canonicalize_file_name-is-specific-to-glibc.patch;striplevel=2 \ + file://tcf-agent.init \ + file://tcf-agent.service \ +" + # tcf-agent falls back to '/bin/sh' if 'bash' is not available, so don't # depend on bash at runtime. RDEPENDS_${PN}_remove = "bash" From 2fb4cfa675f0f9263b9d316cfa51f4e0b12a4b66 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 22 Nov 2017 10:09:33 +0100 Subject: [PATCH 097/113] imx-codec: remove unneeded binaries from the rootfs The current recipe copies binaries for different ARM architectures to the rootfs. For the CC6UL we need to save some space, so delete the versions of the binaries that are not being used. https://jira.digi.com/browse/DEL-4987 Signed-off-by: Javier Viguera --- .../imx-codec/imx-codec_4.1.4.bbappend | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.1.4.bbappend diff --git a/meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.1.4.bbappend b/meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.1.4.bbappend new file mode 100644 index 000000000..4438d9cfd --- /dev/null +++ b/meta-digi-dey/recipes-multimedia/imx-codec/imx-codec_4.1.4.bbappend @@ -0,0 +1,31 @@ +# Copyright (C) 2017 Digi International Inc. + +# Empirically detected binaries that are not needed for a given platform +REDUNDANT_BINS ?= "" +REDUNDANT_BINS_ccimx6ul ?= " \ + usr/lib/imx-mm/audio-codec/wrap/lib_aacd_wrap_arm11_elinux.so* \ + usr/lib/imx-mm/audio-codec/wrap/lib_aacd_wrap_arm9_elinux.so* \ + usr/lib/imx-mm/audio-codec/wrap/lib_mp3d_wrap_arm11_elinux.so* \ + usr/lib/imx-mm/audio-codec/wrap/lib_mp3d_wrap_arm9_elinux.so* \ + usr/lib/imx-mm/audio-codec/wrap/lib_nbamrd_wrap_arm9_elinux.so* \ + usr/lib/imx-mm/audio-codec/wrap/lib_vorbisd_wrap_arm11_elinux.so* \ + usr/lib/imx-mm/audio-codec/wrap/lib_wbamrd_wrap_arm9_elinux.so* \ + usr/lib/lib_aac_dec_arm11_elinux.so* \ + usr/lib/lib_aac_dec_arm9_elinux.so* \ + usr/lib/lib_mp3_dec_arm11_elinux.so* \ + usr/lib/lib_mp3_dec_arm9_elinux.so* \ + usr/lib/lib_mp3_enc_arm11_elinux.so* \ + usr/lib/lib_mp3_enc_arm9_elinux.so* \ + usr/share/imx-mm/audio-codec/examples/aac-dec/bin/test_aac_dec_arm11_elinux* \ + usr/share/imx-mm/audio-codec/examples/aac-dec/bin/test_aac_dec_arm9_elinux* \ + usr/share/imx-mm/audio-codec/examples/mp3-dec/bin/test_mp3_dec_arm11_elinux* \ + usr/share/imx-mm/audio-codec/examples/mp3-dec/bin/test_mp3_dec_arm9_elinux* \ + usr/share/imx-mm/audio-codec/examples/mp3-enc/bin/test_mp3_enc_arm11_elinux* \ + usr/share/imx-mm/audio-codec/examples/mp3-enc/bin/test_mp3_enc_arm9_elinux* \ +" + +do_install_append() { + for i in ${REDUNDANT_BINS}; do + rm -f ${D}/${i} + done +} From 3261119470b7fb7b4bd13bf58e69f1ebd864d8dc Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Wed, 22 Nov 2017 10:10:06 +0100 Subject: [PATCH 098/113] imx-parser: remove unneeded binaries from the rootfs The current recipe copies binaries for different ARM architectures to the rootfs. For the CC6UL we need to save some space, so delete the versions of the binaries that are not being used. https://jira.digi.com/browse/DEL-4987 Signed-off-by: Javier Viguera --- .../imx-parser/imx-parser_4.1.4.bbappend | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.1.4.bbappend diff --git a/meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.1.4.bbappend b/meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.1.4.bbappend new file mode 100644 index 000000000..e8363a7e8 --- /dev/null +++ b/meta-digi-dey/recipes-multimedia/imx-parser/imx-parser_4.1.4.bbappend @@ -0,0 +1,18 @@ +# Copyright (C) 2017 Digi International Inc. + +# Empirically detected binaries that are not needed for a given platform +REDUNDANT_BINS ?= "" +REDUNDANT_BINS_ccimx6ul ?= " \ + usr/lib/imx-mm/parser/lib_avi_parser_arm9_elinux* \ + usr/lib/imx-mm/parser/lib_flv_parser_arm9_elinux* \ + usr/lib/imx-mm/parser/lib_mkv_parser_arm9_elinux* \ + usr/lib/imx-mm/parser/lib_mp4_parser_arm9_elinux* \ + usr/lib/imx-mm/parser/lib_mpg2_parser_arm9_elinux* \ + usr/lib/imx-mm/parser/lib_ogg_parser_arm9_elinux* \ +" + +do_install_append() { + for i in ${REDUNDANT_BINS}; do + rm -f ${D}/${i} + done +} From 14fc51147f6ee7278cffd40e50c333d8b386b1dd Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Wed, 15 Nov 2017 16:51:23 +0100 Subject: [PATCH 099/113] trustfence-cst: add support for CST 2.3.3 https://jira.digi.com/browse/DEL-5337 Signed-off-by: Jose Diaz de Grenu --- .../trustfence-cst/trustfence-cst-native.inc | 50 +++++++++++++++++++ .../trustfence-cst-native_2.3.2.bb | 50 +------------------ .../trustfence-cst-native_2.3.3.bb | 5 ++ ...crypted_data-reuse-existing-DEK-file.patch | 0 ...002-hab4_pki_tree.sh-automate-script.patch | 0 ...elper-use-dev-urandom-as-seed-source.patch | 0 ...-usa-a-random-password-for-the-defau.patch | 0 .../Makefile | 0 8 files changed, 57 insertions(+), 48 deletions(-) create mode 100644 meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc create mode 100644 meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.3.bb rename meta-digi-arm/recipes-bsp/trustfence-cst/{trustfence-cst-2.3.2 => trustfence-cst}/0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch (100%) rename meta-digi-arm/recipes-bsp/trustfence-cst/{trustfence-cst-2.3.2 => trustfence-cst}/0002-hab4_pki_tree.sh-automate-script.patch (100%) rename meta-digi-arm/recipes-bsp/trustfence-cst/{trustfence-cst-2.3.2 => trustfence-cst}/0003-openssl_helper-use-dev-urandom-as-seed-source.patch (100%) rename meta-digi-arm/recipes-bsp/trustfence-cst/{trustfence-cst-2.3.2 => trustfence-cst}/0004-hab4_pki_tree.sh-usa-a-random-password-for-the-defau.patch (100%) rename meta-digi-arm/recipes-bsp/trustfence-cst/{trustfence-cst-2.3.2 => trustfence-cst}/Makefile (100%) diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc new file mode 100644 index 000000000..8d437c2b7 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc @@ -0,0 +1,50 @@ +# Copyright (C) 2017 Digi International +SUMMARY = "NXP Code signing Tool for the High Assurance Boot library" +DESCRIPTION = "Provides software code signing support designed for use with \ +i.MX processors that integrate the HAB library in the internal boot ROM." +HOMEPAGE = "https://www.nxp.com/webapp/Download?colCode=IMX_CST_TOOL" +LICENSE = "CLOSED" + +DEPENDS = "openssl-native" + +SRC_URI = " \ + file://cst-${PV}.tar.gz \ + file://0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch \ + file://0002-hab4_pki_tree.sh-automate-script.patch \ + file://0003-openssl_helper-use-dev-urandom-as-seed-source.patch \ + file://0004-hab4_pki_tree.sh-usa-a-random-password-for-the-defau.patch \ + file://Makefile \ +" + +# Usually local files (with file:// protocol) are not checked for +# premirrors. But in this case we want to be able to download the 'cst' +# package from a premirror in case it's not already in the DL_DIR, so prepend +# a premirror for the 'file://' protocol. +python() { + source_mirror_url = d.getVar('SOURCE_MIRROR_URL', True) + if source_mirror_url: + premirrors = d.getVar('PREMIRRORS', True) + d.setVar('PREMIRRORS', "file://cst.* %s \\n %s" % (source_mirror_url, premirrors)) +} + +S = "${WORKDIR}/cst-${PV}" + +inherit native + +do_configure() { + cp -f ${WORKDIR}/Makefile . +} + +do_compile() { + oe_runmake clean && oe_runmake +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 linux64/cst ${D}${bindir}/cst + install -m 0755 $(find linux64 -type f -name srktool) ${D}${bindir}/srktool + install -m 0755 keys/hab4_pki_tree.sh ${D}${bindir}/trustfence-gen-pki.sh + install -m 0755 ca/openssl.cnf ${D}${bindir}/openssl.cnf + install -m 0755 ca/v3_ca.cnf ${D}${bindir}/v3_ca.cnf + install -m 0755 ca/v3_usr.cnf ${D}${bindir}/v3_usr.cnf +} diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.2.bb b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.2.bb index 77194dbcf..b3ec2f2de 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.2.bb +++ b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.2.bb @@ -1,49 +1,3 @@ -SUMMARY = "NXP Code signing Tool for the High Assurance Boot library" -DESCRIPTION = "Provides software code signing support designed for use with \ -i.MX processors that integrate the HAB library in the internal boot ROM." -HOMEPAGE = "https://www.nxp.com/webapp/Download?colCode=IMX_CST_TOOL" -LICENSE = "CLOSED" +# Copyright (C) 2017 Digi International -DEPENDS = "openssl-native" - -SRC_URI = " \ - ${@base_conditional('TRUSTFENCE_SIGN', '1', 'file://cst-${PV}.tar.gz', '', d)} \ - file://0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch \ - file://0002-hab4_pki_tree.sh-automate-script.patch \ - file://0003-openssl_helper-use-dev-urandom-as-seed-source.patch \ - file://0004-hab4_pki_tree.sh-usa-a-random-password-for-the-defau.patch \ - file://Makefile \ -" - -# Usually local files (with file:// protocol) are not checked for -# premirrors. But in this case we want to be able to download the 'cst' -# package from a premirror in case it's not already in the DL_DIR, so prepend -# a premirror for the 'file://' protocol. -python() { - source_mirror_url = d.getVar('SOURCE_MIRROR_URL', True) - if source_mirror_url: - premirrors = d.getVar('PREMIRRORS', True) - d.setVar('PREMIRRORS', "file://cst.* %s \\n %s" % (source_mirror_url, premirrors)) -} - -S = "${WORKDIR}/cst-${PV}" - -inherit native - -do_configure() { - cp -f ${WORKDIR}/Makefile . -} - -do_compile() { - oe_runmake clean && oe_runmake -} - -do_install() { - install -d ${D}${bindir} - install -m 0755 linux64/cst ${D}${bindir}/cst - install -m 0755 linux64/srktool ${D}${bindir}/srktool - install -m 0755 keys/hab4_pki_tree.sh ${D}${bindir}/trustfence-gen-pki.sh - install -m 0755 ca/openssl.cnf ${D}${bindir}/openssl.cnf - install -m 0755 ca/v3_ca.cnf ${D}${bindir}/v3_ca.cnf - install -m 0755 ca/v3_usr.cnf ${D}${bindir}/v3_usr.cnf -} +require trustfence-cst-native.inc diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.3.bb b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.3.bb new file mode 100644 index 000000000..dc6e8bbd5 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_2.3.3.bb @@ -0,0 +1,5 @@ +# Copyright (C) 2017 Digi International + +require trustfence-cst-native.inc + +INSANE_SKIP_${PN} += "already-stripped" diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch similarity index 100% rename from meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch rename to meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0002-hab4_pki_tree.sh-automate-script.patch b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0002-hab4_pki_tree.sh-automate-script.patch similarity index 100% rename from meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0002-hab4_pki_tree.sh-automate-script.patch rename to meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0002-hab4_pki_tree.sh-automate-script.patch diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0003-openssl_helper-use-dev-urandom-as-seed-source.patch b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0003-openssl_helper-use-dev-urandom-as-seed-source.patch similarity index 100% rename from meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0003-openssl_helper-use-dev-urandom-as-seed-source.patch rename to meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0003-openssl_helper-use-dev-urandom-as-seed-source.patch diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0004-hab4_pki_tree.sh-usa-a-random-password-for-the-defau.patch b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0004-hab4_pki_tree.sh-usa-a-random-password-for-the-defau.patch similarity index 100% rename from meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/0004-hab4_pki_tree.sh-usa-a-random-password-for-the-defau.patch rename to meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/0004-hab4_pki_tree.sh-usa-a-random-password-for-the-defau.patch diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/Makefile b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/Makefile similarity index 100% rename from meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-2.3.2/Makefile rename to meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst/Makefile From f5378d20969246bb23cf4ce451d9ae6d9b85af41 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Thu, 23 Nov 2017 15:49:46 +0100 Subject: [PATCH 100/113] dnsmasq: update to 2.78 version to include vulnerability fixes. This commit updates dnsmasq to version 2.78 to include the following vulnerability patches: * CVE-2017-13704 * CVE-2017-14491 * CVE-2017-14492 * CVE-2017-14493 * CVE-2017-14494 * CVE-2017-14495 * CVE-2017-14496 Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-5136 --- .../recipes-support/dnsmasq/dnsmasq/lua.patch | 30 ++ .../recipes-support/dnsmasq/dnsmasq_2.78.bb | 10 + .../recipes-support/dnsmasq/files/99_dnsmasq | 1 + .../files/dnsmasq-noresolvconf.service | 15 + .../dnsmasq/files/dnsmasq-resolvconf-helper | 62 ++++ .../dnsmasq/files/dnsmasq-resolvconf.service | 17 + .../dnsmasq/files/dnsmasq.conf | 298 ++++++++++++++++++ .../dnsmasq/files/dnsmasq.resolvconf | 84 +++++ .../recipes-support/dnsmasq/files/init | 117 +++++++ 9 files changed, 634 insertions(+) create mode 100644 meta-digi-dey/recipes-support/dnsmasq/dnsmasq/lua.patch create mode 100644 meta-digi-dey/recipes-support/dnsmasq/dnsmasq_2.78.bb create mode 100644 meta-digi-dey/recipes-support/dnsmasq/files/99_dnsmasq create mode 100644 meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-noresolvconf.service create mode 100644 meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf-helper create mode 100644 meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf.service create mode 100755 meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.conf create mode 100755 meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.resolvconf create mode 100644 meta-digi-dey/recipes-support/dnsmasq/files/init diff --git a/meta-digi-dey/recipes-support/dnsmasq/dnsmasq/lua.patch b/meta-digi-dey/recipes-support/dnsmasq/dnsmasq/lua.patch new file mode 100644 index 000000000..0991dd8b9 --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/dnsmasq/lua.patch @@ -0,0 +1,30 @@ +From be1b3d2d0f1608cba5efee73d6aac5ad0709041b Mon Sep 17 00:00:00 2001 +From: Joe MacDonald +Date: Tue, 9 Sep 2014 10:24:58 -0400 +Subject: [PATCH] Upstream-status: Inappropriate [OE specific] + +Signed-off-by: Christopher Larson +Signed-off-by: Paul Eggleton + +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index 73ea23e..ed3eeb9 100644 +--- a/Makefile ++++ b/Makefile +@@ -59,8 +59,8 @@ idn2_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFI + idn2_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --libs libidn2` + ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack` + ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack` +-lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.2` +-lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.2` ++lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua` ++lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua` + nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed` + nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed` + gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp` +-- +2.9.5 + diff --git a/meta-digi-dey/recipes-support/dnsmasq/dnsmasq_2.78.bb b/meta-digi-dey/recipes-support/dnsmasq/dnsmasq_2.78.bb new file mode 100644 index 000000000..e768551f4 --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/dnsmasq_2.78.bb @@ -0,0 +1,10 @@ +# Copyright (C) 2017 Digi International Inc. + +require recipes-support/dnsmasq/dnsmasq.inc + +SRC_URI += "\ + file://lua.patch \ +" + +SRC_URI[dnsmasq-2.78.md5sum] = "3bb97f264c73853f802bf70610150788" +SRC_URI[dnsmasq-2.78.sha256sum] = "c92e5d78aa6353354d02aabf74590d08980bb1385d8a00b80ef9bc80430aa1dc" diff --git a/meta-digi-dey/recipes-support/dnsmasq/files/99_dnsmasq b/meta-digi-dey/recipes-support/dnsmasq/files/99_dnsmasq new file mode 100644 index 000000000..f52ce4e8f --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/files/99_dnsmasq @@ -0,0 +1 @@ +d root root 0755 /run/dnsmasq none diff --git a/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-noresolvconf.service b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-noresolvconf.service new file mode 100644 index 000000000..0c64fab00 --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-noresolvconf.service @@ -0,0 +1,15 @@ +[Unit] +Description=DNS forwarder and DHCP server +After=network.target + +[Service] +Type=forking +PIDFile=/run/dnsmasq.pid +ExecStartPre=/usr/bin/dnsmasq --test +ExecStart=/usr/bin/dnsmasq -x /run/dnsmasq.pid -7 /etc/dnsmasq.d --local-service +ExecStop=/bin/kill $MAINPID +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target + diff --git a/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf-helper b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf-helper new file mode 100644 index 000000000..db54d467e --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf-helper @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Borrowing heavily from the dnsmasq initscript's version of support for +# resolvconf, intended for use in systemd-only configurations. +# +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/dnsmasq +NAME=dnsmasq + +# Most configuration options in /etc/default/dnsmasq are deprecated +# but still honoured. +if [ -r /etc/default/$NAME ]; then + . /etc/default/$NAME +fi + +start_resolvconf() +{ + # If interface "lo" is explicitly disabled in /etc/default/dnsmasq + # Then dnsmasq won't be providing local DNS, so don't add it to + # the resolvconf server set. + for interface in $DNSMASQ_EXCEPT + do + [ $interface = lo ] && return + done + + if [ -x /sbin/resolvconf ] ; then + echo "nameserver 127.0.0.1" | + /sbin/resolvconf -a lo.$NAME + fi + return 0 +} + +stop_resolvconf() +{ + if [ -x /sbin/resolvconf ] ; then + /sbin/resolvconf -d lo.$NAME + fi + return 0 +} + +case "$1" in + start) + start_resolvconf + exit 0 + ;; + stop) + stop_resolvconf + exit 0 + ;; + restart) + stop_resolvconf + start_resolvconf + exit 0 + ;; + *) + echo "Usage: /etc/init.d/$NAME {start|stop|restart}" >&2 + exit 3 + ;; +esac + +exit 0 + diff --git a/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf.service b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf.service new file mode 100644 index 000000000..2980f7def --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq-resolvconf.service @@ -0,0 +1,17 @@ +[Unit] +Description=DNS forwarder and DHCP server +After=network.target + +[Service] +Type=forking +PIDFile=/run/dnsmasq.pid +ExecStartPre=/usr/bin/dnsmasq --test +ExecStart=/usr/bin/dnsmasq -x /run/dnsmasq.pid -7 /etc/dnsmasq.d --local-service +ExecStartPost=/usr/bin/dnsmasq-resolvconf-helper start +ExecStopPre=/usr/bin/dnsmasq-resolvconf-helper stop +ExecStop=/bin/kill $MAINPID +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target + diff --git a/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.conf b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.conf new file mode 100755 index 000000000..9e5ab9f81 --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.conf @@ -0,0 +1,298 @@ +# Configuration file for dnsmasq. +# +# Format is one option per line, legal options are the same +# as the long options legal on the command line. See +# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details. + +# Listen on this specific port instead of the standard DNS port +# (53). Setting this to zero completely disables DNS function, +# leaving only DHCP and/or TFTP. +#port=5353 + +# Change these lines if you want dnsmasq to serve MX records. +# Only one of mx-host and mx-target need be set, the other defaults +# to the name of the host running dnsmasq. +#mx-host= +#mx-target= +#selfmx +#localmx + +# The following two options make you a better netizen, since they +# tell dnsmasq to filter out queries which the public DNS cannot +# answer, and which load the servers (especially the root servers) +# uneccessarily. If you have a dial-on-demand link they also stop +# these requests from bringing up the link uneccessarily. + +# Never forward plain names (with a dot or domain part) +domain-needed +# Never forward addresses in the non-routed address spaces. +bogus-priv + + +# Uncomment this to filter useless windows-originated DNS requests +# which can trigger dial-on-demand links needlessly. +# Note that (amongst other things) this blocks all SRV requests, +# so don't use it if you use eg Kerberos. +#filterwin2k + +# Change this line if you want dns to get its upstream servers from +# somewhere other that /etc/resolv.conf +#resolv-file= + +# By default, dnsmasq will send queries to any of the upstream +# servers it knows about and tries to favour servers to are known +# to be up. Uncommenting this forces dnsmasq to try each query +# with each server strictly in the order they appear in +# /etc/resolv.conf +#strict-order + +# If you don't want dnsmasq to read /etc/resolv.conf or any other +# file, getting its servers for this file instead (see below), then +# uncomment this +#no-resolv + +# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv +# files for changes and re-read them then uncomment this. +#no-poll + +# Add other name servers here, with domain specs if they are for +# non-public domains. +#server=/localnet/192.168.0.1 + +# Add local-only domains here, queries in these domains are answered +# from /etc/hosts or DHCP only. +#local=/localnet/ + +# Add domains which you want to force to an IP address here. +# The example below send any host in doubleclick.net to a local +# webserver. +#address=/doubleclick.net/127.0.0.1 + +# You no longer (as of version 1.7) need to set these to enable +# dnsmasq to read /etc/ppp/resolv.conf since dnsmasq now uses the +# "dip" group to achieve this. +#user= +#group= + +# If you want dnsmasq to listen for requests only on specified interfaces +# (and the loopback) give the name of the interface (eg eth0) here. +# Repeat the line for more than one interface. +#interface= +# Or you can specify which interface _not_ to listen on +#except-interface= +# Or which to listen on by address (remember to include 127.0.0.1 if +# you use this.) +#listen-address=127.0.0.1 + +# On systems which support it, dnsmasq binds the wildcard address, +# even when it is listening on only some interfaces. It then discards +# requests that it shouldn't reply to. This has the advantage of +# working even when interfaces come and go and change address. If you +# want dnsmasq to really bind only the interfaces it is listening on, +# uncomment this option. About the only time you may need this is when +# running another nameserver on the same machine. +#bind-interfaces + +# If you don't want dnsmasq to read /etc/hosts, uncomment the +# following line. +#no-hosts +# or if you want it to read another file, as well as /etc/hosts, use +# this. +#addn-hosts=/etc/banner_add_hosts + +# Set this (and domain: see below) if you want to have a domain +# automatically added to simple names in a hosts-file. +#expand-hosts + +# Set the domain for dnsmasq. this is optional, but if it is set, it +# does the following things. +# 1) Allows DHCP hosts to have fully qualified domain names, as long +# as the domain part matches this setting. +# 2) Sets the "domain" DHCP option thereby potentially setting the +# domain of all systems configured by DHCP +# 3) Provides the domain part for "expand-hosts" +#domain=thekelleys.org.uk + +# Uncomment this to enable the integrated DHCP server, you need +# to supply the range of addresses available for lease and optionally +# a lease time. If you have more than one network, you will need to +# repeat this for each network on which you want to supply DHCP +# service. +#dhcp-range=192.168.0.50,192.168.0.150,12h +#dhcp-range=10.0.0.10,10.0.0.200,2h + +# This is an example of a DHCP range where the netmask is given. This +# is needed for networks we reach the dnsmasq DHCP server via a relay +# agent. If you don't know what a DHCP relay agent is, you probably +# don't need to worry about this. +#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h + +# This is an example of a DHCP range with a network-id, so that +# some DHCP options may be set only for this network. +#dhcp-range=red,192.168.0.50,192.168.0.150 + +# Supply parameters for specified hosts using DHCP. There are lots +# of valid alternatives, so we will give examples of each. Note that +# IP addresses DO NOT have to be in the range given above, they just +# need to be on the same network. The order of the parameters in these +# do not matter, it's permissble to give name,adddress and MAC in any order + +# Always allocate the host with ethernet address 11:22:33:44:55:66 +# The IP address 192.168.0.60 +#dhcp-host=11:22:33:44:55:66,192.168.0.60 + +# Always set the name of the host with hardware address +# 11:22:33:44:55:66 to be "fred" +#dhcp-host=11:22:33:44:55:66,fred + +# Always give the host with ethernet address 11:22:33:44:55:66 +# the name fred and IP address 192.168.0.60 and lease time 45 minutes +#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m + +# Give the machine which says it's name is "bert" IP address +# 192.168.0.70 and an infinite lease +#dhcp-host=bert,192.168.0.70,infinite + +# Always give the host with client identifier 01:02:02:04 +# the IP address 192.168.0.60 +#dhcp-host=id:01:02:02:04,192.168.0.60 + +# Always give the host with client identifier "marjorie" +# the IP address 192.168.0.60 +#dhcp-host=id:marjorie,192.168.0.60 + +# Enable the address given for "judge" in /etc/hosts +# to be given to a machine presenting the name "judge" when +# it asks for a DHCP lease. +#dhcp-host=judge + +# Never offer DHCP service to a machine whose ethernet +# address is 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,ignore + +# Ignore any client-id presented by the machine with ethernet +# address 11:22:33:44:55:66. This is useful to prevent a machine +# being treated differently when running under different OS's or +# between PXE boot and OS boot. +#dhcp-host=11:22:33:44:55:66,id:* + +# Send extra options which are tagged as "red" to +# the machine with ethernet address 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,net:red + +# Send extra options which are tagged as "red" to any machine whose +# DHCP vendorclass string includes the substring "Linux" +#dhcp-vendorclass=red,Linux + +# Send extra options which are tagged as "red" to any machine one +# of whose DHCP userclass strings includes the substring "accounts" +#dhcp-userclass=red,accounts + +# If this line is uncommented, dnsmasq will read /etc/ethers and act +# on the ethernet-address/IP pairs found there just as if they had +# been given as --dhcp-host options. Useful if you keep +# MAC-address/host mappings there for other purposes. +#read-ethers + +# Send options to hosts which ask for a DHCP lease. +# See RFC 2132 for details of available options. +# Note that all the common settings, such as netmask and +# broadcast address, DNS server and default route, are given +# sane defaults by dnsmasq. You very likely will not need any +# any dhcp-options. If you use Windows clients and Samba, there +# are some options which are recommended, they are detailed at the +# end of this section. +# For reference, the common options are: +# subnet mask - 1 +# default router - 3 +# DNS server - 6 +# broadcast address - 28 + +# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5 +#dhcp-option=42,192.168.0.4,10.10.0.5 + +# Set the NTP time server address to be the same machine as +# is running dnsmasq +#dhcp-option=42,0.0.0.0 + +# Set the NIS domain name to "welly" +#dhcp-option=40,welly + +# Set the default time-to-live to 50 +#dhcp-option=23,50 + +# Set the "all subnets are local" flag +#dhcp-option=27,1 + +# Send the etherboot magic flag and then etherboot options (a string). +#dhcp-option=128,e4:45:74:68:00:00 +#dhcp-option=129,NIC=eepro100 + +# Specify an option which will only be sent to the "red" network +# (see dhcp-range for the declaration of the "red" network) +#dhcp-option=red,42,192.168.1.1 + +# The following DHCP options set up dnsmasq in the same way as is specified +# for the ISC dhcpcd in +# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt +# adapted for a typical dnsmasq installation where the host running +# dnsmasq is also the host running samba. +# you may want to uncomment them if you use Windows clients and Samba. +#dhcp-option=19,0 # option ip-forwarding off +#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s) +#dhcp-option=45,0.0.0.0 # netbios datagram distribution server +#dhcp-option=46,8 # netbios node type +#dhcp-option=47 # empty netbios scope. + + +# Set the boot filename and tftpd server name and address +# for BOOTP. You will only need this is you want to +# boot machines over the network. +#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3 + +# Set the limit on DHCP leases, the default is 150 +#dhcp-lease-max=150 + +# The DHCP server needs somewhere on disk to keep its lease database. +# This defaults to a sane location, but if you want to change it, use +# the line below. +#dhcp-leasefile=/var/lib/misc/dnsmasq.leases + +# Set the cachesize here. +#cache-size=150 + +# If you want to disable negative caching, uncomment this. +#no-negcache + +# Normally responses which come form /etc/hosts and the DHCP lease +# file have Time-To-Live set as zero, which conventionally means +# do not cache further. If you are happy to trade lower load on the +# server for potentially stale date, you can set a time-to-live (in +# seconds) here. +#local-ttl= + +# If you want dnsmasq to detect attempts by Verisign to send queries +# to unregistered .com and .net hosts to its sitefinder service and +# have dnsmasq instead return the correct NXDOMAIN response, uncomment +# this line. You can add similar lines to do the same for other +# registries which have implemented wildcard A records. +#bogus-nxdomain=64.94.110.11 + +# If you want to fix up DNS results from upstream servers, use the +# alias option. This only works for IPv4. +# This alias makes a result of 1.2.3.4 appear as 5.6.7.8 +#alias=1.2.3.4,5.6.7.8 +# and this maps 1.2.3.x to 5.6.7.x +#alias=1.2.3.0,5.6.7.0,255.255.255.0 + +# For debugging purposes, log each DNS query as it passes through +# dnsmasq. +#log-queries + +# Include a another lot of configuration options. +#conf-file=/etc/dnsmasq.more.conf + + + + + diff --git a/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.resolvconf b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.resolvconf new file mode 100755 index 000000000..06cd25cec --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/files/dnsmasq.resolvconf @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Script to update the resolver list for dnsmasq +# +# N.B. Resolvconf may run us even if dnsmasq is not (yet) running. +# If dnsmasq is installed then we go ahead and update the resolver list +# in case dnsmasq is started later. +# +# Assumption: On entry, PWD contains the resolv.conf-type files. +# +# This file is part of the dnsmasq package. +# + +set -e + +RUN_DIR="/run/dnsmasq" +RSLVRLIST_FILE="${RUN_DIR}/resolv.conf" +TMP_FILE="${RSLVRLIST_FILE}_new.$$" +MY_NAME_FOR_RESOLVCONF="dnsmasq" + +[ -x /usr/bin/dnsmasq ] || exit 0 +[ -x /lib/resolvconf/list-records ] || exit 1 + +PATH=/bin:/sbin + +report_err() { echo "$0: Error: $*" >&2 ; } + +# Stores arguments (minus duplicates) in RSLT, separated by spaces +# Doesn't work properly if an argument itself contains whitespace +uniquify() +{ + RSLT="" + while [ "$1" ] ; do + for E in $RSLT ; do + [ "$1" = "$E" ] && { shift ; continue 2 ; } + done + RSLT="${RSLT:+$RSLT }$1" + shift + done +} + +if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then + report_err "Failed trying to create directory $RUN_DIR" + exit 1 +fi + +RSLVCNFFILES="" +for F in $(/lib/resolvconf/list-records --after "lo.$MY_NAME_FOR_RESOLVCONF") ; do + case "$F" in + "lo.$MY_NAME_FOR_RESOLVCONF") + # Omit own record + ;; + lo.*) + # Include no more records after one for a local nameserver + RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" + break + ;; + *) + RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" + ;; + esac +done + +NMSRVRS="" +if [ "$RSLVCNFFILES" ] ; then + uniquify $(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]\+//p' $RSLVCNFFILES) + NMSRVRS="$RSLT" +fi + +# Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second, +# to detect changes in the file. This means that if a resolvconf update occurs +# within one second of the previous one then dnsmasq may fail to notice the +# more recent change. To work around this problem we sleep one second here +# if necessary in order to ensure that the new mtime is different. +if [ -f "$RSLVRLIST_FILE" ] && [ "$(stat -c %X "$RSLVRLIST_FILE")" = "$(date +%s)" ] ; then + sleep 1 +fi + +clean_up() { rm -f "$TMP_FILE" ; } +trap clean_up EXIT +: >| "$TMP_FILE" +for N in $NMSRVRS ; do echo "nameserver $N" >> "$TMP_FILE" ; done +mv -f "$TMP_FILE" "$RSLVRLIST_FILE" + diff --git a/meta-digi-dey/recipes-support/dnsmasq/files/init b/meta-digi-dey/recipes-support/dnsmasq/files/init new file mode 100644 index 000000000..51c95dfed --- /dev/null +++ b/meta-digi-dey/recipes-support/dnsmasq/files/init @@ -0,0 +1,117 @@ +#!/bin/sh +DAEMON=/usr/bin/dnsmasq +NAME=dnsmasq +DESC="DNS forwarder and DHCP server" +ARGS="-7 /etc/dnsmasq.d" + +test -f $DAEMON || exit 0 + +set -e + +if [ -r /etc/default/$NAME ] +then + . /etc/default/$NAME +fi + +DNSMASQ_CONF="/etc/dnsmasq.conf" +test "/etc/dnsmasq.d/*" != '/etc/dnsmasq.d/*' && DNSMASQ_CONF="${DNSMASQ_CONF} /etc/dnsmasq.d/*" + +test -z "${PIDFILE}" && PIFILE="/run/dnsmasq.pid" + +if [ -z "$IGNORE_RESOLVCONF" ] +then + egrep -h -q '^no-resolv' ${DNSMASQ_CONF} && IGNORE_RESOLVCONF="yes" +fi + +# RESOLV_CONF: +# If the resolvconf package is installed then use the resolv conf file +# that it provides as the default. Otherwise use /etc/resolv.conf as +# the default. +# +# If IGNORE_RESOLVCONF is set in /etc/default/dnsmasq or an explicit +# filename is set there then this inhibits the use of the resolvconf-provided +# information. +# +# Note that if the resolvconf package is installed it is not possible to +# override it just by configuration in /etc/dnsmasq.conf, it is necessary +# to set IGNORE_RESOLVCONF=yes in /etc/default/dnsmasq. + +test -z "$RESOLV_CONF" -a "$IGNORE_RESOLVCONF" != "yes" -a -x /sbin/resolvconf && \ + RESOLV_CONF=/run/dnsmasq/resolv.conf + +start_resolvconf() +{ + if [ "$IGNORE_RESOLVCONF" != "yes" -a -x /sbin/resolvconf ] + then + echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.$NAME + fi + : +} + +stop_resolvconf() +{ + if [ "$IGNORE_RESOLVCONF" != "yes" -a -x /sbin/resolvconf ] + then + /sbin/resolvconf -d lo.$NAME + fi + : +} + +case "$1" in + start) + echo -n "starting $DESC: $NAME... " + test -d /var/lib/misc/ || mkdir /var/lib/misc/ + start-stop-daemon -S -x $DAEMON -- $ARGS \ + ${RESOLV_CONF:+ -r $RESOLV_CONF} \ + ${PIDFILE:+ -x $PIDFILE} + test $? -eq 0 && start_resolvconf + echo "done." + ;; + stop) + echo -n "stopping $DESC: $NAME... " + stop_resolvconf + start-stop-daemon -K -x $DAEMON + echo "done." + ;; + status) + echo -n "dnsmasq " + start-stop-daemon -q -K -t -x $DAEMON + RET=$? + if [ "$RET" = "0" ]; then + PID=`cat ${PIDFILE}` + echo "($PID) is running" + else + echo "is not running" + exit $RET + fi + ;; + restart) + echo "restarting $DESC: $NAME... " + $0 stop + $0 start + echo "done." + ;; + reload) + echo -n "reloading $DESC: $NAME... " + killall -HUP $(basename ${DAEMON}) + echo "done." + ;; + systemd-start-resolvconf) + start_resolvconf + ;; + systemd-stop-resolvconf) + stop_resolvconf + ;; + systemd-exec) + test -d /var/lib/misc/ || mkdir /var/lib/misc/ + exec $DAEMON --keep-in-foreground $ARGS \ + ${RESOLV_CONF:+ -r $RESOLV_CONF} \ + ${PIDFILE:+ -x $PIDFILE} + ;; + *) + echo "Usage: $0 {start|stop|status|restart|reload}" + exit 1 + ;; +esac + +exit 0 From a2d16e749e6db7d1b90cdc664ac8d914ef4de284 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Fri, 24 Nov 2017 14:58:17 +0100 Subject: [PATCH 101/113] README: Add OS version that have been used to build DEY This commit adds the different OS version that have been used to build DEY. Signed-off-by: Mike Engel https://jira.digi.com/browse/DEL-4984 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 972657536..92692ee83 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,14 @@ Digi Embedded Yocto 2.2 is based on the Yocto Project(TM) 2.2 (Morty) release. For a full list of supported features and interfaces please refer to the online documentation. +# Tested OS versions + +The current release has been verified and tested with the following +OS versions: + +* Ubuntu 16.04 +* Ubuntu 14.04 + # Supported Platforms The current release supports the following hardware platforms: From 0b7da46eb0b6c03bedf62b30d9104c8f3526c8bb Mon Sep 17 00:00:00 2001 From: Jose Diaz de Grenu Date: Fri, 24 Nov 2017 15:11:02 +0100 Subject: [PATCH 102/113] trustfence-cst: avoid warnings about cst tarball When parsing the recipe, a warning is shown because the tarball is only found in the downloads folder. However this is expected as it cannot be distributed. As a workaround, add the tarball to the SRC_URI variable only when Trustfence is active. That way the warning is not shown in all other cases. This was incorrectly removed in commit 14fc51147f6e. Signed-off-by: Jose Diaz de Grenu --- .../recipes-bsp/trustfence-cst/trustfence-cst-native.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc index 8d437c2b7..dd11a8fd4 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc +++ b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native.inc @@ -8,7 +8,7 @@ LICENSE = "CLOSED" DEPENDS = "openssl-native" SRC_URI = " \ - file://cst-${PV}.tar.gz \ + ${@base_conditional('TRUSTFENCE_SIGN', '1', 'file://cst-${PV}.tar.gz', '', d)} \ file://0001-gen_auth_encrypted_data-reuse-existing-DEK-file.patch \ file://0002-hab4_pki_tree.sh-automate-script.patch \ file://0003-openssl_helper-use-dev-urandom-as-seed-source.patch \ From 31444d1bd11560499083139c7f38d291c19ef453 Mon Sep 17 00:00:00 2001 From: Tatiana Leon Date: Thu, 23 Nov 2017 14:23:36 +0100 Subject: [PATCH 103/113] AWS Greengrass: set the GG Core daemon relative path in the init script The recipe modifies the Greengrass Core init script to properly configure the daemon relative path. This daemon location is different depending on the Greengrass version being used. This commits also moves the patch for Greengrass Core 1.0.0 to the 'greengrass-1.0.0' directory in preparation for adding Greengrass Core 1.1.0 recipe in the next commit. https://jira.digi.com/browse/DEL-5368 Signed-off-by: Tatiana Leon --- ...1-greengrassd-remove-bashisms-in-launcher-shell-script.patch | 0 meta-digi-dey/recipes-aws/greengrass/greengrass/greengrass-init | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename meta-digi-dey/recipes-aws/greengrass/{greengrass => greengrass-1.0.0}/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch (100%) diff --git a/meta-digi-dey/recipes-aws/greengrass/greengrass/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch b/meta-digi-dey/recipes-aws/greengrass/greengrass-1.0.0/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch similarity index 100% rename from meta-digi-dey/recipes-aws/greengrass/greengrass/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch rename to meta-digi-dey/recipes-aws/greengrass/greengrass-1.0.0/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch diff --git a/meta-digi-dey/recipes-aws/greengrass/greengrass/greengrass-init b/meta-digi-dey/recipes-aws/greengrass/greengrass/greengrass-init index 8af4aafde..ed6fbb74a 100644 --- a/meta-digi-dey/recipes-aws/greengrass/greengrass/greengrass-init +++ b/meta-digi-dey/recipes-aws/greengrass/greengrass/greengrass-init @@ -18,7 +18,7 @@ # GG_INSTALL_DIR="##GG_INSTALL_DIR##" -GG_LAUNCHER="${GG_INSTALL_DIR}/greengrassd" +GG_LAUNCHER="$(find ${GG_INSTALL_DIR} -type f -name greengrassd)" case "${1}" in start | stop | restart) From 65a3cb16677f2794929aab367a1ac65167e87384 Mon Sep 17 00:00:00 2001 From: Tatiana Leon Date: Thu, 23 Nov 2017 14:46:56 +0100 Subject: [PATCH 104/113] AWS Greengrass: add new recipe for AWS Greengrass core 1.1.0 https://jira.digi.com/browse/DEL-5368 Signed-off-by: Tatiana Leon --- ...ve-bashisms-in-launcher-shell-script.patch | 114 ++++++++++ .../greengrass/greengrass_1.1.0.bb | 203 ++++++++++++++++++ 2 files changed, 317 insertions(+) create mode 100644 meta-digi-dey/recipes-aws/greengrass/greengrass-1.1.0/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch create mode 100644 meta-digi-dey/recipes-aws/greengrass/greengrass_1.1.0.bb diff --git a/meta-digi-dey/recipes-aws/greengrass/greengrass-1.1.0/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch b/meta-digi-dey/recipes-aws/greengrass/greengrass-1.1.0/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch new file mode 100644 index 000000000..adcdea806 --- /dev/null +++ b/meta-digi-dey/recipes-aws/greengrass/greengrass-1.1.0/0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch @@ -0,0 +1,114 @@ +From: Tatiana Leon +Date: Mon, 13 Nov 2017 20:01:59 +0100 +Subject: [PATCH] greengrassd: remove bashisms in launcher shell script + +So it runs properly in other Posix shells (like the one in Busybox) + +Signed-off-by: Tatiana Leon +--- + .../ggc/packages/1.1.0/greengrassd | 27 +++++++++++----------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +diff --git a/ggc/packages/1.1.0/greengrassd +index 9bece0c..4d68477 100755 +--- a/ggc/packages/1.1.0/greengrassd ++++ b/ggc/packages/1.1.0/greengrassd +@@ -1,4 +1,4 @@ +-#!/usr/bin/env bash ++#!/bin/sh + + ##########Environment Requirement for Greengrass Daemon########## + # by default, the daemon assumes it's going to be launched from a directory +@@ -42,20 +42,21 @@ setup() { + mkdir -p $GGC_ROOT_FS + + # Mask greengrass directory for containers +- mknod $GGC_ROOT_FS/greengrass c 1 3 &>/dev/null || true ++ mknod $GGC_ROOT_FS/greengrass c 1 3 >/dev/null 2>&1 || true + + mkdir -p $(dirname "$CRASH_LOG") + } + + validatePlatformSecurity() { + +- if [[ -f $FS_SETTINGS/protected_hardlinks && +- -f $FS_SETTINGS/protected_symlinks ]]; then ++ if [ -f $FS_SETTINGS/protected_hardlinks ] && ++ [ -f $FS_SETTINGS/protected_symlinks ]; then ++ + + PROT_HARDLINK_VAL=$(cat $FS_SETTINGS/protected_hardlinks) + PROT_SOFTLINK_VAL=$(cat $FS_SETTINGS/protected_symlinks) + +- if [[ "$PROT_HARDLINK_VAL" -ne 1 || "$PROT_SOFTLINK_VAL" -ne 1 ]]; then ++ if [ "$PROT_HARDLINK_VAL" -ne 1 ] || [ "$PROT_SOFTLINK_VAL" -ne 1 ]; then + echo "AWS Greengrass detected insecure OS configuration: No hardlink/softlink protection enabled." | tee -a $CRASH_LOG + exit 1 + fi +@@ -134,13 +135,13 @@ finish() { + pid=$1 + echo "$pid" > $PID_FILE + echo "" +- echo -e "\e[0;32mGreengrass successfully started with PID: $pid\e[0m" ++ printf "\e[0;32mGreengrass successfully started with PID: $pid\e[0m\n" + exit 0 + } + + start() { + setup +- if [[ $INSECURE -ne 1 ]]; then ++ if [ "${INSECURE}" != "1" ]; then + validatePlatformSecurity + fi + +@@ -159,7 +160,7 @@ start() { + + echo "" + echo "Greengrass daemon $pid failed to start" +- echo -e "\e[0;31m$(cat $CRASH_LOG)\e[0m" ++ printf "\e[0;31m$(cat $CRASH_LOG)\e[0m\n" + exit 1 + else + echo "Failed to start Greengrass daemon" +@@ -191,7 +192,7 @@ stop() { + # If the pid no longer exists, we're done, remove the pid file and exit. Otherwise, just increment the loop counter + if [ ! -e "/proc/$PID" ]; then + rm $PID_FILE +- echo -e "\nStopped greengrass daemon, exiting with success" ++ printf "\nStopped greengrass daemon, exiting with success\n" + break + else + total_sleep_seconds=$(($total_sleep_seconds+1)) +@@ -207,7 +208,7 @@ stop() { + if [ $total_sleep_seconds -ge $MAX_DAEMON_KILL_WAIT_SECONDS ] && [ -e "/proc/$PID" ]; then + # If we are here, we never exited in the previous loop and the pid still exists. Exit with failure. + kill -9 "$PID" > /dev/null 2>&1 +- echo -e "\nProcess with pid $PID still alive after timeout of $MAX_DAEMON_KILL_WAIT_SECONDS seconds. Forced kill process, exiting with failure." ++ printf "\nProcess with pid $PID still alive after timeout of $MAX_DAEMON_KILL_WAIT_SECONDS seconds. Unable to kill process, exiting with failure.\n" + exit 1 + fi + fi +@@ -217,12 +218,12 @@ usage() { + echo "" + echo "Usage: $0 [FLAGS] {start|stop|restart}" + echo "" +- echo -e "[FLAGS]: \n -i, --insecure \t Run GGC in insecure mode without hardlink/softlink protection, (highly discouraged for production use) \n -v, --version \t\t Outputs the version of GGC." ++ printf "[FLAGS]: \n -i, --insecure \t Run GGC in insecure mode without hardlink/softlink protection, (highly discouraged for production use) \n -v, --version \t\t Outputs the version of GGC.\n" + echo "" + exit 1 + } + +-if [[ $# -eq 0 ]]; then ++if [ $# -eq 0 ]; then + usage + fi + +@@ -236,7 +237,7 @@ do + esac + done + +-while [[ $# -gt 0 ]] ++while [ $# -gt 0 ] + do + key="$1" + case $key in diff --git a/meta-digi-dey/recipes-aws/greengrass/greengrass_1.1.0.bb b/meta-digi-dey/recipes-aws/greengrass/greengrass_1.1.0.bb new file mode 100644 index 000000000..a43a586cd --- /dev/null +++ b/meta-digi-dey/recipes-aws/greengrass/greengrass_1.1.0.bb @@ -0,0 +1,203 @@ +# Copyright (C) 2017, Digi International Inc. + +SUMMARY = "AWS IoT Greengrass core" +HOMEPAGE = "https://aws.amazon.com/greengrass/" +# +# The package includes different licenses: +# +# [Apache-2.0] +# ggc/core/LICENSE/attributions/github_aws_aws_sdk_go_License.txt +# ggc/core/LICENSE/attributions/github_coreos_go_systemd_License.txt +# ggc/core/LICENSE/attributions/github_docker_docker_License.txt +# ggc/core/LICENSE/attributions/github_docker_go_units_License.txt +# ggc/core/LICENSE/attributions/github_go_ini_ini_License.txt +# ggc/core/LICENSE/attributions/github_jmespath_go_jmespath_License.txt +# ggc/core/LICENSE/attributions/github_opencontainers_runc_License.txt +# ggc/core/LICENSE/attributions/github_opencontainers_runtime_spec_License.txt +# ggc/core/LICENSE/attributions/github_pquerna_ffjson_License.txt +# ggc/core/LICENSE/attributions/github_vishvananda_netlink_License.txt +# [BSD-2-Clause] +# ggc/core/LICENSE/attributions/github_godbus_dbus_License.txt +# ggc/core/LICENSE/attributions/github_huin_gobinarytest_License.txt +# ggc/core/LICENSE/attributions/github_seccomp_libseccomp_golang_License.txt +# ggc/core/LICENSE/attributions/github_syndtr_gocapability_License.txt +# [BSD-3-Clause] +# ggc/core/LICENSE/attributions/github_fsnotify_fsnotify_License.txt +# ggc/core/LICENSE/attributions/github_golang_protobuf_License.txt +# ggc/core/LICENSE/attributions/github_jeffallen_mqtt_License.txt +# ggc/core/LICENSE/attributions/Golang_License.txt +# [MIT] +# ggc/core/LICENSE/attributions/github_huin_mqtt_License.txt +# ggc/core/LICENSE/attributions/github_mattn_go_sqlite3_License.txt +# ggc/core/LICENSE/attributions/github_nu7hatch_gouuid_License.txt +# ggc/core/LICENSE/attributions/github_Sirupsen_logrus_License.txt +# ggc/core/LICENSE/attributions/github_urfave_cli_License.txt +# ggc/core/LICENSE/attributions/github_yosssi_gmq_License.txt +# [PD] +# ggc/core/LICENSE/attributions/sqlite_org_License.txt +# [Proprietary] +# ggc/core/LICENSE/Greengrass AWS SW License (IoT additiona) vr6.txt +# +LICENSE = "Apache-2.0 | BSD-2-Clause | BSD-3-Clause | MIT | PD | Proprietary" +LIC_FILES_CHKSUM = " \ + file://ggc/core/LICENSE/attributions/github_aws_aws_sdk_go_License.txt;md5=d273d63619c9aeaf15cdaf76422c4f87 \ + file://ggc/core/LICENSE/attributions/github_coreos_go_systemd_License.txt;md5=715f3348ed8b9bf4fac3b08133384a4d \ + file://ggc/core/LICENSE/attributions/github_docker_docker_License.txt;md5=bba4ee48af378e39b452d742d29c710b \ + file://ggc/core/LICENSE/attributions/github_docker_go_units_License.txt;md5=bb99db20f1c48c2c4952c27c72855e36 \ + file://ggc/core/LICENSE/attributions/github_fsnotify_fsnotify_License.txt;md5=c38914c9a7ab03bb2b96d4baaee10769 \ + file://ggc/core/LICENSE/attributions/github_godbus_dbus_License.txt;md5=b03a62440372a9acf9692ad365932c87 \ + file://ggc/core/LICENSE/attributions/github_go_ini_ini_License.txt;md5=715f3348ed8b9bf4fac3b08133384a4d \ + file://ggc/core/LICENSE/attributions/github_golang_protobuf_License.txt;md5=16fe162f7848190010b6ec7bfaac030a \ + file://ggc/core/LICENSE/attributions/github_huin_gobinarytest_License.txt;md5=f2b3138d9d314bccf5297dea7e3e6d14 \ + file://ggc/core/LICENSE/attributions/github_huin_mqtt_License.txt;md5=12fd125064676697934b7d8c09bed0e8 \ + file://ggc/core/LICENSE/attributions/github_jeffallen_mqtt_License.txt;md5=b7269d52765d477e10f319c19d8a9d33 \ + file://ggc/core/LICENSE/attributions/github_jmespath_go_jmespath_License.txt;md5=640d33f0070c9dc3a194d2ed7db02974 \ + file://ggc/core/LICENSE/attributions/github_mattn_go_sqlite3_License.txt;md5=948f36a2300ac729e60416063190f664 \ + file://ggc/core/LICENSE/attributions/github_nu7hatch_gouuid_License.txt;md5=6b18748dcc29fda05fa5aaef44d517fd \ + file://ggc/core/LICENSE/attributions/github_opencontainers_runc_License.txt;md5=587c01b2dcc5dc3b4bed51b918c64731 \ + file://ggc/core/LICENSE/attributions/github_opencontainers_runtime_spec_License.txt;md5=ef95ed297310c3d09ba16c06d5e161a5 \ + file://ggc/core/LICENSE/attributions/github_pquerna_ffjson_License.txt;md5=d273d63619c9aeaf15cdaf76422c4f87 \ + file://ggc/core/LICENSE/attributions/github_seccomp_libseccomp_golang_License.txt;md5=9205c4c469bfb9d3a63f346539ee445b \ + file://ggc/core/LICENSE/attributions/github_Sirupsen_logrus_License.txt;md5=29baae91637760ae68feb57ca93e5a0a \ + file://ggc/core/LICENSE/attributions/github_syndtr_gocapability_License.txt;md5=321f58fa53a0b1bb9a887f14660d436b \ + file://ggc/core/LICENSE/attributions/github_urfave_cli_License.txt;md5=f1f14a2449300559aed90bedc36a71ed \ + file://ggc/core/LICENSE/attributions/github_vishvananda_netlink_License.txt;md5=c95fd0efd62139c155e956a448df8fd6 \ + file://ggc/core/LICENSE/attributions/github_yosssi_gmq_License.txt;md5=2509f45544da1ecce869ce2de1aa44dd \ + file://ggc/core/LICENSE/attributions/Golang_License.txt;md5=3d7ed06383c65a3161b36c6a0b0b98f5 \ + file://ggc/core/LICENSE/attributions/sqlite_org_License.txt;md5=380e2694a297aa32879ca2ae9c6c029b \ +" + +# Bitbake does not support spaces in filenames, but GG License does have spaces, +# so workaround the problem by renaming the file before using it. +GG_LIC_FILENAME = "Greengrass AWS SW License (IoT additiona) vr6.txt" +GG_LIC_FILENAME_NOSPACES = "${@d.getVar('GG_LIC_FILENAME', True).replace(' ','_')}" +LIC_FILES_CHKSUM += "file://ggc/core/LICENSE/${GG_LIC_FILENAME_NOSPACES};md5=7df5bf535d02b2f83c260250fe330b6c" + +SRC_URI = " \ + http:///not/exist/greengrass-linux-armv7l-${PV}.tar.gz \ + file://greengrass-init \ + file://0001-greengrassd-remove-bashisms-in-launcher-shell-script.patch \ +" +SRC_URI[md5sum] = "6a13664c6a36e495e773f43ab92b8bdf" +SRC_URI[sha256sum] = "13c2637188eaf01049d875c99dc6929e8e206e4b4c98a4194a0cea827dca306d" + +GG_TARBALL_LOCAL_PATH ?= "" + +# The tarball is only available for downloading after registration, so provide +# a PREMIRROR to a local directory that can be configured in the project's +# local.conf file using GG_TARBALL_LOCAL_PATH variable. +python() { + gg_tarball_local_path = d.getVar('GG_TARBALL_LOCAL_PATH', True) + if gg_tarball_local_path: + premirrors = d.getVar('PREMIRRORS', True) + d.setVar('PREMIRRORS', "http:///not/exist/greengrass.* file://%s \\n %s" % (gg_tarball_local_path, premirrors)) +} + +S = "${WORKDIR}/${BPN}" + +inherit aws-iot update-rc.d useradd + +GG_USESYSTEMD = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'yes', 'no', d)}" + +# Rename GG license file +do_unpack[postfuncs] += "rename_license" +rename_license() { + cd ${S}/ggc/core/LICENSE/ + mv "${GG_LIC_FILENAME}" "${GG_LIC_FILENAME_NOSPACES}" +} + +# Disable tasks not needed for the binary package +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -d ${D}/${BPN} + tar --no-same-owner --exclude='./patches' --exclude='./.pc' -cpf - -C ${S} . \ + | tar --no-same-owner -xpf - -C ${D}/${BPN} + + # Install wrapper bootscript to launch Greengrass core on boot + install -d ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/greengrass-init ${D}${sysconfdir}/init.d/greengrass + sed -i -e "s,##GG_INSTALL_DIR##,/${BPN},g" ${D}${sysconfdir}/init.d/greengrass + + # If certificates do exist, install them and update the config file + if [ -f "${AWS_IOT_CERTS_DIR}/${AWS_GGCORE_ROOT_CA}" ] && \ + [ -f "${AWS_IOT_CERTS_DIR}/${AWS_GGCORE_CERTIFICATE}" ] && \ + [ -f "${AWS_IOT_CERTS_DIR}/${AWS_GGCORE_PRIVATE_KEY}" ]; then + install -m 0644 "${AWS_IOT_CERTS_DIR}/${AWS_GGCORE_ROOT_CA}" \ + "${AWS_IOT_CERTS_DIR}/${AWS_GGCORE_CERTIFICATE}" \ + "${AWS_IOT_CERTS_DIR}/${AWS_GGCORE_PRIVATE_KEY}" \ + ${D}/${BPN}/certs/ + sed -i -e "s,\[ROOT_CA_PEM_HERE],${AWS_GGCORE_ROOT_CA},g" \ + -e "s,\[CLOUD_PEM_CRT_HERE],${AWS_GGCORE_CERTIFICATE},g" \ + -e "s,\[CLOUD_PEM_KEY_HERE],${AWS_GGCORE_PRIVATE_KEY},g" \ + ${D}/${BPN}/config/config.json + fi + + # Configure the rest of GG Core parameters + [ -n "${AWS_GGCORE_THING_ARN}" ] && sed -i -e "s,\[THING_ARN_HERE],${AWS_GGCORE_THING_ARN},g" ${D}/${BPN}/config/config.json + if [ -n "${AWS_GGCORE_IOT_HOST}" ]; then + AWS_GGCORE_HOST_PREFIX="$(echo ${AWS_GGCORE_IOT_HOST} | sed -e 's,\([^.]\+\)\.iot.*,\1,g')" + AWS_GGCORE_REGION="$(echo ${AWS_GGCORE_IOT_HOST} | sed -e 's,.*.iot\.\([^.]\+\)\..*,\1,g')" + [ -n "${AWS_GGCORE_HOST_PREFIX}" ] && sed -i -e "s,\[HOST_PREFIX_HERE],${AWS_GGCORE_HOST_PREFIX},g" ${D}/${BPN}/config/config.json + [ -n "${AWS_GGCORE_REGION}" ] && sed -i -e "s,\[AWS_REGION_HERE],${AWS_GGCORE_REGION},g" ${D}/${BPN}/config/config.json + fi + + # Configure whether to use systemd or not + sed -i -e "/useSystemd/{s,\[yes|no],${GG_USESYSTEMD},g}" ${D}/${BPN}/config/config.json +} + +pkg_postinst_${PN}() { + # Enable protection for hardlinks and symlinks + if ! grep -qs 'protected_.*links' $D${sysconfdir}/sysctl.conf; then + cat >> $D${sysconfdir}/sysctl.conf <<-_EOF_ + # Greengrass: protect hardlinks/symlinks + fs.protected_hardlinks = 1 + fs.protected_symlinks = 1 + _EOF_ + fi + + # Customize '/etc/fstab' + if [ -f "$D${sysconfdir}/fstab" ]; then + # Disable TMPFS /var/volatile + sed -i -e '\#^tmpfs[[:blank:]]\+/var/volatile#s,^,#,g' $D${sysconfdir}/fstab + + # Mount a cgroup hierarchy with all available subsystems + if ! grep -qs '^cgroup' $D${sysconfdir}/fstab; then + cat >> $D${sysconfdir}/fstab <<-_EOF_ + # Greengrass: mount cgroups + cgroup /sys/fs/cgroup cgroup defaults 0 0 + _EOF_ + fi + fi + + # Disable '/etc/resolv.conf' symlink + if [ -f "$D${sysconfdir}/default/volatiles/00_core" ]; then + sed -i -e '/resolv.conf/d' $D${sysconfdir}/default/volatiles/00_core + cat >> $D${sysconfdir}/default/volatiles/00_core <<-_EOF_ + # Greengrass: create a real (no symlink) resolv.conf + f root root 0644 /etc/resolv.conf none + _EOF_ + fi +} + +FILES_${PN} = "/${BPN} ${sysconfdir}" + +CONFFILES_${PN} += "/${BPN}/config/config.json" + +INITSCRIPT_NAME = "greengrass" +INITSCRIPT_PARAMS = "defaults 80 20" + +USERADD_PACKAGES = "${PN}" +GROUPADD_PARAM_${PN} = "-r ggc_group" +USERADD_PARAM_${PN} = "-r -M -N -g ggc_group -s /bin/false ggc_user" + +# +# Disable failing QA checks: +# +# Binary was already stripped +# No GNU_HASH in the elf binary +# +INSANE_SKIP_${PN} += "already-stripped ldflags" + +RDEPENDS_${PN} += "ca-certificates python-argparse python-json python-numbers sqlite3" From 89c677d54399ca5d2bcbbdbde662c7eb777c3367 Mon Sep 17 00:00:00 2001 From: Tatiana Leon Date: Mon, 27 Nov 2017 10:42:10 +0100 Subject: [PATCH 105/113] README.md: add new supported Greengrass v1.1.0 Signed-off-by: Tatiana Leon --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 92692ee83..69a06770c 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ Documentation is available online on the Digi documentation site: * SPI * I2C * PWM +* Updated AWS Greengrass Core software to v1.1.0 ## 2.2-r2 From 6b22810b04f3c687f99e37cffd5dab8f8b6fb8ab Mon Sep 17 00:00:00 2001 From: Francisco Gil Date: Mon, 27 Nov 2017 09:47:05 +0100 Subject: [PATCH 106/113] README: add support for the ADC Signed-off-by: Francisco Gil --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 69a06770c..012dcd769 100644 --- a/README.md +++ b/README.md @@ -82,12 +82,13 @@ Documentation is available online on the Digi documentation site: ## 2.2-r3 * Added Digi APIX C library to access and manage ConnectCore platforms interfaces: + * ADC * GPIO - * SPI * I2C * PWM + * SPI * Updated AWS Greengrass Core software to v1.1.0 - +======= ## 2.2-r2 * Use NetworkManager for ethernet, wireless (station) and cellular network interfaces From b55a37b7eff517b10bc10510285b31f30594fc7a Mon Sep 17 00:00:00 2001 From: David Escalona Date: Thu, 23 Nov 2017 18:42:48 +0100 Subject: [PATCH 107/113] ccimx6sbc/ul: synchronize kernel v4.1 defconfig Signed-off-by: David Escalona --- .../recipes-kernel/linux/linux-dey-4.1/ccimx6sbc/defconfig | 2 +- .../recipes-kernel/linux/linux-dey-4.1/ccimx6ul/defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6sbc/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6sbc/defconfig index 3ffe94b7d..f53e48f62 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6sbc/defconfig +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6sbc/defconfig @@ -180,7 +180,7 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_IMX=y -CONFIG_SPI_SPIDEV=y +CONFIG_SPI_SPIDEV=m CONFIG_SPI_SLAVE=y CONFIG_SPI_SLAVE_TIME=y CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6ul/defconfig b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6ul/defconfig index 71f754fe4..0733a5a89 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6ul/defconfig +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey-4.1/ccimx6ul/defconfig @@ -185,7 +185,7 @@ CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_GPIO=y CONFIG_SPI_IMX=y -CONFIG_SPI_SPIDEV=y +CONFIG_SPI_SPIDEV=m CONFIG_SPI_SLAVE=y CONFIG_SPI_SLAVE_TIME=y CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y From b8d04da22a0c29222214148250d7b0aeae739b5a Mon Sep 17 00:00:00 2001 From: Francisco Gil Date: Mon, 27 Nov 2017 16:26:10 +0100 Subject: [PATCH 108/113] apix: adc: change adc default pin Signed-off-by: Francisco Gil --- .../libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf index 1e403afad..cfce290e0 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/ccimx6ulstarter/board.conf @@ -27,4 +27,4 @@ DEFAULT_PWM = 0,0 [ADC] # ADC1_IN4 on Expansion connector (pin 7). -DEFAULT_ADC = 0,4 +DEFAULT_ADC = 1,4 From d76db197e1bedc9e4f3bb23807c0efd093c6b71e Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Thu, 23 Nov 2017 13:53:03 +0100 Subject: [PATCH 109/113] initramfs: launch rngd depending on kernel version Use the kernel version to decide to launch the rngd tool for kernels previous to v3.17 https://jira.digi.com/browse/DEL-5362 https://jira.digi.com/browse/DEL-5363 Signed-off-by: Arturo Buzarra --- .../recovery-initramfs-init | 18 +++++++++++-- .../ccimx6/trustfence-initramfs-init | 25 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init b/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init index 7e7e2dd8b..a59cb846c 100644 --- a/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init +++ b/meta-digi-dey/recipes-core/recovery/recovery-initramfs/recovery-initramfs-init @@ -349,6 +349,19 @@ set_encryption_flag() { fi } +#------------------------------------------------------------------------------ +# Function - get_kernel_version +# +# Obtain the kernel version and return it in number format +# +# @return - kernel version +#------------------------------------------------------------------------------ +get_kernel_version() { + major="$(uname -r | cut -d'.' -f1)" + minor="$(uname -r | cut -d'.' -f2)" + echo $(((major << 8) + minor)) +} + # Main #------------------------------------------------------------------------------ # Setup the environment. @@ -381,8 +394,9 @@ mkdir -p /var/lock # Set kernel console loglevel. sysctl -q -w kernel.printk=4 -if [ "$(is_nand)" = "no" ]; then - # Launch 'rngd' to feed random data to kernel entropy pool +# Launch 'rngd' to feed random data to kernel entropy pool +# for kernels previous to v3.17 +if [ "$(get_kernel_version)" -lt "$(((3 << 8) + 17))" ]; then mkdir -p /var/run && rngd fi diff --git a/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6/trustfence-initramfs-init b/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6/trustfence-initramfs-init index d1d352671..d8eb73c0b 100644 --- a/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6/trustfence-initramfs-init +++ b/meta-digi-dey/recipes-core/trustfence/trustfence-initramfs/ccimx6/trustfence-initramfs-init @@ -24,6 +24,22 @@ error() { sync && poweroff -f } +#------------------------------------------------------------------------------ +# Function - get_kernel_version +# +# Obtain the kernel version and return it in number format +# +# @return - kernel version +#------------------------------------------------------------------------------ +get_kernel_version() { + major="$(uname -r | cut -d'.' -f1)" + minor="$(uname -r | cut -d'.' -f2)" + echo $(((major << 8) + minor)) +} + +# Main +#------------------------------------------------------------------------------ +# Setup the environment. export PATH=/bin:/sbin:/usr/bin:/usr/sbin mkdir -p /proc /sys /dev @@ -36,7 +52,10 @@ LOGLEVEL="$(sysctl -n kernel.printk)" sysctl -q -w kernel.printk=4 # Launch 'rngd' to feed random data to kernel entropy pool -mkdir -p /var/run && rngd +# for kernels previous to v3.17 +if [ "$(get_kernel_version)" -lt "$(((3 << 8) + 17))" ]; then + mkdir -p /var/run && rngd +fi for arg in $(cat /proc/cmdline); do case "${arg}" in @@ -76,7 +95,9 @@ mount ${FSTYPE:+-t ${FSTYPE}} ${root} /newroot # - restore previous kernel console loglevel # - umount virtual filesystems # -pkill -9 rngd +if [ "$(get_kernel_version)" -lt "$(((3 << 8) + 17))" ]; then + pkill -9 rngd +fi [ -n "${LOGLEVEL}" ] && sysctl -q -w kernel.printk="${LOGLEVEL}" mount --move /dev /newroot/dev umount /sys /proc From 1104e5737fb42319297d6652af333c4bad614978 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Fri, 24 Nov 2017 09:12:19 +0100 Subject: [PATCH 110/113] README: update known issues limitation for P2P https://jira.digi.com/browse/DEL-5302 Signed-off-by: Isaac Hermida --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 012dcd769..d1aac605f 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,9 @@ boot a signed U-Boot only. * Cloud Connector * Remote file system management fails with long file names and paths (over 255 characters). +* For P2P connections Digi recommends "Negotiated GO" modes. The QCA6564 + devices (ConnectCore 6UL and ConnectCore 6 Plus) running a 4.9 kernel + version fail to join to autonomous groups. ## Digi ConnectCore 6UL From a45357940a07e524a4a4798ecdd5f58dc0b130d0 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Mon, 27 Nov 2017 13:56:43 +0100 Subject: [PATCH 111/113] libdigiapix: add udev rules for digiapix API These udev rules allow to use the digiapix API by a normal user that belongs to the 'digiapix' group. https://jira.digi.com/browse/DEL-5232 Signed-off-by: Javier Viguera --- .../libdigiapix-git/99-digiapix.rules | 22 +++++++++++++ .../libdigiapix/libdigiapix-git/digiapix.sh | 31 +++++++++++++++++++ .../libdigiapix/libdigiapix_git.bb | 9 +++++- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/99-digiapix.rules create mode 100644 meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/digiapix.sh diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/99-digiapix.rules b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/99-digiapix.rules new file mode 100644 index 000000000..04ec742bb --- /dev/null +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/99-digiapix.rules @@ -0,0 +1,22 @@ +# libdigiapix: configure interfaces so they can be used by group 'digiapix' + +SUBSYSTEM=="i2c-dev", GROUP="digiapix", MODE="0660" +SUBSYSTEM=="spidev", GROUP="digiapix", MODE="0660" + +# +# Use two different rules for GPIO's. +# +# 1. The first rule (gpiochip0) allows to configure the GROUP and MODE of +# the 'export' and 'unexport' files. This is basically executed once on +# boot and it's needed so a normal user (with group 'digiapix') +# is able to export/unexport gpios. +# +# 2. The second rule configures the GROUP and MODE of the sysfs files that +# are created whenever a 'gpio' is exported. +# +# This way we filter out multiple gpiochipX events that we don't want to attend +# +SUBSYSTEM=="gpio", KERNEL=="gpiochip0", ACTION=="add", RUN="/etc/udev/scripts/digiapix.sh" +SUBSYSTEM=="gpio", KERNEL!="gpiochip*", ACTION=="add", RUN="/etc/udev/scripts/digiapix.sh" + +SUBSYSTEM=="pwm", ACTION=="add", RUN="/etc/udev/scripts/digiapix.sh" diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/digiapix.sh b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/digiapix.sh new file mode 100644 index 000000000..bc3897c85 --- /dev/null +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix-git/digiapix.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Copyright (c) 2017, Digi International Inc. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at http://mozilla.org/MPL/2.0/. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +if basename "${DEVPATH}" | grep -qs "gpiochip0$"; then + # Use 'gpiochip0' event to set group and mode for 'export/unexport' files + chown root:digiapix /sys/class/gpio/export /sys/class/gpio/unexport + chmod g+w /sys/class/gpio/export /sys/class/gpio/unexport +elif basename "${DEVPATH}" | grep -qs "pwmchip[0-9]\+$"; then + # Set group and mode for pwmchip's 'export/unexport' files + chown root:digiapix /sys${DEVPATH}/export /sys${DEVPATH}/unexport + chmod g+w /sys${DEVPATH}/export /sys${DEVPATH}/unexport +else + # Change group and mode of the sysfs files created whenever a 'gpioX' + # or 'pwmX' is exported + chown -h root:digiapix /sys${DEVPATH}/* + chmod g+w /sys${DEVPATH}/* +fi diff --git a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb index 88517db7d..7d67c9075 100644 --- a/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb +++ b/meta-digi-dey/recipes-digi/libdigiapix/libdigiapix_git.bb @@ -18,7 +18,9 @@ LIBDIGIAPIX_GIT_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${LIBDIG SRC_URI = " \ ${LIBDIGIAPIX_GIT_URI};branch=${SRCBRANCH} \ + file://99-digiapix.rules \ file://board.conf \ + file://digiapix.sh \ " S = "${WORKDIR}/git" @@ -28,7 +30,12 @@ inherit pkgconfig useradd do_install() { oe_runmake 'DESTDIR=${D}' install - install -d ${D}${sysconfdir}/ + # Install udev rules for digiapix + install -d ${D}${sysconfdir}/udev/rules.d ${D}${sysconfdir}/udev/scripts + install -m 0644 ${WORKDIR}/99-digiapix.rules ${D}${sysconfdir}/udev/rules.d/ + install -m 0755 ${WORKDIR}/digiapix.sh ${D}${sysconfdir}/udev/scripts/ + + # Install board config file install -m 0644 ${WORKDIR}/board.conf ${D}${sysconfdir}/libdigiapix.conf } From b3ae030fce8b24c4f32e9eb618c664d57c6e0dce Mon Sep 17 00:00:00 2001 From: Sebastian Pastor Date: Tue, 28 Nov 2017 14:54:12 +0100 Subject: [PATCH 112/113] suspend: set wireless interfaces managed by NM as unmanaged before suspend With these changes we tell NM to not manage the wireless interfaces before unloading the wireless module. This was causing some unexpected behavior that crashed NetworkManager. Signed-off-by: Sebastian Pastor https://jira.digi.com/browse/DEL-5351 https://jira.digi.com/browse/DEL-4571 --- .../busybox/busybox-1.24.1/ccimx6qpsbc/suspend | 12 ++++++++++++ .../busybox/busybox-1.24.1/ccimx6sbc/suspend | 12 ++++++++++++ .../busybox/busybox-1.24.1/ccimx6ul/suspend | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend index 50e3e59a3..28a9f68ca 100755 --- a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend +++ b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6qpsbc/suspend @@ -36,6 +36,13 @@ suspend_interfaces() { for i in $(sed -ne 's,^\(wlan[0-9]\)=.*,\1,g;T;p' /var/run/ifstate | sort -r); do ifdown "${i}" && RESUME_IFACES="${RESUME_IFACES:+${RESUME_IFACES} }${i}" done + + # Get a list of the wireless interfaces managed by NetworkManager + # and set them to unmanaged before suspend. + for i in $(nmcli -t -f DEVICE,TYPE,STATE dev | grep :wifi: | grep -v unmanaged | cut -d':' -f1); do + nmcli dev set "${i}" managed no && NM_MANAGED_IFACES="${NM_MANAGED_IFACES:+${NM_MANAGED_IFACES} }${i}" + done + grep -qs '^wlan' /proc/modules && rmmod wlan fi @@ -54,6 +61,11 @@ resume_interfaces() { udevadm trigger --action=add --attr-match="modalias=sdio:c00v0271d050A" timeout -t 5 sh -c "while [ ! -d /sys/class/net/wlan0 ]; do sleep .2; done" 2>/dev/null + # Set interfaces managed by NetworkManager back as managed + for i in $(echo ${NM_MANAGED_IFACES} | tr ' ' '\n' | sort); do + nmcli dev set "${i}" managed yes + done + # Bring up the interfaces that were bring down on suspend for i in $(echo ${RESUME_IFACES} | tr ' ' '\n' | sort); do grep -qs "^${i}" /var/run/ifstate || ifup "${i}" diff --git a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6sbc/suspend b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6sbc/suspend index 140645eea..44f9548e6 100755 --- a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6sbc/suspend +++ b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6sbc/suspend @@ -36,6 +36,13 @@ suspend_interfaces() { for i in $(sed -ne 's,^\(wlan[0-9]\)=.*,\1,g;T;p' /var/run/ifstate | sort -r); do ifdown "${i}" && RESUME_IFACES="${RESUME_IFACES:+${RESUME_IFACES} }${i}" done + + # Get a list of the wireless interfaces managed by NetworkManager + # and set them to unmanaged before suspend. + for i in $(nmcli -t -f DEVICE,TYPE,STATE dev | grep :wifi: | grep -v unmanaged | cut -d':' -f1); do + nmcli dev set "${i}" managed no && NM_MANAGED_IFACES="${NM_MANAGED_IFACES:+${NM_MANAGED_IFACES} }${i}" + done + grep -qs '^ath6kl_sdio' /proc/modules && rmmod ath6kl_sdio ath6kl_core fi @@ -54,6 +61,11 @@ resume_interfaces() { udevadm trigger --action=add --attr-match="modalias=sdio:c00v0271d0301" timeout -t 5 sh -c "while [ ! -d /sys/class/net/wlan0 ]; do sleep .2; done" 2>/dev/null + # Set interfaces managed by NetworkManager back as managed + for i in $(echo ${NM_MANAGED_IFACES} | tr ' ' '\n' | sort); do + nmcli dev set "${i}" managed yes + done + # Bring up the interfaces that were bring down on suspend for i in $(echo ${RESUME_IFACES} | tr ' ' '\n' | sort); do grep -qs "^${i}" /var/run/ifstate || ifup "${i}" diff --git a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6ul/suspend b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6ul/suspend index a74f24d35..f2ee3cb22 100755 --- a/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6ul/suspend +++ b/meta-digi-dey/recipes-core/busybox/busybox-1.24.1/ccimx6ul/suspend @@ -36,6 +36,13 @@ suspend_interfaces() { for i in $(sed -ne 's,^\(wlan[0-9]\)=.*,\1,g;T;p' /var/run/ifstate | sort -r); do ifdown "${i}" && RESUME_IFACES="${RESUME_IFACES:+${RESUME_IFACES} }${i}" done + + # Get a list of the wireless interfaces managed by NetworkManager + # and set them to unmanaged before suspend. + for i in $(nmcli -t -f DEVICE,TYPE,STATE dev | grep :wifi: | grep -v unmanaged | cut -d':' -f1); do + nmcli dev set "${i}" managed no && NM_MANAGED_IFACES="${NM_MANAGED_IFACES:+${NM_MANAGED_IFACES} }${i}" + done + grep -qs '^wlan' /proc/modules && rmmod wlan fi @@ -54,6 +61,11 @@ resume_interfaces() { udevadm trigger --action=add --attr-match="modalias=sdio:c00v0271d050A" timeout -t 5 sh -c "while [ ! -d /sys/class/net/wlan0 ]; do sleep .2; done" 2>/dev/null + # Set interfaces managed by NetworkManager back as managed + for i in $(echo ${NM_MANAGED_IFACES} | tr ' ' '\n' | sort); do + nmcli dev set "${i}" managed yes + done + # Bring up the interfaces that were bring down on suspend for i in $(echo ${RESUME_IFACES} | tr ' ' '\n' | sort); do grep -qs "^${i}" /var/run/ifstate || ifup "${i}" From cd1a145e10cd789b112d812affa6d82cd301dfd2 Mon Sep 17 00:00:00 2001 From: Javier Viguera Date: Tue, 28 Nov 2017 18:55:43 +0100 Subject: [PATCH 113/113] libsoc: patch library to allow udev events to complete After exporting a GPIO or PWM, we need to give some time for udev rules to complete, before actually trying to access the newly created entries in the sysfs. This solves a problem, where udev was setting the mode and group of the newly created files, so they are accessible for users (not root) belonging to that group. For traceability and to be sure the patch applies without conflicts, this commit also sets a fixed revision to use from the libsoc repository. https://jira.digi.com/browse/DEL-5389 Signed-off-by: Javier Viguera --- ...elay-to-allow-udev-rules-to-complete.patch | 46 +++++++++++++++++++ .../libsoc/libsoc_git.bbappend | 7 ++- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 meta-digi-dey/recipes-support/libsoc/libsoc/0001-gpio-pwm-add-delay-to-allow-udev-rules-to-complete.patch diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc/0001-gpio-pwm-add-delay-to-allow-udev-rules-to-complete.patch b/meta-digi-dey/recipes-support/libsoc/libsoc/0001-gpio-pwm-add-delay-to-allow-udev-rules-to-complete.patch new file mode 100644 index 000000000..911b7f964 --- /dev/null +++ b/meta-digi-dey/recipes-support/libsoc/libsoc/0001-gpio-pwm-add-delay-to-allow-udev-rules-to-complete.patch @@ -0,0 +1,46 @@ +From: Javier Viguera +Date: Tue, 28 Nov 2017 17:39:05 +0100 +Subject: [PATCH] gpio,pwm: add delay to allow udev rules to complete + +After exporting a GPIO or PWM, we need to give some time for udev rules +to complete, before actually trying to access the newly created entries +in the sysfs. + +This solves a problem, where udev was setting the mode and group of +the newly created files, so they are accessible for users (not root) +belonging to that group. + +Signed-off-by: Javier Viguera +--- + lib/gpio.c | 3 +++ + lib/pwm.c | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/lib/gpio.c b/lib/gpio.c +index bc509f8f09d7..527f2be649a4 100644 +--- a/lib/gpio.c ++++ b/lib/gpio.c +@@ -104,6 +104,9 @@ libsoc_gpio_request (unsigned int gpio_id, gpio_mode mode) + if (file_close (fd)) + return NULL; + ++ /* Give udev some time to execute the rules of the exported GPIO */ ++ usleep(200000); ++ + sprintf (tmp_str, "/sys/class/gpio/gpio%d", gpio_id); + + if (!file_valid (tmp_str)) +diff --git a/lib/pwm.c b/lib/pwm.c +index 94a20d9be281..ed6dec8ee2a9 100644 +--- a/lib/pwm.c ++++ b/lib/pwm.c +@@ -88,6 +88,9 @@ pwm* libsoc_pwm_request (unsigned int chip, unsigned int pwm_num, + return NULL; + } + ++ /* Give udev some time to execute the rules of the exported PWM */ ++ usleep(200000); ++ + sprintf(tmp_str, "/sys/class/pwm/pwmchip%d/pwm%d/enable", chip, pwm_num); + + if (!file_valid(tmp_str)) diff --git a/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend index 04ef0b60d..70d0ba51e 100644 --- a/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend +++ b/meta-digi-dey/recipes-support/libsoc/libsoc_git.bbappend @@ -1,12 +1,15 @@ # Copyright (C) 2017 Digi International Inc. +FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" + LIBSOC_URI_STASH = "${DIGI_MTK_GIT}dey/libsoc.git;protocol=ssh" LIBSOC_URI_GITHUB = "git://github.com/jackmitch/libsoc.git;protocol=git" LIBSOC_URI ?= "${@base_conditional('DIGI_INTERNAL_GIT', '1' , '${LIBSOC_URI_STASH}', '${LIBSOC_URI_GITHUB}', d)}" +SRCREV = "dc62bb1f04c13d0423078b1af2bb439c62023d6c" SRC_URI = " \ - ${LIBSOC_URI};branch=${SRCBRANCH} \ + ${LIBSOC_URI};nobranch=1 \ + file://0001-gpio-pwm-add-delay-to-allow-udev-rules-to-complete.patch \ " PACKAGECONFIG = "python" -